diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c20c2ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ + diff --git a/README.md b/README.md index 4e4b6e9..15d62da 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,127 @@ -# RT-AK-plugin-tflm -RT-AK plugin for Tensorflow Lite Micro + + +

RT-AK 之 tflm

+ + [中文](./README.md) + +- [简介](#简介) +- [目录结构](#目录结构) +- [命令行参数详细说明](#命令行参数详细说明) +- [插件安装](#插件安装) +- [命令行运行 RT-AK](#命令行运行-rt-ak) +- [插件内部工作流程](#插件内部工作流程) + +## 简介 + +> Date: 2021/09/29 +> +> ```shell +> # 模板 +> python aitools.py --project --model_name --platform tflm +> +> # 示例 +> python aitools.py --project="D:\Code\Project\imx6ullrtak\imx6ull" --model="./Models/facelandmark.tflite" --platform=tflm + +> ``` +> + +> Date: 2021/09/29 +> +> Update: 该版本插件尚未支持模型转化功能,使用的是转化好的头文件数组,后续将继续完成 + +*本项目归属于 `RT-AK` 主项目中的一个子模块。* + +使用 `tensorflow lite micro` 作为插件推理后端。 + +- 模型支持:`TFLite` +- 算子支持:reference算子 + +该插件应用示例参考: + +- 教程:docs/RT-AK之tflm快速上手.md + +## 目录结构 + +```shell +% tree -L 2 tflm +imx6ull +├── backend_plugin_tflm +│ ├── backend_tflm.c +│ ├── backend_tflm.h +│ └── readme.md +├── config.py # 生成 `rt_ai__model.h` 的一些配置信息,保存在 /applications +├── generate_rt_ai_model_h.py # 生成 `rt_ai__model.h` ,保存在 /applications +├── gen_rt_ai_model_c.py # 生成 `rt_ai__model.c` ,保存在 /applications +├── __init__.py +├── plugin_tflm_parser.py # `imx6ull` 平台插件运行所需的参数 +├── plugin_tflm.py # `imx6ull` 平台插件运行主函数 +├── prepare_work.py # 生成两个文件夹,存放 TFLite库和 c-model 文件; 加载对应的 Sconscript +├── README.md +├── Sconscripts # 模型转换之后,参与到项目 `scons` 编译的脚本文件 +│ ├── Middlewares +│ └── TFLite +└── TensorflowLiteMicro # `TFLite推理后端源码` +``` + +## 命令行参数详细说明 + +$$ +RT-AK 命令行的参数 = (RT-AK 基础参数 + imx6ull 插件参数) +$$ + +- RT-AK 基础参数,[链接](https://github.com/RT-Thread/RT-AK/tree/main/RT-AK/rt_ai_tools#0x03-%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E) + +- 该部分是 RT-AK 之 tflm 插件的参数说明,详见 `plugin_tflm_parser.py` + +其中需要注意的是加粗部分的三个参数,请注意看相关描述。 + + +| Parameter | Description | +| ------------------- | ------------------------------------------------------------ | +| `--tflite` | 运行所需的推理后端,默认为`./platforms/plugin_imx6ull/TensorflowLiteMicro` | +| `--tflm_out` | 产生的中间文件夹路径,默认是当天的时间戳命名 | +| **--enable_rt_lib** | **在 `project/rtconfgi.h` 中打开宏定义,默认是 `RT_AI_USE_imx6ull`** | +| --clear | 是否需要删除生成的中间文件夹 `stm_out` ,默认为`False` | + +## 插件安装 + +该插件无需主动安装, + +只需要克隆主项目工程:[RT-AK](https://github.com/RT-Thread/RT-AK) + +进入到 `RT-AK/rt_ai_tools` 路径下, + +**仅需要**在执行 `python aitools.py --xxx` 的同时指定 `platform` 参数为 `tflm` 即可,插件会自动下载。 + +## 命令行运行 RT-AK + +请在 `xxx/RTAK/tools` 路径下运行该程序。 + +![](https://gitee.com/lebhoryi/PicGoPictureBed/raw/master/img/20210223145923.png) + +```shell +# 基础运行命令 +python aitools.py --project --model_name --platform tflm + +# 示例 +python aitools.py --project="D:\Code\Project\imx6ullrtak\imx6ull" --model="./Models/speech_case.tflite" --platform=tflm --clear +``` + +![run_example](./doc/../docs/pic/run_example.png) + + +完整的项目实战例程,请阅读:[RT-AK之tflm快速上手.md](./docs/RT-AK之tflm快速上手.md) + +## 插件内部工作流程 + +- [ ] 模型量化 + +- [ ] 判断模型是否支持 +- [ ] 判断 `CPU` 是否支持,目前是写死为tflm +- [x] 在 `stm_out` 下生成后端推理框架和存放 `c-model` 的文件夹 +- [x] 将模型转换成 `c-model`,保存在 `/TFLite` 路径下 +- [x] 生成 `rt_ai__model.h` 文件,保存在 `project/applications` +- [x] 生成 `rt_ai__model.c` 文件,保存在 `project/applications` +- [x] 把 `stm_out` 内的两个关键文件夹加载到 `project` 下 +- [x] 判断是否删除 `stm_out` +- [ ] 解析模型的输入输出维度 diff --git a/Sconscripts/Middlewares b/Sconscripts/Middlewares new file mode 100644 index 0000000..72b1289 --- /dev/null +++ b/Sconscripts/Middlewares @@ -0,0 +1,53 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') +""" +import os, sys +import rtconfig +from building import * + +cwd = GetCurrentDir() +CPPPATH = [cwd + '/TF'] +#LIBPATH = [cwd + '/ST/AI/Lib'] +#lib_file_path = os.listdir(LIBPATH[0]) +# split filenames without suffix, only stem +#lib_files = list() +# lib_files = +# ['libNetworkRuntime520_CM4_GCC_PIC', 'NetworkRuntime520_CM4_IAR', 'NetworkRuntime520_CM4_Keil'] +#for i in range(len(lib_file_path)): +# stem = os.path.splitext(lib_file_path[i])[0] +# lib_files.append(stem) + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR + +for item in lib_files: + if "GCC" in item and rtconfig.CROSS_TOOL == 'gcc': + # libNetworkRuntime520_CM7_GCC_PIC --> NetworkRuntime520_CM7_GCC_PIC + LIBS = [item[3:]] + elif "Keil" in item and rtconfig.CROSS_TOOL == 'keil': + LIBS = [item] + elif "IAR" in item and rtconfig.CROSS_TOOL == 'iar': + LIBS = [item] + + +src = [] + +#group = DefineGroup('Middlewares', src, depend = [''], CPPPATH = CPPPATH, LIBS = LIBS, LIBPATH = LIBPATH) +group = DefineGroup('Middlewares', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') + +""" \ No newline at end of file diff --git a/Sconscripts/TFLite b/Sconscripts/TFLite new file mode 100644 index 0000000..bf71f6c --- /dev/null +++ b/Sconscripts/TFLite @@ -0,0 +1,10 @@ +import rtconfig +from building import * + +cwd = GetCurrentDir() +CPPPATH = [cwd, cwd + '/App'] +src = Glob('App/*.c') + +group = DefineGroup('TFLite', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/.gitignore b/TensorflowLiteMicro/.gitignore new file mode 100644 index 0000000..7049028 --- /dev/null +++ b/TensorflowLiteMicro/.gitignore @@ -0,0 +1,53 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb +.vscode + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/TensorflowLiteMicro/LICENSE b/TensorflowLiteMicro/LICENSE new file mode 100644 index 0000000..40f8c34 --- /dev/null +++ b/TensorflowLiteMicro/LICENSE @@ -0,0 +1,203 @@ +Copyright 2019 The TensorFlow Authors. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/TensorflowLiteMicro/SConscript b/TensorflowLiteMicro/SConscript new file mode 100644 index 0000000..af1d558 --- /dev/null +++ b/TensorflowLiteMicro/SConscript @@ -0,0 +1,16 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +print("TF in") +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/docs/ModelConvert.md b/TensorflowLiteMicro/docs/ModelConvert.md new file mode 100644 index 0000000..3a9190f --- /dev/null +++ b/TensorflowLiteMicro/docs/ModelConvert.md @@ -0,0 +1,202 @@ +# 模型转换器(Converter)的 Python API 指南 + +此md提供了一个关于在 TensorFlow 2.0 中如何使用 TensorFlow Lite 转换器(TensorFlow Lite converter) Python API 的示例。 +Python API + +在 TensorFlow 2.0 中,用来将原始的 TensorFlow 模型格式转换为 TensorFlow Lite 的 Python API 是 tf.lite.TFLiteConverter。在 TFLiteConverter 中有以下的类方法(classmethod): + + TFLiteConverter.from_saved_model():用来转换 SavedModel 格式模型。 + TFLiteConverter.from_keras_model():用来转换 tf.keras 模型。 + TFLiteConverter.from_concrete_functions():用来转换 concrete functions。 + +注意: 在 TensorFlow Lite 2.0 中有一个不同版本的 TFLiteConverter API, 该 API 只包含了 from_concrete_function。 本文中用到的的新版本 API 可以通过 pip 安装 tf-nightly-2.0-preview。 + +本文展示了 API 的 示例用法,不同 TensorFlow 版本的 API 详细列表请看 1.X 版本到 2.0 版本 API 的改变,和 安装 TensorFlow 来安装和使用。 +## 示例 + +### 转换 SavedModel 格式模型 + +以下示例展示了如何将一个 SavedModel 转换为 TensorFlow Lite 中的 FlatBuffer格式。 + + import tensorflow as tf + + # 建立一个简单的模型。 + root = tf.train.Checkpoint() + root.v1 = tf.Variable(3.) + root.v2 = tf.Variable(2.) + root.f = tf.function(lambda x: root.v1 * root.v2 * x) + + # 保存模型。 + export_dir = "/tmp/test_saved_model" + input_data = tf.constant(1., shape=[1, 1]) + to_save = root.f.get_concrete_function(input_data) + tf.saved_model.save(root, export_dir, to_save) + + # 转换模型。 + converter = tf.lite.TFLiteConverter.from_saved_model(export_dir) + tflite_model = converter.convert() + +此 API 不支持指定输入向量的维度。 如果您的模型需要指定输入向量的维度,请使用 `from_concrete_functions` 来完成。 示例: + + model = tf.saved_model.load(export_dir) + concrete_func = model.signatures[ + tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY] + concrete_func.inputs[0].set_shape([1, 256, 256, 3]) + converter = TFLiteConverter.from_concrete_functions([concrete_func]) + +### 转换 Keras 模型 + +以下示例展示了如何将一个 tf.keras 模型 转换为 TensorFlow Lite 中的 FlatBuffer 格式。 + + import tensorflow as tf + + # 创建一个简单的 Keras 模型。 + x = [-1, 0, 1, 2, 3, 4] + y = [-3, -1, 1, 3, 5, 7] + + model = tf.keras.models.Sequential( + [tf.keras.layers.Dense(units=1, input_shape=[1])]) + model.compile(optimizer='sgd', loss='mean_squared_error') + model.fit(x, y, epochs=50) + + # 转换模型。 + converter = tf.lite.TFLiteConverter.from_keras_model(model) + tflite_model = converter.convert() + +### 转换 `concrete function` + +以下示例展示了如何将 TensorFlow 中的` concrete function` 转换为TensorFlow Lite 中的 FlatBuffer 格式。 + + import tensorflow as tf + + # 建立一个模型。 + root = tf.train.Checkpoint() + root.v1 = tf.Variable(3.) + root.v2 = tf.Variable(2.) + root.f = tf.function(lambda x: root.v1 * root.v2 * x) + + # 生成 concrete function。 + input_data = tf.constant(1., shape=[1, 1]) + concrete_func = root.f.get_concrete_function(input_data) + + # 转换模型。 + ## `from_concrete_function` 的传入参数被设计为一个个 concrete functio的列表,然而 + # 现阶段仅支持每次调用时仅接受一个concrete function。 + # 同时转换多个concrete function的功能正在开发中。 + converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func]) + tflite_model = converter.convert() + +## 端到端 MobileNet 转换 + +以下示例展示了如何将将一个提前训练好的 tf.keras MobileNet 模型转换为 TensorFlow Lite 支持的类型并运行推断 (inference)。 随机数据分别在 TensorFlow 和 TensorFlow Lite 模型中运行的结果将被比较。如果是从文件加载模型,请使用 model_path 来代替 model_content。 + + import numpy as np + import tensorflow as tf + + # 加载 MobileNet tf.keras 模型。 + model = tf.keras.applications.MobileNetV2( + weights="imagenet", input_shape=(224, 224, 3)) + + # 转换模型。 + converter = tf.lite.TFLiteConverter.from_keras_model(model) + tflite_model = converter.convert() + + # 加载 TFLite 模型并分配张量(tensor)。 + interpreter = tf.lite.Interpreter(model_content=tflite_model) + interpreter.allocate_tensors() + + # 获取输入和输出张量。 + input_details = interpreter.get_input_details() + output_details = interpreter.get_output_details() + + # 使用随机数据作为输入测试 TensorFlow Lite 模型。 + input_shape = input_details[0]['shape'] + input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32) + interpreter.set_tensor(input_details[0]['index'], input_data) + + interpreter.invoke() + + # 函数 `get_tensor()` 会返回一份张量的拷贝。 + # 使用 `tensor()` 获取指向张量的指针。 + tflite_results = interpreter.get_tensor(output_details[0]['index']) + + # 使用随机数据作为输入测试 TensorFlow 模型。 + tf_results = model(tf.constant(input_data)) + + # 对比结果。 + for tf_result, tflite_result in zip(tf_results, tflite_results): + np.testing.assert_almost_equal(tf_result, tflite_result, decimal=5) + +## 总结 1.X 版本到 2.0 版本 API 的改变 + +本节总结了从 1.X 到 2.0 版本 Python API 的改变。 如果对某些改动有异议,请提交 GitHub issue。 + +### TFLite转换器 支持的格式类型 + +`TFLite转换器`在 2.0 版本中支持由` 1.X `版本和` 2.0 `版本生成的 SavedModels 和 Keras 模型。但是,转换过程不再支持由 1.X 版本冻结的 GraphDefs。 开发者可通过调用 tf.compat.v1.lite.TFLiteConverter 来把冻结的 GraphDefs 转换到 TensorFlow Lite 版本。 + +#### 量化感知训练(Quantization-aware training) + +以下与 量化感知训练(Quantization-aware training) 有关的属性和方法在 TensorFlow 2.0 中从TFLiteConverter 中被移除。 + + inference_type + inference_input_type + quantized_input_stats + default_ranges_stats + reorder_across_fake_quant + change_concat_input_ranges + post_training_quantize - 在 1.X API 中被弃用 + get_input_arrays() + +支持量化感知训练的重写器(rewriter)函数不支持由 TensorFlow 2.0 生成的模型。此外,TensorFlow Lite 的量化 API 已按支持 Keras 中量化感知训练 API 的思路重新设计和精简。 在新的量化 API 部署前,这些属性将不会出现在 2.0 的 API 中。开发者可以使用 tf.compat.v1.lite.TFLiteConverter 来转换由重写器函数生成的模型。 + +#### 关于 TFLiteConverter 中属性的改变 + +属性 target_ops 已成为 TargetSpec 中的属性且作为未来对优化框架的补充被重命名为 supported_ops。 + +此外,以下属性被移除: + +- drop_control_dependency (default: True) - TFLite 现不支持控制流(control flow),所以此属性将恒为 True。 +- Graph visualization - 在 TensorFlow 2.0 中,推荐使用 visualize.py 实现对 TensorFlow Lite 图(graph)的可视化。 不同于 GraphViz, 它支持开发者对已进行过 post training 量化的图(graph)可视化。以下与图可视化的属性将被移除: +- output_format + - dump_graphviz_dir + - dump_graphviz_video + +## 通用 API 的改变 +#### 转换方法 + +以下在 1.X 中被弃用的方法不会在 2.0 中出现: + + lite.toco_convert + lite.TocoConverter + +#### lite.constants + +在 2.0 中,为了减少 TensorFlow 和 TensorFlow Lite 之间的重复移除了` lite.constants` API。以下的列表展示了` lite.constant `中的类型在 TensorFlow 中对应的类型: + + lite.constants.FLOAT: tf.float32 + lite.constants.INT8: tf.int8 + lite.constants.INT32: tf.int32 + lite.constants.INT64: tf.int64 + lite.constants.STRING: tf.string + lite.constants.QUANTIZED_UINT8: tf.uint8 + +此外,lite.constants.TFLITE 和 lite.constants.GRAPHVIZ_DOT 被移除(由于 TFLiteConverter 中的 flage output_format被移除)。 +lite.OpHint + +由于 API OpHint 与 2.0 的 API 不兼容,故暂不可用。 此 API可用于转换基于 LSTM 的模型。 在 2.0 中对 LSTMs 的支持正在被探究。所有与 lite.experimental 有关的 API 都因此被移除。 + +### 安装 TensorFlow +#### 安装 TensorFlow 2.0 nightly + +可用以下命令安装 TensorFlow 2.0 nightly: + + pip install tf-nightly-2.0-preview + +#### 在已安装的 1.X 中使用 TensorFlow 2.0 + +可通过以下代码片段从最近安装的 1.X 中使用 TensorFlow 2.0。 + + import tensorflow.compat.v2 as tf + + tf.enable_v2_behavior() \ No newline at end of file diff --git a/TensorflowLiteMicro/docs/api.md b/TensorflowLiteMicro/docs/api.md new file mode 100644 index 0000000..8259c26 --- /dev/null +++ b/TensorflowLiteMicro/docs/api.md @@ -0,0 +1,59 @@ +# Tensorflow Lite Micro API + +## 目前软件包支持的算子(共52个算子) + +每个算子定义的详细内容可以参见[`all_ops_resolver.cc`](../tensorflow/lite/micro/all_ops_resolver.cc) + +| 算子名称 | 描述 | +|:-------------------------------------|--------| +|`ABS()` | 元素级取绝对值 | +| `ADD()` | 元素级求和 | +| `ARG_MAX()` | 获得最大值对应的下标 | +| `ARG_MIN()` | 获得最小值对应的下标 | +| `AVERAGE_POOL_2D()` | 二维均值池化算子 | +| `CEIL()` | 对tensor向上取整 | +| `CONCATENATION()` | tensor按第一维进行聚合 | +| `CONV_2D()` | 二维卷积 | +| `COS()` | cos(x)函数 | +| `DEPTHWISE_CONV_2D()` | 深度可分离二维卷积 | +| `DEQUANTIZE()` | 反量化算子 | +| `EQUAL()` | 量化算子 | +| `FLOOR()` | 对tensor向下取整 | +| `FULLY_CONNECTED()` | 全连接层 | +| `GREATER()` | | +| `GREATER_EQUAL()` | | +| `L2_NORMALIZATION()` | 应用欧式距离进行归一化 | +| `LESS()` | | +| `LESS_EQUAL()` | | +| `LOG()` | 对tensor进行log运算 | +| `AND()` | 元素级与 | +| `NOT()` | 元素级取反 | +| `OR()` | 元素级或 | +| `LOGISTIC()` | 对tensor引用逻辑回归函数 | +| `MAX_POOL_2D()` | 最大值池化 | +| `MAXIMUM()` | 对两个输入tensor求较大的tensor | +| `MEAN()` | | +| `MINIMUM()` | | +| `MUL()` | | +| `NEG()` | | +| `NOT_EQUAL()` | | +| `PACK()` | | +| `PAD()` | | +| `PADV2()` | | +| `PRELU()` | | +| `QUANTIZE()` | | +| `RELU()` | RELU激活函数 | +| `RELU6()` | | +| `RESHAPE()` | 对tensor维度进行重新设置 | +| `RESIZE_NEAREST_NEIGHBOR()` | | +| `ROUND()` | | +| `RSQRT()` | | +| `SIN()` | sin(x)函数 | +| `SOFTMAX()` | | +| `SPLIT()` | | +| `SQRT()` | | +| `SQUARE()` | | +| `STRIDED_SLICE()` | | +| `SVDF()` | | +| `TANH()` | tan(x)函数 | +| `UNPACK()` | | diff --git a/TensorflowLiteMicro/docs/introduction.md b/TensorflowLiteMicro/docs/introduction.md new file mode 100644 index 0000000..2ea763d --- /dev/null +++ b/TensorflowLiteMicro/docs/introduction.md @@ -0,0 +1,54 @@ +# TensorFlow Lite Micro软件包 + +TensorFlow Lite Micro 是 TensorFlow Lite 的实验性端口,专门用于在嵌入式设备和其他只有几千字节内存的设备上运行机器学习模型。 + +它不需要操作系统支持、任何标准 C/C++ 库或动态内存分配。核心运行时在 Arm Cortex M3 上占用 16 KB 的内存,并且具有足够多的运算符来运行语音关键字检测模型,运行时总共占用 22 KB 的内存。 + +一些示例应用演示了如何使用微控制器执行唤醒字词检测,根据加速度计数据进行手势分类(待移植),以及使用相机数据进行图像分类(待移植)等任务。 + +## 使用入门 + +如需试用示例应用并了解如何使用该 API,请参阅[用户指导](user-guide.md)。 + +## 为什么要在嵌入式设备中使用机器学习模型 + +嵌入式设备通常是小型低功耗计算设备,往往嵌入到需要执行基本计算的硬件(包括家用电器和物联网设备)中。微控制芯片的年生产量高达数十亿。 + +微控制器芯片通常经过优化以实现低能耗和小尺寸,但处理能力、内存和存储空间会受到影响。同时一些微控制器是为了优化机器学习任务的性能而被设计出来的。 + +通过在微控制器上运行机器学习推断,开发者可以在不依靠网络连接的情况下向各种硬件设备添加 AI 功能,而依赖网络的AI功能通常会受到带宽和功率限制,并且会导致长时间延迟。由于数据无需离开设备,因此在设备端运行推断也有助于保护隐私。 + +## 开发者工作流程 + +为了将 TensorFlow 模型部署到微控制器,您需要遵循以下流程: + +1. **创建或获取 TensorFlow 模型** + + 该模型必须足够小,在转换后适合目标设备,并且只能使用[支持的操作](https://tensorflow.google.cn/lite/microcontrollers/build_convert#operation_support)。如果您想使用目前不受支持的操作,可以提供自己的实现。 + +2. **将模型转换为 TensorFlow Lite FlatBuffer** + + 您可以使用 [TensorFlow Lite 转换器](https://tensorflow.google.cn/lite/microcontrollers/build_convert#model_conversion)将模型转换为标准 TensorFlow Lite 格式。您可能希望输出量化模型,因为它们更小而且执行效率更高。 + +3. **将 FlatBuffer 转换为 C 字节数组** + + 模型保存在只读程序内存中,并以简单 C 文件的形式提供。您可以使用标准工具[将 FlatBuffer 转换为 C 数组](https://tensorflow.google.cn/lite/microcontrollers/build_convert#convert_to_a_c_array)。 + +4. **集成适用于微控制器的 TensorFlow Lite C++ 库** + + 编写微控制器代码以收集数据、使用 [C++ 库](https://tensorflow.google.cn/lite/microcontrollers/library)执行推断,并利用结果。 + +5. **部署到您的设备** + + 构建程序并将其部署到您的设备。 + +## 限制 + +适用于微控制器的 TensorFlow Lite 专为满足微控制器开发的特定限制条件而设计。如果您使用的是更强大的设备(例如 Raspberry Pi 等嵌入式 Linux 设备),那么标准 TensorFlow Lite 框架可能更易于集成。 + +应考虑以下限制条件: + +- 支持的 TensorFlow 操作[有限](https://tensorflow.google.cn/lite/microcontrollers/build_convert#operation_support) +- 支持的设备有限 +- 需要手动内存管理的低阶 C++ API +- 不支持训练 \ No newline at end of file diff --git a/TensorflowLiteMicro/docs/principle.md b/TensorflowLiteMicro/docs/principle.md new file mode 100644 index 0000000..45f4753 --- /dev/null +++ b/TensorflowLiteMicro/docs/principle.md @@ -0,0 +1,2 @@ +# Tensorflow Lite Micro 工作原理 + diff --git a/TensorflowLiteMicro/docs/samples.md b/TensorflowLiteMicro/docs/samples.md new file mode 100644 index 0000000..4b571c6 --- /dev/null +++ b/TensorflowLiteMicro/docs/samples.md @@ -0,0 +1,167 @@ +# Tensorflow Lite Micro示例程序 # + +此示例使用一个简单的 [音频识别模型](https://tensorflow.google.cn/tutorials/sequences/audio_recognition) 来识别语音中的关键字。示例代码从设备的麦克风中捕获音频。模型通过对该音频进行实时分类来确定是否说过“是”或“否一词。 + +## 运行推断 + +以下部分将介绍[微语音](https://tensorflow.google.cn/lite/microcontrollers/get_started#微语音示例)示例中的 [main.cc](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/main.cc) 文件并解释了它如何使用用于微控制器的 Tensorflow Lite 来运行推断。 + +### 包含项 + +要使用库,必须包含以下头文件: + +```C++ +#include "tensorflow/lite/micro/kernels/all_ops_resolver.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/version.h" +``` + +- [`all_ops_resolver.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/kernels/all_ops_resolver.h) 提供给解释器(interpreter)用于运行模型的操作。 +- [`micro_error_reporter.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/micro_error_reporter.h) 输出调试信息。 +- [`micro_interpreter.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/micro_interpreter.h) 包含处理和运行模型的代码。 +- [`schema_generated.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/schema/schema_generated.h) 包含 TensorFlow Lite [`FlatBuffer`](https://google.github.io/flatbuffers/) 模型文件格式的模式。 +- [`version.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/version.h) 提供 Tensorflow Lite 架构的版本信息。 + +示例还包括其他一些文件。以下这些是最重要的: + +```C++ +#include "tensorflow/lite/micro/examples/micro_speech/feature_provider.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/tiny_conv_micro_features_model_data.h" +``` + +- [`feature_provider.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_features/feature_provider.h) 包含从音频流中提取要输入到模型中的特征的代码。 +- [`tiny_conv_micro_features_model_data.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_features/tiny_conv_micro_features_model_data.h) 包含存储为 `char` 数组的模型。阅读 [“构建与转换模型”](https://tensorflow.google.cn/lite/microcontrollers/build_convert) 来了解如何将 Tensorflow Lite 模型转换为该格式。 +- [`micro_model_settings.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h) 定义与模型相关的各种常量。 + +### 设置日志记录 + +要设置日志记录,需要使用一个指向 `tflite::MicroErrorReporter` 实例的指针来创建一个 `tflite::ErrorReporter` 指针: + +```C++ +tflite::MicroErrorReporter micro_error_reporter; +tflite::ErrorReporter* error_reporter = µ_error_reporter; +``` + +该变量被传递到解释器(interpreter)中,解释器允许它写日志。由于微控制器通常具有多种日志记录机制,`tflite::MicroErrorReporter` 的实现是为您的特定设备所定制的。 + +### 加载模型 + +在以下代码中,模型是从一个 `char` 数组中实例化的,`g_tiny_conv_micro_features_model_data` (要了解其是如何构建的,请参见[“构建与转换模型”](https://tensorflow.google.cn/lite/microcontrollers/build_convert))。 随后我们检查模型来确保其架构版本与我们使用的版本所兼容: + +```C++ +const tflite::Model* model = + ::tflite::GetModel(g_tiny_conv_micro_features_model_data); +if (model->version() != TFLITE_SCHEMA_VERSION) { + error_reporter->Report( + "Model provided is schema version %d not equal " + "to supported version %d.\n", + model->version(), TFLITE_SCHEMA_VERSION); + return 1; +} +``` + +### 实例化操作解析器 + +解释器(interpreter)需要一个 [`AllOpsResolver`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/kernels/all_ops_resolver.h) 实例来访问 Tensorflow 操作。可以扩展此类以向您的项目添加自定义操作: + +```C++ +tflite::ops::micro::AllOpsResolver resolver; +``` + +### 分配内存 + +我们需要预先为输入、输出以及中间数组分配一定的内存。该预分配的内存是一个大小为 `tensor_arena_size` 的 `uint8_t` 数组,它被传递给 `tflite::SimpleTensorAllocator` 实例: + +```C++ +const int tensor_arena_size = 10 * 1024; +uint8_t tensor_arena[tensor_arena_size]; +tflite::SimpleTensorAllocator tensor_allocator(tensor_arena, + tensor_arena_size); +``` + +注意:所需内存大小取决于您使用的模型,可能需要通过实验来确定。 + +### 实例化解释器(Interpreter) + +我们创建一个 `tflite::MicroInterpreter` 实例,传递给之前创建的变量: + +```C++ +tflite::MicroInterpreter interpreter(model, resolver, &tensor_allocator, + error_reporter); +``` + +### 验证输入维度 + +`MicroInterpreter` 实例可以通过调用 `.input(0)` 为我们提供一个指向模型输入张量的指针,其中 `0` 代表第一个(也是唯一一个)输入张量。我们检查这个张量以确认它的维度与类型是我们所期望的: + +```C++ +TfLiteTensor* model_input = interpreter.input(0); +if ((model_input->dims->size != 4) || (model_input->dims->data[0] != 1) || + (model_input->dims->data[1] != kFeatureSliceCount) || + (model_input->dims->data[2] != kFeatureSliceSize) || + (model_input->type != kTfLiteUInt8)) { + error_reporter->Report("Bad input tensor parameters in model"); + return 1; +} +``` + +在这个代码段中,变量 `kFeatureSliceCount` 和 `kFeatureSliceSize` 与输入的属性相关,它们定义在 [`micro_model_settings.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h) 中。枚举值 `kTfLiteUInt8` 是对 Tensorflow Lite 某一数据类型的引用,它定义在 [`c_api_internal.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api_internal.h) 中。 + +### 生成特征 + +我们输入到模型中的数据必须由微控制器的音频输入生成。[`feature_provider.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_features/feature_provider.h) 中定义的 `FeatureProvider` 类捕获音频并将其转换为一组将被传入模型的特征集合。当该类被实例化时,我们用之前获取的 `TfLiteTensor` 来传入一个指向输入数组的指针。`FeatureProvider` 使用它来填充将传递给模型的输入数据: + +```C++ + FeatureProvider feature_provider(kFeatureElementCount, + model_input->data.uint8); +``` + +以下代码使 `FeatureProvider` 从最近一秒的音频生成一组特征并填充进输入张量: + +```C++ +TfLiteStatus feature_status = feature_provider.PopulateFeatureData( + error_reporter, previous_time, current_time, &how_many_new_slices); +``` + +在此例子中,特征生成和推断是在一个循环中发生的,因此设备能够不断地捕捉和处理新的音频。 + +当在编写自己的程序时,您可能会以其它的方式生成特征,但您总需要在运行模型之前就用数据填充输入张量。 + +### 运行模型 + +要运行模型,我们可以在 `tflite::MicroInterpreter` 实例上调用 `Invoke()`: + +```C++ +TfLiteStatus invoke_status = interpreter.Invoke(); +if (invoke_status != kTfLiteOk) { + error_reporter->Report("Invoke failed"); + return 1; +} +``` + +我们可以检查返回值 `TfLiteStatus` 以确定运行是否成功。在 [`c_api_internal.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api_internal.h) 中定义的 `TfLiteStatus` 的可能值有 `kTfLiteOk` 和 `kTfLiteError`。 + +### 获取输出 + +模型的输出张量可以通过在 `tflite::MicroIntepreter` 上调用 `output(0)` 获得,其中 `0` 代表第一个(也是唯一一个)输出张量。 + +在示例中,输出是一个数组,表示输入属于不同类别(“是”(yes)、“否”(no)、“未知”(unknown)以及“静默”(silence))的概率。由于它们是按照集合顺序排列的,我们可以使用简单的逻辑来确定概率最高的类别: + +```C++ + TfLiteTensor* output = interpreter.output(0); + uint8_t top_category_score = 0; + int top_category_index; + for (int category_index = 0; category_index < kCategoryCount; + ++category_index) { + const uint8_t category_score = output->data.uint8[category_index]; + if (category_score > top_category_score) { + top_category_score = category_score; + top_category_index = category_index; + } + } +``` + +在示例其他部分中,使用了一个更加复杂的算法来平滑多帧的识别结果。该部分在 [recognize_commands.h](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/recognize_commands.h) 中有所定义。在处理任何连续的数据流时,也可以使用相同的技术来提高可靠性。 \ No newline at end of file diff --git a/TensorflowLiteMicro/docs/user-guide.md b/TensorflowLiteMicro/docs/user-guide.md new file mode 100644 index 0000000..279966e --- /dev/null +++ b/TensorflowLiteMicro/docs/user-guide.md @@ -0,0 +1,239 @@ +# Tensorflow Lite Micro使用说明 + +`Tensorflow Lite Micro` 是` TensorFlow Lite `的实验性端口,专门用于在微控制器和其他只有几千字节内存的设备上运行机器学习模型。 + +它不需要操作系统支持、任何标准 C/C++ 库或动态内存分配。核心运行时在 Arm Cortex M3 上占用 16 KB 的内存,并且具有足够多的运算符来运行语音关键字检测模型,总共占用 22 KB 的内存。 + +# 建立与转换模型 + +由于嵌入式设备具有有限的 RAM 和存储空间,因此限制了深度学习模型的规模。此外,本TensorFlow Lite Micro 目前只支持有限的一部分运算,因此并非所有的模型结构都是可行的。 + +本部分将介绍由 TensorFlow 模型转换为可在嵌入式设备中上运行的过程。本部分也概述了可支持的运算,并对设计与训练一个模型以使其符合内存限制给出了一些指导。 + +## 模型转换 + +将一个已训练好的 TensorFlow 模型转换为可以在嵌入式设备中运行的Tensorflow Lite模型可以使用 [TensorFlow Lite 转换器 Python API](ModelConvert.md) 。它能够将模型转换成 [`FlatBuffer`](https://google.github.io/flatbuffers/) 格式,减小模型规模,并修改模型以使用 TensorFlow Lite 支持的运算。 + +### 量化 + +为了获得尽可能小的模型规模,你应该考虑使用[训练后量化](https://tensorflow.google.cn/lite/performance/post_training_quantization)。它会降低你模型中数字的精度,从而减小模型规模。不过,这种操作可能会导致模型推理准确性的下降,对于小规模模型来说尤为如此, 所有我们需要在量化前后分析模型的准确性变换以确保这种损失在可接受范围内。 + +以下这段 Python 代码片段展示了如何使用预训练量化进行模型转换: + +```python +import tensorflow as tf +converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) +converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE] +tflite_quant_model = converter.convert() +open("converted_model.tflite", "wb").write(tflite_quant_model) +``` + +### 转换为一个 C 数组 + +许多微控制器平台没有本地文件系统的支持。从程序中使用一个模型最简单的方式是将其以一个 C 数组的形式并将其编译进你的程序。 + +以下的 unix 命令会生成一个以 `char` 数组形式包含 TensorFlow Lite 模型的 C 源文件: + +```bash +xxd -i converted_model.tflite > model_data.cc +``` + +其输出类似如下: + +```c +unsigned char converted_model_tflite[] = { + 0x18, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x0e, 0x00, + // +}; +unsigned int converted_model_tflite_len = 18200; +``` + +在生成了此文件之后,你可以将它包含到你的程序。在嵌入式平台上,我们需要将该数组声明为 `const` 类型以获得更好的内存效率。 + +一个如何在你的程序中包含及使用模型的例子,请见微型语音示例中的 [`model.h`](tensorflow/lite/micro/examples/micro_speech/micro_features/model.h) 。 + +## 模型结构与训练 + +在设计一个面向微控制器的模型时,考虑模型的规模、工作负载,以及用到的运算是非常重要的。 + +### 模型规模 + +一个模型必须在二进制和运行时方面都足够小,以使其可以和你程序的其他部分一起符合你目标设备的内存限制。 + +为了创建一个更小的模型,你可以在你的结构里使用更少和更小的层。然而,小规模的模型更易面临欠拟合问题。这意味着对于许多问题,尝试并使用符合内存限制的尽可能大规模的模型是有意义的。但是,使用更大规模的模型也会导致处理器工作负载的增加。 + +注:在一个 Cortex M3 上,面向微控制器的 TensorFlow Lite 的核心运行时占 16 KB。 + +### 工作负载 + +工作负载受到模型规模与复杂度的影响。大规模、复杂的模型可能会导致更高的占空比,即导致你所用设备处理器的工作时间增长、空闲时间缩短。视你的应用,这种情况所带来的电力消耗与热量输出的增加可能会成为一个问题。 + +### 运算支持 + +面向微控制器的 TensorFlow Lite 目前仅支持有限的部分 TensorFlow 运算,这影响了可以运行的模型结构。我们正致力于在参考实现和针对特定结构的优化方面扩展运算支持。 + +已支持的运算可以在文件 [`all_ops_resolver.cc`](../tensorflow/lite/micro/all_ops_resolver.cc) 中看到。 + +## 运行推断 + +以下部分将介绍软件包自带语音历程中的 [main_functions.cc](../tensorflow/lite/micro/examples/micro_speech/main_functions.cc) 文件并解释了它如何使用用于微控制器的 Tensorflow Lite 来运行推断。 + +### 包含项 + +要使用库,必须包含以下头文件: + +```C++ +#include "tensorflow/lite/micro/kernels/micro_ops.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/version.h" +``` + +- [`micro_ops.h`](../tensorflow/lite/micro/kernels/micro_ops.h) 提供给解释器(interpreter)用于运行模型的操作。 +- [`micro_error_reporter.h`](../tensorflow/lite/micro/micro_error_reporter.h) 输出调试信息。 +- [`micro_interpreter.h`](../tensorflow/lite/micro/micro_interpreter.h) 包含处理和运行模型的代码。 +- [`schema_generated.h`](../tensorflow/lite/schema/schema_generated.h) 包含 TensorFlow Lite [`FlatBuffer`](https://google.github.io/flatbuffers/) 模型文件格式的模式。 +- [`version.h`](../tensorflow/lite/version.h) 提供 Tensorflow Lite 架构的版本信息。 + +示例还包括其他一些文件。以下这些是最重要的: + +```C++ +#include "tensorflow/lite/micro/examples/micro_speech/feature_provider.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/model.h" +``` + +- [`feature_provider.h`](../tensorflow/lite/micro/examples/micro_speech/feature_provider.h) 包含从音频流中提取要输入到模型中的特征的代码。 +- [`model.h`](../tensorflow/lite/micro/examples/micro_speech/micro_features/model.h) 包含存储为 `char` 数组的模型。阅读 [“构建与转换模型”](ModelConvert.md)来了解如何将 Tensorflow Lite 模型转换为该格式。 +- [`micro_model_settings.h`](../tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h) 定义与模型相关的各种常量。 + +### 设置日志记录 + +要设置日志记录,需要使用一个指向 `tflite::MicroErrorReporter` 实例的指针来创建一个 `tflite::ErrorReporter` 指针: + +```C++ +tflite::MicroErrorReporter micro_error_reporter; +tflite::ErrorReporter* error_reporter = µ_error_reporter; +``` + +该变量被传递到解释器(interpreter)中,解释器允许它写日志。由于微控制器通常具有多种日志记录机制,`tflite::MicroErrorReporter` 的实现是为您的特定设备所定制的。 + +### 加载模型 + +在以下代码中,模型是从一个 `char` 数组中实例化的,`g_tiny_conv_micro_features_model_data` (要了解其是如何构建的,请参见[“构建与转换模型”](ModelConvert.md))。 随后我们检查模型来确保其架构版本与我们使用的版本所兼容: + +```C++ +const tflite::Model* model = + ::tflite::GetModel(g_tiny_conv_micro_features_model_data); +if (model->version() != TFLITE_SCHEMA_VERSION) { + error_reporter->Report( + "Model provided is schema version %d not equal " + "to supported version %d.\n", + model->version(), TFLITE_SCHEMA_VERSION); + return 1; +} +``` + +### 实例化操作解析器 + +解释器(interpreter)需要一个 [`micro_ops`](../tensorflow/lite/micro/kernels/micro_ops.h) 实例来访问 Tensorflow 操作。可以扩展此类以向您的项目添加自定义操作: + +```C++ +tflite::ops::micro::micro_op_resolver resolver; +``` + +### 分配内存 + +我们需要预先为输入、输出以及中间数组分配一定的内存。该预分配的内存是一个大小为 `tensor_arena_size` 的 `uint8_t` 数组,它被传递给 `tflite::SimpleTensorAllocator` 实例: + +```C++ +const int tensor_arena_size = 10 * 1024; +uint8_t tensor_arena[tensor_arena_size]; +tflite::SimpleTensorAllocator tensor_allocator(tensor_arena, + tensor_arena_size); +``` + +注意:所需内存大小取决于您使用的模型,可能需要通过实验来确定。 + +### 实例化解释器(Interpreter) + +我们创建一个 `tflite::MicroInterpreter` 实例,传递给之前创建的变量: + +```C++ +tflite::MicroInterpreter interpreter(model, resolver, &tensor_allocator, + error_reporter); +``` + +### 验证输入维度 + +`MicroInterpreter` 实例可以通过调用 `.input(0)` 为我们提供一个指向模型输入张量的指针,其中 `0` 代表第一个(也是唯一一个)输入张量。我们检查这个张量以确认它的维度与类型是我们所期望的: + +```C++ +TfLiteTensor* model_input = interpreter.input(0); +if ((model_input->dims->size != 4) || (model_input->dims->data[0] != 1) || + (model_input->dims->data[1] != kFeatureSliceCount) || + (model_input->dims->data[2] != kFeatureSliceSize) || + (model_input->type != kTfLiteUInt8)) { + error_reporter->Report("Bad input tensor parameters in model"); + return 1; +} +``` + +在这个代码段中,变量 `kFeatureSliceCount` 和 `kFeatureSliceSize` 与输入的属性相关,它们定义在 [`micro_model_settings.h`](../tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h) 中。枚举值 `kTfLiteUInt8` 是对 Tensorflow Lite 某一数据类型的引用,它定义在 [`common.h`](../tenserflow/lite/c/common.h) 中。 + +### 生成特征 + +我们输入到模型中的数据必须由微控制器的音频输入生成。[`feature_provider.h`](../tensorflow/lite/micro/examples/micro_speech/feature_provider.h) 中定义的 `FeatureProvider` 类捕获音频并将其转换为一组将被传入模型的特征集合。当该类被实例化时,我们用之前获取的 `TfLiteTensor` 来传入一个指向输入数组的指针。`FeatureProvider` 使用它来填充将传递给模型的输入数据: + +```C++ + FeatureProvider feature_provider(kFeatureElementCount, + model_input->data.uint8); +``` + +以下代码使 `FeatureProvider` 从最近一秒的音频生成一组特征并填充进输入张量: + +```C++ +TfLiteStatus feature_status = feature_provider.PopulateFeatureData( + error_reporter, previous_time, current_time, &how_many_new_slices); +``` + +在此例子中,特征生成和推断是在一个循环中发生的,因此设备能够不断地捕捉和处理新的音频。 + +当在编写自己的程序时,您可能会以其它的方式生成特征,但您总需要在运行模型之前就用数据填充输入张量。 + +### 运行模型 + +要运行模型,我们可以在 `tflite::MicroInterpreter` 实例上调用 `Invoke()`: + +```C++ +TfLiteStatus invoke_status = interpreter.Invoke(); +if (invoke_status != kTfLiteOk) { + error_reporter->Report("Invoke failed"); + return 1; +} +``` + +我们可以检查返回值 `TfLiteStatus` 以确定运行是否成功。在 [`common.h`](../tenserflow/lite/c/common.h) 中定义的 `TfLiteStatus` 的可能值有 `kTfLiteOk` 和 `kTfLiteError`。 + +### 获取输出 + +模型的输出张量可以通过在 `tflite::MicroIntepreter` 上调用 `output(0)` 获得,其中 `0` 代表第一个(也是唯一一个)输出张量。 + +在示例中,输出是一个数组,表示输入属于不同类别(“是”(yes)、“否”(no)、“未知”(unknown)以及“静默”(silence))的概率。由于它们是按照集合顺序排列的,我们可以使用简单的逻辑来确定概率最高的类别: + +```C++ + TfLiteTensor* output = interpreter.output(0); + uint8_t top_category_score = 0; + int top_category_index; + for (int category_index = 0; category_index < kCategoryCount; + ++category_index) { + const uint8_t category_score = output->data.uint8[category_index]; + if (category_score > top_category_score) { + top_category_score = category_score; + top_category_index = category_index; + } + } +``` + +在示例其他部分中,使用了一个更加复杂的算法来平滑多帧的识别结果。该部分在 [recognize_commands.h](../tensorflow/lite/micro/examples/micro_speech/recognize_commands.h) 中有所定义。在处理任何连续的数据流时,也可以使用相同的技术来提高可靠性。 \ No newline at end of file diff --git a/TensorflowLiteMicro/docs/version.md b/TensorflowLiteMicro/docs/version.md new file mode 100644 index 0000000..031d2a9 --- /dev/null +++ b/TensorflowLiteMicro/docs/version.md @@ -0,0 +1,6 @@ +# 版本和修订 # + +| Date | Version | Author | Note | +| -------- | :-----: | :---- | :---- | +| 2020-09-25 | v0.1 | QingChuanWS | 初始版本 | +| 2020-10-10 | v1.0.0 | QingChuanWS | 第一版稳定版本 | \ No newline at end of file diff --git a/TensorflowLiteMicro/examples/audio_main.cc b/TensorflowLiteMicro/examples/audio_main.cc new file mode 100644 index 0000000..a77719a --- /dev/null +++ b/TensorflowLiteMicro/examples/audio_main.cc @@ -0,0 +1,33 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include +#include +#include +#include "tflite/micro/examples/micro_speech/main_functions.h" + +// This is the default main used on systems that have the standard C entry +// point. Other devices (for example FreeRTOS or ESP32) that have different +// requirements for entry code (like an app_main function) should specialize +// this main.cc file in a target-specific subfolder. +int main(int argc, char* argv[]) { + setup(); + rt_kprintf("model load successfully!!\n"); + while (true) { + loop(); + } + + return 0; +} diff --git a/TensorflowLiteMicro/tensorflow/SConscript b/TensorflowLiteMicro/tensorflow/SConscript new file mode 100644 index 0000000..4c815c4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/tensorflow/core/public/version.h b/TensorflowLiteMicro/tensorflow/core/public/version.h new file mode 100644 index 0000000..431784a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/core/public/version.h @@ -0,0 +1,139 @@ +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_CORE_PUBLIC_VERSION_H_ +#define TENSORFLOW_CORE_PUBLIC_VERSION_H_ + +// TensorFlow uses semantic versioning, see http://semver.org/. + +// Also update tensorflow/tensorflow.bzl and +// tensorflow/tools/pip_package/setup.py +#define TF_MAJOR_VERSION 2 +#define TF_MINOR_VERSION 4 +#define TF_PATCH_VERSION 0 + +// TF_VERSION_SUFFIX is non-empty for pre-releases (e.g. "-alpha", "-alpha.1", +// "-beta", "-rc", "-rc.1") +#define TF_VERSION_SUFFIX "" + +#define TF_STR_HELPER(x) #x +#define TF_STR(x) TF_STR_HELPER(x) + +// e.g. "0.5.0" or "0.6.0-alpha". +#define TF_VERSION_STRING \ + (TF_STR(TF_MAJOR_VERSION) "." TF_STR(TF_MINOR_VERSION) "." TF_STR( \ + TF_PATCH_VERSION) TF_VERSION_SUFFIX) + +// GraphDef compatibility versions (the versions field in graph.proto). +// +// Each graph has producer and min_consumer versions, and each +// consumer has its own version and a min_producer. In addition, graphs can +// mark specific consumer versions as bad (to prevent bugs from executing). +// A consumer will execute a graph if the consumer's version is at least the +// graph's min_consumer, the graph's producer version is at least the consumer's +// min_producer, and the consumer version isn't specifically disallowed by the +// graph. +// +// By default, newly created graphs have producer version TF_GRAPH_DEF_VERSION +// min_consumer TF_GRAPH_DEF_MIN_CONSUMER, and no other bad consumer versions. +// +// Version history: +// +// 0. Graphs created before GraphDef versioning +// 1. First real version (2dec2015) +// 2. adjust_contrast only takes float, doesn't perform clamping (11dec2015) +// 3. Remove TileGrad, since it was equivalent to reduce_sum (30dec2015) +// 4. When support for this version is removed, we can safely make AttrValue +// parsing more strict with respect to empty list values (see +// 111635679, 7jan2016). +// 5. Graphs are wholly-validated during Session::Create() (7jan2016). +// 6. TensorFlow is scalar strict within Google (27jan2016). +// 7. Remove TopK in favor of TopKV2 (5feb2016). +// 8. Replace RandomCrop from C++ with pure Python (5feb2016). +// 9. Deprecate batch_norm_with_global_normalization (16feb2016). +// 10. Deprecate conv3d_backprop_{filter,input} (10jun2016). +// 11. Deprecate {batch}_self_adjoint_eig (3aug2016). +// 12. Graph consumers understand the node_def field of FunctionDef (22aug2016). +// 13. Deprecate multiple batch linear algebra ops (9sep2016). +// 14. Deprecate batch_matrix_* ops. (10sep2016). +// 15. Deprecate batch_fft_* ops. (14sep2016). +// 16. Deprecate tensor_array (v1) ops in favor of v2 (10nov2016). +// 17. Deprecate inv (11nov2016). +// 17. Expose reverse_v2 (10nov2016) +// 18. Add VariableV2 (30nov2016) +// 19. Deprecated ops created by models moved out of core SkipGram, NegTrain. +// (08dec2016) +// 20. Catch all version 1.0 changes to Python API generation. SplitV is now +// used for tf.split, ReverseV2 is now used by tf.reverse, ConcatV2 is +// now used by tf.concat. Graphs use flooring +// division and mod semantics. TensorArrayV3. (12dec2016) +// Also considered the version for when it is required for reduction +// ops' indices to be scalar or vector, and not higher rank. +// Some earlier graph def versions allowed this. +// 21. Dropped FunctionDef.Node support, switched to node_def introduced +// in version 12. (11jan2017) +// 22. Placeholder now can specify and enforce scalar and partial +// shapes, particularly when restoring a graph from GraphDef +// produced at version 22 or later. (04/10/2016) +// 23. Remove NonMaxSuppression in favor of NonMaxSuppressionV2. +// 24. Deprecate lookup ops (v1) ops in favor of v2 (30may2017) +// 25. Deprecate stack (v1) ops in favor of v2 (2017/6/15). +// 25. Deprecate RandomPoisson (v1) ops in favor of v2 (2017/10/25). +// 26. Add a bool 'stripped_default_attrs' to MetaInfoDef indicating +// whether default-valued attrs have been stripped from the nodes in the +// GraphDef. (7dec2017) +// 27. Deprecate TensorArray ops v2 in favor of v3 and deprecated io_ops +// deprecated in favor of V2 ops. (2018/01/23) +// 28. Deprecate MatrixExponential op in favor of Python implementation. +// (2018/08/21). +// (2019/02/15). Added `control_ret` field to FunctionDef proto, and +// `control_output` field to OpDef proto. +// 29. Deprecate StatefulStandardNormal op in favor of StatefulStandardNormalV2. +// (2019/03/25). +// (2019/04/17). Added `arg_attr` field to FunctionDefProto. +// 30. (2019/05/09) First date based GraphDef version. GraphDef +// versions advance by 1 each day after this point. + +#define TF_GRAPH_DEF_VERSION_MIN_PRODUCER 0 +#define TF_GRAPH_DEF_VERSION_MIN_CONSUMER 0 +#define TF_GRAPH_DEF_VERSION 485 // Updated: 2020/8/6 + +// Checkpoint compatibility versions (the versions field in SavedSliceMeta). +// +// The checkpoint versions have the same semantics as GraphDef versions, but the +// numbering scheme is separate. We have no plans to ever deprecate checkpoint +// versions, but it's good to have this in place in case we ever need to. +// +// Version history: +// +// 0. Checkpoints saved before checkpoint versioning. +// 1. First real version (10feb2015). +#define TF_CHECKPOINT_VERSION_MIN_PRODUCER 0 +#define TF_CHECKPOINT_VERSION_MIN_CONSUMER 0 +#define TF_CHECKPOINT_VERSION 1 + +/// Version query functions (defined in generated version_info.cc) + +// Host compiler version (declared elsewhere to be __VERSION__) +extern const char* tf_compiler_version(); +// The git commit designator when tensorflow was built +// If no git repository, this will be "internal". +extern const char* tf_git_version(); +// Value of the _GLIBCXX_USE_CXX11_ABI flag, or 0 if it's not set. +extern int tf_cxx11_abi_flag(); +// Returns 1 if build is monolithic, or 0 otherwise. +extern int tf_monolithic_build(); + +#endif // TENSORFLOW_CORE_PUBLIC_VERSION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/SConscript b/TensorflowLiteMicro/tensorflow/lite/SConscript new file mode 100644 index 0000000..4c815c4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/tensorflow/lite/c/SConscript b/TensorflowLiteMicro/tensorflow/lite/c/SConscript new file mode 100644 index 0000000..85a4112 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/c/SConscript @@ -0,0 +1,31 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cc') + +#. +root = str(Dir('#')) + +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break + +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") + + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy] + +group = DefineGroup('lite/c', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/tensorflow/lite/c/builtin_op_data.h b/TensorflowLiteMicro/tensorflow/lite/c/builtin_op_data.h new file mode 100644 index 0000000..e205f07 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/c/builtin_op_data.h @@ -0,0 +1,472 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_ +#define TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_ + +#include + +#include "tensorflow/lite/c/common.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// TfLiteReshapeParams can't have dynamic data so we fix the maximum possible +// number of dimensions. +#define TFLITE_RESHAPE_PARAMS_MAX_DIMENSION_COUNT 8 + +// TODO(aselle): Consider using "if this then that" for testing. + +// Useful placeholder to put in otherwise empty structs to avoid size warnings. +typedef struct { + char dummy; +} EmptyStructPlaceholder; + +// IMPORTANT: All new members of structs must be added at the end to ensure +// backwards compatibility. + +// Possible padding types (for convolutions) +typedef enum { + kTfLitePaddingUnknown = 0, + kTfLitePaddingSame, + kTfLitePaddingValid, +} TfLitePadding; + +typedef enum { + kTfLiteMirrorPaddingUnknown = 0, + kTfLiteMirrorPaddingReflect, + kTfLiteMirrorPaddingSymmetric, +} TfLiteMirrorPaddingMode; + +// TODO(b/130259536): We should move this out of builtin_op_data. +typedef struct { + int width; + int height; + int width_offset; + int height_offset; +} TfLitePaddingValues; + +typedef struct { + TfLiteMirrorPaddingMode mode; +} TfLiteMirrorPaddingParams; + +// Possible fused activation functions. +// TODO(aselle): rename to TfLiteActivation +typedef enum { + kTfLiteActNone = 0, + kTfLiteActRelu, + kTfLiteActReluN1To1, // min(max(-1, x), 1) + kTfLiteActRelu1 = kTfLiteActReluN1To1, // kTfLiteActRelu1 will be deprecated. + kTfLiteActRelu6, // min(max(0, x), 6) + kTfLiteActTanh, + kTfLiteActSignBit, + kTfLiteActSigmoid, +} TfLiteFusedActivation; + +typedef struct { + // Parameters for CONV_2D version 1. + TfLitePadding padding; + int stride_width; + int stride_height; + TfLiteFusedActivation activation; + + // Parameters for CONV_2D version 2. + // Note: Version 2 supports dilation values not equal to 1. + int dilation_width_factor; + int dilation_height_factor; +} TfLiteConvParams; + +typedef struct { + TfLitePadding padding; + int stride_width; + int stride_height; + int filter_width; + int filter_height; + TfLiteFusedActivation activation; + struct { + TfLitePaddingValues padding; + } computed; +} TfLitePoolParams; + +typedef struct { + // Parameters for DepthwiseConv version 1 or above. + TfLitePadding padding; + int stride_width; + int stride_height; + // `depth_multiplier` is redundant. It's used by CPU kernels in + // TensorFlow 2.0 or below, but ignored in versions above. + // + // The information can be deduced from the shape of input and the shape of + // weights. Since the TFLiteConverter toolchain doesn't support partially + // specified shapes, relying on `depth_multiplier` stops us from supporting + // graphs with dynamic shape tensors. + // + // Note: Some of the delegates (e.g. NNAPI, GPU) are still relying on this + // field. + int depth_multiplier; + TfLiteFusedActivation activation; + // Parameters for DepthwiseConv version 2 or above. + int dilation_width_factor; + int dilation_height_factor; +} TfLiteDepthwiseConvParams; + +typedef struct { + int rank; + TfLiteFusedActivation activation; + + // Parameter for SVDF version 4. + bool asymmetric_quantize_inputs; +} TfLiteSVDFParams; + +typedef struct { + TfLiteFusedActivation activation; + + // Parameter for RNN version 3. + bool asymmetric_quantize_inputs; +} TfLiteRNNParams; + +typedef struct { + bool time_major; + TfLiteFusedActivation activation; + + // Parameter for Sequence RNN version 3. + bool asymmetric_quantize_inputs; +} TfLiteSequenceRNNParams; + +typedef struct { + bool time_major; + TfLiteFusedActivation activation; + bool merge_outputs; + + // Parameter for Bidirectional RNN verison 3. + bool asymmetric_quantize_inputs; +} TfLiteBidirectionalSequenceRNNParams; + +typedef enum { + kTfLiteFullyConnectedWeightsFormatDefault = 0, + kTfLiteFullyConnectedWeightsFormatShuffled4x16Int8 = 1, +} TfLiteFullyConnectedWeightsFormat; + +typedef struct { + // Parameters for FullyConnected version 1 or above. + TfLiteFusedActivation activation; + + // Parameters for FullyConnected version 2 or above. + TfLiteFullyConnectedWeightsFormat weights_format; + + // Parameters for FullyConnected version 5 or above. + // If set to true, then the number of dimensions in the input and the output + // tensors are the same. Furthermore, all but the last dimension of the input + // and output shapes will be equal. + bool keep_num_dims; + + // Parameters for FullyConnected version 7 or above. + // If set to true and the weights are quantized, then non constant inputs + // are quantized at evaluation time with asymmetric quantization. + bool asymmetric_quantize_inputs; +} TfLiteFullyConnectedParams; + +typedef enum { + kTfLiteLshProjectionUnknown = 0, + kTfLiteLshProjectionSparse = 1, + kTfLiteLshProjectionDense = 2, +} TfLiteLSHProjectionType; + +typedef struct { + TfLiteLSHProjectionType type; +} TfLiteLSHProjectionParams; + +typedef struct { + float beta; +} TfLiteSoftmaxParams; + +typedef struct { + int axis; + TfLiteFusedActivation activation; +} TfLiteConcatenationParams; + +typedef struct { + TfLiteFusedActivation activation; + // Parameter added for the version 4. + bool pot_scale_int16; +} TfLiteAddParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteSpaceToBatchNDParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteBatchToSpaceNDParams; + +typedef struct { + bool adj_x; + bool adj_y; +} TfLiteBatchMatMulParams; + +typedef struct { + TfLiteFusedActivation activation; +} TfLiteMulParams; + +typedef struct { + TfLiteFusedActivation activation; + // Parameter added for the version 5. + bool pot_scale_int16; +} TfLiteSubParams; + +typedef struct { + TfLiteFusedActivation activation; +} TfLiteDivParams; + +typedef struct { + TfLiteFusedActivation activation; +} TfLiteL2NormParams; + +typedef struct { + int radius; + float bias; + float alpha; + float beta; +} TfLiteLocalResponseNormParams; + +typedef enum { + kTfLiteLSTMFullKernel = 0, + kTfLiteLSTMBasicKernel +} TfLiteLSTMKernelType; + +typedef struct { + // Parameters for LSTM version 1. + TfLiteFusedActivation activation; + float cell_clip; + float proj_clip; + + // Parameters for LSTM version 2. + // kTfLiteLSTMBasicKernel is only supported in version 2 or above. + TfLiteLSTMKernelType kernel_type; + + // Parameters for LSTM version 4. + bool asymmetric_quantize_inputs; +} TfLiteLSTMParams; + +typedef struct { + // Parameters needed for the underlying LSTM. + TfLiteFusedActivation activation; + float cell_clip; + float proj_clip; + + // If set to true then the first dimension is time, otherwise batch. + bool time_major; + + // Parameter for unidirectional sequence RNN version 3. + bool asymmetric_quantize_inputs; +} TfLiteUnidirectionalSequenceLSTMParams; + +typedef struct { + // Parameters supported by version 1: + // Parameters inherited for the LSTM kernel. + TfLiteFusedActivation activation; + float cell_clip; + float proj_clip; + + // If true, store the outputs of both directions in the first output. + bool merge_outputs; + + // Parameters supported by version 2: + // If set to true then the first dimension is time, otherwise batch. + bool time_major; + + // Parameters supported by version 4: + // If set to true, then hybrid ops use asymmetric quantization for inputs. + bool asymmetric_quantize_inputs; +} TfLiteBidirectionalSequenceLSTMParams; + +typedef struct { + bool align_corners; + // half_pixel_centers assumes pixels are of half the actual dimensions, and + // yields more accurate resizes. Corresponds to the same argument for the + // original TensorFlow op in TF2.0. + bool half_pixel_centers; +} TfLiteResizeBilinearParams; + +typedef struct { + bool align_corners; + bool half_pixel_centers; +} TfLiteResizeNearestNeighborParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLitePadParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLitePadV2Params; + +typedef struct { + // TODO(ahentz): We can't have dynamic data in this struct, at least not yet. + // For now we will fix the maximum possible number of dimensions. + int shape[TFLITE_RESHAPE_PARAMS_MAX_DIMENSION_COUNT]; + int num_dimensions; +} TfLiteReshapeParams; + +typedef struct { + int ngram_size; + int max_skip_size; + bool include_all_ngrams; +} TfLiteSkipGramParams; + +typedef struct { + int block_size; +} TfLiteSpaceToDepthParams; + +typedef struct { + int block_size; +} TfLiteDepthToSpaceParams; + +typedef struct { + TfLiteType in_data_type; + TfLiteType out_data_type; +} TfLiteCastParams; + +typedef enum { + kTfLiteCombinerTypeSum = 0, + kTfLiteCombinerTypeMean = 1, + kTfLiteCombinerTypeSqrtn = 2, +} TfLiteCombinerType; + +typedef struct { + TfLiteCombinerType combiner; +} TfLiteEmbeddingLookupSparseParams; + +typedef struct { + int axis; +} TfLiteGatherParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteTransposeParams; + +typedef struct { + bool keep_dims; +} TfLiteReducerParams; + +typedef struct { + int num_splits; +} TfLiteSplitParams; + +typedef struct { + int num_splits; +} TfLiteSplitVParams; + +typedef struct { + // TODO(ahentz): We can't have dynamic data in this struct, at least not yet. + // For now we will fix the maximum possible number of dimensions. + int squeeze_dims[8]; + int num_squeeze_dims; +} TfLiteSqueezeParams; + +typedef struct { + int begin_mask; + int end_mask; + int ellipsis_mask; + int new_axis_mask; + int shrink_axis_mask; +} TfLiteStridedSliceParams; + +typedef struct { + TfLiteType output_type; +} TfLiteArgMaxParams; + +typedef struct { + TfLiteType output_type; +} TfLiteArgMinParams; + +typedef struct { + TfLitePadding padding; + int stride_width; + int stride_height; +} TfLiteTransposeConvParams; + +typedef struct { + bool validate_indices; +} TfLiteSparseToDenseParams; + +typedef struct { + TfLiteType out_type; +} TfLiteShapeParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteRankParams; + +typedef struct { + // Parameters supported by version 1: + float min; + float max; + int num_bits; + + // Parameters supported by version 2: + bool narrow_range; +} TfLiteFakeQuantParams; + +typedef struct { + int values_count; + int axis; +} TfLitePackParams; + +typedef struct { + int axis; +} TfLiteOneHotParams; + +typedef struct { + int num; + int axis; +} TfLiteUnpackParams; + +typedef struct { + float alpha; +} TfLiteLeakyReluParams; + +typedef struct { + TfLiteType index_out_type; +} TfLiteUniqueParams; + +typedef struct { + int seq_dim; + int batch_dim; +} TfLiteReverseSequenceParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteMatrixDiagParams; + +typedef struct { + EmptyStructPlaceholder placeholder; +} TfLiteMatrixSetDiagParams; + +typedef struct { + int then_subgraph_index; + int else_subgraph_index; +} TfLiteIfParams; + +typedef struct { + int cond_subgraph_index; + int body_subgraph_index; +} TfLiteWhileParams; + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/c/common.c b/TensorflowLiteMicro/tensorflow/lite/c/common.c new file mode 100644 index 0000000..0264f42 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/c/common.c @@ -0,0 +1,232 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/common.h" +#ifndef TF_LITE_STATIC_MEMORY +#include +#include +#endif // TF_LITE_STATIC_MEMORY + +int TfLiteIntArrayGetSizeInBytes(int size) { + static TfLiteIntArray dummy; + return sizeof(dummy) + sizeof(dummy.data[0]) * size; +} + +int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b) { + if (a == b) return 1; + if (a == NULL || b == NULL) return 0; + return TfLiteIntArrayEqualsArray(a, b->size, b->data); +} + +int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size, + const int b_data[]) { + if (a == NULL) return (b_size == 0); + if (a->size != b_size) return 0; + int i = 0; + for (; i < a->size; i++) + if (a->data[i] != b_data[i]) return 0; + return 1; +} + +#ifndef TF_LITE_STATIC_MEMORY + +TfLiteIntArray* TfLiteIntArrayCreate(int size) { + TfLiteIntArray* ret = + (TfLiteIntArray*)malloc(TfLiteIntArrayGetSizeInBytes(size)); + ret->size = size; + return ret; +} + +TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src) { + if (!src) return NULL; + TfLiteIntArray* ret = TfLiteIntArrayCreate(src->size); + if (ret) { + memcpy(ret->data, src->data, src->size * sizeof(int)); + } + return ret; +} + +void TfLiteIntArrayFree(TfLiteIntArray* a) { free(a); } + +#endif // TF_LITE_STATIC_MEMORY + +int TfLiteFloatArrayGetSizeInBytes(int size) { + static TfLiteFloatArray dummy; + return sizeof(dummy) + sizeof(dummy.data[0]) * size; +} + +#ifndef TF_LITE_STATIC_MEMORY + +TfLiteFloatArray* TfLiteFloatArrayCreate(int size) { + TfLiteFloatArray* ret = + (TfLiteFloatArray*)malloc(TfLiteFloatArrayGetSizeInBytes(size)); + ret->size = size; + return ret; +} + +void TfLiteFloatArrayFree(TfLiteFloatArray* a) { free(a); } + +void TfLiteTensorDataFree(TfLiteTensor* t) { + if (t->allocation_type == kTfLiteDynamic || + t->allocation_type == kTfLitePersistentRo) { + free(t->data.raw); + } + t->data.raw = NULL; +} + +void TfLiteQuantizationFree(TfLiteQuantization* quantization) { + if (quantization->type == kTfLiteAffineQuantization) { + TfLiteAffineQuantization* q_params = + (TfLiteAffineQuantization*)(quantization->params); + if (q_params->scale) { + TfLiteFloatArrayFree(q_params->scale); + q_params->scale = NULL; + } + if (q_params->zero_point) { + TfLiteIntArrayFree(q_params->zero_point); + q_params->zero_point = NULL; + } + free(q_params); + } + quantization->params = NULL; + quantization->type = kTfLiteNoQuantization; +} + +void TfLiteSparsityFree(TfLiteSparsity* sparsity) { + if (sparsity == NULL) { + return; + } + + if (sparsity->traversal_order) { + TfLiteIntArrayFree(sparsity->traversal_order); + sparsity->traversal_order = NULL; + } + + if (sparsity->block_map) { + TfLiteIntArrayFree(sparsity->block_map); + sparsity->block_map = NULL; + } + + if (sparsity->dim_metadata) { + int i = 0; + for (; i < sparsity->dim_metadata_size; i++) { + TfLiteDimensionMetadata metadata = sparsity->dim_metadata[i]; + if (metadata.format == kTfLiteDimSparseCSR) { + TfLiteIntArrayFree(metadata.array_segments); + metadata.array_segments = NULL; + TfLiteIntArrayFree(metadata.array_indices); + metadata.array_indices = NULL; + } + } + free(sparsity->dim_metadata); + sparsity->dim_metadata = NULL; + } + + free(sparsity); +} + +void TfLiteTensorFree(TfLiteTensor* t) { + TfLiteTensorDataFree(t); + if (t->dims) TfLiteIntArrayFree(t->dims); + t->dims = NULL; + + if (t->dims_signature) { + TfLiteIntArrayFree((TfLiteIntArray *) t->dims_signature); + } + t->dims_signature = NULL; + + TfLiteQuantizationFree(&t->quantization); + TfLiteSparsityFree(t->sparsity); + t->sparsity = NULL; +} + +void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims, + TfLiteQuantizationParams quantization, char* buffer, + size_t size, TfLiteAllocationType allocation_type, + const void* allocation, bool is_variable, + TfLiteTensor* tensor) { + TfLiteTensorFree(tensor); + tensor->type = type; + tensor->name = name; + tensor->dims = dims; + tensor->params = quantization; + tensor->data.raw = buffer; + tensor->bytes = size; + tensor->allocation_type = allocation_type; + tensor->allocation = allocation; + tensor->is_variable = is_variable; + + tensor->quantization.type = kTfLiteNoQuantization; + tensor->quantization.params = NULL; +} + +void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor) { + if (tensor->allocation_type != kTfLiteDynamic && + tensor->allocation_type != kTfLitePersistentRo) { + return; + } + // TODO(b/145340303): Tensor data should be aligned. + if (!tensor->data.raw) { + tensor->data.raw = malloc(num_bytes); + } else if (num_bytes > tensor->bytes) { + tensor->data.raw = realloc(tensor->data.raw, num_bytes); + } + tensor->bytes = num_bytes; +} +#endif // TF_LITE_STATIC_MEMORY + +const char* TfLiteTypeGetName(TfLiteType type) { + switch (type) { + case kTfLiteNoType: + return "NOTYPE"; + case kTfLiteFloat32: + return "FLOAT32"; + case kTfLiteInt16: + return "INT16"; + case kTfLiteInt32: + return "INT32"; + case kTfLiteUInt8: + return "UINT8"; + case kTfLiteInt8: + return "INT8"; + case kTfLiteInt64: + return "INT64"; + case kTfLiteBool: + return "BOOL"; + case kTfLiteComplex64: + return "COMPLEX64"; + case kTfLiteComplex128: + return "COMPLEX128"; + case kTfLiteString: + return "STRING"; + case kTfLiteFloat16: + return "FLOAT16"; + case kTfLiteFloat64: + return "FLOAT64"; + } + return "Unknown type"; +} + +TfLiteDelegate TfLiteDelegateCreate() { + TfLiteDelegate d = { + .data_ = NULL, + .Prepare = NULL, + .CopyFromBufferHandle = NULL, + .CopyToBufferHandle = NULL, + .FreeBufferHandle = NULL, + .flags = kTfLiteDelegateFlagsNone, + }; + return d; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/c/common.h b/TensorflowLiteMicro/tensorflow/lite/c/common.h new file mode 100644 index 0000000..7ef173c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/c/common.h @@ -0,0 +1,936 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This file defines common C types and APIs for implementing operations, +// delegates and other constructs in TensorFlow Lite. The actual operations and +// delegates can be defined using C++, but the interface between the interpreter +// and the operations are C. +// +// Summary of abstractions +// TF_LITE_ENSURE - Self-sufficient error checking +// TfLiteStatus - Status reporting +// TfLiteIntArray - stores tensor shapes (dims), +// TfLiteContext - allows an op to access the tensors +// TfLiteTensor - tensor (a multidimensional array) +// TfLiteNode - a single node or operation +// TfLiteRegistration - the implementation of a conceptual operation. +// TfLiteDelegate - allows delegation of nodes to alternative backends. +// +// Some abstractions in this file are created and managed by Interpreter. +// +// NOTE: The order of values in these structs are "semi-ABI stable". New values +// should be added only to the end of structs and never reordered. + +#ifndef TENSORFLOW_LITE_C_COMMON_H_ +#define TENSORFLOW_LITE_C_COMMON_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum TfLiteStatus { + kTfLiteOk = 0, + kTfLiteError = 1, + kTfLiteDelegateError = 2 +} TfLiteStatus; + +// The list of external context types known to TF Lite. This list exists solely +// to avoid conflicts and to ensure ops can share the external contexts they +// need. Access to the external contexts is controlled by one of the +// corresponding support files. +typedef enum TfLiteExternalContextType { + kTfLiteEigenContext = 0, // include eigen_support.h to use. + kTfLiteGemmLowpContext = 1, // include gemm_support.h to use. + kTfLiteEdgeTpuContext = 2, // Placeholder for Edge TPU support. + kTfLiteCpuBackendContext = 3, // include cpu_backend_context.h to use. + kTfLiteMaxExternalContexts = 4 +} TfLiteExternalContextType; + +// Forward declare so dependent structs and methods can reference these types +// prior to the struct definitions. +struct TfLiteContext; +struct TfLiteDelegate; +struct TfLiteRegistration; + +// An external context is a collection of information unrelated to the TF Lite +// framework, but useful to a subset of the ops. TF Lite knows very little +// about about the actual contexts, but it keeps a list of them, and is able to +// refresh them if configurations like the number of recommended threads +// change. +typedef struct TfLiteExternalContext { + TfLiteExternalContextType type; + TfLiteStatus (*Refresh)(struct TfLiteContext* context); +} TfLiteExternalContext; + +#define kTfLiteOptionalTensor (-1) + +// Fixed size list of integers. Used for dimensions and inputs/outputs tensor +// indices +typedef struct TfLiteIntArray { + int size; +// gcc 6.1+ have a bug where flexible members aren't properly handled +// https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \ + __GNUC_MINOR__ >= 1) || \ + defined(HEXAGON) + int data[0]; +#else + int data[]; +#endif +} TfLiteIntArray; + +// Given the size (number of elements) in a TfLiteIntArray, calculate its size +// in bytes. +int TfLiteIntArrayGetSizeInBytes(int size); + +#ifndef TF_LITE_STATIC_MEMORY +// Create a array of a given `size` (uninitialized entries). +// This returns a pointer, that you must free using TfLiteIntArrayFree(). +TfLiteIntArray* TfLiteIntArrayCreate(int size); +#endif + +// Check if two intarrays are equal. Returns 1 if they are equal, 0 otherwise. +int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b); + +// Check if an intarray equals an array. Returns 1 if equals, 0 otherwise. +int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size, + const int b_data[]); + +#ifndef TF_LITE_STATIC_MEMORY +// Create a copy of an array passed as `src`. +// You are expected to free memory with TfLiteIntArrayFree +TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src); + +// Free memory of array `a`. +void TfLiteIntArrayFree(TfLiteIntArray* a); +#endif // TF_LITE_STATIC_MEMORY + +// Fixed size list of floats. Used for per-channel quantization. +typedef struct TfLiteFloatArray { + int size; +// gcc 6.1+ have a bug where flexible members aren't properly handled +// https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c +// This also applies to the toolchain used for Qualcomm Hexagon DSPs. +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \ + __GNUC_MINOR__ >= 1 + float data[0]; +#else + float data[]; +#endif +} TfLiteFloatArray; + +// Given the size (number of elements) in a TfLiteFloatArray, calculate its size +// in bytes. +int TfLiteFloatArrayGetSizeInBytes(int size); + +#ifndef TF_LITE_STATIC_MEMORY +// Create a array of a given `size` (uninitialized entries). +// This returns a pointer, that you must free using TfLiteFloatArrayFree(). +TfLiteFloatArray* TfLiteFloatArrayCreate(int size); + +// Free memory of array `a`. +void TfLiteFloatArrayFree(TfLiteFloatArray* a); +#endif // TF_LITE_STATIC_MEMORY + +// Since we must not depend on any libraries, define a minimal subset of +// error macros while avoiding names that have pre-conceived meanings like +// assert and check. + +// Try to make all reporting calls through TF_LITE_KERNEL_LOG rather than +// calling the context->ReportError function directly, so that message strings +// can be stripped out if the binary size needs to be severely optimized. +#ifndef TF_LITE_STRIP_ERROR_STRINGS +#define TF_LITE_KERNEL_LOG(context, ...) \ + do { \ + (context)->ReportError((context), __VA_ARGS__); \ + } while (false) + +#define TF_LITE_MAYBE_KERNEL_LOG(context, ...) \ + do { \ + if ((context) != nullptr) { \ + (context)->ReportError((context), __VA_ARGS__); \ + } \ + } while (false) +#else // TF_LITE_STRIP_ERROR_STRINGS +#define TF_LITE_KERNEL_LOG(context, ...) +#define TF_LITE_MAYBE_KERNEL_LOG(context, ...) +#endif // TF_LITE_STRIP_ERROR_STRINGS + +// Check whether value is true, and if not return kTfLiteError from +// the current function (and report the error string msg). +#define TF_LITE_ENSURE_MSG(context, value, msg) \ + do { \ + if (!(value)) { \ + TF_LITE_KERNEL_LOG((context), __FILE__ " " msg); \ + return kTfLiteError; \ + } \ + } while (0) + +// Check whether the value `a` is true, and if not return kTfLiteError from +// the current function, while also reporting the location of the error. +#define TF_LITE_ENSURE(context, a) \ + do { \ + if (!(a)) { \ + TF_LITE_KERNEL_LOG((context), "%s:%d %s was not true.", __FILE__, \ + __LINE__, #a); \ + return kTfLiteError; \ + } \ + } while (0) + +#define TF_LITE_ENSURE_STATUS(a) \ + do { \ + const TfLiteStatus s = (a); \ + if (s != kTfLiteOk) { \ + return s; \ + } \ + } while (0) + +// Check whether the value `a == b` is true, and if not return kTfLiteError from +// the current function, while also reporting the location of the error. +// `a` and `b` may be evaluated more than once, so no side effects or +// extremely expensive computations should be done. +// NOTE: Use TF_LITE_ENSURE_TYPES_EQ if comparing TfLiteTypes. +#define TF_LITE_ENSURE_EQ(context, a, b) \ + do { \ + if ((a) != (b)) { \ + TF_LITE_KERNEL_LOG((context), "%s:%d %s != %s (%d != %d)", __FILE__, \ + __LINE__, #a, #b, (a), (b)); \ + return kTfLiteError; \ + } \ + } while (0) + +#define TF_LITE_ENSURE_TYPES_EQ(context, a, b) \ + do { \ + if ((a) != (b)) { \ + TF_LITE_KERNEL_LOG((context), "%s:%d %s != %s (%s != %s)", __FILE__, \ + __LINE__, #a, #b, TfLiteTypeGetName(a), \ + TfLiteTypeGetName(b)); \ + return kTfLiteError; \ + } \ + } while (0) + +#define TF_LITE_ENSURE_OK(context, status) \ + do { \ + const TfLiteStatus s = (status); \ + if ((s) != kTfLiteOk) { \ + return s; \ + } \ + } while (0) + +// Define TFL_CAPI_EXPORT macro to export a function properly with a shared +// library. +#ifdef SWIG +#define TFL_CAPI_EXPORT +#else +#if defined(_WIN32) +#ifdef TFL_COMPILE_LIBRARY +#define TFL_CAPI_EXPORT __declspec(dllexport) +#else +#define TFL_CAPI_EXPORT __declspec(dllimport) +#endif // TFL_COMPILE_LIBRARY +#else +#define TFL_CAPI_EXPORT __attribute__((visibility("default"))) +#endif // _WIN32 +#endif // SWIG + +// Single-precision complex data type compatible with the C99 definition. +typedef struct TfLiteComplex64 { + float re, im; // real and imaginary parts, respectively. +} TfLiteComplex64; + +// Double-precision complex data type compatible with the C99 definition. +typedef struct TfLiteComplex128 { + double re, im; // real and imaginary parts, respectively. +} TfLiteComplex128; + +// Half precision data type compatible with the C99 definition. +typedef struct TfLiteFloat16 { + uint16_t data; +} TfLiteFloat16; + +// Types supported by tensor +typedef enum { + kTfLiteNoType = 0, + kTfLiteFloat32 = 1, + kTfLiteInt32 = 2, + kTfLiteUInt8 = 3, + kTfLiteInt64 = 4, + kTfLiteString = 5, + kTfLiteBool = 6, + kTfLiteInt16 = 7, + kTfLiteComplex64 = 8, + kTfLiteInt8 = 9, + kTfLiteFloat16 = 10, + kTfLiteFloat64 = 11, + kTfLiteComplex128 = 12, +} TfLiteType; + +// Return the name of a given type, for error reporting purposes. +const char* TfLiteTypeGetName(TfLiteType type); + +// SupportedQuantizationTypes. +typedef enum TfLiteQuantizationType { + // No quantization. + kTfLiteNoQuantization = 0, + // Affine quantization (with support for per-channel quantization). + // Corresponds to TfLiteAffineQuantization. + kTfLiteAffineQuantization = 1, +} TfLiteQuantizationType; + +// Structure specifying the quantization used by the tensor, if-any. +typedef struct TfLiteQuantization { + // The type of quantization held by params. + TfLiteQuantizationType type; + // Holds a reference to one of the quantization param structures specified + // below. + void* params; +} TfLiteQuantization; + +// Legacy. Will be deprecated in favor of TfLiteAffineQuantization. +// If per-layer quantization is specified this field will still be populated in +// addition to TfLiteAffineQuantization. +// Parameters for asymmetric quantization. Quantized values can be converted +// back to float using: +// real_value = scale * (quantized_value - zero_point) +typedef struct TfLiteQuantizationParams { + float scale; + int32_t zero_point; +} TfLiteQuantizationParams; + +// Parameters for asymmetric quantization across a dimension (i.e per output +// channel quantization). +// quantized_dimension specifies which dimension the scales and zero_points +// correspond to. +// For a particular value in quantized_dimension, quantized values can be +// converted back to float using: +// real_value = scale * (quantized_value - zero_point) +typedef struct TfLiteAffineQuantization { + TfLiteFloatArray* scale; + TfLiteIntArray* zero_point; + int32_t quantized_dimension; +} TfLiteAffineQuantization; + +/* A union of pointers that points to memory for a given tensor. */ +typedef union TfLitePtrUnion { + /* Do not access these members directly, if possible, use + * GetTensorData(tensor) instead, otherwise only access .data, as other + * members are deprecated. */ + int32_t* i32; + int64_t* i64; + float* f; + TfLiteFloat16* f16; + double* f64; + char* raw; + const char* raw_const; + uint8_t* uint8; + bool* b; + int16_t* i16; + TfLiteComplex64* c64; + TfLiteComplex128* c128; + int8_t* int8; + /* Only use this member. */ + void* data; +} TfLitePtrUnion; + +// Memory allocation strategies. +// * kTfLiteMmapRo: Read-only memory-mapped data, or data externally allocated. +// * kTfLiteArenaRw: Arena allocated with no guarantees about persistence, +// and available during eval. +// * kTfLiteArenaRwPersistent: Arena allocated but persistent across eval, and +// only available during eval. +// * kTfLiteDynamic: Allocated during eval, or for string tensors. +// * kTfLitePersistentRo: Allocated and populated during prepare. This is +// useful for tensors that can be computed during prepare and treated +// as constant inputs for downstream ops (also in prepare). +typedef enum TfLiteAllocationType { + kTfLiteMemNone = 0, + kTfLiteMmapRo, + kTfLiteArenaRw, + kTfLiteArenaRwPersistent, + kTfLiteDynamic, + kTfLitePersistentRo, +} TfLiteAllocationType; + +// The delegates should use zero or positive integers to represent handles. +// -1 is reserved from unallocated status. +typedef int TfLiteBufferHandle; +enum { + kTfLiteNullBufferHandle = -1, +}; + +// Storage format of each dimension in a sparse tensor. +typedef enum TfLiteDimensionType { + kTfLiteDimDense = 0, + kTfLiteDimSparseCSR, +} TfLiteDimensionType; + +// Metadata to encode each dimension in a sparse tensor. +typedef struct TfLiteDimensionMetadata { + TfLiteDimensionType format; + int dense_size; + TfLiteIntArray* array_segments; + TfLiteIntArray* array_indices; +} TfLiteDimensionMetadata; + +// Parameters used to encode a sparse tensor. For detailed explanation of each +// field please refer to lite/schema/schema.fbs. +typedef struct TfLiteSparsity { + TfLiteIntArray* traversal_order; + TfLiteIntArray* block_map; + TfLiteDimensionMetadata* dim_metadata; + int dim_metadata_size; +} TfLiteSparsity; + +// An tensor in the interpreter system which is a wrapper around a buffer of +// data including a dimensionality (or NULL if not currently defined). +#ifndef TF_LITE_STATIC_MEMORY +typedef struct TfLiteTensor { + // The data type specification for data stored in `data`. This affects + // what member of `data` union should be used. + TfLiteType type; + // A union of data pointers. The appropriate type should be used for a typed + // tensor based on `type`. + TfLitePtrUnion data; + // A pointer to a structure representing the dimensionality interpretation + // that the buffer should have. NOTE: the product of elements of `dims` + // and the element datatype size should be equal to `bytes` below. + TfLiteIntArray* dims; + // Quantization information. + TfLiteQuantizationParams params; + // How memory is mapped + // kTfLiteMmapRo: Memory mapped read only. + // i.e. weights + // kTfLiteArenaRw: Arena allocated read write memory + // (i.e. temporaries, outputs). + TfLiteAllocationType allocation_type; + // The number of bytes required to store the data of this Tensor. I.e. + // (bytes of each element) * dims[0] * ... * dims[n-1]. For example, if + // type is kTfLiteFloat32 and dims = {3, 2} then + // bytes = sizeof(float) * 3 * 2 = 4 * 3 * 2 = 24. + size_t bytes; + + // An opaque pointer to a tflite::MMapAllocation + const void* allocation; + + // Null-terminated name of this tensor. + const char* name; + + // The delegate which knows how to handle `buffer_handle`. + // WARNING: This is an experimental interface that is subject to change. + struct TfLiteDelegate* delegate; + + // An integer buffer handle that can be handled by `delegate`. + // The value is valid only when delegate is not null. + // WARNING: This is an experimental interface that is subject to change. + TfLiteBufferHandle buffer_handle; + + // If the delegate uses its own buffer (e.g. GPU memory), the delegate is + // responsible to set data_is_stale to true. + // `delegate->CopyFromBufferHandle` can be called to copy the data from + // delegate buffer. + // WARNING: This is an // experimental interface that is subject to change. + bool data_is_stale; + + // True if the tensor is a variable. + bool is_variable; + + // Quantization information. Replaces params field above. + TfLiteQuantization quantization; + + // Parameters used to encode a sparse tensor. + // This is optional. The field is NULL if a tensor is dense. + // WARNING: This is an experimental interface that is subject to change. + TfLiteSparsity* sparsity; + + // Optional. Encodes shapes with unknown dimensions with -1. This field is + // only populated when unknown dimensions exist in a read-write tensor (i.e. + // an input or output tensor). (e.g. `dims` contains [1, 1, 1, 3] and + // `dims_signature` contains [1, -1, -1, 3]). + const TfLiteIntArray* dims_signature; +} TfLiteTensor; + +// A structure representing an instance of a node. +// This structure only exhibits the inputs, outputs and user defined data, not +// other features like the type. +typedef struct TfLiteNode { + // Inputs to this node expressed as indices into the simulator's tensors. + TfLiteIntArray* inputs; + + // Outputs to this node expressed as indices into the simulator's tensors. + TfLiteIntArray* outputs; + + // intermediate tensors to this node expressed as indices into the simulator's + // tensors. + TfLiteIntArray* intermediates; + + // Temporary tensors uses during the computations. This usually contains no + // tensors, but ops are allowed to change that if they need scratch space of + // any sort. + TfLiteIntArray* temporaries; + + // Opaque data provided by the node implementer through `Registration.init`. + void* user_data; + + // Opaque data provided to the node if the node is a builtin. This is usually + // a structure defined in builtin_op_data.h + void* builtin_data; + + // Custom initial data. This is the opaque data provided in the flatbuffer. + // WARNING: This is an experimental interface that is subject to change. + const void* custom_initial_data; + int custom_initial_data_size; + + // The pointer to the delegate. This is non-null only when the node is + // created by calling `interpreter.ModifyGraphWithDelegate`. + // WARNING: This is an experimental interface that is subject to change. + struct TfLiteDelegate* delegate; +} TfLiteNode; +#else // defined(TF_LITE_STATIC_MEMORY)? +// NOTE: This flag is opt-in only at compile time. +// +// Specific reduced TfLiteTensor struct for TF Micro runtime. This struct +// contains only the minimum fields required to initialize and prepare a micro +// inference graph. The fields in this struct have been ordered from +// largest-to-smallest for optimal struct sizeof. +// +// This struct does not use: +// - allocation +// - buffer_handle +// - data_is_stale +// - delegate +// - dims_signature +// - name +// - sparsity +typedef struct TfLiteTensor { + // TODO(b/155784997): Consider consolidating these quantization fields: + // Quantization information. Replaces params field above. + TfLiteQuantization quantization; + + // Quantization information. + TfLiteQuantizationParams params; + + // A union of data pointers. The appropriate type should be used for a typed + // tensor based on `type`. + TfLitePtrUnion data; + + // A pointer to a structure representing the dimensionality interpretation + // that the buffer should have. NOTE: the product of elements of `dims` + // and the element datatype size should be equal to `bytes` below. + TfLiteIntArray* dims; + + // The number of bytes required to store the data of this Tensor. I.e. + // (bytes of each element) * dims[0] * ... * dims[n-1]. For example, if + // type is kTfLiteFloat32 and dims = {3, 2} then + // bytes = sizeof(float) * 3 * 2 = 4 * 3 * 2 = 24. + size_t bytes; + + // The data type specification for data stored in `data`. This affects + // what member of `data` union should be used. + TfLiteType type; + + // How memory is mapped + // kTfLiteMmapRo: Memory mapped read only. + // i.e. weights + // kTfLiteArenaRw: Arena allocated read write memory + // (i.e. temporaries, outputs). + TfLiteAllocationType allocation_type; + + // True if the tensor is a variable. + bool is_variable; +} TfLiteTensor; + +// Specific reduced TfLiteNode struct for TF Micro runtime. This struct contains +// only the minimum fields required to represent a node. +// +// This struct does not use: +// - delegate +// - intermediates +// - temporaries +typedef struct TfLiteNode { + // Inputs to this node expressed as indices into the simulator's tensors. + TfLiteIntArray* inputs; + + // Outputs to this node expressed as indices into the simulator's tensors. + TfLiteIntArray* outputs; + + // Opaque data provided by the node implementer through `Registration.init`. + void* user_data; + + // Opaque data provided to the node if the node is a builtin. This is usually + // a structure defined in builtin_op_data.h + void* builtin_data; + + // Custom initial data. This is the opaque data provided in the flatbuffer. + // WARNING: This is an experimental interface that is subject to change. + const void* custom_initial_data; + int custom_initial_data_size; +} TfLiteNode; +#endif // TF_LITE_STATIC_MEMORY + +// Light-weight tensor struct for TF Micro runtime. Provides the minimal amount +// of information required for a kernel to run during TfLiteRegistration::Eval. +// TODO(b/160955687): Move this field into TF_LITE_STATIC_MEMORY when TFLM +// builds with this flag by default internally. +typedef struct TfLiteEvalTensor { + // A union of data pointers. The appropriate type should be used for a typed + // tensor based on `type`. + TfLitePtrUnion data; + + // A pointer to a structure representing the dimensionality interpretation + // that the buffer should have. + TfLiteIntArray* dims; + + // The data type specification for data stored in `data`. This affects + // what member of `data` union should be used. + TfLiteType type; +} TfLiteEvalTensor; + +#ifndef TF_LITE_STATIC_MEMORY +// Free data memory of tensor `t`. +void TfLiteTensorDataFree(TfLiteTensor* t); + +// Free quantization data. +void TfLiteQuantizationFree(TfLiteQuantization* quantization); + +// Free sparsity parameters. +void TfLiteSparsityFree(TfLiteSparsity* sparsity); + +// Free memory of tensor `t`. +void TfLiteTensorFree(TfLiteTensor* t); + +// Set all of a tensor's fields (and free any previously allocated data). +void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims, + TfLiteQuantizationParams quantization, char* buffer, + size_t size, TfLiteAllocationType allocation_type, + const void* allocation, bool is_variable, + TfLiteTensor* tensor); + +// Resize the allocated data of a (dynamic) tensor. Tensors with allocation +// types other than kTfLiteDynamic will be ignored. +void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor); +#endif // TF_LITE_STATIC_MEMORY + +// WARNING: This is an experimental interface that is subject to change. +// +// Currently, TfLiteDelegateParams has to be allocated in a way that it's +// trivially destructable. It will be stored as `builtin_data` field in +// `TfLiteNode` of the delegate node. +// +// See also the `CreateDelegateParams` function in `interpreter.cc` details. +typedef struct TfLiteDelegateParams { + struct TfLiteDelegate* delegate; + TfLiteIntArray* nodes_to_replace; + TfLiteIntArray* input_tensors; + TfLiteIntArray* output_tensors; +} TfLiteDelegateParams; + +typedef struct TfLiteContext { + // Number of tensors in the context. + size_t tensors_size; + + // The execution plan contains a list of the node indices in execution + // order. execution_plan->size is the current number of nodes. And, + // execution_plan->data[0] is the first node that needs to be run. + // TfLiteDelegates can traverse the current execution plan by iterating + // through each member of this array and using GetNodeAndRegistration() to + // access details about a node. i.e. + // TfLiteIntArray* execution_plan; + // TF_LITE_ENSURE_STATUS(context->GetExecutionPlan(context, &execution_plan)); + // for (int exec_index = 0; exec_index < execution_plan->size; exec_index++) { + // int node_index = execution_plan->data[exec_index]; + // TfLiteNode* node; + // TfLiteRegistration* reg; + // context->GetNodeAndRegistration(context, node_index, &node, ®); + // } + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*GetExecutionPlan)(struct TfLiteContext* context, + TfLiteIntArray** execution_plan); + + // An array of tensors in the interpreter context (of length `tensors_size`) + TfLiteTensor* tensors; + + // opaque full context ptr (an opaque c++ data structure) + void* impl_; + + // Request memory pointer be resized. Updates dimensions on the tensor. + // NOTE: ResizeTensor takes ownership of newSize. + TfLiteStatus (*ResizeTensor)(struct TfLiteContext*, TfLiteTensor* tensor, + TfLiteIntArray* new_size); + // Request that an error be reported with format string msg. + void (*ReportError)(struct TfLiteContext*, const char* msg, ...); + + // Add `tensors_to_add` tensors, preserving pre-existing Tensor entries. If + // non-null, the value pointed to by `first_new_tensor_index` will be set to + // the index of the first new tensor. + TfLiteStatus (*AddTensors)(struct TfLiteContext*, int tensors_to_add, + int* first_new_tensor_index); + + // Get a Tensor node by node_index. + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*GetNodeAndRegistration)( + struct TfLiteContext*, int node_index, TfLiteNode** node, + struct TfLiteRegistration** registration); + + // Replace ops with one or more stub delegate operations. This function + // does not take ownership of `nodes_to_replace`. + TfLiteStatus (*ReplaceNodeSubsetsWithDelegateKernels)( + struct TfLiteContext*, struct TfLiteRegistration registration, + const TfLiteIntArray* nodes_to_replace, struct TfLiteDelegate* delegate); + + // Number of threads that are recommended to subsystems like gemmlowp and + // eigen. + int recommended_num_threads; + + // Access external contexts by type. + // WARNING: This is an experimental interface that is subject to change. + TfLiteExternalContext* (*GetExternalContext)(struct TfLiteContext*, + TfLiteExternalContextType); + // Set the value of a external context. Does not take ownership of the + // pointer. + // WARNING: This is an experimental interface that is subject to change. + void (*SetExternalContext)(struct TfLiteContext*, TfLiteExternalContextType, + TfLiteExternalContext*); + + // Flag for allowing float16 precision for FP32 calculation. + // default: false. + // WARNING: This is an experimental API and subject to change. + bool allow_fp32_relax_to_fp16; + + // Pointer to the op-level profiler, if set; nullptr otherwise. + void* profiler; + + // Allocate persistent buffer which has the same life time as the interpreter. + // Returns nullptr on failure. + // The memory is allocated from heap for TFL, and from tail in TFLM. + // This method is only available in Init or Prepare stage. + // WARNING: This is an experimental interface that is subject to change. + void* (*AllocatePersistentBuffer)(struct TfLiteContext* ctx, size_t bytes); + + // Allocate a buffer which will be deallocated right after invoke phase. + // The memory is allocated from heap in TFL, and from volatile arena in TFLM. + // This method is only available in invoke stage. + // NOTE: If possible use RequestScratchBufferInArena method to avoid memory + // allocation during inference time. + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*AllocateBufferForEval)(struct TfLiteContext* ctx, size_t bytes, + void** ptr); + + // Request a scratch buffer in the arena through static memory planning. + // This method is only available in Prepare stage and the buffer is allocated + // by the interpreter between Prepare and Eval stage. In Eval stage, + // GetScratchBuffer API can be used to fetch the address. + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*RequestScratchBufferInArena)(struct TfLiteContext* ctx, + size_t bytes, int* buffer_idx); + + // Get the scratch buffer pointer. + // This method is only available in Eval stage. + // WARNING: This is an experimental interface that is subject to change. + void* (*GetScratchBuffer)(struct TfLiteContext* ctx, int buffer_idx); + + // Resize the memory pointer of the `tensor`. This method behaves the same as + // `ResizeTensor`, except that it makes a copy of the shape array internally + // so the shape array could be deallocated right afterwards. + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*ResizeTensorExplicit)(struct TfLiteContext* ctx, + TfLiteTensor* tensor, int dims, + const int* shape); + + // This method provides a preview of post-delegation partitioning. Each + // TfLiteDelegateParams in the referenced array corresponds to one instance of + // the delegate kernel. + // Example usage: + // + // TfLiteIntArray* nodes_to_replace = ...; + // TfLiteDelegateParams* params_array; + // int num_partitions = 0; + // TF_LITE_ENSURE_STATUS(context->PreviewDelegatePartitioning( + // context, delegate, nodes_to_replace, ¶ms_array, &num_partitions)); + // for (int idx = 0; idx < num_partitions; idx++) { + // const auto& partition_params = params_array[idx]; + // ... + // } + // + // NOTE: The context owns the memory referenced by partition_params_array. It + // will be cleared with another call to PreviewDelegateParitioning, or after + // TfLiteDelegateParams::Prepare returns. + // + // WARNING: This is an experimental interface that is subject to change. + TfLiteStatus (*PreviewDelegatePartitioning)( + struct TfLiteContext* context, const TfLiteIntArray* nodes_to_replace, + TfLiteDelegateParams** partition_params_array, int* num_partitions); + + // Returns a TfLiteTensor struct for a given index. + // WARNING: This is an experimental interface that is subject to change. + // WARNING: This method may not be available on all platforms. + TfLiteTensor* (*GetTensor)(const struct TfLiteContext* context, + int tensor_idx); + + // Returns a TfLiteEvalTensor struct for a given index. + // WARNING: This is an experimental interface that is subject to change. + // WARNING: This method may not be available on all platforms. + TfLiteEvalTensor* (*GetEvalTensor)(const struct TfLiteContext* context, + int tensor_idx); +} TfLiteContext; + +typedef struct TfLiteRegistration { + // Initializes the op from serialized data. + // If a built-in op: + // `buffer` is the op's params data (TfLiteLSTMParams*). + // `length` is zero. + // If custom op: + // `buffer` is the op's `custom_options`. + // `length` is the size of the buffer. + // + // Returns a type-punned (i.e. void*) opaque data (e.g. a primitive pointer + // or an instance of a struct). + // + // The returned pointer will be stored with the node in the `user_data` field, + // accessible within prepare and invoke functions below. + // NOTE: if the data is already in the desired format, simply implement this + // function to return `nullptr` and implement the free function to be a no-op. + void* (*init)(TfLiteContext* context, const char* buffer, size_t length); + + // The pointer `buffer` is the data previously returned by an init invocation. + void (*free)(TfLiteContext* context, void* buffer); + + // prepare is called when the inputs this node depends on have been resized. + // context->ResizeTensor() can be called to request output tensors to be + // resized. + // + // Returns kTfLiteOk on success. + TfLiteStatus (*prepare)(TfLiteContext* context, TfLiteNode* node); + + // Execute the node (should read node->inputs and output to node->outputs). + // Returns kTfLiteOk on success. + TfLiteStatus (*invoke)(TfLiteContext* context, TfLiteNode* node); + + // profiling_string is called during summarization of profiling information + // in order to group executions together. Providing a value here will cause a + // given op to appear multiple times is the profiling report. This is + // particularly useful for custom ops that can perform significantly + // different calculations depending on their `user-data`. + const char* (*profiling_string)(const TfLiteContext* context, + const TfLiteNode* node); + + // Builtin codes. If this kernel refers to a builtin this is the code + // of the builtin. This is so we can do marshaling to other frameworks like + // NN API. + // Note: It is the responsibility of the registration binder to set this + // properly. + int32_t builtin_code; + + // Custom op name. If the op is a builtin, this will be null. + // Note: It is the responsibility of the registration binder to set this + // properly. + // WARNING: This is an experimental interface that is subject to change. + const char* custom_name; + + // The version of the op. + // Note: It is the responsibility of the registration binder to set this + // properly. + int version; +} TfLiteRegistration; + +// The flags used in `TfLiteDelegate`. Note that this is a bitmask, so the +// values should be 1, 2, 4, 8, ...etc. +typedef enum TfLiteDelegateFlags { + kTfLiteDelegateFlagsNone = 0, + // The flag is set if the delegate can handle dynamic sized tensors. + // For example, the output shape of a `Resize` op with non-constant shape + // can only be inferred when the op is invoked. + // In this case, the Delegate is responsible for calling + // `SetTensorToDynamic` to mark the tensor as a dynamic tensor, and calling + // `ResizeTensor` when invoking the op. + // + // If the delegate isn't capable to handle dynamic tensors, this flag need + // to be set to false. + kTfLiteDelegateFlagsAllowDynamicTensors = 1, + + // This flag can be used by delegates (that allow dynamic tensors) to ensure + // applicable tensor shapes are automatically propagated in the case of tensor + // resizing. + // This means that non-dynamic (allocation_type != kTfLiteDynamic) I/O tensors + // of a delegate kernel will have correct shapes before its Prepare() method + // is called. The runtime leverages TFLite builtin ops in the original + // execution plan to propagate shapes. + // + // A few points to note: + // 1. This requires kTfLiteDelegateFlagsAllowDynamicTensors. If that flag is + // false, this one is redundant since the delegate kernels are re-initialized + // every time tensors are resized. + // 2. Enabling this flag adds some overhead to AllocateTensors(), since extra + // work is required to prepare the original execution plan. + // 3. This flag requires that the original execution plan only have ops with + // valid registrations (and not 'dummy' custom ops like with Flex). + // WARNING: This feature is experimental and subject to change. + kTfLiteDelegateFlagsRequirePropagatedShapes = 2 +} TfLiteDelegateFlags; + +// WARNING: This is an experimental interface that is subject to change. +typedef struct TfLiteDelegate { + // Data that delegate needs to identify itself. This data is owned by the + // delegate. The delegate is owned in the user code, so the delegate is + // responsible for doing this when it is destroyed. + void* data_; + + // Invoked by ModifyGraphWithDelegate. This prepare is called, giving the + // delegate a view of the current graph through TfLiteContext*. It typically + // will look at the nodes and call ReplaceNodeSubsetsWithDelegateKernels() + // to ask the TensorFlow lite runtime to create macro-nodes to represent + // delegated subgraphs of the original graph. + TfLiteStatus (*Prepare)(TfLiteContext* context, + struct TfLiteDelegate* delegate); + + // Copy the data from delegate buffer handle into raw memory of the given + // 'tensor'. Note that the delegate is allowed to allocate the raw bytes as + // long as it follows the rules for kTfLiteDynamic tensors, in which case this + // cannot be null. + TfLiteStatus (*CopyFromBufferHandle)(TfLiteContext* context, + struct TfLiteDelegate* delegate, + TfLiteBufferHandle buffer_handle, + TfLiteTensor* tensor); + + // Copy the data from raw memory of the given 'tensor' to delegate buffer + // handle. This can be null if the delegate doesn't use its own buffer. + TfLiteStatus (*CopyToBufferHandle)(TfLiteContext* context, + struct TfLiteDelegate* delegate, + TfLiteBufferHandle buffer_handle, + TfLiteTensor* tensor); + + // Free the Delegate Buffer Handle. Note: This only frees the handle, but + // this doesn't release the underlying resource (e.g. textures). The + // resources are either owned by application layer or the delegate. + // This can be null if the delegate doesn't use its own buffer. + void (*FreeBufferHandle)(TfLiteContext* context, + struct TfLiteDelegate* delegate, + TfLiteBufferHandle* handle); + + // Bitmask flags. See the comments in `TfLiteDelegateFlags`. + int64_t flags; +} TfLiteDelegate; + +// Build a 'null' delegate, with all the fields properly set to their default +// values. +TfLiteDelegate TfLiteDelegateCreate(); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus +#endif // TENSORFLOW_LITE_C_COMMON_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/core/SConscript b/TensorflowLiteMicro/tensorflow/lite/core/SConscript new file mode 100644 index 0000000..d4a00f7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/SConscript @@ -0,0 +1,16 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/SConscript b/TensorflowLiteMicro/tensorflow/lite/core/api/SConscript new file mode 100644 index 0000000..d71fe04 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/SConscript @@ -0,0 +1,29 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cc') + +#. +root = str(Dir('#')) +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") + + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy] + +group = DefineGroup('lite/core', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.cc b/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.cc new file mode 100644 index 0000000..7070eaa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.cc @@ -0,0 +1,38 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/core/api/error_reporter.h" +#include + +namespace tflite { + +int ErrorReporter::Report(const char* format, ...) { + va_list args; + va_start(args, format); + int code = Report(format, args); + va_end(args); + return code; +} + +// TODO(aselle): Make the name of ReportError on context the same, so +// we can use the ensure functions w/o a context and w/ a reporter. +int ErrorReporter::ReportError(void*, const char* format, ...) { + va_list args; + va_start(args, format); + int code = Report(format, args); + va_end(args); + return code; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.h b/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.h new file mode 100644 index 0000000..05839a6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/error_reporter.h @@ -0,0 +1,59 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_ +#define TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_ + +#include + +namespace tflite { + +/// A functor that reports error to supporting system. Invoked similar to +/// printf. +/// +/// Usage: +/// ErrorReporter foo; +/// foo.Report("test %d", 5); +/// or +/// va_list args; +/// foo.Report("test %d", args); // where args is va_list +/// +/// Subclass ErrorReporter to provide another reporting destination. +/// For example, if you have a GUI program, you might redirect to a buffer +/// that drives a GUI error log box. +class ErrorReporter { + public: + virtual ~ErrorReporter() {} + virtual int Report(const char* format, va_list args) = 0; + int Report(const char* format, ...); + int ReportError(void*, const char* format, ...); +}; + +} // namespace tflite + +// You should not make bare calls to the error reporter, instead use the +// TF_LITE_REPORT_ERROR macro, since this allows message strings to be +// stripped when the binary size has to be optimized. If you are looking to +// reduce binary size, define TF_LITE_STRIP_ERROR_STRINGS when compiling and +// every call will be stubbed out, taking no memory. +#ifndef TF_LITE_STRIP_ERROR_STRINGS +#define TF_LITE_REPORT_ERROR(reporter, ...) \ + do { \ + static_cast(reporter)->Report(__VA_ARGS__); \ + } while (false) +#else // TF_LITE_STRIP_ERROR_STRINGS +#define TF_LITE_REPORT_ERROR(reporter, ...) +#endif // TF_LITE_STRIP_ERROR_STRINGS + +#endif // TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.cc b/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.cc new file mode 100644 index 0000000..7fb04f5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.cc @@ -0,0 +1,1739 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/core/api/flatbuffer_conversions.h" + +#include +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +namespace { + +// Utility class for safely allocating POD data. This is useful for avoiding +// leaks in cases where op params are allocated but fail to propagate to the +// parsed op data (e.g., when model parameters are invalid). +class SafeBuiltinDataAllocator { + public: + class BuiltinDataDeleter { + public: + explicit BuiltinDataDeleter(BuiltinDataAllocator* allocator) + : allocator_(allocator) {} + + void operator()(void* data) { allocator_->Deallocate(data); } + + private: + BuiltinDataAllocator* allocator_; + }; + + template + using BuiltinDataPtr = std::unique_ptr; + + explicit SafeBuiltinDataAllocator(BuiltinDataAllocator* allocator) + : allocator_(allocator) {} + + template + BuiltinDataPtr Allocate() { + return BuiltinDataPtr(allocator_->AllocatePOD(), + BuiltinDataDeleter(allocator_)); + } + + private: + BuiltinDataAllocator* allocator_; +}; + +// All the Parse functions take some pointers as params and this function has +// the common DCHECKs to catch if any of those are nullptr. +void CheckParsePointerParams(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + TFLITE_DCHECK(op != nullptr); + TFLITE_DCHECK(error_reporter != nullptr); + TFLITE_DCHECK(allocator != nullptr); + TFLITE_DCHECK(builtin_data != nullptr); +} + +// Copies the contents from the flatbuffer int vector `flatbuffer` into the +// int array `buffer`. `flat_vector` and `buffer` represent the same +// configuration operation for a given operation. +TfLiteStatus FlatBufferIntVectorToArray( + int max_size_of_buffer, const flatbuffers::Vector* flat_vector, + int* buffer, ErrorReporter* error_reporter, const char* op_name) { + if (!flat_vector) { + TF_LITE_REPORT_ERROR(error_reporter, + "Input array not provided for operation '%s'.\n", + op_name); + return kTfLiteError; + } else { + size_t num_dimensions = flat_vector->size(); + if (num_dimensions > max_size_of_buffer / sizeof(int)) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Found too many dimensions in the input array of operation '%s'.\n", + op_name); + return kTfLiteError; + } else { + for (size_t i = 0; i < num_dimensions; ++i) { + buffer[i] = flat_vector->Get(i); + } + } + } + return kTfLiteOk; +} + +// Converts the flatbuffer activation to what is used at runtime. +TfLiteFusedActivation ConvertActivation(ActivationFunctionType activation) { + switch (activation) { + case ActivationFunctionType_NONE: + return kTfLiteActNone; + case ActivationFunctionType_RELU: + return kTfLiteActRelu; + case ActivationFunctionType_RELU_N1_TO_1: + return kTfLiteActReluN1To1; + case ActivationFunctionType_RELU6: + return kTfLiteActRelu6; + case ActivationFunctionType_TANH: + return kTfLiteActTanh; + case ActivationFunctionType_SIGN_BIT: + return kTfLiteActSignBit; + } + return kTfLiteActNone; +} + +// Converts the flatbuffer padding enum to what is used at runtime. +TfLitePadding ConvertPadding(Padding padding) { + switch (padding) { + case Padding_SAME: + return kTfLitePaddingSame; + case Padding_VALID: + return kTfLitePaddingValid; + } + return kTfLitePaddingUnknown; +} + +#ifndef TF_LITE_STATIC_MEMORY +TfLiteStatus ParseOpDataTfLite(const Operator* op, BuiltinOperator op_type, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + auto parseLSHProjectionType = [](LSHProjectionType type) { + switch (type) { + case LSHProjectionType_SPARSE: + return kTfLiteLshProjectionSparse; + case LSHProjectionType_DENSE: + return kTfLiteLshProjectionDense; + default: + return kTfLiteLshProjectionUnknown; + } + }; + auto parseCombinerType = [](CombinerType type) { + switch (type) { + case CombinerType_MEAN: + return kTfLiteCombinerTypeMean; + case CombinerType_SQRTN: + return kTfLiteCombinerTypeSqrtn; + case CombinerType_SUM: + default: + return kTfLiteCombinerTypeSum; + } + }; + + SafeBuiltinDataAllocator safe_allocator(allocator); + *builtin_data = nullptr; + switch (op_type) { + case BuiltinOperator_ABS: { + return ParseAbs(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_ADD: { + return ParseAdd(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_ARG_MAX: { + return ParseArgMax(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_ARG_MIN: { + return ParseArgMin(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_AVERAGE_POOL_2D: { + return ParsePool(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_CEIL: { + return ParseCeil(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_CONCATENATION: { + return ParseConcatenation(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_CONV_2D: { + return ParseConv2D(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_DEPTHWISE_CONV_2D: { + return ParseDepthwiseConv2D(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_DEQUANTIZE: { + return ParseDequantize(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_FLOOR: { + return ParseFloor(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_FULLY_CONNECTED: { + return ParseFullyConnected(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_GREATER: { + return ParseGreater(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_GREATER_EQUAL: { + return ParseGreaterEqual(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_HARD_SWISH: { + return ParseHardSwish(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_L2_NORMALIZATION: { + return ParseL2Normalization(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_L2_POOL_2D: { + return ParsePool(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LESS: { + return ParseLess(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LESS_EQUAL: { + return ParseLessEqual(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LOG: { + return ParseLog(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LOGICAL_AND: { + return ParseLogicalAnd(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LOGICAL_NOT: { + return ParseLogicalNot(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LOGICAL_OR: { + return ParseLogicalOr(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_LOGISTIC: { + return ParseLogistic(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_MAXIMUM: { + return ParseMaximum(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_MAX_POOL_2D: { + return ParsePool(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_MEAN: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_MINIMUM: { + return ParseMinimum(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_MUL: { + return ParseMul(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_NEG: { + return ParseNeg(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_NOT_EQUAL: { + return ParseNotEqual(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_PACK: { + return ParsePack(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_PAD: { + return ParsePad(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_PADV2: { + return ParsePadV2(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_PRELU: { + return ParsePrelu(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_QUANTIZE: { + return ParseQuantize(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_REDUCE_ANY: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_REDUCE_MAX: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_REDUCE_MIN: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_REDUCE_PROD: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_RELU: { + return ParseRelu(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_RELU6: { + return ParseRelu6(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_RESHAPE: { + return ParseReshape(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_RESIZE_NEAREST_NEIGHBOR: { + return ParseResizeNearestNeighbor(op, error_reporter, allocator, + builtin_data); + } + + case BuiltinOperator_ROUND: { + return ParseRound(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_RSQRT: { + return ParseRsqrt(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SIN: { + return ParseSin(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SOFTMAX: { + return ParseSoftmax(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SPLIT: { + return ParseSplit(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SQRT: { + return ParseSqrt(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SQUARE: { + return ParseSquare(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_STRIDED_SLICE: { + return ParseStridedSlice(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SUB: { + return ParseSub(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SUM: { + return ParseReducer(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_SVDF: { + return ParseSvdf(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_TANH: { + return ParseTanh(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_UNPACK: { + return ParseUnpack(op, error_reporter, allocator, builtin_data); + } + + case BuiltinOperator_CAST: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_CastOptions()) { + TF_LITE_ENSURE_STATUS(ConvertTensorType(schema_params->in_data_type(), + ¶ms->in_data_type, + error_reporter)); + TF_LITE_ENSURE_STATUS(ConvertTensorType(schema_params->out_data_type(), + ¶ms->out_data_type, + error_reporter)); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_LSH_PROJECTION: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* lshParams = + op->builtin_options_as_LSHProjectionOptions()) { + params->type = parseLSHProjectionType(lshParams->type()); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* sequence_rnn_params = + op->builtin_options_as_SequenceRNNOptions()) { + params->activation = + ConvertActivation(sequence_rnn_params->fused_activation_function()); + params->time_major = sequence_rnn_params->time_major(); + params->asymmetric_quantize_inputs = + sequence_rnn_params->asymmetric_quantize_inputs(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN: { + auto params = + safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* bidi_sequence_rnn_params = + op->builtin_options_as_BidirectionalSequenceRNNOptions()) { + params->activation = ConvertActivation( + bidi_sequence_rnn_params->fused_activation_function()); + params->time_major = bidi_sequence_rnn_params->time_major(); + params->merge_outputs = bidi_sequence_rnn_params->merge_outputs(); + params->asymmetric_quantize_inputs = + bidi_sequence_rnn_params->asymmetric_quantize_inputs(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_RNN: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* rnn_params = op->builtin_options_as_RNNOptions()) { + params->activation = + ConvertActivation(rnn_params->fused_activation_function()); + params->asymmetric_quantize_inputs = + rnn_params->asymmetric_quantize_inputs(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_EMBEDDING_LOOKUP_SPARSE: { + auto params = + safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* embedding_params = + op->builtin_options_as_EmbeddingLookupSparseOptions()) { + params->combiner = parseCombinerType(embedding_params->combiner()); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + + case BuiltinOperator_HASHTABLE_LOOKUP: + // no-op. + return kTfLiteOk; + case BuiltinOperator_DIV: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_DivOptions()) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = + op->builtin_options_as_LocalResponseNormalizationOptions()) { + params->radius = schema_params->radius(); + params->bias = schema_params->bias(); + params->alpha = schema_params->alpha(); + params->beta = schema_params->beta(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_LSTM: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* lstm_params = op->builtin_options_as_LSTMOptions()) { + params->activation = + ConvertActivation(lstm_params->fused_activation_function()); + params->cell_clip = lstm_params->cell_clip(); + params->proj_clip = lstm_params->proj_clip(); + switch (lstm_params->kernel_type()) { + case LSTMKernelType_FULL: + params->kernel_type = kTfLiteLSTMFullKernel; + break; + case LSTMKernelType_BASIC: + params->kernel_type = kTfLiteLSTMBasicKernel; + break; + default: + TF_LITE_REPORT_ERROR(error_reporter, + "Unhandled LSTM kernel type: %d", + lstm_params->kernel_type()); + return kTfLiteError; + } + params->asymmetric_quantize_inputs = + lstm_params->asymmetric_quantize_inputs(); + } else { + TF_LITE_REPORT_ERROR(error_reporter, + "No valid LSTM builtin options exist"); + return kTfLiteError; + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM: { + auto params = + safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* seq_lstm_params = + op->builtin_options_as_UnidirectionalSequenceLSTMOptions()) { + params->activation = + ConvertActivation(seq_lstm_params->fused_activation_function()); + params->cell_clip = seq_lstm_params->cell_clip(); + params->proj_clip = seq_lstm_params->proj_clip(); + params->time_major = seq_lstm_params->time_major(); + params->asymmetric_quantize_inputs = + seq_lstm_params->asymmetric_quantize_inputs(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM: { + auto params = + safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* bidi_lstm_params = + op->builtin_options_as_BidirectionalSequenceLSTMOptions()) { + params->activation = + ConvertActivation(bidi_lstm_params->fused_activation_function()); + params->cell_clip = bidi_lstm_params->cell_clip(); + params->proj_clip = bidi_lstm_params->proj_clip(); + params->merge_outputs = bidi_lstm_params->merge_outputs(); + params->time_major = bidi_lstm_params->time_major(); + params->asymmetric_quantize_inputs = + bidi_lstm_params->asymmetric_quantize_inputs(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_RESIZE_BILINEAR: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = + op->builtin_options_as_ResizeBilinearOptions()) { + params->align_corners = schema_params->align_corners(); + params->half_pixel_centers = schema_params->half_pixel_centers(); + } else { + // Some older models did not populate the ResizeBilinearOptions field in + // the flatbuffer, so ensure it's set to a sensible default. + params->align_corners = false; + params->half_pixel_centers = false; + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SKIP_GRAM: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* skip_gram_params = + op->builtin_options_as_SkipGramOptions()) { + params->ngram_size = skip_gram_params->ngram_size(); + params->max_skip_size = skip_gram_params->max_skip_size(); + params->include_all_ngrams = skip_gram_params->include_all_ngrams(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SPACE_TO_DEPTH: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = + op->builtin_options_as_SpaceToDepthOptions()) { + params->block_size = schema_params->block_size(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_DEPTH_TO_SPACE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = + op->builtin_options_as_DepthToSpaceOptions()) { + params->block_size = schema_params->block_size(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_GATHER: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + params->axis = 0; + if (const auto* gather_params = op->builtin_options_as_GatherOptions()) { + params->axis = gather_params->axis(); + } + + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SPLIT_V: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_SplitVOptions()) { + params->num_splits = schema_params->num_splits(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SQUEEZE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_SqueezeOptions()) { + const auto* squeeze_dims = schema_params->squeeze_dims(); + TF_LITE_ENSURE_STATUS(FlatBufferIntVectorToArray( + sizeof(params->squeeze_dims), squeeze_dims, params->squeeze_dims, + error_reporter, "squeeze")); + params->num_squeeze_dims = squeeze_dims->size(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_TRANSPOSE_CONV: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* transpose_conv_params = + op->builtin_options_as_TransposeConvOptions()) { + params->padding = ConvertPadding(transpose_conv_params->padding()); + params->stride_width = transpose_conv_params->stride_w(); + params->stride_height = transpose_conv_params->stride_h(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SPARSE_TO_DENSE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* sparse_to_dense_params = + op->builtin_options_as_SparseToDenseOptions()) { + params->validate_indices = sparse_to_dense_params->validate_indices(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_SHAPE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_ShapeOptions()) { + TF_LITE_ENSURE_STATUS(ConvertTensorType( + schema_params->out_type(), ¶ms->out_type, error_reporter)); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_DELEGATE: { + // TODO(ycling): Revisit when supporting saving delegated models. + TF_LITE_REPORT_ERROR(error_reporter, + "DELEGATE op shouldn't exist in model."); + return kTfLiteError; + } + case BuiltinOperator_FAKE_QUANT: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = + op->builtin_options_as_FakeQuantOptions()) { + params->min = schema_params->min(); + params->max = schema_params->max(); + params->num_bits = schema_params->num_bits(); + params->narrow_range = schema_params->narrow_range(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_ONE_HOT: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* schema_params = op->builtin_options_as_OneHotOptions()) { + params->axis = schema_params->axis(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_LEAKY_RELU: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* leaky_relu_params = + op->builtin_options_as_LeakyReluOptions()) { + params->alpha = leaky_relu_params->alpha(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_MIRROR_PAD: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + const auto* mirror_pad_params = op->builtin_options_as_MirrorPadOptions(); + if (mirror_pad_params != nullptr) { + params->mode = + mirror_pad_params->mode() == tflite::MirrorPadMode_REFLECT + ? TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingReflect + : TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingSymmetric; + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_UNIQUE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + const auto* unique_params = op->builtin_options_as_UniqueOptions(); + if (unique_params != nullptr) { + params->index_out_type = + unique_params->idx_out_type() == tflite::TensorType_INT64 + ? TfLiteType::kTfLiteInt64 + : TfLiteType::kTfLiteInt32; + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_REVERSE_SEQUENCE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* reverse_seq_params = + op->builtin_options_as_ReverseSequenceOptions()) { + params->seq_dim = reverse_seq_params->seq_dim(); + params->batch_dim = reverse_seq_params->batch_dim(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_IF: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* if_params = op->builtin_options_as_IfOptions()) { + params->then_subgraph_index = if_params->then_subgraph_index(); + params->else_subgraph_index = if_params->else_subgraph_index(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_WHILE: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* while_params = op->builtin_options_as_WhileOptions()) { + params->cond_subgraph_index = while_params->cond_subgraph_index(); + params->body_subgraph_index = while_params->body_subgraph_index(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + case BuiltinOperator_BATCH_MATMUL: { + auto params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + if (const auto* bmm_params = + op->builtin_options_as_BatchMatMulOptions()) { + params->adj_x = bmm_params->adj_x(); + params->adj_y = bmm_params->adj_y(); + } + *builtin_data = params.release(); + return kTfLiteOk; + } + // Below are the ops with no builtin_data structure. + case BuiltinOperator_BATCH_TO_SPACE_ND: + // TODO(aselle): Implement call in BuiltinOptions, but nullptrs are + // ok for now, since there is no call implementation either. + case BuiltinOperator_CALL: + case BuiltinOperator_CONCAT_EMBEDDINGS: + case BuiltinOperator_COS: + case BuiltinOperator_CUSTOM: + case BuiltinOperator_ELU: + case BuiltinOperator_EMBEDDING_LOOKUP: + case BuiltinOperator_EQUAL: + case BuiltinOperator_EXP: + case BuiltinOperator_EXPAND_DIMS: + case BuiltinOperator_LOG_SOFTMAX: + case BuiltinOperator_MATRIX_DIAG: + case BuiltinOperator_MATRIX_SET_DIAG: + case BuiltinOperator_RELU_N1_TO_1: + case BuiltinOperator_SELECT: + case BuiltinOperator_SELECT_V2: + case BuiltinOperator_SLICE: + case BuiltinOperator_SPACE_TO_BATCH_ND: + case BuiltinOperator_TILE: + case BuiltinOperator_TOPK_V2: + case BuiltinOperator_TRANSPOSE: + case BuiltinOperator_POW: + case BuiltinOperator_FLOOR_DIV: + case BuiltinOperator_ZEROS_LIKE: + case BuiltinOperator_FILL: + case BuiltinOperator_FLOOR_MOD: + case BuiltinOperator_RANGE: + case BuiltinOperator_SQUARED_DIFFERENCE: + case BuiltinOperator_REVERSE_V2: + case BuiltinOperator_ADD_N: + case BuiltinOperator_GATHER_ND: + case BuiltinOperator_WHERE: + case BuiltinOperator_RANK: + case BuiltinOperator_NON_MAX_SUPPRESSION_V4: + case BuiltinOperator_NON_MAX_SUPPRESSION_V5: + case BuiltinOperator_SCATTER_ND: + case BuiltinOperator_DENSIFY: + case BuiltinOperator_SEGMENT_SUM: + return kTfLiteOk; + } + return kTfLiteError; +} // NOLINT[readability/fn_size] +#endif // !defined(TF_LITE_STATIC_MEMORY) +} // namespace + +TfLiteStatus ConvertTensorType(TensorType tensor_type, TfLiteType* type, + ErrorReporter* error_reporter) { + switch (tensor_type) { + case TensorType_FLOAT16: + *type = kTfLiteFloat16; + return kTfLiteOk; + case TensorType_FLOAT32: + *type = kTfLiteFloat32; + return kTfLiteOk; + case TensorType_FLOAT64: + *type = kTfLiteFloat64; + return kTfLiteOk; + case TensorType_INT16: + *type = kTfLiteInt16; + return kTfLiteOk; + case TensorType_INT32: + *type = kTfLiteInt32; + return kTfLiteOk; + case TensorType_UINT8: + *type = kTfLiteUInt8; + return kTfLiteOk; + case TensorType_INT8: + *type = kTfLiteInt8; + return kTfLiteOk; + case TensorType_INT64: + *type = kTfLiteInt64; + return kTfLiteOk; + case TensorType_STRING: + *type = kTfLiteString; + return kTfLiteOk; + case TensorType_BOOL: + *type = kTfLiteBool; + return kTfLiteOk; + case TensorType_COMPLEX64: + *type = kTfLiteComplex64; + return kTfLiteOk; + case TensorType_COMPLEX128: + *type = kTfLiteComplex128; + return kTfLiteOk; + default: + *type = kTfLiteNoType; + TF_LITE_REPORT_ERROR(error_reporter, + "Unsupported data type %d in tensor\n", tensor_type); + return kTfLiteError; + } +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseAbs(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseAdd(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const AddOptions* schema_params = op->builtin_options_as_AddOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + params->pot_scale_int16 = schema_params->pot_scale_int16(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseArgMax(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ArgMaxOptions* schema_params = op->builtin_options_as_ArgMaxOptions(); + + if (schema_params != nullptr) { + TF_LITE_ENSURE_STATUS(ConvertTensorType( + schema_params->output_type(), ¶ms->output_type, error_reporter)); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseArgMin(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ArgMinOptions* schema_params = op->builtin_options_as_ArgMinOptions(); + + if (schema_params != nullptr) { + TF_LITE_ENSURE_STATUS(ConvertTensorType( + schema_params->output_type(), ¶ms->output_type, error_reporter)); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseCeil(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseConcatenation(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ConcatenationOptions* schema_params = + op->builtin_options_as_ConcatenationOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + params->axis = schema_params->axis(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseConv2D(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const Conv2DOptions* schema_params = op->builtin_options_as_Conv2DOptions(); + + if (schema_params != nullptr) { + params->padding = ConvertPadding(schema_params->padding()); + params->stride_width = schema_params->stride_w(); + params->stride_height = schema_params->stride_h(); + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + + params->dilation_width_factor = schema_params->dilation_w_factor(); + params->dilation_height_factor = schema_params->dilation_h_factor(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseCos(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseDepthwiseConv2D(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const DepthwiseConv2DOptions* schema_params = + op->builtin_options_as_DepthwiseConv2DOptions(); + + if (schema_params != nullptr) { + params->padding = ConvertPadding(schema_params->padding()); + params->stride_width = schema_params->stride_w(); + params->stride_height = schema_params->stride_h(); + params->depth_multiplier = schema_params->depth_multiplier(); + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + + params->dilation_width_factor = schema_params->dilation_w_factor(); + params->dilation_height_factor = schema_params->dilation_h_factor(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseDequantize(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseEqual(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseFloor(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseFullyConnected(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const FullyConnectedOptions* schema_params = + op->builtin_options_as_FullyConnectedOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + params->keep_num_dims = schema_params->keep_num_dims(); + params->asymmetric_quantize_inputs = + schema_params->asymmetric_quantize_inputs(); + + switch (schema_params->weights_format()) { + case FullyConnectedOptionsWeightsFormat_DEFAULT: + params->weights_format = kTfLiteFullyConnectedWeightsFormatDefault; + break; + case FullyConnectedOptionsWeightsFormat_SHUFFLED4x16INT8: + params->weights_format = + kTfLiteFullyConnectedWeightsFormatShuffled4x16Int8; + break; + default: + TF_LITE_REPORT_ERROR(error_reporter, + "Unhandled fully-connected weights format."); + return kTfLiteError; + } + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseGreater(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseGreaterEqual(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseHardSwish(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseL2Normalization(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const L2NormOptions* schema_params = op->builtin_options_as_L2NormOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLess(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLessEqual(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLog(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLogicalAnd(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLogicalNot(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLogicalOr(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseLogistic(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseMaximum(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseMinimum(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseMul(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const MulOptions* schema_params = op->builtin_options_as_MulOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseNeg(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseNotEqual(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +TfLiteStatus ParsePack(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const PackOptions* schema_params = op->builtin_options_as_PackOptions(); + + if (schema_params != nullptr) { + params->values_count = schema_params->values_count(); + params->axis = schema_params->axis(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParsePad(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParsePadV2(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParsePool(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const Pool2DOptions* schema_params = op->builtin_options_as_Pool2DOptions(); + + if (schema_params != nullptr) { + params->padding = ConvertPadding(schema_params->padding()); + params->stride_width = schema_params->stride_w(); + params->stride_height = schema_params->stride_h(); + params->filter_width = schema_params->filter_width(); + params->filter_height = schema_params->filter_height(); + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParsePrelu(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseQuantize(const Operator*, ErrorReporter*, + BuiltinDataAllocator*, void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseReducer(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ReducerOptions* schema_params = op->builtin_options_as_ReducerOptions(); + + if (schema_params != nullptr) { + params->keep_dims = schema_params->keep_dims(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseRelu(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseRelu6(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseReshape(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ReshapeOptions* schema_params = op->builtin_options_as_ReshapeOptions(); + + if (schema_params != nullptr) { + const flatbuffers::Vector* new_shape = schema_params->new_shape(); + // TODO(b/147203660): We need to figure out when dynamic reshape + // (new_shape is a tensor) happens, why the option is not a nullptr. + // But nonethless, we should only copy when new_shape is not a nullptr. + if (new_shape != nullptr) { + TF_LITE_ENSURE_STATUS( + FlatBufferIntVectorToArray(sizeof(params->shape), new_shape, + params->shape, error_reporter, "reshape")); + params->num_dimensions = new_shape->size(); + } else { + // TODO(b/157480169) TODO(b/147203660): We should either return + // kTfLiteError or fill in some reasonable defaults in the params struct. + // We are not doing so until we better undertand the ramifications of + // changing the legacy behavior. + } + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseResizeNearestNeighbor(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const ResizeNearestNeighborOptions* schema_params = + op->builtin_options_as_ResizeNearestNeighborOptions(); + + if (schema_params != nullptr) { + params->align_corners = schema_params->align_corners(); + params->half_pixel_centers = schema_params->half_pixel_centers(); + } else { + params->align_corners = false; + params->half_pixel_centers = false; + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseRound(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseRsqrt(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseSin(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseSoftmax(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const SoftmaxOptions* schema_params = op->builtin_options_as_SoftmaxOptions(); + + if (schema_params != nullptr) { + params->beta = schema_params->beta(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseSplit(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const SplitOptions* schema_params = op->builtin_options_as_SplitOptions(); + + if (schema_params != nullptr) { + params->num_splits = schema_params->num_splits(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseSqrt(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseSquare(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseStridedSlice(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const StridedSliceOptions* schema_params = + op->builtin_options_as_StridedSliceOptions(); + + if (schema_params != nullptr) { + params->begin_mask = schema_params->begin_mask(); + params->end_mask = schema_params->end_mask(); + params->ellipsis_mask = schema_params->ellipsis_mask(); + params->new_axis_mask = schema_params->new_axis_mask(); + params->shrink_axis_mask = schema_params->shrink_axis_mask(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseSub(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const SubOptions* schema_params = op->builtin_options_as_SubOptions(); + + if (schema_params != nullptr) { + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + params->pot_scale_int16 = schema_params->pot_scale_int16(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseSvdf(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const SVDFOptions* schema_params = op->builtin_options_as_SVDFOptions(); + if (schema_params != nullptr) { + params->rank = schema_params->rank(); + params->activation = + ConvertActivation(schema_params->fused_activation_function()); + params->asymmetric_quantize_inputs = + schema_params->asymmetric_quantize_inputs(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +// We have this parse function instead of directly returning kTfLiteOk from the +// switch-case in ParseOpData because this function is used as part of the +// selective registration for the OpResolver implementation in micro. +TfLiteStatus ParseTanh(const Operator*, ErrorReporter*, BuiltinDataAllocator*, + void**) { + return kTfLiteOk; +} + +TfLiteStatus ParseUnpack(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { + CheckParsePointerParams(op, error_reporter, allocator, builtin_data); + + SafeBuiltinDataAllocator safe_allocator(allocator); + std::unique_ptr + params = safe_allocator.Allocate(); + TF_LITE_ENSURE(error_reporter, params != nullptr); + + const UnpackOptions* schema_params = op->builtin_options_as_UnpackOptions(); + + if (schema_params != nullptr) { + params->num = schema_params->num(); + params->axis = schema_params->axis(); + } else { + // TODO(b/157480169): We should either return kTfLiteError or fill in some + // reasonable defaults in the params struct. We are not doing so until we + // better undertand the ramifications of changing the legacy behavior. + } + + *builtin_data = params.release(); + return kTfLiteOk; +} + +TfLiteStatus ParseOpData(const Operator* op, BuiltinOperator op_type, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data) { +// TODO(b/145762662): It would be preferable to have the build graph for TF Lite +// Micro not have the ParseOpData function at all. This would require splitting +// the current file into two separate files, one of which defines the +// ParseOpData function and the other that defines the operator specific parse +// functions (e.g. ParseAdd). +// +// Such a split was attempted but was not worth the effort at the time because +// of the following reasons: +// * We could either duplicate the functions and the SafeBuiltinDataAllocator +// class in the anonymous namespace of this file, or attempt to make a common +// library with these helper functions and class. +// * Making a common library with a separate build target was not feasible as +// it introduced circular dependencies due to the ErrorReporter and a common +// .cc and .h within the same api build target the also cause circular +// dependencies due to the BuiltinDataAllocator class. +// * If all the builtin operators were to have their own parse functions, or we +// were ok with some amount of code duplication, then this split of the .cc +// files would be a lot more feasible. +#ifdef TF_LITE_STATIC_MEMORY + TF_LITE_REPORT_ERROR( + error_reporter, + "ParseOpData is unsupported on TfLiteMicro, please use the operator " + "specific parse functions (e.g. ParseAdd etc.).\n"); + return kTfLiteError; +#else + return ParseOpDataTfLite(op, op_type, error_reporter, allocator, + builtin_data); +#endif +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.h b/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.h new file mode 100644 index 0000000..aaeb98c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/flatbuffer_conversions.h @@ -0,0 +1,253 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_ +#define TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_ + +// These functions transform codes and data structures that are defined in the +// flatbuffer serialization format into in-memory values that are used by the +// runtime API and interpreter. + +#include +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +// Interface class for builtin data allocations. +class BuiltinDataAllocator { + public: + virtual void* Allocate(size_t size, size_t alignment_hint) = 0; + virtual void Deallocate(void* data) = 0; + + // Allocate a structure, but make sure it is a POD structure that doesn't + // require constructors to run. The reason we do this, is that Interpreter's C + // extension part will take ownership so destructors will not be run during + // deallocation. + template + T* AllocatePOD() { + // TODO(b/154346074): Change this to is_trivially_destructible when all + // platform targets support that properly. + static_assert(std::is_pod::value, "Builtin data structure must be POD."); + void* allocated_memory = this->Allocate(sizeof(T), alignof(T)); + return new (allocated_memory) T; + } + + virtual ~BuiltinDataAllocator() {} +}; + +// Parse the appropriate data out of the op. +// +// This handles builtin data explicitly as there are flatbuffer schemas. +// If it returns kTfLiteOk, it passes the data out with `builtin_data`. The +// calling function has to pass in an allocator object, and this allocator +// will be called to reserve space for the output data. If the calling +// function's allocator reserves memory on the heap, then it's the calling +// function's responsibility to free it. +// If it returns kTfLiteError, `builtin_data` will be `nullptr`. +TfLiteStatus ParseOpData(const Operator* op, BuiltinOperator op_type, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +// Converts the tensor data type used in the flat buffer to the representation +// used by the runtime. +TfLiteStatus ConvertTensorType(TensorType tensor_type, TfLiteType* type, + ErrorReporter* error_reporter); + +TfLiteStatus ParseAbs(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseAdd(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseArgMax(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseArgMin(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseCeil(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseConcatenation(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseConv2D(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseCos(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseDepthwiseConv2D(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseDequantize(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseEqual(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseFloor(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseFullyConnected(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseGreater(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseGreaterEqual(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseHardSwish(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseL2Normalization(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseLess(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseLessEqual(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseLog(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseLogicalAnd(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseLogicalNot(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseLogicalOr(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseLogistic(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseMaximum(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseMinimum(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseMul(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseNeg(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseNotEqual(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParsePack(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParsePad(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParsePadV2(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParsePool(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParsePrelu(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseQuantize(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseReducer(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseRelu(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseRelu6(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseReshape(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseResizeNearestNeighbor(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseRound(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseRsqrt(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSin(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSoftmax(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSplit(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSqrt(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSquare(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseStridedSlice(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + +TfLiteStatus ParseSub(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseSvdf(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseTanh(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +TfLiteStatus ParseUnpack(const Operator* op, ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, void** builtin_data); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.cc b/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.cc new file mode 100644 index 0000000..c239d9e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.cc @@ -0,0 +1,66 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/core/api/op_resolver.h" + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" + +namespace tflite { + +TfLiteStatus GetRegistrationFromOpCode( + const OperatorCode* opcode, const OpResolver& op_resolver, + ErrorReporter* error_reporter, const TfLiteRegistration** registration) { + TfLiteStatus status = kTfLiteOk; + *registration = nullptr; + auto builtin_code = opcode->builtin_code(); + int version = opcode->version(); + + if (builtin_code > BuiltinOperator_MAX || + builtin_code < BuiltinOperator_MIN) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Op builtin_code out of range: %d. Are you using old TFLite binary " + "with newer model?", + builtin_code); + status = kTfLiteError; + } else if (builtin_code != BuiltinOperator_CUSTOM) { + *registration = op_resolver.FindOp(builtin_code, version); + if (*registration == nullptr) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Didn't find op for builtin opcode '%s' version '%d'\n", + EnumNameBuiltinOperator(builtin_code), version); + status = kTfLiteError; + } + } else if (!opcode->custom_code()) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Operator with CUSTOM builtin_code has no custom_code.\n"); + status = kTfLiteError; + } else { + const char* name = opcode->custom_code()->c_str(); + *registration = op_resolver.FindOp(name, version); + if (*registration == nullptr) { + // Do not report error for unresolved custom op, we do the final check + // while preparing ops. + status = kTfLiteError; + } + } + return status; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.h b/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.h new file mode 100644 index 0000000..1294b7b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/op_resolver.h @@ -0,0 +1,48 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_CORE_API_OP_RESOLVER_H_ +#define TENSORFLOW_LITE_CORE_API_OP_RESOLVER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +/// Abstract interface that returns TfLiteRegistrations given op codes or custom +/// op names. This is the mechanism that ops being referenced in the flatbuffer +/// model are mapped to executable function pointers (TfLiteRegistrations). +class OpResolver { + public: + /// Finds the op registration for a builtin operator by enum code. + virtual const TfLiteRegistration* FindOp(tflite::BuiltinOperator op, + int version) const = 0; + /// Finds the op registration of a custom operator by op name. + virtual const TfLiteRegistration* FindOp(const char* op, + int version) const = 0; + virtual ~OpResolver() {} +}; + +// Handles the logic for converting between an OperatorCode structure extracted +// from a flatbuffer and information about a registered operator +// implementation. +TfLiteStatus GetRegistrationFromOpCode(const OperatorCode* opcode, + const OpResolver& op_resolver, + ErrorReporter* error_reporter, + const TfLiteRegistration** registration); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_CORE_API_OP_RESOLVER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/profiler.h b/TensorflowLiteMicro/tensorflow/lite/core/api/profiler.h new file mode 100644 index 0000000..897efbe --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/profiler.h @@ -0,0 +1,194 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_CORE_API_PROFILER_H_ +#define TENSORFLOW_LITE_CORE_API_PROFILER_H_ + +#include + +namespace tflite { + +// A simple utility for enabling profiled event tracing in TensorFlow Lite. +class Profiler { + public: + // As certain Profiler instance might be only interested in certain event + // types, we define each event type value to allow a Profiler to use + // bitmasking bitwise operations to determine whether an event should be + // recorded or not. + enum class EventType { + // Default event type, the metadata field has no special significance. + DEFAULT = 1, + + // The event is an operator invocation and the event_metadata field is the + // index of operator node. + OPERATOR_INVOKE_EVENT = 2, + + // The event is an invocation for an internal operator of a TFLite delegate. + // The event_metadata field is the index of operator node that's specific to + // the delegate. + DELEGATE_OPERATOR_INVOKE_EVENT = 4, + + // The event is a recording of runtime instrumentation such as the overall + // TFLite runtime status, the TFLite delegate status (if a delegate + // is applied), and the overall model inference latency etc. + // Note, the delegate status and overall status are stored as separate + // event_metadata fields. In particular, the delegate status is encoded + // as DelegateStatus::full_status(). + GENERAL_RUNTIME_INSTRUMENTATION_EVENT = 8, + }; + + virtual ~Profiler() {} + + // Signals the beginning of an event and returns a handle to the profile + // event. The `event_metadata1` and `event_metadata2` have different + // interpretations based on the actual Profiler instance and the `event_type`. + // For example, as for the 'SubgraphAwareProfiler' defined in + // lite/core/subgraph.h, when the event_type is OPERATOR_INVOKE_EVENT, + // `event_metadata1` represents the index of a TFLite node, and + // `event_metadata2` represents the index of the subgraph that this event + // comes from. + virtual uint32_t BeginEvent(const char* tag, EventType event_type, + int64_t event_metadata1, + int64_t event_metadata2) = 0; + // Similar w/ the above, but `event_metadata2` defaults to 0. + uint32_t BeginEvent(const char* tag, EventType event_type, + int64_t event_metadata) { + return BeginEvent(tag, event_type, event_metadata, /*event_metadata2*/ 0); + } + + // Signals an end to the specified profile event with 'event_metadata's, This + // is useful when 'event_metadata's are not available when the event begins + // or when one wants to overwrite the 'event_metadata's set at the beginning. + virtual void EndEvent(uint32_t event_handle, int64_t event_metadata1, + int64_t event_metadata2) {} + // Signals an end to the specified profile event. + virtual void EndEvent(uint32_t event_handle) = 0; + + // Appends an event of type 'event_type' with 'tag' and 'event_metadata' + // which started at 'start' and ended at 'end' + // Note: + // In cases were ProfileSimmarizer and tensorflow::StatsCalculator are used + // they assume the value is in "usec", if in any case subclasses + // didn't put usec, then the values are not meaningful. + // TODO karimnosseir: Revisit and make the function more clear. + void AddEvent(const char* tag, EventType event_type, uint64_t start, + uint64_t end, int64_t event_metadata) { + AddEvent(tag, event_type, start, end, event_metadata, + /*event_metadata2*/ 0); + } + + virtual void AddEvent(const char* tag, EventType event_type, uint64_t start, + uint64_t end, int64_t event_metadata1, + int64_t event_metadata2) {} + + protected: + friend class ScopedProfile; +}; + +// Adds a profile event to `profiler` that begins with the construction +// of the object and ends when the object goes out of scope. +// The lifetime of tag should be at least the lifetime of `profiler`. +// `profiler` may be null, in which case nothing is profiled. +class ScopedProfile { + public: + ScopedProfile(Profiler* profiler, const char* tag, + Profiler::EventType event_type = Profiler::EventType::DEFAULT, + int64_t event_metadata = 0) + : profiler_(profiler), event_handle_(0) { + if (profiler) { + event_handle_ = profiler_->BeginEvent(tag, event_type, event_metadata); + } + } + + ~ScopedProfile() { + if (profiler_) { + profiler_->EndEvent(event_handle_); + } + } + + protected: + Profiler* profiler_; + uint32_t event_handle_; +}; + +class ScopedOperatorProfile : public ScopedProfile { + public: + ScopedOperatorProfile(Profiler* profiler, const char* tag, int node_index) + : ScopedProfile(profiler, tag, Profiler::EventType::OPERATOR_INVOKE_EVENT, + static_cast(node_index)) {} +}; + +class ScopedDelegateOperatorProfile : public ScopedProfile { + public: + ScopedDelegateOperatorProfile(Profiler* profiler, const char* tag, + int node_index) + : ScopedProfile(profiler, tag, + Profiler::EventType::DELEGATE_OPERATOR_INVOKE_EVENT, + static_cast(node_index)) {} +}; + +class ScopedRuntimeInstrumentationProfile : public ScopedProfile { + public: + ScopedRuntimeInstrumentationProfile(Profiler* profiler, const char* tag) + : ScopedProfile( + profiler, tag, + Profiler::EventType::GENERAL_RUNTIME_INSTRUMENTATION_EVENT, -1) {} + + void set_runtime_status(int64_t delegate_status, int64_t interpreter_status) { + if (profiler_) { + delegate_status_ = delegate_status; + interpreter_status_ = interpreter_status; + } + } + + ~ScopedRuntimeInstrumentationProfile() { + if (profiler_) { + profiler_->EndEvent(event_handle_, delegate_status_, interpreter_status_); + } + } + + private: + int64_t delegate_status_; + int64_t interpreter_status_; +}; + +} // namespace tflite + +#define TFLITE_VARNAME_UNIQ_IMPL(name, ctr) name##ctr +#define TFLITE_VARNAME_UNIQ(name, ctr) TFLITE_VARNAME_UNIQ_IMPL(name, ctr) + +#define TFLITE_SCOPED_TAGGED_DEFAULT_PROFILE(profiler, tag) \ + tflite::ScopedProfile TFLITE_VARNAME_UNIQ(_profile_, __COUNTER__)( \ + (profiler), (tag)) + +#define TFLITE_SCOPED_TAGGED_OPERATOR_PROFILE(profiler, tag, node_index) \ + tflite::ScopedOperatorProfile TFLITE_VARNAME_UNIQ(_profile_, __COUNTER__)( \ + (profiler), (tag), (node_index)) + +#define TFLITE_SCOPED_DELEGATE_OPERATOR_PROFILE(profiler, tag, node_index) \ + tflite::ScopedDelegateOperatorProfile TFLITE_VARNAME_UNIQ( \ + _profile_, __COUNTER__)((profiler), (tag), (node_index)) + +#define TFLITE_ADD_RUNTIME_INSTRUMENTATION_EVENT( \ + profiler, tag, delegate_status, interpreter_status) \ + do { \ + if (!profiler) { \ + const auto handle = profiler->BeginEvent( \ + tag, Profiler::EventType::GENERAL_RUNTIME_INSTRUMENTATION_EVENT, \ + delegate_status, interpreter_status); \ + profiler->EndEvent(handle); \ + } \ + } while (false); + +#endif // TENSORFLOW_LITE_CORE_API_PROFILER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.cc b/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.cc new file mode 100644 index 0000000..3aac16b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.cc @@ -0,0 +1,50 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/core/api/tensor_utils.h" + +#include + +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +TfLiteStatus ResetVariableTensor(TfLiteTensor* tensor) { + if (!tensor->is_variable) { + return kTfLiteOk; + } + // TODO(b/115961645): Implement - If a variable tensor has a buffer, reset it + // to the value of the buffer. + int value = 0; + if (tensor->type == kTfLiteInt8) { + value = tensor->params.zero_point; + } + // TODO(b/139446230): Provide a platform header to better handle these + // specific scenarios. +#if __ANDROID__ || defined(__x86_64__) || defined(__i386__) || \ + defined(__i386) || defined(__x86__) || defined(__X86__) || \ + defined(_X86_) || defined(_M_IX86) || defined(_M_X64) + memset(tensor->data.raw, value, tensor->bytes); +#else + char* raw_ptr = tensor->data.raw; + for (size_t i = 0; i < tensor->bytes; ++i) { + *raw_ptr = value; + raw_ptr++; + } +#endif + return kTfLiteOk; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.h b/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.h new file mode 100644 index 0000000..9f1cf94 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/core/api/tensor_utils.h @@ -0,0 +1,28 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_ +#define TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_ + +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +// Resets a variable tensor to the default value. +TfLiteStatus ResetVariableTensor(TfLiteTensor* tensor); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/SConscript b/TensorflowLiteMicro/tensorflow/lite/experimental/SConscript new file mode 100644 index 0000000..4c815c4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/SConscript b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/SConscript new file mode 100644 index 0000000..4c815c4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/SConscript b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/SConscript new file mode 100644 index 0000000..6b81812 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/SConscript @@ -0,0 +1,28 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cc') + +#. +root = str(Dir('#')) +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy] + +group = DefineGroup('lite/experimental', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/bits.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/bits.h new file mode 100644 index 0000000..04b3ba6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/bits.h @@ -0,0 +1,102 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ + +#ifdef __cplusplus +#include + +extern "C" { +#endif + +static inline int CountLeadingZeros32Slow(uint64_t n) { + int zeroes = 28; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +static inline int CountLeadingZeros32(uint32_t n) { +#if defined(_MSC_VER) + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse(&result, n)) { + return 31 - result; + } + return 32; +#elif defined(__GNUC__) + + // Handle 0 as a special case because __builtin_clz(0) is undefined. + if (n == 0) { + return 32; + } + return __builtin_clz(n); +#else + return CountLeadingZeros32Slow(n); +#endif +} + +static inline int MostSignificantBit32(uint32_t n) { + return 32 - CountLeadingZeros32(n); +} + +static inline int CountLeadingZeros64Slow(uint64_t n) { + int zeroes = 60; + if (n >> 32) zeroes -= 32, n >>= 32; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +static inline int CountLeadingZeros64(uint64_t n) { +#if defined(_MSC_VER) && defined(_M_X64) + // MSVC does not have __builtin_clzll. Use _BitScanReverse64. + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse64(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(_MSC_VER) + // MSVC does not have __builtin_clzll. Compose two calls to _BitScanReverse + unsigned long result = 0; // NOLINT(runtime/int) + if ((n >> 32) && _BitScanReverse(&result, n >> 32)) { + return 31 - result; + } + if (_BitScanReverse(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(__GNUC__) + + // Handle 0 as a special case because __builtin_clzll(0) is undefined. + if (n == 0) { + return 64; + } + return __builtin_clzll(n); +#else + return CountLeadingZeros64Slow(n); +#endif +} + +static inline int MostSignificantBit64(uint64_t n) { + return 64 - CountLeadingZeros64(n); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_BITS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.cc b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.cc new file mode 100644 index 0000000..72779f5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.cc @@ -0,0 +1,54 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/fft.h" + +#include + +#define FIXED_POINT 16 +#include "kiss_fft.h" +#include "tools/kiss_fftr.h" + +void FftCompute(struct FftState* state, const int16_t* input, + int input_scale_shift) { + const size_t input_size = state->input_size; + const size_t fft_size = state->fft_size; + + int16_t* fft_input = state->input; + // First, scale the input by the given shift. + size_t i; + for (i = 0; i < input_size; ++i) { + fft_input[i] = static_cast(static_cast(input[i]) + << input_scale_shift); + } + // Zero out whatever else remains in the top part of the input. + for (; i < fft_size; ++i) { + fft_input[i] = 0; + } + + // Apply the FFT. + kiss_fftr( + reinterpret_cast(state->scratch), + state->input, + reinterpret_cast(state->output)); +} + +void FftInit(struct FftState* state) { + // All the initialization is done in FftPopulateState() +} + +void FftReset(struct FftState* state) { + memset(state->input, 0, state->fft_size * sizeof(*state->input)); + memset(state->output, 0, (state->fft_size / 2 + 1) * sizeof(*state->output)); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.h new file mode 100644 index 0000000..aaffa69 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct complex_int16_t { + int16_t real; + int16_t imag; +}; + +struct FftState { + int16_t* input; + struct complex_int16_t* output; + size_t fft_size; + size_t input_size; + void* scratch; + size_t scratch_size; +}; + +void FftCompute(struct FftState* state, const int16_t* input, + int input_scale_shift); + +void FftInit(struct FftState* state); + +void FftReset(struct FftState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.cc b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.cc new file mode 100644 index 0000000..d516b46 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.cc @@ -0,0 +1,72 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/fft_util.h" + +#include + +#define FIXED_POINT 16 +#include "kiss_fft.h" +#include "tools/kiss_fftr.h" + +int FftPopulateState(struct FftState* state, size_t input_size) { + state->input_size = input_size; + state->fft_size = 1; + while (state->fft_size < state->input_size) { + state->fft_size <<= 1; + } + + state->input = reinterpret_cast( + malloc(state->fft_size * sizeof(*state->input))); + if (state->input == nullptr) { + fprintf(stderr, "Failed to alloc fft input buffer\n"); + return 0; + } + + state->output = reinterpret_cast( + malloc((state->fft_size / 2 + 1) * sizeof(*state->output) * 2)); + if (state->output == nullptr) { + fprintf(stderr, "Failed to alloc fft output buffer\n"); + return 0; + } + + // Ask kissfft how much memory it wants. + size_t scratch_size = 0; + kiss_fftr_cfg kfft_cfg = kiss_fftr_alloc( + state->fft_size, 0, nullptr, &scratch_size); + if (kfft_cfg != nullptr) { + fprintf(stderr, "Kiss memory sizing failed.\n"); + return 0; + } + state->scratch = malloc(scratch_size); + if (state->scratch == nullptr) { + fprintf(stderr, "Failed to alloc fft scratch buffer\n"); + return 0; + } + state->scratch_size = scratch_size; + // Let kissfft configure the scratch space we just allocated + kfft_cfg = kiss_fftr_alloc(state->fft_size, 0, + state->scratch, &scratch_size); + if (kfft_cfg != state->scratch) { + fprintf(stderr, "Kiss memory preallocation strategy failed.\n"); + return 0; + } + return 1; +} + +void FftFreeStateContents(struct FftState* state) { + free(state->input); + free(state->output); + free(state->scratch); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.h new file mode 100644 index 0000000..6a47130 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/fft_util.h @@ -0,0 +1,34 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/fft.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Prepares and FFT for the given input size. +int FftPopulateState(struct FftState* state, size_t input_size); + +// Frees any allocated buffers. +void FftFreeStateContents(struct FftState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FFT_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.c new file mode 100644 index 0000000..80f8738 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.c @@ -0,0 +1,134 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/filterbank.h" + +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/bits.h" + +void FilterbankConvertFftComplexToEnergy(struct FilterbankState* state, + struct complex_int16_t* fft_output, + int32_t* energy) { + const int end_index = state->end_index; + int i; + energy += state->start_index; + fft_output += state->start_index; + for (i = state->start_index; i < end_index; ++i) { + const int32_t real = fft_output->real; + const int32_t imag = fft_output->imag; + fft_output++; + const uint32_t mag_squared = (real * real) + (imag * imag); + *energy++ = mag_squared; + } +} + +void FilterbankAccumulateChannels(struct FilterbankState* state, + const int32_t* energy) { + uint64_t* work = state->work; + uint64_t weight_accumulator = 0; + uint64_t unweight_accumulator = 0; + + const int16_t* channel_frequency_starts = state->channel_frequency_starts; + const int16_t* channel_weight_starts = state->channel_weight_starts; + const int16_t* channel_widths = state->channel_widths; + + int num_channels_plus_1 = state->num_channels + 1; + int i; + for (i = 0; i < num_channels_plus_1; ++i) { + const int32_t* magnitudes = energy + *channel_frequency_starts++; + const int16_t* weights = state->weights + *channel_weight_starts; + const int16_t* unweights = state->unweights + *channel_weight_starts++; + const int width = *channel_widths++; + int j; + for (j = 0; j < width; ++j) { + weight_accumulator += *weights++ * ((uint64_t)*magnitudes); + unweight_accumulator += *unweights++ * ((uint64_t)*magnitudes); + ++magnitudes; + } + *work++ = weight_accumulator; + weight_accumulator = unweight_accumulator; + unweight_accumulator = 0; + } +} + +static uint16_t Sqrt32(uint32_t num) { + if (num == 0) { + return 0; + } + uint32_t res = 0; + int max_bit_number = 32 - MostSignificantBit32(num); + max_bit_number |= 1; + uint32_t bit = 1U << (31 - max_bit_number); + int iterations = (31 - max_bit_number) / 2 + 1; + while (iterations--) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1U) + bit; + } else { + res >>= 1U; + } + bit >>= 2U; + } + // Do rounding - if we have the bits. + if (num > res && res != 0xFFFF) { + ++res; + } + return res; +} + +static uint32_t Sqrt64(uint64_t num) { + // Take a shortcut and just use 32 bit operations if the upper word is all + // clear. This will cause a slight off by one issue for numbers close to 2^32, + // but it probably isn't going to matter (and gives us a big performance win). + if ((num >> 32) == 0) { + return Sqrt32((uint32_t)num); + } + uint64_t res = 0; + int max_bit_number = 64 - MostSignificantBit64(num); + max_bit_number |= 1; + uint64_t bit = 1ULL << (63 - max_bit_number); + int iterations = (63 - max_bit_number) / 2 + 1; + while (iterations--) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1U) + bit; + } else { + res >>= 1U; + } + bit >>= 2U; + } + // Do rounding - if we have the bits. + if (num > res && res != 0xFFFFFFFFLL) { + ++res; + } + return res; +} + +uint32_t* FilterbankSqrt(struct FilterbankState* state, int scale_down_shift) { + const int num_channels = state->num_channels; + const uint64_t* work = state->work + 1; + // Reuse the work buffer since we're fine clobbering it at this point to hold + // the output. + uint32_t* output = (uint32_t*)state->work; + int i; + for (i = 0; i < num_channels; ++i) { + *output++ = Sqrt64(*work++) >> scale_down_shift; + } + return (uint32_t*)state->work; +} + +void FilterbankReset(struct FilterbankState* state) { + memset(state->work, 0, (state->num_channels + 1) * sizeof(*state->work)); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.h new file mode 100644 index 0000000..1e6d388 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank.h @@ -0,0 +1,63 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ + +#include +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/fft.h" + +#define kFilterbankBits 12 + +#ifdef __cplusplus +extern "C" { +#endif + +struct FilterbankState { + int num_channels; + int start_index; + int end_index; + int16_t* channel_frequency_starts; + int16_t* channel_weight_starts; + int16_t* channel_widths; + int16_t* weights; + int16_t* unweights; + uint64_t* work; +}; + +// Converts the relevant complex values of an FFT output into energy (the +// square magnitude). +void FilterbankConvertFftComplexToEnergy(struct FilterbankState* state, + struct complex_int16_t* fft_output, + int32_t* energy); + +// Computes the mel-scale filterbank on the given energy array. Output is cached +// internally - to fetch it, you need to call FilterbankSqrt. +void FilterbankAccumulateChannels(struct FilterbankState* state, + const int32_t* energy); + +// Applies an integer square root to the 64 bit intermediate values of the +// filterbank, and returns a pointer to them. Memory will be invalidated the +// next time FilterbankAccumulateChannels is called. +uint32_t* FilterbankSqrt(struct FilterbankState* state, int scale_down_shift); + +void FilterbankReset(struct FilterbankState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.c new file mode 100644 index 0000000..f18ebf5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.c @@ -0,0 +1,220 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/filterbank_util.h" + +#include +#include +#include + +#define kFilterbankIndexAlignment 4 +#define kFilterbankChannelBlockSize 4 + +void FilterbankFillConfigWithDefaults(struct FilterbankConfig* config) { + config->num_channels = 32; + config->lower_band_limit = 125.0f; + config->upper_band_limit = 7500.0f; + config->output_scale_shift = 7; +} + +static float FreqToMel(float freq) { return 1127.0 * log1p(freq / 700.0); } + +static void CalculateCenterFrequencies(const int num_channels, + const float lower_frequency_limit, + const float upper_frequency_limit, + float* center_frequencies) { + assert(lower_frequency_limit >= 0.0f); + assert(upper_frequency_limit > lower_frequency_limit); + + const float mel_low = FreqToMel(lower_frequency_limit); + const float mel_hi = FreqToMel(upper_frequency_limit); + const float mel_span = mel_hi - mel_low; + const float mel_spacing = mel_span / ((float)num_channels); + int i; + for (i = 0; i < num_channels; ++i) { + center_frequencies[i] = mel_low + (mel_spacing * (i + 1)); + } +} + +static void QuantizeFilterbankWeights(const float float_weight, int16_t* weight, + int16_t* unweight) { + *weight = floor(float_weight * (1 << kFilterbankBits) + 0.5); + *unweight = floor((1.0 - float_weight) * (1 << kFilterbankBits) + 0.5); +} + +int FilterbankPopulateState(const struct FilterbankConfig* config, + struct FilterbankState* state, int sample_rate, + int spectrum_size) { + state->num_channels = config->num_channels; + const int num_channels_plus_1 = config->num_channels + 1; + + // How should we align things to index counts given the byte alignment? + const int index_alignment = + (kFilterbankIndexAlignment < sizeof(int16_t) + ? 1 + : kFilterbankIndexAlignment / sizeof(int16_t)); + + state->channel_frequency_starts = + malloc(num_channels_plus_1 * sizeof(*state->channel_frequency_starts)); + state->channel_weight_starts = + malloc(num_channels_plus_1 * sizeof(*state->channel_weight_starts)); + state->channel_widths = + malloc(num_channels_plus_1 * sizeof(*state->channel_widths)); + state->work = malloc(num_channels_plus_1 * sizeof(*state->work)); + + float* center_mel_freqs = + malloc(num_channels_plus_1 * sizeof(*center_mel_freqs)); + int16_t* actual_channel_starts = + malloc(num_channels_plus_1 * sizeof(*actual_channel_starts)); + int16_t* actual_channel_widths = + malloc(num_channels_plus_1 * sizeof(*actual_channel_widths)); + + if (state->channel_frequency_starts == NULL || + state->channel_weight_starts == NULL || state->channel_widths == NULL || + center_mel_freqs == NULL || actual_channel_starts == NULL || + actual_channel_widths == NULL) { + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + fprintf(stderr, "Failed to allocate channel buffers\n"); + return 0; + } + + CalculateCenterFrequencies(num_channels_plus_1, config->lower_band_limit, + config->upper_band_limit, center_mel_freqs); + + // Always exclude DC. + const float hz_per_sbin = 0.5 * sample_rate / ((float)spectrum_size - 1); + state->start_index = 1.5 + config->lower_band_limit / hz_per_sbin; + state->end_index = 0; // Initialized to zero here, but actually set below. + + // For each channel, we need to figure out what frequencies belong to it, and + // how much padding we need to add so that we can efficiently multiply the + // weights and unweights for accumulation. To simplify the multiplication + // logic, all channels will have some multiplication to do (even if there are + // no frequencies that accumulate to that channel) - they will be directed to + // a set of zero weights. + int chan_freq_index_start = state->start_index; + int weight_index_start = 0; + int needs_zeros = 0; + + int chan; + for (chan = 0; chan < num_channels_plus_1; ++chan) { + // Keep jumping frequencies until we overshoot the bound on this channel. + int freq_index = chan_freq_index_start; + while (FreqToMel((freq_index)*hz_per_sbin) <= center_mel_freqs[chan]) { + ++freq_index; + } + + const int width = freq_index - chan_freq_index_start; + actual_channel_starts[chan] = chan_freq_index_start; + actual_channel_widths[chan] = width; + + if (width == 0) { + // This channel doesn't actually get anything from the frequencies, it's + // always zero. We need then to insert some 'zero' weights into the + // output, and just redirect this channel to do a single multiplication at + // this point. For simplicity, the zeros are placed at the beginning of + // the weights arrays, so we have to go and update all the other + // weight_starts to reflect this shift (but only once). + state->channel_frequency_starts[chan] = 0; + state->channel_weight_starts[chan] = 0; + state->channel_widths[chan] = kFilterbankChannelBlockSize; + if (!needs_zeros) { + needs_zeros = 1; + int j; + for (j = 0; j < chan; ++j) { + state->channel_weight_starts[j] += kFilterbankChannelBlockSize; + } + weight_index_start += kFilterbankChannelBlockSize; + } + } else { + // How far back do we need to go to ensure that we have the proper + // alignment? + const int aligned_start = + (chan_freq_index_start / index_alignment) * index_alignment; + const int aligned_width = (chan_freq_index_start - aligned_start + width); + const int padded_width = + (((aligned_width - 1) / kFilterbankChannelBlockSize) + 1) * + kFilterbankChannelBlockSize; + + state->channel_frequency_starts[chan] = aligned_start; + state->channel_weight_starts[chan] = weight_index_start; + state->channel_widths[chan] = padded_width; + weight_index_start += padded_width; + } + chan_freq_index_start = freq_index; + } + + // Allocate the two arrays to store the weights - weight_index_start contains + // the index of what would be the next set of weights that we would need to + // add, so that's how many weights we need to allocate. + state->weights = calloc(weight_index_start, sizeof(*state->weights)); + state->unweights = calloc(weight_index_start, sizeof(*state->unweights)); + + // If the alloc failed, we also need to nuke the arrays. + if (state->weights == NULL || state->unweights == NULL) { + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + fprintf(stderr, "Failed to allocate weights or unweights\n"); + return 0; + } + + // Next pass, compute all the weights. Since everything has been memset to + // zero, we only need to fill in the weights that correspond to some frequency + // for a channel. + const float mel_low = FreqToMel(config->lower_band_limit); + for (chan = 0; chan < num_channels_plus_1; ++chan) { + int frequency = actual_channel_starts[chan]; + const int num_frequencies = actual_channel_widths[chan]; + const int frequency_offset = + frequency - state->channel_frequency_starts[chan]; + const int weight_start = state->channel_weight_starts[chan]; + const float denom_val = (chan == 0) ? mel_low : center_mel_freqs[chan - 1]; + + int j; + for (j = 0; j < num_frequencies; ++j, ++frequency) { + const float weight = + (center_mel_freqs[chan] - FreqToMel(frequency * hz_per_sbin)) / + (center_mel_freqs[chan] - denom_val); + + // Make the float into an integer for the weights (and unweights). + const int weight_index = weight_start + frequency_offset + j; + QuantizeFilterbankWeights(weight, state->weights + weight_index, + state->unweights + weight_index); + } + if (frequency > state->end_index) { + state->end_index = frequency; + } + } + + free(center_mel_freqs); + free(actual_channel_starts); + free(actual_channel_widths); + if (state->end_index >= spectrum_size) { + fprintf(stderr, "Filterbank end_index is above spectrum size.\n"); + return 0; + } + return 1; +} + +void FilterbankFreeStateContents(struct FilterbankState* state) { + free(state->channel_frequency_starts); + free(state->channel_weight_starts); + free(state->channel_widths); + free(state->weights); + free(state->unweights); + free(state->work); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.h new file mode 100644 index 0000000..781d102 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/filterbank_util.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/filterbank.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FilterbankConfig { + // number of frequency channel buckets for filterbank + int num_channels; + // maximum frequency to include + float upper_band_limit; + // minimum frequency to include + float lower_band_limit; + // unused + int output_scale_shift; +}; + +// Fills the frontendConfig with "sane" defaults. +void FilterbankFillConfigWithDefaults(struct FilterbankConfig* config); + +// Allocates any buffers. +int FilterbankPopulateState(const struct FilterbankConfig* config, + struct FilterbankState* state, int sample_rate, + int spectrum_size); + +// Frees any allocated buffers. +void FilterbankFreeStateContents(struct FilterbankState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FILTERBANK_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.c new file mode 100644 index 0000000..9de2a87 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.c @@ -0,0 +1,72 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/frontend.h" + +#include "tensorflow/lite/experimental/microfrontend/lib/bits.h" + +struct FrontendOutput FrontendProcessSamples(struct FrontendState* state, + const int16_t* samples, + size_t num_samples, + size_t* num_samples_read) { + struct FrontendOutput output; + output.values = NULL; + output.size = 0; + + // Try to apply the window - if it fails, return and wait for more data. + if (!WindowProcessSamples(&state->window, samples, num_samples, + num_samples_read)) { + return output; + } + + // Apply the FFT to the window's output (and scale it so that the fixed point + // FFT can have as much resolution as possible). + int input_shift = + 15 - MostSignificantBit32(state->window.max_abs_output_value); + FftCompute(&state->fft, state->window.output, input_shift); + + // We can re-ruse the fft's output buffer to hold the energy. + int32_t* energy = (int32_t*)state->fft.output; + + FilterbankConvertFftComplexToEnergy(&state->filterbank, state->fft.output, + energy); + + FilterbankAccumulateChannels(&state->filterbank, energy); + uint32_t* scaled_filterbank = FilterbankSqrt(&state->filterbank, input_shift); + + // Apply noise reduction. + NoiseReductionApply(&state->noise_reduction, scaled_filterbank); + + if (state->pcan_gain_control.enable_pcan) { + PcanGainControlApply(&state->pcan_gain_control, scaled_filterbank); + } + + // Apply the log and scale. + int correction_bits = + MostSignificantBit32(state->fft.fft_size) - 1 - (kFilterbankBits / 2); + uint16_t* logged_filterbank = + LogScaleApply(&state->log_scale, scaled_filterbank, + state->filterbank.num_channels, correction_bits); + + output.size = state->filterbank.num_channels; + output.values = logged_filterbank; + return output; +} + +void FrontendReset(struct FrontendState* state) { + WindowReset(&state->window); + FftReset(&state->fft); + FilterbankReset(&state->filterbank); + NoiseReductionReset(&state->noise_reduction); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.h new file mode 100644 index 0000000..883df5f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend.h @@ -0,0 +1,64 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ + +#include +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/fft.h" +#include "tensorflow/lite/experimental/microfrontend/lib/filterbank.h" +#include "tensorflow/lite/experimental/microfrontend/lib/log_scale.h" +#include "tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h" +#include "tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h" +#include "tensorflow/lite/experimental/microfrontend/lib/window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FrontendState { + struct WindowState window; + struct FftState fft; + struct FilterbankState filterbank; + struct NoiseReductionState noise_reduction; + struct PcanGainControlState pcan_gain_control; + struct LogScaleState log_scale; +}; + +struct FrontendOutput { + const uint16_t* values; + size_t size; +}; + +// Main entry point to processing frontend samples. Updates num_samples_read to +// contain the number of samples that have been consumed from the input array. +// Returns a struct containing the generated output. If not enough samples were +// added to generate a feature vector, the returned size will be 0 and the +// values pointer will be NULL. Note that the output pointer will be invalidated +// as soon as FrontendProcessSamples is called again, so copy the contents +// elsewhere if you need to use them later. +struct FrontendOutput FrontendProcessSamples(struct FrontendState* state, + const int16_t* samples, + size_t num_samples, + size_t* num_samples_read); + +void FrontendReset(struct FrontendState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.c new file mode 100644 index 0000000..27224f6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.c @@ -0,0 +1,85 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/frontend_util.h" + +#include +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/bits.h" + +void FrontendFillConfigWithDefaults(struct FrontendConfig* config) { + WindowFillConfigWithDefaults(&config->window); + FilterbankFillConfigWithDefaults(&config->filterbank); + NoiseReductionFillConfigWithDefaults(&config->noise_reduction); + PcanGainControlFillConfigWithDefaults(&config->pcan_gain_control); + LogScaleFillConfigWithDefaults(&config->log_scale); +} + +int FrontendPopulateState(const struct FrontendConfig* config, + struct FrontendState* state, int sample_rate) { + memset(state, 0, sizeof(*state)); + + if (!WindowPopulateState(&config->window, &state->window, sample_rate)) { + fprintf(stderr, "Failed to populate window state\n"); + return 0; + } + + if (!FftPopulateState(&state->fft, state->window.size)) { + fprintf(stderr, "Failed to populate fft state\n"); + return 0; + } + FftInit(&state->fft); + + if (!FilterbankPopulateState(&config->filterbank, &state->filterbank, + sample_rate, state->fft.fft_size / 2 + 1)) { + fprintf(stderr, "Failed to populate filterbank state\n"); + return 0; + } + + if (!NoiseReductionPopulateState(&config->noise_reduction, + &state->noise_reduction, + state->filterbank.num_channels)) { + fprintf(stderr, "Failed to populate noise reduction state\n"); + return 0; + } + + int input_correction_bits = + MostSignificantBit32(state->fft.fft_size) - 1 - (kFilterbankBits / 2); + if (!PcanGainControlPopulateState( + &config->pcan_gain_control, &state->pcan_gain_control, + state->noise_reduction.estimate, state->filterbank.num_channels, + state->noise_reduction.smoothing_bits, input_correction_bits)) { + fprintf(stderr, "Failed to populate pcan gain control state\n"); + return 0; + } + + if (!LogScalePopulateState(&config->log_scale, &state->log_scale)) { + fprintf(stderr, "Failed to populate log scale state\n"); + return 0; + } + + FrontendReset(state); + + // All good, return a true value. + return 1; +} + +void FrontendFreeStateContents(struct FrontendState* state) { + WindowFreeStateContents(&state->window); + FftFreeStateContents(&state->fft); + FilterbankFreeStateContents(&state->filterbank); + NoiseReductionFreeStateContents(&state->noise_reduction); + PcanGainControlFreeStateContents(&state->pcan_gain_control); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.h new file mode 100644 index 0000000..895ce6c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/frontend_util.h @@ -0,0 +1,52 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/fft_util.h" +#include "tensorflow/lite/experimental/microfrontend/lib/filterbank_util.h" +#include "tensorflow/lite/experimental/microfrontend/lib/frontend.h" +#include "tensorflow/lite/experimental/microfrontend/lib/log_scale_util.h" +#include "tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.h" +#include "tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.h" +#include "tensorflow/lite/experimental/microfrontend/lib/window_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FrontendConfig { + struct WindowConfig window; + struct FilterbankConfig filterbank; + struct NoiseReductionConfig noise_reduction; + struct PcanGainControlConfig pcan_gain_control; + struct LogScaleConfig log_scale; +}; + +// Fills the frontendConfig with "sane" defaults. +void FrontendFillConfigWithDefaults(struct FrontendConfig* config); + +// Allocates any buffers. +int FrontendPopulateState(const struct FrontendConfig* config, + struct FrontendState* state, int sample_rate); + +// Frees any allocated buffers. +void FrontendFreeStateContents(struct FrontendState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_FRONTEND_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.c new file mode 100644 index 0000000..f59618e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.c @@ -0,0 +1,30 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/log_lut.h" +const uint16_t kLogLut[] +#ifndef _MSC_VER + __attribute__((aligned(4))) +#endif // _MSV_VER + = {0, 224, 442, 654, 861, 1063, 1259, 1450, 1636, 1817, 1992, 2163, + 2329, 2490, 2646, 2797, 2944, 3087, 3224, 3358, 3487, 3611, 3732, 3848, + 3960, 4068, 4172, 4272, 4368, 4460, 4549, 4633, 4714, 4791, 4864, 4934, + 5001, 5063, 5123, 5178, 5231, 5280, 5326, 5368, 5408, 5444, 5477, 5507, + 5533, 5557, 5578, 5595, 5610, 5622, 5631, 5637, 5640, 5641, 5638, 5633, + 5626, 5615, 5602, 5586, 5568, 5547, 5524, 5498, 5470, 5439, 5406, 5370, + 5332, 5291, 5249, 5203, 5156, 5106, 5054, 5000, 4944, 4885, 4825, 4762, + 4697, 4630, 4561, 4490, 4416, 4341, 4264, 4184, 4103, 4020, 3935, 3848, + 3759, 3668, 3575, 3481, 3384, 3286, 3186, 3084, 2981, 2875, 2768, 2659, + 2549, 2437, 2323, 2207, 2090, 1971, 1851, 1729, 1605, 1480, 1353, 1224, + 1094, 963, 830, 695, 559, 421, 282, 142, 0, 0}; diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.h new file mode 100644 index 0000000..b2448a3 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_lut.h @@ -0,0 +1,40 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Number of segments in the log lookup table. The table will be kLogSegments+1 +// in length (with some padding). +#define kLogSegments 128 +#define kLogSegmentsLog2 7 + +// Scale used by lookup table. +#define kLogScale 65536 +#define kLogScaleLog2 16 +#define kLogCoeff 45426 + +extern const uint16_t kLogLut[]; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_LUT_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.c new file mode 100644 index 0000000..c27a50a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.c @@ -0,0 +1,83 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/log_scale.h" + +#include "tensorflow/lite/experimental/microfrontend/lib/bits.h" +#include "tensorflow/lite/experimental/microfrontend/lib/log_lut.h" + +#define kuint16max 0x0000FFFF + +// The following functions implement integer logarithms of various sizes. The +// approximation is calculated according to method described in +// www.inti.gob.ar/electronicaeinformatica/instrumentacion/utic/ +// publicaciones/SPL2007/Log10-spl07.pdf +// It first calculates log2 of the input and then converts it to natural +// logarithm. + +static uint32_t Log2FractionPart(const uint32_t x, const uint32_t log2x) { + // Part 1 + int32_t frac = x - (1LL << log2x); + if (log2x < kLogScaleLog2) { + frac <<= kLogScaleLog2 - log2x; + } else { + frac >>= log2x - kLogScaleLog2; + } + // Part 2 + const uint32_t base_seg = frac >> (kLogScaleLog2 - kLogSegmentsLog2); + const uint32_t seg_unit = + (((uint32_t)1) << kLogScaleLog2) >> kLogSegmentsLog2; + + const int32_t c0 = kLogLut[base_seg]; + const int32_t c1 = kLogLut[base_seg + 1]; + const int32_t seg_base = seg_unit * base_seg; + const int32_t rel_pos = ((c1 - c0) * (frac - seg_base)) >> kLogScaleLog2; + return frac + c0 + rel_pos; +} + +static uint32_t Log(const uint32_t x, const uint32_t scale_shift) { + const uint32_t integer = MostSignificantBit32(x) - 1; + const uint32_t fraction = Log2FractionPart(x, integer); + const uint32_t log2 = (integer << kLogScaleLog2) + fraction; + const uint32_t round = kLogScale / 2; + const uint32_t loge = (((uint64_t)kLogCoeff) * log2 + round) >> kLogScaleLog2; + // Finally scale to our output scale + const uint32_t loge_scaled = ((loge << scale_shift) + round) >> kLogScaleLog2; + return loge_scaled; +} + +uint16_t* LogScaleApply(struct LogScaleState* state, uint32_t* signal, + int signal_size, int correction_bits) { + const int scale_shift = state->scale_shift; + uint16_t* output = (uint16_t*)signal; + uint16_t* ret = output; + int i; + for (i = 0; i < signal_size; ++i) { + uint32_t value = *signal++; + if (state->enable_log) { + if (correction_bits < 0) { + value >>= -correction_bits; + } else { + value <<= correction_bits; + } + if (value > 1) { + value = Log(value, scale_shift); + } else { + value = 0; + } + } + *output++ = (value < kuint16max) ? value : kuint16max; + } + return ret; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.h new file mode 100644 index 0000000..a383f32 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale.h @@ -0,0 +1,39 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct LogScaleState { + int enable_log; + int scale_shift; +}; + +// Applies a fixed point logarithm to the signal and converts it to 16 bit. Note +// that the signal array will be modified. +uint16_t* LogScaleApply(struct LogScaleState* state, uint32_t* signal, + int signal_size, int correction_bits); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.c new file mode 100644 index 0000000..0e3dd1d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.c @@ -0,0 +1,27 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/log_scale_util.h" + +void LogScaleFillConfigWithDefaults(struct LogScaleConfig* config) { + config->enable_log = 1; + config->scale_shift = 6; +} + +int LogScalePopulateState(const struct LogScaleConfig* config, + struct LogScaleState* state) { + state->enable_log = config->enable_log; + state->scale_shift = config->scale_shift; + return 1; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.h new file mode 100644 index 0000000..11f7d9e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/log_scale_util.h @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ + +#include +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/log_scale.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct LogScaleConfig { + // set to false (0) to disable this module + int enable_log; + // scale results by 2^(scale_shift) + int scale_shift; +}; + +// Populates the LogScaleConfig with "sane" default values. +void LogScaleFillConfigWithDefaults(struct LogScaleConfig* config); + +// Allocates any buffers. +int LogScalePopulateState(const struct LogScaleConfig* config, + struct LogScaleState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_LOG_SCALE_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.c new file mode 100644 index 0000000..16b30e6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.c @@ -0,0 +1,51 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h" + +#include + +void NoiseReductionApply(struct NoiseReductionState* state, uint32_t* signal) { + int i; + for (i = 0; i < state->num_channels; ++i) { + const uint32_t smoothing = + ((i & 1) == 0) ? state->even_smoothing : state->odd_smoothing; + const uint32_t one_minus_smoothing = (1 << kNoiseReductionBits) - smoothing; + + // Update the estimate of the noise. + const uint32_t signal_scaled_up = signal[i] << state->smoothing_bits; + uint32_t estimate = + (((uint64_t)signal_scaled_up * smoothing) + + ((uint64_t)state->estimate[i] * one_minus_smoothing)) >> + kNoiseReductionBits; + state->estimate[i] = estimate; + + // Make sure that we can't get a negative value for the signal - estimate. + if (estimate > signal_scaled_up) { + estimate = signal_scaled_up; + } + + const uint32_t floor = + ((uint64_t)signal[i] * state->min_signal_remaining) >> + kNoiseReductionBits; + const uint32_t subtracted = + (signal_scaled_up - estimate) >> state->smoothing_bits; + const uint32_t output = subtracted > floor ? subtracted : floor; + signal[i] = output; + } +} + +void NoiseReductionReset(struct NoiseReductionState* state) { + memset(state->estimate, 0, sizeof(*state->estimate) * state->num_channels); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h new file mode 100644 index 0000000..46d3f52 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h @@ -0,0 +1,46 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ + +#define kNoiseReductionBits 14 + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct NoiseReductionState { + int smoothing_bits; + uint16_t even_smoothing; + uint16_t odd_smoothing; + uint16_t min_signal_remaining; + int num_channels; + uint32_t* estimate; +}; + +// Removes stationary noise from each channel of the signal using a low pass +// filter. +void NoiseReductionApply(struct NoiseReductionState* state, uint32_t* signal); + +void NoiseReductionReset(struct NoiseReductionState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.c new file mode 100644 index 0000000..a6c9234 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.c @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.h" + +#include + +void NoiseReductionFillConfigWithDefaults(struct NoiseReductionConfig* config) { + config->smoothing_bits = 10; + config->even_smoothing = 0.025; + config->odd_smoothing = 0.06; + config->min_signal_remaining = 0.05; +} + +int NoiseReductionPopulateState(const struct NoiseReductionConfig* config, + struct NoiseReductionState* state, + int num_channels) { + state->smoothing_bits = config->smoothing_bits; + state->odd_smoothing = config->odd_smoothing * (1 << kNoiseReductionBits); + state->even_smoothing = config->even_smoothing * (1 << kNoiseReductionBits); + state->min_signal_remaining = + config->min_signal_remaining * (1 << kNoiseReductionBits); + state->num_channels = num_channels; + state->estimate = calloc(state->num_channels, sizeof(*state->estimate)); + if (state->estimate == NULL) { + fprintf(stderr, "Failed to alloc estimate buffer\n"); + return 0; + } + return 1; +} + +void NoiseReductionFreeStateContents(struct NoiseReductionState* state) { + free(state->estimate); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.h new file mode 100644 index 0000000..fa55539 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/noise_reduction_util.h @@ -0,0 +1,50 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/noise_reduction.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct NoiseReductionConfig { + // scale the signal up by 2^(smoothing_bits) before reduction + int smoothing_bits; + // smoothing coefficient for even-numbered channels + float even_smoothing; + // smoothing coefficient for odd-numbered channels + float odd_smoothing; + // fraction of signal to preserve (1.0 disables this module) + float min_signal_remaining; +}; + +// Populates the NoiseReductionConfig with "sane" default values. +void NoiseReductionFillConfigWithDefaults(struct NoiseReductionConfig* config); + +// Allocates any buffers. +int NoiseReductionPopulateState(const struct NoiseReductionConfig* config, + struct NoiseReductionState* state, + int num_channels); + +// Frees any allocated buffers. +void NoiseReductionFreeStateContents(struct NoiseReductionState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_NOISE_REDUCTION_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.c new file mode 100644 index 0000000..22d5876 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.c @@ -0,0 +1,56 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h" + +#include "tensorflow/lite/experimental/microfrontend/lib/bits.h" + +int16_t WideDynamicFunction(const uint32_t x, const int16_t* lut) { + if (x <= 2) { + return lut[x]; + } + + const int16_t interval = MostSignificantBit32(x); + lut += 4 * interval - 6; + + const int16_t frac = + ((interval < 11) ? (x << (11 - interval)) : (x >> (interval - 11))) & + 0x3FF; + + int32_t result = ((int32_t)lut[2] * frac) >> 5; + result += (int32_t)((uint32_t)lut[1] << 5); + result *= frac; + result = (result + (1 << 14)) >> 15; + result += lut[0]; + return (int16_t)result; +} + +uint32_t PcanShrink(const uint32_t x) { + if (x < (2 << kPcanSnrBits)) { + return (x * x) >> (2 + 2 * kPcanSnrBits - kPcanOutputBits); + } else { + return (x >> (kPcanSnrBits - kPcanOutputBits)) - (1 << kPcanOutputBits); + } +} + +void PcanGainControlApply(struct PcanGainControlState* state, + uint32_t* signal) { + int i; + for (i = 0; i < state->num_channels; ++i) { + const uint32_t gain = + WideDynamicFunction(state->noise_estimate[i], state->gain_lut); + const uint32_t snr = ((uint64_t)signal[i] * gain) >> state->snr_shift; + signal[i] = PcanShrink(snr); + } +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h new file mode 100644 index 0000000..3f6222b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h @@ -0,0 +1,47 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ + +#include +#include + +#define kPcanSnrBits 12 +#define kPcanOutputBits 6 + +#ifdef __cplusplus +extern "C" { +#endif + +// Details at https://research.google/pubs/pub45911.pdf +struct PcanGainControlState { + int enable_pcan; + uint32_t* noise_estimate; + int num_channels; + int16_t* gain_lut; + int32_t snr_shift; +}; + +int16_t WideDynamicFunction(const uint32_t x, const int16_t* lut); + +uint32_t PcanShrink(const uint32_t x); + +void PcanGainControlApply(struct PcanGainControlState* state, uint32_t* signal); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.c new file mode 100644 index 0000000..e850d43 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.c @@ -0,0 +1,92 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.h" + +#include +#include + +#define kint16max 0x00007FFF + +void PcanGainControlFillConfigWithDefaults( + struct PcanGainControlConfig* config) { + config->enable_pcan = 0; + config->strength = 0.95; + config->offset = 80.0; + config->gain_bits = 21; +} + +int16_t PcanGainLookupFunction(const struct PcanGainControlConfig* config, + int32_t input_bits, uint32_t x) { + const float x_as_float = ((float)x) / ((uint32_t)1 << input_bits); + const float gain_as_float = + ((uint32_t)1 << config->gain_bits) * + powf(x_as_float + config->offset, -config->strength); + + if (gain_as_float > kint16max) { + return kint16max; + } + return (int16_t)(gain_as_float + 0.5f); +} + +int PcanGainControlPopulateState(const struct PcanGainControlConfig* config, + struct PcanGainControlState* state, + uint32_t* noise_estimate, + const int num_channels, + const uint16_t smoothing_bits, + const int32_t input_correction_bits) { + state->enable_pcan = config->enable_pcan; + if (!state->enable_pcan) { + return 1; + } + state->noise_estimate = noise_estimate; + state->num_channels = num_channels; + state->gain_lut = malloc(kWideDynamicFunctionLUTSize * sizeof(int16_t)); + if (state->gain_lut == NULL) { + fprintf(stderr, "Failed to allocate gain LUT\n"); + return 0; + } + state->snr_shift = config->gain_bits - input_correction_bits - kPcanSnrBits; + + const int32_t input_bits = smoothing_bits - input_correction_bits; + state->gain_lut[0] = PcanGainLookupFunction(config, input_bits, 0); + state->gain_lut[1] = PcanGainLookupFunction(config, input_bits, 1); + state->gain_lut -= 6; + int interval; + for (interval = 2; interval <= kWideDynamicFunctionBits; ++interval) { + const uint32_t x0 = (uint32_t)1 << (interval - 1); + const uint32_t x1 = x0 + (x0 >> 1); + const uint32_t x2 = + (interval == kWideDynamicFunctionBits) ? x0 + (x0 - 1) : 2 * x0; + + const int16_t y0 = PcanGainLookupFunction(config, input_bits, x0); + const int16_t y1 = PcanGainLookupFunction(config, input_bits, x1); + const int16_t y2 = PcanGainLookupFunction(config, input_bits, x2); + + const int32_t diff1 = (int32_t)y1 - y0; + const int32_t diff2 = (int32_t)y2 - y0; + const int32_t a1 = 4 * diff1 - diff2; + const int32_t a2 = diff2 - a1; + + state->gain_lut[4 * interval] = y0; + state->gain_lut[4 * interval + 1] = (int16_t)a1; + state->gain_lut[4 * interval + 2] = (int16_t)a2; + } + state->gain_lut += 6; + return 1; +} + +void PcanGainControlFreeStateContents(struct PcanGainControlState* state) { + free(state->gain_lut); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.h new file mode 100644 index 0000000..d4bfaa2 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control_util.h @@ -0,0 +1,57 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/pcan_gain_control.h" + +#define kWideDynamicFunctionBits 32 +#define kWideDynamicFunctionLUTSize (4 * kWideDynamicFunctionBits - 3) + +#ifdef __cplusplus +extern "C" { +#endif + +struct PcanGainControlConfig { + // set to false (0) to disable this module + int enable_pcan; + // gain normalization exponent (0.0 disables, 1.0 full strength) + float strength; + // positive value added in the normalization denominator + float offset; + // number of fractional bits in the gain + int gain_bits; +}; + +void PcanGainControlFillConfigWithDefaults( + struct PcanGainControlConfig* config); + +int16_t PcanGainLookupFunction(const struct PcanGainControlConfig* config, + int32_t input_bits, uint32_t x); + +int PcanGainControlPopulateState(const struct PcanGainControlConfig* config, + struct PcanGainControlState* state, + uint32_t* noise_estimate, + const int num_channels, + const uint16_t smoothing_bits, + const int32_t input_correction_bits); + +void PcanGainControlFreeStateContents(struct PcanGainControlState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_PCAN_GAIN_CONTROL_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.c new file mode 100644 index 0000000..10da676 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.c @@ -0,0 +1,70 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/window.h" + +#include + +int WindowProcessSamples(struct WindowState* state, const int16_t* samples, + size_t num_samples, size_t* num_samples_read) { + const int size = state->size; + + // Copy samples from the samples buffer over to our local input. + size_t max_samples_to_copy = state->size - state->input_used; + if (max_samples_to_copy > num_samples) { + max_samples_to_copy = num_samples; + } + memcpy(state->input + state->input_used, samples, + max_samples_to_copy * sizeof(*samples)); + *num_samples_read = max_samples_to_copy; + state->input_used += max_samples_to_copy; + + if (state->input_used < state->size) { + // We don't have enough samples to compute a window. + return 0; + } + + // Apply the window to the input. + const int16_t* coefficients = state->coefficients; + const int16_t* input = state->input; + int16_t* output = state->output; + int i; + int16_t max_abs_output_value = 0; + for (i = 0; i < size; ++i) { + int16_t new_value = + (((int32_t)*input++) * *coefficients++) >> kFrontendWindowBits; + *output++ = new_value; + if (new_value < 0) { + new_value = -new_value; + } + if (new_value > max_abs_output_value) { + max_abs_output_value = new_value; + } + } + // Shuffle the input down by the step size, and update how much we have used. + memmove(state->input, state->input + state->step, + sizeof(*state->input) * (state->size - state->step)); + state->input_used -= state->step; + state->max_abs_output_value = max_abs_output_value; + + // Indicate that the output buffer is valid for the next stage. + return 1; +} + +void WindowReset(struct WindowState* state) { + memset(state->input, 0, state->size * sizeof(*state->input)); + memset(state->output, 0, state->size * sizeof(*state->output)); + state->input_used = 0; + state->max_abs_output_value = 0; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.h new file mode 100644 index 0000000..bad8151 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window.h @@ -0,0 +1,49 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ + +#include +#include + +#define kFrontendWindowBits 12 + +#ifdef __cplusplus +extern "C" { +#endif + +struct WindowState { + size_t size; + int16_t* coefficients; + size_t step; + + int16_t* input; + size_t input_used; + int16_t* output; + int16_t max_abs_output_value; +}; + +// Applies a window to the samples coming in, stepping forward at the given +// rate. +int WindowProcessSamples(struct WindowState* state, const int16_t* samples, + size_t num_samples, size_t* num_samples_read); + +void WindowReset(struct WindowState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.c b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.c new file mode 100644 index 0000000..eee6e7b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.c @@ -0,0 +1,73 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/experimental/microfrontend/lib/window_util.h" + +#include +#include +#include +#include + +// Some platforms don't have M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void WindowFillConfigWithDefaults(struct WindowConfig* config) { + config->size_ms = 25; + config->step_size_ms = 10; +} + +int WindowPopulateState(const struct WindowConfig* config, + struct WindowState* state, int sample_rate) { + state->size = config->size_ms * sample_rate / 1000; + state->step = config->step_size_ms * sample_rate / 1000; + + state->coefficients = malloc(state->size * sizeof(*state->coefficients)); + if (state->coefficients == NULL) { + fprintf(stderr, "Failed to allocate window coefficients\n"); + return 0; + } + + // Populate the window values. + const float arg = M_PI * 2.0 / ((float)state->size); + int i; + for (i = 0; i < state->size; ++i) { + float float_value = 0.5 - (0.5 * cos(arg * (i + 0.5))); + // Scale it to fixed point and round it. + state->coefficients[i] = + floor(float_value * (1 << kFrontendWindowBits) + 0.5); + } + + state->input_used = 0; + state->input = malloc(state->size * sizeof(*state->input)); + if (state->input == NULL) { + fprintf(stderr, "Failed to allocate window input\n"); + return 0; + } + + state->output = malloc(state->size * sizeof(*state->output)); + if (state->output == NULL) { + fprintf(stderr, "Failed to allocate window output\n"); + return 0; + } + + return 1; +} + +void WindowFreeStateContents(struct WindowState* state) { + free(state->coefficients); + free(state->input); + free(state->output); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.h b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.h new file mode 100644 index 0000000..68e4de9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/experimental/microfrontend/lib/window_util.h @@ -0,0 +1,45 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ + +#include "tensorflow/lite/experimental/microfrontend/lib/window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct WindowConfig { + // length of window frame in milliseconds + size_t size_ms; + // length of step for next frame in milliseconds + size_t step_size_ms; +}; + +// Populates the WindowConfig with "sane" default values. +void WindowFillConfigWithDefaults(struct WindowConfig* config); + +// Allocates any buffers. +int WindowPopulateState(const struct WindowConfig* config, + struct WindowState* state, int sample_rate); + +// Frees any allocated buffers. +void WindowFreeStateContents(struct WindowState* state); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICROFRONTEND_LIB_WINDOW_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/SConscript b/TensorflowLiteMicro/tensorflow/lite/kernels/SConscript new file mode 100644 index 0000000..2763426 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/SConscript @@ -0,0 +1,29 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cc') + Glob('internal/*.cc') + +#. +root = str(Dir('#')) +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") + + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy] + +group = DefineGroup('lite/kernels', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/common.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/common.h new file mode 100644 index 0000000..66a2d97 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/common.h @@ -0,0 +1,956 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_COMMON_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_COMMON_H_ + +#ifndef ALLOW_SLOW_GENERIC_DEPTHWISECONV_FALLBACK +#ifdef GEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK +#define ALLOW_SLOW_GENERIC_DEPTHWISECONV_FALLBACK +#endif +#endif + +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/optimized/neon_check.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +constexpr int kReverseShift = -1; + +inline void GetActivationMinMax(FusedActivationFunctionType ac, + float* output_activation_min, + float* output_activation_max) { + switch (ac) { + case FusedActivationFunctionType::kNone: + *output_activation_min = std::numeric_limits::lowest(); + *output_activation_max = std::numeric_limits::max(); + break; + case FusedActivationFunctionType::kRelu: + *output_activation_min = 0.f; + *output_activation_max = std::numeric_limits::max(); + break; + case FusedActivationFunctionType::kRelu1: + *output_activation_min = -1.f; + *output_activation_max = 1.f; + break; + case FusedActivationFunctionType::kRelu6: + *output_activation_min = 0.f; + *output_activation_max = 6.f; + break; + } +} + +template +inline T ActivationFunctionWithMinMax(T x, T output_activation_min, + T output_activation_max) { + using std::max; + using std::min; + return min(max(x, output_activation_min), output_activation_max); +} + +// Legacy function, left for compatibility only. +template +float ActivationFunction(float x) { + float output_activation_min, output_activation_max; + GetActivationMinMax(Ac, &output_activation_min, &output_activation_max); + return ActivationFunctionWithMinMax(x, output_activation_min, + output_activation_max); +} + +inline void BiasAndClamp(float clamp_min, float clamp_max, int bias_size, + const float* bias_data, int array_size, + float* array_data) { + // Note: see b/132215220: in May 2019 we thought it would be OK to replace + // this with the Eigen one-liner: + // return (array.colwise() + bias).cwiseMin(clamp_max).cwiseMin(clamp_max). + // This turned out to severely regress performance: +4ms (i.e. 8%) on + // MobileNet v2 / 1.0 / 224. So we keep custom NEON code for now. + TFLITE_DCHECK_EQ((array_size % bias_size), 0); +#ifdef USE_NEON + float* array_ptr = array_data; + float* array_end_ptr = array_ptr + array_size; + const auto clamp_min_vec = vdupq_n_f32(clamp_min); + const auto clamp_max_vec = vdupq_n_f32(clamp_max); + for (; array_ptr != array_end_ptr; array_ptr += bias_size) { + int i = 0; + for (; i <= bias_size - 16; i += 16) { + auto b0 = vld1q_f32(bias_data + i); + auto b1 = vld1q_f32(bias_data + i + 4); + auto b2 = vld1q_f32(bias_data + i + 8); + auto b3 = vld1q_f32(bias_data + i + 12); + auto a0 = vld1q_f32(array_ptr + i); + auto a1 = vld1q_f32(array_ptr + i + 4); + auto a2 = vld1q_f32(array_ptr + i + 8); + auto a3 = vld1q_f32(array_ptr + i + 12); + auto x0 = vaddq_f32(a0, b0); + auto x1 = vaddq_f32(a1, b1); + auto x2 = vaddq_f32(a2, b2); + auto x3 = vaddq_f32(a3, b3); + x0 = vmaxq_f32(clamp_min_vec, x0); + x1 = vmaxq_f32(clamp_min_vec, x1); + x2 = vmaxq_f32(clamp_min_vec, x2); + x3 = vmaxq_f32(clamp_min_vec, x3); + x0 = vminq_f32(clamp_max_vec, x0); + x1 = vminq_f32(clamp_max_vec, x1); + x2 = vminq_f32(clamp_max_vec, x2); + x3 = vminq_f32(clamp_max_vec, x3); + vst1q_f32(array_ptr + i, x0); + vst1q_f32(array_ptr + i + 4, x1); + vst1q_f32(array_ptr + i + 8, x2); + vst1q_f32(array_ptr + i + 12, x3); + } + for (; i <= bias_size - 4; i += 4) { + auto b = vld1q_f32(bias_data + i); + auto a = vld1q_f32(array_ptr + i); + auto x = vaddq_f32(a, b); + x = vmaxq_f32(clamp_min_vec, x); + x = vminq_f32(clamp_max_vec, x); + vst1q_f32(array_ptr + i, x); + } + for (; i < bias_size; i++) { + array_ptr[i] = ActivationFunctionWithMinMax(array_ptr[i] + bias_data[i], + clamp_min, clamp_max); + } + } +#else // not NEON + for (int array_offset = 0; array_offset < array_size; + array_offset += bias_size) { + for (int i = 0; i < bias_size; i++) { + array_data[array_offset + i] = ActivationFunctionWithMinMax( + array_data[array_offset + i] + bias_data[i], clamp_min, clamp_max); + } + } +#endif +} + +inline int32_t MultiplyByQuantizedMultiplierSmallerThanOneExp( + int32_t x, int32_t quantized_multiplier, int left_shift) { + using gemmlowp::RoundingDivideByPOT; + using gemmlowp::SaturatingRoundingDoublingHighMul; + return RoundingDivideByPOT( + SaturatingRoundingDoublingHighMul(x, quantized_multiplier), -left_shift); +} + +inline int32_t MultiplyByQuantizedMultiplierGreaterThanOne( + int32_t x, int32_t quantized_multiplier, int left_shift) { + using gemmlowp::SaturatingRoundingDoublingHighMul; + return SaturatingRoundingDoublingHighMul(x * (1 << left_shift), + quantized_multiplier); +} + +inline int32_t MultiplyByQuantizedMultiplier(int32_t x, + int32_t quantized_multiplier, + int shift) { + using gemmlowp::RoundingDivideByPOT; + using gemmlowp::SaturatingRoundingDoublingHighMul; + int left_shift = shift > 0 ? shift : 0; + int right_shift = shift > 0 ? 0 : -shift; + return RoundingDivideByPOT(SaturatingRoundingDoublingHighMul( + x * (1 << left_shift), quantized_multiplier), + right_shift); +} + +inline int32_t MultiplyByQuantizedMultiplier(int64_t x, + int32_t quantized_multiplier, + int shift) { + // Inputs: + // - quantized_multiplier has fixed point at bit 31 + // - shift is -31 to +7 (negative for right shift) + // + // Assumptions: The following input ranges are assumed + // - quantize_scale>=0 (the usual range is (1<<30) to (1>>31)-1) + // - scaling is chosen so final scaled result fits in int32_t + // - input x is in the range -(1<<47) <= x < (1<<47) + assert(quantized_multiplier >= 0); + assert(shift >= -31 && shift < 8); + + int32_t reduced_multiplier = (quantized_multiplier + (1 << 15)) >> 16; + int total_shift = 15 - shift; + x = (x * (int64_t)reduced_multiplier) + ((int64_t)1 << (total_shift - 1)); + int32_t result = x >> total_shift; + return result; +} + +template +int CountLeadingZeros(T integer_input) { + static_assert(std::is_unsigned::value, + "Only unsigned integer types handled."); +#if defined(__GNUC__) + return integer_input ? __builtin_clz(integer_input) + : std::numeric_limits::digits; +#else + if (integer_input == 0) { + return std::numeric_limits::digits; + } + + const T one_in_leading_positive = static_cast(1) + << (std::numeric_limits::digits - 1); + int leading_zeros = 0; + while (integer_input < one_in_leading_positive) { + integer_input <<= 1; + ++leading_zeros; + } + return leading_zeros; +#endif +} + +template +inline int CountLeadingSignBits(T integer_input) { + static_assert(std::is_signed::value, "Only signed integer types handled."); +#if defined(__GNUC__) && !defined(__clang__) + return integer_input ? __builtin_clrsb(integer_input) + : std::numeric_limits::digits; +#else + using U = typename std::make_unsigned::type; + return integer_input >= 0 + ? CountLeadingZeros(static_cast(integer_input)) - 1 + : integer_input != std::numeric_limits::min() + ? CountLeadingZeros(2 * static_cast(-integer_input) - 1) + : 0; +#endif +} + +// Use "count leading zeros" helper functions to do a fast Floor(log_2(x)). +template +inline Integer FloorLog2(Integer n) { + static_assert(std::is_integral::value, ""); + static_assert(std::is_signed::value, ""); + static_assert(sizeof(Integer) == 4 || sizeof(Integer) == 8, ""); + TFLITE_CHECK_GT(n, 0); + if (sizeof(Integer) == 4) { + return 30 - CountLeadingSignBits(n); + } else { + return 62 - CountLeadingSignBits(n); + } +} + +// generate INT16 LUT for function(), e.g., table exp(x) and 1/(1+x) used in +// softmax +inline void gen_lut(const std::function& func, double min, + double max, int16_t* table, const int num) { + // size of table should equal to num + 1 + // last element only for slope calculation + double step = (max - min) / (num - 1); + double half_step = step / 2.0; + for (int i = 0; i < num - 1; i++) { + double sample_val = TfLiteRound(func(min + i * step) * 32768.0); + double midpoint_interp_val = + TfLiteRound((func(min + (i + 1) * step) * 32768.0 + + TfLiteRound(func(min + i * step) * 32768.0)) / + 2.0); + double midpoint_val = + TfLiteRound(func(min + i * step + half_step) * 32768.0); + double midpoint_err = midpoint_interp_val - midpoint_val; + double bias = TfLiteRound(midpoint_err / 2.0); + table[i] = std::min(std::max(sample_val - bias, -32768.0), 32767.0); + } + table[num - 1] = + std::min(std::max(TfLiteRound(func(max) * 32768.0), -32768.0), 32767.0); +} + +// int16_t func table lookup, e.g., lookup exp() and 1/(1+x) used in softmax +inline int16_t generic_int16_table_lookup(int16_t value, const int16_t* lut) { + // 512 base value, lut[513] only for calculate slope + uint16_t index = static_cast(256 + (value >> 7)); + assert(index < 512 && "LUT index out of range."); + int16_t offset = value & 0x7f; + + // base and slope are Q0.15 + int16_t base = lut[index]; + int16_t slope = lut[index + 1] - lut[index]; + + // Q0.15 * Q0.7 = Q0.22 + // Round and convert from Q0.22 to Q0.15 + int32_t delta = (static_cast(slope) * offset + 64) >> 7; + + // Q0.15 + Q0.15 + return base + delta; +} + +// Table of sigmoid(i/24) at 0.16 format - 256 elements. + +// We use combined sigmoid and tanh look-up table, since +// tanh(x) = 2*sigmoid(2*x) -1. +// Both functions are symmetric, so the LUT table is only needed +// for the absolute value of the input. +static const uint16_t sigmoid_table_uint16[256] = { + 32768, 33451, 34133, 34813, 35493, 36169, 36843, 37513, 38180, 38841, 39498, + 40149, 40794, 41432, 42064, 42688, 43304, 43912, 44511, 45102, 45683, 46255, + 46817, 47369, 47911, 48443, 48964, 49475, 49975, 50464, 50942, 51409, 51865, + 52311, 52745, 53169, 53581, 53983, 54374, 54755, 55125, 55485, 55834, 56174, + 56503, 56823, 57133, 57433, 57724, 58007, 58280, 58544, 58800, 59048, 59288, + 59519, 59743, 59959, 60168, 60370, 60565, 60753, 60935, 61110, 61279, 61441, + 61599, 61750, 61896, 62036, 62172, 62302, 62428, 62549, 62666, 62778, 62886, + 62990, 63090, 63186, 63279, 63368, 63454, 63536, 63615, 63691, 63765, 63835, + 63903, 63968, 64030, 64090, 64148, 64204, 64257, 64308, 64357, 64405, 64450, + 64494, 64536, 64576, 64614, 64652, 64687, 64721, 64754, 64786, 64816, 64845, + 64873, 64900, 64926, 64950, 64974, 64997, 65019, 65039, 65060, 65079, 65097, + 65115, 65132, 65149, 65164, 65179, 65194, 65208, 65221, 65234, 65246, 65258, + 65269, 65280, 65291, 65301, 65310, 65319, 65328, 65337, 65345, 65352, 65360, + 65367, 65374, 65381, 65387, 65393, 65399, 65404, 65410, 65415, 65420, 65425, + 65429, 65433, 65438, 65442, 65445, 65449, 65453, 65456, 65459, 65462, 65465, + 65468, 65471, 65474, 65476, 65479, 65481, 65483, 65485, 65488, 65489, 65491, + 65493, 65495, 65497, 65498, 65500, 65501, 65503, 65504, 65505, 65507, 65508, + 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65517, 65518, + 65519, 65520, 65520, 65521, 65522, 65522, 65523, 65523, 65524, 65524, 65525, + 65525, 65526, 65526, 65526, 65527, 65527, 65528, 65528, 65528, 65529, 65529, + 65529, 65529, 65530, 65530, 65530, 65530, 65531, 65531, 65531, 65531, 65531, + 65532, 65532, 65532, 65532, 65532, 65532, 65533, 65533, 65533, 65533, 65533, + 65533, 65533, 65533, 65534, 65534, 65534, 65534, 65534, 65534, 65534, 65534, + 65534, 65534, 65535}; + +// TODO(b/77858996): Add these to gemmlowp. +template +IntegerType SaturatingAddNonGemmlowp(IntegerType a, IntegerType b) { + static_assert(std::is_same::value, "unimplemented"); + return a; +} + +template <> +inline std::int32_t SaturatingAddNonGemmlowp(std::int32_t a, std::int32_t b) { + std::int64_t a64 = a; + std::int64_t b64 = b; + std::int64_t sum = a64 + b64; + return static_cast(std::min( + static_cast(std::numeric_limits::max()), + std::max( + static_cast(std::numeric_limits::min()), + sum))); +} + +template +gemmlowp::FixedPoint SaturatingAddNonGemmlowp( + gemmlowp::FixedPoint a, + gemmlowp::FixedPoint b) { + return gemmlowp::FixedPoint::FromRaw( + SaturatingAddNonGemmlowp(a.raw(), b.raw())); +} + +template +IntegerType SaturatingSub(IntegerType a, IntegerType b) { + static_assert(std::is_same::value, "unimplemented"); + return a; +} + +template <> +inline std::int16_t SaturatingSub(std::int16_t a, std::int16_t b) { + std::int32_t a32 = a; + std::int32_t b32 = b; + std::int32_t diff = a32 - b32; + return static_cast( + std::min(static_cast(32767), + std::max(static_cast(-32768), diff))); +} + +template <> +inline std::int32_t SaturatingSub(std::int32_t a, std::int32_t b) { + std::int64_t a64 = a; + std::int64_t b64 = b; + std::int64_t diff = a64 - b64; + return static_cast(std::min( + static_cast(std::numeric_limits::max()), + std::max( + static_cast(std::numeric_limits::min()), + diff))); +} + +template +gemmlowp::FixedPoint SaturatingSub( + gemmlowp::FixedPoint a, + gemmlowp::FixedPoint b) { + return gemmlowp::FixedPoint::FromRaw( + SaturatingSub(a.raw(), b.raw())); +} +// End section to be moved to gemmlowp. + +template +IntegerType SaturatingRoundingMultiplyByPOTParam(IntegerType x, int exponent) { + if (exponent == 0) { + return x; + } + using ScalarIntegerType = + typename gemmlowp::FixedPointRawTypeTraits::ScalarRawType; + const IntegerType min = + gemmlowp::Dup(std::numeric_limits::min()); + const IntegerType max = + gemmlowp::Dup(std::numeric_limits::max()); + const int ScalarIntegerTypeBits = 8 * sizeof(ScalarIntegerType); + + const std::int32_t threshold = + ((1 << (ScalarIntegerTypeBits - 1 - exponent)) - 1); + const IntegerType positive_mask = + gemmlowp::MaskIfGreaterThan(x, gemmlowp::Dup(threshold)); + const IntegerType negative_mask = + gemmlowp::MaskIfLessThan(x, gemmlowp::Dup(-threshold)); + + IntegerType result = gemmlowp::ShiftLeft(x, exponent); + result = gemmlowp::SelectUsingMask(positive_mask, max, result); + result = gemmlowp::SelectUsingMask(negative_mask, min, result); + return result; +} + +// If we want to leave IntegerBits fixed, then multiplication +// by a power of two has to be saturating/rounding, not exact anymore. +template +gemmlowp::FixedPoint +SaturatingRoundingMultiplyByPOTParam( + gemmlowp::FixedPoint a, int exponent) { + return gemmlowp::FixedPoint::FromRaw( + SaturatingRoundingMultiplyByPOTParam(a.raw(), exponent)); +} + +// Convert int32_t multiplier to int16_t with rounding. +inline void DownScaleInt32ToInt16Multiplier(int32_t multiplier_int32_t, + int16_t* multiplier_int16_t) { + TFLITE_DCHECK_GE(multiplier_int32_t, 0); + static constexpr int32_t kRoundingOffset = 1 << 15; + if (multiplier_int32_t >= + std::numeric_limits::max() - kRoundingOffset) { + *multiplier_int16_t = std::numeric_limits::max(); + return; + } + const int32_t result = (multiplier_int32_t + kRoundingOffset) >> 16; + TFLITE_DCHECK_LE(result << 16, multiplier_int32_t + kRoundingOffset); + TFLITE_DCHECK_GT(result << 16, multiplier_int32_t - kRoundingOffset); + *multiplier_int16_t = result; + TFLITE_DCHECK_EQ(*multiplier_int16_t, result); +} + +// Minimum output bits to accommodate log of maximum input range. It actually +// does not matter if one considers, say, [-64,64] or [-64,64). +// +// For example, run this through Octave: +// [0:127; ... +// ceil(log(abs( log(2.^(0:127))+1 ))/log(2)); ... +// ceil(log(abs( log(2.^(0:127))+1 ))/log(2))] +constexpr int min_log_x_output_bits(int input_bits) { + return input_bits > 90 ? 7 + : input_bits > 44 ? 6 + : input_bits > 21 ? 5 + : input_bits > 10 ? 4 + : input_bits > 4 ? 3 + : input_bits > 1 ? 2 + : 1; +} + +// Although currently the name of this function says that it cannot handle +// values less than 1, in practice it can handle as low as 1/x_max, where +// x_max is the largest representable input. In other words, the output range +// is symmetric. +template +inline gemmlowp::FixedPoint +log_x_for_x_greater_than_or_equal_to_1_impl( + gemmlowp::FixedPoint input_val) { + // assert(__builtin_clz(0u) >= std::numeric_limits::digits - 1); + // assert(__builtin_clz(0u) <= std::numeric_limits::digits); + using FixedPoint0 = gemmlowp::FixedPoint; + // The reason for accumulating the result with an extra bit of headroom is + // that z_pow_2_adj * log_2 might be saturated, and adding num_scaled * + // recip_denom will otherwise introduce an error. + static constexpr int kAccumIntegerBits = OutputIntegerBits + 1; + using FixedPointAccum = gemmlowp::FixedPoint; + + const FixedPoint0 log_2 = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 1488522236, std::log(2.0)); + const FixedPoint0 sqrt_sqrt_half = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 1805811301, std::sqrt(std::sqrt(0.5))); + const FixedPoint0 sqrt_half = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 1518500250, std::sqrt(0.5)); + const FixedPoint0 one_quarter = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(FixedPoint0, 536870912, 1.0 / 4.0); + + const FixedPoint0 alpha_n = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 117049297, 11.0 / 240.0 * std::sqrt(std::sqrt(2.0))); + const FixedPoint0 alpha_d = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 127690142, 1.0 / 20.0 * std::sqrt(std::sqrt(2.0))); + const FixedPoint0 alpha_i = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 1057819769, + 2.0 / std::sqrt(std::sqrt(2.0)) - std::sqrt(std::sqrt(2.0))); + const FixedPoint0 alpha_f = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( + FixedPoint0, 638450708, 1.0 / 4.0 * std::sqrt(std::sqrt(2.0))); + + const FixedPointAccum shifted_quarter = + gemmlowp::Rescale(one_quarter); + + // Reinterpret the input value as Q0.31, because we will figure out the + // required shift "ourselves" instead of using, say, Rescale. + FixedPoint0 z_a = FixedPoint0::FromRaw(input_val.raw()); + // z_a_pow_2 = input_integer_bits - z_a_headroom; + int z_a_headroom_plus_1 = CountLeadingZeros(static_cast(z_a.raw())); + FixedPoint0 r_a_tmp = + SaturatingRoundingMultiplyByPOTParam(z_a, (z_a_headroom_plus_1 - 1)); + const int32_t r_a_raw = + SaturatingRoundingMultiplyByPOTParam((r_a_tmp * sqrt_half).raw(), 1); + // z_pow_2_adj = max(z_pow_2_a - 0.75, z_pow_2_b - 0.25); + // z_pow_2_adj = max(InputIntegerBits - z_a_headroom_plus_1 + 0.25, + // InputIntegerBits - z_b_headroom - 0.25); + const FixedPointAccum z_a_pow_2_adj = SaturatingAddNonGemmlowp( + FixedPointAccum::FromRaw(SaturatingRoundingMultiplyByPOTParam( + InputIntegerBits - z_a_headroom_plus_1, 31 - kAccumIntegerBits)), + shifted_quarter); + + // z_b is treated like z_a, but premultiplying by sqrt(0.5). + FixedPoint0 z_b = z_a * sqrt_half; + int z_b_headroom = CountLeadingZeros(static_cast(z_b.raw())) - 1; + const int32_t r_b_raw = + SaturatingRoundingMultiplyByPOTParam(z_a.raw(), z_b_headroom); + const FixedPointAccum z_b_pow_2_adj = SaturatingSub( + FixedPointAccum::FromRaw(SaturatingRoundingMultiplyByPOTParam( + InputIntegerBits - z_b_headroom, 31 - kAccumIntegerBits)), + shifted_quarter); + + const FixedPoint0 r = FixedPoint0::FromRaw(std::min(r_a_raw, r_b_raw)); + const FixedPointAccum z_pow_2_adj = FixedPointAccum::FromRaw( + std::max(z_a_pow_2_adj.raw(), z_b_pow_2_adj.raw())); + + const FixedPoint0 p = gemmlowp::RoundingHalfSum(r, sqrt_sqrt_half); + FixedPoint0 q = r - sqrt_sqrt_half; + q = q + q; + + const FixedPoint0 common_sq = q * q; + const FixedPoint0 num = q * r + q * common_sq * alpha_n; + const FixedPoint0 denom_minus_one_0 = + p * (alpha_i + q + alpha_d * common_sq) + alpha_f * q; + const FixedPoint0 recip_denom = + one_over_one_plus_x_for_x_in_0_1(denom_minus_one_0); + + const FixedPointAccum num_scaled = gemmlowp::Rescale(num); + return gemmlowp::Rescale(z_pow_2_adj * log_2 + + num_scaled * recip_denom); +} + +template +inline gemmlowp::FixedPoint +log_x_for_x_greater_than_or_equal_to_1( + gemmlowp::FixedPoint input_val) { + static_assert( + OutputIntegerBits >= min_log_x_output_bits(InputIntegerBits), + "Output integer bits must be sufficient to accommodate logs of inputs."); + return log_x_for_x_greater_than_or_equal_to_1_impl( + input_val); +} + +inline int32_t GetReciprocal(int32_t x, int x_integer_digits, + int* num_bits_over_unit) { + int headroom_plus_one = CountLeadingZeros(static_cast(x)); + // This is the number of bits to the left of the binary point above 1.0. + // Consider x=1.25. In that case shifted_scale=0.8 and + // no later adjustment will be needed. + *num_bits_over_unit = x_integer_digits - headroom_plus_one; + const int32_t shifted_sum_minus_one = + static_cast((static_cast(x) << headroom_plus_one) - + (static_cast(1) << 31)); + + gemmlowp::FixedPoint shifted_scale = + gemmlowp::one_over_one_plus_x_for_x_in_0_1( + gemmlowp::FixedPoint::FromRaw(shifted_sum_minus_one)); + return shifted_scale.raw(); +} + +inline void GetInvSqrtQuantizedMultiplierExp(int32_t input, int reverse_shift, + int32_t* output_inv_sqrt, + int* output_shift) { + TFLITE_DCHECK_GE(input, 0); + if (input <= 1) { + // Handle the input value 1 separately to avoid overflow in that case + // in the general computation below (b/143972021). Also handle 0 as if it + // were a 1. 0 is an invalid input here (divide by zero) and 1 is a valid + // but rare/unrealistic input value. We can expect both to occur in some + // incompletely trained models, but probably not in fully trained models. + *output_inv_sqrt = std::numeric_limits::max(); + *output_shift = 0; + return; + } + TFLITE_DCHECK_GT(input, 1); + *output_shift = 11; + while (input >= (1 << 29)) { + input /= 4; + ++*output_shift; + } + const unsigned max_left_shift_bits = + CountLeadingZeros(static_cast(input)) - 1; + const unsigned max_left_shift_bit_pairs = max_left_shift_bits / 2; + const unsigned left_shift_bit_pairs = max_left_shift_bit_pairs - 1; + *output_shift -= left_shift_bit_pairs; + input <<= 2 * left_shift_bit_pairs; + TFLITE_DCHECK_GE(input, (1 << 27)); + TFLITE_DCHECK_LT(input, (1 << 29)); + using gemmlowp::FixedPoint; + using gemmlowp::Rescale; + using gemmlowp::SaturatingRoundingMultiplyByPOT; + // Using 3 integer bits gives us enough room for the internal arithmetic in + // this Newton-Raphson iteration. + using F3 = FixedPoint; + using F0 = FixedPoint; + const F3 fixedpoint_input = F3::FromRaw(input >> 1); + const F3 fixedpoint_half_input = + SaturatingRoundingMultiplyByPOT<-1>(fixedpoint_input); + const F3 fixedpoint_half_three = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F3, (1 << 28) + (1 << 27), 1.5); + // Newton-Raphson iteration + // Naive unoptimized starting guess: x = 1 + F3 x = F3::One(); + // Naive unoptimized number of iterations: 5 + for (int i = 0; i < 5; i++) { + const F3 x3 = Rescale<3>(x * x * x); + x = Rescale<3>(fixedpoint_half_three * x - fixedpoint_half_input * x3); + } + const F0 fixedpoint_half_sqrt_2 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F0, 1518500250, std::sqrt(2.) / 2.); + x = x * fixedpoint_half_sqrt_2; + *output_inv_sqrt = x.raw(); + if (*output_shift < 0) { + *output_inv_sqrt <<= -*output_shift; + *output_shift = 0; + } + // Convert right shift (right is positive) to left shift. + *output_shift *= reverse_shift; +} + +// DO NOT USE THIS STRUCT FOR NEW FUNCTIONALITY BEYOND IMPLEMENTING +// BROADCASTING. +// +// NdArrayDesc describes the shape and memory layout of an N-dimensional +// rectangular array of numbers. +// +// NdArrayDesc is basically identical to Dims defined in types.h. +// However, as Dims is to be deprecated, this class exists as an adaptor +// to enable simple unoptimized implementations of element-wise broadcasting +// operations. +template +struct NdArrayDesc { + // The "extent" of each dimension. Indices along dimension d must be in the + // half-open interval [0, extents[d]). + int extents[N]; + + // The number of *elements* (not bytes) between consecutive indices of each + // dimension. + int strides[N]; +}; + +// DO NOT USE THIS FUNCTION FOR NEW FUNCTIONALITY BEYOND IMPLEMENTING +// BROADCASTING. +// +// Same as Offset(), except takes as NdArrayDesc instead of Dims. +inline int SubscriptToIndex(const NdArrayDesc<4>& desc, int i0, int i1, int i2, + int i3) { + TFLITE_DCHECK(i0 >= 0 && i0 < desc.extents[0]); + TFLITE_DCHECK(i1 >= 0 && i1 < desc.extents[1]); + TFLITE_DCHECK(i2 >= 0 && i2 < desc.extents[2]); + TFLITE_DCHECK(i3 >= 0 && i3 < desc.extents[3]); + return i0 * desc.strides[0] + i1 * desc.strides[1] + i2 * desc.strides[2] + + i3 * desc.strides[3]; +} + +inline int SubscriptToIndex(const NdArrayDesc<5>& desc, int indexes[5]) { + return indexes[0] * desc.strides[0] + indexes[1] * desc.strides[1] + + indexes[2] * desc.strides[2] + indexes[3] * desc.strides[3] + + indexes[4] * desc.strides[4]; +} + +// Given the dimensions of the operands for an element-wise binary broadcast, +// adjusts them so that they can be directly iterated over with simple loops. +// Returns the adjusted dims as instances of NdArrayDesc in 'desc0_out' and +// 'desc1_out'. 'desc0_out' and 'desc1_out' cannot be nullptr. +// +// This function assumes that the two input shapes are compatible up to +// broadcasting and the shorter one has already been prepended with 1s to be the +// same length. E.g., if shape0 is (1, 16, 16, 64) and shape1 is (1, 64), +// shape1 must already have been prepended to be (1, 1, 1, 64). Recall that +// Dims refer to shapes in reverse order. In this case, input0_dims will be +// (64, 16, 16, 1) and input1_dims will be (64, 1, 1, 1). +// +// When two shapes are compatible up to broadcasting, for each dimension d, +// the input extents are either equal, or one of them is 1. +// +// This function performs the following for each dimension d: +// - If the extents are equal, then do nothing since the loop that walks over +// both of the input arrays is correct. +// - Otherwise, one (and only one) of the extents must be 1. Say extent0 is 1 +// and extent1 is e1. Then set extent0 to e1 and stride0 *to 0*. This allows +// array0 to be referenced *at any index* in dimension d and still access the +// same slice. +template +inline void NdArrayDescsForElementwiseBroadcast(const Dims& input0_dims, + const Dims& input1_dims, + NdArrayDesc* desc0_out, + NdArrayDesc* desc1_out) { + TFLITE_DCHECK(desc0_out != nullptr); + TFLITE_DCHECK(desc1_out != nullptr); + + // Copy dims to desc. + for (int i = 0; i < N; ++i) { + desc0_out->extents[i] = input0_dims.sizes[i]; + desc0_out->strides[i] = input0_dims.strides[i]; + desc1_out->extents[i] = input1_dims.sizes[i]; + desc1_out->strides[i] = input1_dims.strides[i]; + } + + // Walk over each dimension. If the extents are equal do nothing. + // Otherwise, set the desc with extent 1 to have extent equal to the other and + // stride 0. + for (int i = 0; i < N; ++i) { + const int extent0 = ArraySize(input0_dims, i); + const int extent1 = ArraySize(input1_dims, i); + if (extent0 != extent1) { + if (extent0 == 1) { + desc0_out->strides[i] = 0; + desc0_out->extents[i] = extent1; + } else { + TFLITE_DCHECK_EQ(extent1, 1); + desc1_out->strides[i] = 0; + desc1_out->extents[i] = extent0; + } + } + } +} + +// Copies dims to desc, calculating strides. +template +inline void CopyDimsToDesc(const RuntimeShape& input_shape, + NdArrayDesc* desc_out) { + int desc_stride = 1; + for (int i = N - 1; i >= 0; --i) { + desc_out->extents[i] = input_shape.Dims(i); + desc_out->strides[i] = desc_stride; + desc_stride *= input_shape.Dims(i); + } +} + +template +inline void NdArrayDescsForElementwiseBroadcast( + const RuntimeShape& input0_shape, const RuntimeShape& input1_shape, + NdArrayDesc* desc0_out, NdArrayDesc* desc1_out) { + TFLITE_DCHECK(desc0_out != nullptr); + TFLITE_DCHECK(desc1_out != nullptr); + + auto extended_input0_shape = RuntimeShape::ExtendedShape(N, input0_shape); + auto extended_input1_shape = RuntimeShape::ExtendedShape(N, input1_shape); + + // Copy dims to desc, calculating strides. + CopyDimsToDesc(extended_input0_shape, desc0_out); + CopyDimsToDesc(extended_input1_shape, desc1_out); + + // Walk over each dimension. If the extents are equal do nothing. + // Otherwise, set the desc with extent 1 to have extent equal to the other and + // stride 0. + for (int i = 0; i < N; ++i) { + const int extent0 = extended_input0_shape.Dims(i); + const int extent1 = extended_input1_shape.Dims(i); + if (extent0 != extent1) { + if (extent0 == 1) { + desc0_out->strides[i] = 0; + desc0_out->extents[i] = extent1; + } else { + TFLITE_DCHECK_EQ(extent1, 1); + desc1_out->strides[i] = 0; + desc1_out->extents[i] = extent0; + } + } + } +} + +template +inline void NdArrayDescsForElementwiseBroadcast( + const RuntimeShape& input0_shape, const RuntimeShape& input1_shape, + const RuntimeShape& input2_shape, NdArrayDesc* desc0_out, + NdArrayDesc* desc1_out, NdArrayDesc* desc2_out) { + TFLITE_DCHECK(desc0_out != nullptr); + TFLITE_DCHECK(desc1_out != nullptr); + TFLITE_DCHECK(desc2_out != nullptr); + + auto extended_input0_shape = RuntimeShape::ExtendedShape(N, input0_shape); + auto extended_input1_shape = RuntimeShape::ExtendedShape(N, input1_shape); + auto extended_input2_shape = RuntimeShape::ExtendedShape(N, input2_shape); + + // Copy dims to desc, calculating strides. + CopyDimsToDesc(extended_input0_shape, desc0_out); + CopyDimsToDesc(extended_input1_shape, desc1_out); + CopyDimsToDesc(extended_input2_shape, desc2_out); + + // Walk over each dimension. If the extents are equal do nothing. + // Otherwise, set the desc with extent 1 to have extent equal to the other and + // stride 0. + for (int i = 0; i < N; ++i) { + const int extent0 = extended_input0_shape.Dims(i); + const int extent1 = extended_input1_shape.Dims(i); + const int extent2 = extended_input2_shape.Dims(i); + + int extent = extent0; + if (extent1 != 1) extent = extent1; + if (extent2 != 1) extent = extent2; + + TFLITE_DCHECK(extent0 == 1 || extent0 == extent); + TFLITE_DCHECK(extent1 == 1 || extent1 == extent); + TFLITE_DCHECK(extent2 == 1 || extent2 == extent); + + if (!(extent0 == extent1 && extent1 == extent2)) { + if (extent0 == 1) { + desc0_out->strides[i] = 0; + desc0_out->extents[i] = extent; + } + if (extent1 == 1) { + desc1_out->strides[i] = 0; + desc1_out->extents[i] = extent; + } + if (extent2 == 1) { + desc2_out->strides[i] = 0; + desc2_out->extents[i] = extent; + } + } + } +} + +// Detailed implementation of NDOpsHelper, the indexes must be a zero array. +// This implementation is equivalent to N nested loops. Ex, if N=4, it can be +// re-writen as: +// for (int b = 0; b < output.extents[0]; ++b) { +// for (int y = 0; y < output.extents[1]; ++y) { +// for (int x = 0; x < output.extents[2]; ++x) { +// for (int c = 0; c < output.extents[3]; ++c) { +// calc({b,y,x,c}); +// } +// } +// } +// } +template +typename std::enable_if::type NDOpsHelperImpl( + const NdArrayDesc& output, const Calc& calc, int indexes[N]) { + for (indexes[DIM] = 0; indexes[DIM] < output.extents[DIM]; ++indexes[DIM]) { + NDOpsHelperImpl(output, calc, indexes); + } +} + +template +typename std::enable_if::type NDOpsHelperImpl( + const NdArrayDesc& output, const Calc& calc, int indexes[N]) { + for (indexes[DIM] = 0; indexes[DIM] < output.extents[DIM]; ++indexes[DIM]) { + calc(indexes); + } +} + +// Execute the calc function in the innermost iteration based on the shape of +// the output. The calc function should take a single argument of type int[N]. +template +inline void NDOpsHelper(const NdArrayDesc& output, const Calc& calc) { + int indexes[N] = {0}; + NDOpsHelperImpl(output, calc, indexes); +} +// Copied from gemmlowp::RoundDown when we dropped direct dependency on +// gemmlowp. +// +// Returns the runtime argument rounded down to the nearest multiple of +// the fixed Modulus. +template +Integer RoundDown(Integer i) { + return i - (i % Modulus); +} + +// Copied from gemmlowp::RoundUp when we dropped direct dependency on +// gemmlowp. +// +// Returns the runtime argument rounded up to the nearest multiple of +// the fixed Modulus. +template +Integer RoundUp(Integer i) { + return RoundDown(i + Modulus - 1); +} + +// Copied from gemmlowp::CeilQuotient when we dropped direct dependency on +// gemmlowp. +// +// Returns the quotient a / b rounded up ('ceil') to the nearest integer. +template +Integer CeilQuotient(Integer a, Integer b) { + return (a + b - 1) / b; +} + +// This function is a copy of gemmlowp::HowManyThreads, copied when we dropped +// the direct dependency of internal/optimized/ on gemmlowp. +// +// It computes a reasonable number of threads to use for a GEMM of shape +// (rows, cols, depth). +// +// TODO(b/131910176): get rid of this function by switching each call site +// to its own more sensible logic for its own workload. +template +inline int LegacyHowManyThreads(int max_num_threads, int rows, int cols, + int depth) { + // Early-exit in the default case where multi-threading is disabled. + if (max_num_threads == 1) { + return 1; + } + + // Ensure that each thread has KernelRows rows to process, if at all possible. + int thread_count = std::min(max_num_threads, rows / KernelRows); + + // Limit the number of threads according to the overall size of the problem. + if (thread_count > 1) { + // Empirically determined value. + static constexpr std::uint64_t min_cubic_size_per_thread = 64 * 1024; + + // We can only multiply two out of three sizes without risking overflow + const std::uint64_t cubic_size = + std::uint64_t(rows) * std::uint64_t(cols) * std::uint64_t(depth); + + thread_count = std::min( + thread_count, static_cast(cubic_size / min_cubic_size_per_thread)); + } + + if (thread_count < 1) { + thread_count = 1; + } + + assert(thread_count > 0 && thread_count <= max_num_threads); + return thread_count; +} + +template +void optimized_ops_preload_l1_stream(const T* ptr) { +#ifdef __GNUC__ + // builtin offered by GCC-compatible compilers including clang + __builtin_prefetch(ptr, /* 0 means read */ 0, /* 0 means no locality */ 0); +#else + (void)ptr; +#endif +} + +template +void optimized_ops_preload_l1_keep(const T* ptr) { +#ifdef __GNUC__ + // builtin offered by GCC-compatible compilers including clang + __builtin_prefetch(ptr, /* 0 means read */ 0, /* 3 means high locality */ 3); +#else + (void)ptr; +#endif +} + +template +void optimized_ops_prefetch_write_l1_keep(const T* ptr) { +#ifdef __GNUC__ + // builtin offered by GCC-compatible compilers including clang + __builtin_prefetch(ptr, /* 1 means write */ 1, /* 3 means high locality */ 3); +#else + (void)ptr; +#endif +} + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_COMMON_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/compatibility.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/compatibility.h new file mode 100644 index 0000000..61becad --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/compatibility.h @@ -0,0 +1,112 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_COMPATIBILITY_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_COMPATIBILITY_H_ + +#include + +#include "tensorflow/lite/kernels/op_macros.h" + +#ifndef TFLITE_DCHECK +#define TFLITE_DCHECK(condition) (condition) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_EQ +#define TFLITE_DCHECK_EQ(x, y) ((x) == (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_NE +#define TFLITE_DCHECK_NE(x, y) ((x) != (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_GE +#define TFLITE_DCHECK_GE(x, y) ((x) >= (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_GT +#define TFLITE_DCHECK_GT(x, y) ((x) > (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_LE +#define TFLITE_DCHECK_LE(x, y) ((x) <= (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +#ifndef TFLITE_DCHECK_LT +#define TFLITE_DCHECK_LT(x, y) ((x) < (y)) ? (void)0 : TFLITE_ASSERT_FALSE +#endif + +// TODO(ahentz): Clean up: We should stick to the DCHECK versions. +#ifndef TFLITE_CHECK +#define TFLITE_CHECK(condition) (condition) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_EQ +#define TFLITE_CHECK_EQ(x, y) ((x) == (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_NE +#define TFLITE_CHECK_NE(x, y) ((x) != (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_GE +#define TFLITE_CHECK_GE(x, y) ((x) >= (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_GT +#define TFLITE_CHECK_GT(x, y) ((x) > (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_LE +#define TFLITE_CHECK_LE(x, y) ((x) <= (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TFLITE_CHECK_LT +#define TFLITE_CHECK_LT(x, y) ((x) < (y)) ? (void)0 : TFLITE_ABORT +#endif + +#ifndef TF_LITE_STATIC_MEMORY +// TODO(b/162019032): Consider removing these type-aliases. +using int8 = std::int8_t; +using uint8 = std::uint8_t; +using int16 = std::int16_t; +using uint16 = std::uint16_t; +using int32 = std::int32_t; +using uint32 = std::uint32_t; +#endif // !defined(TF_LITE_STATIC_MEMORY) + +// TFLITE_DEPRECATED() +// +// Duplicated from absl/base/macros.h to avoid pulling in that library. +// Marks a deprecated class, struct, enum, function, method and variable +// declarations. The macro argument is used as a custom diagnostic message (e.g. +// suggestion of a better alternative). +// +// Example: +// +// class TFLITE_DEPRECATED("Use Bar instead") Foo {...}; +// TFLITE_DEPRECATED("Use Baz instead") void Bar() {...} +// +// Every usage of a deprecated entity will trigger a warning when compiled with +// clang's `-Wdeprecated-declarations` option. This option is turned off by +// default, but the warnings will be reported by clang-tidy. +#if defined(__clang__) && __cplusplus >= 201103L +#define TFLITE_DEPRECATED(message) __attribute__((deprecated(message))) +#endif + +#ifndef TFLITE_DEPRECATED +#define TFLITE_DEPRECATED(message) +#endif + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_COMPATIBILITY_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/cppmath.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/cppmath.h new file mode 100644 index 0000000..f01fac6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/cppmath.h @@ -0,0 +1,40 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_ + +#include + +namespace tflite { + +#if defined(TF_LITE_USE_GLOBAL_CMATH_FUNCTIONS) || \ + (defined(__ANDROID__) && !defined(__NDK_MAJOR__)) || defined(ARDUINO) || \ + defined(__ZEPHYR__) +#define TF_LITE_GLOBAL_STD_PREFIX +#else +#define TF_LITE_GLOBAL_STD_PREFIX //std +#endif + +#define DECLARE_STD_GLOBAL_SWITCH1(tf_name, std_name) \ + template \ + inline T tf_name(const T x) { \ + return TF_LITE_GLOBAL_STD_PREFIX::std_name(x); \ + } + +DECLARE_STD_GLOBAL_SWITCH1(TfLiteRound, round); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/max.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/max.h new file mode 100644 index 0000000..96e4e66 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/max.h @@ -0,0 +1,35 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_ + +#include + +namespace tflite { + +#if defined(TF_LITE_USE_GLOBAL_MAX) || defined(__ZEPHYR__) +inline float TfLiteMax(const float& x, const float& y) { + return ::max(x, y); +} +#else +template +inline T TfLiteMax(const T& x, const T& y) { + return ::fmax(x, y); +} +#endif + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/min.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/min.h new file mode 100644 index 0000000..e97b3f2 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/min.h @@ -0,0 +1,35 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_ + +#include + +namespace tflite { + +#if defined(TF_LITE_USE_GLOBAL_MIN) || defined(__ZEPHYR__) +inline float TfLiteMin(const float& x, const float& y) { + return ::min(x, y); +} +#else +template +inline T TfLiteMin(const T& x, const T& y) { + return ::fmin(x, y); +} +#endif + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/optimized/neon_check.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/optimized/neon_check.h new file mode 100644 index 0000000..bbf745c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/optimized/neon_check.h @@ -0,0 +1,40 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_ + +#if defined(__ARM_NEON__) || defined(__ARM_NEON) +#define USE_NEON +#include +#endif + +#if defined __GNUC__ && defined __SSE4_1__ && !defined TF_LITE_DISABLE_X86_NEON +#define USE_NEON +#include "NEON_2_SSE.h" +#endif + +// NEON_OR_PORTABLE(SomeFunc, args) calls NeonSomeFunc(args) if USE_NEON is +// defined, PortableSomeFunc(args) otherwise. +#ifdef USE_NEON +// Always use Neon code +#define NEON_OR_PORTABLE(funcname, ...) Neon##funcname(__VA_ARGS__) + +#else +// No NEON available: Use Portable code +#define NEON_OR_PORTABLE(funcname, ...) Portable##funcname(__VA_ARGS__) + +#endif // defined(USE_NEON) + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.cc b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.cc new file mode 100644 index 0000000..cf431cf --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.cc @@ -0,0 +1,395 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/quantization_util.h" + +#include +#include +#include + +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" + +namespace tflite { + +namespace { +// These constants are used to manipulate the binary representation of doubles. +// Double-precision binary64 floating point format is: +// Bit | 63 | 62-52 | 51-0 | +// | Sign | Exponent | Fraction | +// To avoid 64-bit integers as much as possible, I break this into high and +// low 32-bit chunks. High is: +// Bit | 31 | 30-20 | 19-0 | +// | Sign | Exponent | High Fraction | +// Low is: +// Bit | 31-0 | +// | Low Fraction | +// We then access the components through logical bit-wise operations to +// extract the parts needed, with the positions and masks derived from the +// layout shown above. +constexpr uint64_t kSignMask = 0x8000000000000000LL; +constexpr uint64_t kExponentMask = 0x7ff0000000000000LL; +constexpr int32_t kExponentShift = 52; +constexpr int32_t kExponentBias = 1023; +constexpr uint32_t kExponentIsBadNum = 0x7ff; +constexpr uint64_t kFractionMask = 0x000fffffffc00000LL; +constexpr uint32_t kFractionShift = 22; +constexpr uint32_t kFractionRoundingMask = 0x003fffff; +constexpr uint32_t kFractionRoundingThreshold = 0x00200000; +} // namespace + +void QuantizeMultiplier(double double_multiplier, int32_t* quantized_multiplier, + int* shift) { + if (double_multiplier == 0.) { + *quantized_multiplier = 0; + *shift = 0; + return; + } +#ifdef TFLITE_EMULATE_FLOAT + // If we're trying to avoid the use of floating-point instructions (for + // example on microcontrollers) then use an alternative implementation + // that only requires integer and bitwise operations. To enable this, you + // need to set the define during the build process for your platform. + int64_t q_fixed = IntegerFrExp(double_multiplier, shift); +#else // TFLITE_EMULATE_FLOAT + const double q = std::frexp(double_multiplier, shift); + auto q_fixed = static_cast(TfLiteRound(q * (1ll << 31))); +#endif // TFLITE_EMULATE_FLOAT + TFLITE_CHECK(q_fixed <= (1ll << 31)); + if (q_fixed == (1ll << 31)) { + q_fixed /= 2; + ++*shift; + } + TFLITE_CHECK_LE(q_fixed, std::numeric_limits::max()); + // A shift amount smaller than -31 would cause all bits to be shifted out + // and thus all results would be zero. We implement that instead with + // q_fixed==0, so as to avoid hitting issues with right-shift + // operations with shift amounts greater than 31. Note that this happens + // roughly when abs(double_multiplier) < 2^-31 and the present handling means + // that we're effectively flushing tiny double_multiplier's to zero. + // We could conceivably handle values in the range (roughly) [32, 63] + // as 'denormals' i.e. (shift==0, q_fixed < 2^30). In that point of view + // the present handling is just doing 'flush denormals to zero'. We could + // reconsider and actually generate nonzero denormals if a need arises. + if (*shift < -31) { + *shift = 0; + q_fixed = 0; + } + *quantized_multiplier = static_cast(q_fixed); +} + +void QuantizeMultiplierGreaterThanOne(double double_multiplier, + int32_t* quantized_multiplier, + int* left_shift) { + TFLITE_CHECK_GT(double_multiplier, 1.); + QuantizeMultiplier(double_multiplier, quantized_multiplier, left_shift); + TFLITE_CHECK_GE(*left_shift, 0); +} + +void QuantizeMultiplierSmallerThanOneExp(double double_multiplier, + int32_t* quantized_multiplier, + int* left_shift) { + TFLITE_CHECK_LT(double_multiplier, 1.); + TFLITE_CHECK_GT(double_multiplier, 0.); + int shift; + QuantizeMultiplier(double_multiplier, quantized_multiplier, &shift); + TFLITE_CHECK_LE(shift, 0); + *left_shift = shift; +} + +int64_t IntegerFrExp(double input, int* shift) { + // Make sure our assumptions about the double layout hold. + TFLITE_CHECK_EQ(8, sizeof(double)); + + // We want to access the bits of the input double value directly, which is + // tricky to do safely, so use a union to handle the casting. + union { + double double_value; + uint64_t double_as_uint; + } cast_union; + cast_union.double_value = input; + const uint64_t u = cast_union.double_as_uint; + + // If the bitfield is all zeros apart from the sign bit, this is a normalized + // zero value, so return standard values for this special case. + if ((u & ~kSignMask) == 0) { + *shift = 0; + return 0; + } + + // Deal with NaNs and Infs, which are always indicated with a fixed pattern in + // the exponent, and distinguished by whether the fractions are zero or + // non-zero. + const uint32_t exponent_part = ((u & kExponentMask) >> kExponentShift); + if (exponent_part == kExponentIsBadNum) { + *shift = std::numeric_limits::max(); + if (u & kFractionMask) { + // NaN, so just return zero (with the exponent set to INT_MAX). + return 0; + } else { + // Infinity, so return +/- INT_MAX. + if (u & kSignMask) { + return std::numeric_limits::min(); + } else { + return std::numeric_limits::max(); + } + } + } + + // The shift is fairly easy to extract from the high bits of the double value, + // just by masking it out and applying a bias. The std::frexp() implementation + // always returns values between 0.5 and 1.0 though, whereas the exponent + // assumes 1.0 to 2.0 is the standard range, so I add on one to match that + // interface. + *shift = (exponent_part - kExponentBias) + 1; + + // There's an implicit high bit in the double format definition, so make sure + // we include that at the top, and then reconstruct the rest of the fractional + // value from the remaining fragments. + int64_t fraction = 0x40000000 + ((u & kFractionMask) >> kFractionShift); + + // We're cutting off some bits at the bottom, so to exactly match the standard + // frexp implementation here we'll apply rounding by adding one to the least + // significant bit of the result if the discarded portion is over half of the + // maximum. + if ((u & kFractionRoundingMask) > kFractionRoundingThreshold) { + fraction += 1; + } + // Negate the fraction if the sign bit was set. + if (u & kSignMask) { + fraction *= -1; + } + + return fraction; +} + +double DoubleFromFractionAndShift(int64_t fraction, int shift) { + union { + double double_value; + uint64_t double_as_uint; + } result; + + // Detect NaNs and infinities. + if (shift == std::numeric_limits::max()) { + if (fraction == 0) { + return std::numeric_limits::quiet_NaN(); + } else if (fraction > 0) { + return std::numeric_limits::infinity(); + } else { + return -std::numeric_limits::infinity(); + } + } + + // Return a normalized zero for a zero fraction. + if (fraction == 0) { + result.double_as_uint = 0; + return result.double_value; + } + + bool is_negative = (fraction < 0); + int64_t encoded_fraction = is_negative ? -fraction : fraction; + int64_t encoded_shift = (shift - 1); + while (encoded_fraction < 0x40000000) { + encoded_fraction *= 2; + encoded_shift -= 1; + } + while (encoded_fraction > 0x80000000) { + encoded_fraction /= 2; + encoded_shift += 1; + } + encoded_fraction -= 0x40000000; + if (encoded_shift < -1022) { + encoded_shift = -1023; + } else if (encoded_shift > 1022) { + encoded_shift = 1023; + } + encoded_shift += kExponentBias; + uint64_t encoded_sign = is_negative ? kSignMask : 0; + result.double_as_uint = encoded_sign | (encoded_shift << kExponentShift) | + (encoded_fraction << kFractionShift); + return result.double_value; +} + +double IntegerDoubleMultiply(double a, double b) { + int a_shift; + const int64_t a_fraction = IntegerFrExp(a, &a_shift); + int b_shift; + const int64_t b_fraction = IntegerFrExp(b, &b_shift); + // Detect NaNs and infinities. + if (a_shift == std::numeric_limits::max() || + (b_shift == std::numeric_limits::max())) { + return std::numeric_limits::quiet_NaN(); + } + const int result_shift = a_shift + b_shift + 1; + const int64_t result_fraction = (a_fraction * b_fraction) >> 32; + return DoubleFromFractionAndShift(result_fraction, result_shift); +} + +int IntegerDoubleCompare(double a, double b) { + int a_shift; + const int64_t a_fraction = IntegerFrExp(a, &a_shift); + int b_shift; + const int64_t b_fraction = IntegerFrExp(b, &b_shift); + + // Detect NaNs and infinities. + if (a_shift == std::numeric_limits::max() || + (b_shift == std::numeric_limits::max())) { + return 1; + } + + if ((a_fraction == 0) && (b_fraction < 0)) { + return 1; + } else if ((a_fraction < 0) && (b_fraction == 0)) { + return -1; + } else if (a_shift < b_shift) { + return -1; + } else if (a_shift > b_shift) { + return 1; + } else if (a_fraction < b_fraction) { + return -1; + } else if (a_fraction > b_fraction) { + return 1; + } else { + return 0; + } +} + +void PreprocessSoftmaxScaling(double beta, double input_scale, + int input_integer_bits, + int32_t* quantized_multiplier, int* left_shift) { + // If the overall multiplier (input and beta) is large, then exp() of an + // input difference of 1 scaled by this will be large. In other words, we + // can cap the multiplier and know that, when it is used, the output will be + // (round to) zero wherever the input is not at the maximum value. + + // If the overall scale is less than one, and input_integer_bits=0, then the + // result is double equivalent of Q0.31 (actually with more precision). Thus + // this generates a Q(input_integer_bits).(31-input_integer_bits) + // representation. +#ifdef TFLITE_EMULATE_FLOAT + const double input_beta = IntegerDoubleMultiply(beta, input_scale); + int shift; + int64_t fraction = IntegerFrExp(input_beta, &shift); + shift += (31 - input_integer_bits); + double input_beta_real_multiplier = + DoubleFromFractionAndShift(fraction, shift); + if (IntegerDoubleCompare(input_beta_real_multiplier, (1ll << 31) - 1.0) > 0) { + input_beta_real_multiplier = (1ll << 31) - 1.0; + } +#else // TFLITE_EMULATE_FLOAT + const double input_beta_real_multiplier = std::min( + beta * input_scale * (1 << (31 - input_integer_bits)), (1ll << 31) - 1.0); +#endif // TFLITE_EMULATE_FLOAT + + QuantizeMultiplierGreaterThanOne(input_beta_real_multiplier, + quantized_multiplier, left_shift); +} + +void PreprocessLogSoftmaxScalingExp(double beta, double input_scale, + int input_integer_bits, + int32_t* quantized_multiplier, + int* left_shift, + int32_t* reverse_scaling_divisor, + int* reverse_scaling_left_shift) { + PreprocessSoftmaxScaling(beta, input_scale, input_integer_bits, + quantized_multiplier, left_shift); + + // Also calculate what amounts to the inverse scaling factor for the input. + const double real_reverse_scaling_divisor = + (1 << (31 - *left_shift)) / static_cast(*quantized_multiplier); + tflite::QuantizeMultiplierSmallerThanOneExp(real_reverse_scaling_divisor, + reverse_scaling_divisor, + reverse_scaling_left_shift); +} + +int CalculateInputRadius(int input_integer_bits, int input_left_shift, + int total_signed_bits) { +#ifdef TFLITE_EMULATE_FLOAT + int64_t result = (1 << input_integer_bits) - 1; + result <<= (total_signed_bits - input_integer_bits); + result >>= input_left_shift; + return result; +#else // TFLITE_EMULATE_FLOAT + const double max_input_rescaled = + 1.0 * ((1 << input_integer_bits) - 1) * + (1ll << (total_signed_bits - input_integer_bits)) / + (1ll << input_left_shift); + // Tighten bound using floor. Suppose that we could use the exact value. + // After scaling the difference, the result would be at the maximum. Thus we + // must ensure that our value has lower magnitude. + return static_cast(std::floor(max_input_rescaled)); +#endif // TFLITE_EMULATE_FLOAT +} + +void NudgeQuantizationRange(const float min, const float max, + const int quant_min, const int quant_max, + float* nudged_min, float* nudged_max, + float* nudged_scale) { + // This code originates from tensorflow/core/kernels/fake_quant_ops_functor.h. + const float quant_min_float = static_cast(quant_min); + const float quant_max_float = static_cast(quant_max); + *nudged_scale = (max - min) / (quant_max_float - quant_min_float); + const float zero_point_from_min = quant_min_float - min / *nudged_scale; + uint16_t nudged_zero_point; + if (zero_point_from_min < quant_min_float) { + nudged_zero_point = static_cast(quant_min); + } else if (zero_point_from_min > quant_max_float) { + nudged_zero_point = static_cast(quant_max); + } else { + nudged_zero_point = static_cast(TfLiteRound(zero_point_from_min)); + } + *nudged_min = (quant_min_float - nudged_zero_point) * (*nudged_scale); + *nudged_max = (quant_max_float - nudged_zero_point) * (*nudged_scale); +} + +void FakeQuantizeArray(const float nudged_scale, const float nudged_min, + const float nudged_max, const float* input_data, + float* output_data, const float size) { + // This code originates from tensorflow/core/kernels/fake_quant_ops_functor.h. + const float inv_nudged_scale = 1.0f / nudged_scale; + + for (int i = 0; i < size; i++) { + const float src_val = input_data[i]; + const float clamped = std::min(nudged_max, std::max(nudged_min, src_val)); + const float clamped_shifted = clamped - nudged_min; + const float dst_val = + TfLiteRound(clamped_shifted * inv_nudged_scale) * nudged_scale + + nudged_min; + output_data[i] = dst_val; + } +} + +bool CheckedLog2(const float x, int* log2_result) { + // Using TfLiteRound instead of std::round and std::log instead of + // std::log2 to work around these functions being missing in a toolchain + // used in some TensorFlow tests as of May 2018. + const float x_log2 = std::log(x) * (1.0f / std::log(2.0f)); + const float x_log2_rounded = TfLiteRound(x_log2); + const float x_log2_fracpart = x_log2 - x_log2_rounded; + + *log2_result = static_cast(x_log2_rounded); + return std::abs(x_log2_fracpart) < 1e-3f; +} + +void QuantizeMultiplierArray(const double* effective_scales, size_t size, + int32_t* effective_scale_significand, + int* effective_shift) { + for (size_t i = 0; i < size; ++i) { + QuantizeMultiplier(effective_scales[i], &effective_scale_significand[i], + &effective_shift[i]); + } +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.h new file mode 100644 index 0000000..0ee914b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/quantization_util.h @@ -0,0 +1,292 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_QUANTIZATION_UTIL_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_QUANTIZATION_UTIL_H_ + +#include +#include +#include + +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +// Given the min and max values of a float array, return +// reasonable quantization parameters to use for this array. +template +QuantizationParams ChooseQuantizationParams(double rmin, double rmax, + bool narrow_range) { + const T qmin = std::numeric_limits::min() + (narrow_range ? 1 : 0); + const T qmax = std::numeric_limits::max(); + const double qmin_double = qmin; + const double qmax_double = qmax; + // 0 should always be a representable value. Let's assume that the initial + // min,max range contains 0. + TFLITE_CHECK_LE(rmin, 0.); + TFLITE_CHECK_GE(rmax, 0.); + if (rmin == rmax) { + // Special case where the min,max range is a point. Should be {0}. + TFLITE_CHECK_EQ(rmin, 0.); + TFLITE_CHECK_EQ(rmax, 0.); + QuantizationParams quantization_params; + quantization_params.zero_point = 0; + quantization_params.scale = 0.; + return quantization_params; + } + + // General case. + // + // First determine the scale. + const double scale = (rmax - rmin) / (qmax_double - qmin_double); + + // Zero-point computation. + // First the initial floating-point computation. The zero-point can be + // determined from solving an affine equation for any known pair + // (real value, corresponding quantized value). + // We know two such pairs: (rmin, qmin) and (rmax, qmax). + // The arithmetic error on the zero point computed from either pair + // will be roughly machine_epsilon * (sum of absolute values of terms) + // so we want to use the variant that adds the smaller terms. + const double zero_point_from_min = qmin_double - rmin / scale; + const double zero_point_from_max = qmax_double - rmax / scale; + const double zero_point_from_min_error = + std::abs(qmin_double) + std::abs(rmin / scale); + const double zero_point_from_max_error = + std::abs(qmax_double) + std::abs(rmax / scale); + + const double zero_point_double = + zero_point_from_min_error < zero_point_from_max_error + ? zero_point_from_min + : zero_point_from_max; + + // Now we need to nudge the zero point to be an integer + // (our zero points are integer, and this is motivated by the requirement + // to be able to represent the real value "0" exactly as a quantized value, + // which is required in multiple places, for example in Im2col with SAME + // padding). + T nudged_zero_point = 0; + if (zero_point_double < qmin_double) { + nudged_zero_point = qmin; + } else if (zero_point_double > qmax_double) { + nudged_zero_point = qmax; + } else { + nudged_zero_point = static_cast(round(zero_point_double)); + } + // The zero point should always be in the range of quantized value, + // [qmin, qmax]. + TFLITE_CHECK_GE(nudged_zero_point, qmin); + TFLITE_CHECK_LE(nudged_zero_point, qmax); + + // Finally, store the result nudged quantization params. + QuantizationParams quantization_params; + quantization_params.zero_point = nudged_zero_point; + quantization_params.scale = scale; + return quantization_params; +} + +template +QuantizationParams ChooseQuantizationParams(double rmin, double rmax) { + return ChooseQuantizationParams(rmin, rmax, false); +} + +// Converts a floating-point number to an integer. For all inputs x where +// static_cast(x) is legal according to the C++ standard, the result +// is identical to that cast (i.e. the result is x with its fractional part +// truncated whenever that is representable as IntOut). +// +// static_cast would cause undefined behavior for the following cases, which +// have well-defined behavior for this function: +// +// 1. If x is NaN, the result is zero. +// +// 2. If the truncated form of x is above the representable range of IntOut, +// the result is std::numeric_limits::max(). +// +// 3. If the truncated form of x is below the representable range of IntOut, +// the result is std::numeric_limits::min(). +// +// Note that cases #2 and #3 cover infinities as well as finite numbers. +// +// The range of FloatIn must include the range of IntOut, otherwise +// the results are undefined. +// TODO(sfeuz): Replace by absl::SafeCast once available. +template +IntOut SafeCast(FloatIn x) { + static_assert(!std::numeric_limits::is_integer, + "FloatIn is integer"); + static_assert(std::numeric_limits::is_integer, + "IntOut is not integer"); + static_assert(std::numeric_limits::radix == 2, "IntOut is base 2"); + + // Special case NaN, for which the logic below doesn't work. + if (std::isnan(x)) { + return 0; + } + + // Negative values all clip to zero for unsigned results. + if (!std::numeric_limits::is_signed && x < 0) { + return 0; + } + + // Handle infinities. + if (std::isinf(x)) { + return x < 0 ? std::numeric_limits::min() + : std::numeric_limits::max(); + } + + // Set exp such that x == f * 2^exp for some f with |f| in [0.5, 1.0), + // unless x is zero in which case exp == 0. Note that this implies that the + // magnitude of x is strictly less than 2^exp. + int exp = 0; + std::frexp(x, &exp); + + // Let N be the number of non-sign bits in the representation of IntOut. If + // the magnitude of x is strictly less than 2^N, the truncated version of x + // is representable as IntOut. The only representable integer for which this + // is not the case is kMin for signed types (i.e. -2^N), but that is covered + // by the fall-through below. + if (exp <= std::numeric_limits::digits) { + return x; + } + + // Handle numbers with magnitude >= 2^N. + return x < 0 ? std::numeric_limits::min() + : std::numeric_limits::max(); +} + +// Decompose a double multiplier into a Q0.31 int32 representation of its +// significand, and shift representation of NEGATIVE its exponent --- +// this is intended as a RIGHT-shift. +// +// Restricted to the case where the multiplier < 1 (and non-negative). +void QuantizeMultiplierSmallerThanOneExp(double double_multiplier, + int32_t* quantized_multiplier, + int* left_shift); + +// Decompose a double multiplier into a Q0.31 int32 representation of its +// significand, and shift representation of its exponent. +// +// Restricted to the case where the multiplier > 1. +void QuantizeMultiplierGreaterThanOne(double double_multiplier, + int32_t* quantized_multiplier, + int* left_shift); + +// Decompose a double multiplier into a Q0.31 int32 representation of its +// significand, and shift representation of its exponent. +// +// Handles an arbitrary positive multiplier. The 'shift' output-value is +// basically the 'floating-point exponent' of the multiplier: +// Negative for a right-shift (when the multiplier is <1), positive for a +// left-shift (when the multiplier is >1) +void QuantizeMultiplier(double double_multiplier, int32_t* quantized_multiplier, + int* shift); + +// Splits a double input value into a returned fraction, and a shift value from +// the exponent, using only bitwise and integer operations to support +// microcontrollers and other environments without floating-point support. +// +// This is designed to be a replacement for how std::frexp() is used within the +// QuantizeMultiplier() function, and so has a different signature than the +// standard version, returning a 64-bit integer rather than a double. This +// result has a maximum value of 1<<31, with the fraction expressed as a +// proportion of that maximum. +// +// std::frexp() returns NaNs and infinities unmodified, but since we're +// returning integers that can't represent those values, instead we return +// a shift of std::numeric_limits::max() for all bad numbers, with an int64 +// result of 0 for NaNs, std:numeric_limits::max() for +INFINITY, and +// std::numeric_limits::min() for -INFINITY. Denormalized inputs will +// result in return values that end up truncating some bits at the end, +// reflecting the loss of precision inherent in denormalization. +int64_t IntegerFrExp(double input, int* shift); + +// Converts an integer fraction in the format produced by IntegerFrExp (where +// 0x40000000 is 1.0) and an exponent shift (between -1022 and +1022) into an +// IEEE binary64 double format result. The implementation uses only integer and +// bitwise operators, so no floating point hardware support or emulation is +// needed. This is here so quantized operations can run non-time-critical +// preparation calculations on microcontrollers and other platforms without +// float support. +double DoubleFromFractionAndShift(int64_t fraction, int shift); + +// Performs a multiplication of two numbers in double format, using only integer +// and bitwise instructions. This is aimed at supporting housekeeping functions +// for quantized operations on microcontrollers without floating-point hardware. +double IntegerDoubleMultiply(double a, double b); + +// Returns -1 if a is less than b, 0 if a and b are equal, and +1 if a is +// greater than b. It is implemented using only integer and logical instructions +// so that it can be easily run on microcontrollers for quantized operations. +int IntegerDoubleCompare(double a, double b); + +// This first creates a multiplier in a double equivalent of +// Q(input_integer_bits).(31-input_integer_bits) representation, with extra +// precision in the double's fractional bits. It then splits the result into +// significand and exponent. +void PreprocessSoftmaxScaling(double beta, double input_scale, + int input_integer_bits, + int32_t* quantized_multiplier, int* left_shift); +// Like PreprocessSoftmaxScaling, but inverse scaling factors also calculated. +void PreprocessLogSoftmaxScalingExp(double beta, double input_scale, + int input_integer_bits, + int32_t* quantized_multiplier, + int* left_shift, + int32_t* reverse_scaling_divisor, + int* reverse_scaling_left_shift); +// Calculate the largest input that will result in a within-bounds intermediate +// result within MultiplyByQuantizedMultiplierGreaterThanOne. In other words, +// it must not overflow before we reduce the value by multiplication by the +// input multiplier. The negative radius is used as the minimum difference in +// Softmax. +int CalculateInputRadius(int input_integer_bits, int input_left_shift, + int total_signed_bits = 31); + +// Nudges a min/max quantization range to ensure zero is zero. +// Gymnastics with nudged zero point is to ensure that real zero maps to +// an integer, which is required for e.g. zero-padding in convolutional layers. +// Outputs nudged_min, nudged_max, nudged_scale. +void NudgeQuantizationRange(const float min, const float max, + const int quant_min, const int quant_max, + float* nudged_min, float* nudged_max, + float* nudged_scale); + +// Fake quantizes (quantizes and dequantizes) input_data using the scale, +// nudged_min, and nudged_max from NudgeQuantizationRange. This matches the code +// in TensorFlow's FakeQuantizeWithMinMaxVarsFunctor. +void FakeQuantizeArray(const float nudged_scale, const float nudged_min, + const float nudged_max, const float* input_data, + float* output_data, const float size); + +// If x is approximately a power of two (with any positive or negative +// exponent), stores that exponent (i.e. log2(x)) in *log2_result, otherwise +// returns false. +bool CheckedLog2(const float x, int* log2_result); + +// Decomposes an array of double multipliers into a Q0.31 int32 representation +// of its significand, and shift representation of its exponent. +// +// Handles an arbitrary multiplier. The 'shift' output-value is +// basically the 'floating-point exponent' of the multiplier: +// Negative for a right-shift (when the multiplier is <1), positive for a +// left-shift (when the multiplier is >1) +void QuantizeMultiplierArray(const double* effective_scales, size_t size, + int32_t* effective_scale_significand, + int* effective_shift); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_QUANTIZATION_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/add.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/add.h new file mode 100644 index 0000000..5be7ab4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/add.h @@ -0,0 +1,454 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ADD_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ADD_H_ + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { + +namespace reference_ops { + +template +inline void Add(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const T* input1_data, + const RuntimeShape& input2_shape, const T* input2_data, + const RuntimeShape& output_shape, T* output_data) { + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = ActivationFunctionWithMinMax( + input1_data[i] + input2_data[i], params.quantized_activation_min, + params.quantized_activation_max); + } +} + +inline void Add(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const float* input1_data, + const RuntimeShape& input2_shape, const float* input2_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; i++) { + auto x = input1_data[i] + input2_data[i]; + output_data[i] = ActivationFunctionWithMinMax( + x, params.float_activation_min, params.float_activation_max); + } +} + +// Element-wise add that can often be used for inner loop of broadcast add as +// well as the non-broadcast add. + +// This function is used for 8-bit as well as for 16-bit, but the accumulator +// is 32-bit for both cases. The overflow does not happen due to the +// choice of the shift (20 or 15, accordingly - see add.cc for more comments). +template +inline void AddElementwise(int size, const ArithmeticParams& params, + const T* input1_data, const T* input2_data, + T* output_data) { + TFLITE_DCHECK_GT(params.input1_offset, -std::numeric_limits::max()); + TFLITE_DCHECK_GT(params.input2_offset, -std::numeric_limits::max()); + TFLITE_DCHECK_LT(params.input1_offset, std::numeric_limits::max()); + TFLITE_DCHECK_LT(params.input2_offset, std::numeric_limits::max()); + + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sum = scaled_input1_val + scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sum, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[i] = static_cast(clamped_output); + } +} + +// Scalar-broadcast add that can be used for inner loop of more general +// broadcast add, so that, for example, scalar-broadcast with batch will still +// be fast. +inline void AddScalarBroadcast(int size, const ArithmeticParams& params, + uint8_t input1_data, const uint8_t* input2_data, + uint8_t* output_data) { + TFLITE_DCHECK_GT(params.input1_offset, -256); + TFLITE_DCHECK_GT(params.input2_offset, -256); + TFLITE_DCHECK_LT(params.input1_offset, 256); + TFLITE_DCHECK_LT(params.input2_offset, 256); + + const int32_t input1_val = params.input1_offset + input1_data; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + for (int i = 0; i < size; ++i) { + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sum = scaled_input1_val + scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sum, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[i] = static_cast(clamped_output); + } +} + +inline void Add(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const uint8_t* input1_data, + const RuntimeShape& input2_shape, const uint8_t* input2_data, + const RuntimeShape& output_shape, uint8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + TFLITE_DCHECK_GT(params.input1_offset, -256); + TFLITE_DCHECK_GT(params.input2_offset, -256); + TFLITE_DCHECK_LT(params.input1_offset, 256); + TFLITE_DCHECK_LT(params.input2_offset, 256); + AddElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +inline void AddGeneralParamScale(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int16_t* input1_data, + const RuntimeShape& input2_shape, + const int16_t* input2_data, + const RuntimeShape& output_shape, + int16_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + int max_value = std::numeric_limits::max(); + + TFLITE_DCHECK_GT(params.input1_offset, -max_value); + TFLITE_DCHECK_GT(params.input2_offset, -max_value); + TFLITE_DCHECK_LT(params.input1_offset, max_value); + TFLITE_DCHECK_LT(params.input2_offset, max_value); + AddElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +inline void Add(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const int16_t* input1_data, + const RuntimeShape& input2_shape, const int16_t* input2_data, + const RuntimeShape& output_shape, int16_t* output_data, + bool pot_scale = true) { + if (!pot_scale) { + AddGeneralParamScale(params, input1_shape, input1_data, input2_shape, + input2_data, output_shape, output_data); + return; + } + + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + + const int input1_shift = params.input1_shift; + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + const int16_t output_activation_min = params.quantized_activation_min; + const int16_t output_activation_max = params.quantized_activation_max; + + TFLITE_DCHECK(input1_shift == 0 || params.input2_shift == 0); + TFLITE_DCHECK_LE(input1_shift, 0); + TFLITE_DCHECK_LE(params.input2_shift, 0); + const int16_t* not_shift_input = + input1_shift == 0 ? input1_data : input2_data; + const int16_t* shift_input = input1_shift == 0 ? input2_data : input1_data; + const int input_right_shift = + input1_shift == 0 ? -params.input2_shift : -input1_shift; + + for (int i = 0; i < flat_size; i++) { + // F0 uses 0 integer bits, range [-1, 1]. + using F0 = gemmlowp::FixedPoint; + + F0 input_ready_scaled = F0::FromRaw(not_shift_input[i]); + F0 scaled_input = F0::FromRaw( + gemmlowp::RoundingDivideByPOT(shift_input[i], input_right_shift)); + F0 result = gemmlowp::SaturatingAdd(scaled_input, input_ready_scaled); + const int16_t raw_output = result.raw(); + const int16_t clamped_output = std::min( + output_activation_max, std::max(output_activation_min, raw_output)); + output_data[i] = clamped_output; + } +} + +// TODO(jiawen): We can implement BroadcastAdd on buffers of arbitrary +// dimensionality if the runtime code does a single loop over one dimension +// that handles broadcasting as the base case. The code generator would then +// generate max(D1, D2) nested for loops. +// TODO(benoitjacob): BroadcastAdd is intentionally duplicated from +// reference_ops.h. Once an optimized version is implemented and NdArrayDesc +// is no longer referenced in this file, move NdArrayDesc from types.h to +// reference_ops.h. +inline void BroadcastAdd4DSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const float* input1_data, + const RuntimeShape& input2_shape, + const float* input2_data, + const RuntimeShape& output_shape, + float* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + output_data[Offset(extended_output_shape, b, y, x, c)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, b, y, x, c)] + + input2_data[SubscriptToIndex(desc2, b, y, x, c)], + params.float_activation_min, params.float_activation_max); + } + } + } + } +} + +inline void BroadcastAdd4DSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int32_t* input1_data, + const RuntimeShape& input2_shape, + const int32_t* input2_data, + const RuntimeShape& output_shape, + int32_t* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + output_data[Offset(extended_output_shape, b, y, x, c)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, b, y, x, c)] + + input2_data[SubscriptToIndex(desc2, b, y, x, c)], + params.quantized_activation_min, + params.quantized_activation_max); + } + } + } + } +} + +// This function is used for 8-bit as well as for 16-bit, but the accumulator +// is 32-bit for both cases. The overflow does not happen due to the +// choice of the shift (20 or 15, accordingly - see add.cc for more comments). +template +inline void BroadcastAdd4DSlow( + const ArithmeticParams& params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, T* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + const int32_t input1_val = + params.input1_offset + + input1_data[SubscriptToIndex(desc1, b, y, x, c)]; + const int32_t input2_val = + params.input2_offset + + input2_data[SubscriptToIndex(desc2, b, y, x, c)]; + const int32_t shifted_input1_val = + input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = + input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, + params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, + params.input2_shift); + const int32_t raw_sum = scaled_input1_val + scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sum, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[Offset(extended_output_shape, b, y, x, c)] = + static_cast(clamped_output); + } + } + } + } +} + +inline void BroadcastAddFivefold(const ArithmeticParams& unswitched_params, + const RuntimeShape& unswitched_input1_shape, + const uint8_t* unswitched_input1_data, + const RuntimeShape& unswitched_input2_shape, + const uint8_t* unswitched_input2_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + ArithmeticParams switched_params = unswitched_params; + switched_params.input1_offset = unswitched_params.input2_offset; + switched_params.input1_multiplier = unswitched_params.input2_multiplier; + switched_params.input1_shift = unswitched_params.input2_shift; + switched_params.input2_offset = unswitched_params.input1_offset; + switched_params.input2_multiplier = unswitched_params.input1_multiplier; + switched_params.input2_shift = unswitched_params.input1_shift; + + const bool use_unswitched = + unswitched_params.broadcast_category == + tflite::BroadcastableOpCategory::kFirstInputBroadcastsFast; + + const ArithmeticParams& params = + use_unswitched ? unswitched_params : switched_params; + const uint8_t* input1_data = + use_unswitched ? unswitched_input1_data : unswitched_input2_data; + const uint8_t* input2_data = + use_unswitched ? unswitched_input2_data : unswitched_input1_data; + + // Fivefold nested loops. The second input resets its position for each + // iteration of the second loop. The first input resets its position at the + // beginning of the fourth loop. The innermost loop is an elementwise add of + // sections of the arrays. + uint8_t* output_data_ptr = output_data; + const uint8_t* input1_data_ptr = input1_data; + const uint8_t* input2_data_reset = input2_data; + // In the fivefold pattern, y0, y2 and y4 are not broadcast, and so shared + // between input shapes. y3 for input 1 is always broadcast, and so the + // dimension there is 1, whereas optionally y1 might be broadcast for input 2. + // Put another way, + // input1.shape.FlatSize = y0 * y1 * y2 * y4, + // input2.shape.FlatSize = y0 * y2 * y3 * y4. + int y0 = params.broadcast_shape[0]; + int y1 = params.broadcast_shape[1]; + int y2 = params.broadcast_shape[2]; + int y3 = params.broadcast_shape[3]; + int y4 = params.broadcast_shape[4]; + if (y4 > 1) { + // General fivefold pattern, with y4 > 1 so there is a non-broadcast inner + // dimension. + for (int i0 = 0; i0 < y0; ++i0) { + const uint8_t* input2_data_ptr; + for (int i1 = 0; i1 < y1; ++i1) { + input2_data_ptr = input2_data_reset; + for (int i2 = 0; i2 < y2; ++i2) { + for (int i3 = 0; i3 < y3; ++i3) { + AddElementwise(y4, params, input1_data_ptr, input2_data_ptr, + output_data_ptr); + input2_data_ptr += y4; + output_data_ptr += y4; + } + // We have broadcast y4 of input1 data y3 times, and now move on. + input1_data_ptr += y4; + } + } + // We have broadcast y2*y3*y4 of input2 data y1 times, and now move on. + input2_data_reset = input2_data_ptr; + } + } else { + // Special case of y4 == 1, in which the innermost loop is a single element + // and can be combined with the next (y3) as an inner broadcast. + // + // Note that this handles the case of pure scalar broadcast when + // y0 == y1 == y2 == 1. With low overhead it handles cases such as scalar + // broadcast with batch (as y2 > 1). + // + // NOTE The process is the same as the above general case except simplified + // for y4 == 1 and the loop over y3 is contained within the + // AddScalarBroadcast function. + for (int i0 = 0; i0 < y0; ++i0) { + const uint8_t* input2_data_ptr; + for (int i1 = 0; i1 < y1; ++i1) { + input2_data_ptr = input2_data_reset; + for (int i2 = 0; i2 < y2; ++i2) { + AddScalarBroadcast(y3, params, *input1_data_ptr, input2_data_ptr, + output_data_ptr); + input2_data_ptr += y3; + output_data_ptr += y3; + input1_data_ptr += 1; + } + } + input2_data_reset = input2_data_ptr; + } + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ADD_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/arg_min_max.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/arg_min_max.h new file mode 100644 index 0000000..e6f34fd --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/arg_min_max.h @@ -0,0 +1,68 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ARG_MIN_MAX_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ARG_MIN_MAX_H_ + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +template +void ArgMinMax(const RuntimeShape& input1_shape, const T1* input1_data, + const T3* input2_data, const RuntimeShape& output_shape, + T2* output_data, const Cmp& cmp) { + TFLITE_DCHECK_GT(input1_shape.DimensionsCount(), 0); + TFLITE_DCHECK_EQ(input1_shape.DimensionsCount() - 1, + output_shape.DimensionsCount()); + int axis = input2_data[0]; + if (axis < 0) { + axis += input1_shape.DimensionsCount(); + } + const int axis_size = input1_shape.Dims(axis); + + int outer_size = 1; + for (int i = 0; i < axis; ++i) { + TFLITE_DCHECK_EQ(input1_shape.Dims(i), output_shape.Dims(i)); + outer_size *= input1_shape.Dims(i); + } + + int inner_size = 1; + const int dims_count = input1_shape.DimensionsCount(); + for (int i = axis + 1; i < dims_count; ++i) { + TFLITE_DCHECK_EQ(input1_shape.Dims(i), output_shape.Dims(i - 1)); + inner_size *= input1_shape.Dims(i); + } + for (int outer = 0; outer < outer_size; ++outer) { + for (int inner = 0; inner < inner_size; ++inner) { + auto min_max_value = input1_data[outer * axis_size * inner_size + inner]; + T2 min_max_index = 0; + for (int i = 1; i < axis_size; ++i) { + const auto& curr_value = + input1_data[(outer * axis_size + i) * inner_size + inner]; + if (cmp(curr_value, min_max_value)) { + min_max_value = curr_value; + min_max_index = static_cast(i); + } + } + output_data[outer * inner_size + inner] = min_max_index; + } + } +} +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ARG_MIN_MAX_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/binary_function.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/binary_function.h new file mode 100644 index 0000000..51d9e2b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/binary_function.h @@ -0,0 +1,84 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_BINARY_FUNCTION_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_BINARY_FUNCTION_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// TODO(ycling): Refactoring. Remove BroadcastLogical and use the more +// generalized and efficient BroadcastBinaryFunction. +// +// Also appears to duplicate MinimumMaximum. +// +// R: Result type. T1: Input 1 type. T2: Input 2 type. +template +inline void BroadcastBinaryFunction4DSlow( + const RuntimeShape& unextended_input1_shape, const T1* input1_data, + const RuntimeShape& unextended_input2_shape, const T2* input2_data, + const RuntimeShape& unextended_output_shape, R* output_data, + R (*func)(T1, T2)) { + TFLITE_DCHECK_LE(unextended_input1_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_input2_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(unextended_input1_shape, + unextended_input2_shape, &desc1, &desc2); + + for (int b = 0; b < output_shape.Dims(0); ++b) { + for (int y = 0; y < output_shape.Dims(1); ++y) { + for (int x = 0; x < output_shape.Dims(2); ++x) { + for (int c = 0; c < output_shape.Dims(3); ++c) { + auto out_idx = Offset(output_shape, b, y, x, c); + auto in1_idx = SubscriptToIndex(desc1, b, y, x, c); + auto in2_idx = SubscriptToIndex(desc2, b, y, x, c); + auto in1_val = input1_data[in1_idx]; + auto in2_val = input2_data[in2_idx]; + output_data[out_idx] = func(in1_val, in2_val); + } + } + } + } +} + +// R: Result type. T1: Input 1 type. T2: Input 2 type. +// TODO(renjieliu): Refactor other binary functions to use this one. +template +inline void BinaryFunction(const RuntimeShape& input1_shape, + const T1* input1_data, + const RuntimeShape& input2_shape, + const T2* input2_data, + const RuntimeShape& output_shape, R* output_data, + R (*func)(T1, T2)) { + const int flat_size = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = func(input1_data[i], input2_data[i]); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_BINARY_FUNCTION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/ceil.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/ceil.h new file mode 100644 index 0000000..66d1dc3 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/ceil.h @@ -0,0 +1,37 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CEIL_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CEIL_H_ + +#include + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline void Ceil(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; ++i) { + output_data[i] = std::ceil(input_data[i]); + } +} + +} // namespace reference_ops +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CEIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/comparisons.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/comparisons.h new file mode 100644 index 0000000..49844ab --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/comparisons.h @@ -0,0 +1,334 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_COMPARISONS_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_COMPARISONS_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/string_util.h" + +namespace tflite { + +namespace reference_ops { + +template +inline bool EqualFn(T lhs, T rhs) { + return lhs == rhs; +} + +template +inline bool NotEqualFn(T lhs, T rhs) { + return lhs != rhs; +} + +template +inline bool GreaterFn(T lhs, T rhs) { + return lhs > rhs; +} +template +inline bool GreaterEqualFn(T lhs, T rhs) { + return lhs >= rhs; +} +template +inline bool LessFn(T lhs, T rhs) { + return lhs < rhs; +} +template +inline bool LessEqualFn(T lhs, T rhs) { + return lhs <= rhs; +} + +inline bool StringRefEqualFn(const StringRef& lhs, const StringRef& rhs) { + if (lhs.len != rhs.len) return false; + for (int i = 0; i < lhs.len; ++i) { + if (lhs.str[i] != rhs.str[i]) return false; + } + return true; +} + +inline bool StringRefNotEqualFn(const StringRef& lhs, const StringRef& rhs) { + return !StringRefEqualFn(lhs, rhs); +} + +template +using ComparisonFn = bool (*)(T, T); + +template F> +inline void ComparisonImpl( + const ComparisonParams& op_params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, bool* output_data) { + const int64_t flatsize = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + for (int64_t i = 0; i < flatsize; ++i) { + output_data[i] = F(input1_data[i], input2_data[i]); + } +} + +inline void ComparisonStringImpl(bool (*F)(const StringRef&, const StringRef&), + const RuntimeShape& input1_shape, + const TfLiteTensor* input1, + const RuntimeShape& input2_shape, + const TfLiteTensor* input2, + const RuntimeShape& output_shape, + bool* output_data) { + const int64_t flatsize = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + for (int64_t i = 0; i < flatsize; ++i) { + const auto lhs = GetString(input1, i); + const auto rhs = GetString(input2, i); + output_data[i] = F(lhs, rhs); + } +} + +template F> +inline void Comparison(const ComparisonParams& op_params, + const RuntimeShape& input1_shape, + const float* input1_data, + const RuntimeShape& input2_shape, + const float* input2_data, + const RuntimeShape& output_shape, bool* output_data) { + ComparisonImpl(op_params, input1_shape, input1_data, input2_shape, + input2_data, output_shape, output_data); +} + +template F> +inline void ComparisonWithScaling( + const ComparisonParams& op_params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, bool* output_data) { + int left_shift = op_params.left_shift; + int32_t input1_offset = op_params.input1_offset; + int32_t input1_multiplier = op_params.input1_multiplier; + int input1_shift = op_params.input1_shift; + int32_t input2_offset = op_params.input2_offset; + int32_t input2_multiplier = op_params.input2_multiplier; + int input2_shift = op_params.input2_shift; + + const int64_t flatsize = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + for (int64_t i = 0; i < flatsize; ++i) { + const int32_t input1_val = input1_offset + input1_data[i]; + const int32_t input2_val = input2_offset + input2_data[i]; + const int32_t shifted_input1_val = input1_val * (1 << left_shift); + const int32_t shifted_input2_val = input2_val * (1 << left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, input1_multiplier, input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, input2_multiplier, input2_shift); + output_data[i] = F(scaled_input1_val, scaled_input2_val); + } +} + +struct BroadcastComparison4DSlowCommon { + const RuntimeShape output_shape; + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; +}; + +inline BroadcastComparison4DSlowCommon BroadcastComparison4DSlowPreprocess( + const RuntimeShape& unextended_input1_shape, + const RuntimeShape& unextended_input2_shape, + const RuntimeShape& unextended_output_shape) { + TFLITE_DCHECK_LE(unextended_input1_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_input2_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(unextended_input1_shape, + unextended_input2_shape, &desc1, &desc2); + return {RuntimeShape::ExtendedShape(4, unextended_output_shape), desc1, + desc2}; +} + +template F> +inline void BroadcastComparison4DSlowImpl( + const ComparisonParams& op_params, + const RuntimeShape& unextended_input1_shape, const T* input1_data, + const RuntimeShape& unextended_input2_shape, const T* input2_data, + const RuntimeShape& unextended_output_shape, bool* output_data) { + const BroadcastComparison4DSlowCommon dims = + BroadcastComparison4DSlowPreprocess(unextended_input1_shape, + unextended_input2_shape, + unextended_output_shape); + + for (int b = 0; b < dims.output_shape.Dims(0); ++b) { + for (int y = 0; y < dims.output_shape.Dims(1); ++y) { + for (int x = 0; x < dims.output_shape.Dims(2); ++x) { + for (int c = 0; c < dims.output_shape.Dims(3); ++c) { + output_data[Offset(dims.output_shape, b, y, x, c)] = + F(input1_data[SubscriptToIndex(dims.desc1, b, y, x, c)], + input2_data[SubscriptToIndex(dims.desc2, b, y, x, c)]); + } + } + } + } +} + +inline void BroadcastComparison4DSlowStringImpl( + bool (*F)(const StringRef&, const StringRef&), + const RuntimeShape& unextended_input1_shape, const TfLiteTensor* input1, + const RuntimeShape& unextended_input2_shape, const TfLiteTensor* input2, + const RuntimeShape& unextended_output_shape, bool* output_data) { + const BroadcastComparison4DSlowCommon dims = + BroadcastComparison4DSlowPreprocess(unextended_input1_shape, + unextended_input2_shape, + unextended_output_shape); + + for (int b = 0; b < dims.output_shape.Dims(0); ++b) { + for (int y = 0; y < dims.output_shape.Dims(1); ++y) { + for (int x = 0; x < dims.output_shape.Dims(2); ++x) { + for (int c = 0; c < dims.output_shape.Dims(3); ++c) { + const auto lhs = + GetString(input1, SubscriptToIndex(dims.desc1, b, y, x, c)); + const auto rhs = + GetString(input2, SubscriptToIndex(dims.desc2, b, y, x, c)); + output_data[Offset(dims.output_shape, b, y, x, c)] = F(lhs, rhs); + } + } + } + } +} + +template F> +inline void BroadcastComparison4DSlow(const ComparisonParams& op_params, + const RuntimeShape& input1_shape, + const float* input1_data, + const RuntimeShape& input2_shape, + const float* input2_data, + const RuntimeShape& output_shape, + bool* output_data) { + BroadcastComparison4DSlowImpl(op_params, input1_shape, input1_data, + input2_shape, input2_data, + output_shape, output_data); +} + +template F> +inline void BroadcastComparison4DSlowWithScaling( + const ComparisonParams& op_params, + const RuntimeShape& unextended_input1_shape, const T* input1_data, + const RuntimeShape& unextended_input2_shape, const T* input2_data, + const RuntimeShape& unextended_output_shape, bool* output_data) { + const BroadcastComparison4DSlowCommon dims = + BroadcastComparison4DSlowPreprocess(unextended_input1_shape, + unextended_input2_shape, + unextended_output_shape); + + int left_shift = op_params.left_shift; + int32_t input1_offset = op_params.input1_offset; + int32_t input1_multiplier = op_params.input1_multiplier; + int input1_shift = op_params.input1_shift; + int32_t input2_offset = op_params.input2_offset; + int32_t input2_multiplier = op_params.input2_multiplier; + int input2_shift = op_params.input2_shift; + + for (int b = 0; b < dims.output_shape.Dims(0); ++b) { + for (int y = 0; y < dims.output_shape.Dims(1); ++y) { + for (int x = 0; x < dims.output_shape.Dims(2); ++x) { + for (int c = 0; c < dims.output_shape.Dims(3); ++c) { + const int32_t input1_val = + input1_offset + + input1_data[SubscriptToIndex(dims.desc1, b, y, x, c)]; + const int32_t input2_val = + input2_offset + + input2_data[SubscriptToIndex(dims.desc2, b, y, x, c)]; + const int32_t shifted_input1_val = input1_val * (1 << left_shift); + const int32_t shifted_input2_val = input2_val * (1 << left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, input1_multiplier, input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, input2_multiplier, input2_shift); + output_data[Offset(dims.output_shape, b, y, x, c)] = + F(scaled_input1_val, scaled_input2_val); + } + } + } + } +} + +#define TFLITE_COMPARISON_OP(name) \ + inline void name(const ComparisonParams& op_params, \ + const RuntimeShape& input1_shape, const float* input1_data, \ + const RuntimeShape& input2_shape, const float* input2_data, \ + const RuntimeShape& output_shape, bool* output_data) { \ + Comparison(op_params, input1_shape, input1_data, input2_shape, \ + input2_data, output_shape, output_data); \ + } \ + template \ + inline void name##NoScaling( \ + const ComparisonParams& op_params, const RuntimeShape& input1_shape, \ + const T* input1_data, const RuntimeShape& input2_shape, \ + const T* input2_data, const RuntimeShape& output_shape, \ + bool* output_data) { \ + ComparisonImpl(op_params, input1_shape, input1_data, \ + input2_shape, input2_data, output_shape, \ + output_data); \ + } \ + template \ + inline void name##WithScaling( \ + const ComparisonParams& op_params, const RuntimeShape& input1_shape, \ + const T* input1_data, const RuntimeShape& input2_shape, \ + const T* input2_data, const RuntimeShape& output_shape, \ + bool* output_data) { \ + ComparisonWithScaling(op_params, input1_shape, input1_data, \ + input2_shape, input2_data, \ + output_shape, output_data); \ + } \ + template \ + inline void Broadcast4DSlow##name##NoScaling( \ + const ComparisonParams& op_params, const RuntimeShape& input1_shape, \ + const T* input1_data, const RuntimeShape& input2_shape, \ + const T* input2_data, const RuntimeShape& output_shape, \ + bool* output_data) { \ + BroadcastComparison4DSlowImpl( \ + op_params, input1_shape, input1_data, input2_shape, input2_data, \ + output_shape, output_data); \ + } \ + inline void Broadcast4DSlow##name( \ + const ComparisonParams& op_params, const RuntimeShape& input1_shape, \ + const float* input1_data, const RuntimeShape& input2_shape, \ + const float* input2_data, const RuntimeShape& output_shape, \ + bool* output_data) { \ + BroadcastComparison4DSlow(op_params, input1_shape, input1_data, \ + input2_shape, input2_data, \ + output_shape, output_data); \ + } \ + template \ + inline void Broadcast4DSlow##name##WithScaling( \ + const ComparisonParams& op_params, const RuntimeShape& input1_shape, \ + const T* input1_data, const RuntimeShape& input2_shape, \ + const T* input2_data, const RuntimeShape& output_shape, \ + bool* output_data) { \ + BroadcastComparison4DSlowWithScaling( \ + op_params, input1_shape, input1_data, input2_shape, input2_data, \ + output_shape, output_data); \ + } +TFLITE_COMPARISON_OP(Equal); +TFLITE_COMPARISON_OP(NotEqual); +TFLITE_COMPARISON_OP(Greater); +TFLITE_COMPARISON_OP(GreaterEqual); +TFLITE_COMPARISON_OP(Less); +TFLITE_COMPARISON_OP(LessEqual); +#undef TFLITE_COMPARISON_OP + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_COMPARISONS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/concatenation.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/concatenation.h new file mode 100644 index 0000000..2595979 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/concatenation.h @@ -0,0 +1,140 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONCATENATION_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONCATENATION_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +template +inline void Concatenation(const ConcatenationParams& params, + const RuntimeShape* const* input_shapes, + const Scalar* const* input_data, + const RuntimeShape& output_shape, + Scalar* output_data) { + int axis = params.axis; + int inputs_count = params.inputs_count; + const int concat_dimensions = output_shape.DimensionsCount(); + TFLITE_DCHECK_LT(axis, concat_dimensions); + + int64_t concat_size = 0; + for (int i = 0; i < inputs_count; i++) { + TFLITE_DCHECK_EQ(input_shapes[i]->DimensionsCount(), concat_dimensions); + for (int j = 0; j < concat_dimensions; j++) { + if (j != axis) { + MatchingDim(*input_shapes[i], j, output_shape, j); + } + } + concat_size += input_shapes[i]->Dims(axis); + } + TFLITE_DCHECK_EQ(concat_size, output_shape.Dims(axis)); + int64_t outer_size = 1; + for (int i = 0; i < axis; ++i) { + outer_size *= output_shape.Dims(i); + } + // For all input arrays, + // FlatSize() = outer_size * Dims(axis) * base_inner_size; + int64_t base_inner_size = 1; + for (int i = axis + 1; i < concat_dimensions; ++i) { + base_inner_size *= output_shape.Dims(i); + } + + Scalar* output_ptr = output_data; + for (int k = 0; k < outer_size; k++) { + for (int i = 0; i < inputs_count; ++i) { + const int copy_size = input_shapes[i]->Dims(axis) * base_inner_size; + const Scalar* input_ptr = input_data[i] + k * copy_size; + memcpy(output_ptr, input_ptr, copy_size * sizeof(Scalar)); + output_ptr += copy_size; + } + } +} + +// TODO(prabhumk): This is the same as the optimized implementation. +// TODO(prabhumk): The quantized implementation of concatentation isn't fully +// quantized as it takes scale as a floating point value. This should be fixed +// when optimizng this routine further. +inline void ConcatenationWithScaling(const ConcatenationParams& params, + const RuntimeShape* const* input_shapes, + const uint8_t* const* input_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + int axis = params.axis; + const int32_t* input_zeropoint = params.input_zeropoint; + const float* input_scale = params.input_scale; + int inputs_count = params.inputs_count; + const int32_t output_zeropoint = params.output_zeropoint; + const float output_scale = params.output_scale; + + const int concat_dimensions = output_shape.DimensionsCount(); + TFLITE_DCHECK_LT(axis, concat_dimensions); + + int64_t concat_size = 0; + for (int i = 0; i < inputs_count; i++) { + TFLITE_DCHECK_EQ(input_shapes[i]->DimensionsCount(), concat_dimensions); + for (int j = 0; j < concat_dimensions; j++) { + if (j != axis) { + MatchingDim(*input_shapes[i], j, output_shape, j); + } + } + concat_size += input_shapes[i]->Dims(axis); + } + TFLITE_DCHECK_EQ(concat_size, output_shape.Dims(axis)); + int64_t outer_size = 1; + for (int i = 0; i < axis; ++i) { + outer_size *= output_shape.Dims(i); + } + // For all input arrays, + // FlatSize() = outer_size * Dims(axis) * base_inner_size; + int64_t base_inner_size = 1; + for (int i = axis + 1; i < concat_dimensions; ++i) { + base_inner_size *= output_shape.Dims(i); + } + + const float inverse_output_scale = 1.f / output_scale; + uint8_t* output_ptr = output_data; + for (int k = 0; k < outer_size; k++) { + for (int i = 0; i < inputs_count; ++i) { + const int copy_size = input_shapes[i]->Dims(axis) * base_inner_size; + const uint8_t* input_ptr = input_data[i] + k * copy_size; + if (input_zeropoint[i] == output_zeropoint && + input_scale[i] == output_scale) { + memcpy(output_ptr, input_ptr, copy_size); + } else { + const float scale = input_scale[i] * inverse_output_scale; + const float bias = -input_zeropoint[i] * scale; + for (int j = 0; j < copy_size; ++j) { + const int32_t value = static_cast(tflite::TfLiteRound( + input_ptr[j] * scale + bias)) + + output_zeropoint; + output_ptr[j] = static_cast( + std::max(std::min(255, value), 0)); + } + } + output_ptr += copy_size; + } + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONCATENATION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/conv.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/conv.h new file mode 100644 index 0000000..d4bf46a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/conv.h @@ -0,0 +1,262 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONV_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONV_H_ + +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/internal/common.h" + + + +namespace tflite { + +namespace reference_ops { + + +inline void Conv(const ConvParams& params, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& filter_shape, + const float* filter_data, const RuntimeShape& bias_shape, + const float* bias_data, const RuntimeShape& output_shape, + float* output_data, const RuntimeShape& im2col_shape, + float* im2col_data) { + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const float output_activation_min = params.float_activation_min; + const float output_activation_max = params.float_activation_max; + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + (void)im2col_data; // only used in optimized code. + (void)im2col_shape; // only used in optimized code. + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (bias_data) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int out_channel = 0; out_channel < output_depth; ++out_channel) { + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + float total = 0.f; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // If the location is outside the bounds of the input image, + // use zero as a default value. + if ((in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height)) { + float input_value = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + float filter_value = + filter_data[Offset(filter_shape, out_channel, filter_y, + filter_x, in_channel)]; + total += (input_value * filter_value); + } + } + } + } + float bias_value = 0.0f; + if (bias_data) { + bias_value = bias_data[out_channel]; + } + output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] = + ActivationFunctionWithMinMax(total + bias_value, + output_activation_min, + output_activation_max); + } + } + } + } +} + +inline void Conv(const ConvParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& filter_shape, + const uint8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + uint8_t* output_data, const RuntimeShape& im2col_shape, + uint8_t* im2col_data, void* cpu_backend_context) { + (void)cpu_backend_context; // only used in optimized code. + (void)im2col_data; // only used in optimized code. + (void)im2col_shape; // only used in optimized code. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int32_t input_offset = params.input_offset; + const int32_t filter_offset = params.weights_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (bias_data) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int out_channel = 0; out_channel < output_depth; ++out_channel) { + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // If the location is outside the bounds of the input image, + // use zero as a default value. + if ((in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height)) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = + filter_data[Offset(filter_shape, out_channel, filter_y, + filter_x, in_channel)]; + acc += + (filter_val + filter_offset) * (input_val + input_offset); + } + } + } + } + if (bias_data) { + acc += bias_data[out_channel]; + } + acc = MultiplyByQuantizedMultiplier(acc, output_multiplier, + output_shift); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] = + static_cast(acc); + } + } + } + } +} + +inline void HybridConvPerChannel( + const ConvParams& params, float* scaling_factors_ptr, + const RuntimeShape& input_shape, const int8_t* input_data, + const RuntimeShape& filter_shape, const int8_t* filter_data, + const RuntimeShape& bias_shape, const float* bias_data, + const RuntimeShape& output_shape, float* output_data, + const RuntimeShape& im2col_shape, int8_t* im2col_data, + const float* per_channel_scale, int32_t* input_offset) { + (void)im2col_data; // only used in optimized code. + (void)im2col_shape; // only used in optimized code. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const float output_activation_min = params.float_activation_min; + const float output_activation_max = params.float_activation_max; + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (bias_data) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int out_channel = 0; out_channel < output_depth; ++out_channel) { + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // If the location is outside the bounds of the input image, + // use zero as a default value. + if ((in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height)) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = + filter_data[Offset(filter_shape, out_channel, filter_y, + filter_x, in_channel)]; + acc += filter_val * (input_val - input_offset[batch]); + } + } + } + } + float acc_float = + acc * per_channel_scale[out_channel] * scaling_factors_ptr[batch]; + if (bias_data) { + acc_float += bias_data[out_channel]; + } + output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] = + ActivationFunctionWithMinMax(acc_float, output_activation_min, + output_activation_max); + } + } + } + } +} + +} // namespace reference_ops +} // namespace tflite + + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h new file mode 100644 index 0000000..0cecb16 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h @@ -0,0 +1,100 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_FLOAT_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_FLOAT_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +inline void DepthwiseConv( + const DepthwiseParams& params, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& filter_shape, + const float* filter_data, const RuntimeShape& bias_shape, + const float* bias_data, const RuntimeShape& output_shape, + float* output_data) { + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const float output_activation_min = params.float_activation_min; + const float output_activation_max = params.float_activation_max; + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + + for (int b = 0; b < batches; ++b) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int ic = 0; ic < input_depth; ++ic) { + for (int m = 0; m < depth_multiplier; m++) { + const int oc = m + ic * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + float total = 0.f; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // If the location is outside the bounds of the input image, + // use zero as a default value. + if ((in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height)) { + float input_value = + input_data[Offset(input_shape, b, in_y, in_x, ic)]; + float filter_value = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, oc)]; + total += (input_value * filter_value); + } + } + } + float bias_value = 0.0f; + if (bias_data) { + bias_value = bias_data[oc]; + } + output_data[Offset(output_shape, b, out_y, out_x, oc)] = + ActivationFunctionWithMinMax(total + bias_value, + output_activation_min, + output_activation_max); + } + } + } + } + } +} + +} // end namespace reference_ops +} // end namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_FLOAT_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h new file mode 100644 index 0000000..20bf83d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h @@ -0,0 +1,297 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_UINT8_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_UINT8_H_ + +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +// Used in tests and template parameters to control which version of depthwise +// convolution is called. Primarily for reference code, and specializations +// forced in tests. +enum class DepthwiseConvImplementation { + // Run all tests against kUseStandardEntry even if also testing another + // kernel, since we need to be sure that the main DepthwiseConv() function in + // optimized_ops.h dispatches to a correctly-executing kernel. + kNone = 0, // The "default" option: use the normal + // DepthwiseConv kernel (entry) function. + kUseGenericKernel, // Forced use of generic kernel. + kUseNeon3x3, // 3x3 kernel that uses NEON when available. + kUseNeon3x3DotProduct, // 3x3 kernel that uses dot-product enabled NEON + // when available. + kUseCModel3x3DotProduct, // 3x3 kernel, reference C model that is intended + // to match overall design NEON code. + kUseUnwound3x3DotProduct, // 3x3 kernel, reference C model with unwound loops + // and some arrays. + kUseIntrinsics3x3DotProduct, // 3x3 kernel using NEON intrinsics. +}; + +// Category of depthwise convolution output rounding. +enum class DepthwiseConvOutputRounding { + kNone = 0, // Invalid: specific method must be specified. + kAwayFromZero, // Original method: exact halves rounded away from zero. + kUpward, // Halves towards +infinity: adds 0.5 before truncate. + // This is where a future kNearestEven would be placed. +}; + +// Category of depthwise convolution depth multiplication. +enum class DepthwiseConvDepthMultiplication { + kNoMultiplication = 0, // Depth multiplier = 1. + kUnitInputDepth, // Input depth = 1, output depth = depth multiplier. +}; + +namespace reference_ops { +namespace depthwise_conv { + +template +inline int32_t DepthwiseConvRound(int32_t x, int32_t quantized_multiplier, + int shift) { + TFLITE_DCHECK_NE(output_rounding, DepthwiseConvOutputRounding::kNone); + return MultiplyByQuantizedMultiplier(x, quantized_multiplier, shift); +} + +template <> +inline int32_t DepthwiseConvRound( + int32_t x, int32_t quantized_multiplier, int shift) { + return MultiplyByQuantizedMultiplier(x, quantized_multiplier, shift); +} + +template <> +inline int32_t DepthwiseConvRound( + int32_t x, int32_t quantized_multiplier, int shift) { + using gemmlowp::SaturatingRoundingDoublingHighMul; + const int left_shift = shift > 0 ? shift : 0; + const int right_shift = shift > 0 ? 0 : -shift; + const int rounding_offset = right_shift > 0 ? 1 << (right_shift - 1) : 0; + return (SaturatingRoundingDoublingHighMul(x * (1 << left_shift), + quantized_multiplier) + + rounding_offset) >> + right_shift; +} + +template +struct DepthwiseConvBasicKernel { + static inline void Run( + const DepthwiseParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& filter_shape, + const uint8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + uint8_t* output_data) { + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + const int32_t input_offset = params.input_offset; + const int32_t filter_offset = params.weights_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + + for (int b = 0; b < batches; ++b) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int ic = 0; ic < input_depth; ++ic) { + for (int m = 0; m < depth_multiplier; m++) { + const int oc = m + ic * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = + in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // If the location is outside the bounds of the input image, + // use zero as a default value. + if ((in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height)) { + int32_t input_val = + input_data[Offset(input_shape, b, in_y, in_x, ic)]; + int32_t filter_val = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, oc)]; + acc += (filter_val + filter_offset) * + (input_val + input_offset); + } + } + } + if (bias_data) { + acc += bias_data[oc]; + } + acc = DepthwiseConvRound(acc, output_multiplier, + output_shift); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[Offset(output_shape, b, out_y, out_x, oc)] = + static_cast(acc); + } + } + } + } + } + } + + // TODO(b/148596273): Reconcile reference versions, perhaps with common + // MultiplyByQuantizedMultiplier or DepthwiseConvRound function. + static inline void RunPerChannel( + const DepthwiseParams& params, const RuntimeShape& input_shape, + const int8_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int8_t* output_data) { + // Get parameters. + // TODO(b/141565753): Re-introduce ScopedProfilingLabel on Micro. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const int32_t input_offset = params.input_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + const int32_t* output_multiplier = params.output_multiplier_per_channel; + const int32_t* output_shift = params.output_shift_per_channel; + + // Check dimensions of the tensors. + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + for (int m = 0; m < depth_multiplier; ++m) { + const int output_channel = m + in_channel * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = + in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, output_channel)]; + // Accumulate with 32 bits accumulator. + // In the nudging process during model quantization, we + // force real value of 0.0 be represented by a quantized + // value. This guarantees that the input_offset is a int8_t, + // even though it is represented using int32_t. int32_t += + // int8_t + // * (int8_t - int8_t) so the highest value we can get from + // each accumulation is [-127, 127] * ([-128, 127] - + // [-128, 127]), which is [-32512, 32512]. log2(32512) + // = 14.98, which means we can accumulate at least 2^16 + // multiplications without overflow. The accumulator is + // applied to a filter so the accumulation logic will hold + // as long as the filter size (filter_y * filter_x * + // in_channel) does not exceed 2^16, which is the case in + // all the models we have seen so far. + acc += filter_val * (input_val + input_offset); + } + } + } + if (bias_data) { + acc += bias_data[output_channel]; + } + acc = DepthwiseConvRound( + acc, output_multiplier[output_channel], + output_shift[output_channel]); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, + output_channel)] = static_cast(acc); + } + } + } + } + } + } +}; + +} // namespace depthwise_conv + +inline void DepthwiseConv( + const DepthwiseParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& filter_shape, + const uint8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + uint8_t* output_data) { + return depthwise_conv::DepthwiseConvBasicKernel< + DepthwiseConvOutputRounding::kAwayFromZero>::Run(params, input_shape, + input_data, filter_shape, + filter_data, bias_shape, + bias_data, output_shape, + output_data); +} + +} // namespace reference_ops +} // end namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEPTHWISECONV_UINT8_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/dequantize.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/dequantize.h new file mode 100644 index 0000000..b90951f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/dequantize.h @@ -0,0 +1,78 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEQUANTIZE_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEQUANTIZE_H_ + +#include + +#include + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// Dequantizes into a float without rounding. +template +inline void Dequantize(const tflite::DequantizationParams& op_params, + const RuntimeShape& input_shape, + const InputT* input_data, + const RuntimeShape& output_shape, OutputT* output_data) { + int32_t zero_point = op_params.zero_point; + const double scale = op_params.scale; + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + const int32_t val = input_data[i]; + const OutputT result = static_cast(scale * (val - zero_point)); + output_data[i] = result; + } +} + +// Dequantizes per-channel quantized tensor to float. +template +inline void PerChannelDequantize( + const tflite::PerChannelDequantizationParams& op_params, + const RuntimeShape& input_shape, const T* input_data, + const RuntimeShape& output_shape, float* output_data) { + // Ensure flat size is same. + MatchingFlatSize(input_shape, output_shape); + + const int32_t* zero_point = op_params.zero_point; + const float* scale = op_params.scale; + const int32_t quantized_dimension = op_params.quantized_dimension; + const int32_t num_dims = input_shape.DimensionsCount(); + const int32_t* dims_data = input_shape.DimsData(); + std::vector current_dim(num_dims, 0); + + do { + size_t offset = + ReducedOutputOffset(num_dims, reinterpret_cast(dims_data), + current_dim.data(), 0, nullptr); + const int channel = current_dim[quantized_dimension]; + const int32_t val = input_data[offset]; + const float result = + static_cast(scale[channel] * (val - zero_point[channel])); + output_data[offset] = result; + } while (NextIndex(num_dims, reinterpret_cast(dims_data), + current_dim.data())); +} + +} // namespace reference_ops + +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_DEQUANTIZE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/floor.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/floor.h new file mode 100644 index 0000000..0693fd4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/floor.h @@ -0,0 +1,39 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FLOOR_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FLOOR_H_ + +#include + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline void Floor(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + int offset = i; + output_data[offset] = std::floor(input_data[offset]); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FLOOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/fully_connected.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/fully_connected.h new file mode 100644 index 0000000..39a9cd0 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/fully_connected.h @@ -0,0 +1,320 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FULLY_CONNECTED_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FULLY_CONNECTED_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +inline void FullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& weights_shape, + const float* weights_data, const RuntimeShape& bias_shape, + const float* bias_data, const RuntimeShape& output_shape, + float* output_data) { + const float output_activation_min = params.float_activation_min; + const float output_activation_max = params.float_activation_max; + // TODO(benoitjacob): This really should be: + // const int batches = ArraySize(output_dims, 1); + // but the current --variable_batch hack consists in overwriting the 3rd + // dimension with the runtime batch size, as we don't keep track for each + // array of which dimension is the batch dimension in it. + const int output_dims_count = output_shape.DimensionsCount(); + const int weights_dims_count = weights_shape.DimensionsCount(); + const int batches = FlatSizeSkipDim(output_shape, output_dims_count - 1); + const int output_depth = MatchingDim(weights_shape, weights_dims_count - 2, + output_shape, output_dims_count - 1); + const int accum_depth = weights_shape.Dims(weights_dims_count - 1); + for (int b = 0; b < batches; ++b) { + for (int out_c = 0; out_c < output_depth; ++out_c) { + float total = 0.f; + for (int d = 0; d < accum_depth; ++d) { + total += input_data[b * accum_depth + d] * + weights_data[out_c * accum_depth + d]; + } + float bias_value = 0.0f; + if (bias_data) { + bias_value = bias_data[out_c]; + } + output_data[out_c + output_depth * b] = ActivationFunctionWithMinMax( + total + bias_value, output_activation_min, output_activation_max); + } + } +} + +inline void FullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& filter_shape, + const uint8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + uint8_t* output_data) { + const int32_t input_offset = params.input_offset; + const int32_t filter_offset = params.weights_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_GE(filter_shape.DimensionsCount(), 2); + TFLITE_DCHECK_GE(output_shape.DimensionsCount(), 1); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + // TODO(benoitjacob): This really should be: + // const int batches = ArraySize(output_dims, 1); + // but the current --variable_batch hack consists in overwriting the 3rd + // dimension with the runtime batch size, as we don't keep track for each + // array of which dimension is the batch dimension in it. + const int output_dim_count = output_shape.DimensionsCount(); + const int filter_dim_count = filter_shape.DimensionsCount(); + const int batches = FlatSizeSkipDim(output_shape, output_dim_count - 1); + const int output_depth = MatchingDim(filter_shape, filter_dim_count - 2, + output_shape, output_dim_count - 1); + const int accum_depth = filter_shape.Dims(filter_dim_count - 1); + for (int b = 0; b < batches; ++b) { + for (int out_c = 0; out_c < output_depth; ++out_c) { + int32_t acc = 0; + for (int d = 0; d < accum_depth; ++d) { + int32_t input_val = input_data[b * accum_depth + d]; + int32_t filter_val = filter_data[out_c * accum_depth + d]; + acc += (filter_val + filter_offset) * (input_val + input_offset); + } + if (bias_data) { + acc += bias_data[out_c]; + } + acc = MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[out_c + output_depth * b] = static_cast(acc); + } + } +} + +inline void FullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& filter_shape, + const uint8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int16_t* output_data) { + const int32_t input_offset = params.input_offset; + const int32_t filter_offset = params.weights_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + TFLITE_DCHECK_EQ(output_offset, 0); + // TODO(benoitjacob): This really should be: + // const int batches = ArraySize(output_dims, 1); + // but the current --variable_batch hack consists in overwriting the 3rd + // dimension with the runtime batch size, as we don't keep track for each + // array of which dimension is the batch dimension in it. + const int output_dim_count = output_shape.DimensionsCount(); + const int filter_dim_count = filter_shape.DimensionsCount(); + const int batches = FlatSizeSkipDim(output_shape, output_dim_count - 1); + const int output_depth = MatchingDim(filter_shape, filter_dim_count - 2, + output_shape, output_dim_count - 1); + const int accum_depth = filter_shape.Dims(filter_dim_count - 1); + for (int b = 0; b < batches; ++b) { + for (int out_c = 0; out_c < output_depth; ++out_c) { + // Internal accumulation. + // Initialize accumulator with the bias-value. + int32_t accum = bias_data[out_c]; + // Accumulation loop. + for (int d = 0; d < accum_depth; ++d) { + int16_t input_val = input_data[b * accum_depth + d] + input_offset; + int16_t filter_val = + filter_data[out_c * accum_depth + d] + filter_offset; + accum += filter_val * input_val; + } + // Down-scale the final int32_t accumulator to the scale used by our + // (16-bit, typically 3 integer bits) fixed-point format. The quantized + // multiplier and shift here have been pre-computed offline + // (e.g. by toco). + accum = + MultiplyByQuantizedMultiplier(accum, output_multiplier, output_shift); + // Saturate, cast to int16_t, and store to output array. + accum = std::max(accum, output_activation_min - output_offset); + accum = std::min(accum, output_activation_max - output_offset); + accum += output_offset; + output_data[out_c + output_depth * b] = accum; + } + } +} + +inline void ShuffledFullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& weights_shape, + const uint8_t* shuffled_weights_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int16_t* output_data, uint8_t* shuffled_input_workspace_data) { + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + + TFLITE_DCHECK_GE(input_shape.DimensionsCount(), 1); + TFLITE_DCHECK_GE(weights_shape.DimensionsCount(), 2); + TFLITE_DCHECK_GE(output_shape.DimensionsCount(), 1); + // TODO(benoitjacob): This really should be: + // const int batches = ArraySize(output_dims, 1); + // but the current --variable_batch hack consists in overwriting the 3rd + // dimension with the runtime batch size, as we don't keep track for each + // array of which dimension is the batch dimension in it. + const int output_dim_count = output_shape.DimensionsCount(); + const int weights_dim_count = weights_shape.DimensionsCount(); + const int batches = FlatSizeSkipDim(output_shape, output_dim_count - 1); + const int output_depth = MatchingDim(weights_shape, weights_dim_count - 2, + output_shape, output_dim_count - 1); + const int accum_depth = weights_shape.Dims(weights_dim_count - 1); + TFLITE_DCHECK((accum_depth % 16) == 0); + TFLITE_DCHECK((output_depth % 4) == 0); + + // Shuffling and xoring of input activations into the workspace buffer + uint8_t* shuffled_input_workspace_ptr = shuffled_input_workspace_data; + if (batches == 1) { + for (int i = 0; i < accum_depth; i++) { + shuffled_input_workspace_data[i] = input_data[i] ^ 0x80; + } + } else if (batches == 4) { + for (int c = 0; c < accum_depth; c += 16) { + for (int b = 0; b < 4; b++) { + const uint8_t* src_data_ptr = input_data + b * accum_depth + c; + for (int j = 0; j < 16; j++) { + uint8_t src_val = *src_data_ptr++; + // Flip the sign bit, so that the kernel will only need to + // reinterpret these uint8_t values as int8_t, getting for free the + // subtraction of the zero_point value 128. + uint8_t dst_val = src_val ^ 0x80; + *shuffled_input_workspace_ptr++ = dst_val; + } + } + } + } else { + TFLITE_DCHECK(false); + return; + } + + // Actual computation + if (batches == 1) { + int16_t* output_ptr = output_data; + // Shuffled weights have had their sign bit (0x80) pre-flipped (xor'd) + // so that just reinterpreting them as int8_t values is equivalent to + // subtracting 128 from them, thus implementing for free the subtraction of + // the zero_point value 128. + const int8_t* shuffled_weights_ptr = + reinterpret_cast(shuffled_weights_data); + // Likewise, we preshuffled and pre-xored the input data above. + const int8_t* shuffled_input_data = + reinterpret_cast(shuffled_input_workspace_data); + for (int c = 0; c < output_depth; c += 4) { + // Internal accumulation. + // Initialize accumulator with the bias-value. + int32_t accum[4] = {0}; + // Accumulation loop. + for (int d = 0; d < accum_depth; d += 16) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 16; j++) { + int8_t input_val = shuffled_input_data[d + j]; + int8_t weights_val = *shuffled_weights_ptr++; + accum[i] += weights_val * input_val; + } + } + } + for (int i = 0; i < 4; i++) { + // Add bias value + int32_t acc = accum[i] + bias_data[c + i]; + // Down-scale the final int32_t accumulator to the scale used by our + // (16-bit, typically 3 integer bits) fixed-point format. The quantized + // multiplier and shift here have been pre-computed offline + // (e.g. by toco). + acc = + MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift); + // Saturate, cast to int16_t, and store to output array. + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_ptr[c + i] = acc; + } + } + } else if (batches == 4) { + int16_t* output_ptr = output_data; + // Shuffled weights have had their sign bit (0x80) pre-flipped (xor'd) + // so that just reinterpreting them as int8_t values is equivalent to + // subtracting 128 from them, thus implementing for free the subtraction of + // the zero_point value 128. + const int8_t* shuffled_weights_ptr = + reinterpret_cast(shuffled_weights_data); + // Likewise, we preshuffled and pre-xored the input data above. + const int8_t* shuffled_input_data = + reinterpret_cast(shuffled_input_workspace_data); + for (int c = 0; c < output_depth; c += 4) { + const int8_t* shuffled_input_ptr = shuffled_input_data; + // Accumulation loop. + // Internal accumulation. + // Initialize accumulator with the bias-value. + int32_t accum[4][4]; + for (int i = 0; i < 4; i++) { + for (int b = 0; b < 4; b++) { + accum[i][b] = 0; + } + } + for (int d = 0; d < accum_depth; d += 16) { + for (int i = 0; i < 4; i++) { + for (int b = 0; b < 4; b++) { + for (int j = 0; j < 16; j++) { + int8_t input_val = shuffled_input_ptr[16 * b + j]; + int8_t weights_val = shuffled_weights_ptr[16 * i + j]; + accum[i][b] += weights_val * input_val; + } + } + } + shuffled_input_ptr += 64; + shuffled_weights_ptr += 64; + } + for (int i = 0; i < 4; i++) { + for (int b = 0; b < 4; b++) { + // Add bias value + int32_t acc = accum[i][b] + bias_data[c + i]; + // Down-scale the final int32_t accumulator to the scale used by our + // (16-bit, typically 3 integer bits) fixed-point format. The + // quantized multiplier and shift here have been pre-computed offline + // (e.g. by toco). + acc = MultiplyByQuantizedMultiplier(acc, output_multiplier, + output_shift); + // Saturate, cast to int16_t, and store to output array. + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_ptr[b * output_depth + c + i] = acc; + } + } + } + } else { + TFLITE_DCHECK(false); + return; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_FULLY_CONNECTED_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/hard_swish.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/hard_swish.h new file mode 100644 index 0000000..cda1b5c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/hard_swish.h @@ -0,0 +1,166 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ACTIVATIONS_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ACTIVATIONS_H_ + +#include "ruy/profiler/instrumentation.h" // from @ruy +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +inline int16_t SaturatingLeftShift(int16_t value, int amount) { + int32_t result = static_cast(value) * (1 << amount); + result = std::min(result, std::numeric_limits::max()); + result = std::max(result, std::numeric_limits::min()); + return result; +} + +// Similar to ARM instruction SQDMULH. +// Similar to gemmlowp::SaturatingRoundingDoublingHighMul except +// rounding to zero instead of to nearest (SQRDMULH). +inline std::int16_t SaturatingDoublingHighMul(std::int16_t a, std::int16_t b) { + bool overflow = a == b && a == std::numeric_limits::min(); + std::int32_t a_32(a); + std::int32_t b_32(b); + std::int32_t ab_32 = a_32 * b_32; + std::int16_t ab_x2_high16 = static_cast((ab_32) / (1 << 15)); + return overflow ? std::numeric_limits::max() : ab_x2_high16; +} + +template +inline void HardSwish(const RuntimeShape& input_shape, const T* input_data, + const RuntimeShape& output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("ReferenceHardSwish/Float"); + auto matching_size = MatchingFlatSize(input_shape, output_shape); + const T* in_end = input_data + matching_size; + for (; input_data < in_end; input_data++, output_data++) { + const float in = *input_data; + *output_data = + in * std::min(static_cast(6), std::max(static_cast(0), in + 3)) / + 6; + } +} + +template +inline void HardSwish(const HardSwishParams& params, + const RuntimeShape& input_shape, const T* input_data, + const RuntimeShape& output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("ReferenceHardSwish/Quantized"); + + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + const int16_t input_value = input_data[i] - params.input_zero_point; + // Left-shift as much as we can without overflow/saturation to put + // significant bits in the high bits of our 16-bit fixedpoint values, so + // that fixed-point approximate computations below are as accurate as + // possible. + const int16_t input_value_on_hires_input_scale = input_value * (1 << 7); + // Compute the input value on essentially the output scale, just not + // right-shifted yet. This is the value that we'll use in the (x >= +3) + // case, and that in the general case we'll multiply against the "relu-ish" + // fixed-point multiplier in [0, 1]. + const int16_t input_value_on_preshift_output_scale = + gemmlowp::SaturatingRoundingDoublingHighMul( + input_value_on_hires_input_scale, + params.output_multiplier_fixedpoint_int16); + // Now compute the "relu-ish multiplier". In the (-3 <= x <= +3) case, that + // is just an affine rescaling of x from [-3, 3] to [0, 1]. In the general + // case, it is just that plus saturation at the boundaries of [-3, 3]. + // First, we rescale from [-3, 3] to [-1, 1], saturating. + // That is done by rescaling the input value with a fixed-point multiplier + // (reluish_multiplier_fixedpoint) and bit-shift such that we represent + // that input value on the scale where the real value 3.0f is represented + // by the quantized value 32768. (+32768 is actually not representable as + // int16_t, so this saturates at +32767, and that is seen empirically to be + // a negligible contribution to numerical error/bias). + // + // This code is careful to correctly implement any magnitude of multiplier, + // involving either a right shift or a left shift, with correct saturation + // behavior in the left-shift case. This forces this code to be more + // complicated, but is necessary for real applications: a partially + // trained quantized MobileNet v3-small model that motivated this code + // exhibits some large [min, max] range boundaries, of the order of + // magnitude of 10 or 100 depending on layers. + // + // The next few lines are basically just an ordinary + // MultiplyByQuantizedMultiplier, except that we are more careful here + // about the fine details of saturation when left-shifting, because here + // overflow in left-shift is a common case, not an anomaly as + // MultiplyByQuantizedMultiplier assumes. + int16_t reluish_value = input_value_on_hires_input_scale; + // Shift left, saturating, as much as we can while ensuring that this + // saturation will not contribute to the result. That is, left shift amount + // reduced by 1. + if (params.reluish_multiplier_exponent > 0) { + reluish_value = SaturatingLeftShift( + reluish_value, params.reluish_multiplier_exponent - 1); + } + // Apply the fixed-point multiplier, dividing the value by a divisor + // ranging in [1, 2]. + reluish_value = gemmlowp::SaturatingRoundingDoublingHighMul( + reluish_value, params.reluish_multiplier_fixedpoint_int16); + // Apply the last bit of left-shift. Thus, in the left-shifting case, if + // any saturation affects the result, it is happening here --- any + // saturation having occurred above is overwritten here, not affecting the + // result. + if (params.reluish_multiplier_exponent > 0) { + reluish_value = SaturatingLeftShift(reluish_value, 1); + } + // Shift right, in the right-shifting case. + if (params.reluish_multiplier_exponent < 0) { + reluish_value = gemmlowp::RoundingDivideByPOT( + reluish_value, -params.reluish_multiplier_exponent); + } + // At this point we have rescaled the value into a 16bit fixedpoint + // reluish_value in [-1, 1]. + // We now convert that to a 16bit fixedpoint value in [0, 1]. + reluish_value = (reluish_value + (1 << 15)) >> 1; + // Use of SaturatingDoublingHighMul here is important to cancel the biases + // from the above SaturatingRoundingDoublingHighMul. + // + // On a partially trained MobileNet-v3-small, + // + // | bias on | ImageNet + // | quantized | Top-1 + // Operation used here | values | accuracy (50k) + // --------------------------------------+------------+----------- + // SaturatingDoublingHighMul | -0.0024 | 58.920 + // SaturatingRoundingDoublingHighMul | -0.0067 | 58.064 + // + // In activations_test, this is covered by this testcase: + // QuantizedActivationsOpTest.HardSwishBias + // + const int16_t preshift_output_value = SaturatingDoublingHighMul( + reluish_value, input_value_on_preshift_output_scale); + // We were so far operating on the pre-shift output scale. Now we finally + // apply that output shift, arriving at the final output scale. + int16_t output_value = gemmlowp::RoundingDivideByPOT( + preshift_output_value, -params.output_multiplier_exponent); + output_value += params.output_zero_point; + output_value = + std::min(output_value, std::numeric_limits::max()); + output_value = + std::max(output_value, std::numeric_limits::min()); + output_data[i] = output_value; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/add.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/add.h new file mode 100644 index 0000000..2af6f37 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/add.h @@ -0,0 +1,145 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_ADD_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_ADD_H_ + +#include + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void CheckArithmeticParams(const ArithmeticParams& params) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + // Input offset is negative input zero point. Activation tensors are + // asymmetric quantized so they span the full int8 range. + TFLITE_DCHECK_GE(-params.input1_offset, std::numeric_limits::min()); + TFLITE_DCHECK_GE(-params.input2_offset, std::numeric_limits::min()); + TFLITE_DCHECK_LE(-params.input1_offset, std::numeric_limits::max()); + TFLITE_DCHECK_LE(-params.input2_offset, std::numeric_limits::max()); +} + +// Element-wise add that can often be used for inner loop of broadcast add as +// well as the non-broadcast add. +inline void AddElementwise(int size, const ArithmeticParams& params, + const int8_t* input1_data, const int8_t* input2_data, + int8_t* output_data) { + CheckArithmeticParams(params); + + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sum = scaled_input1_val + scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sum, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[i] = static_cast(clamped_output); + } +} + +inline void Add(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const int8_t* input1_data, + const RuntimeShape& input2_shape, const int8_t* input2_data, + const RuntimeShape& output_shape, int8_t* output_data) { + CheckArithmeticParams(params); + + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + AddElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +inline void BroadcastAdd4DSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int8_t* input1_data, + const RuntimeShape& input2_shape, + const int8_t* input2_data, + const RuntimeShape& output_shape, + int8_t* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + const int32_t input1_val = + params.input1_offset + + input1_data[SubscriptToIndex(desc1, b, y, x, c)]; + const int32_t input2_val = + params.input2_offset + + input2_data[SubscriptToIndex(desc2, b, y, x, c)]; + const int32_t shifted_input1_val = + input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = + input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, + params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, + params.input2_shift); + const int32_t raw_sum = scaled_input1_val + scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sum, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[Offset(extended_output_shape, b, y, x, c)] = + static_cast(clamped_output); + } + } + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_ADD_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/conv.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/conv.h new file mode 100644 index 0000000..f4bcb2b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/conv.h @@ -0,0 +1,217 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_CONV_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_CONV_H_ + +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +// Fixed-point per-channel-quantization convolution reference kernel. +inline void ConvPerChannel( + const ConvParams& params, const int32_t* output_multiplier, + const int32_t* output_shift, const RuntimeShape& input_shape, + const int8_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int8_t* output_data) { + // Get parameters. + const int32_t input_offset = params.input_offset; // r = s(q - Z) + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int32_t output_offset = params.output_offset; + + // Set min and max value of the output. + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + + // Consistency check. + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (bias_data) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + + // Check dimensions of the tensors. + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int out_channel = 0; out_channel < output_depth; ++out_channel) { + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = + filter_data[Offset(filter_shape, out_channel, filter_y, + filter_x, in_channel)]; + // Accumulate with 32 bits accumulator. + // In the nudging process during model quantization, we force + // real value of 0.0 be represented by a quantized value. This + // guarantees that the input_offset is a int8_t, even though + // it is represented using int32_t. int32_t += int8_t * + // (int8_t - int8_t) so the highest value we can get from each + // accumulation is [-127, 127] * ([-128, 127] - + // [-128, 127]), which is [-32512, 32512]. log2(32512) + // = 14.98, which means we can accumulate at least 2^16 + // multiplications without overflow. The accumulator is + // applied to a filter so the accumulation logic will hold as + // long as the filter size (filter_y * filter_x * in_channel) + // does not exceed 2^16, which is the case in all the models + // we have seen so far. + // TODO(jianlijianli): Add a check to make sure the + // accumulator depth is smaller than 2^16. + acc += filter_val * (input_val + input_offset); + } + } + } + } + + if (bias_data) { + acc += bias_data[out_channel]; + } + acc = MultiplyByQuantizedMultiplier( + acc, output_multiplier[out_channel], output_shift[out_channel]); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] = + static_cast(acc); + } + } + } + } +} + +// Fixed-point per-channel-quantization convolution reference kernel. +// 16-bit data and 8-bit filter +inline void ConvPerChannel( + const ConvParams& params, const int32_t* output_multiplier, + const int32_t* output_shift, const RuntimeShape& input_shape, + const int16_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const std::int64_t* bias_data, const RuntimeShape& output_shape, + int16_t* output_data) { + // Get parameters. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + + // Set min and max value of the output. + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + + // Consistency check. + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (bias_data) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + + // Check dimensions of the tensors. + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int out_channel = 0; out_channel < output_depth; ++out_channel) { + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + std::int64_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = + filter_data[Offset(filter_shape, out_channel, filter_y, + filter_x, in_channel)]; + // Accumulate with 64 bits accumulator. + // int64_t += int8_t * int16_t so the highest value we can + // get from each accumulation is [-127, 127] * ([-32768, + // 32767] - + // [-32768, 32767]), which is [-8322945, 8322945]. + // log2(8322945) = 22.99. + acc += filter_val * input_val; + } + } + } + } + if (bias_data) { + acc += bias_data[out_channel]; + } + int32_t scaled_acc = MultiplyByQuantizedMultiplier( + acc, output_multiplier[out_channel], output_shift[out_channel]); + scaled_acc = std::max(scaled_acc, output_activation_min); + scaled_acc = std::min(scaled_acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, out_channel)] = + static_cast(scaled_acc); + } + } + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h new file mode 100644 index 0000000..6f54e47 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h @@ -0,0 +1,289 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_DEPTHWISE_CONV_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_DEPTHWISE_CONV_H_ + +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { +inline void DepthwiseConvPerChannel( + const DepthwiseParams& params, const int32_t* output_multiplier, + const int32_t* output_shift, const RuntimeShape& input_shape, + const int8_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int8_t* output_data) { + // Get parameters. + // TODO(b/141565753): Re-introduce ScopedProfilingLabel on Micro. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const int32_t input_offset = params.input_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + + // Check dimensions of the tensors. + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + for (int m = 0; m < depth_multiplier; ++m) { + const int output_channel = m + in_channel * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, output_channel)]; + // Accumulate with 32 bits accumulator. + // In the nudging process during model quantization, we force + // real value of 0.0 be represented by a quantized value. This + // guarantees that the input_offset is a int8_t, even though + // it is represented using int32_t. int32_t += int8_t * + // (int8_t - int8_t) so the highest value we can get from each + // accumulation is [-127, 127] * ([-128, 127] - + // [-128, 127]), which is [-32512, 32512]. log2(32512) + // = 14.98, which means we can accumulate at least 2^16 + // multiplications without overflow. The accumulator is + // applied to a filter so the accumulation logic will hold as + // long as the filter size (filter_y * filter_x * in_channel) + // does not exceed 2^16, which is the case in all the models + // we have seen so far. + // TODO(jianlijianli): Add a check to make sure the + // accumulator depth is smaller than 2^16. + acc += filter_val * (input_val + input_offset); + } + } + } + if (bias_data) { + acc += bias_data[output_channel]; + } + acc = MultiplyByQuantizedMultiplier( + acc, output_multiplier[output_channel], + output_shift[output_channel]); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, + output_channel)] = static_cast(acc); + } + } + } + } + } +} + +inline void DepthwiseConvPerChannel( + const DepthwiseParams& params, const int32_t* output_multiplier, + const int32_t* output_shift, const RuntimeShape& input_shape, + const int16_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const std::int64_t* bias_data, const RuntimeShape& output_shape, + int16_t* output_data) { + // Get parameters. + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + + // Check dimensions of the tensors. + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + for (int m = 0; m < depth_multiplier; ++m) { + const int output_channel = m + in_channel * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + std::int64_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, output_channel)]; + // Accumulate with 64 bits accumulator. + // We assume maximum of 2^16 accumulations as with the 8-bit + // case so actually the value in the accumulator should not + // exceed 40 bits + acc += static_cast(filter_val) * + static_cast(input_val); + } + } + } + if (bias_data) { + acc += bias_data[output_channel]; + } + int32_t scaled_acc = MultiplyByQuantizedMultiplier( + acc, output_multiplier[output_channel], + output_shift[output_channel]); + scaled_acc = std::max(scaled_acc, output_activation_min); + scaled_acc = std::min(scaled_acc, output_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, + output_channel)] = + static_cast(scaled_acc); + } + } + } + } + } +} + +inline void DepthwiseConvHybridPerChannel( + const DepthwiseParams& params, float* scaling_factors_ptr, + const RuntimeShape& input_shape, const int8_t* input_data, + const RuntimeShape& filter_shape, const int8_t* filter_data, + const RuntimeShape& bias_shape, const float* bias_data, + const RuntimeShape& output_shape, float* output_data, + const float* per_channel_scale, int32_t* input_offset) { + const int stride_width = params.stride_width; + const int stride_height = params.stride_height; + const int dilation_width_factor = params.dilation_width_factor; + const int dilation_height_factor = params.dilation_height_factor; + const int pad_width = params.padding_values.width; + const int pad_height = params.padding_values.height; + const int depth_multiplier = params.depth_multiplier; + const float output_activation_min = params.float_activation_min; + const float output_activation_max = params.float_activation_max; + // Check dimensions of the tensors. + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int bias_depth = bias_shape.FlatSize(); + TFLITE_DCHECK_EQ(output_depth, input_depth * depth_multiplier); + TFLITE_DCHECK_EQ(bias_depth, output_depth); + + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int in_channel = 0; in_channel < input_depth; ++in_channel) { + for (int m = 0; m < depth_multiplier; ++m) { + const int output_channel = m + in_channel * depth_multiplier; + const int in_x_origin = (out_x * stride_width) - pad_width; + const int in_y_origin = (out_y * stride_height) - pad_height; + int32_t acc = 0; + for (int filter_y = 0; filter_y < filter_height; ++filter_y) { + for (int filter_x = 0; filter_x < filter_width; ++filter_x) { + const int in_x = in_x_origin + dilation_width_factor * filter_x; + const int in_y = + in_y_origin + dilation_height_factor * filter_y; + // Zero padding by omitting the areas outside the image. + const bool is_point_inside_image = + (in_x >= 0) && (in_x < input_width) && (in_y >= 0) && + (in_y < input_height); + if (is_point_inside_image) { + int32_t input_val = input_data[Offset( + input_shape, batch, in_y, in_x, in_channel)]; + int32_t filter_val = filter_data[Offset( + filter_shape, 0, filter_y, filter_x, output_channel)]; + acc += filter_val * (input_val - input_offset[batch]); + } + } + } + float acc_float = static_cast(acc); + acc_float *= + per_channel_scale[output_channel] * scaling_factors_ptr[batch]; + if (bias_data && output_channel < bias_depth) { + acc_float += bias_data[output_channel]; + } + output_data[Offset(output_shape, batch, out_y, out_x, + output_channel)] = + ActivationFunctionWithMinMax(acc_float, output_activation_min, + output_activation_max); + } + } + } + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_DEPTHWISE_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h new file mode 100644 index 0000000..2bc3e79 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h @@ -0,0 +1,108 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_ + +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void FullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const int8_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const int32_t* bias_data, const RuntimeShape& output_shape, + int8_t* output_data) { + const int32_t input_offset = params.input_offset; + const int32_t filter_offset = params.weights_offset; + const int32_t output_offset = params.output_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_GE(filter_shape.DimensionsCount(), 2); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 2); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int filter_dim_count = filter_shape.DimensionsCount(); + const int batches = output_shape.Dims(0); + const int output_depth = output_shape.Dims(1); + TFLITE_DCHECK_LE(output_depth, filter_shape.Dims(filter_dim_count - 2)); + const int accum_depth = filter_shape.Dims(filter_dim_count - 1); + for (int b = 0; b < batches; ++b) { + for (int out_c = 0; out_c < output_depth; ++out_c) { + int32_t acc = 0; + for (int d = 0; d < accum_depth; ++d) { + int32_t input_val = input_data[b * accum_depth + d]; + int32_t filter_val = filter_data[out_c * accum_depth + d]; + acc += (filter_val + filter_offset) * (input_val + input_offset); + } + if (bias_data) { + acc += bias_data[out_c]; + } + acc = MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift); + acc += output_offset; + acc = std::max(acc, output_activation_min); + acc = std::min(acc, output_activation_max); + output_data[out_c + output_depth * b] = static_cast(acc); + } + } +} + +inline void FullyConnected( + const FullyConnectedParams& params, const RuntimeShape& input_shape, + const int16_t* input_data, const RuntimeShape& filter_shape, + const int8_t* filter_data, const RuntimeShape& bias_shape, + const int64_t* bias_data, const RuntimeShape& output_shape, + int16_t* output_data) { + const int32_t filter_offset = params.weights_offset; + const int32_t output_multiplier = params.output_multiplier; + const int output_shift = params.output_shift; + const int32_t output_activation_min = params.quantized_activation_min; + const int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_GE(filter_shape.DimensionsCount(), 2); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 2); + + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + const int filter_dim_count = filter_shape.DimensionsCount(); + const int batches = output_shape.Dims(0); + const int output_depth = output_shape.Dims(1); + TFLITE_DCHECK_LE(output_depth, filter_shape.Dims(filter_dim_count - 2)); + const int accum_depth = filter_shape.Dims(filter_dim_count - 1); + for (int b = 0; b < batches; ++b) { + for (int out_c = 0; out_c < output_depth; ++out_c) { + int64_t acc = 0; + for (int d = 0; d < accum_depth; ++d) { + int32_t input_val = input_data[b * accum_depth + d]; + int32_t filter_val = filter_data[out_c * accum_depth + d]; + acc += (filter_val + filter_offset) * input_val; + } + if (bias_data) { + acc += bias_data[out_c]; + } + int32_t acc_scaled = + MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift); + acc_scaled = std::max(acc_scaled, output_activation_min); + acc_scaled = std::min(acc_scaled, output_activation_max); + output_data[out_c + output_depth * b] = static_cast(acc_scaled); + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_FULLY_CONNECTED_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h new file mode 100644 index 0000000..31f2de9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h @@ -0,0 +1,65 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_L2NORMALIZATION_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_L2NORMALIZATION_H_ + +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void L2Normalization(int32_t input_zero_point, int32_t outer_size, + int32_t depth, const int8_t* input_data, + int8_t* output_data) { + static constexpr int8_t kMinInt8 = std::numeric_limits::min(); + static constexpr int8_t kMaxInt8 = std::numeric_limits::max(); + // The output scale must be in sync with Prepare(). + // Output is in 1/128 scale so the actual output range is nudged from [-1, 1] + // to [-1, 127/128]. + static constexpr int32_t kOutputScale = 7; + for (int outer_index = 0; outer_index < outer_size; ++outer_index) { + // int32_t = (int8_t - int8_t) ^ 2. + // ([-128, 127] - [-128, 127]) ^ 2 = [0, (2^8 - 1)^2] so the accumulator is + // safe from overflowing in at least 2^16 steps. + int32_t acc = 0; + for (int inner_index = 0; inner_index < depth; ++inner_index) { + int32_t input = + input_data[depth * outer_index + inner_index] - input_zero_point; + acc += input * input; + } + int32_t inv_l2norm_multiplier; + int inv_l2norm_shift; + GetInvSqrtQuantizedMultiplierExp(acc, kReverseShift, &inv_l2norm_multiplier, + &inv_l2norm_shift); + + for (int inner_index = 0; inner_index < depth; ++inner_index) { + int32_t input = + input_data[depth * outer_index + inner_index] - input_zero_point; + + // Rescale and downcast. Rescale is folded into the division. + int32_t output_in_q24 = MultiplyByQuantizedMultiplier( + input, inv_l2norm_multiplier, inv_l2norm_shift + kOutputScale); + output_in_q24 = + std::min(static_cast(kMaxInt8), + std::max(static_cast(kMinInt8), output_in_q24)); + output_data[depth * outer_index + inner_index] = + static_cast(output_in_q24); + } + } +} +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_L2NORMALIZATION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h new file mode 100644 index 0000000..e315683 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h @@ -0,0 +1,99 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_LOGISTIC_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_LOGISTIC_H_ + +#include +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void Logistic(int32_t input_zero_point, int32_t input_range_radius, + int32_t input_multiplier, int32_t input_left_shift, + int32_t input_size, const int8_t* input_data, + int8_t* output_data) { + // Integer bits must be in sync with Prepare() function. + static constexpr int32_t kInputIntegerBits = 4; + static constexpr int32_t kOutputIntegerBits = 8; + static constexpr int8_t kMinInt8 = std::numeric_limits::min(); + static constexpr int8_t kMaxInt8 = std::numeric_limits::max(); + static constexpr int32_t kOutputZeroPoint = -128; + + for (int i = 0; i < input_size; ++i) { + const int32_t input = + static_cast(input_data[i]) - input_zero_point; + if (input <= -input_range_radius) { + output_data[i] = kMinInt8; + } else if (input >= input_range_radius) { + output_data[i] = kMaxInt8; + } else { + const int32_t input_in_q4 = MultiplyByQuantizedMultiplier( + input, input_multiplier, input_left_shift); + using FixedPoint4 = gemmlowp::FixedPoint; + const int32_t output_in_q0 = + gemmlowp::logistic(FixedPoint4::FromRaw(input_in_q4)).raw(); + + // Rescale and downcast. + using gemmlowp::RoundingDivideByPOT; + int32_t output_in_q23 = + RoundingDivideByPOT(output_in_q0, 31 - kOutputIntegerBits); + output_in_q23 = std::min(std::max(output_in_q23 + kOutputZeroPoint, + static_cast(kMinInt8)), + static_cast(kMaxInt8)); + output_data[i] = static_cast(output_in_q23); + } + } +} + +inline void Logistic(int32_t input_multiplier, int32_t input_size, + const int16_t* ptr_input_data, int16_t* ptr_output_data) { + // We use the LUT for sigmoid and take into account, that + // tanh(x) = 2*sigmoid(2*x) - 1 + + int32_t input_data_mul = (input_multiplier > 0) ? input_multiplier : 1; + + for (int i = 0; i < input_size; ++i, ptr_input_data++, ptr_output_data++) { + int32_t input_data = (*ptr_input_data) * input_data_mul; + + // Scale by 3/4 to expand range [-8,8]->[-10.7,10.7] and + // we do interpolation on unsigned values. + uint32_t abs_input_data = 3 * abs(input_data); + + // We divide by 2 power of 9, because + // we need to divide by 2 in power of 7 for + // the input conversion + 1/4 from the scale above. + uint8_t uh = abs_input_data >> 9; + uint32_t ua = sigmoid_table_uint16[uh]; + uint32_t ub = sigmoid_table_uint16[uh + 1]; + uint32_t ut = abs_input_data & 0x1ff; + + // Interpolation is done using the fractional bit. + uint32_t result = (ua << 9) + ut * (ub - ua); + + result = (input_data >= 0) ? (result + (1 << 9)) + : ((1 << (16 + 9)) - result + (1 << 9) - 1); + + // Back to 16-bit. + result >>= 10; + + *ptr_output_data = result; + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_LOGISTIC_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/mul.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/mul.h new file mode 100644 index 0000000..b80838a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/mul.h @@ -0,0 +1,131 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_MUL_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_MUL_H_ + +#include "fixedpoint/fixedpoint.h" +#include "ruy/profiler/instrumentation.h" // from @ruy +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +template +inline void MulElementwise(int size, const ArithmeticParams& params, + const T* input1_data, const T* input2_data, + T* output_data) { + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t unclamped_result = + params.output_offset + + MultiplyByQuantizedMultiplier(input1_val * input2_val, + params.output_multiplier, + params.output_shift); + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, unclamped_result)); + output_data[i] = static_cast(clamped_output); + } +} + +template +inline void Mul(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const T* input1_data, + const RuntimeShape& input2_shape, const T* input2_data, + const RuntimeShape& output_shape, T* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + ruy::profiler::ScopeLabel label("Mul/8bit"); + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + MulElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +// Mul with 16 bit inputs and int8_t outputs. +inline void Mul(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const int16_t* input1_data, + const RuntimeShape& input2_shape, const int16_t* input2_data, + const RuntimeShape& output_shape, int8_t* output_data) { + ruy::profiler::ScopeLabel label("Mul/Int16Int8"); + int32_t output_offset = params.output_offset; + int32_t output_activation_min = params.quantized_activation_min; + int32_t output_activation_max = params.quantized_activation_max; + TFLITE_DCHECK_LE(output_activation_min, output_activation_max); + + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + // F0 uses 0 integer bits, range [-1, 1]. + using F0 = gemmlowp::FixedPoint; + + F0 unclamped_result = + F0::FromRaw(input1_data[i]) * F0::FromRaw(input2_data[i]); + int16_t rescaled_result = + gemmlowp::RoundingDivideByPOT(unclamped_result.raw(), 8); + int16_t clamped_result = std::min( + output_activation_max - output_offset, rescaled_result); + clamped_result = std::max(output_activation_min - output_offset, + clamped_result); + output_data[i] = output_offset + clamped_result; + } +} + +template +inline void BroadcastMul4DSlow( + const ArithmeticParams& params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("BroadcastMul4DSlow"); + + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + // The input shapes are extended as part of NdArrayDesc initialization. + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + const int32_t input1_val = + params.input1_offset + + input1_data[SubscriptToIndex(desc1, b, y, x, c)]; + const int32_t input2_val = + params.input2_offset + + input2_data[SubscriptToIndex(desc2, b, y, x, c)]; + const int32_t unclamped_result = + params.output_offset + + MultiplyByQuantizedMultiplier(input1_val * input2_val, + params.output_multiplier, + params.output_shift); + const int32_t clamped_output = std::min( + params.quantized_activation_max, + std::max(params.quantized_activation_min, unclamped_result)); + output_data[Offset(extended_output_shape, b, y, x, c)] = + static_cast(clamped_output); + } + } + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_MUL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h new file mode 100644 index 0000000..17944bc --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h @@ -0,0 +1,258 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_POOLING_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_POOLING_H_ + +#include +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void AveragePool(const PoolParams& params, + const RuntimeShape& input_shape, + const int8_t* input_data, + const RuntimeShape& output_shape, int8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + int32_t acc = 0; + int filter_count = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + acc += + input_data[Offset(input_shape, batch, in_y, in_x, channel)]; + filter_count++; + } + } + // Round to the closest integer value. + acc = acc > 0 ? (acc + filter_count / 2) / filter_count + : (acc - filter_count / 2) / filter_count; + acc = std::max(acc, params.quantized_activation_min); + acc = std::min(acc, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(acc); + } + } + } + } +} + +inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape, + const int8_t* input_data, const RuntimeShape& output_shape, + int8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_GE(params.quantized_activation_min, + std::numeric_limits::min()); + TFLITE_DCHECK_LE(params.quantized_activation_max, + std::numeric_limits::max()); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + int8_t max = std::numeric_limits::lowest(); + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + max = std::max( + max, + input_data[Offset(input_shape, batch, in_y, in_x, channel)]); + } + } + max = std::max(max, params.quantized_activation_min); + max = std::min(max, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(max); + } + } + } + } +} + +inline void AveragePool(const PoolParams& params, + const RuntimeShape& input_shape, + const int16_t* input_data, + const RuntimeShape& output_shape, + int16_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + int32_t acc = 0; + int filter_count = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + acc += + input_data[Offset(input_shape, batch, in_y, in_x, channel)]; + filter_count++; + } + } + // Round to the closest integer value. + acc = acc > 0 ? (acc + filter_count / 2) / filter_count + : (acc - filter_count / 2) / filter_count; + acc = std::max(acc, params.quantized_activation_min); + acc = std::min(acc, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(acc); + } + } + } + } +} + +inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape, + const int16_t* input_data, const RuntimeShape& output_shape, + int16_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_GE(params.quantized_activation_min, + std::numeric_limits::min()); + TFLITE_DCHECK_LE(params.quantized_activation_max, + std::numeric_limits::max()); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + int16_t max = std::numeric_limits::lowest(); + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + max = std::max( + max, + input_data[Offset(input_shape, batch, in_y, in_x, channel)]); + } + } + max = std::max(max, params.quantized_activation_min); + max = std::min(max, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(max); + } + } + } + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_POOLING_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h new file mode 100644 index 0000000..baae65a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h @@ -0,0 +1,106 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_TANH_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_TANH_H_ + +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { +namespace reference_integer_ops { + +inline void Tanh(int32_t input_zero_point, int32_t input_range_radius, + int32_t input_multiplier, int32_t input_shift, + int32_t input_size, const int8_t* input_data, + int8_t* output_data) { + // Integer bits must be in sync with Prepare() function. + static constexpr int32_t kInputIntegerBits = 4; + static constexpr int32_t kOutputScale = 7; + static constexpr int32_t kMinInt8 = std::numeric_limits::min(); + static constexpr int32_t kMaxInt8 = std::numeric_limits::max(); + using F4 = gemmlowp::FixedPoint; + + for (int i = 0; i < input_size; ++i) { + const int32_t input = + static_cast(input_data[i]) - input_zero_point; + if (input <= -input_range_radius) { + output_data[i] = kMinInt8; + } else if (input >= input_range_radius) { + output_data[i] = kMaxInt8; + } else { + const int32_t input_in_q4 = + MultiplyByQuantizedMultiplier(input, input_multiplier, input_shift); + const int32_t output_in_q0 = + gemmlowp::tanh(F4::FromRaw(input_in_q4)).raw(); + + // Rescale and downcast. + using gemmlowp::RoundingDivideByPOT; + int32_t output_in_q24 = + RoundingDivideByPOT(output_in_q0, 31 - kOutputScale); + output_in_q24 = std::min(std::max(output_in_q24, kMinInt8), kMaxInt8); + output_data[i] = static_cast(output_in_q24); + } + } +} + +inline void Tanh(int32_t input_multiplier, int32_t input_left_shift, + int32_t input_size, const int16_t* ptr_input_data, + int16_t* ptr_output_data) { + // We use the LUT for sigmoid and take into account, that + // tanh(x) = 2*sigmoid(2*x) - 1 + + int32_t input_data_mul = (input_multiplier > 0) ? input_multiplier : 1; + + for (int i = 0; i < input_size; ++i, ptr_input_data++, ptr_output_data++) { + int32_t input_data = (*ptr_input_data) * input_data_mul; + + if (input_left_shift == 1) { + input_data <<= 1; + } + + // Scale by 3/4 to expand range [-8,8]->[-10.7,10.7]. + uint32_t abs_input_data = 3 * abs(input_data); + uint32_t uh = abs_input_data >> 8; + int32_t result; + + if (uh >= 255) { + // Saturate to maximum. + result = 0xFFFF << 8; + } else { + uint32_t ua = sigmoid_table_uint16[uh]; + uint32_t ub = sigmoid_table_uint16[uh + 1]; + + uint8_t ut = abs_input_data & 0xFF; + + result = (ua << 8) + ut * (ub - ua); + } + + result = (input_data >= 0) + ? (result - (1 << (14 + 9)) + (1 << (9 - 2))) + : (-result + (1 << (14 + 9)) + (1 << (9 - 2)) - 1); + + // Convert back to 16-bit. + result >>= (9 - 1); + + *ptr_output_data = result; + } +} + +} // namespace reference_integer_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_INTEGER_OPS_TANH_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/l2normalization.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/l2normalization.h new file mode 100644 index 0000000..7587d2b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/l2normalization.h @@ -0,0 +1,90 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_L2NORMALIZATION_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_L2NORMALIZATION_H_ + +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline void L2Normalization(const tflite::L2NormalizationParams& op_params, + const RuntimeShape& input_shape, + const float* input_data, + const RuntimeShape& output_shape, + float* output_data, float epsilon = 1e-6) { + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + for (int i = 0; i < outer_size; ++i) { + float squared_l2_norm = 0; + for (int c = 0; c < depth; ++c) { + const float val = input_data[depth * i + c]; + squared_l2_norm += val * val; + } + float l2_norm = std::sqrt(squared_l2_norm); + l2_norm = std::max(l2_norm, epsilon); + for (int c = 0; c < depth; ++c) { + output_data[depth * i + c] = input_data[depth * i + c] / l2_norm; + } + } +} + +inline void L2Normalization(const tflite::L2NormalizationParams& op_params, + const RuntimeShape& input_shape, + const uint8_t* input_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int32_t input_zero_point = op_params.input_zero_point; + + for (int i = 0; i < outer_size; ++i) { + int32_t square_l2_norm = 0; + for (int c = 0; c < depth; c++) { + int32_t diff = input_data[depth * i + c] - input_zero_point; + square_l2_norm += diff * diff; + } + int32_t inv_l2norm_multiplier; + int inv_l2norm_shift; + GetInvSqrtQuantizedMultiplierExp(square_l2_norm, kReverseShift, + &inv_l2norm_multiplier, &inv_l2norm_shift); + for (int c = 0; c < depth; c++) { + int32_t diff = input_data[depth * i + c] - input_zero_point; + int32_t rescaled_diff = MultiplyByQuantizedMultiplierSmallerThanOneExp( + 128 * diff, inv_l2norm_multiplier, inv_l2norm_shift); + int32_t unclamped_output_val = 128 + rescaled_diff; + int32_t output_val = + std::min(static_cast(255), + std::max(static_cast(0), unclamped_output_val)); + output_data[depth * i + c] = static_cast(output_val); + } + } +} + +} // namespace reference_ops +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_L2NORMALIZATION_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/logistic.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/logistic.h new file mode 100644 index 0000000..64b7133 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/logistic.h @@ -0,0 +1,132 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_LOGISTIC_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_LOGISTIC_H_ + +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/op_macros.h" + +namespace tflite { +namespace reference_ops { + +inline void Logistic(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const float cutoff_upper = 16.619047164916992188f; + const float cutoff_lower = -9.f; + + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + // Rational for using approximation in reference kernel. + // 0. This approximation gives enough precision for float. + // 1. This works around an issue on an embedded chipset where exp() does not + // return correctly as expected - exp(x) should return inf when overflown + // not 1.701417 IEEE 754 defines representation for inf. + // 2. This will speed up calculation and is matching the behavior in the + // optimized kernels. (check the definition of scalar_logistic_op) + + for (int i = 0; i < flat_size; i++) { + float val = input_data[i]; + float result; + if (val > cutoff_upper) { + result = 1.0f; + } else if (val < cutoff_lower) { + result = std::exp(val); + } else { + result = 1.f / (1.f + std::exp(-val)); + } + output_data[i] = result; + } +} + +// Convenience version that allows, for example, generated-code calls to be +// uniform between data types. +inline void Logistic(const LogisticParams&, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& output_shape, + float* output_data) { + // Drop params: not needed. + Logistic(input_shape, input_data, output_shape, output_data); +} + +inline void Logistic(const LogisticParams& params, + const RuntimeShape& input_shape, const int16_t* input_data, + const RuntimeShape& output_shape, int16_t* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + // F0 uses 0 integer bits, range [-1, 1]. + // This is the return type of math functions such as tanh, logistic, + // whose range is in [-1, 1]. + using F0 = gemmlowp::FixedPoint; + // F3 uses 3 integer bits, range [-8, 8], the input range expected here. + using F3 = gemmlowp::FixedPoint; + + const F3 input = F3::FromRaw(input_data[i]); + F0 output = gemmlowp::logistic(input); + output_data[i] = output.raw(); + } +} + +// Quantized int8_t logistic activation. Cheats by dequantizing and +// requantizing around the floating point logistic method. This implementation +// is slow on platforms without a floating point unit. + +// TODO(b/141211002): Delete this int8_t implementation once we can reuse the +// approach used in TFLite for int8_t Logistic. +inline void Logistic(const RuntimeShape& input_shape, const int8_t* input_data, + float input_scale, int input_zero_point, + const RuntimeShape& output_shape, int8_t* output_data, + float output_scale, int output_zero_point) { + const float cutoff_upper = 16.619047164916992188f; + const float cutoff_lower = -9.f; + + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + // Rational for using approximation in reference kernel. + // 0. This approximation gives enough precision for float. + // 1. This works around an issue on an embedded chipset where exp() does not + // return correctly as expected - exp(x) should return inf when overflown + // not 1.701417 IEEE 754 defines representation for inf. + // 2. This will speed up calculation and is matching the behavior in the + // optimized kernels. (check the definition of scalar_logistic_op) + + for (int i = 0; i < flat_size; i++) { + // Dequantize. + float val = + static_cast((input_data[i] - input_zero_point) * input_scale); + float result; + if (val > cutoff_upper) { + result = 1.0f; + } else if (val < cutoff_lower) { + result = std::exp(val); + } else { + result = 1.f / (1.f + std::exp(-val)); + } + // Requantize + int8_t output = + static_cast(result / output_scale + output_zero_point); + output_data[i] = output; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_LOGISTIC_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/maximum_minimum.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/maximum_minimum.h new file mode 100644 index 0000000..cd11b41 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/maximum_minimum.h @@ -0,0 +1,64 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MAXIMUM_MINIMUM_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MAXIMUM_MINIMUM_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +template +void MaximumMinimumBroadcastSlow(const RuntimeShape& unextended_input1_shape, + const T* input1_data, + const RuntimeShape& unextended_input2_shape, + const T* input2_data, + const RuntimeShape& unextended_output_shape, + T* output_data, Op op) { + // Uses element-wise calculation if broadcast is not required. + if (unextended_input1_shape == unextended_input2_shape) { + const int flat_size = + MatchingElementsSize(unextended_input1_shape, unextended_input2_shape, + unextended_output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = op(input1_data[i], input2_data[i]); + } + } else { + TFLITE_DCHECK_LE(unextended_input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(unextended_input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), N); + + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast( + unextended_input1_shape, unextended_input2_shape, &desc1, &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, unextended_output_shape), + &output_desc); + + auto maxmin_func = [&](int indexes[N]) { + output_data[SubscriptToIndex(output_desc, indexes)] = + op(input1_data[SubscriptToIndex(desc1, indexes)], + input2_data[SubscriptToIndex(desc2, indexes)]); + }; + NDOpsHelper(output_desc, maxmin_func); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MAXIMUM_MINIMUM_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/mul.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/mul.h new file mode 100644 index 0000000..0578b81 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/mul.h @@ -0,0 +1,166 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MUL_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MUL_H_ + +#include "tensorflow/lite/kernels/internal/common.h" + +namespace tflite { + +namespace reference_ops { + +// Element-wise mul that can often be used for inner loop of broadcast Mul as +// well as the non-broadcast Mul. +inline void MulElementwise(int size, const ArithmeticParams& params, + const uint8_t* input1_data, + const uint8_t* input2_data, uint8_t* output_data) { + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t unclamped_result = + params.output_offset + + MultiplyByQuantizedMultiplier(input1_val * input2_val, + params.output_multiplier, + params.output_shift); + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, unclamped_result)); + output_data[i] = static_cast(clamped_output); + } +} + +template +inline void Mul(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const T* input1_data, + const RuntimeShape& input2_shape, const T* input2_data, + const RuntimeShape& output_shape, T* output_data) { + T output_activation_min; + T output_activation_max; + GetActivationParams(params, &output_activation_min, &output_activation_max); + + const int flat_size = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = ActivationFunctionWithMinMax( + input1_data[i] * input2_data[i], output_activation_min, + output_activation_max); + } +} + +inline void Mul(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const uint8_t* input1_data, + const RuntimeShape& input2_shape, const uint8_t* input2_data, + const RuntimeShape& output_shape, uint8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + const int flat_size = + MatchingFlatSize(input1_shape, input2_shape, output_shape); + + MulElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +inline void BroadcastMul4DSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const uint8_t* input1_data, + const RuntimeShape& input2_shape, + const uint8_t* input2_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + const int32_t input1_val = + params.input1_offset + + input1_data[SubscriptToIndex(desc1, b, y, x, c)]; + const int32_t input2_val = + params.input2_offset + + input2_data[SubscriptToIndex(desc2, b, y, x, c)]; + const int32_t unclamped_result = + params.output_offset + + MultiplyByQuantizedMultiplier(input1_val * input2_val, + params.output_multiplier, + params.output_shift); + const int32_t clamped_output = std::min( + params.quantized_activation_max, + std::max(params.quantized_activation_min, unclamped_result)); + output_data[Offset(extended_output_shape, b, y, x, c)] = + static_cast(clamped_output); + } + } + } + } +} + +template +void BroadcastMul4DSlow(const ArithmeticParams& params, + const RuntimeShape& unextended_input1_shape, + const T* input1_data, + const RuntimeShape& unextended_input2_shape, + const T* input2_data, + const RuntimeShape& unextended_output_shape, + T* output_data) { + T output_activation_min; + T output_activation_max; + GetActivationParams(params, &output_activation_min, &output_activation_max); + + TFLITE_DCHECK_LE(unextended_input1_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_input2_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(unextended_input1_shape, + unextended_input2_shape, &desc1, &desc2); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < output_shape.Dims(0); ++b) { + for (int y = 0; y < output_shape.Dims(1); ++y) { + for (int x = 0; x < output_shape.Dims(2); ++x) { + for (int c = 0; c < output_shape.Dims(3); ++c) { + output_data[Offset(output_shape, b, y, x, c)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, b, y, x, c)] * + input2_data[SubscriptToIndex(desc2, b, y, x, c)], + output_activation_min, output_activation_max); + } + } + } + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_MUL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/neg.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/neg.h new file mode 100644 index 0000000..e127883 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/neg.h @@ -0,0 +1,37 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_NEG_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_NEG_H_ + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +template +inline void Negate(const RuntimeShape& input_shape, const T* input_data, + const RuntimeShape& output_shape, T* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; ++i) { + output_data[i] = -input_data[i]; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_NEG_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pad.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pad.h new file mode 100644 index 0000000..2a040ce --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pad.h @@ -0,0 +1,162 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PAD_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PAD_H_ + +#include + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// TFLite Pad supports activation tensors with up to 4 dimensions. +constexpr int PadKernelMaxDimensionCount() { return 4; } + +// There are two versions of pad: Pad and PadV2. In PadV2 there is a second +// scalar input that provides the padding value. Therefore pad_value_ptr can be +// equivalent to a simple input1_data. For Pad, it should point to a zero +// value. +// +// Note that two typenames are required, so that T=P=int32_t is considered a +// specialization distinct from P=int32_t. +template +inline void PadImpl(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, const T* input_data, + const P* pad_value_ptr, const RuntimeShape& output_shape, + T* output_data) { + const RuntimeShape ext_input_shape = + RuntimeShape::ExtendedShape(PadKernelMaxDimensionCount(), input_shape); + const RuntimeShape ext_output_shape = + RuntimeShape::ExtendedShape(PadKernelMaxDimensionCount(), output_shape); + TFLITE_DCHECK_LE(op_params.left_padding_count, PadKernelMaxDimensionCount()); + TFLITE_DCHECK_LE(op_params.right_padding_count, PadKernelMaxDimensionCount()); + + // Runtime calls are currently fixed at 4 dimensions. Copy inputs so we can + // pad them to 4 dims (yes, we are "padding the padding"). + int left_padding_copy[PadKernelMaxDimensionCount()]; + for (int i = 0; i < PadKernelMaxDimensionCount(); i++) { + left_padding_copy[i] = 0; + } + for (int i = 0; i < op_params.left_padding_count; ++i) { + left_padding_copy[i + PadKernelMaxDimensionCount() - + op_params.left_padding_count] = op_params.left_padding[i]; + } + int right_padding_copy[PadKernelMaxDimensionCount()]; + for (int i = 0; i < PadKernelMaxDimensionCount(); i++) { + right_padding_copy[i] = 0; + } + for (int i = 0; i < op_params.right_padding_count; ++i) { + right_padding_copy[i + PadKernelMaxDimensionCount() - + op_params.right_padding_count] = + op_params.right_padding[i]; + } + + const int output_batch = ext_output_shape.Dims(0); + const int output_height = ext_output_shape.Dims(1); + const int output_width = ext_output_shape.Dims(2); + const int output_depth = ext_output_shape.Dims(3); + + const int left_b_padding = left_padding_copy[0]; + const int left_h_padding = left_padding_copy[1]; + const int left_w_padding = left_padding_copy[2]; + const int left_d_padding = left_padding_copy[3]; + + const int right_b_padding = right_padding_copy[0]; + const int right_h_padding = right_padding_copy[1]; + const int right_w_padding = right_padding_copy[2]; + const int right_d_padding = right_padding_copy[3]; + + const T pad_value = *pad_value_ptr; + + const T* in_ptr = input_data; + T* out_ptr = output_data; + for (int out_b = 0; out_b < output_batch; ++out_b) { + for (int out_h = 0; out_h < output_height; ++out_h) { + for (int out_w = 0; out_w < output_width; ++out_w) { + for (int out_d = 0; out_d < output_depth; ++out_d) { + if (out_b < left_b_padding || + out_b >= output_batch - right_b_padding || + out_h < left_h_padding || + out_h >= output_height - right_h_padding || + out_w < left_w_padding || + out_w >= output_width - right_w_padding || + out_d < left_d_padding || + out_d >= output_depth - right_d_padding) { + *out_ptr++ = pad_value; + } else { + *out_ptr++ = *in_ptr++; + } + } + } + } + } +} + +template +inline void Pad(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, const T* input_data, + const P* pad_value_ptr, const RuntimeShape& output_shape, + T* output_data) { + PadImpl(op_params, input_shape, input_data, pad_value_ptr, output_shape, + output_data); +} + +// The second (pad-value) input can be int32_t when, say, the first is uint8_t. +template +inline void Pad(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, const T* input_data, + const int32_t* pad_value_ptr, const RuntimeShape& output_shape, + T* output_data) { + const T converted_pad_value = static_cast(*pad_value_ptr); + PadImpl(op_params, input_shape, input_data, &converted_pad_value, + output_shape, output_data); +} + +// This version avoids conflicting template matching. +template <> +inline void Pad(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, const int32_t* input_data, + const int32_t* pad_value_ptr, const RuntimeShape& output_shape, + int32_t* output_data) { + PadImpl(op_params, input_shape, input_data, pad_value_ptr, output_shape, + output_data); +} + +template +inline void PadImageStyle(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, const T* input_data, + const P* pad_value_ptr, + const RuntimeShape& output_shape, T* output_data) { + Pad(op_params, input_shape, input_data, pad_value_ptr, output_shape, + output_data); +} + +template +inline void PadImageStyle(const tflite::PadParams& op_params, + const RuntimeShape& input_shape, + const float* input_data, const P* pad_value_ptr, + const RuntimeShape& output_shape, + float* output_data) { + Pad(op_params, input_shape, input_data, pad_value_ptr, output_shape, + output_data); +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PAD_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pooling.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pooling.h new file mode 100644 index 0000000..0872f52 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/pooling.h @@ -0,0 +1,297 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_POOLING_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_POOLING_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +inline void AveragePool(const PoolParams& params, + const RuntimeShape& input_shape, + const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + float total = 0.f; + float filter_count = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + total += + input_data[Offset(input_shape, batch, in_y, in_x, channel)]; + filter_count++; + } + } + const float average = total / filter_count; + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + ActivationFunctionWithMinMax(average, params.float_activation_min, + params.float_activation_max); + } + } + } + } +} + +inline void AveragePool(const PoolParams& params, + const RuntimeShape& input_shape, + const uint8_t* input_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + int32_t acc = 0; + int filter_count = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + acc += + input_data[Offset(input_shape, batch, in_y, in_x, channel)]; + filter_count++; + } + } + acc = (acc + filter_count / 2) / filter_count; + acc = std::max(acc, params.quantized_activation_min); + acc = std::min(acc, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(acc); + } + } + } + } +} + +inline void L2Pool(const PoolParams& params, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& output_shape, + float* output_data) { + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + float sum_squares = 0.f; + int filter_count = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + const float val = + input_data[Offset(input_shape, batch, in_y, in_x, channel)]; + sum_squares += val * val; + filter_count++; + } + } + const float l2pool_result = std::sqrt(sum_squares / filter_count); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + ActivationFunctionWithMinMax(l2pool_result, + params.float_activation_min, + params.float_activation_max); + } + } + } + } +} + +inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& output_shape, + float* output_data) { + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + float max = std::numeric_limits::lowest(); + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + max = std::max( + max, + input_data[Offset(input_shape, batch, in_y, in_x, channel)]); + } + } + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + ActivationFunctionWithMinMax(max, params.float_activation_min, + params.float_activation_max); + } + } + } + } +} + +inline void MaxPool(const PoolParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& output_shape, + uint8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + TFLITE_DCHECK_GE(params.quantized_activation_min, 0); + TFLITE_DCHECK_LE(params.quantized_activation_max, 255); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batches = MatchingDim(input_shape, 0, output_shape, 0); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int stride_height = params.stride_height; + const int stride_width = params.stride_width; + for (int batch = 0; batch < batches; ++batch) { + for (int out_y = 0; out_y < output_height; ++out_y) { + for (int out_x = 0; out_x < output_width; ++out_x) { + for (int channel = 0; channel < depth; ++channel) { + const int in_x_origin = + (out_x * stride_width) - params.padding_values.width; + const int in_y_origin = + (out_y * stride_height) - params.padding_values.height; + // Compute the boundaries of the filter region clamped so as to + // ensure that the filter window fits in the input array. + const int filter_x_start = std::max(0, -in_x_origin); + const int filter_x_end = + std::min(params.filter_width, input_width - in_x_origin); + const int filter_y_start = std::max(0, -in_y_origin); + const int filter_y_end = + std::min(params.filter_height, input_height - in_y_origin); + uint8_t max = 0; + for (int filter_y = filter_y_start; filter_y < filter_y_end; + ++filter_y) { + for (int filter_x = filter_x_start; filter_x < filter_x_end; + ++filter_x) { + const int in_x = in_x_origin + filter_x; + const int in_y = in_y_origin + filter_y; + max = std::max( + max, + input_data[Offset(input_shape, batch, in_y, in_x, channel)]); + } + } + max = std::max(max, params.quantized_activation_min); + max = std::min(max, params.quantized_activation_max); + output_data[Offset(output_shape, batch, out_y, out_x, channel)] = + static_cast(max); + } + } + } + } +} +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_POOLING_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/prelu.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/prelu.h new file mode 100644 index 0000000..02db517 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/prelu.h @@ -0,0 +1,109 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PRELU_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PRELU_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// Broadcast prelu to output_shape for quantized uint8_t/int8_t data. +template +inline void BroadcastPrelu4DSlow( + const PreluParams& params, const RuntimeShape& input_shape, + const T* input_data, const RuntimeShape& alpha_shape, const T* alpha_data, + const RuntimeShape& output_shape, T* output_data) { + TFLITE_DCHECK_LE(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(alpha_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), 4); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input_shape, alpha_shape, &desc1, &desc2); + + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + int output_index = Offset(extended_output_shape, b, y, x, c); + int input_index = SubscriptToIndex(desc1, b, y, x, c); + const int32_t input_value = + params.input_offset + input_data[input_index]; + int32_t output_value; + if (input_value >= 0) { + output_value = MultiplyByQuantizedMultiplier( + input_value, params.output_multiplier_1, params.output_shift_1); + } else { + auto alpha_index = SubscriptToIndex(desc2, b, y, x, c); + const int32_t alpha_value = + params.alpha_offset + alpha_data[alpha_index]; + + output_value = MultiplyByQuantizedMultiplier( + input_value * alpha_value, params.output_multiplier_2, + params.output_shift_2); + } + output_value += params.output_offset; + + const int32_t quantized_min = std::numeric_limits::min(); + const int32_t quantized_max = std::numeric_limits::max(); + const int32_t clamped_output = + std::min(quantized_max, std::max(quantized_min, output_value)); + output_data[output_index] = static_cast(clamped_output); + } + } + } + } +} + +template +inline void Prelu(const PreluParams& params, const RuntimeShape& input_shape, + const T* input_data, const RuntimeShape& alpha_shape, + const T* alpha_data, const RuntimeShape& output_shape, + T* output_data) { + const int32_t quantized_min = std::numeric_limits::min(); + const int32_t quantized_max = std::numeric_limits::max(); + + const int flat_size = + MatchingElementsSize(input_shape, alpha_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + const int32_t input_value = params.input_offset + input_data[i]; + int32_t output_value; + if (input_value >= 0) { + output_value = MultiplyByQuantizedMultiplier( + input_value, params.output_multiplier_1, params.output_shift_1); + } else { + const int32_t alpha_value = params.alpha_offset + alpha_data[i]; + + output_value = MultiplyByQuantizedMultiplier(input_value * alpha_value, + params.output_multiplier_2, + params.output_shift_2); + } + output_value += params.output_offset; + + const int32_t clamped_output = + std::min(quantized_max, std::max(quantized_min, output_value)); + output_data[i] = static_cast(clamped_output); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PRELU_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h new file mode 100644 index 0000000..40f779c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h @@ -0,0 +1,138 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PROCESS_BROADCAST_SHAPES_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PROCESS_BROADCAST_SHAPES_H_ + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// Consolidates dimensions in broadcast inputs, checks for five-fold pattern. +// +// For example, if sequence of dimensions of one input is +// ..., 1, 3, 1, 7, 9, 5,... and the other is ..., 2, 3, 1, 7, 1, 1, ... +// we can consolidate these as +// ..., 1, 3*7, 9*5, ... and 2, 3*7, 1. +// +// The category is updated in the less-frequent case of shapes that are +// not suited to a fivefold-loop broadcast. +// +// Falls back to generic pattern when it does not know how to process properly. +// +// Returns true iff there is some sort of broadcast, which includes five-fold +// patterns and falling back to generic broadcast. +inline bool ProcessBroadcastShapes(const RuntimeShape& shape0, + const RuntimeShape& shape1, + tflite::ArithmeticParams* params) { + const int dims_count = + std::max(shape0.DimensionsCount(), shape1.DimensionsCount()); + + params->broadcast_category = BroadcastableOpCategory::kGenericBroadcast; + RuntimeShape scalar_shape(dims_count, 1); + + auto extended_shape0 = RuntimeShape::ExtendedShape(dims_count, shape0); + auto extended_shape1 = RuntimeShape::ExtendedShape(dims_count, shape1); + + // Check for "exact" match, implicitly accepting any scalar shapes. + if (extended_shape0 == extended_shape1) { + params->broadcast_category = BroadcastableOpCategory::kNonBroadcast; + return false; + } + + for (int i = dims_count - 1; i >= 0; --i) { + if (extended_shape0.Dims(i) == extended_shape1.Dims(i)) { + continue; + } else if (extended_shape0.Dims(i) == 1) { + params->broadcast_category = + BroadcastableOpCategory::kFirstInputBroadcastsFast; + break; + } else if (extended_shape1.Dims(i) == 1) { + params->broadcast_category = + BroadcastableOpCategory::kSecondInputBroadcastsFast; + break; + } else { + // This case is erroneous: there is a dimension that does not match and + // is not a broadcast from one shape to the other. + params->broadcast_category = BroadcastableOpCategory::kGenericBroadcast; + return true; + } + } + + if (params->broadcast_category != + BroadcastableOpCategory::kFirstInputBroadcastsFast && + params->broadcast_category != + BroadcastableOpCategory::kSecondInputBroadcastsFast) { + // This is unreachable because at least one else clause in the above loop + // must be reached. + TFLITE_DCHECK(false); + params->broadcast_category = BroadcastableOpCategory::kNonBroadcast; + return false; + } + + // From this point it is assumed contractually that corresponding dimensions + // in shape0 and shape1 are either (a) equal or (b) one or other equals 1. + const bool swap_inputs = params->broadcast_category == + BroadcastableOpCategory::kSecondInputBroadcastsFast; + const RuntimeShape* shape_a = + swap_inputs ? &extended_shape1 : &extended_shape0; + const RuntimeShape* shape_b = + swap_inputs ? &extended_shape0 : &extended_shape1; + + int i = dims_count - 1; + params->broadcast_shape[0] = 1; + params->broadcast_shape[1] = 1; + params->broadcast_shape[2] = 1; + params->broadcast_shape[3] = 1; + params->broadcast_shape[4] = 1; + // y_0 is greedy: include dims if both or neither equal 1: in other words, + // test for equality rather than (shape_a->Dims(i) != 1). + while (i >= 0 && shape_a->Dims(i) == shape_b->Dims(i)) { + params->broadcast_shape[4] *= shape_b->Dims(i); + --i; + } + // Here either input_a or input_b has dim of 1 (if i >= 0). If it is input_b + // that has the unit dimension, the next two loops are not entered. + while (i >= 0 && shape_a->Dims(i) == 1) { + params->broadcast_shape[3] *= shape_b->Dims(i); + --i; + } + while (i >= 0 && shape_a->Dims(i) == shape_b->Dims(i)) { + params->broadcast_shape[2] *= shape_a->Dims(i); + --i; + } + // Here either input_a or input_b has dim of 1 (if i >= 0). + while (i >= 0 && shape_b->Dims(i) == 1) { + params->broadcast_shape[1] *= shape_a->Dims(i); + --i; + } + while (i >= 0 && shape_a->Dims(i) == shape_b->Dims(i)) { + params->broadcast_shape[0] *= shape_b->Dims(i); + --i; + } + + // Rarer case is when the broadcast dimensions cannot be handled by a fivefold + // loop. + if (i >= 0) { + params->broadcast_category = BroadcastableOpCategory::kGenericBroadcast; + } + return true; +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_PROCESS_BROADCAST_SHAPES_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/quantize.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/quantize.h new file mode 100644 index 0000000..6f3f9ae --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/quantize.h @@ -0,0 +1,55 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_QUANTIZE_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_QUANTIZE_H_ + +#include +#include + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +template +inline void AffineQuantize(const tflite::QuantizationParams& op_params, + const RuntimeShape& input_shape, + const InputT* input_data, + const RuntimeShape& output_shape, + OutputT* output_data) { + const int32_t zero_point = op_params.zero_point; + const double scale = op_params.scale; + const int flat_size = MatchingFlatSize(input_shape, output_shape); + static constexpr int32_t min_val = std::numeric_limits::min(); + static constexpr int32_t max_val = std::numeric_limits::max(); + + for (int i = 0; i < flat_size; i++) { + const InputT val = input_data[i]; + int32_t unclamped = + static_cast(TfLiteRound(val / static_cast(scale))) + + zero_point; + int32_t clamped = std::min(std::max(unclamped, min_val), max_val); + output_data[i] = clamped; + } +} + +} // namespace reference_ops + +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_QUANTIZE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/reduce.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/reduce.h new file mode 100644 index 0000000..597d015 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/reduce.h @@ -0,0 +1,405 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REDUCE_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REDUCE_H_ + +#include "ruy/profiler/instrumentation.h" // from @ruy +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/max.h" +#include "tensorflow/lite/kernels/internal/min.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +// A generic reduce method that can be used for reduce_sum, reduce_mean, etc. +// This method iterates through input data and reduce elements along the +// dimensions given in axis. +template +inline bool Reduce(const In* input_data, const int* input_dims, + const int* output_dims, const int input_num_dims, + const int output_num_dims, const int* axis, + const int num_axis, int* input_iter, + Out reducer(const Out current, const In in), + Out* output_data) { + // Reset input iterator. + for (int idx = 0; idx < input_num_dims; ++idx) { + input_iter[idx] = 0; + } + // Iterate through input_data. + do { + size_t input_offset = + ReducedOutputOffset(input_num_dims, input_dims, input_iter, 0, nullptr); + size_t output_offset = ReducedOutputOffset(input_num_dims, input_dims, + input_iter, num_axis, axis); + output_data[output_offset] = + reducer(output_data[output_offset], input_data[input_offset]); + } while (NextIndex(input_num_dims, input_dims, input_iter)); + return true; +} + +// This method parses the input 'axis' to remove duplicates and handle negative +// values, and returns a valid 'out_axis' +inline bool ResolveAxis(const int num_dims, const int* axis, + const int64_t num_axis, int* out_axis, + int* out_num_axis) { + *out_num_axis = 0; // Just in case. + // Short-circuit axis resolution for scalars; the axis will go unused. + if (num_dims == 0) { + return true; + } + // o(n^2) is fine since out_num_axis should be really small, mostly <= 4 + for (int64_t idx = 0; idx < num_axis; ++idx) { + // Handle negative index. A positive index 'p_idx' can be represented as a + // negative index 'n_idx' as: n_idx = p_idx-num_dims + // eg: For num_dims=3, [0, 1, 2] is the same as [-3, -2, -1] */ + int current = axis[idx] < 0 ? (axis[idx] + num_dims) : axis[idx]; + TFLITE_DCHECK(current >= 0 && current < num_dims); + bool is_dup = false; + for (int j = 0; j < *out_num_axis; ++j) { + if (out_axis[j] == current) { + is_dup = true; + break; + } + } + if (!is_dup) { + out_axis[*out_num_axis] = current; + *out_num_axis += 1; + } + } + return true; +} + +// This method expects that output_data has been initialized. +template +inline bool ReduceSumImpl(const In* input_data, const int* input_dims, + const int* output_dims, const int input_num_dims, + const int output_num_dims, const int* axis, + const int num_axis, int* input_iter, + Out* output_data) { + auto reducer = [](const Out current, const In in) -> Out { + const Out actual_in = static_cast(in); + return current + actual_in; + }; + return Reduce(input_data, input_dims, output_dims, input_num_dims, + output_num_dims, axis, num_axis, input_iter, reducer, + output_data); +} + +template +inline bool InitTensorDataForReduce(const int* dims, const int num_dims, + const T init_value, T* data) { + size_t num_elements = 1; + for (int idx = 0; idx < num_dims; ++idx) { + size_t current = static_cast(dims[idx]); + // Overflow prevention. + if (num_elements > std::numeric_limits::max() / current) { + return false; + } + num_elements *= current; + } + for (size_t idx = 0; idx < num_elements; ++idx) { + data[idx] = init_value; + } + return true; +} + +// Computes the generic value (i.e., sum/max/min/prod) of elements across +// dimensions given in axis. It needs to pass in init_value and reducer. +template +inline bool ReduceGeneric(const T* input_data, const int* input_dims, + const int input_num_dims, T* output_data, + const int* output_dims, const int output_num_dims, + const int* axis, const int64_t num_axis_dimensions, + bool keep_dims, int* temp_index, int* resolved_axis, + T init_value, + T reducer(const T current, const T in)) { + // Reset output data. + if (!InitTensorDataForReduce(output_dims, output_num_dims, init_value, + output_data)) { + return false; + } + + // Resolve axis. + int num_resolved_axis = 0; + if (!ResolveAxis(input_num_dims, axis, num_axis_dimensions, resolved_axis, + &num_resolved_axis)) { + return false; + } + + return Reduce(input_data, input_dims, output_dims, input_num_dims, + output_num_dims, resolved_axis, num_resolved_axis, + temp_index, reducer, output_data); +} + +// Computes the mean of elements across dimensions given in axis. +// It does so in two stages, first calculates the sum of elements along the axis +// then divides it by the number of element in axis. +template +inline bool Mean(const T* input_data, const int* input_dims, + const int input_num_dims, T* output_data, + const int* output_dims, const int output_num_dims, + const int* axis, const int num_axis_dimensions, bool keep_dims, + int* temp_index, int* resolved_axis, U* temp_sum) { + ruy::profiler::ScopeLabel label("Mean"); + // Reset output data. + size_t num_outputs = 1; + for (int idx = 0; idx < output_num_dims; ++idx) { + size_t current = static_cast(output_dims[idx]); + // Overflow prevention. + if (num_outputs > std::numeric_limits::max() / current) { + return false; + } + num_outputs *= current; + } + for (size_t idx = 0; idx < num_outputs; ++idx) { + output_data[idx] = T(); + temp_sum[idx] = U(); + } + + // Resolve axis. + int num_resolved_axis = 0; + if (!ResolveAxis(input_num_dims, axis, num_axis_dimensions, resolved_axis, + &num_resolved_axis)) { + return false; + } + + if (!ReduceSumImpl(input_data, input_dims, output_dims, input_num_dims, + output_num_dims, resolved_axis, num_resolved_axis, + temp_index, temp_sum)) { + return false; + } + + // Calculate mean by dividing output_data by num of aggregated element. + U num_elements_in_axis = 1; + for (int idx = 0; idx < num_resolved_axis; ++idx) { + size_t current = static_cast(input_dims[resolved_axis[idx]]); + // Overflow prevention. + if (current > (std::numeric_limits::max() / num_elements_in_axis)) { + return false; + } + num_elements_in_axis *= current; + } + + if (num_elements_in_axis > 0) { + for (size_t idx = 0; idx < num_outputs; ++idx) { + output_data[idx] = + static_cast(temp_sum[idx] / static_cast(num_elements_in_axis)); + } + } + return true; +} + +template +inline void Mean(const tflite::MeanParams& op_params, + const RuntimeShape& unextended_input_shape, + const T* input_data, + const RuntimeShape& unextended_output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("Mean4D"); + + // Current implementation only supports dimension equals 4 and simultaneous + // reduction over width and height. + TFLITE_CHECK_EQ(unextended_input_shape.DimensionsCount(), 4); + TFLITE_CHECK_LE(unextended_output_shape.DimensionsCount(), 4); + const RuntimeShape input_shape = + RuntimeShape::ExtendedShape(4, unextended_input_shape); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + const int output_batch = output_shape.Dims(0); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int output_depth = output_shape.Dims(3); + + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + + TFLITE_CHECK_EQ(op_params.axis_count, 2); + TFLITE_CHECK((op_params.axis[0] == 1 && op_params.axis[1] == 2) || + (op_params.axis[0] == 2 && op_params.axis[1] == 1)); + TFLITE_CHECK_EQ(output_height, 1); + TFLITE_CHECK_EQ(output_width, 1); + + for (int out_b = 0; out_b < output_batch; ++out_b) { + for (int out_d = 0; out_d < output_depth; ++out_d) { + float value = 0; + for (int in_h = 0; in_h < input_height; ++in_h) { + for (int in_w = 0; in_w < input_width; ++in_w) { + value += input_data[Offset(input_shape, out_b, in_h, in_w, out_d)]; + } + } + output_data[Offset(output_shape, out_b, 0, 0, out_d)] = + value / (input_width * input_height); + } + } +} + +inline void Mean(const tflite::MeanParams& op_params, + const RuntimeShape& unextended_input_shape, + const uint8_t* input_data, int32_t input_zero_point, + float input_scale, const RuntimeShape& unextended_output_shape, + uint8_t* output_data, int32_t output_zero_point, + float output_scale) { + ruy::profiler::ScopeLabel label("Mean4D/Uint8"); + + // Current implementation only supports dimension equals 4 and simultaneous + // reduction over width and height. + TFLITE_CHECK_EQ(unextended_input_shape.DimensionsCount(), 4); + TFLITE_CHECK_LE(unextended_output_shape.DimensionsCount(), 4); + const RuntimeShape input_shape = + RuntimeShape::ExtendedShape(4, unextended_input_shape); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + const int output_batch = output_shape.Dims(0); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + const int output_depth = output_shape.Dims(3); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const float num_elements_in_axis = input_width * input_height; + + TFLITE_CHECK_EQ(op_params.axis_count, 2); + TFLITE_CHECK((op_params.axis[0] == 1 && op_params.axis[1] == 2) || + (op_params.axis[0] == 2 && op_params.axis[1] == 1)); + TFLITE_CHECK_EQ(output_height, 1); + TFLITE_CHECK_EQ(output_width, 1); + + constexpr int32_t kMinValue = std::numeric_limits::min(); + constexpr int32_t kMaxValue = std::numeric_limits::max(); + + int32_t bias = + output_zero_point - + static_cast(input_zero_point * input_scale / output_scale); + double real_scale = + static_cast(input_scale / (num_elements_in_axis * output_scale)); + + int32_t multiplier; + int shift; + QuantizeMultiplier(real_scale, &multiplier, &shift); + for (int out_b = 0; out_b < output_batch; ++out_b) { + for (int out_d = 0; out_d < output_depth; ++out_d) { + int32_t acc = 0; + for (int in_h = 0; in_h < input_height; ++in_h) { + for (int in_w = 0; in_w < input_width; ++in_w) { + acc += input_data[Offset(input_shape, out_b, in_h, in_w, out_d)]; + } + } + acc = MultiplyByQuantizedMultiplier(acc, multiplier, shift); + acc += bias; + acc = std::min(std::max(acc, kMinValue), kMaxValue); + output_data[Offset(output_shape, out_b, 0, 0, out_d)] = + static_cast(acc); + } + } +} + +// Computes the mean of elements across dimensions given in axis. +// It does so in two stages, first calculates the sum of elements along the axis +// then divides it by the number of element in axis for quantized values. +template +inline bool QuantizedMeanOrSum(const T* input_data, int32_t input_zero_point, + float input_scale, const int* input_dims, + const int input_num_dims, T* output_data, + int32_t output_zero_point, float output_scale, + const int* output_dims, + const int output_num_dims, const int* axis, + const int num_axis_dimensions, bool keep_dims, + int* temp_index, int* resolved_axis, U* temp_sum, + bool compute_sum) { + const bool uint8_case = std::is_same::value; + const bool int16_case = std::is_same::value; + if (uint8_case) { + ruy::profiler::ScopeLabel label(compute_sum ? "Sum/Uint8" : "Mean/Uint8"); + } else if (int16_case) { + ruy::profiler::ScopeLabel label(compute_sum ? "Sum/Int16" : "Mean/Int16"); + } else { + ruy::profiler::ScopeLabel label(compute_sum ? "Sum/Int8" : "Mean/Int8"); + } + // Reset output data. + size_t num_outputs = 1; + for (int idx = 0; idx < output_num_dims; ++idx) { + size_t current = static_cast(output_dims[idx]); + // Overflow prevention. + if (num_outputs > std::numeric_limits::max() / current) { + return false; + } + num_outputs *= current; + } + for (size_t idx = 0; idx < num_outputs; ++idx) { + output_data[idx] = T(); + temp_sum[idx] = U(); + } + + // Resolve axis. + int num_resolved_axis = 0; + if (!ResolveAxis(input_num_dims, axis, num_axis_dimensions, resolved_axis, + &num_resolved_axis)) { + return false; + } + + if (!ReduceSumImpl(input_data, input_dims, output_dims, input_num_dims, + output_num_dims, resolved_axis, num_resolved_axis, + temp_index, temp_sum)) { + return false; + } + + // Calculate mean by dividing output_data by num of aggregated element. + U num_elements_in_axis = 1; + for (int idx = 0; idx < num_resolved_axis; ++idx) { + size_t current = static_cast(input_dims[resolved_axis[idx]]); + // Overflow prevention. + if (current > (std::numeric_limits::max() / num_elements_in_axis)) { + return false; + } + num_elements_in_axis *= current; + } + + if (num_elements_in_axis > 0) { + const float scale = input_scale / output_scale; + if (compute_sum) { + // TODO(b/116341117): Eliminate float and do this completely in 8bit. + const float bias = + -input_zero_point * scale * num_elements_in_axis + 0.5f; + for (size_t idx = 0; idx < num_outputs; ++idx) { + const U value = + static_cast(TfLiteRound(temp_sum[idx] * scale + bias)) + + output_zero_point; + output_data[idx] = static_cast(value); + } + } else { + const float bias = -input_zero_point * scale + 0.5f; + for (size_t idx = 0; idx < num_outputs; ++idx) { + float float_mean = static_cast(temp_sum[idx]) / + static_cast(num_elements_in_axis); + float result = TfLiteMin( + TfLiteRound(float_mean * scale + bias) + output_zero_point, + static_cast(std::numeric_limits::max())); + result = TfLiteMax(result, + static_cast(std::numeric_limits::min())); + output_data[idx] = static_cast(result); + } + } + } + return true; +} + +} // namespace reference_ops + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REDUCE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/requantize.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/requantize.h new file mode 100644 index 0000000..32e32ed --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/requantize.h @@ -0,0 +1,67 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REQUANTIZE_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REQUANTIZE_H_ + +#include "ruy/profiler/instrumentation.h" // from @ruy +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace reference_ops { + +template +inline void Requantize(const input_type* input_data, int32_t size, + int32_t effective_scale_multiplier, + int32_t effective_scale_shift, int32_t input_zeropoint, + int32_t output_zeropoint, output_type* output_data) { + ruy::profiler::ScopeLabel label("Requantize"); + const bool same_scale = + (effective_scale_multiplier == 1 << 30 && effective_scale_shift == 1); + if (same_scale) { + const bool mixed_type_int8_uint8 = + std::is_same::value && + std::is_same::value; + const bool mixed_type_uint8_int8 = + std::is_same::value && + std::is_same::value; + const int32_t zero_point_diff = input_zeropoint - output_zeropoint; + // Fast path to do requantization for the case when just a shift of 128 is + // needed. + if ((mixed_type_int8_uint8 && zero_point_diff == -128) || + (mixed_type_uint8_int8 && zero_point_diff == 128)) { + for (int i = 0; i < size; ++i) { + output_data[i] = input_data[i] ^ 0x80; + } + } + } + static constexpr int32_t kMinOutput = std::numeric_limits::min(); + static constexpr int32_t kMaxOutput = std::numeric_limits::max(); + for (int i = 0; i < size; ++i) { + const int32_t input = input_data[i] - input_zeropoint; + const int32_t output = + MultiplyByQuantizedMultiplier(input, effective_scale_multiplier, + effective_scale_shift) + + output_zeropoint; + const int32_t clamped_output = + std::max(std::min(output, kMaxOutput), kMinOutput); + output_data[i] = static_cast(clamped_output); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_REQUANTIZE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h new file mode 100644 index 0000000..95550ab --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h @@ -0,0 +1,101 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_RESIZE_NEAREST_NEIGHBOR_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_RESIZE_NEAREST_NEIGHBOR_H_ + +#include + +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline int32_t GetNearestNeighbor(const int input_value, + const int32_t input_size, + const int32_t output_size, + const bool align_corners, + const bool half_pixel_centers) { + const float scale = + (align_corners && output_size > 1) + ? (input_size - 1) / static_cast(output_size - 1) + : input_size / static_cast(output_size); + const float offset = half_pixel_centers ? 0.5f : 0.0f; + int32_t output_value = std::min( + align_corners + ? static_cast(TfLiteRound((input_value + offset) * scale)) + : static_cast(std::floor((input_value + offset) * scale)), + input_size - 1); + if (half_pixel_centers) { + output_value = std::max(static_cast(0), output_value); + } + return output_value; +} + +template +inline void ResizeNearestNeighbor( + const tflite::ResizeNearestNeighborParams& op_params, + const RuntimeShape& unextended_input_shape, const T* input_data, + const RuntimeShape& output_size_shape, const int32_t* output_size_data, + const RuntimeShape& unextended_output_shape, T* output_data) { + TFLITE_DCHECK_LE(unextended_input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + + const RuntimeShape input_shape = + RuntimeShape::ExtendedShape(4, unextended_input_shape); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + int32_t batches = MatchingDim(input_shape, 0, output_shape, 0); + int32_t input_height = input_shape.Dims(1); + int32_t input_width = input_shape.Dims(2); + int32_t depth = MatchingDim(input_shape, 3, output_shape, 3); + + // The Tensorflow version of this op allows resize on the width and height + // axis only. + TFLITE_DCHECK_EQ(output_size_shape.FlatSize(), 2); + int32_t output_height = output_size_data[0]; + int32_t output_width = output_size_data[1]; + + const int col_offset = input_shape.Dims(3); + const int row_offset = input_shape.Dims(2) * col_offset; + const int batch_offset = input_shape.Dims(1) * row_offset; + + const T* input_ptr = input_data; + T* output_ptr = output_data; + for (int b = 0; b < batches; ++b) { + for (int y = 0; y < output_height; ++y) { + int32_t in_y = GetNearestNeighbor(y, input_height, output_height, + op_params.align_corners, + op_params.half_pixel_centers); + const T* y_input_ptr = input_ptr + in_y * row_offset; + for (int x = 0; x < output_width; ++x) { + int32_t in_x = GetNearestNeighbor(x, input_width, output_width, + op_params.align_corners, + op_params.half_pixel_centers); + const T* x_input_ptr = y_input_ptr + in_x * col_offset; + memcpy(output_ptr, x_input_ptr, depth * sizeof(T)); + output_ptr += depth; + } + } + input_ptr += batch_offset; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_RESIZE_NEAREST_NEIGHBOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/round.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/round.h new file mode 100644 index 0000000..9bd8f3f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/round.h @@ -0,0 +1,51 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ROUND_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ROUND_H_ + +#include + +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline float RoundToNearest(float value) { + auto floor_val = std::floor(value); + auto diff = value - floor_val; + if ((diff < 0.5f) || + ((diff == 0.5f) && (static_cast(floor_val) % 2 == 0))) { + return floor_val; + } else { + return floor_val = floor_val + 1.0f; + } +} + +inline void Round(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + // Note that this implementation matches that of tensorFlow tf.round + // and corresponds to the bankers rounding method. + // cfenv (for fesetround) is not yet supported universally on Android, so + // using a work around. + output_data[i] = RoundToNearest(input_data[i]); + } +} + +} // namespace reference_ops +} // namespace tflite +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_ROUND_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/softmax.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/softmax.h new file mode 100644 index 0000000..b035b43 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/softmax.h @@ -0,0 +1,228 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SOFTMAX_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SOFTMAX_H_ + +#include +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/op_macros.h" + +namespace tflite { +namespace reference_ops { + +inline void Softmax(const SoftmaxParams& params, + const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + + for (int i = 0; i < outer_size; ++i) { + // Find max element value which we'll use to ensure numerical stability + // taking advantage of the following equality: + // exp(x[i])/sum(exp(x[i])) == exp(x[i]+C)/sum(exp(x[i]+C)) + float max = std::numeric_limits::lowest(); + for (int c = 0; c < depth; ++c) { + max = std::max(max, input_data[i * depth + c]); + } + + // Compute sum. + float sum = 0.f; + for (int c = 0; c < depth; ++c) { + sum += std::exp((input_data[i * depth + c] - max) * + static_cast(params.beta)); + } + + // Compute result. + for (int c = 0; c < depth; ++c) { + output_data[i * depth + c] = std::exp((input_data[i * depth + c] - max) * + static_cast(params.beta)) / + sum; + } + } +} + +// Quantized softmax with int8_t/uint8_t input and int8_t/uint8_t/int16_t +// output. +template +inline void Softmax(const SoftmaxParams& params, + const RuntimeShape& input_shape, const InputT* input_data, + const RuntimeShape& output_shape, OutputT* output_data) { + const int32_t input_beta_multiplier = params.input_multiplier; + const int32_t input_beta_left_shift = params.input_left_shift; + const int diff_min = params.diff_min; + // The representation chosen for the input to the exp() function is Q5.26. + // We need to leave extra space since values that we skip might be as large as + // -32 before multiplying by input_beta_multiplier, and therefore as large as + // -16 afterwards. Note that exp(-8) is definitely not insignificant to + // accumulation, but exp(-16) definitely is. + static const int kScaledDiffIntegerBits = 5; + static const int kAccumulationIntegerBits = 12; + using FixedPointScaledDiff = + gemmlowp::FixedPoint; + using FixedPointAccum = + gemmlowp::FixedPoint; + using FixedPoint0 = gemmlowp::FixedPoint; + + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + + for (int i = 0; i < outer_size; ++i) { + InputT max_in_row = std::numeric_limits::min(); + for (int c = 0; c < depth; ++c) { + max_in_row = std::max(max_in_row, input_data[i * depth + c]); + } + + FixedPointAccum sum_of_exps = FixedPointAccum::Zero(); + for (int c = 0; c < depth; ++c) { + int32_t input_diff = + static_cast(input_data[i * depth + c]) - max_in_row; + if (input_diff >= diff_min) { + const int32_t input_diff_rescaled = + MultiplyByQuantizedMultiplierGreaterThanOne( + input_diff, input_beta_multiplier, input_beta_left_shift); + const FixedPointScaledDiff scaled_diff_f8 = + FixedPointScaledDiff::FromRaw(input_diff_rescaled); + sum_of_exps = sum_of_exps + gemmlowp::Rescale( + exp_on_negative_values(scaled_diff_f8)); + } + } + + int num_bits_over_unit; + FixedPoint0 shifted_scale = FixedPoint0::FromRaw(GetReciprocal( + sum_of_exps.raw(), kAccumulationIntegerBits, &num_bits_over_unit)); + + for (int c = 0; c < depth; ++c) { + int32_t input_diff = + static_cast(input_data[i * depth + c]) - max_in_row; + if (input_diff >= diff_min) { + const int32_t input_diff_rescaled = + MultiplyByQuantizedMultiplierGreaterThanOne( + input_diff, input_beta_multiplier, input_beta_left_shift); + const FixedPointScaledDiff scaled_diff_f8 = + FixedPointScaledDiff::FromRaw(input_diff_rescaled); + + FixedPoint0 exp_in_0 = exp_on_negative_values(scaled_diff_f8); + int32_t unsat_output = gemmlowp::RoundingDivideByPOT( + (shifted_scale * exp_in_0).raw(), + num_bits_over_unit + 31 - (sizeof(OutputT) * 8)); + + const int32_t shifted_output = + unsat_output + + static_cast(std::numeric_limits::min()); + + output_data[i * depth + c] = static_cast(std::max( + std::min(shifted_output, + static_cast(std::numeric_limits::max())), + static_cast(std::numeric_limits::min()))); + } else { + output_data[i * depth + c] = std::numeric_limits::min(); + } + } + } +} + +// Quantized softmax with int16_t input and int16_t output. +inline void SoftmaxInt16(const SoftmaxParams& params, + const RuntimeShape& input_shape, + const int16_t* input_data, + const RuntimeShape& output_shape, + int16_t* output_data) { + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + + for (int i = 0; i < outer_size; ++i) { + // Find the largest element + int16_t max_in_row = std::numeric_limits::min(); + for (int c = 0; c < depth; ++c) { + max_in_row = std::max(max_in_row, input_data[i * depth + c]); + } + + // Compute exp(input - max_input) + std::vector exp_result_Q015(depth); + for (int c = 0; c < depth; ++c) { + int32_t input_diff = input_data[i * depth + c] - max_in_row; + // scale the input_diff such that [-65535, 0] correspond to [-10.0, 0.0] + int32_t scaled_diff = MultiplyByQuantizedMultiplier( + input_diff, params.input_multiplier, params.input_left_shift); + // recenter to [-32768, 32767] + int32_t sym_scaled_diff = scaled_diff + 32767; + int16_t sat_sym_scaled_diff = + std::min(std::max(sym_scaled_diff, static_cast(-32768)), + static_cast(32767)); + // apply the exp() LUT activation function + exp_result_Q015[c] = + generic_int16_table_lookup(sat_sym_scaled_diff, params.exp_lut); + } + + // sum_of_exps is a Q16.15 fixed point format. + int32_t sum_of_exps = 0; + for (int c = 0; c < depth; ++c) { + // Q16.15 + Q0.15 + sum_of_exps += exp_result_Q015[c]; + } + + // Compute the reciprocal 1/sum_of_exps + uint8_t headroom_plus_one = + CountLeadingZeros(static_cast(sum_of_exps)); + int32_t shifted_sum = + ((static_cast(sum_of_exps) << (headroom_plus_one - 1)) + + (1 << 13)) >> + 14; + // since the LUT computes 1/(1 + x) we need to first compute x = (sum - 1). + // also, the LUT expects a symmetrical input, so we must also recenter x + // from [0, 65535] to [-32768, 32767]. + int32_t sym_shifted_sum = shifted_sum + (-((1 << 15) + (1 << 16))); + int16_t sat_sym_shifted_sum = static_cast( + std::min(std::max(sym_shifted_sum, static_cast(-32768)), + static_cast(32767))); + // apply 1/(1 + x) LUT activation function + int16_t reciprocal_scale_Q015 = generic_int16_table_lookup( + sat_sym_shifted_sum, params.one_over_one_plus_x_lut); + + // Rescale the exp_result with reciprocal + // range of output is [0, 32767] correspond to [0.0, 1.0] + for (int c = 0; c < depth; ++c) { + uint8_t right_shift = 31 - headroom_plus_one; + int64_t round = 1 << (right_shift - 1); + int32_t result = (static_cast(exp_result_Q015[c]) * + static_cast(reciprocal_scale_Q015) + + round) >> + right_shift; + output_data[i * depth + c] = static_cast( + std::min(std::max(result, static_cast(0)), + static_cast(32767))); + } + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SOFTMAX_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/strided_slice.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/strided_slice.h new file mode 100644 index 0000000..8b6f0c1 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/strided_slice.h @@ -0,0 +1,94 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_STRIDED_SLICE_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_STRIDED_SLICE_H_ + +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/strided_slice_logic.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { +template +inline void StridedSlice(const tflite::StridedSliceParams& op_params, + const RuntimeShape& unextended_input_shape, + const T* input_data, + const RuntimeShape& unextended_output_shape, + T* output_data) { + using strided_slice::LoopCondition; + using strided_slice::StartForAxis; + using strided_slice::StopForAxis; + // Note that the output_shape is not used herein. + tflite::StridedSliceParams params_copy = op_params; + + TFLITE_DCHECK_LE(unextended_input_shape.DimensionsCount(), 5); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 5); + const RuntimeShape input_shape = + RuntimeShape::ExtendedShape(5, unextended_input_shape); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(5, unextended_output_shape); + + // Reverse and pad to 5 dimensions because that is what the runtime code + // requires (ie. all shapes must be 5D and are given backwards). + strided_slice::StridedSlicePadIndices(¶ms_copy, 5); + + const int start_0 = StartForAxis(params_copy, input_shape, 0); + const int stop_0 = StopForAxis(params_copy, input_shape, 0, start_0); + const int start_1 = StartForAxis(params_copy, input_shape, 1); + const int stop_1 = StopForAxis(params_copy, input_shape, 1, start_1); + const int start_2 = StartForAxis(params_copy, input_shape, 2); + const int stop_2 = StopForAxis(params_copy, input_shape, 2, start_2); + const int start_3 = StartForAxis(params_copy, input_shape, 3); + const int stop_3 = StopForAxis(params_copy, input_shape, 3, start_3); + const int start_4 = StartForAxis(params_copy, input_shape, 4); + const int stop_4 = StopForAxis(params_copy, input_shape, 4, start_4); + + T* out_ptr = output_data; + for (int offset_0 = start_0 * input_shape.Dims(1), + end_0 = stop_0 * input_shape.Dims(1), + step_0 = params_copy.strides[0] * input_shape.Dims(1); + !LoopCondition(offset_0, end_0, params_copy.strides[0]); + offset_0 += step_0) { + for (int offset_1 = (offset_0 + start_1) * input_shape.Dims(2), + end_1 = (offset_0 + stop_1) * input_shape.Dims(2), + step_1 = params_copy.strides[1] * input_shape.Dims(2); + !LoopCondition(offset_1, end_1, params_copy.strides[1]); + offset_1 += step_1) { + for (int offset_2 = (offset_1 + start_2) * input_shape.Dims(3), + end_2 = (offset_1 + stop_2) * input_shape.Dims(3), + step_2 = params_copy.strides[2] * input_shape.Dims(3); + !LoopCondition(offset_2, end_2, params_copy.strides[2]); + offset_2 += step_2) { + for (int offset_3 = (offset_2 + start_3) * input_shape.Dims(4), + end_3 = (offset_2 + stop_3) * input_shape.Dims(4), + step_3 = params_copy.strides[3] * input_shape.Dims(4); + !LoopCondition(offset_3, end_3, params_copy.strides[3]); + offset_3 += step_3) { + for (int offset_4 = offset_3 + start_4, end_4 = offset_3 + stop_4; + !LoopCondition(offset_4, end_4, params_copy.strides[4]); + offset_4 += params_copy.strides[4]) { + *out_ptr++ = input_data[offset_4]; + } + } + } + } + } +} +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_STRIDED_SLICE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/sub.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/sub.h new file mode 100644 index 0000000..b27f251 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/sub.h @@ -0,0 +1,516 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SUB_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SUB_H_ + +#include + +#include +#include + +#include "ruy/profiler/instrumentation.h" // from @ruy +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +namespace reference_ops { + +inline void SubNonBroadcast(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const float* input1_data, + const RuntimeShape& input2_shape, + const float* input2_data, + const RuntimeShape& output_shape, + float* output_data) { + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = ActivationFunctionWithMinMax( + input1_data[i] - input2_data[i], params.float_activation_min, + params.float_activation_max); + } +} + +inline void SubNonBroadcast(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int32_t* input1_data, + const RuntimeShape& input2_shape, + const int32_t* input2_data, + const RuntimeShape& output_shape, + int32_t* output_data) { + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + output_data[i] = ActivationFunctionWithMinMax( + input1_data[i] - input2_data[i], params.quantized_activation_min, + params.quantized_activation_max); + } +} + +// TODO(b/151345304): We can implement BroadcastSub on buffers of arbitrary +// dimensionality if the runtime code does a single loop over one dimension +// that handles broadcasting as the base case. The code generator would then +// generate max(D1, D2) nested for loops. +// TODO(b/151345101): BroadcastSub is intentionally duplicated from +// reference_ops.h. Once an optimized version is implemented and NdArrayDesc +// is no longer referenced in this file, move NdArrayDesc from types.h to +// reference_ops.h. +template +inline void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const float* input1_data, + const RuntimeShape& input2_shape, + const float* input2_data, + const RuntimeShape& output_shape, + float* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/float"); + TFLITE_DCHECK_LE(input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), N); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + output_data[SubscriptToIndex(output_desc, indexes)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, indexes)] - + input2_data[SubscriptToIndex(desc2, indexes)], + params.float_activation_min, params.float_activation_max); + }; + NDOpsHelper(output_desc, sub_func); +} + +template +inline void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const uint8_t* input1_data, + const RuntimeShape& input2_shape, + const uint8_t* input2_data, + const RuntimeShape& output_shape, + uint8_t* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/uint8_t"); + TFLITE_DCHECK_LE(input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), N); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + const int32_t input1_val = + params.input1_offset + input1_data[SubscriptToIndex(desc1, indexes)]; + const int32_t input2_val = + params.input2_offset + input2_data[SubscriptToIndex(desc2, indexes)]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sub = scaled_input1_val - scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sub, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[SubscriptToIndex(output_desc, indexes)] = + static_cast(clamped_output); + }; + NDOpsHelper(output_desc, sub_func); +} + +template +inline void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int32_t* input1_data, + const RuntimeShape& input2_shape, + const int32_t* input2_data, + const RuntimeShape& output_shape, + int32_t* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/int32_t"); + TFLITE_DCHECK_LE(input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), N); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + output_data[SubscriptToIndex(output_desc, indexes)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, indexes)] - + input2_data[SubscriptToIndex(desc2, indexes)], + params.quantized_activation_min, params.quantized_activation_max); + }; + NDOpsHelper(output_desc, sub_func); +} + +template +inline void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int8_t* input1_data, + const RuntimeShape& input2_shape, + const int8_t* input2_data, + const RuntimeShape& output_shape, + int8_t* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/int8_t"); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + const int32_t input1_val = + params.input1_offset + input1_data[SubscriptToIndex(desc1, indexes)]; + const int32_t input2_val = + params.input2_offset + input2_data[SubscriptToIndex(desc2, indexes)]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sub = scaled_input1_val - scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sub, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[SubscriptToIndex(output_desc, indexes)] = + static_cast(clamped_output); + }; + NDOpsHelper(output_desc, sub_func); +} + +template +void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, + const int64_t* input1_data, + const RuntimeShape& input2_shape, + const int64_t* input2_data, + const RuntimeShape& output_shape, int64_t* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/int64_t"); + TFLITE_DCHECK_LE(input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), N); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + output_data[SubscriptToIndex(output_desc, indexes)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, indexes)] - + input2_data[SubscriptToIndex(desc2, indexes)], + params.int64_activation_min, params.int64_activation_max); + }; + NDOpsHelper(output_desc, sub_func); +} + +template +void BroadcastSubSlow(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const T* input1_data, + const RuntimeShape& input2_shape, const T* input2_data, + const RuntimeShape& output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("BroadcastSubSlow/templated"); + TFLITE_DCHECK_LE(input1_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(input2_shape.DimensionsCount(), N); + TFLITE_DCHECK_LE(output_shape.DimensionsCount(), N); + NdArrayDesc desc1; + NdArrayDesc desc2; + NdArrayDesc output_desc; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + CopyDimsToDesc(RuntimeShape::ExtendedShape(N, output_shape), &output_desc); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + auto sub_func = [&](int indexes[N]) { + output_data[SubscriptToIndex(output_desc, indexes)] = + ActivationFunctionWithMinMax( + input1_data[SubscriptToIndex(desc1, indexes)] - + input2_data[SubscriptToIndex(desc2, indexes)], + params.quantized_activation_min, params.quantized_activation_max); + }; + NDOpsHelper(output_desc, sub_func); +} + +// Element-wise Sub that can often be used for inner loop of broadcast sub as +// well as the non-broadcast sub. +inline void SubElementwise(int size, const ArithmeticParams& params, + const uint8_t* input1_data, + const uint8_t* input2_data, uint8_t* output_data) { + TFLITE_DCHECK_GT(params.input1_offset, -256); + TFLITE_DCHECK_GT(params.input2_offset, -256); + TFLITE_DCHECK_LT(params.input1_offset, 256); + TFLITE_DCHECK_LT(params.input2_offset, 256); + + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sub = scaled_input1_val - scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sub, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[i] = static_cast(clamped_output); + } +} + +// Element-wise add that can often be used for inner loop of broadcast add as +// well as the non-broadcast add. +inline void SubElementwise(int size, const ArithmeticParams& params, + const int8_t* input1_data, const int8_t* input2_data, + int8_t* output_data) { + const int32_t int8_max_value = std::numeric_limits::max(); + TFLITE_DCHECK_GE(params.input1_offset, -1 * int8_max_value); + TFLITE_DCHECK_GE(params.input2_offset, -1 * int8_max_value); + TFLITE_DCHECK_LE(params.input1_offset, int8_max_value); + TFLITE_DCHECK_LE(params.input2_offset, int8_max_value); + + for (int i = 0; i < size; ++i) { + const int32_t input1_val = params.input1_offset + input1_data[i]; + const int32_t input2_val = params.input2_offset + input2_data[i]; + const int32_t shifted_input1_val = input1_val * (1 << params.left_shift); + const int32_t shifted_input2_val = input2_val * (1 << params.left_shift); + const int32_t scaled_input1_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input1_val, params.input1_multiplier, params.input1_shift); + const int32_t scaled_input2_val = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + shifted_input2_val, params.input2_multiplier, params.input2_shift); + const int32_t raw_sub = scaled_input1_val - scaled_input2_val; + const int32_t raw_output = + MultiplyByQuantizedMultiplierSmallerThanOneExp( + raw_sub, params.output_multiplier, params.output_shift) + + params.output_offset; + const int32_t clamped_output = + std::min(params.quantized_activation_max, + std::max(params.quantized_activation_min, raw_output)); + output_data[i] = static_cast(clamped_output); + } +} + +inline void Sub(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const uint8_t* input1_data, + const RuntimeShape& input2_shape, const uint8_t* input2_data, + const RuntimeShape& output_shape, uint8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + TFLITE_DCHECK_GT(params.input1_offset, -256); + TFLITE_DCHECK_GT(params.input2_offset, -256); + TFLITE_DCHECK_LT(params.input1_offset, 256); + TFLITE_DCHECK_LT(params.input2_offset, 256); + SubElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +inline void Sub(const ArithmeticParams& params, + const RuntimeShape& input1_shape, const int8_t* input1_data, + const RuntimeShape& input2_shape, const int8_t* input2_data, + const RuntimeShape& output_shape, int8_t* output_data) { + TFLITE_DCHECK_LE(params.quantized_activation_min, + params.quantized_activation_max); + + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + + const int32_t int8_max_value = std::numeric_limits::max(); + TFLITE_DCHECK_GE(params.input1_offset, -1 * int8_max_value); + TFLITE_DCHECK_GE(params.input2_offset, -1 * int8_max_value); + TFLITE_DCHECK_LE(params.input1_offset, int8_max_value); + TFLITE_DCHECK_LE(params.input2_offset, int8_max_value); + SubElementwise(flat_size, params, input1_data, input2_data, output_data); +} + +template +void Sub(const ArithmeticParams& params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, + T* output_data) { + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(input1_shape, input2_shape, &desc1, + &desc2); + const RuntimeShape extended_output_shape = + RuntimeShape::ExtendedShape(4, output_shape); + + // In Tensorflow, the dimensions are canonically named (batch_number, row, + // col, channel), with extents (batches, height, width, depth), with the + // trailing dimension changing most rapidly (channels has the smallest stride, + // typically 1 element). + // + // In generated C code, we store arrays with the dimensions reversed. The + // first dimension has smallest stride. + // + // We name our variables by their Tensorflow convention, but generate C code + // nesting loops such that the innermost loop has the smallest stride for the + // best cache behavior. + for (int b = 0; b < extended_output_shape.Dims(0); ++b) { + for (int y = 0; y < extended_output_shape.Dims(1); ++y) { + for (int x = 0; x < extended_output_shape.Dims(2); ++x) { + for (int c = 0; c < extended_output_shape.Dims(3); ++c) { + output_data[Offset(extended_output_shape, b, y, x, c)] = + input1_data[SubscriptToIndex(desc1, b, y, x, c)] - + input2_data[SubscriptToIndex(desc2, b, y, x, c)]; + } + } + } + } +} + +inline void SetActivationMinMax(const ArithmeticParams& params, + int32_t* activation_min, + int32_t* activation_max) { + *activation_min = params.quantized_activation_min; + *activation_max = params.quantized_activation_max; +} + +inline void SetActivationMinMax(const ArithmeticParams& params, + float* activation_min, float* activation_max) { + *activation_min = params.float_activation_min; + *activation_max = params.float_activation_max; +} + +inline void SetActivationMinMax(const ArithmeticParams& params, + int64_t* activation_min, + int64_t* activation_max) { + *activation_min = params.int64_activation_min; + *activation_max = params.int64_activation_max; +} + +template +inline void SubWithActivation( + const ArithmeticParams& params, const RuntimeShape& input1_shape, + const T* input1_data, const RuntimeShape& input2_shape, + const T* input2_data, const RuntimeShape& output_shape, T* output_data) { + ruy::profiler::ScopeLabel label("SubWithActivation"); + const int flat_size = + MatchingElementsSize(input1_shape, input2_shape, output_shape); + T activation_min, activation_max; + SetActivationMinMax(params, &activation_min, &activation_max); + + for (int i = 0; i < flat_size; ++i) { + output_data[i] = ActivationFunctionWithMinMax( + input1_data[i] - input2_data[i], activation_min, activation_max); + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_SUB_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/tanh.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/tanh.h new file mode 100644 index 0000000..3a05c47 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/reference/tanh.h @@ -0,0 +1,129 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_TANH_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_TANH_H_ + +#include + +#include "fixedpoint/fixedpoint.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/op_macros.h" + +namespace tflite { +namespace reference_ops { + +inline void Tanh(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + float val = input_data[i]; + float result = std::tanh(val); + output_data[i] = result; + } +} + +// Convenience version that allows, for example, generated-code calls to be +// uniform between data types. +inline void Tanh(const TanhParams&, const RuntimeShape& input_shape, + const float* input_data, const RuntimeShape& output_shape, + float* output_data) { + // Drop params: not needed. + Tanh(input_shape, input_data, output_shape, output_data); +} + +inline void Tanh(const TanhParams& params, const RuntimeShape& input_shape, + const int16_t* input_data, const RuntimeShape& output_shape, + int16_t* output_data) { + const int input_left_shift = params.input_left_shift; + // Support for shifts is limited until we have a parameterized version of + // SaturatingRoundingMultiplyByPOT(). + TFLITE_DCHECK_GE(input_left_shift, 0); + TFLITE_DCHECK_LE(input_left_shift, 1); + + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + // F0 uses 0 integer bits, range [-1, 1]. + // This is the return type of math functions such as tanh, logistic, + // whose range is in [-1, 1]. + using F0 = gemmlowp::FixedPoint; + // F3 uses 3 integer bits, range [-8, 8], the input range expected here. + using F3 = gemmlowp::FixedPoint; + + if (input_left_shift == 0) { + for (int i = 0; i < flat_size; i++) { + F3 input = F3::FromRaw(input_data[i]); + F0 output = gemmlowp::tanh(input); + output_data[i] = output.raw(); + } + } else { + for (int i = 0; i < flat_size; i++) { + F3 input = F3::FromRaw( + gemmlowp::SaturatingRoundingMultiplyByPOT<1>(input_data[i])); + F0 output = gemmlowp::tanh(input); + output_data[i] = output.raw(); + } + } +} + +inline void Tanh(const TanhParams& params, const RuntimeShape& input_shape, + const uint8_t* input_data, const RuntimeShape& output_shape, + uint8_t* output_data) { + const int32_t input_zero_point = params.input_zero_point; + const int32_t input_range_radius = params.input_range_radius; + const int32_t input_multiplier = params.input_multiplier; + const int input_left_shift = params.input_left_shift; + const int32_t output_zero_point = 128; + const int flat_size = MatchingFlatSize(input_shape, output_shape); + + for (int i = 0; i < flat_size; i++) { + const uint8_t input_val_u8 = input_data[i]; + const int32_t input_val_centered = + static_cast(input_val_u8) - input_zero_point; + uint8_t output_val; + if (input_val_centered <= -input_range_radius) { + output_val = 0; + } else if (input_val_centered >= input_range_radius) { + output_val = 255; + } else { + const int32_t input_val_rescaled = + MultiplyByQuantizedMultiplierGreaterThanOne( + input_val_centered, input_multiplier, input_left_shift); + using FixedPoint4 = gemmlowp::FixedPoint; + using FixedPoint0 = gemmlowp::FixedPoint; + const FixedPoint4 input_val_f4 = FixedPoint4::FromRaw(input_val_rescaled); + const FixedPoint0 output_val_f0 = gemmlowp::tanh(input_val_f4); + // Convert from Q0.31 to Q24.7. + using gemmlowp::RoundingDivideByPOT; + int32_t output_val_s32 = RoundingDivideByPOT(output_val_f0.raw(), 24); + output_val_s32 += output_zero_point; + if (output_val_s32 == 256) { + output_val_s32 = 255; + } + // Reinterpret as Q0.7, encoded in uint8_t. + TFLITE_DCHECK_GE(output_val_s32, 0); + TFLITE_DCHECK_LE(output_val_s32, 255); + output_val = static_cast(output_val_s32); + } + output_data[i] = output_val; + } +} + +} // namespace reference_ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_REFERENCE_TANH_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/strided_slice_logic.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/strided_slice_logic.h new file mode 100644 index 0000000..d9b5acb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/strided_slice_logic.h @@ -0,0 +1,204 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_STRIDED_SLICE_LOGIC_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_STRIDED_SLICE_LOGIC_H_ + +#include +#include +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace strided_slice { + +// Use until std::clamp() is available from C++17. +inline int Clamp(const int v, const int lo, const int hi) { + TFLITE_DCHECK(!(hi < lo)); + if (hi < v) return hi; + if (v < lo) return lo; + return v; +} + +inline void StridedSlicePadIndices(tflite::StridedSliceParams* p, + int dim_count) { + // Add indices and mask bits to fully include extra dimensions + TFLITE_CHECK_LE(dim_count, 5); + TFLITE_CHECK_GE(dim_count, p->start_indices_count); + TFLITE_CHECK_EQ(p->start_indices_count, p->stop_indices_count); + TFLITE_CHECK_EQ(p->stop_indices_count, p->strides_count); + + const int pad_count = dim_count - p->start_indices_count; + + // Pad indices at start, so move arrays by pad_count. + for (int i = p->start_indices_count - 1; i >= 0; --i) { + p->strides[i + pad_count] = p->strides[i]; + p->start_indices[i + pad_count] = p->start_indices[i]; + p->stop_indices[i + pad_count] = p->stop_indices[i]; + } + for (int i = 0; i < pad_count; ++i) { + p->start_indices[i] = 0; + p->stop_indices[i] = 1; + p->strides[i] = 1; + } + + // Pad masks with 0s or 1s as required. + p->shrink_axis_mask <<= pad_count; + p->ellipsis_mask <<= pad_count; + p->new_axis_mask <<= pad_count; + p->begin_mask <<= pad_count; + p->end_mask <<= pad_count; + p->begin_mask |= (1 << pad_count) - 1; + p->end_mask |= (1 << pad_count) - 1; + + p->start_indices_count = dim_count; + p->stop_indices_count = dim_count; + p->strides_count = dim_count; +} + +// Return the index for the first element along that axis. This index will be a +// positive integer between [0, axis_size - 1] that can be used to index +// directly into the data. +inline int StartForAxis(const tflite::StridedSliceParams& params, + const RuntimeShape& input_shape, int axis) { + const auto begin_mask = params.begin_mask; + const auto* start_indices = params.start_indices; + const auto* strides = params.strides; + const int axis_size = input_shape.Dims(axis); + if (axis_size == 0) { + return 0; + } + // Begin with the specified index. + int start = start_indices[axis]; + + // begin_mask override + if (begin_mask & 1 << axis) { + if (strides[axis] > 0) { + // Forward iteration - use the first element. These values will get + // clamped below (Note: We could have set them to 0 and axis_size-1, but + // use lowest() and max() to maintain symmetry with StopForAxis()) + start = std::numeric_limits::lowest(); + } else { + // Backward iteration - use the last element. + start = std::numeric_limits::max(); + } + } + + // Handle negative indices + if (start < 0) { + start += axis_size; + } + + // Clamping + start = Clamp(start, 0, axis_size - 1); + + return start; +} + +// Return the "real" index for the end of iteration along that axis. This is an +// "end" in the traditional C sense, in that it points to one past the last +// element. ie. So if you were iterating through all elements of a 1D array of +// size 4, this function would return 4 as the stop, because it is one past the +// "real" indices of 0, 1, 2 & 3. +inline int StopForAxis(const tflite::StridedSliceParams& params, + const RuntimeShape& input_shape, int axis, + int start_for_axis) { + const auto end_mask = params.end_mask; + const auto shrink_axis_mask = params.shrink_axis_mask; + const auto* stop_indices = params.stop_indices; + const auto* strides = params.strides; + const int axis_size = input_shape.Dims(axis); + if (axis_size == 0) { + return 0; + } + + // Begin with the specified index + const bool shrink_axis = shrink_axis_mask & (1 << axis); + int stop = stop_indices[axis]; + + // When shrinking an axis, the end position does not matter (and can be + // incorrect when negative indexing is used, see Issue #19260). Always use + // start_for_axis + 1 to generate a length 1 slice, since start_for_axis has + // already been adjusted for negative indices. + if (shrink_axis) { + stop = start_for_axis + 1; + } + + // end_mask override + if (end_mask & (1 << axis)) { + if (strides[axis] > 0) { + // Forward iteration - use the last element. These values will get + // clamped below + stop = std::numeric_limits::max(); + } else { + // Backward iteration - use the first element. + stop = std::numeric_limits::lowest(); + } + } + + // Handle negative indices + if (stop < 0) { + stop += axis_size; + } + + // Clamping + // Because the end index points one past the last element, we need slightly + // different clamping ranges depending on the direction. + if (strides[axis] > 0) { + // Forward iteration + stop = Clamp(stop, 0, axis_size); + } else { + // Backward iteration + stop = Clamp(stop, -1, axis_size - 1); + } + + return stop; +} + +inline bool LoopCondition(int index, int stop, int stride) { + // True when we have reached the end of an axis and should loop. + return stride > 0 ? index >= stop : index <= stop; +} + +inline tflite::StridedSliceParams BuildStridedSliceParams( + int begin_mask, int end_mask, int shrink_axis_mask, + const std::vector& start_indices, const std::vector& stop_indices, + const std::vector& strides) { + tflite::StridedSliceParams op_params; + const int dims_count = start_indices.size(); + + op_params.start_indices_count = dims_count; + op_params.stop_indices_count = dims_count; + op_params.strides_count = dims_count; + for (int i = 0; i < dims_count; ++i) { + op_params.start_indices[i] = start_indices[i]; + op_params.stop_indices[i] = stop_indices[i]; + op_params.strides[i] = strides[i]; + } + + op_params.begin_mask = begin_mask; + op_params.ellipsis_mask = 0; + op_params.end_mask = end_mask; + op_params.new_axis_mask = 0; + op_params.shrink_axis_mask = shrink_axis_mask; + + return op_params; +} + +} // namespace strided_slice + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_STRIDED_SLICE_LOGIC_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor.h new file mode 100644 index 0000000..905552f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor.h @@ -0,0 +1,147 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_ + +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/string_util.h" + +namespace tflite { + +inline RuntimeShape GetTensorShape(std::vector data) { + return RuntimeShape(data.size(), data.data()); +} + +// A list of tensors in a format that can be used by kernels like split and +// concatenation. +template +class VectorOfTensors { + public: + // Build with the tensors in 'tensor_list'. + VectorOfTensors(const TfLiteContext& context, + const TfLiteIntArray& tensor_list) { + int num_tensors = tensor_list.size; + + all_data_.reserve(num_tensors); + all_shape_.reserve(num_tensors); + all_shape_ptr_.reserve(num_tensors); + + for (int i = 0; i < num_tensors; ++i) { + TfLiteTensor* t = &context.tensors[tensor_list.data[i]]; + all_data_.push_back(GetTensorData(t)); + all_shape_.push_back(GetTensorShape(t)); + } + + // Taking the pointer from inside a std::vector is only OK if the vector is + // never modified, so we populate all_shape in the previous loop and then we + // are free to grab iterators here. + for (int i = 0; i < num_tensors; ++i) { + all_shape_ptr_.push_back(&all_shape_[i]); + } + } + // Return a pointer to the data pointers of all tensors in the list. For + // example: + // float* const* f = v.data(); + // f[0][1] is the second element of the first tensor. + T* const* data() const { return all_data_.data(); } + + // Return a pointer the shape pointers of all tensors in the list. For + // example: + // const RuntimeShape* const* d = v.dims(); + // dims[1] are the dimensions of the second tensor in the list. + const RuntimeShape* const* shapes() const { return all_shape_ptr_.data(); } + + private: + std::vector all_data_; + std::vector all_shape_; + std::vector all_shape_ptr_; +}; + +// A list of quantized tensors in a format that can be used by kernels like +// split and concatenation. +class VectorOfQuantizedTensors : public VectorOfTensors { + public: + // Build with the tensors in 'tensor_list'. + VectorOfQuantizedTensors(const TfLiteContext& context, + const TfLiteIntArray& tensor_list) + : VectorOfTensors(context, tensor_list) { + for (int i = 0; i < tensor_list.size; ++i) { + TfLiteTensor* t = &context.tensors[tensor_list.data[i]]; + zero_point_.push_back(t->params.zero_point); + scale_.push_back(t->params.scale); + } + } + + const float* scale() const { return scale_.data(); } + const int32_t* zero_point() const { return zero_point_.data(); } + + private: + std::vector zero_point_; + std::vector scale_; +}; + +// Writes randomly accessed values from `input` sequentially into `output`. +template +class SequentialTensorWriter { + public: + SequentialTensorWriter(const TfLiteTensor* input, TfLiteTensor* output) { + input_data_ = GetTensorData(input); + output_ptr_ = GetTensorData(output); + } + SequentialTensorWriter(const T* input_data, T* output_data) + : input_data_(input_data), output_ptr_(output_data) {} + + void Write(int position) { *output_ptr_++ = input_data_[position]; } + void WriteN(int position, int len) { + memcpy(output_ptr_, &input_data_[position], sizeof(T) * len); + output_ptr_ += len; + } + + private: + const T* input_data_; + T* output_ptr_; +}; + +// String ops are not yet supported on platforms w/ static memory. +#ifndef TF_LITE_STATIC_MEMORY +template <> +class SequentialTensorWriter { + public: + SequentialTensorWriter(const TfLiteTensor* input, TfLiteTensor* output) + : input_(input), output_(output) {} + ~SequentialTensorWriter() { buffer_.WriteToTensor(output_, nullptr); } + + void Write(int position) { this->WriteN(position, 1); } + void WriteN(int position, int len) { + for (int i = 0; i < len; i++) { + buffer_.AddString(GetString(input_, position + i)); + } + } + + private: + const TfLiteTensor* input_; + TfLiteTensor* output_; + DynamicBuffer buffer_; +}; +#endif // TF_LITE_STATIC_MEMORY + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor_ctypes.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor_ctypes.h new file mode 100644 index 0000000..f1d3e17 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/tensor_ctypes.h @@ -0,0 +1,47 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_CTYPES_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_CTYPES_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +template +inline T* GetTensorData(TfLiteTensor* tensor) { + return tensor != nullptr ? reinterpret_cast(tensor->data.raw) : nullptr; +} + +template +inline const T* GetTensorData(const TfLiteTensor* tensor) { + return tensor != nullptr ? reinterpret_cast(tensor->data.raw) + : nullptr; +} + +inline RuntimeShape GetTensorShape(const TfLiteTensor* tensor) { + if (tensor == nullptr) { + return RuntimeShape(); + } + + TfLiteIntArray* dims = tensor->dims; + const int dims_size = dims->size; + const int32_t* dims_data = reinterpret_cast(dims->data); + return RuntimeShape(dims_size, dims_data); +} + +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_CTYPES_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/internal/types.h b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/types.h new file mode 100644 index 0000000..9db742d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/internal/types.h @@ -0,0 +1,1153 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_TYPES_H_ +#define TENSORFLOW_LITE_KERNELS_INTERNAL_TYPES_H_ + +#include +#include +#include +#include + +#include "tensorflow/lite/kernels/internal/compatibility.h" + +namespace tflite { + +enum class FusedActivationFunctionType : uint8_t { + kNone, + kRelu6, + kRelu1, + kRelu +}; +enum class PaddingType : uint8_t { kNone, kSame, kValid }; + +struct PaddingValues { + int16_t width; + int16_t height; + // offset is used for calculating "remaining" padding, for example, `width` + // is 1 and `width_offset` is 1, so padding_left is 1 while padding_right is + // 1 + 1 = 2. + int16_t width_offset; + // Same as width_offset except it's over the height dimension. + int16_t height_offset; +}; + +// This enumeration allows for non-default formats for the weights array +// of a fully-connected operator, allowing the use of special optimized +// runtime paths. +enum class FullyConnectedWeightsFormat : uint8_t { + // Default format (flat 2D layout, the inner contiguous dimension + // is input_depth, the outer non-contiguous dimension is output_depth) + kDefault, + // Summary: optimized layout for fast CPU runtime implementation, + // aimed specifically at ARM CPUs at the moment, and specialized for + // 8-bit quantized layers. + // + // The use case we're concerned with here is: 8-bit quantization, + // large weights matrix that doesn't fit in cache (e.g. 4096x2048 in + // a key application that drove this), very small batch size (e.g. 1 -- 4). + // + // Even with 8-bit quantization of weights, the performance of memory + // accesses to the weights can become the dominant issue when + // the batch size is small, so each weight value is used in only a few + // arithmetic ops, i.e. the fully-connected node has a low arithmetic + // intensity. The specific issues that arise are of three kinds: + // (1) One may, ideally, max out DRAM bandwidth, i.e. be truly memory + // bound. That's the "good" issue to run into. + // (2) One may run into sub-optimal pre-fetching: the data hasn't been + // prefetched into the cache by the time we need it. + // (3) One may run into cache aliasing: multiple values that are + // pre-fetched, alias each other in the L1 cache (which typically + // has only 4-way set associativity in ARM CPUs) and thus evict + // each other before we get to using them. + // + // The point of this shuffling is to avoid issues (2) and (3) so that + // we get as fast as possible given only the hard constraint (1). + // This is achieved by turning the difficulty into a solution: the + // difficulty, that each value loaded from memory is used only in + // one kernel iteration, making this operation memory-intensive, hints at + // the solution, of shuffling the weights so that they are stored in the + // exact order as the kernel needs to load them, so that the memory + // accesses made by the kernel are trivial. This solves (2) because the + // trivial memory access pattern allows the CPU's automatic prefetching + // to perform very well (no need even for preload instructions), and this + // solves (3) because the values being loaded concurrently are now + // contiguous in the address space, thus don't alias each other in the cache. + // + // On ARM, we typically want our kernel to process a 4x16 block of weights + // at a time, because: + // - 16 is the number of bytes in a NEON register. + // - 4 is how many rows we need to handle concurrently in the kernel in + // order to have sufficient mutual independence of instructions to + // maximize arithmetic throughput. + // + // Finally, the 'Int8' part in the name refers to the fact that this + // weights format has each weights value encoded as a signed int8_t value, + // even if the data type of the weights buffer is uint8_t. This is intended + // to save runtime kernels the effort to have to XOR the top bit of these + // bytes before using them in signed arithmetic, see this file for more + // explanations on the 'signed int8_t trick' in matrix multiplication kernels: + // + // tensorflow/lite/toco/graph_transformations/ensure_uint8_weights_safe_for_fast_int8_kernels.cc + // + kShuffled4x16Int8, +}; + +// Quantization parameters, determining the mapping of quantized values +// to real values (i.e. determining how quantized values are mathematically +// interpreted). +// +// The correspondence is as follows: +// +// real_value = scale * (quantized_value - zero_point); +// +// In other words, zero_point designates which quantized value corresponds to +// the real 0 value, and scale designates the difference between the real values +// corresponding to consecutive quantized values differing by 1. +struct QuantizationParams { + int32_t zero_point = 0; + double scale = 0.0; +}; + +inline bool operator==(const QuantizationParams& qp1, + const QuantizationParams& qp2) { + return qp1.zero_point == qp2.zero_point && qp1.scale == qp2.scale; +} + +template +struct Dims { + int sizes[N]; + int strides[N]; +}; + +class RuntimeShape { + public: + // Shapes with dimensions up to 5 are stored directly in the structure, while + // larger shapes are separately allocated. + static constexpr int kMaxSmallSize = 5; + + RuntimeShape& operator=(RuntimeShape const&) = delete; + + RuntimeShape() : size_(0) {} + + explicit RuntimeShape(int dimensions_count) : size_(dimensions_count) { + if (dimensions_count > kMaxSmallSize) { +#ifdef TF_LITE_STATIC_MEMORY + TFLITE_CHECK(false && "No shape resizing supported on this platform"); +#else // TF_LITE_STATIC_MEMORY + dims_pointer_ = new int32_t[dimensions_count]; +#endif // TF_LITE_STATIC_MEMORY + } + } + + RuntimeShape(int shape_size, int32_t value) : size_(0) { + Resize(shape_size); + for (int i = 0; i < shape_size; ++i) { + SetDim(i, value); + } + } + + RuntimeShape(int dimensions_count, const int32_t* dims_data) : size_(0) { + ReplaceWith(dimensions_count, dims_data); + } + + RuntimeShape(const std::initializer_list init_list) : size_(0) { + BuildFrom(init_list); + } + + // Avoid using this constructor. We should be able to delete it when C++17 + // rolls out. + RuntimeShape(RuntimeShape const& other) : size_(other.DimensionsCount()) { + if (size_ > kMaxSmallSize) { + dims_pointer_ = new int32_t[size_]; + } + std::memcpy(DimsData(), other.DimsData(), sizeof(int32_t) * size_); + } + + bool operator==(const RuntimeShape& comp) const { + return this->size_ == comp.size_ && + std::memcmp(DimsData(), comp.DimsData(), size_ * sizeof(int32_t)) == + 0; + } + + ~RuntimeShape() { + if (size_ > kMaxSmallSize) { +#ifdef TF_LITE_STATIC_MEMORY + TFLITE_CHECK(false && "No shape resizing supported on this platform"); +#else // TF_LITE_STATIC_MEMORY + delete[] dims_pointer_; +#endif // TF_LITE_STATIC_MEMORY + } + } + + inline int32_t DimensionsCount() const { return size_; } + inline int32_t Dims(int i) const { + TFLITE_DCHECK_GE(i, 0); + TFLITE_DCHECK_LT(i, size_); + return size_ > kMaxSmallSize ? dims_pointer_[i] : dims_[i]; + } + inline void SetDim(int i, int32_t val) { + TFLITE_DCHECK_GE(i, 0); + TFLITE_DCHECK_LT(i, size_); + if (size_ > kMaxSmallSize) { + dims_pointer_[i] = val; + } else { + dims_[i] = val; + } + } + + inline int32_t* DimsData() { + return size_ > kMaxSmallSize ? dims_pointer_ : dims_; + } + inline const int32_t* DimsData() const { + return size_ > kMaxSmallSize ? dims_pointer_ : dims_; + } + // The caller must ensure that the shape is no bigger than 5-D. + inline const int32_t* DimsDataUpTo5D() const { return dims_; } + + inline void Resize(int dimensions_count) { + if (size_ > kMaxSmallSize) { +#ifdef TF_LITE_STATIC_MEMORY + TFLITE_CHECK(false && "No shape resizing supported on this platform"); +#else // TF_LITE_STATIC_MEMORY + delete[] dims_pointer_; +#endif // TF_LITE_STATIC_MEMORY + } + size_ = dimensions_count; + if (dimensions_count > kMaxSmallSize) { +#ifdef TF_LITE_STATIC_MEMORY + TFLITE_CHECK(false && "No shape resizing supported on this platform"); +#else // TF_LITE_STATIC_MEMORY + dims_pointer_ = new int32_t[dimensions_count]; +#endif // TF_LITE_STATIC_MEMORY + } + } + + inline void ReplaceWith(int dimensions_count, const int32_t* dims_data) { + Resize(dimensions_count); + int32_t* dst_dims = DimsData(); + std::memcpy(dst_dims, dims_data, dimensions_count * sizeof(int32_t)); + } + + template + inline void BuildFrom(const T& src_iterable) { + const int dimensions_count = + std::distance(src_iterable.begin(), src_iterable.end()); + Resize(dimensions_count); + int32_t* data = DimsData(); + for (auto it : src_iterable) { + *data = it; + ++data; + } + } + + // This will probably be factored out. Old code made substantial use of 4-D + // shapes, and so this function is used to extend smaller shapes. Note that + // (a) as Dims<4>-dependent code is eliminated, the reliance on this should be + // reduced, and (b) some kernels are stricly 4-D, but then the shapes of their + // inputs should already be 4-D, so this function should not be needed. + inline static RuntimeShape ExtendedShape(int new_shape_size, + const RuntimeShape& shape) { + return RuntimeShape(new_shape_size, shape, 1); + } + + inline void BuildFrom(const std::initializer_list init_list) { + BuildFrom>(init_list); + } + + // Returns the total count of elements, that is the size when flattened into a + // vector. + inline int FlatSize() const { + int buffer_size = 1; + const int* dims_data = reinterpret_cast(DimsData()); + for (int i = 0; i < size_; i++) { + buffer_size *= dims_data[i]; + } + return buffer_size; + } + + bool operator!=(const RuntimeShape& comp) const { return !((*this) == comp); } + + private: + // For use only by ExtendedShape(), written to guarantee (return-value) copy + // elision in C++17. + // This creates a shape padded to the desired size with the specified value. + RuntimeShape(int new_shape_size, const RuntimeShape& shape, int pad_value) + : size_(0) { + // If the following check fails, it is likely because a 4D-only kernel is + // being used with an array of larger dimension count. + TFLITE_CHECK_GE(new_shape_size, shape.DimensionsCount()); + Resize(new_shape_size); + const int size_increase = new_shape_size - shape.DimensionsCount(); + for (int i = 0; i < size_increase; ++i) { + SetDim(i, pad_value); + } + std::memcpy(DimsData() + size_increase, shape.DimsData(), + sizeof(int32_t) * shape.DimensionsCount()); + } + + int32_t size_; + union { + int32_t dims_[kMaxSmallSize]; + int32_t* dims_pointer_; + }; +}; + +// Converts inference-style shape to legacy tflite::Dims<4>. +inline tflite::Dims<4> ToRuntimeDims(const tflite::RuntimeShape& array_shape) { + tflite::Dims<4> result; + const int dimensions_count = array_shape.DimensionsCount(); + TFLITE_CHECK_LE(dimensions_count, 4); + int cum_prod = 1; + for (int i = 0; i < 4; i++) { + const int new_dim = + (i < dimensions_count) ? array_shape.Dims(dimensions_count - 1 - i) : 1; + result.sizes[i] = new_dim; + result.strides[i] = cum_prod; + cum_prod *= new_dim; + } + return result; +} + +// TODO(b/80418076): Move to legacy ops file, update invocations. +inline RuntimeShape DimsToShape(const tflite::Dims<4>& dims) { + return RuntimeShape( + {dims.sizes[3], dims.sizes[2], dims.sizes[1], dims.sizes[0]}); +} + +// Gets next index to iterate through a multidimensional array. +inline bool NextIndex(const int num_dims, const int* dims, int* current) { + if (num_dims == 0) { + return false; + } + TFLITE_DCHECK(dims != nullptr); + TFLITE_DCHECK(current != nullptr); + int carry = 1; + for (int idx = num_dims - 1; idx >= 0; --idx) { + int current_val = current[idx] + carry; + TFLITE_DCHECK_GE(dims[idx], current_val); + if (dims[idx] == current_val) { + current[idx] = 0; + } else { + current[idx] = current_val; + carry = 0; + break; + } + } + return (carry == 0); +} + +// Gets offset of index if reducing on axis. When reducing, the flattened offset +// will not change, if the input index changes on the given axis. For example, +// if you have a 3D tensor and you are reducing to 2D by eliminating axis 0, +// then index (0, 1, 2) and index (1, 1, 2) will map to the same flattened +// offset. +// TODO(kanlig): uses Dims to represent dimensions. +inline size_t ReducedOutputOffset(const int num_dims, const int* dims, + const int* index, const int num_axis, + const int* axis) { + if (num_dims == 0) { + return 0; + } + TFLITE_DCHECK(dims != nullptr); + TFLITE_DCHECK(index != nullptr); + size_t offset = 0; + for (int idx = 0; idx < num_dims; ++idx) { + // if we need to skip this axis + bool is_axis = false; + if (axis != nullptr) { + for (int axis_idx = 0; axis_idx < num_axis; ++axis_idx) { + if (idx == axis[axis_idx]) { + is_axis = true; + break; + } + } + } + if (!is_axis) { + offset = offset * static_cast(dims[idx]) + + static_cast(index[idx]); + } + } + return offset; +} + +inline int Offset(const RuntimeShape& shape, int i0, int i1, int i2, int i3) { + TFLITE_DCHECK_EQ(shape.DimensionsCount(), 4); + const int* dims_data = reinterpret_cast(shape.DimsDataUpTo5D()); + TFLITE_DCHECK(i0 >= 0 && i0 < dims_data[0]); + TFLITE_DCHECK(i1 >= 0 && i1 < dims_data[1]); + TFLITE_DCHECK(i2 >= 0 && i2 < dims_data[2]); + TFLITE_DCHECK(i3 >= 0 && i3 < dims_data[3]); + return ((i0 * dims_data[1] + i1) * dims_data[2] + i2) * dims_data[3] + i3; +} + +inline int Offset(const Dims<4>& dims, int i0, int i1, int i2, int i3) { + TFLITE_DCHECK(i0 >= 0 && i0 < dims.sizes[0]); + TFLITE_DCHECK(i1 >= 0 && i1 < dims.sizes[1]); + TFLITE_DCHECK(i2 >= 0 && i2 < dims.sizes[2]); + TFLITE_DCHECK(i3 >= 0 && i3 < dims.sizes[3]); + return i0 * dims.strides[0] + i1 * dims.strides[1] + i2 * dims.strides[2] + + i3 * dims.strides[3]; +} + +inline int Offset(const Dims<4>& dims, int* index) { + return Offset(dims, index[0], index[1], index[2], index[3]); +} + +inline int Offset(const RuntimeShape& shape, int* index) { + return Offset(shape, index[0], index[1], index[2], index[3]); +} + +// Get array size, DCHECKing that the dim index is in range. +// +// Note that this will be phased out with Dims<4>, since RuntimeShape::Dims() +// already performs this check. +template +int ArraySize(const Dims& array, int index) { + TFLITE_DCHECK(index >= 0 && index < N); + return array.sizes[index]; +} + +// Get common array size, DCHECKing that they all agree. +template +int MatchingArraySize(const ArrayType1& array1, int index1, + const ArrayType2& array2, int index2) { + TFLITE_DCHECK_EQ(ArraySize(array1, index1), ArraySize(array2, index2)); + return ArraySize(array1, index1); +} + +template +int MatchingArraySize(const ArrayType1& array1, int index1, + const ArrayType2& array2, int index2, Args... args) { + TFLITE_DCHECK_EQ(ArraySize(array1, index1), ArraySize(array2, index2)); + return MatchingArraySize(array1, index1, args...); +} + +// Get common shape dim, DCHECKing that they all agree. +inline int MatchingDim(const RuntimeShape& shape1, int index1, + const RuntimeShape& shape2, int index2) { + TFLITE_DCHECK_EQ(shape1.Dims(index1), shape2.Dims(index2)); + return shape1.Dims(index1); +} + +template +int MatchingDim(const RuntimeShape& shape1, int index1, + const RuntimeShape& shape2, int index2, Args... args) { + TFLITE_DCHECK_EQ(shape1.Dims(index1), shape2.Dims(index2)); + return MatchingDim(shape1, index1, args...); +} + +// Will be phased out with Dims<4>, replaced by RuntimeShape::FlatSize(). +template +inline int FlatSize(const Dims& dims) { + int flat_size = 1; + for (int i = 0; i < N; ++i) { + flat_size *= dims.sizes[i]; + } + return flat_size; +} + +TFLITE_DEPRECATED("Prefer FlatSize.") +inline int RequiredBufferSizeForDims(const Dims<4>& dims) { + return FlatSize(dims); +} + +inline int MatchingElementsSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0) { + const int size_1 = shape.FlatSize(); + const int size_2 = check_shape_0.FlatSize(); + TFLITE_CHECK_EQ(size_1, size_2); + return size_1; +} + +inline int MatchingElementsSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1) { + const int size_1 = shape.FlatSize(); + const int size_2 = check_shape_0.FlatSize(); + const int size_3 = check_shape_1.FlatSize(); + TFLITE_CHECK_EQ(size_1, size_2); + TFLITE_CHECK_EQ(size_2, size_3); + return size_1; +} + +// Flat size calculation, checking that dimensions match with one or more other +// arrays. +inline int MatchingFlatSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0) { + TFLITE_DCHECK_EQ(shape.DimensionsCount(), check_shape_0.DimensionsCount()); + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + return shape.FlatSize(); +} + +inline int MatchingFlatSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1) { + TFLITE_DCHECK_EQ(shape.DimensionsCount(), check_shape_0.DimensionsCount()); + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + return MatchingFlatSize(shape, check_shape_1); +} + +inline int MatchingFlatSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1, + const RuntimeShape& check_shape_2) { + TFLITE_DCHECK_EQ(shape.DimensionsCount(), check_shape_0.DimensionsCount()); + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + return MatchingFlatSize(shape, check_shape_1, check_shape_2); +} + +inline int MatchingFlatSize(const RuntimeShape& shape, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1, + const RuntimeShape& check_shape_2, + const RuntimeShape& check_shape_3) { + TFLITE_DCHECK_EQ(shape.DimensionsCount(), check_shape_0.DimensionsCount()); + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + return MatchingFlatSize(shape, check_shape_1, check_shape_2, check_shape_3); +} + +// Flat size calculation, checking that dimensions match with one or more other +// arrays. +template +inline int MatchingFlatSize(const Dims& dims, const Dims& check_dims_0) { + for (int i = 0; i < N; ++i) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + return FlatSize(dims); +} + +template +inline int MatchingFlatSize(const Dims& dims, const Dims& check_dims_0, + const Dims& check_dims_1) { + for (int i = 0; i < N; ++i) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + return MatchingFlatSize(dims, check_dims_1); +} + +template +inline int MatchingFlatSize(const Dims& dims, const Dims& check_dims_0, + const Dims& check_dims_1, + const Dims& check_dims_2) { + for (int i = 0; i < N; ++i) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + return MatchingFlatSize(dims, check_dims_1, check_dims_2); +} + +template +inline int MatchingFlatSize(const Dims& dims, const Dims& check_dims_0, + const Dims& check_dims_1, + const Dims& check_dims_2, + const Dims& check_dims_3) { + for (int i = 0; i < N; ++i) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + return MatchingFlatSize(dims, check_dims_1, check_dims_2, check_dims_3); +} + +// Data is required to be contiguous, and so many operators can use either the +// full array flat size or the flat size with one dimension skipped (commonly +// the depth). +template +inline int FlatSizeSkipDim(const Dims& dims, int skip_dim) { + TFLITE_DCHECK(skip_dim >= 0 && skip_dim < N); + int flat_size = 1; + for (int i = 0; i < N; ++i) { + flat_size *= (i == skip_dim) ? 1 : dims.sizes[i]; + } + return flat_size; +} + +// A combination of MatchingFlatSize() and FlatSizeSkipDim(). +template +inline int MatchingFlatSizeSkipDim(const Dims& dims, int skip_dim, + const Dims& check_dims_0) { + for (int i = 0; i < N; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + } + return FlatSizeSkipDim(dims, skip_dim); +} + +template +inline int MatchingFlatSizeSkipDim(const Dims& dims, int skip_dim, + const Dims& check_dims_0, + const Dims& check_dims_1) { + for (int i = 0; i < N; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + } + return MatchingFlatSizeSkipDim(dims, skip_dim, check_dims_1); +} + +template +inline int MatchingFlatSizeSkipDim(const Dims& dims, int skip_dim, + const Dims& check_dims_0, + const Dims& check_dims_1, + const Dims& check_dims_2) { + for (int i = 0; i < N; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + } + return MatchingFlatSizeSkipDim(dims, skip_dim, check_dims_1, check_dims_2); +} + +template +inline int MatchingFlatSizeSkipDim(const Dims& dims, int skip_dim, + const Dims& check_dims_0, + const Dims& check_dims_1, + const Dims& check_dims_2, + const Dims& check_dims_3) { + for (int i = 0; i < N; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(ArraySize(dims, i), ArraySize(check_dims_0, i)); + } + } + return MatchingFlatSizeSkipDim(dims, skip_dim, check_dims_1, check_dims_2, + check_dims_3); +} + +// Data is required to be contiguous, and so many operators can use either the +// full array flat size or the flat size with one dimension skipped (commonly +// the depth). +inline int FlatSizeSkipDim(const RuntimeShape& shape, int skip_dim) { + const int dims_count = shape.DimensionsCount(); + TFLITE_DCHECK(skip_dim >= 0 && skip_dim < dims_count); + const auto* dims_data = shape.DimsData(); + int flat_size = 1; + for (int i = 0; i < dims_count; ++i) { + flat_size *= (i == skip_dim) ? 1 : dims_data[i]; + } + return flat_size; +} + +// A combination of MatchingFlatSize() and FlatSizeSkipDim(). +inline int MatchingFlatSizeSkipDim(const RuntimeShape& shape, int skip_dim, + const RuntimeShape& check_shape_0) { + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + } + return FlatSizeSkipDim(shape, skip_dim); +} + +inline int MatchingFlatSizeSkipDim(const RuntimeShape& shape, int skip_dim, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1) { + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + } + return MatchingFlatSizeSkipDim(shape, skip_dim, check_shape_1); +} + +inline int MatchingFlatSizeSkipDim(const RuntimeShape& shape, int skip_dim, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1, + const RuntimeShape& check_shape_2) { + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + } + return MatchingFlatSizeSkipDim(shape, skip_dim, check_shape_1, check_shape_2); +} + +inline int MatchingFlatSizeSkipDim(const RuntimeShape& shape, int skip_dim, + const RuntimeShape& check_shape_0, + const RuntimeShape& check_shape_1, + const RuntimeShape& check_shape_2, + const RuntimeShape& check_shape_3) { + const int dims_count = shape.DimensionsCount(); + for (int i = 0; i < dims_count; ++i) { + if (i != skip_dim) { + TFLITE_DCHECK_EQ(shape.Dims(i), check_shape_0.Dims(i)); + } + } + return MatchingFlatSizeSkipDim(shape, skip_dim, check_shape_1, check_shape_2, + check_shape_3); +} + +template +bool IsPackedWithoutStrides(const Dims& dims) { + int expected_stride = 1; + for (int d = 0; d < N; d++) { + if (dims.strides[d] != expected_stride) return false; + expected_stride *= dims.sizes[d]; + } + return true; +} + +template +void ComputeStrides(Dims* dims) { + dims->strides[0] = 1; + for (int d = 1; d < N; d++) { + dims->strides[d] = dims->strides[d - 1] * dims->sizes[d - 1]; + } +} + +enum class BroadcastableOpCategory : uint8_t { + kNone, + kNonBroadcast, // Matching input shapes. + kFirstInputBroadcastsFast, // Fivefold nested loops. + kSecondInputBroadcastsFast, // Fivefold nested loops. + kGenericBroadcast, // Fall-back. +}; + +struct MinMax { + float min; + float max; +}; +static_assert(sizeof(MinMax) == 8, ""); + +struct ActivationParams { + FusedActivationFunctionType activation_type; + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; +}; + +struct ReluParams : public ActivationParams { + int32_t input_offset; + int32_t output_offset; + int32_t output_multiplier; + int output_shift; +}; + +// Styles of resizing op usages. For example, kImageStyle can be used with a Pad +// op for pattern-specific optimization. +enum class ResizingCategory : uint8_t { + kNone, + kImageStyle, // 4D, operating on inner dimensions, say {0, a, b, 0}. + kGenericResize, +}; + +// For Add, Sub, Mul ops. +struct ArithmeticParams { + // Shape dependent / common to data / op types. + BroadcastableOpCategory broadcast_category; + // uint8_t inference params. + int32_t input1_offset; + int32_t input2_offset; + int32_t output_offset; + int32_t output_multiplier; + int output_shift; + // Add / Sub, not Mul, uint8_t inference params. + int left_shift; + int32_t input1_multiplier; + int input1_shift; + int32_t input2_multiplier; + int input2_shift; + + // TODO(b/158622529): Union the following activation params. + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; + // float activation params. + float float_activation_min; + float float_activation_max; + // int64_t activation params. + int64_t int64_activation_min; + int64_t int64_activation_max; + + // Processed output dimensions. + // Let input "a" be the one that broadcasts in the faster-changing dimension. + // Then, after coalescing, for shapes {a0, a1, a2, a3, a4} and + // {b0, b1, b2, b3, b4}, + // broadcast_shape[4] = b0 = a0. + // broadcast_shape[3] = b1; a1 = 1. + // broadcast_shape[2] = b2 = a2. + // broadcast_shape[1] = a3; b3 = 1. + // broadcast_shape[0] = b4 = a4. + int broadcast_shape[5]; +}; + +struct ConcatenationParams { + int8_t axis; + const int32_t* input_zeropoint; + const float* input_scale; + uint16_t inputs_count; + int32_t output_zeropoint; + float output_scale; +}; + +struct ComparisonParams { + // uint8_t inference params. + int left_shift; + int32_t input1_offset; + int32_t input1_multiplier; + int input1_shift; + int32_t input2_offset; + int32_t input2_multiplier; + int input2_shift; + // Shape dependent / common to inference types. + bool is_broadcast; +}; + +struct ConvParams { + PaddingType padding_type; + PaddingValues padding_values; + // TODO(starka): This was just "stride", so check that width+height is OK. + int16_t stride_width; + int16_t stride_height; + int16_t dilation_width_factor; + int16_t dilation_height_factor; + // uint8_t inference params. + // TODO(b/65838351): Use smaller types if appropriate. + int32_t input_offset; + int32_t weights_offset; + int32_t output_offset; + int32_t output_multiplier; + int output_shift; + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; + // float activation params. + float float_activation_min; + float float_activation_max; +}; + +struct DepthToSpaceParams { + int32_t block_size; +}; + +struct DepthwiseParams { + PaddingType padding_type; + PaddingValues padding_values; + int16_t stride_width; + int16_t stride_height; + int16_t dilation_width_factor; + int16_t dilation_height_factor; + int16_t depth_multiplier; + // uint8_t inference params. + // TODO(b/65838351): Use smaller types if appropriate. + int32_t input_offset; + int32_t weights_offset; + int32_t output_offset; + int32_t output_multiplier; + int output_shift; + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; + // float activation params. + float float_activation_min; + float float_activation_max; + const int32_t* output_multiplier_per_channel; + const int32_t* output_shift_per_channel; +}; + +struct DequantizationParams { + double scale; + int32_t zero_point; +}; + +struct PerChannelDequantizationParams { + const float* scale; + const int32_t* zero_point; + int32_t quantized_dimension; +}; + +struct FakeQuantParams { + MinMax minmax; + int32_t num_bits; +}; + +struct FullyConnectedParams { + // uint8_t inference params. + // TODO(b/65838351): Use smaller types if appropriate. + int32_t input_offset; + int32_t weights_offset; + int32_t output_offset; + int32_t output_multiplier; + int output_shift; + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; + // float activation params. + float float_activation_min; + float float_activation_max; + // Mark the operands as cacheable if they are unchanging, e.g. weights. + bool lhs_cacheable; + bool rhs_cacheable; + FullyConnectedWeightsFormat weights_format; +}; + +struct GatherParams { + int16_t axis; +}; + +struct L2NormalizationParams { + // uint8_t inference params. + int32_t input_zero_point; +}; + +struct LocalResponseNormalizationParams { + int32_t range; + double bias; + double alpha; + double beta; +}; + +struct HardSwishParams { + // zero_point of the input activations. + int16_t input_zero_point; + // zero_point of the output activations. + int16_t output_zero_point; + // 16bit fixed-point component of the multiplier to apply to go from the + // "high-res input scale", which is the input scale multiplied by 2^7, to the + // "relu-ish scale", which 3.0/32768. + // See the implementation of HardSwishPrepare. + int16_t reluish_multiplier_fixedpoint_int16; + // exponent/bit-shift component of the aforementioned multiplier. + int reluish_multiplier_exponent; + // 16bit fixed-point component of the multiplier to apply to go from the + // "high-res input scale", which is the input scale multiplied by 2^7, to the + // output scale. + // See the implementation of HardSwishPrepare. + int16_t output_multiplier_fixedpoint_int16; + // exponent/bit-shift component of the aforementioned multiplier. + int output_multiplier_exponent; +}; + +struct LogisticParams { + // uint8_t inference params. + int32_t input_zero_point; + int32_t input_range_radius; + int32_t input_multiplier; + int input_left_shift; +}; + +struct LstmCellParams { + int32_t weights_zero_point; + int32_t accum_multiplier; + int accum_shift; + int state_integer_bits; +}; + +struct MeanParams { + int8_t axis_count; + int16_t axis[4]; +}; + +struct PackParams { + int8_t axis; + const int32_t* input_zeropoint; + const float* input_scale; + uint16_t inputs_count; + int32_t output_zeropoint; + float output_scale; +}; + +struct PadParams { + int8_t left_padding_count; + int32_t left_padding[4]; + int8_t right_padding_count; + int32_t right_padding[4]; + ResizingCategory resizing_category; +}; + +struct PreluParams { + int32_t input_offset; + int32_t alpha_offset; + int32_t output_offset; + int32_t output_multiplier_1; + int output_shift_1; + int32_t output_multiplier_2; + int output_shift_2; +}; + +struct PoolParams { + FusedActivationFunctionType activation; + PaddingType padding_type; + PaddingValues padding_values; + int stride_height; + int stride_width; + int filter_height; + int filter_width; + // uint8_t, etc, activation params. + int32_t quantized_activation_min; + int32_t quantized_activation_max; + // float activation params. + float float_activation_min; + float float_activation_max; +}; + +struct ReshapeParams { + int8_t shape_count; + int32_t shape[4]; +}; + +struct ResizeBilinearParams { + bool align_corners; + // half_pixel_centers assumes pixels are of half the actual dimensions, and + // yields more accurate resizes. Corresponds to the same argument for the + // original TensorFlow op in TF2.0. + bool half_pixel_centers; +}; + +struct ResizeNearestNeighborParams { + bool align_corners; + bool half_pixel_centers; +}; + +struct SliceParams { + int8_t begin_count; + int32_t begin[4]; + int8_t size_count; + int32_t size[4]; +}; + +struct SoftmaxParams { + // beta is not really used (not a Tensorflow parameter) and not implemented + // for LogSoftmax. + double beta; + // uint8_t inference params. Used even when beta defaults to 1.0. + int32_t input_multiplier; + int32_t input_left_shift; + // Reverse scaling is only used by LogSoftmax. + int32_t reverse_scaling_divisor; + int32_t reverse_scaling_right_shift; + int diff_min; + int32_t zero_point; + float scale; + float* table; + int16_t* exp_lut; + int16_t* one_over_one_plus_x_lut; + uint8_t* uint8_table1; + uint8_t* uint8_table2; +}; + +struct SpaceToBatchParams { + // "Zero" padding for uint8_t means padding with the output offset. + int32_t output_offset; +}; + +struct SpaceToDepthParams { + int32_t block_size; +}; + +struct SplitParams { + // Graphs that split into, say, 2000 nodes are encountered. The indices in + // OperatorEdges are of type uint16_t. + uint16_t num_split; + int16_t axis; +}; + +struct SqueezeParams { + int8_t squeeze_dims_count; + int32_t squeeze_dims[4]; +}; + +struct StridedSliceParams { + int8_t start_indices_count; + int32_t start_indices[5]; + int8_t stop_indices_count; + int32_t stop_indices[5]; + int8_t strides_count; + int32_t strides[5]; + + int16_t begin_mask; + int16_t ellipsis_mask; + int16_t end_mask; + int16_t new_axis_mask; + int16_t shrink_axis_mask; +}; + +struct TanhParams { + int32_t input_zero_point; + int32_t input_range_radius; + int32_t input_multiplier; + int input_left_shift; +}; + +struct TransposeParams { + int8_t perm_count; + int32_t perm[5]; +}; + +struct UnpackParams { + uint16_t num_split; + int16_t axis; +}; + +struct LeakyReluParams { + float alpha; + int32_t input_offset; + int32_t output_offset; + int32_t output_multiplier_alpha; + int32_t output_shift_alpha; + int32_t output_multiplier_identity; + int32_t output_shift_identity; +}; + +template +inline void SetActivationParams(float min, float max, P* params) { + params->float_activation_min = min; + params->float_activation_max = max; +} + +template +inline void SetActivationParams(int32_t min, int32_t max, P* params) { + params->quantized_activation_min = min; + params->quantized_activation_max = max; +} + +template +inline void SetActivationParams(int64_t min, int64_t max, P* params) { + params->int64_activation_min = min; + params->int64_activation_max = max; +} + +template +inline void GetActivationParams(const P& params, int32_t* min, int32_t* max) { + *min = params.quantized_activation_min; + *max = params.quantized_activation_max; +} + +template +inline void GetActivationParams(const P& params, float* min, float* max) { + *min = params.float_activation_min; + *max = params.float_activation_max; +} + +template +inline void GetActivationParams(const P& params, int64_t* min, int64_t* max) { + *min = params.int64_activation_min; + *max = params.int64_activation_max; +} +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_TYPES_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.cc b/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.cc new file mode 100644 index 0000000..74c8c88 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.cc @@ -0,0 +1,325 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/kernel_util.h" + +#include +#include + +#include +#include +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" + +namespace tflite { + +const TfLiteTensor* GetInput(const TfLiteContext* context, + const TfLiteNode* node, int index) { + if (context->tensors != nullptr) { + return &context->tensors[node->inputs->data[index]]; + } else { + return context->GetTensor(context, node->inputs->data[index]); + } +} + +TfLiteTensor* GetVariableInput(TfLiteContext* context, const TfLiteNode* node, + int index) { + TfLiteTensor* tensor = nullptr; + if (context->tensors != nullptr) { + tensor = &context->tensors[node->inputs->data[index]]; + } else { + tensor = context->GetTensor(context, node->inputs->data[index]); + } + return tensor->is_variable ? tensor : nullptr; +} + +TfLiteTensor* GetOutput(TfLiteContext* context, const TfLiteNode* node, + int index) { + if (context->tensors != nullptr) { + return &context->tensors[node->outputs->data[index]]; + } else { + return context->GetTensor(context, node->outputs->data[index]); + } +} + +const TfLiteTensor* GetOptionalInputTensor(const TfLiteContext* context, + const TfLiteNode* node, int index) { + const bool use_tensor = index < node->inputs->size && + node->inputs->data[index] != kTfLiteOptionalTensor; + if (use_tensor) { + if (context->tensors != nullptr) { + return &context->tensors[node->inputs->data[index]]; + } else { + return context->GetTensor(context, node->inputs->data[index]); + } + } + return nullptr; +} + +// Per-axis +TfLiteStatus PopulateConvolutionQuantizationParams( + TfLiteContext* context, const TfLiteTensor* input, + const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, + const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, + int32_t* output_activation_min, int32_t* output_activation_max, + int32_t* per_channel_multiplier, int* per_channel_shift) { + const auto* affine_quantization = + reinterpret_cast(filter->quantization.params); + return PopulateConvolutionQuantizationParams( + context, input, filter, bias, output, activation, multiplier, shift, + output_activation_min, output_activation_max, per_channel_multiplier, + per_channel_shift, affine_quantization->scale->size); +} + +// Per-axis & per-tensor +TfLiteStatus PopulateConvolutionQuantizationParams( + TfLiteContext* context, const TfLiteTensor* input, + const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, + const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, + int32_t* output_activation_min, int32_t* output_activation_max, + int32_t* per_channel_multiplier, int* per_channel_shift, int num_channels) { + TF_LITE_ENSURE_EQ(context, input->quantization.type, + kTfLiteAffineQuantization); + TF_LITE_ENSURE_EQ(context, filter->quantization.type, + kTfLiteAffineQuantization); + // TODO(jianlijianli): Enable bias type check and bias scale == input scale + // * filter scale for each channel in affine quantization once bias + // quantization is properly populated. + // TF_LITE_ENSURE_EQ(context, bias->quantization.type, + // kTfLiteAffineQuantization); + + // Check data type. + const auto* affine_quantization = + reinterpret_cast(filter->quantization.params); + TF_LITE_ENSURE(context, affine_quantization); + TF_LITE_ENSURE(context, affine_quantization->scale); + const bool is_per_channel = affine_quantization->scale->size > 1; + if (is_per_channel) { + // Currently only Int8/Int16 is supported for per channel quantization. + TF_LITE_ENSURE(context, + input->type == kTfLiteInt8 || input->type == kTfLiteInt16); + TF_LITE_ENSURE_EQ(context, filter->type, kTfLiteInt8); + TF_LITE_ENSURE_EQ(context, affine_quantization->scale->size, num_channels); + TF_LITE_ENSURE_EQ( + context, num_channels, + filter->dims->data[affine_quantization->quantized_dimension]); + } + + // Populate multiplier and shift using affine quantization. + const float input_scale = input->params.scale; + const float output_scale = output->params.scale; + const float* filter_scales = affine_quantization->scale->data; + for (int i = 0; i < num_channels; ++i) { + // If per-tensor quantization parameter is specified, broadcast it along the + // quantization dimension (channels_out). + const float scale = is_per_channel ? filter_scales[i] : filter_scales[0]; + const double filter_scale = static_cast(scale); + const double effective_output_scale = static_cast(input_scale) * + filter_scale / + static_cast(output_scale); + int32_t significand; + int channel_shift; + QuantizeMultiplier(effective_output_scale, &significand, &channel_shift); + per_channel_multiplier[i] = significand; + per_channel_shift[i] = channel_shift; + } + + // Populate scalar quantization parameters. + // This check on legacy quantization parameters is kept only for backward + // compatibility. + if (input->type == kTfLiteUInt8) { + // Check bias scale == input scale * filter scale. + double real_multiplier = 0.0; + TF_LITE_ENSURE_STATUS(GetQuantizedConvolutionMultipler( + context, input, filter, bias, output, &real_multiplier)); + int exponent; + + // Populate quantization parameters with multiplier and shift. + QuantizeMultiplier(real_multiplier, multiplier, &exponent); + *shift = -exponent; + } + if (input->type == kTfLiteInt8 || input->type == kTfLiteUInt8 || + input->type == kTfLiteInt16) { + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, activation, output, output_activation_min, + output_activation_max)); + } + return kTfLiteOk; +} + +TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, + const TfLiteTensor* input, + const TfLiteTensor* filter, + const TfLiteTensor* bias, + TfLiteTensor* output, + double* multiplier) { + const double input_product_scale = static_cast(input->params.scale) * + static_cast(filter->params.scale); + // TODO(ahentz): The following conditions must be guaranteed by the training + // pipeline. + if (bias) { + const double bias_scale = static_cast(bias->params.scale); + // Here we're making sure the input_product_scale & bias_scale are about the + // same. Since we have: + // (output - output_zp) * output_scale = + // input_product_scale * input_product + bias * bias_scale ---- (0) + // + // (0) equals: + // (input_product + bias) * input_product_scale ----- (1) + // + + // bias * (bias_scale - input_product_scale) ------ (2) + // + // For the real kernel computation, we're doing (1), so we really need to + // make sure (2) has minimum impact on the output, so: + // bias * (bias_scale - input_product_scale) / output_scale should be + // a small number for an integer. + // Since normally bias should be within a small range. + // We should expect (bias_scale - input_product_scale) / output_scale to + // be a small number like 0.02. + const double scale_diff = std::abs(input_product_scale - bias_scale); + const double output_scale = static_cast(output->params.scale); + + TF_LITE_ENSURE(context, scale_diff / output_scale <= 0.02); + } + return GetQuantizedConvolutionMultipler(context, input, filter, output, + multiplier); +} + +TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, + const TfLiteTensor* input, + const TfLiteTensor* filter, + TfLiteTensor* output, + double* multiplier) { + const double input_product_scale = + static_cast(input->params.scale * filter->params.scale); + TF_LITE_ENSURE(context, input_product_scale >= 0); + *multiplier = input_product_scale / static_cast(output->params.scale); + + return kTfLiteOk; +} + +namespace { +void CalculateActivationRangeQuantizedImpl(TfLiteFusedActivation activation, + int32_t qmin, int32_t qmax, + TfLiteTensor* output, + int32_t* act_min, int32_t* act_max) { + const auto scale = output->params.scale; + const auto zero_point = output->params.zero_point; + + auto quantize = [scale, zero_point](float f) { + return zero_point + static_cast(TfLiteRound(f / scale)); + }; + + if (activation == kTfLiteActRelu) { + *act_min = std::max(qmin, quantize(0.0)); + *act_max = qmax; + } else if (activation == kTfLiteActRelu6) { + *act_min = std::max(qmin, quantize(0.0)); + *act_max = std::min(qmax, quantize(6.0)); + } else if (activation == kTfLiteActReluN1To1) { + *act_min = std::max(qmin, quantize(-1.0)); + *act_max = std::min(qmax, quantize(1.0)); + } else { + *act_min = qmin; + *act_max = qmax; + } +} +} // namespace + +TfLiteStatus CalculateActivationRangeQuantized(TfLiteContext* context, + TfLiteFusedActivation activation, + TfLiteTensor* output, + int32_t* act_min, + int32_t* act_max) { + int32_t qmin = 0; + int32_t qmax = 0; + if (output->type == kTfLiteUInt8) { + qmin = std::numeric_limits::min(); + qmax = std::numeric_limits::max(); + } else if (output->type == kTfLiteInt8) { + qmin = std::numeric_limits::min(); + qmax = std::numeric_limits::max(); + } else if (output->type == kTfLiteInt16) { + qmin = std::numeric_limits::min(); + qmax = std::numeric_limits::max(); + } else { + TF_LITE_ENSURE(context, false); + } + + CalculateActivationRangeQuantizedImpl(activation, qmin, qmax, output, act_min, + act_max); + return kTfLiteOk; +} + +bool HaveSameShapes(const TfLiteTensor* input1, const TfLiteTensor* input2) { + return TfLiteIntArrayEqual(input1->dims, input2->dims); +} + +// TODO(petewarden): Having macros around this is ugly, look at other strategies +// before replicating this approach elsewhere. +#ifndef TF_LITE_STATIC_MEMORY +TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + TfLiteIntArray** output_shape) { + int dims1 = NumDimensions(input1); + int dims2 = NumDimensions(input2); + int out_dims = std::max(dims1, dims2); + if (NumElements(input1) == 0) { + *output_shape = TfLiteIntArrayCopy(input1->dims); + return kTfLiteOk; + } + std::unique_ptr shape( + TfLiteIntArrayCreate(out_dims), TfLiteIntArrayFree); + for (int i = 0; i < out_dims; ++i) { + int d1 = i >= dims1 ? 1 : SizeOfDimension(input1, dims1 - i - 1); + int d2 = i >= dims2 ? 1 : SizeOfDimension(input2, dims2 - i - 1); + TF_LITE_ENSURE(context, d1 == d2 || d1 == 1 || d2 == 1); + shape->data[out_dims - i - 1] = std::max(d1, d2); + } + *output_shape = shape.release(); + return kTfLiteOk; +} + +TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + const TfLiteTensor* input3, + TfLiteIntArray** output_shape) { + int dims1 = NumDimensions(input1); + int dims2 = NumDimensions(input2); + int dims3 = NumDimensions(input3); + int out_dims = std::max(std::max(dims1, dims2), dims3); + std::unique_ptr shape( + TfLiteIntArrayCreate(out_dims), TfLiteIntArrayFree); + for (int i = 0; i < out_dims; ++i) { + int d1 = i >= dims1 ? 1 : SizeOfDimension(input1, dims1 - i - 1); + int d2 = i >= dims2 ? 1 : SizeOfDimension(input2, dims2 - i - 1); + int d3 = i >= dims3 ? 1 : SizeOfDimension(input3, dims3 - i - 1); + int max_value = std::max(std::max(d1, d2), d3); + TF_LITE_ENSURE(context, d1 == 1 || d1 == max_value); + TF_LITE_ENSURE(context, d2 == 1 || d2 == max_value); + TF_LITE_ENSURE(context, d3 == 1 || d3 == max_value); + shape->data[out_dims - i - 1] = max_value; + } + *output_shape = shape.release(); + return kTfLiteOk; +} +#endif // TF_LITE_STATIC_MEMORY + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.h b/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.h new file mode 100644 index 0000000..0d6aa8f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/kernel_util.h @@ -0,0 +1,196 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_KERNEL_UTIL_H_ +#define TENSORFLOW_LITE_KERNELS_KERNEL_UTIL_H_ + +#include + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +// A fair number of functions in this header have historically been inline. +// It is ok to change functions to not be inline if the latency with +// benchmark_model for MobileNet + MobileBERT is unaffected. If such a change is +// made, move the newly non-inlined function declarations to the top of this +// header file. +const TfLiteTensor* GetInput(const TfLiteContext* context, + const TfLiteNode* node, int index); + +// Note: You must check if result is not null: +// TfLiteTensor* my_tensor = GetVariableInput(context, node, kMyTensorIdx); +// TF_LITE_ENSURE(context, my_tensor != nullptr); +TfLiteTensor* GetVariableInput(TfLiteContext* context, const TfLiteNode* node, + int index); + +TfLiteTensor* GetOutput(TfLiteContext* context, const TfLiteNode* node, + int index); + +const TfLiteTensor* GetOptionalInputTensor(const TfLiteContext* context, + const TfLiteNode* node, int index); + +inline int NumDimensions(const TfLiteTensor* t) { return t->dims->size; } +inline int SizeOfDimension(const TfLiteTensor* t, int dim) { + return t->dims->data[dim]; +} + +#ifndef TF_LITE_STATIC_MEMORY +inline TfLiteTensor* GetTemporary(TfLiteContext* context, + const TfLiteNode* node, int index) { + return &context->tensors[node->temporaries->data[index]]; +} +inline const TfLiteTensor* GetIntermediates(TfLiteContext* context, + const TfLiteNode* node, int index) { + return &context->tensors[node->intermediates->data[index]]; +} +inline int NumIntermediates(const TfLiteNode* node) { + return node->intermediates->size; +} +#endif // TF_LITE_STATIC_MEMORY +inline int NumInputs(const TfLiteNode* node) { return node->inputs->size; } +inline int NumOutputs(const TfLiteNode* node) { return node->outputs->size; } + +inline int64_t NumElements(const TfLiteIntArray* dims) { + int64_t count = 1; + for (int i = 0; i < dims->size; ++i) { + count *= dims->data[i]; + } + return count; +} + +inline int64_t NumElements(const TfLiteTensor* t) { + return NumElements(t->dims); +} + +// Determines whether tensor is constant. +// TODO(b/138199592): Introduce new query which checks for constant OR +// persistent-read-only, which would be useful for most tensor kernels that +// are potentially dynamic based on the input tensor value availability at the +// time of prepare. +inline bool IsConstantTensor(const TfLiteTensor* tensor) { + return tensor->allocation_type == kTfLiteMmapRo; +} + +// Determines whether tensor is dynamic. Note that a tensor can be non-const and +// not dynamic. This function specifically checks for a dynamic tensor. +inline bool IsDynamicTensor(const TfLiteTensor* tensor) { + return tensor->allocation_type == kTfLiteDynamic; +} + +// Sets tensor to dynamic. +inline void SetTensorToDynamic(TfLiteTensor* tensor) { + if (tensor->allocation_type != kTfLiteDynamic) { + tensor->allocation_type = kTfLiteDynamic; + tensor->data.raw = nullptr; + } +} + +// Sets tensor to persistent and read-only. +inline void SetTensorToPersistentRo(TfLiteTensor* tensor) { + if (tensor->allocation_type != kTfLitePersistentRo) { + tensor->allocation_type = kTfLitePersistentRo; + tensor->data.raw = nullptr; + } +} + +// Determines whether it is a hybrid op - one that has float inputs and +// quantized weights. +inline bool IsHybridOp(const TfLiteTensor* input, const TfLiteTensor* weight) { + return ((weight->type == kTfLiteUInt8 || weight->type == kTfLiteInt8) && + input->type == kTfLiteFloat32); +} + +// Check dimensionality match and populate OpData for Conv and DepthwiseConv. +TfLiteStatus PopulateConvolutionQuantizationParams( + TfLiteContext* context, const TfLiteTensor* input, + const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, + const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, + int32_t* output_activation_min, int32_t* output_activation_max, + int32_t* per_channel_multiplier, int* per_channel_shift); + +TfLiteStatus PopulateConvolutionQuantizationParams( + TfLiteContext* context, const TfLiteTensor* input, + const TfLiteTensor* filter, const TfLiteTensor* bias, TfLiteTensor* output, + const TfLiteFusedActivation& activation, int32_t* multiplier, int* shift, + int32_t* output_activation_min, int32_t* output_activation_max, + int32_t* per_channel_multiplier, int* per_channel_shift, int num_channels); + +// Calculates the multiplication factor for a quantized convolution (or +// quantized depthwise convolution) involving the given tensors. Returns an +// error if the scales of the tensors are not compatible. +TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, + const TfLiteTensor* input, + const TfLiteTensor* filter, + const TfLiteTensor* bias, + TfLiteTensor* output, + double* multiplier); + +TfLiteStatus GetQuantizedConvolutionMultipler(TfLiteContext* context, + const TfLiteTensor* input, + const TfLiteTensor* filter, + TfLiteTensor* output, + double* multiplier); + +// Calculates the useful quantized range of an activation layer given its +// activation tensor. +TfLiteStatus CalculateActivationRangeQuantized(TfLiteContext* context, + TfLiteFusedActivation activation, + TfLiteTensor* output, + int32_t* act_min, + int32_t* act_max); + +// Calculates the useful range of an activation layer given its activation +// tensor.a +template +void CalculateActivationRange(TfLiteFusedActivation activation, + T* activation_min, T* activation_max) { + if (activation == kTfLiteActRelu) { + *activation_min = 0; + *activation_max = std::numeric_limits::max(); + } else if (activation == kTfLiteActRelu6) { + *activation_min = 0; + *activation_max = 6; + } else if (activation == kTfLiteActReluN1To1) { + *activation_min = -1; + *activation_max = 1; + } else { + *activation_min = std::numeric_limits::lowest(); + *activation_max = std::numeric_limits::max(); + } +} + +// Return true if the given tensors have the same shape. +bool HaveSameShapes(const TfLiteTensor* input1, const TfLiteTensor* input2); + +// Calculates the output_shape that is necessary for element-wise operations +// with broadcasting involving the two input tensors. +TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + TfLiteIntArray** output_shape); + +// Calculates the output_shape that is necessary for element-wise operations +// with broadcasting involving the three input tensors. +TfLiteStatus CalculateShapeForBroadcast(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + const TfLiteTensor* input3, + TfLiteIntArray** output_shape); +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_KERNEL_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/op_macros.h b/TensorflowLiteMicro/tensorflow/lite/kernels/op_macros.h new file mode 100644 index 0000000..5786756 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/op_macros.h @@ -0,0 +1,83 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_OP_MACROS_H_ +#define TENSORFLOW_LITE_KERNELS_OP_MACROS_H_ + +// If we're on a platform without standard IO functions, fall back to a +// non-portable function. +#ifdef TF_LITE_MCU_DEBUG_LOG + +#include "tensorflow/lite/micro/debug_log.h" + +#define DEBUG_LOG(x) \ + do { \ + DebugLog(x); \ + } while (0) + +inline void InfiniteLoop() { + DEBUG_LOG("HALTED\n"); + while (1) { + } +} + +#define TFLITE_ABORT InfiniteLoop(); + +#else // TF_LITE_MCU_DEBUG_LOG + +#include +#include + +#define DEBUG_LOG(x) \ + do { \ + fprintf(stderr, "%s", (x)); \ + } while (0) + +// Report Error for unsupported type by op 'op_name' and returns kTfLiteError. +#define TF_LITE_UNSUPPORTED_TYPE(context, type, op_name) \ + do { \ + TF_LITE_KERNEL_LOG((context), "%s:%d Type %s is unsupported by op %s.", \ + __FILE__, __LINE__, TfLiteTypeGetName(type), \ + (op_name)); \ + return kTfLiteError; \ + } while (0) + +#define TFLITE_ABORT abort() + +#endif // TF_LITE_MCU_DEBUG_LOG + +#ifdef NDEBUG +#define TFLITE_ASSERT_FALSE (static_cast(0)) +#else +#define TFLITE_ASSERT_FALSE TFLITE_ABORT +#endif + +#define TF_LITE_FATAL(msg) \ + do { \ + DEBUG_LOG(msg); \ + DEBUG_LOG("\nFATAL\n"); \ + TFLITE_ABORT; \ + } while (0) + +#define TF_LITE_ASSERT(x) \ + do { \ + if (!(x)) TF_LITE_FATAL(#x); \ + } while (0) + +#define TF_LITE_ASSERT_EQ(x, y) \ + do { \ + if ((x) != (y)) TF_LITE_FATAL(#x " didn't equal " #y); \ + } while (0) + +#endif // TENSORFLOW_LITE_KERNELS_OP_MACROS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/kernels/padding.h b/TensorflowLiteMicro/tensorflow/lite/kernels/padding.h new file mode 100644 index 0000000..1116b1d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/kernels/padding.h @@ -0,0 +1,80 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_KERNELS_PADDING_H_ +#define TENSORFLOW_LITE_KERNELS_PADDING_H_ + +#include "tensorflow/lite/c/builtin_op_data.h" + +namespace tflite { + +// TODO(renjieliu): Migrate others to use ComputePaddingWithLeftover. +inline int ComputePadding(int stride, int dilation_rate, int in_size, + int filter_size, int out_size) { + int effective_filter_size = (filter_size - 1) * dilation_rate + 1; + int padding = ((out_size - 1) * stride + effective_filter_size - in_size) / 2; + return padding > 0 ? padding : 0; +} + +// It's not guaranteed that padding is symmetric. It's important to keep +// offset for algorithms need all paddings. +inline int ComputePaddingWithOffset(int stride, int dilation_rate, int in_size, + int filter_size, int out_size, + int* offset) { + int effective_filter_size = (filter_size - 1) * dilation_rate + 1; + int total_padding = + ((out_size - 1) * stride + effective_filter_size - in_size); + total_padding = total_padding > 0 ? total_padding : 0; + *offset = total_padding % 2; + return total_padding / 2; +} + +// Matching GetWindowedOutputSize in TensorFlow. +inline int ComputeOutSize(TfLitePadding padding, int image_size, + int filter_size, int stride, int dilation_rate = 1) { + int effective_filter_size = (filter_size - 1) * dilation_rate + 1; + switch (padding) { + case kTfLitePaddingSame: + return (image_size + stride - 1) / stride; + case kTfLitePaddingValid: + return (image_size + stride - effective_filter_size) / stride; + default: + return 0; + } +} + +inline TfLitePaddingValues ComputePaddingHeightWidth( + int stride_height, int stride_width, int dilation_rate_height, + int dilation_rate_width, int in_height, int in_width, int filter_height, + int filter_width, TfLitePadding padding, int* out_height, int* out_width) { + *out_width = ComputeOutSize(padding, in_width, filter_width, stride_width, + dilation_rate_width); + *out_height = ComputeOutSize(padding, in_height, filter_height, stride_height, + dilation_rate_height); + + TfLitePaddingValues padding_values; + int offset = 0; + padding_values.height = + ComputePaddingWithOffset(stride_height, dilation_rate_height, in_height, + filter_height, *out_height, &offset); + padding_values.height_offset = offset; + padding_values.width = + ComputePaddingWithOffset(stride_width, dilation_rate_width, in_width, + filter_width, *out_width, &offset); + padding_values.width_offset = offset; + return padding_values; +} +} // namespace tflite + +#endif // TENSORFLOW_LITE_KERNELS_PADDING_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/SConscript b/TensorflowLiteMicro/tensorflow/lite/micro/SConscript new file mode 100644 index 0000000..8b36d92 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/SConscript @@ -0,0 +1,97 @@ +from building import * +import os + +src = Split(''' +kernels/activations.cc +kernels/arg_min_max.cc +kernels/ceil.cc +kernels/circular_buffer.cc +kernels/comparisons.cc +kernels/concatenation.cc +kernels/dequantize.cc +kernels/elementwise.cc +kernels/ethosu.cc +kernels/floor.cc +kernels/hard_swish.cc +kernels/kernel_runner.cc +kernels/kernel_util.cc +kernels/l2norm.cc +kernels/logical.cc +kernels/logistic.cc +kernels/maximum_minimum.cc +kernels/neg.cc +kernels/pack.cc +kernels/pad.cc +kernels/prelu.cc +kernels/quantize.cc +kernels/reduce.cc +kernels/reshape.cc +kernels/resize_nearest_neighbor.cc +kernels/round.cc +kernels/split.cc +kernels/strided_slice.cc +kernels/sub.cc +kernels/svdf.cc +kernels/tanh.cc +kernels/unpack.cc +''') + Glob('*.c') + Glob('*.cc') + Glob('benchmarks/*.cc') \ + + Glob('memory_planner/*.cc') + Glob('testing/*.cc') + +#if GetDepend('PKG_USING_TENSORFLOWLITEMICRO_AUDIO_EXAMPLE'): +#src += Glob('examples/micro_speech/*.cc') + Glob('examples/micro_speech/micro_features/*.cc') +src += Glob('examples/person_detection_experimental/*.cc') +#if GetDepend('PKG_USING_TENSORFLOWLITEMICRO_REFERENCE'): +src += Split(''' +kernels/add.cc +kernels/conv.cc +kernels/depthwise_conv.cc +kernels/fully_connected.cc +kernels/mul.cc +kernels/pooling.cc +kernels/softmax.cc +''') +if GetDepend('PKG_USING_TENSORFLOWLITEMICRO_CMSISNN'): + src += Split(''' + kernels/cmsis-nn/add.cc + kernels/cmsis-nn/conv.cc + kernels/cmsis-nn/depthwise_conv.cc + kernels/cmsis-nn/fully_connected.cc + kernels/cmsis-nn/mul.cc + kernels/cmsis-nn/pooling.cc + kernels/cmsis-nn/softmax.cc + ''') + src += Glob('tools/cmsis/CMSIS/NN/Source/ActivationFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/PoolingFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/ReshapeFunctions/*.c') + src += Glob('tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/*.c') + +#. +root = str(Dir('#')) +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") +#./tensorflow/lite/micro/tools/make/downloads +cmsis = os.path.join(tflm_pkg, "tensorflow/lite/micro/tools/") + + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy, cmsis] + +group = DefineGroup('lite/micro', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.cc b/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.cc new file mode 100644 index 0000000..ff461cb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.cc @@ -0,0 +1,91 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/all_ops_resolver.h" + +#include "tensorflow/lite/micro/kernels/micro_ops.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace custom { +TfLiteRegistration* Register_ETHOSU(); +const char* GetString_ETHOSU(); +} // namespace custom +} // namespace micro +} // namespace ops + +AllOpsResolver::AllOpsResolver() { + // Please keep this list of Builtin Operators in alphabetical order. + AddAbs(); + AddAdd(); + AddArgMax(); + AddArgMin(); + AddAveragePool2D(); + AddCeil(); + AddConcatenation(); + AddConv2D(); + AddCos(); + AddDepthwiseConv2D(); + AddDequantize(); + AddEqual(); + AddFloor(); + AddFullyConnected(); + AddGreater(); + AddGreaterEqual(); + AddHardSwish(); + AddL2Normalization(); + AddLess(); + AddLessEqual(); + AddLog(); + AddLogicalAnd(); + AddLogicalNot(); + AddLogicalOr(); + AddLogistic(); + AddMaximum(); + AddMaxPool2D(); + AddMean(); + AddMinimum(); + AddMul(); + AddNeg(); + AddNotEqual(); + AddPack(); + AddPad(); + AddPadV2(); + AddPrelu(); + AddQuantize(); + AddRelu(); + AddRelu6(); + AddReshape(); + AddResizeNearestNeighbor(); + AddRound(); + AddRsqrt(); + AddSin(); + AddSoftmax(); + AddSplit(); + AddSqrt(); + AddSquare(); + AddStridedSlice(); + AddSub(); + AddSvdf(); + AddTanh(); + AddUnpack(); + + // TODO(b/159644355): Figure out if custom Ops belong in AllOpsResolver. + TfLiteRegistration* registration = + tflite::ops::micro::custom::Register_ETHOSU(); + if (registration) { + AddCustom(tflite::ops::micro::custom::GetString_ETHOSU(), registration); + } +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.h b/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.h new file mode 100644 index 0000000..e8105b9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/all_ops_resolver.h @@ -0,0 +1,35 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_ALL_OPS_RESOLVER_H_ +#define TENSORFLOW_LITE_MICRO_ALL_OPS_RESOLVER_H_ + +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" + +namespace tflite { + +// The magic number in the template parameter is the maximum number of ops that +// can be added to AllOpsResolver. It can be increased if needed. And most +// applications that care about the memory footprint will want to directly use +// MicroMutableOpResolver and have an application specific template parameter. +// The examples directory has sample code for this. +class AllOpsResolver : public MicroMutableOpResolver<128> { + public: + AllOpsResolver(); + + private: + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_ALL_OPS_RESOLVER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/compatibility.h b/TensorflowLiteMicro/tensorflow/lite/micro/compatibility.h new file mode 100644 index 0000000..49acb28 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/compatibility.h @@ -0,0 +1,32 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_COMPATIBILITY_H_ +#define TENSORFLOW_LITE_MICRO_COMPATIBILITY_H_ + +// C++ will automatically create class-specific delete operators for virtual +// objects, which by default call the global delete function. For embedded +// applications we want to avoid this, and won't be calling new/delete on these +// objects, so we need to override the default implementation with one that does +// nothing to avoid linking in ::delete(). +// This macro needs to be included in all subclasses of a virtual base class in +// the private section. +#ifdef TF_LITE_STATIC_MEMORY +#define TF_LITE_REMOVE_VIRTUAL_DELETE \ + void operator delete(void* p) {} +#else +#define TF_LITE_REMOVE_VIRTUAL_DELETE +#endif + +#endif // TENSORFLOW_LITE_MICRO_COMPATIBILITY_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.cc b/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.cc new file mode 100644 index 0000000..4858b56 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.cc @@ -0,0 +1,43 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Reference implementation of the DebugLog() function that's required for a +// platform to support the TensorFlow Lite for Microcontrollers library. This is +// the only function that's absolutely required to be available on a target +// device, since it's used for communicating test results back to the host so +// that we can verify the implementation is working correctly. +// It's designed to be as easy as possible to supply an implementation though. +// On platforms that have a POSIX stack or C library, it can be written as a +// single call to `fprintf(stderr, "%s", s)` to output a string to the error +// stream of the console, but if there's no OS or C library available, there's +// almost always an equivalent way to write out a string to some serial +// interface that can be used instead. For example on Arm M-series MCUs, calling +// the `bkpt #0xAB` assembler instruction will output the string in r1 to +// whatever debug serial connection is available. If you're running mbed, you +// can do the same by creating `Serial pc(USBTX, USBRX)` and then calling +// `pc.printf("%s", s)`. +// To add an equivalent function for your own platform, create your own +// implementation file, and place it in a subfolder with named after the OS +// you're targeting. For example, see the Cortex M bare metal version in +// tensorflow/lite/micro/bluepill/debug_log.cc or the mbed one on +// tensorflow/lite/micro/mbed/debug_log.cc. + +#include "tensorflow/lite/micro/debug_log.h" + +#include +#include +#include + +extern "C" void DebugLog(const char* s) { rt_kprintf("%s", s); } diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.h b/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.h new file mode 100644 index 0000000..1004ab9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/debug_log.h @@ -0,0 +1,23 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_DEBUG_LOG_H_ +#define TENSORFLOW_LITE_MICRO_DEBUG_LOG_H_ + +// This function should be implemented by each target platform, and provide a +// way for strings to be output to some text stream. For more information, see +// tensorflow/lite/micro/debug_log.cc. +extern "C" void DebugLog(const char* s); + +#endif // TENSORFLOW_LITE_MICRO_DEBUG_LOG_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.cc new file mode 100644 index 0000000..5775592 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.cc @@ -0,0 +1,39 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/audio_provider.h" + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" + +namespace { +int16_t g_dummy_audio_data[kMaxAudioSampleSize]; +int32_t g_latest_audio_timestamp = 0; +} // namespace + +TfLiteStatus GetAudioSamples(tflite::ErrorReporter* error_reporter, + int start_ms, int duration_ms, + int* audio_samples_size, int16_t** audio_samples) { + for (int i = 0; i < kMaxAudioSampleSize; ++i) { + g_dummy_audio_data[i] = 0; + } + *audio_samples_size = kMaxAudioSampleSize; + *audio_samples = g_dummy_audio_data; + return kTfLiteOk; +} + +int32_t LatestAudioTimestamp() { + g_latest_audio_timestamp += 100; + return g_latest_audio_timestamp; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.h new file mode 100644 index 0000000..c51cc5f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/audio_provider.h @@ -0,0 +1,46 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// This is an abstraction around an audio source like a microphone, and is +// expected to return 16-bit PCM sample data for a given point in time. The +// sample data itself should be used as quickly as possible by the caller, since +// to allow memory optimizations there are no guarantees that the samples won't +// be overwritten by new data in the future. In practice, implementations should +// ensure that there's a reasonable time allowed for clients to access the data +// before any reuse. +// The reference implementation can have no platform-specific dependencies, so +// it just returns an array filled with zeros. For real applications, you should +// ensure there's a specialized implementation that accesses hardware APIs. +TfLiteStatus GetAudioSamples(tflite::ErrorReporter* error_reporter, + int start_ms, int duration_ms, + int* audio_samples_size, int16_t** audio_samples); + +// Returns the time that audio data was last captured in milliseconds. There's +// no contract about what time zero represents, the accuracy, or the granularity +// of the result. Subsequent calls will generally not return a lower value, but +// even that's not guaranteed if there's an overflow wraparound. +// The reference implementation of this function just returns a constantly +// incrementing value for each call, since it would need a non-portable platform +// call to access time information. For real applications, you'll need to write +// your own platform-specific implementation. +int32_t LatestAudioTimestamp(); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_AUDIO_PROVIDER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.cc new file mode 100644 index 0000000..10c458f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.cc @@ -0,0 +1,30 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h" +#include "rtthread.h" + +// The default implementation writes out the name of the recognized command +// to the error console. Real applications will want to take some custom +// action instead, and should implement their own versions of this function. +void RespondToCommand(tflite::ErrorReporter* error_reporter, + int32_t current_time, const char* found_command, + uint8_t score, bool is_new_command) { + //rt_kprintf("command\n"); + if (is_new_command) { + TF_LITE_REPORT_ERROR(error_reporter, "Heard %s (%d) @%dms", found_command, + score, current_time); + } +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.h new file mode 100644 index 0000000..ac3f448 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/command_responder.h @@ -0,0 +1,32 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Provides an interface to take an action based on an audio command. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Called every time the results of an audio recognition run are available. The +// human-readable name of any recognized command is in the `found_command` +// argument, `score` has the numerical confidence, and `is_new_command` is set +// if the previous command was different to this one. +void RespondToCommand(tflite::ErrorReporter* error_reporter, + int32_t current_time, const char* found_command, + uint8_t score, bool is_new_command); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_COMMAND_RESPONDER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.cc new file mode 100644 index 0000000..3242425 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.cc @@ -0,0 +1,121 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/feature_provider.h" + +#include "tensorflow/lite/micro/examples/micro_speech/audio_provider.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h" + +FeatureProvider::FeatureProvider(int feature_size, int8_t* feature_data) + : feature_size_(feature_size), + feature_data_(feature_data), + is_first_run_(true) { + // Initialize the feature data to default values. + for (int n = 0; n < feature_size_; ++n) { + feature_data_[n] = g_yes_micro_f2e59fea_nohash_1_data[n]; + } +} + +FeatureProvider::~FeatureProvider() {} + +TfLiteStatus FeatureProvider::PopulateFeatureData( + tflite::ErrorReporter* error_reporter, int32_t last_time_in_ms, + int32_t time_in_ms, int* how_many_new_slices) { + if (feature_size_ != kFeatureElementCount) { + TF_LITE_REPORT_ERROR(error_reporter, + "Requested feature_data_ size %d doesn't match %d", + feature_size_, kFeatureElementCount); + return kTfLiteError; + } + + // Quantize the time into steps as long as each window stride, so we can + // figure out which audio data we need to fetch. + const int last_step = (last_time_in_ms / kFeatureSliceStrideMs); + const int current_step = (time_in_ms / kFeatureSliceStrideMs); + + int slices_needed = current_step - last_step; + // If this is the first call, make sure we don't use any cached information. + if (is_first_run_) { + TfLiteStatus init_status = InitializeMicroFeatures(error_reporter); + if (init_status != kTfLiteOk) { + return init_status; + } + is_first_run_ = false; + slices_needed = kFeatureSliceCount; + } + if (slices_needed > kFeatureSliceCount) { + slices_needed = kFeatureSliceCount; + } + *how_many_new_slices = slices_needed; + + const int slices_to_keep = kFeatureSliceCount - slices_needed; + const int slices_to_drop = kFeatureSliceCount - slices_to_keep; + // If we can avoid recalculating some slices, just move the existing data + // up in the spectrogram, to perform something like this: + // last time = 80ms current time = 120ms + // +-----------+ +-----------+ + // | data@20ms | --> | data@60ms | + // +-----------+ -- +-----------+ + // | data@40ms | -- --> | data@80ms | + // +-----------+ -- -- +-----------+ + // | data@60ms | -- -- | | + // +-----------+ -- +-----------+ + // | data@80ms | -- | | + // +-----------+ +-----------+ + if (slices_to_keep > 0) { + for (int dest_slice = 0; dest_slice < slices_to_keep; ++dest_slice) { + int8_t* dest_slice_data = + feature_data_ + (dest_slice * kFeatureSliceSize); + const int src_slice = dest_slice + slices_to_drop; + const int8_t* src_slice_data = + feature_data_ + (src_slice * kFeatureSliceSize); + for (int i = 0; i < kFeatureSliceSize; ++i) { + dest_slice_data[i] = src_slice_data[i]; + } + } + } + // Any slices that need to be filled in with feature data have their + // appropriate audio data pulled, and features calculated for that slice. + if (slices_needed > 0) { + for (int new_slice = slices_to_keep; new_slice < kFeatureSliceCount; + ++new_slice) { + const int new_step = (current_step - kFeatureSliceCount + 1) + new_slice; + const int32_t slice_start_ms = (new_step * kFeatureSliceStrideMs); + int16_t* audio_samples = nullptr; + int audio_samples_size = 0; + // TODO(petewarden): Fix bug that leads to non-zero slice_start_ms + GetAudioSamples(error_reporter, (slice_start_ms > 0 ? slice_start_ms : 0), + kFeatureSliceDurationMs, &audio_samples_size, + &audio_samples); + if (audio_samples_size < kMaxAudioSampleSize) { + TF_LITE_REPORT_ERROR(error_reporter, + "Audio data size %d too small, want %d", + audio_samples_size, kMaxAudioSampleSize); + return kTfLiteError; + } + int8_t* new_slice_data = feature_data_ + (new_slice * kFeatureSliceSize); + size_t num_samples_read; + TfLiteStatus generate_status = GenerateMicroFeatures( + error_reporter, audio_samples, audio_samples_size, kFeatureSliceSize, + new_slice_data, &num_samples_read); + if (generate_status != kTfLiteOk) { + return generate_status; + } + } + } + return kTfLiteOk; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.h new file mode 100644 index 0000000..d086e01 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/feature_provider.h @@ -0,0 +1,52 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Binds itself to an area of memory intended to hold the input features for an +// audio-recognition neural network model, and fills that data area with the +// features representing the current audio input, for example from a microphone. +// The audio features themselves are a two-dimensional array, made up of +// horizontal slices representing the frequencies at one point in time, stacked +// on top of each other to form a spectrogram showing how those frequencies +// changed over time. +class FeatureProvider { + public: + // Create the provider, and bind it to an area of memory. This memory should + // remain accessible for the lifetime of the provider object, since subsequent + // calls will fill it with feature data. The provider does no memory + // management of this data. + FeatureProvider(int feature_size, int8_t* feature_data); + ~FeatureProvider(); + + // Fills the feature data with information from audio inputs, and returns how + // many feature slices were updated. + TfLiteStatus PopulateFeatureData(tflite::ErrorReporter* error_reporter, + int32_t last_time_in_ms, int32_t time_in_ms, + int* how_many_new_slices); + + private: + int feature_size_; + int8_t* feature_data_; + // Make sure we don't try to use cached information if this is the first call + // into the provider. + bool is_first_run_; +}; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_FEATURE_PROVIDER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.cc new file mode 100644 index 0000000..74f2ccd --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.cc @@ -0,0 +1,185 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/main_functions.h" + +#include "tensorflow/lite/micro/examples/micro_speech/audio_provider.h" +#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h" +#include "tensorflow/lite/micro/examples/micro_speech/feature_provider.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/model.h" + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h" + +#include "tensorflow/lite/micro/examples/micro_speech/recognize_commands.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/version.h" + +#include "rtthread.h" + +// Globals, used for compatibility with Arduino-style sketches. +namespace { +tflite::ErrorReporter* error_reporter = nullptr; +const tflite::Model* model = nullptr; +tflite::MicroInterpreter* interpreter = nullptr; +TfLiteTensor* model_input = nullptr; +FeatureProvider* feature_provider = nullptr; +RecognizeCommands* recognizer = nullptr; +int32_t previous_time = 0; + +// Create an area of memory to use for input, output, and intermediate arrays. +// The size of this will depend on the model you're using, and may need to be +// determined by experimentation. +constexpr int kTensorArenaSize = 10 * 1024; +uint8_t tensor_arena[kTensorArenaSize]; +int8_t feature_buffer[kFeatureElementCount]; +int8_t* model_input_buffer = nullptr; +} // namespace + +// The name of this function is important for Arduino compatibility. +void setup() { + // Set up logging. Google style is to avoid globals or statics because of + // lifetime uncertainty, but since this has a trivial destructor it's okay. + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroErrorReporter micro_error_reporter; + error_reporter = µ_error_reporter; + + // Map the model into a usable data structure. This doesn't involve any + // copying or parsing, it's a very lightweight operation. + model = tflite::GetModel(g_model); + if (model->version() != TFLITE_SCHEMA_VERSION) { + TF_LITE_REPORT_ERROR(error_reporter, + "Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); + return; + } + + // Pull in only the operation implementations we need. + // This relies on a complete list of all the ops needed by this graph. + // An easier approach is to just use the AllOpsResolver, but this will + // incur some penalty in code space for op implementations that are not + // needed by this graph. + // + // tflite::AllOpsResolver resolver; + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroMutableOpResolver<4> micro_op_resolver(error_reporter); + if (micro_op_resolver.AddDepthwiseConv2D() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddFullyConnected() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddSoftmax() != kTfLiteOk) { + return; + } + if (micro_op_resolver.AddReshape() != kTfLiteOk) { + return; + } + + // Build an interpreter to run the model with. + static tflite::MicroInterpreter static_interpreter( + model, micro_op_resolver, tensor_arena, kTensorArenaSize, error_reporter); + interpreter = &static_interpreter; + + // Allocate memory from the tensor_arena for the model's tensors. + TfLiteStatus allocate_status = interpreter->AllocateTensors(); + if (allocate_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed"); + return; + } + + // Get information about the memory area to use for the model's input. + model_input = interpreter->input(0); + if ((model_input->dims->size != 2) || (model_input->dims->data[0] != 1) || + (model_input->dims->data[1] != + (kFeatureSliceCount * kFeatureSliceSize)) || + (model_input->type != kTfLiteInt8)) { + TF_LITE_REPORT_ERROR(error_reporter, + "Bad input tensor parameters in model"); + return; + } + model_input_buffer = model_input->data.int8; + + // Prepare to access the audio spectrograms from a microphone or other source + // that will provide the inputs to the neural network. + // NOLINTNEXTLINE(runtime-global-variables) + static FeatureProvider static_feature_provider(kFeatureElementCount, + feature_buffer); + feature_provider = &static_feature_provider; + + static RecognizeCommands static_recognizer(error_reporter); + recognizer = &static_recognizer; + + previous_time = 0; +} + +// The name of this function is important for Arduino compatibility. +void loop() { + rt_kprintf("start to run speech case...\n"); + // Fetch the spectrogram for the current time. + const int32_t current_time = LatestAudioTimestamp(); + int how_many_new_slices = 0; + TfLiteStatus feature_status = feature_provider->PopulateFeatureData( + error_reporter, previous_time, current_time, &how_many_new_slices); + if (feature_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "Feature generation failed"); + return; + } + previous_time = current_time; + // If no new audio samples have been received since last time, don't bother + // running the network model. + if (how_many_new_slices == 0) { + return; + } + + // Copy feature buffer to input tensor + for (int i = 0; i < kFeatureElementCount; i++) { + //rt_kprintf("%d " , g_yes_micro_f2e59fea_nohash_1_data[i]); + //model_input_buffer[i] = g_no_micro_f9643d42_nohash_4_data[i]; + model_input_buffer[i] = feature_buffer[i]; + } + + // Run the model on the spectrogram input and make sure it succeeds. + TfLiteStatus invoke_status = interpreter->Invoke(); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed"); + return; + } + + // Obtain a pointer to the output tensor + TfLiteTensor* output = interpreter->output(0); + // Determine whether a command was recognized based on the output of inference + const char* found_command = nullptr; + uint8_t score = 0; + bool is_new_command = false; + TfLiteStatus process_status = recognizer->ProcessLatestResults( + output, current_time, &found_command, &score, &is_new_command); + if (process_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, + "RecognizeCommands::ProcessLatestResults() failed"); + return; + } + is_new_command = true; + // Do something based on the recognized command. The default implementation + // just prints to the error console, but you should replace this with your + // own function for a real application. + RespondToCommand(error_reporter, current_time, found_command, score, + is_new_command); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.h new file mode 100644 index 0000000..0ac0677 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/main_functions.h @@ -0,0 +1,37 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ + +// Expose a C friendly interface for main functions. +#ifdef __cplusplus +extern "C" { +#endif + +// Initializes all data needed for the example. The name is important, and needs +// to be setup() for Arduino compatibility. +void setup(); + +// Runs one iteration of data gathering and inference. This should be called +// repeatedly from the application code. The name needs to be loop() for Arduino +// compatibility. +void loop(); + +#ifdef __cplusplus +} +#endif + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MAIN_FUNCTIONS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.cc new file mode 100644 index 0000000..9e07643 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.cc @@ -0,0 +1,116 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.h" + +#include +#include + +#include "tensorflow/lite/experimental/microfrontend/lib/frontend.h" +#include "tensorflow/lite/experimental/microfrontend/lib/frontend_util.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" + +// Configure FFT to output 16 bit fixed point. +#define FIXED_POINT 16 + +namespace { + +FrontendState g_micro_features_state; +bool g_is_first_time = true; + +} // namespace + +TfLiteStatus InitializeMicroFeatures(tflite::ErrorReporter* error_reporter) { + FrontendConfig config; + config.window.size_ms = kFeatureSliceDurationMs; + config.window.step_size_ms = kFeatureSliceStrideMs; + config.noise_reduction.smoothing_bits = 10; + config.filterbank.num_channels = kFeatureSliceSize; + config.filterbank.lower_band_limit = 125.0; + config.filterbank.upper_band_limit = 7500.0; + config.noise_reduction.smoothing_bits = 10; + config.noise_reduction.even_smoothing = 0.025; + config.noise_reduction.odd_smoothing = 0.06; + config.noise_reduction.min_signal_remaining = 0.05; + config.pcan_gain_control.enable_pcan = 1; + config.pcan_gain_control.strength = 0.95; + config.pcan_gain_control.offset = 80.0; + config.pcan_gain_control.gain_bits = 21; + config.log_scale.enable_log = 1; + config.log_scale.scale_shift = 6; + if (!FrontendPopulateState(&config, &g_micro_features_state, + kAudioSampleFrequency)) { + TF_LITE_REPORT_ERROR(error_reporter, "FrontendPopulateState() failed"); + return kTfLiteError; + } + g_is_first_time = true; + return kTfLiteOk; +} + +// This is not exposed in any header, and is only used for testing, to ensure +// that the state is correctly set up before generating results. +void SetMicroFeaturesNoiseEstimates(const uint32_t* estimate_presets) { + for (int i = 0; i < g_micro_features_state.filterbank.num_channels; ++i) { + g_micro_features_state.noise_reduction.estimate[i] = estimate_presets[i]; + } +} + +TfLiteStatus GenerateMicroFeatures(tflite::ErrorReporter* error_reporter, + const int16_t* input, int input_size, + int output_size, int8_t* output, + size_t* num_samples_read) { + const int16_t* frontend_input; + if (g_is_first_time) { + frontend_input = input; + g_is_first_time = false; + } else { + frontend_input = input + 160; + } + FrontendOutput frontend_output = FrontendProcessSamples( + &g_micro_features_state, frontend_input, input_size, num_samples_read); + + for (size_t i = 0; i < frontend_output.size; ++i) { + // These scaling values are derived from those used in input_data.py in the + // training pipeline. + // The feature pipeline outputs 16-bit signed integers in roughly a 0 to 670 + // range. In training, these are then arbitrarily divided by 25.6 to get + // float values in the rough range of 0.0 to 26.0. This scaling is performed + // for historical reasons, to match up with the output of other feature + // generators. + // The process is then further complicated when we quantize the model. This + // means we have to scale the 0.0 to 26.0 real values to the -128 to 127 + // signed integer numbers. + // All this means that to get matching values from our integer feature + // output into the tensor input, we have to perform: + // input = (((feature / 25.6) / 26.0) * 256) - 128 + // To simplify this and perform it in 32-bit integer math, we rearrange to: + // input = (feature * 256) / (25.6 * 26.0) - 128 + constexpr int32_t value_scale = 256; + constexpr int32_t value_div = static_cast((25.6f * 26.0f) + 0.5f); + int32_t value = + ((frontend_output.values[i] * value_scale) + (value_div / 2)) / + value_div; + value -= 128; + if (value < -128) { + value = -128; + } + if (value > 127) { + value = 127; + } + output[i] = value; + } + + return kTfLiteOk; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.h new file mode 100644 index 0000000..2930423 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_features_generator.h @@ -0,0 +1,32 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Sets up any resources needed for the feature generation pipeline. +TfLiteStatus InitializeMicroFeatures(tflite::ErrorReporter* error_reporter); + +// Converts audio sample data into a more compact form that's appropriate for +// feeding into a neural network. +TfLiteStatus GenerateMicroFeatures(tflite::ErrorReporter* error_reporter, + const int16_t* input, int input_size, + int output_size, int8_t* output, + size_t* num_samples_read); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_FEATURES_GENERATOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.cc new file mode 100644 index 0000000..47d12ba --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.cc @@ -0,0 +1,23 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" + +const char* kCategoryLabels[kCategoryCount] = { + "silence", + "unknown", + "yes", + "no", +}; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h new file mode 100644 index 0000000..e542213 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h @@ -0,0 +1,43 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ + +// Keeping these as constant expressions allow us to allocate fixed-sized arrays +// on the stack for our working memory. + +// The size of the input time series data we pass to the FFT to produce the +// frequency information. This has to be a power of two, and since we're dealing +// with 30ms of 16KHz inputs, which means 480 samples, this is the next value. +constexpr int kMaxAudioSampleSize = 512; +constexpr int kAudioSampleFrequency = 16000; + +// The following values are derived from values used during model training. +// If you change the way you preprocess the input, update all these constants. +constexpr int kFeatureSliceSize = 40; +constexpr int kFeatureSliceCount = 49; +constexpr int kFeatureElementCount = (kFeatureSliceSize * kFeatureSliceCount); +constexpr int kFeatureSliceStrideMs = 20; +constexpr int kFeatureSliceDurationMs = 30; + +// Variables for the model's output categories. +constexpr int kSilenceIndex = 0; +constexpr int kUnknownIndex = 1; +// If you modify the output categories, you need to update the following values. +constexpr int kCategoryCount = 4; +extern const char* kCategoryLabels[kCategoryCount]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MICRO_MODEL_SETTINGS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.cc new file mode 100644 index 0000000..d1e797f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.cc @@ -0,0 +1,1596 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a standard TensorFlow Lite FlatBuffer model file that has been +// converted into a C data array, so it can be easily compiled into a binary +// for devices that don't have a file system. It was created using the command: +// xxd -i model.tflite > model.cc + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/model.h" + +// We need to keep the data array aligned on some architectures. +#ifdef __has_attribute +#define HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAVE_ATTRIBUTE(x) 0 +#endif +#if HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) +#define DATA_ALIGN_ATTRIBUTE __attribute__((aligned(4))) +#else +#define DATA_ALIGN_ATTRIBUTE +#endif + +const unsigned char g_model[] DATA_ALIGN_ATTRIBUTE = { + 0x20, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, + 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x94, 0x48, 0x00, 0x00, 0x34, 0x42, 0x00, 0x00, + 0x1c, 0x42, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x5f, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xd4, 0x41, 0x00, 0x00, + 0xb4, 0x41, 0x00, 0x00, 0x24, 0x03, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, + 0xec, 0x02, 0x00, 0x00, 0xe4, 0x02, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, + 0xbc, 0x02, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0xbd, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x31, 0x2e, 0x35, 0x2e, + 0x30, 0x00, 0x00, 0x00, 0x94, 0xba, 0xff, 0xff, 0x98, 0xba, 0xff, 0xff, + 0x32, 0xbd, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0xfa, 0xee, 0x28, 0xc4, 0xee, 0xfe, 0xcf, 0x0f, 0x1e, 0xf7, 0x1f, 0x06, + 0x0d, 0xed, 0xe9, 0x83, 0x5c, 0xc9, 0x18, 0xe3, 0xf9, 0x14, 0x28, 0x2a, + 0x09, 0xf2, 0x18, 0x34, 0x62, 0xea, 0xef, 0xd6, 0x36, 0xb7, 0x1e, 0xf7, + 0x3b, 0x22, 0x28, 0x39, 0xc2, 0x9d, 0xf1, 0x07, 0x5e, 0x0b, 0x1e, 0x2c, + 0x07, 0xdd, 0xfd, 0xc3, 0xd8, 0x4a, 0xf3, 0x28, 0xa7, 0x16, 0xd5, 0xf1, + 0xc3, 0x05, 0xfd, 0x27, 0xcc, 0xba, 0x1e, 0xcb, 0xd7, 0x3d, 0xd4, 0x29, + 0x00, 0xfd, 0x28, 0x44, 0xfb, 0xf2, 0xf3, 0xb6, 0x4f, 0xcf, 0x09, 0xf0, + 0xfa, 0x45, 0x41, 0x49, 0x05, 0xc5, 0x17, 0x5d, 0x64, 0x00, 0xf8, 0xee, + 0x48, 0x17, 0xf4, 0xe9, 0x2e, 0x4b, 0x2e, 0x3f, 0xdf, 0xee, 0xe4, 0x08, + 0x38, 0xf1, 0x16, 0x13, 0x2f, 0x2a, 0xed, 0xc2, 0xbf, 0x36, 0xf4, 0x02, + 0xcf, 0xaa, 0xd2, 0xfa, 0xac, 0x13, 0xf6, 0xe8, 0xb5, 0x68, 0x12, 0xb6, + 0xce, 0x0e, 0xdf, 0x58, 0xe4, 0x49, 0x14, 0x15, 0x03, 0xed, 0xfa, 0xd4, + 0x40, 0xa7, 0xf6, 0xca, 0xfb, 0x00, 0x4d, 0x5e, 0xe4, 0x55, 0x1d, 0x30, + 0x45, 0xe2, 0xfc, 0x01, 0x48, 0x81, 0xe9, 0xf1, 0x1e, 0xfc, 0x21, 0x32, + 0xed, 0x4b, 0xed, 0xfa, 0x2f, 0xd2, 0xfa, 0xfb, 0x4d, 0xa7, 0xed, 0xc7, + 0x92, 0xdf, 0xe6, 0xdb, 0xf8, 0x1f, 0xd9, 0xfa, 0x91, 0xf5, 0xe5, 0xc5, + 0x8c, 0x17, 0x0f, 0xb9, 0xd2, 0xc7, 0xfe, 0x68, 0xd3, 0x51, 0x2e, 0x49, + 0x1f, 0xbd, 0x01, 0xeb, 0x31, 0x17, 0xf0, 0xef, 0xff, 0xb8, 0x5d, 0x62, + 0x02, 0x0f, 0x1f, 0x78, 0x6a, 0xb0, 0xf9, 0xfe, 0x4f, 0xcc, 0xd3, 0xff, + 0x0a, 0x96, 0x1e, 0x2c, 0xed, 0xbc, 0xf4, 0x0b, 0x42, 0xc8, 0xf1, 0xea, + 0x6e, 0x58, 0xec, 0xc4, 0x99, 0xae, 0xdc, 0xd7, 0x12, 0x87, 0xd8, 0x06, + 0xa2, 0xc2, 0xe6, 0xa2, 0x81, 0x24, 0xe9, 0xac, 0xce, 0xb6, 0x15, 0x6b, + 0xba, 0x00, 0x19, 0x58, 0x29, 0xb6, 0xfe, 0x01, 0x25, 0x96, 0xd2, 0xec, + 0x0e, 0x9c, 0x60, 0x5f, 0xe9, 0xf4, 0xf5, 0x69, 0x6b, 0xb5, 0xe1, 0xf6, + 0x5e, 0xb7, 0xb1, 0xe5, 0x11, 0x9b, 0x18, 0x10, 0xe3, 0xe1, 0xe0, 0x0d, + 0x4f, 0xa5, 0xde, 0xe5, 0x6f, 0xe2, 0xfb, 0x99, 0x82, 0xa5, 0xc9, 0xb6, + 0x1f, 0x46, 0xf3, 0x04, 0xc6, 0xca, 0xd6, 0x97, 0x90, 0x1d, 0xc0, 0x95, + 0xf0, 0x19, 0x30, 0x77, 0xc2, 0x3c, 0xfa, 0x24, 0x02, 0x4d, 0x06, 0x07, + 0x15, 0x02, 0xb0, 0xe7, 0x27, 0x22, 0x67, 0x4d, 0xf1, 0xc2, 0xf4, 0x64, + 0x38, 0x40, 0xdf, 0xf6, 0x3a, 0x43, 0xb8, 0xe1, 0x0d, 0x15, 0x11, 0xfe, + 0xf5, 0xec, 0xf9, 0xe5, 0x22, 0x36, 0xe4, 0xfd, 0x6d, 0xbf, 0x0d, 0x8e, + 0xb7, 0x15, 0xbf, 0x9f, 0x16, 0xad, 0x0a, 0x02, 0x8e, 0x14, 0xda, 0x9b, + 0x8e, 0xc3, 0xa6, 0xca, 0xf5, 0x7f, 0x51, 0x56, 0xc1, 0xb3, 0xd9, 0x35, + 0xf8, 0x7f, 0x04, 0x0a, 0x03, 0x3f, 0xbe, 0xee, 0x19, 0x68, 0x78, 0x50, + 0xf9, 0xa7, 0xf7, 0x7f, 0x1d, 0x76, 0xdb, 0xe8, 0x33, 0xb9, 0xd7, 0xe7, + 0xe8, 0x69, 0x15, 0xf7, 0xf5, 0xb2, 0xfe, 0xe8, 0xf3, 0x5b, 0xe2, 0x06, + 0x6e, 0x09, 0x36, 0xb7, 0xcc, 0x38, 0xbf, 0x8a, 0x28, 0x14, 0x2e, 0x18, + 0xa7, 0x26, 0xcb, 0xb2, 0x95, 0x37, 0xac, 0xcd, 0xd7, 0x51, 0x67, 0x44, + 0xcd, 0x31, 0xde, 0x04, 0xe9, 0x6a, 0x00, 0x13, 0x0a, 0x0c, 0xdd, 0x16, + 0xe0, 0x24, 0x7e, 0x49, 0xf1, 0xb5, 0x04, 0x52, 0x01, 0x50, 0xdd, 0xf5, + 0x26, 0xc9, 0xf4, 0xf8, 0xd6, 0x31, 0x1b, 0xd0, 0xef, 0x03, 0x0a, 0xc0, + 0xd4, 0x4f, 0xe2, 0xfd, 0x72, 0xf4, 0x5a, 0xc9, 0xd7, 0x31, 0xc0, 0x8e, + 0x17, 0x5e, 0x57, 0x00, 0xb4, 0x3a, 0xc8, 0xd2, 0x92, 0x32, 0xcb, 0xd8, + 0xc3, 0xa6, 0x63, 0x26, 0xcf, 0xbc, 0xe8, 0x57, 0x9b, 0xe9, 0xf7, 0x1c, + 0xea, 0x12, 0xf1, 0xf7, 0xdb, 0xb9, 0x7f, 0x16, 0xf6, 0xe0, 0x08, 0x70, + 0xa2, 0xed, 0xcc, 0xf1, 0x1e, 0x10, 0x04, 0xf7, 0xa9, 0xb7, 0x34, 0xaa, + 0x0a, 0xdb, 0x2a, 0xa6, 0xb6, 0x10, 0xea, 0xf8, 0x5e, 0x06, 0x72, 0xdd, + 0xd0, 0xb9, 0xd6, 0xa0, 0x10, 0x9f, 0x5a, 0x17, 0xb1, 0xe7, 0xc0, 0x01, + 0x9d, 0x01, 0xe0, 0xe0, 0xaf, 0x9c, 0x46, 0xd8, 0xaf, 0xe8, 0xce, 0x02, + 0x8a, 0xbb, 0xe4, 0xf6, 0xf3, 0x36, 0x07, 0xca, 0xcb, 0x87, 0x6e, 0xcc, + 0xd6, 0x9e, 0x0a, 0x2a, 0x81, 0xd7, 0xcf, 0xc0, 0x04, 0xeb, 0x24, 0xcc, + 0xc9, 0x95, 0x33, 0x81, 0xf7, 0xad, 0x1c, 0x9c, 0xa4, 0xd6, 0xf9, 0xe6, + 0x3d, 0x84, 0x7f, 0xcc, 0xd4, 0xb0, 0xf4, 0xa2, 0xe9, 0x3c, 0x36, 0xee, + 0xd5, 0xcf, 0xcd, 0x2d, 0x28, 0xbd, 0xff, 0xff, 0xc2, 0xbf, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0xbd, 0xff, 0xff, 0x4c, 0xbd, 0xff, 0xff, 0xe6, 0xbf, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x8a, 0xfe, 0xff, 0xff, + 0xa9, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0xd0, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0xfb, 0xff, 0xff, + 0x4a, 0xfd, 0xff, 0xff, 0x12, 0xc0, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x3e, 0x00, 0x00, 0xff, 0xf9, 0xfd, 0x0a, 0x07, 0x08, 0x07, 0x03, + 0x07, 0xf2, 0xd1, 0x09, 0xf0, 0xe9, 0x28, 0x09, 0xdf, 0x05, 0xfa, 0xf0, + 0xe8, 0xe3, 0x13, 0x0e, 0x08, 0xef, 0xd3, 0xee, 0x0f, 0xe8, 0xeb, 0x14, + 0xf7, 0xed, 0xfd, 0x1f, 0xe8, 0xd5, 0xeb, 0xfc, 0x0e, 0xf4, 0xf7, 0x07, + 0x05, 0xea, 0xf6, 0x1f, 0xf8, 0xdb, 0xdc, 0x0b, 0x03, 0xdd, 0xd8, 0xf3, + 0x0f, 0x19, 0xe1, 0x09, 0xfc, 0xe4, 0x02, 0x04, 0xf1, 0x04, 0xeb, 0xf3, + 0x1e, 0x06, 0xfd, 0x11, 0xfc, 0xfa, 0xf6, 0x1f, 0x0f, 0x02, 0xf5, 0xf7, + 0xff, 0x24, 0xdf, 0xf7, 0xf8, 0xf3, 0xf6, 0xe9, 0xef, 0x03, 0xdd, 0xf2, + 0x28, 0xe1, 0xf2, 0x22, 0xf4, 0x09, 0xf7, 0xf9, 0xf0, 0xd4, 0xf9, 0xee, + 0xff, 0x14, 0xda, 0xf3, 0x11, 0xe2, 0xf6, 0x0c, 0xf2, 0xeb, 0xf8, 0xe8, + 0xe3, 0x08, 0x02, 0x17, 0xf4, 0x0b, 0x0c, 0x27, 0xe6, 0x02, 0x03, 0xf9, + 0x14, 0x18, 0xf6, 0xeb, 0x1f, 0x0c, 0xf1, 0xee, 0xfc, 0x08, 0xf0, 0xfe, + 0xfd, 0xee, 0x17, 0xfd, 0x1c, 0xef, 0xfd, 0xde, 0x04, 0x05, 0xf0, 0x31, + 0xfa, 0x0b, 0xdc, 0x0d, 0xed, 0xf5, 0xfa, 0xf4, 0x08, 0x0c, 0xd7, 0x1e, + 0x15, 0x03, 0xf5, 0x02, 0xf4, 0xfb, 0xed, 0x01, 0xfe, 0xd6, 0x1f, 0xfd, + 0xfd, 0x0e, 0xfa, 0x06, 0xf1, 0xf9, 0xe2, 0x16, 0xe9, 0xf1, 0x03, 0x0d, + 0x0d, 0xdf, 0xf9, 0x1a, 0x0e, 0xf6, 0xfc, 0x0a, 0x19, 0xe2, 0xe0, 0x09, + 0x15, 0xf0, 0xf1, 0x06, 0xf1, 0xe1, 0xef, 0x1a, 0x08, 0xe8, 0xfd, 0x12, + 0x14, 0x06, 0xf1, 0xfc, 0xea, 0xfb, 0xf7, 0xea, 0x1d, 0x09, 0xfa, 0xf6, + 0x08, 0xf2, 0xe7, 0xf8, 0xfc, 0x16, 0xf5, 0x0e, 0x08, 0xf9, 0x0a, 0x03, + 0x26, 0xd8, 0x02, 0xf5, 0xf6, 0xf6, 0xef, 0x1f, 0xe4, 0xe2, 0xfb, 0x02, + 0x1b, 0xe6, 0xde, 0x00, 0xf2, 0xed, 0xfb, 0x18, 0xe4, 0x16, 0x1a, 0x1d, + 0xf1, 0xf6, 0xea, 0x16, 0x05, 0xde, 0xfb, 0x18, 0xf5, 0xe4, 0xfe, 0xe2, + 0x1b, 0x1c, 0x0c, 0xe8, 0x02, 0xee, 0xfb, 0x07, 0x24, 0xf2, 0xe9, 0xfa, + 0x0d, 0x05, 0xf1, 0x03, 0xfe, 0xf6, 0x19, 0x06, 0xff, 0xf9, 0x04, 0xfb, + 0x15, 0xef, 0xf1, 0xf8, 0xe9, 0xe1, 0x10, 0x04, 0xfc, 0xe6, 0x1f, 0xed, + 0x0b, 0xef, 0x00, 0x1e, 0xe6, 0x16, 0xf3, 0x09, 0xfd, 0x08, 0x08, 0x06, + 0x06, 0x23, 0xdf, 0xfc, 0x08, 0xf4, 0xea, 0x0c, 0xf2, 0xe6, 0x18, 0xf5, + 0x02, 0xf9, 0x50, 0x09, 0x01, 0xda, 0x0b, 0x05, 0x12, 0x18, 0xef, 0x04, + 0x0e, 0xd9, 0xff, 0xdc, 0xf6, 0x16, 0xf9, 0xf4, 0xec, 0xff, 0xea, 0xe6, + 0xfa, 0x0a, 0xed, 0xef, 0x02, 0xf0, 0x25, 0x21, 0xf1, 0x26, 0xf5, 0xed, + 0x09, 0xea, 0xea, 0x24, 0xfa, 0x11, 0xfc, 0xdf, 0xf3, 0x0a, 0x28, 0x0c, + 0x19, 0xff, 0xf5, 0xd6, 0x0e, 0xe2, 0x2a, 0x06, 0xfa, 0x03, 0xf9, 0xe6, + 0xef, 0x23, 0xf9, 0xfa, 0xe6, 0xfe, 0xfc, 0x03, 0x06, 0x1a, 0xf9, 0x08, + 0xe0, 0xe5, 0xff, 0x05, 0x01, 0xe7, 0x12, 0x02, 0x1d, 0x05, 0x03, 0x05, + 0x0b, 0xee, 0xed, 0xfc, 0x0f, 0xf3, 0x02, 0xe0, 0x15, 0xdf, 0x02, 0xed, + 0x10, 0x26, 0xef, 0x0d, 0x06, 0xee, 0xef, 0xf6, 0xeb, 0x11, 0x09, 0xf4, + 0xf7, 0x06, 0x0f, 0x01, 0x2a, 0x0b, 0x01, 0xdd, 0xfc, 0xf4, 0xf1, 0x17, + 0x03, 0x04, 0x07, 0xfc, 0x22, 0xfc, 0xde, 0xfe, 0x0b, 0x03, 0xf3, 0xfb, + 0x0c, 0x25, 0x04, 0x19, 0x04, 0x03, 0x01, 0xfa, 0xfb, 0xf7, 0xf6, 0x0e, + 0x15, 0x0e, 0x09, 0xff, 0x06, 0xfa, 0xfb, 0x1e, 0xfb, 0x05, 0x22, 0xf9, + 0xfe, 0xf7, 0x1d, 0xed, 0xdf, 0x18, 0x09, 0xeb, 0xef, 0x04, 0x12, 0xea, + 0xdf, 0xfb, 0xda, 0xf6, 0xdf, 0x17, 0xef, 0xef, 0xe1, 0x1a, 0xd9, 0xe2, + 0xe2, 0xfc, 0x05, 0x11, 0xf6, 0xee, 0xe8, 0xf2, 0xe1, 0x08, 0x26, 0x04, + 0xed, 0x03, 0xe0, 0xfb, 0xee, 0x0c, 0xee, 0xf6, 0x04, 0x2d, 0xf2, 0xd3, + 0xf4, 0xe0, 0xf8, 0x0c, 0xfe, 0x11, 0x0b, 0xd7, 0xfd, 0x18, 0x07, 0x0d, + 0x07, 0x08, 0xf4, 0xc6, 0x0a, 0x0a, 0x1f, 0x0c, 0xf4, 0x1d, 0x02, 0x0b, + 0x09, 0x0e, 0x21, 0xff, 0x17, 0x0b, 0x0d, 0xf2, 0xed, 0xd7, 0x0a, 0xf8, + 0x03, 0x06, 0xfa, 0xe5, 0xfd, 0x03, 0x14, 0x0f, 0xe9, 0x1a, 0xf4, 0xda, + 0x01, 0xe6, 0x09, 0x06, 0x11, 0x0d, 0xfd, 0xeb, 0x16, 0x23, 0xfa, 0x00, + 0x0b, 0x17, 0xf7, 0xda, 0xd7, 0x1b, 0xfa, 0x01, 0x03, 0x05, 0xfe, 0xd6, + 0x02, 0xee, 0xee, 0x02, 0xf3, 0x06, 0xed, 0x03, 0xec, 0x01, 0xf2, 0x0f, + 0x05, 0x17, 0x0b, 0xfb, 0x0f, 0x05, 0x03, 0x13, 0xff, 0x06, 0x02, 0xf5, + 0xf4, 0x18, 0x2b, 0xf0, 0x00, 0x17, 0xfc, 0xfd, 0x05, 0x0b, 0x0e, 0x14, + 0xe1, 0x24, 0x08, 0x24, 0xe6, 0xeb, 0x21, 0x12, 0xfb, 0x12, 0xe7, 0xf4, + 0xe8, 0x0e, 0x18, 0xee, 0xf5, 0xf3, 0xd9, 0xf3, 0xdb, 0xec, 0x0c, 0x1e, + 0xcf, 0x14, 0xdb, 0xe3, 0xdc, 0x02, 0x0c, 0xfb, 0xdb, 0x1b, 0xd0, 0xfe, + 0xf9, 0xfe, 0x2a, 0xf5, 0x00, 0x0b, 0xcd, 0xe0, 0xe2, 0x0e, 0x04, 0xf8, + 0xda, 0x1c, 0xe5, 0x0f, 0xe8, 0xf4, 0xf7, 0x15, 0x06, 0xf8, 0x02, 0xf7, + 0x0f, 0xfb, 0x17, 0xf9, 0xda, 0x01, 0xda, 0xd1, 0xf6, 0x02, 0xfd, 0x16, + 0xf1, 0xe4, 0xfa, 0x07, 0xee, 0x0a, 0xf3, 0xfd, 0xf2, 0x23, 0xf0, 0xe1, + 0x0a, 0x1a, 0x12, 0x1f, 0xef, 0x27, 0x09, 0xf1, 0x0c, 0x13, 0x23, 0xfd, + 0xf5, 0x03, 0xfe, 0x09, 0xfd, 0x16, 0xf8, 0x07, 0x08, 0x25, 0x08, 0xf8, + 0xf6, 0x0a, 0xf1, 0xf5, 0x07, 0x09, 0x05, 0xcc, 0xf8, 0x08, 0x13, 0xf9, + 0x1d, 0x11, 0x0f, 0xdc, 0xee, 0xf3, 0x27, 0xf9, 0xf9, 0x22, 0xfa, 0x0d, + 0xe2, 0x13, 0xfb, 0x11, 0x03, 0x1e, 0xff, 0xfb, 0xed, 0xf1, 0x0e, 0x0b, + 0x0f, 0x00, 0x06, 0xe0, 0x15, 0xf3, 0x13, 0xfc, 0x18, 0xf9, 0xff, 0x09, + 0xfa, 0x1f, 0x12, 0xe5, 0xe2, 0x06, 0xf9, 0xf4, 0x07, 0x15, 0x0b, 0x04, + 0xdb, 0x0d, 0xeb, 0xf3, 0xe6, 0x06, 0xe5, 0xee, 0xd8, 0x22, 0xd8, 0x10, + 0xea, 0xf9, 0x1c, 0xf7, 0xd3, 0x11, 0xc3, 0xf8, 0xde, 0x05, 0x00, 0xe6, + 0x07, 0xfd, 0xd3, 0x03, 0xea, 0xe0, 0x13, 0x14, 0xcf, 0xeb, 0xcd, 0xd3, + 0xde, 0xf5, 0xf0, 0x0c, 0x0c, 0xfa, 0xeb, 0xd3, 0xfb, 0xfd, 0x08, 0xf9, + 0xf4, 0x10, 0xfa, 0xd3, 0xf4, 0x11, 0x11, 0xf8, 0xef, 0xf8, 0xf8, 0xf1, + 0xfc, 0xe1, 0xf7, 0x12, 0x04, 0xf4, 0xfb, 0xed, 0xef, 0x0c, 0xfd, 0x1c, + 0xfe, 0x0e, 0xfd, 0xe2, 0xfe, 0x0a, 0x02, 0xfe, 0xe6, 0x1f, 0xef, 0xe5, + 0xe6, 0xf8, 0x16, 0x27, 0xe8, 0x20, 0x05, 0xe3, 0xf1, 0xef, 0xee, 0xed, + 0x0d, 0x11, 0x16, 0xfb, 0xf3, 0xff, 0x14, 0x01, 0xff, 0x15, 0x10, 0x02, + 0xe5, 0x28, 0x29, 0x13, 0x13, 0x16, 0xe6, 0x00, 0xd2, 0x26, 0xfd, 0x03, + 0x04, 0x05, 0x07, 0x06, 0xf1, 0x0e, 0x05, 0x0d, 0xe2, 0x0f, 0x02, 0xe1, + 0x07, 0xf7, 0x1c, 0xfa, 0x14, 0x30, 0xf7, 0xee, 0x00, 0xfa, 0x3d, 0x06, + 0x1c, 0x04, 0x06, 0x07, 0x05, 0x1a, 0x10, 0xf6, 0xee, 0x0a, 0xeb, 0x04, + 0xeb, 0xdf, 0x1d, 0x09, 0xd5, 0xe8, 0xd6, 0xf4, 0xf0, 0x0f, 0x1d, 0xea, + 0xf2, 0xf8, 0xa6, 0x0b, 0xdc, 0x09, 0x08, 0x24, 0xee, 0x24, 0xaa, 0xe4, + 0xcb, 0x15, 0xef, 0xe7, 0xe9, 0x0c, 0xcf, 0x06, 0xe3, 0x12, 0x11, 0x00, + 0x07, 0x14, 0xd7, 0xde, 0xf6, 0x0f, 0x0b, 0x04, 0xfb, 0x0d, 0xf8, 0x0d, + 0xf6, 0x1b, 0xf1, 0x21, 0xdd, 0xfc, 0xf4, 0xe9, 0xf8, 0xe8, 0xf7, 0x06, + 0x03, 0x1e, 0xce, 0xe1, 0xea, 0xf6, 0x05, 0xf9, 0x16, 0x15, 0x04, 0xe0, + 0x14, 0xf7, 0x1e, 0x1c, 0x0a, 0x27, 0xef, 0xf3, 0x0f, 0xf3, 0xee, 0x04, + 0xf8, 0xf1, 0x07, 0xe3, 0x05, 0x0b, 0x00, 0x1c, 0x15, 0x27, 0x07, 0xf7, + 0xfa, 0x0b, 0xfa, 0xfa, 0x17, 0x13, 0xe1, 0xf5, 0xfb, 0x0c, 0x21, 0x2f, + 0xd7, 0xfb, 0xf5, 0xfd, 0xd3, 0xf4, 0x07, 0x0e, 0xfd, 0x0b, 0xfc, 0xfa, + 0xf5, 0x0e, 0x02, 0xfa, 0xfa, 0x19, 0xfd, 0xfa, 0xfc, 0x13, 0x24, 0x0c, + 0xe4, 0x31, 0xf8, 0x12, 0xf4, 0x04, 0x18, 0x29, 0x27, 0x19, 0xfc, 0x08, + 0x11, 0xe3, 0x07, 0xfe, 0x26, 0x40, 0x05, 0x02, 0x04, 0x02, 0x0f, 0xee, + 0xf4, 0x27, 0xea, 0xf4, 0xf5, 0x11, 0x26, 0x0b, 0xe7, 0x05, 0xd2, 0xf6, + 0xea, 0xfa, 0x0b, 0xf9, 0xfa, 0x16, 0xba, 0x00, 0xfb, 0x0d, 0x0b, 0xf9, + 0xe6, 0xf6, 0xc5, 0xf8, 0xf6, 0x01, 0x0f, 0xed, 0xed, 0x13, 0xcd, 0x0d, + 0xda, 0x06, 0x17, 0xee, 0x07, 0x1d, 0xb8, 0xfa, 0xe2, 0xea, 0xf2, 0xee, + 0x04, 0x00, 0xdc, 0xd0, 0xfb, 0xf5, 0xec, 0xfe, 0xf1, 0x0d, 0xf0, 0xdb, + 0xf9, 0x0d, 0x03, 0x03, 0x0e, 0x0a, 0xda, 0xd6, 0x01, 0xf2, 0x06, 0x14, + 0x1c, 0x1f, 0xe8, 0xe8, 0x0e, 0xfd, 0x0c, 0xf5, 0xf3, 0x3d, 0xf3, 0x05, + 0x10, 0xfa, 0x1b, 0x18, 0x08, 0x36, 0x09, 0xf1, 0xeb, 0xf9, 0x22, 0x01, + 0xf3, 0xf7, 0xff, 0xf0, 0x0c, 0xe9, 0x01, 0x29, 0x21, 0x15, 0x03, 0xee, + 0xe9, 0x1a, 0xf7, 0x15, 0x06, 0x25, 0xfa, 0xf0, 0xe4, 0xf1, 0x1f, 0x01, + 0xdc, 0x2d, 0xce, 0xe9, 0xea, 0x0b, 0x06, 0x2c, 0x0a, 0x30, 0xe7, 0x09, + 0xf4, 0xf0, 0x10, 0x29, 0xf9, 0x3d, 0xe7, 0xdc, 0xe4, 0xf7, 0x3b, 0x27, + 0x23, 0x3a, 0x0a, 0x06, 0x0e, 0xfd, 0x2c, 0x07, 0x2b, 0x1c, 0xfa, 0x00, + 0xf9, 0x11, 0xea, 0x14, 0xeb, 0xfc, 0x18, 0x03, 0xf1, 0x16, 0x12, 0x04, + 0xcf, 0x12, 0xdd, 0xe4, 0x0e, 0xf0, 0x09, 0xe8, 0xf3, 0xfb, 0xa8, 0xf9, + 0xee, 0xfb, 0x1e, 0x1d, 0xfd, 0x05, 0xab, 0xe5, 0xff, 0x01, 0xfe, 0x04, + 0xf9, 0x02, 0xb9, 0xdc, 0xdf, 0x05, 0xf1, 0xef, 0xf1, 0x1e, 0xc7, 0xee, + 0xf7, 0x1e, 0x00, 0x00, 0xf8, 0x10, 0xec, 0xe8, 0x04, 0x0f, 0xf6, 0xff, + 0x04, 0x09, 0xe0, 0x0a, 0x0e, 0xe4, 0xf0, 0xf1, 0x16, 0x2b, 0xd3, 0xe1, + 0x0a, 0xef, 0xf9, 0xfe, 0x0b, 0x22, 0xf5, 0x01, 0x0a, 0xf8, 0x02, 0x00, + 0x17, 0x19, 0xf3, 0x05, 0x21, 0xfa, 0xee, 0xee, 0x12, 0xf2, 0xfa, 0xf5, + 0x05, 0x12, 0xee, 0xe4, 0x28, 0xfa, 0xf1, 0x03, 0x15, 0x16, 0x18, 0xfd, + 0x0f, 0x21, 0x04, 0xf4, 0xe5, 0x0c, 0x06, 0x13, 0xde, 0x36, 0xe8, 0xfb, + 0xe7, 0xfd, 0xf6, 0x12, 0x0e, 0x1d, 0xea, 0xf8, 0xd4, 0xe8, 0x19, 0x07, + 0xe5, 0x1c, 0xf7, 0x0c, 0xef, 0x05, 0x0f, 0x09, 0xdd, 0x1a, 0xea, 0xd7, + 0xf9, 0xf9, 0x12, 0x17, 0x2e, 0x10, 0x08, 0xfe, 0x14, 0xf5, 0x1d, 0xfa, + 0x06, 0x33, 0xed, 0xfe, 0xf7, 0x11, 0xf0, 0x15, 0xe2, 0x24, 0xf6, 0x0a, + 0xe2, 0xfc, 0x23, 0x12, 0xdd, 0x11, 0xfd, 0xe5, 0x08, 0xff, 0x15, 0xf6, + 0xf1, 0x1b, 0xae, 0xfe, 0xe6, 0x15, 0x2c, 0x2d, 0x15, 0x15, 0xc5, 0xf8, + 0xea, 0xe7, 0x07, 0x04, 0xfe, 0x28, 0xa1, 0xf2, 0xe1, 0xf9, 0xf8, 0xff, + 0xf4, 0x22, 0xb4, 0xdb, 0x03, 0x20, 0xe6, 0xf3, 0x0e, 0x19, 0xe3, 0x0a, + 0xfa, 0xee, 0xf3, 0xe5, 0xd8, 0xf9, 0xf1, 0xde, 0x06, 0x05, 0xf2, 0xf5, + 0xe7, 0x16, 0xd8, 0xfe, 0x07, 0xea, 0xee, 0x0e, 0xfa, 0xff, 0xdb, 0xe7, + 0x03, 0xed, 0x01, 0xfd, 0x09, 0x1a, 0xfa, 0xe6, 0x05, 0x10, 0xe9, 0x01, + 0x1f, 0x13, 0xf7, 0xf6, 0xfb, 0x13, 0xff, 0xdb, 0xed, 0xfe, 0x0a, 0x10, + 0x09, 0x29, 0xf5, 0x04, 0xf5, 0x26, 0x0d, 0x0c, 0xf9, 0x16, 0xfa, 0x02, + 0xf4, 0x2e, 0xde, 0xf5, 0xe1, 0x1d, 0xfb, 0x02, 0x0b, 0x23, 0x07, 0xea, + 0xd9, 0x0a, 0xf3, 0x0a, 0x0f, 0x1e, 0xe7, 0xf1, 0xd7, 0x0b, 0xf6, 0xff, + 0x0d, 0x24, 0xcc, 0x0a, 0xee, 0xda, 0x14, 0x12, 0x11, 0x29, 0xf4, 0x1a, + 0xef, 0x0b, 0xfa, 0xec, 0x0c, 0x1b, 0xf4, 0xff, 0xf5, 0xef, 0x0f, 0x10, + 0xd4, 0x04, 0xf9, 0xf8, 0xec, 0xf9, 0x21, 0x05, 0xd3, 0x27, 0xf3, 0x17, + 0xff, 0xf6, 0x15, 0xf9, 0xed, 0x0a, 0xac, 0x02, 0xfd, 0xfb, 0x04, 0x29, + 0x06, 0x03, 0xb8, 0xe6, 0xd5, 0x17, 0x09, 0x1b, 0xf6, 0x1b, 0xab, 0xdc, + 0xdf, 0xfd, 0x06, 0x09, 0x09, 0x37, 0xbb, 0xed, 0x19, 0xd7, 0xe2, 0xdd, + 0x05, 0x01, 0xec, 0xfb, 0xe4, 0x0e, 0xeb, 0xf0, 0x03, 0x17, 0x04, 0xeb, + 0x09, 0xee, 0xeb, 0xe7, 0x0c, 0x16, 0xcb, 0x0e, 0x17, 0xd8, 0xe1, 0xf8, + 0x2b, 0x19, 0xde, 0xeb, 0x10, 0xf2, 0xff, 0xf8, 0xee, 0x0e, 0xe7, 0xf0, + 0x15, 0x08, 0xf8, 0xdf, 0x06, 0x0d, 0xf9, 0x14, 0xfa, 0x0b, 0x04, 0xfd, + 0x15, 0x23, 0x20, 0xff, 0xfd, 0x1d, 0x0c, 0xf1, 0xfe, 0x15, 0x0a, 0x02, + 0xed, 0xfe, 0xfb, 0x04, 0xfb, 0x1e, 0xdd, 0x05, 0xe0, 0x16, 0xf9, 0xf6, + 0xfd, 0x32, 0xdc, 0xf2, 0xd3, 0x08, 0xf4, 0xec, 0x17, 0x25, 0xe2, 0xf0, + 0xee, 0xf1, 0x0d, 0xfe, 0x13, 0x2d, 0x01, 0x11, 0xd4, 0xe4, 0x07, 0xfb, + 0x32, 0x11, 0x14, 0x07, 0xd7, 0x02, 0x10, 0xeb, 0x2b, 0x1d, 0x01, 0xfc, + 0xf3, 0xf0, 0x13, 0x1a, 0xdb, 0x20, 0x00, 0xf0, 0xf0, 0x05, 0x16, 0x03, + 0xd4, 0xe3, 0xc2, 0xf0, 0x06, 0x02, 0x1e, 0x0a, 0xec, 0x1f, 0xab, 0xea, + 0xfa, 0xe3, 0x20, 0x22, 0x03, 0x1b, 0xb3, 0x0e, 0xe3, 0xf3, 0x1d, 0x27, + 0xe3, 0x10, 0xa7, 0xda, 0xf3, 0x00, 0x0a, 0x0a, 0x04, 0xfb, 0xb2, 0x0f, + 0x0c, 0xf5, 0x07, 0xff, 0x13, 0x1e, 0xdb, 0xf6, 0xf9, 0xef, 0xe8, 0xe7, + 0xfb, 0x18, 0xeb, 0xec, 0x09, 0xda, 0xf1, 0xf0, 0x0b, 0x04, 0xe1, 0xfa, + 0x1c, 0x25, 0xee, 0x01, 0x0b, 0x29, 0xd7, 0x0c, 0x04, 0x0b, 0xef, 0xfd, + 0x1c, 0xfc, 0xf1, 0xfb, 0x0b, 0x0f, 0xdf, 0xed, 0x17, 0x38, 0x0c, 0xd7, + 0xff, 0xfd, 0x01, 0xfc, 0xfb, 0xfb, 0x18, 0x1a, 0x18, 0xe3, 0xf9, 0xf4, + 0xfa, 0x20, 0x06, 0x09, 0x11, 0x08, 0x1d, 0xf8, 0xfa, 0x1d, 0xf5, 0x1c, + 0xf5, 0xfe, 0x03, 0x07, 0xe4, 0x33, 0xc8, 0x0c, 0xe1, 0x13, 0xff, 0xe5, + 0x10, 0x2c, 0xd3, 0xf0, 0xed, 0x04, 0x07, 0x01, 0xf1, 0x16, 0xe0, 0x13, + 0xfa, 0x11, 0x07, 0xfa, 0x19, 0x16, 0x01, 0x00, 0x07, 0x26, 0x00, 0xec, + 0x1d, 0x23, 0x05, 0xf4, 0x07, 0x17, 0x2c, 0x1d, 0xee, 0xf0, 0x0c, 0x09, + 0xe3, 0x1a, 0x24, 0x0b, 0xf3, 0x1e, 0xce, 0xfe, 0xfe, 0x12, 0x21, 0x1a, + 0xf6, 0x23, 0xc3, 0x03, 0xf4, 0x10, 0x1a, 0x2a, 0xf4, 0x08, 0xbf, 0xff, + 0x04, 0xf4, 0x0b, 0x1d, 0x1a, 0xf8, 0xcc, 0x00, 0xf7, 0x13, 0xf4, 0xfd, + 0xf4, 0x19, 0xbd, 0xef, 0x0c, 0x0d, 0x02, 0xfc, 0x12, 0x13, 0xe9, 0xe7, + 0xf5, 0xfa, 0xfa, 0xf6, 0x1a, 0x2e, 0xce, 0xd4, 0x01, 0x12, 0xfd, 0xfc, + 0x26, 0x10, 0xcc, 0xe7, 0xee, 0x13, 0xee, 0xff, 0xef, 0xea, 0x00, 0x0e, + 0x1a, 0x17, 0x04, 0x0c, 0x04, 0x0c, 0xe6, 0xf3, 0xf6, 0xdb, 0xdd, 0x04, + 0xf4, 0x22, 0x11, 0x16, 0xf3, 0x07, 0xec, 0xf8, 0xf2, 0x07, 0x03, 0x02, + 0xf5, 0x0a, 0xf6, 0x02, 0x1d, 0x1b, 0x11, 0x06, 0xf8, 0x06, 0x02, 0xea, + 0xf3, 0x1d, 0xce, 0x00, 0xed, 0xf9, 0xef, 0xf6, 0xec, 0x22, 0xc7, 0xf0, + 0xed, 0xdb, 0xe0, 0x02, 0x11, 0x07, 0xe8, 0xf0, 0xd1, 0xed, 0xff, 0xfd, + 0x0c, 0x2e, 0xd4, 0xed, 0xec, 0x0e, 0xf1, 0x07, 0x01, 0x0e, 0x0e, 0xfe, + 0xda, 0x0b, 0x0a, 0x0a, 0x1f, 0x2e, 0x13, 0x07, 0x00, 0x07, 0x14, 0x21, + 0xe9, 0xfc, 0xf0, 0x1e, 0xd7, 0xea, 0x34, 0x07, 0xc6, 0x0c, 0xd4, 0xec, + 0xfd, 0x06, 0x24, 0x0a, 0xf3, 0x15, 0xaf, 0xff, 0xe9, 0xf1, 0x0d, 0x3e, + 0xe9, 0x18, 0xba, 0x13, 0xed, 0xd7, 0x0b, 0x31, 0x05, 0x0e, 0xaf, 0x13, + 0xd6, 0x0e, 0x10, 0x02, 0x02, 0x14, 0xcb, 0xd5, 0xf9, 0x0c, 0xf9, 0x0e, + 0x1f, 0x24, 0xd5, 0xeb, 0xff, 0xf1, 0xf5, 0x0c, 0x08, 0x07, 0xf4, 0xd7, + 0x06, 0x10, 0xe8, 0xef, 0xfc, 0x2f, 0xee, 0xf1, 0x18, 0xf8, 0xf4, 0x02, + 0x11, 0x21, 0xd3, 0x12, 0x14, 0xe4, 0xf4, 0x02, 0x05, 0x24, 0xca, 0xf2, + 0xf3, 0xeb, 0xe7, 0xf8, 0x16, 0x1a, 0xeb, 0x0d, 0x05, 0x16, 0xf1, 0xec, + 0x11, 0x1c, 0x09, 0x1e, 0xe0, 0xe6, 0xfa, 0x0e, 0x0d, 0x2a, 0xea, 0x2e, + 0xed, 0xf9, 0xf7, 0x16, 0x09, 0x05, 0xdd, 0xd6, 0x02, 0xeb, 0xf5, 0xf3, + 0xe4, 0x3b, 0xed, 0x04, 0xe0, 0x0e, 0xfd, 0x09, 0xfd, 0x35, 0xdc, 0x18, + 0xf3, 0x04, 0xfa, 0x05, 0x15, 0x34, 0xe5, 0xe1, 0xe4, 0xf4, 0xe0, 0xf9, + 0x08, 0x32, 0x04, 0x08, 0xf4, 0x0f, 0xff, 0x08, 0x09, 0x2f, 0x06, 0x02, + 0xfd, 0x05, 0x0c, 0x24, 0xe3, 0x1e, 0xf5, 0x0c, 0xdd, 0xf8, 0x18, 0x20, + 0xd8, 0x14, 0xef, 0xf4, 0x17, 0x08, 0x25, 0x14, 0x04, 0x06, 0xb0, 0xf5, + 0xf5, 0x09, 0x0f, 0x3e, 0xff, 0x28, 0xb3, 0xf5, 0x19, 0xd8, 0x14, 0x21, + 0xd9, 0xf7, 0xb7, 0xe5, 0xfe, 0xe7, 0x07, 0x1e, 0x04, 0x15, 0xc5, 0xf9, + 0x14, 0x20, 0xeb, 0x01, 0x01, 0x18, 0xce, 0x00, 0xe6, 0xe2, 0xf7, 0xfb, + 0xf3, 0x0d, 0xd3, 0xf3, 0x04, 0xf8, 0xf0, 0x03, 0xf1, 0x25, 0xb5, 0xef, + 0x05, 0xe0, 0x01, 0xf6, 0x04, 0x16, 0xd1, 0x01, 0x0a, 0x21, 0x01, 0x05, + 0x0e, 0x01, 0xf0, 0x0a, 0xf3, 0x00, 0x03, 0xf8, 0xfa, 0x03, 0x0b, 0xde, + 0xfe, 0xff, 0xfb, 0xea, 0x09, 0x02, 0xf5, 0xe8, 0xe7, 0x08, 0x00, 0xf5, + 0xf8, 0x0f, 0x13, 0xfa, 0xeb, 0xe8, 0xfb, 0x1f, 0x08, 0x16, 0xe6, 0xfa, + 0xe1, 0x00, 0x03, 0xdd, 0xf1, 0x26, 0xe5, 0x1d, 0xd9, 0xff, 0xf2, 0xf8, + 0xff, 0x33, 0xea, 0xe5, 0x03, 0x0c, 0x07, 0xf9, 0xf8, 0x0f, 0xe1, 0x1e, + 0xdd, 0x0f, 0x00, 0xf1, 0x06, 0x21, 0x09, 0x05, 0xf3, 0xec, 0xe6, 0x04, + 0x07, 0x32, 0xf1, 0xf9, 0xf2, 0x01, 0x18, 0x1f, 0xd2, 0xe2, 0x0a, 0xf4, + 0xca, 0xfc, 0x28, 0x16, 0xc2, 0x10, 0xf2, 0xfc, 0x08, 0xe9, 0x2a, 0x0f, + 0xfa, 0xf5, 0xa9, 0x07, 0xec, 0xe9, 0x19, 0x43, 0x0b, 0x1c, 0xa6, 0xe9, + 0xf4, 0x16, 0x0d, 0x2b, 0xfc, 0x11, 0x9a, 0xe1, 0xf1, 0x1c, 0xf5, 0x0f, + 0xe4, 0x18, 0xc0, 0xd9, 0x14, 0x26, 0xe6, 0xf8, 0x0a, 0x17, 0xec, 0xfb, + 0xe1, 0x22, 0xdf, 0xf2, 0xfe, 0x1e, 0xd4, 0xeb, 0xd7, 0x0e, 0x08, 0xf6, + 0xef, 0xfc, 0xe6, 0xd4, 0xf7, 0x0b, 0xfb, 0xf5, 0x01, 0x25, 0xd7, 0xfb, + 0x0d, 0xfe, 0xff, 0xf3, 0x1d, 0x32, 0xfe, 0xee, 0x12, 0xf2, 0x0c, 0xec, + 0x02, 0x10, 0xef, 0x01, 0xf2, 0x0b, 0xf3, 0xf7, 0xfa, 0x25, 0xfb, 0x0d, + 0x11, 0x15, 0x04, 0xfc, 0x0c, 0x21, 0x12, 0x29, 0x00, 0xfa, 0xf6, 0xf5, + 0x06, 0x22, 0xea, 0xe2, 0xee, 0x00, 0xfd, 0xf0, 0x0b, 0x1d, 0xd3, 0xe4, + 0xe4, 0x0a, 0xfc, 0xe8, 0xea, 0x2c, 0xed, 0xed, 0xef, 0xe8, 0xf2, 0x05, + 0xfd, 0x15, 0xd8, 0xda, 0xca, 0xee, 0xfa, 0x00, 0xfe, 0x0e, 0xf2, 0xf0, + 0x0e, 0xf5, 0x04, 0x03, 0x1d, 0x2b, 0xee, 0x05, 0x0f, 0x10, 0x13, 0x35, + 0xe2, 0x04, 0x10, 0xdf, 0xcf, 0xeb, 0x40, 0x26, 0xe4, 0x03, 0xf3, 0xf9, + 0xf5, 0x14, 0x24, 0x2a, 0xdf, 0xfe, 0xab, 0xe5, 0xfe, 0x1c, 0x27, 0x35, + 0xdb, 0xff, 0xac, 0x01, 0xf6, 0xfc, 0x19, 0x1a, 0x11, 0x1f, 0xa8, 0xf5, + 0x02, 0x0f, 0x1a, 0x1f, 0xf7, 0xf2, 0xa2, 0x00, 0x15, 0x22, 0xe4, 0x13, + 0x00, 0x09, 0xd9, 0xd5, 0x02, 0x19, 0xfd, 0xf8, 0xe7, 0xff, 0xfb, 0xe0, + 0xef, 0xf7, 0xee, 0xf3, 0xf3, 0x19, 0xb0, 0xdf, 0x00, 0x0f, 0x08, 0xf3, + 0x15, 0x17, 0xec, 0x0f, 0x11, 0x14, 0x02, 0x08, 0x10, 0x17, 0xe6, 0x08, + 0xf7, 0x00, 0xed, 0xf7, 0x29, 0x07, 0x10, 0x05, 0x05, 0xe7, 0xed, 0xf4, + 0xf9, 0x15, 0xf9, 0xf0, 0x08, 0x00, 0x03, 0x09, 0x21, 0x28, 0xf6, 0x0e, + 0xfb, 0xf3, 0x03, 0xf7, 0x0f, 0x0c, 0xf0, 0xf5, 0xe3, 0xd8, 0xf8, 0xf2, + 0x09, 0x1c, 0xe7, 0xfb, 0xe4, 0xf6, 0xfa, 0xf8, 0xf1, 0x42, 0xf6, 0xda, + 0xdd, 0xd7, 0xfa, 0xff, 0x2f, 0x2c, 0xda, 0x0a, 0xde, 0xec, 0xf1, 0x14, + 0xfb, 0x1d, 0xeb, 0xee, 0xf2, 0xeb, 0xf3, 0xed, 0x0e, 0x35, 0xf0, 0x06, + 0x19, 0x04, 0x2f, 0x23, 0xe2, 0x07, 0x13, 0x0f, 0xe9, 0xf0, 0x22, 0x2e, + 0xd9, 0x1a, 0xcb, 0xed, 0xfd, 0x04, 0x27, 0x1e, 0xf6, 0x07, 0x96, 0xd6, + 0xd8, 0x11, 0x18, 0x56, 0xd2, 0xfb, 0x92, 0xfc, 0x0b, 0x0a, 0x17, 0x2c, + 0xe5, 0x04, 0xa2, 0xf8, 0xe2, 0x04, 0x1a, 0x0d, 0xeb, 0x11, 0xa2, 0xe5, + 0xe5, 0xf8, 0x02, 0xf7, 0x17, 0x03, 0xca, 0xe9, 0x0c, 0x1f, 0xfe, 0xf5, + 0x18, 0x12, 0xdd, 0x08, 0x15, 0xff, 0xfc, 0xf6, 0xe1, 0x1d, 0xe2, 0xe1, + 0xfe, 0xfc, 0x03, 0xff, 0xf2, 0x23, 0xd2, 0x01, 0x13, 0xdd, 0xf3, 0xf4, + 0xf2, 0x07, 0xef, 0x03, 0x15, 0x21, 0xd8, 0xf8, 0x09, 0xf3, 0xe8, 0xea, + 0xe8, 0xf2, 0x08, 0xf0, 0x04, 0x1a, 0xf2, 0x19, 0xfb, 0x1b, 0x15, 0xfc, + 0x1d, 0x30, 0xe5, 0x1e, 0x09, 0xe8, 0xe9, 0x09, 0xf7, 0x2a, 0xe1, 0x0e, + 0x00, 0x21, 0xf3, 0xff, 0xfb, 0x01, 0xdf, 0xf2, 0xfe, 0xf4, 0xfc, 0xf0, + 0x0b, 0x0b, 0xdd, 0xe4, 0xd2, 0x14, 0xf7, 0xfe, 0x0b, 0x39, 0x01, 0xe6, + 0xe4, 0x27, 0xfa, 0xe4, 0x04, 0x2c, 0xe2, 0x04, 0xf5, 0x07, 0xf2, 0x03, + 0xf0, 0x10, 0xf5, 0xf6, 0xfc, 0x16, 0x22, 0x1b, 0xf8, 0x11, 0xe4, 0x09, + 0xf6, 0xf0, 0x41, 0x1e, 0xcf, 0x04, 0xea, 0xee, 0x0e, 0xf6, 0x1b, 0x2f, + 0xc7, 0xf1, 0xba, 0xef, 0x0f, 0x16, 0x1e, 0x39, 0x05, 0x1e, 0x90, 0xe6, + 0x0d, 0xfa, 0x22, 0x3f, 0xe3, 0x23, 0xa5, 0xe3, 0xe9, 0x0f, 0x05, 0x27, + 0x02, 0x11, 0x99, 0x05, 0xfa, 0x05, 0x03, 0x01, 0xff, 0x26, 0xd3, 0xf7, + 0xf7, 0xf9, 0x05, 0xf4, 0xef, 0x23, 0xd2, 0xdd, 0x05, 0x08, 0xfa, 0xff, + 0x03, 0x04, 0xbd, 0xd7, 0x14, 0x06, 0xef, 0x06, 0xe5, 0x05, 0xea, 0xea, + 0x02, 0xfd, 0x0d, 0x00, 0x08, 0xff, 0xe7, 0xfb, 0xfe, 0x13, 0xfe, 0xec, + 0xf9, 0x02, 0xf3, 0xff, 0xff, 0x08, 0x04, 0xed, 0x19, 0x1d, 0xfa, 0x0a, + 0x0d, 0xf2, 0x0f, 0xec, 0x25, 0x1c, 0xec, 0x0b, 0x01, 0xff, 0x01, 0xf6, + 0x08, 0x09, 0xe8, 0xe2, 0xec, 0x23, 0xe5, 0xe9, 0xf0, 0x2e, 0xbd, 0xe1, + 0xef, 0x14, 0xe9, 0xf6, 0xf5, 0x1d, 0xdc, 0xe3, 0xd7, 0xfc, 0xf9, 0xf2, + 0xfe, 0x24, 0xf2, 0x05, 0xd5, 0xed, 0xe9, 0xf9, 0xfa, 0x2d, 0xf0, 0xfe, + 0xee, 0xf2, 0xe8, 0xf7, 0x06, 0x14, 0x01, 0x10, 0x06, 0xf3, 0x0e, 0x0e, + 0xc2, 0x1d, 0xf2, 0x1c, 0xed, 0xe3, 0x53, 0x21, 0xb8, 0x0c, 0xde, 0x03, + 0x15, 0xeb, 0x46, 0x39, 0xdf, 0xf6, 0xa3, 0xee, 0xf6, 0xe0, 0x33, 0x50, + 0xdd, 0x27, 0x9f, 0x07, 0x13, 0xe2, 0x1f, 0x35, 0xed, 0x1f, 0xb7, 0x07, + 0x11, 0xed, 0x17, 0x28, 0xf4, 0x20, 0xc1, 0xec, 0xef, 0x16, 0x02, 0xfa, + 0xe0, 0x1b, 0xf7, 0xdb, 0xfd, 0x0a, 0xe7, 0xfb, 0xe7, 0x25, 0xe2, 0xe7, + 0xf8, 0xf0, 0xee, 0xe9, 0x02, 0x06, 0xc9, 0xe4, 0x14, 0xe3, 0xe2, 0xf7, + 0xf8, 0xfd, 0xdd, 0xe2, 0x08, 0x0a, 0xe4, 0x05, 0xf5, 0x16, 0xe7, 0x01, + 0x00, 0x1c, 0xe7, 0xf0, 0xf6, 0x19, 0xfe, 0x0c, 0xf2, 0x06, 0x03, 0xe8, + 0x0b, 0xfe, 0xe3, 0x19, 0x08, 0x1a, 0x10, 0xfd, 0x00, 0x21, 0xf0, 0xeb, + 0x18, 0x02, 0xf3, 0x04, 0xf0, 0x18, 0xdb, 0x05, 0x01, 0xde, 0xed, 0xe9, + 0x23, 0x15, 0xaf, 0xe6, 0xf1, 0x0a, 0xe6, 0xea, 0x01, 0x18, 0xd8, 0xfd, + 0xf1, 0xe6, 0xec, 0xf5, 0x0e, 0x1e, 0xcc, 0xfc, 0xe7, 0x00, 0xe9, 0x11, + 0x00, 0x30, 0xf9, 0x14, 0xf4, 0x19, 0xdd, 0xf7, 0xf7, 0x2f, 0xf4, 0xf2, + 0xff, 0x27, 0x15, 0x1c, 0xbc, 0x2f, 0xe9, 0x14, 0xf5, 0xe8, 0x44, 0x30, + 0xe8, 0x1d, 0xe4, 0x18, 0x11, 0x00, 0x0c, 0x2b, 0xf3, 0x29, 0x96, 0xe0, + 0x06, 0xee, 0x3e, 0x55, 0xdc, 0x13, 0x98, 0xdf, 0xf0, 0xfe, 0x17, 0x33, + 0xe8, 0x09, 0xa3, 0x07, 0xef, 0x0e, 0x1d, 0x37, 0xdd, 0xfe, 0xb5, 0x00, + 0xf7, 0xe0, 0xea, 0xfd, 0xfd, 0x19, 0xbc, 0xfd, 0x15, 0xfe, 0x01, 0xf3, + 0xd5, 0x20, 0xbf, 0xe3, 0x15, 0x0e, 0xf0, 0xf6, 0xf2, 0x14, 0xcc, 0xf0, + 0xf7, 0x04, 0xf2, 0xff, 0x0b, 0x02, 0xd2, 0xd8, 0xfa, 0xfc, 0xe5, 0x02, + 0x00, 0xfb, 0xf0, 0xdc, 0x1e, 0x10, 0x02, 0x01, 0x00, 0x18, 0xe9, 0xdb, + 0x1e, 0xf6, 0xfc, 0x03, 0xef, 0x0a, 0x00, 0x16, 0x00, 0x0f, 0xf4, 0x16, + 0xfa, 0x0b, 0xe2, 0xfa, 0xe0, 0x07, 0xfb, 0x02, 0x21, 0x0e, 0xdd, 0x0b, + 0xea, 0xf0, 0xeb, 0xfb, 0x19, 0x09, 0xd4, 0xf2, 0xef, 0x0b, 0x00, 0xeb, + 0x1a, 0x2f, 0xea, 0x06, 0x03, 0xf6, 0xf8, 0xfb, 0xfe, 0x1d, 0xea, 0xdd, + 0xed, 0xfd, 0xfb, 0xe7, 0xfe, 0x18, 0xf4, 0xfc, 0x0b, 0xf6, 0xfc, 0x0b, + 0xfb, 0x28, 0x07, 0xff, 0x07, 0x1e, 0x03, 0x21, 0xcf, 0x22, 0x05, 0xe6, + 0xea, 0xe7, 0x43, 0x2e, 0xe7, 0x14, 0xfb, 0x0a, 0x1e, 0xfe, 0x2c, 0x24, + 0xd5, 0xfd, 0x9e, 0xd1, 0xf2, 0x1c, 0x32, 0x51, 0x01, 0xf3, 0xac, 0xe1, + 0xf4, 0xe5, 0x1c, 0x37, 0xf1, 0x0f, 0xa7, 0xdb, 0x00, 0xf6, 0x0f, 0x18, + 0xe1, 0x10, 0xc9, 0xc5, 0xe8, 0xeb, 0xf2, 0xfd, 0xf6, 0x02, 0xc2, 0xff, + 0x00, 0x19, 0x03, 0x0f, 0x02, 0x22, 0xd4, 0xe7, 0x07, 0x0f, 0xe5, 0x1a, + 0x09, 0x0b, 0xdc, 0xd2, 0x00, 0x05, 0xee, 0xf8, 0xdc, 0x14, 0xd0, 0x0a, + 0x0a, 0xfa, 0xeb, 0x04, 0xf3, 0x06, 0xde, 0x05, 0xfb, 0xfd, 0xe3, 0xec, + 0xfd, 0x14, 0xd7, 0x11, 0x0e, 0xe6, 0x06, 0xec, 0xde, 0x22, 0xd7, 0x00, + 0x03, 0xf5, 0xf5, 0x0d, 0x01, 0x05, 0xea, 0x0b, 0x16, 0x04, 0xff, 0x13, + 0xf3, 0x12, 0xd2, 0xdf, 0x0b, 0xe4, 0x06, 0xf6, 0x08, 0x2d, 0xd3, 0xd6, + 0xe7, 0x0a, 0xec, 0xff, 0xfe, 0x01, 0xdf, 0xf4, 0xdf, 0x1c, 0xfe, 0xf9, + 0xf7, 0x13, 0xca, 0xff, 0x03, 0x06, 0xe9, 0xf7, 0x06, 0x08, 0xd7, 0xf3, + 0xed, 0x08, 0xe3, 0xfd, 0x0c, 0x11, 0x15, 0xfb, 0x15, 0x08, 0x28, 0x40, + 0xe7, 0x0d, 0x08, 0xec, 0xe8, 0x16, 0x67, 0x46, 0xc8, 0x16, 0xf1, 0x02, + 0x24, 0x00, 0x3a, 0x43, 0xd6, 0x12, 0xae, 0xe7, 0xf4, 0xf8, 0x3a, 0x65, + 0xe4, 0x0c, 0xb2, 0xef, 0x1f, 0xe8, 0x29, 0x59, 0xf8, 0x11, 0xc4, 0xe1, + 0xfe, 0xfa, 0x27, 0x43, 0xc9, 0x1e, 0xbb, 0xfb, 0xf3, 0x13, 0x15, 0x0d, + 0xf1, 0x13, 0xcd, 0xf0, 0x07, 0x19, 0x07, 0x00, 0xd8, 0xeb, 0xbf, 0xf0, + 0xfc, 0xf6, 0xef, 0x16, 0x01, 0x02, 0xc1, 0xdf, 0xfd, 0xe9, 0x06, 0x06, + 0xf1, 0x08, 0xd7, 0xcc, 0xfb, 0x0e, 0xfc, 0x14, 0xf2, 0x1a, 0xe2, 0x0d, + 0xeb, 0x09, 0x07, 0x10, 0xe6, 0x13, 0xeb, 0xf5, 0x15, 0x14, 0xeb, 0xfe, + 0xf9, 0x17, 0xd2, 0xe3, 0x1e, 0xf5, 0x04, 0x0a, 0xf1, 0x0e, 0xde, 0xe7, + 0x01, 0x20, 0x0c, 0xfc, 0xdc, 0xf9, 0xe5, 0xe9, 0xff, 0x1d, 0x0a, 0xfe, + 0xec, 0x25, 0xaf, 0xd2, 0x01, 0x16, 0xfc, 0x17, 0xe8, 0x1e, 0xcd, 0xd9, + 0xe2, 0xf1, 0xeb, 0x08, 0xff, 0x33, 0xe5, 0xfb, 0xeb, 0x04, 0xfe, 0xf7, + 0xfd, 0x1f, 0xee, 0xff, 0xed, 0xf8, 0xe0, 0xff, 0xfd, 0x2b, 0x0a, 0xf5, + 0x15, 0x1d, 0xf3, 0x3f, 0x16, 0xf6, 0xf2, 0xee, 0xf4, 0xef, 0xf0, 0x56, + 0x0a, 0x1a, 0xbc, 0xfc, 0x2f, 0xfb, 0xf0, 0x56, 0x1e, 0x0e, 0xc6, 0xe8, + 0x06, 0x0b, 0x11, 0x62, 0x3e, 0xf9, 0xb8, 0xc9, 0xed, 0xeb, 0x02, 0x63, + 0x2c, 0xfd, 0xc5, 0xe9, 0x00, 0x17, 0x0f, 0x37, 0xfe, 0x20, 0xcc, 0xe0, + 0xe0, 0x0e, 0xe6, 0x20, 0x0a, 0xfd, 0xdf, 0xee, 0x0b, 0x02, 0xee, 0x1f, + 0xfb, 0x06, 0xd2, 0xed, 0xfe, 0xeb, 0xfc, 0x12, 0xfd, 0x14, 0x00, 0xd8, + 0x08, 0xf6, 0xec, 0x17, 0xf9, 0x10, 0x00, 0xd9, 0x18, 0xf1, 0xee, 0x0f, + 0xf4, 0x03, 0xee, 0xeb, 0xf0, 0xef, 0xf2, 0x06, 0x04, 0x00, 0xf4, 0x0f, + 0x09, 0x06, 0xf7, 0x0b, 0xfd, 0x01, 0x03, 0x03, 0xf4, 0xf6, 0xdd, 0x14, + 0x1c, 0xef, 0xf1, 0xdd, 0xf7, 0x13, 0xd9, 0x15, 0xef, 0x02, 0xd2, 0xe7, + 0x05, 0x05, 0xe2, 0x09, 0xf2, 0x11, 0xf5, 0xba, 0xf0, 0x04, 0xe0, 0x01, + 0x06, 0x10, 0xe6, 0xef, 0xfc, 0x12, 0xf9, 0xf4, 0x1b, 0x2f, 0xe3, 0x0f, + 0xd7, 0xf6, 0x0b, 0x11, 0xf7, 0x0c, 0x00, 0x06, 0x18, 0xef, 0x06, 0x03, + 0x0a, 0x09, 0xf6, 0x1a, 0x0d, 0xed, 0xfe, 0x2c, 0x43, 0xf4, 0xe5, 0xde, + 0xf5, 0x02, 0x25, 0x5a, 0x49, 0xd4, 0xe6, 0x24, 0x1e, 0xf7, 0x0e, 0x5c, + 0x5d, 0xf0, 0xf9, 0xe4, 0x1c, 0xeb, 0x28, 0x7f, 0x5b, 0xec, 0xfa, 0xdb, + 0x0c, 0xf5, 0x20, 0x49, 0x51, 0xe1, 0xed, 0xe6, 0x0e, 0x26, 0x28, 0x33, + 0x35, 0x05, 0xe1, 0xe4, 0x1f, 0xfc, 0xf9, 0x39, 0x18, 0x04, 0xed, 0xed, + 0x01, 0xe7, 0xe6, 0x08, 0x09, 0x03, 0xe7, 0xf9, 0x0e, 0x06, 0xec, 0x08, + 0x12, 0x1a, 0xda, 0xef, 0xdf, 0xf9, 0xe2, 0x1e, 0x1c, 0x00, 0x12, 0xd7, + 0x01, 0xf7, 0x21, 0x17, 0x13, 0x19, 0xde, 0xe0, 0xec, 0x16, 0x01, 0x1b, + 0x06, 0x0c, 0xf0, 0xe8, 0x18, 0x03, 0x06, 0x0e, 0x09, 0xfa, 0x03, 0xf3, + 0xdd, 0x01, 0xfb, 0x0a, 0x2a, 0xf4, 0xf6, 0xda, 0xe9, 0xfe, 0xe9, 0x12, + 0x19, 0xe9, 0x05, 0xdf, 0x00, 0xeb, 0xf2, 0x10, 0x0c, 0xe1, 0xcd, 0xcb, + 0xf2, 0x1f, 0xd9, 0x0c, 0xfa, 0xfb, 0xe8, 0xde, 0x00, 0xfc, 0xe5, 0x00, + 0x11, 0x02, 0xe6, 0x17, 0x14, 0x00, 0xf2, 0xfd, 0x00, 0xe1, 0x10, 0x24, + 0x12, 0xec, 0xed, 0x1e, 0x09, 0x18, 0x03, 0x0c, 0x04, 0xf4, 0x15, 0x0f, + 0x10, 0x18, 0xd6, 0x29, 0x10, 0x04, 0x1c, 0xef, 0x0f, 0x0c, 0xc7, 0x04, + 0xfe, 0xeb, 0xff, 0xf5, 0xe3, 0x15, 0xfe, 0xcb, 0x10, 0xff, 0x12, 0xfb, + 0xe4, 0xeb, 0xf9, 0x00, 0x02, 0xf1, 0x14, 0x13, 0x01, 0x02, 0xf9, 0x01, + 0x06, 0x0c, 0xf5, 0x0a, 0x1e, 0x01, 0x19, 0x0e, 0x05, 0xf5, 0x0a, 0xff, + 0xff, 0xf2, 0xfb, 0xdb, 0xf8, 0x06, 0x17, 0xf2, 0xf7, 0x0d, 0x0e, 0xf4, + 0xfa, 0xf7, 0x14, 0xdb, 0xe0, 0xfd, 0x08, 0x16, 0xf7, 0x16, 0xfc, 0x09, + 0x27, 0x07, 0x09, 0xfb, 0x0a, 0xfc, 0x0c, 0xe4, 0xdb, 0xee, 0xff, 0x10, + 0xf3, 0x09, 0xfa, 0xf4, 0x23, 0xf3, 0xf4, 0x19, 0xff, 0xfa, 0xff, 0x19, + 0x0f, 0x11, 0xed, 0xec, 0xf8, 0x0f, 0x10, 0xf3, 0xff, 0x0b, 0xf7, 0x06, + 0x0b, 0x0e, 0x07, 0xe4, 0x18, 0x0a, 0x08, 0x0e, 0x02, 0x0a, 0x05, 0x19, + 0x02, 0xf3, 0xfe, 0xfe, 0x0b, 0x0f, 0xfc, 0xfa, 0x05, 0xf9, 0xe2, 0xf9, + 0x1b, 0xf7, 0x0f, 0x07, 0xfc, 0x12, 0xfe, 0x01, 0xfd, 0xf0, 0x04, 0xf4, + 0xfd, 0x07, 0xf2, 0x04, 0x04, 0x07, 0xef, 0x0c, 0xed, 0x0e, 0xf6, 0xef, + 0x08, 0x07, 0x04, 0xe9, 0xf3, 0x20, 0xda, 0x15, 0xf8, 0xff, 0xec, 0xe0, + 0xf6, 0xff, 0xe9, 0x08, 0x01, 0x10, 0xf0, 0xfc, 0xe9, 0x08, 0xe8, 0xf5, + 0xf8, 0xe5, 0x17, 0xe6, 0x03, 0xfc, 0x09, 0xf5, 0xdd, 0xf2, 0xff, 0x05, + 0xf6, 0xf8, 0xf5, 0x07, 0xfc, 0xf1, 0x04, 0xf3, 0x13, 0xe1, 0x0f, 0xf2, + 0x0a, 0xf9, 0xfd, 0x1c, 0xe0, 0x11, 0x1b, 0xe6, 0xef, 0x05, 0x05, 0x0c, + 0x23, 0x10, 0x09, 0xfe, 0xf7, 0x1a, 0xf1, 0xfc, 0x11, 0x1d, 0xff, 0x03, + 0x03, 0xe6, 0x07, 0x11, 0x0c, 0x0d, 0x16, 0x05, 0x05, 0x25, 0xf3, 0x10, + 0x10, 0x06, 0x09, 0xe8, 0x1a, 0xf0, 0xee, 0x09, 0xff, 0x24, 0xf7, 0xfb, + 0xe6, 0x06, 0xfa, 0x08, 0x03, 0x00, 0xf2, 0x04, 0xf0, 0xeb, 0x14, 0x1c, + 0x03, 0x21, 0x14, 0x1d, 0xfe, 0x03, 0xf6, 0x02, 0x09, 0xff, 0x00, 0x13, + 0xef, 0x10, 0x1e, 0x0b, 0x1d, 0x1c, 0xf1, 0xf6, 0xe7, 0xfd, 0x14, 0x01, + 0xff, 0x13, 0xf7, 0xfc, 0x00, 0x21, 0xe3, 0xeb, 0x07, 0x0e, 0x09, 0xf1, + 0xf8, 0xfd, 0x03, 0xee, 0x19, 0xfd, 0xff, 0xfb, 0xff, 0xea, 0xfb, 0x07, + 0xf0, 0x0a, 0x04, 0x04, 0x0b, 0x12, 0xfe, 0x0b, 0xe0, 0xff, 0xf6, 0xe5, + 0xfc, 0x11, 0xed, 0xfd, 0x15, 0x03, 0xdd, 0xdb, 0x04, 0xfe, 0xff, 0x0e, + 0xff, 0xfa, 0xfb, 0xe5, 0xef, 0xf6, 0xfe, 0x22, 0x0f, 0xe8, 0xfe, 0xf4, + 0xfd, 0xd9, 0x03, 0x0a, 0xdf, 0xcf, 0xf1, 0x14, 0x05, 0xfd, 0xfb, 0xf3, + 0xfb, 0xfb, 0x0f, 0xf8, 0x05, 0x09, 0x03, 0xf7, 0x05, 0x05, 0x13, 0xfb, + 0xeb, 0x23, 0xe7, 0x18, 0xfb, 0x00, 0xfe, 0xdd, 0xe9, 0xea, 0xd3, 0xe8, + 0x1a, 0xef, 0x01, 0xf1, 0x09, 0x1d, 0xd8, 0xfc, 0xda, 0x19, 0x03, 0xec, + 0xe5, 0xf3, 0xed, 0x0a, 0xf4, 0x13, 0x0b, 0xf7, 0x0c, 0x00, 0xf9, 0xea, + 0xe3, 0xfe, 0xff, 0x0d, 0x0a, 0x1b, 0xd7, 0x17, 0xeb, 0xe9, 0x00, 0x0e, + 0xee, 0x24, 0xef, 0x09, 0x07, 0xf0, 0xf5, 0x07, 0xf5, 0xf5, 0x10, 0x17, + 0x06, 0xf7, 0xfc, 0x02, 0xfb, 0xf9, 0xe7, 0x0a, 0x26, 0xf3, 0x01, 0x01, + 0x09, 0x0b, 0x02, 0x27, 0xf8, 0xee, 0xfd, 0x1c, 0xf8, 0xf2, 0x0f, 0xfc, + 0x0d, 0xe0, 0xea, 0x02, 0x0b, 0x00, 0xe0, 0x08, 0xfe, 0x10, 0x04, 0xfe, + 0xeb, 0x13, 0x01, 0x0c, 0x0e, 0xed, 0x09, 0x01, 0x0c, 0xe3, 0x10, 0xdf, + 0xd1, 0x14, 0xf3, 0xef, 0x09, 0xf0, 0xee, 0xe5, 0x11, 0xf4, 0xf6, 0x00, + 0xe8, 0x20, 0x0a, 0xfc, 0xea, 0xf7, 0x02, 0x16, 0xe7, 0xf3, 0x0d, 0xe4, + 0x04, 0xe6, 0xef, 0xf8, 0x0f, 0x23, 0x02, 0xe0, 0x01, 0x01, 0x01, 0x05, + 0xf5, 0x0d, 0xf5, 0xf5, 0xe1, 0xff, 0x04, 0x00, 0xf4, 0x0d, 0xee, 0xf1, + 0xef, 0xf7, 0x0b, 0xff, 0x1b, 0xec, 0x05, 0xe7, 0xf3, 0x13, 0x12, 0xf2, + 0xf3, 0xfc, 0xea, 0x06, 0xfe, 0x13, 0x12, 0xdb, 0x11, 0xe2, 0xfc, 0x0d, + 0x1c, 0xe8, 0x1d, 0xfc, 0xf2, 0xe2, 0x13, 0x1d, 0xda, 0xf6, 0x1c, 0x18, + 0x1e, 0xf4, 0xfa, 0x03, 0xdc, 0x0f, 0xff, 0xff, 0x18, 0x0b, 0xed, 0xf1, + 0xf8, 0x02, 0xf4, 0x10, 0xf9, 0xeb, 0x0b, 0x0e, 0x0f, 0x01, 0x02, 0x1b, + 0x06, 0x10, 0x00, 0xe7, 0x23, 0x0d, 0xf6, 0x11, 0x08, 0xf5, 0x0f, 0x05, + 0x13, 0xf7, 0x01, 0x01, 0x0c, 0xf6, 0xf9, 0xf0, 0x29, 0x01, 0xe9, 0x11, + 0x02, 0xfa, 0xeb, 0x16, 0x0e, 0x10, 0x09, 0x0e, 0x1c, 0x0a, 0xe3, 0xd3, + 0x01, 0xe3, 0x00, 0x06, 0xe2, 0xe9, 0x19, 0xef, 0x12, 0xf3, 0xfc, 0x02, + 0x0b, 0x0c, 0x0d, 0xed, 0xfd, 0xf6, 0xf9, 0xe9, 0xf2, 0x28, 0xfe, 0x03, + 0xec, 0x03, 0x00, 0xf8, 0xde, 0x0d, 0x25, 0x07, 0x1a, 0xe7, 0xfd, 0x29, + 0xd8, 0xf7, 0xfb, 0xde, 0x0c, 0x08, 0x06, 0x22, 0xee, 0x1d, 0x05, 0x07, + 0xf0, 0xfb, 0xfe, 0x07, 0xf1, 0x04, 0xe9, 0x01, 0xfc, 0xf1, 0x00, 0xeb, + 0xe3, 0x08, 0xec, 0xfe, 0x04, 0xeb, 0xfc, 0x01, 0xf6, 0x0e, 0xdf, 0xf8, + 0x12, 0xe3, 0x16, 0xdc, 0x21, 0x0a, 0xe6, 0x06, 0xe5, 0x10, 0x07, 0xf7, + 0x1e, 0xde, 0xe3, 0x07, 0x16, 0xed, 0x23, 0xf2, 0x12, 0x0d, 0xe9, 0xf9, + 0xe8, 0xfe, 0x0e, 0x02, 0x18, 0x0a, 0xea, 0xec, 0xfb, 0xfe, 0x0c, 0x1b, + 0x19, 0x20, 0xfa, 0x07, 0xe5, 0x0c, 0x04, 0x27, 0xdb, 0xe6, 0xfe, 0x0d, + 0x0a, 0x0a, 0xfe, 0x39, 0xdd, 0xde, 0x05, 0xec, 0x09, 0x05, 0x0a, 0x2c, + 0xf4, 0x02, 0x1f, 0xd3, 0x24, 0xee, 0x0f, 0x3c, 0xf5, 0xfd, 0xf8, 0xf8, + 0x12, 0xf5, 0xf3, 0x19, 0xf9, 0xda, 0xf6, 0x0a, 0x0a, 0xf4, 0x09, 0x0f, + 0xfc, 0x00, 0x01, 0x01, 0xf3, 0xf8, 0x05, 0xf3, 0x0c, 0x19, 0x0e, 0xfd, + 0xfa, 0xe1, 0xfc, 0x0c, 0x03, 0xfb, 0x1b, 0x06, 0xcc, 0xe4, 0x08, 0xf9, + 0x10, 0xe9, 0x06, 0x00, 0x17, 0xe8, 0x0d, 0x12, 0xca, 0xf5, 0x23, 0xe4, + 0x21, 0xf6, 0x19, 0x33, 0xdd, 0xfa, 0x0c, 0x01, 0x14, 0x07, 0x00, 0x34, + 0xda, 0x05, 0x07, 0x01, 0x07, 0xe4, 0x06, 0x24, 0x02, 0xff, 0xf0, 0x09, + 0xfc, 0xf4, 0x03, 0x06, 0xee, 0x08, 0xe2, 0x1d, 0xfa, 0x0c, 0xfc, 0x02, + 0x03, 0xe5, 0xf0, 0xe2, 0x0a, 0x18, 0x12, 0x0c, 0x1e, 0x20, 0xed, 0x20, + 0xe4, 0x01, 0x2a, 0x09, 0x0d, 0x0e, 0xd0, 0xf4, 0xdd, 0xfd, 0x2b, 0xf2, + 0x08, 0x0c, 0xf8, 0xf7, 0xfc, 0xf9, 0x15, 0xef, 0x19, 0x1c, 0x01, 0xff, + 0xe2, 0x01, 0xf3, 0x30, 0x0e, 0xfb, 0x15, 0xe8, 0x1c, 0x00, 0xfa, 0x16, + 0xef, 0xea, 0xfb, 0x05, 0xf0, 0x0e, 0x02, 0x13, 0xf4, 0x01, 0x03, 0xe5, + 0x29, 0x07, 0x09, 0x24, 0xf9, 0xe3, 0xf8, 0xde, 0x2d, 0xf4, 0xf5, 0x40, + 0xed, 0xdf, 0x07, 0xef, 0x0f, 0x0a, 0x0b, 0x32, 0x0d, 0xe8, 0x00, 0xe6, + 0xf6, 0xfc, 0xfd, 0x19, 0x11, 0x09, 0xf3, 0x03, 0xea, 0xf1, 0xfb, 0x02, + 0xfd, 0x06, 0xff, 0xfe, 0x09, 0xec, 0x06, 0x0c, 0x15, 0xf9, 0x06, 0xd7, + 0xe3, 0xf7, 0xed, 0x01, 0x03, 0xfd, 0x14, 0x01, 0x0e, 0xe0, 0x37, 0x0d, + 0xd2, 0x18, 0x2f, 0xea, 0x12, 0x0d, 0x05, 0x3a, 0xd5, 0x07, 0x1e, 0xf2, + 0x21, 0x11, 0xf9, 0x36, 0xd3, 0xf5, 0x12, 0xf6, 0xfb, 0xf6, 0x06, 0x0f, + 0xde, 0xf9, 0x06, 0x09, 0xdf, 0xff, 0x0b, 0xf3, 0xf5, 0x01, 0xf1, 0xea, + 0xf2, 0x02, 0x12, 0xfc, 0x0e, 0xee, 0xf8, 0xeb, 0x00, 0xef, 0x21, 0x0f, + 0x09, 0xef, 0xeb, 0x1e, 0xef, 0xf2, 0x26, 0xf9, 0x17, 0xf1, 0xf1, 0xf0, + 0x0c, 0x10, 0x1d, 0xff, 0x1d, 0x06, 0x03, 0xf6, 0xfb, 0x14, 0x1b, 0x03, + 0x22, 0xfd, 0xec, 0x03, 0xfa, 0xf8, 0x01, 0x2b, 0x1e, 0x1b, 0x09, 0x09, + 0x07, 0xff, 0xf0, 0x20, 0xee, 0x14, 0xfb, 0xf6, 0xf8, 0x11, 0xd9, 0x29, + 0xf4, 0xfa, 0x07, 0xef, 0x20, 0xf9, 0xf2, 0x30, 0xee, 0xf0, 0xf3, 0xd6, + 0x0d, 0xfe, 0x03, 0x36, 0xf5, 0xd7, 0x01, 0xe6, 0x04, 0xf0, 0x05, 0x1f, + 0x0f, 0xdd, 0xff, 0xf8, 0x1f, 0xf2, 0x04, 0x37, 0xfa, 0x00, 0xfd, 0xf8, + 0x10, 0xe1, 0xfb, 0x0d, 0xed, 0xf6, 0xe2, 0xfe, 0x08, 0xfe, 0x07, 0x08, + 0x08, 0x11, 0x0a, 0xf0, 0xf8, 0xf5, 0x04, 0xea, 0x08, 0x12, 0x06, 0x0d, + 0x0f, 0x10, 0x40, 0x28, 0xc0, 0xfb, 0x3f, 0x08, 0x1d, 0x09, 0x1b, 0x3d, + 0xee, 0xf4, 0x29, 0x13, 0x20, 0xfc, 0x11, 0x4c, 0xdb, 0x02, 0x15, 0x05, + 0xec, 0xeb, 0x0a, 0x22, 0xe7, 0x00, 0x02, 0x01, 0xd4, 0xea, 0x0a, 0xf3, + 0xe3, 0xf8, 0xf5, 0xfa, 0x01, 0x0d, 0x19, 0x06, 0x24, 0x13, 0x02, 0xf5, + 0xf1, 0xf1, 0x1b, 0x0f, 0x19, 0x04, 0xe3, 0xf9, 0xe7, 0x02, 0x29, 0xfc, + 0x29, 0xec, 0xe9, 0x04, 0xdc, 0x22, 0x1d, 0xfd, 0x1f, 0x01, 0xec, 0xe8, + 0xf5, 0x14, 0x1b, 0x19, 0x06, 0x0e, 0x02, 0x0d, 0xf9, 0x06, 0xfc, 0x15, + 0x07, 0xfa, 0x0c, 0xe1, 0x18, 0x1a, 0xe8, 0x1b, 0xe9, 0xef, 0x0a, 0x18, + 0xfc, 0x05, 0xf9, 0x14, 0xdc, 0x04, 0x01, 0xff, 0x07, 0xfd, 0xf0, 0x2c, + 0xf2, 0xec, 0x0e, 0xe7, 0x1a, 0x05, 0xe8, 0x35, 0x13, 0x09, 0xf9, 0x07, + 0xfe, 0xfa, 0x0d, 0x40, 0x0c, 0xea, 0xf4, 0x04, 0x01, 0x11, 0xfc, 0x23, + 0xeb, 0xf4, 0xe9, 0x04, 0xeb, 0xe7, 0x07, 0x09, 0xfb, 0xf1, 0xf6, 0xfd, + 0x02, 0xfa, 0x02, 0xff, 0x00, 0xff, 0xf1, 0xf1, 0x1a, 0xe9, 0x10, 0xe3, + 0x0b, 0x0c, 0x08, 0x04, 0x1b, 0x0a, 0x2b, 0x10, 0xe1, 0x01, 0x1f, 0x06, + 0x04, 0xec, 0x19, 0x49, 0xee, 0xf8, 0x22, 0x0c, 0x20, 0x02, 0x07, 0x31, + 0xe7, 0xff, 0x0f, 0xf0, 0xfd, 0xea, 0x13, 0x26, 0xce, 0xfa, 0xff, 0xee, + 0xe9, 0xfe, 0x15, 0x08, 0x04, 0x05, 0x0d, 0xfa, 0xdd, 0xf8, 0x07, 0x0b, + 0x33, 0xef, 0xec, 0xf9, 0xd9, 0xe6, 0x1d, 0x10, 0x41, 0xf6, 0xdf, 0x11, + 0xe3, 0x14, 0x1d, 0xfb, 0x2b, 0x15, 0xdc, 0x09, 0xf6, 0x05, 0x16, 0x00, + 0x1c, 0x27, 0xe4, 0xfc, 0xf7, 0x16, 0x08, 0x08, 0x2f, 0xdd, 0xf8, 0xfa, + 0xe9, 0x0e, 0x0b, 0x0b, 0x02, 0x12, 0x02, 0xfd, 0x19, 0x03, 0xeb, 0x11, + 0xf4, 0x09, 0x09, 0x15, 0x12, 0x0d, 0xef, 0x1c, 0xe4, 0xfe, 0x17, 0x0c, + 0x09, 0x04, 0xea, 0x2f, 0xf2, 0x1e, 0x02, 0xfb, 0xfe, 0xe3, 0x00, 0x2e, + 0x04, 0xf9, 0x0c, 0x05, 0x27, 0x0c, 0x07, 0x2d, 0xf7, 0x0b, 0xfb, 0xf9, + 0x1c, 0xdf, 0x11, 0x36, 0x05, 0xf2, 0x02, 0xf8, 0x0b, 0x07, 0x05, 0xfb, + 0xfc, 0x0e, 0x13, 0xfa, 0xfb, 0x09, 0xf5, 0xfd, 0x06, 0x15, 0xf9, 0x03, + 0x18, 0xfd, 0x1a, 0x0a, 0x03, 0xe2, 0xfb, 0x00, 0x1e, 0xfe, 0x4f, 0x27, + 0xe1, 0xf7, 0x31, 0xf0, 0x1b, 0xec, 0x07, 0x5f, 0xe2, 0xf8, 0x40, 0x05, + 0x17, 0x24, 0x0c, 0x3c, 0xf3, 0x10, 0x13, 0xf8, 0x0b, 0xf3, 0xf9, 0x36, + 0xe1, 0xf3, 0xf4, 0xe8, 0xef, 0xf8, 0xfc, 0xeb, 0xe3, 0xfb, 0xf0, 0xee, + 0xdb, 0x06, 0x0c, 0x11, 0x1e, 0x10, 0xe2, 0xe9, 0xeb, 0x0d, 0x34, 0x0f, + 0x43, 0xd9, 0xef, 0x08, 0xec, 0x05, 0x1d, 0x02, 0x33, 0xef, 0xf4, 0xf7, + 0xe6, 0xf9, 0x22, 0x07, 0x04, 0x06, 0xe9, 0x02, 0xf0, 0xfc, 0x24, 0x20, + 0x24, 0x17, 0xe6, 0x0f, 0x05, 0xf6, 0xfc, 0x1f, 0xf2, 0x01, 0x0d, 0xe7, + 0xff, 0x1d, 0xf0, 0xfa, 0xd0, 0x00, 0xff, 0x0e, 0x23, 0xf9, 0xf3, 0x11, + 0xde, 0x0d, 0x05, 0x04, 0x0b, 0x0b, 0xfb, 0x26, 0x0d, 0x0d, 0xff, 0xe8, + 0x16, 0xe8, 0x0b, 0x3c, 0x18, 0xe4, 0x04, 0xff, 0xfa, 0xf3, 0xff, 0x40, + 0xee, 0x06, 0xfc, 0x0d, 0x00, 0xf7, 0x13, 0x3f, 0xf7, 0x13, 0x06, 0x08, + 0xf9, 0x13, 0xf2, 0x19, 0xfd, 0xf9, 0xf3, 0xe6, 0xfc, 0x07, 0xf6, 0xfd, + 0x0a, 0x22, 0x00, 0x01, 0x19, 0xff, 0xe7, 0xff, 0x08, 0xfd, 0x03, 0xfd, + 0x1f, 0xe7, 0x28, 0x08, 0xde, 0xf3, 0x43, 0xf6, 0x0c, 0xfe, 0x1e, 0x52, + 0xf2, 0x04, 0x17, 0xf2, 0x08, 0x0d, 0x04, 0x38, 0xde, 0x0c, 0x10, 0xef, + 0xdf, 0x0f, 0x01, 0x24, 0xde, 0xe1, 0x0d, 0xfd, 0xd4, 0xf6, 0x12, 0x0e, + 0xed, 0x01, 0xf0, 0xf3, 0xfd, 0xff, 0x18, 0xf3, 0x36, 0xda, 0xf6, 0xef, + 0xe8, 0xef, 0x37, 0x27, 0x4e, 0xf8, 0xf4, 0xff, 0xe5, 0xf3, 0x32, 0x0b, + 0x36, 0x08, 0xe9, 0xf6, 0xe2, 0x13, 0x21, 0xfe, 0x12, 0xed, 0xdd, 0xfb, + 0xf8, 0x05, 0x0f, 0x03, 0x1c, 0x04, 0xfc, 0xf2, 0x23, 0x0e, 0x03, 0xfc, + 0xf9, 0x18, 0xf7, 0x01, 0x1b, 0x03, 0xf5, 0xfd, 0xde, 0xf3, 0x19, 0xfc, + 0x11, 0x02, 0xe7, 0x13, 0xde, 0xd8, 0xf2, 0x05, 0x28, 0x02, 0x02, 0x27, + 0x07, 0x08, 0xff, 0x07, 0x27, 0x0e, 0x19, 0x40, 0xfb, 0x02, 0x0c, 0xf6, + 0x0d, 0x07, 0x0f, 0x47, 0xf8, 0x05, 0x0e, 0xfd, 0x03, 0x1e, 0x07, 0x32, + 0xe7, 0xf6, 0x24, 0x01, 0x01, 0x02, 0x0a, 0xff, 0xf6, 0x26, 0x15, 0xf0, + 0x04, 0x13, 0x03, 0xfa, 0xfe, 0xf6, 0xf1, 0x09, 0x2a, 0xe6, 0xea, 0xf6, + 0x17, 0x13, 0xeb, 0xff, 0x15, 0xeb, 0x23, 0x06, 0xc8, 0xf6, 0x33, 0xeb, + 0xf4, 0xe7, 0x12, 0x2a, 0xe3, 0xe6, 0x32, 0xfa, 0x16, 0x15, 0x17, 0x40, + 0xf1, 0x08, 0x1a, 0xf3, 0xf6, 0x0c, 0x0c, 0x11, 0xd0, 0x22, 0x02, 0xee, + 0xea, 0xf4, 0xf8, 0xf9, 0x13, 0x10, 0x17, 0xf5, 0xf1, 0x0a, 0x0e, 0xfd, + 0x32, 0xda, 0xf1, 0xe2, 0xdb, 0xf2, 0x34, 0x1f, 0x53, 0xfc, 0xe4, 0xf2, + 0xf6, 0xf2, 0x1d, 0x04, 0x4a, 0xec, 0xee, 0x06, 0xdf, 0x01, 0x1a, 0x04, + 0x27, 0xfc, 0xe6, 0xfd, 0xd9, 0xfd, 0x0e, 0x00, 0x0c, 0x16, 0xf3, 0x03, + 0xf7, 0xfc, 0x0e, 0x0f, 0x09, 0x06, 0x06, 0x04, 0x08, 0x02, 0xed, 0xf5, + 0xe4, 0xe6, 0x07, 0x06, 0x03, 0x18, 0xea, 0x13, 0xe2, 0xfa, 0x10, 0xf2, + 0x02, 0xec, 0x03, 0x3c, 0xf6, 0xf6, 0x0a, 0x10, 0x09, 0xf8, 0x15, 0x24, + 0xfd, 0x0d, 0x09, 0x01, 0x00, 0xff, 0x00, 0x1a, 0xf0, 0xee, 0x08, 0x03, + 0x1d, 0x05, 0x16, 0x46, 0xe6, 0xf8, 0x08, 0x00, 0x09, 0x09, 0xff, 0x01, + 0xfc, 0x20, 0xfc, 0xec, 0x05, 0x1b, 0x03, 0xf1, 0x12, 0xe4, 0xfa, 0x24, + 0x1c, 0xf5, 0xf2, 0x05, 0x11, 0xe7, 0xfa, 0x02, 0x20, 0xea, 0x31, 0x10, + 0xcf, 0xd8, 0x33, 0xee, 0xff, 0x09, 0x20, 0x3f, 0xe2, 0x0a, 0x29, 0xee, + 0x3a, 0xf2, 0x1e, 0x39, 0x02, 0x1e, 0xfe, 0xf2, 0xef, 0xe2, 0x0d, 0x0f, + 0xf1, 0x19, 0x02, 0xe7, 0xec, 0xff, 0xfe, 0xe4, 0xfe, 0xfb, 0x02, 0xf6, + 0xf1, 0xf4, 0x07, 0x1a, 0x2a, 0xf9, 0x06, 0xf9, 0xda, 0xf4, 0x22, 0x02, + 0x4f, 0x0a, 0xf3, 0xfc, 0xf3, 0xf6, 0x25, 0x0a, 0x28, 0x01, 0xf7, 0x09, + 0xe6, 0x05, 0x28, 0xf7, 0x1e, 0xf2, 0xee, 0x13, 0xee, 0x05, 0x0f, 0x0a, + 0x09, 0xe8, 0xe8, 0x0e, 0x05, 0x12, 0x0f, 0x15, 0x02, 0xec, 0xf8, 0x02, + 0xf7, 0x05, 0xf8, 0xff, 0xdc, 0x00, 0x01, 0x00, 0x12, 0x17, 0xec, 0x19, + 0xfa, 0x09, 0xfa, 0xf3, 0x1d, 0x0b, 0x07, 0x25, 0xea, 0x0c, 0xf5, 0xfa, + 0x04, 0xf7, 0xfe, 0x33, 0xfe, 0x14, 0xef, 0x04, 0xf0, 0x00, 0x00, 0x3a, + 0xea, 0xfa, 0x10, 0x01, 0xe4, 0x00, 0xff, 0x23, 0xe9, 0x26, 0x15, 0x10, + 0x04, 0x14, 0x0d, 0x08, 0xf8, 0xfd, 0x10, 0xfb, 0x00, 0x21, 0x06, 0xfa, + 0x0f, 0x08, 0xf1, 0x09, 0x28, 0xf0, 0xd8, 0x0d, 0x08, 0x09, 0x02, 0xfb, + 0x12, 0x03, 0x0e, 0xfb, 0xce, 0xf0, 0x39, 0xe5, 0x09, 0xf6, 0x1f, 0x35, + 0xdd, 0x1c, 0x25, 0xef, 0x17, 0x0c, 0xf6, 0x3e, 0xf0, 0x21, 0x08, 0xff, + 0xd7, 0xfc, 0xfd, 0x1f, 0xe5, 0x18, 0x12, 0xe9, 0xf5, 0xe9, 0x12, 0xf6, + 0x02, 0x13, 0xf4, 0x0a, 0xfd, 0x03, 0x09, 0x08, 0x2f, 0x07, 0xee, 0xfd, + 0xd7, 0x00, 0x2b, 0x29, 0x3b, 0xdb, 0xde, 0xf1, 0xe1, 0xf7, 0x47, 0x12, + 0x35, 0x0c, 0xe4, 0x09, 0xef, 0x17, 0x2b, 0xea, 0x2d, 0xf8, 0xe8, 0x18, + 0xef, 0x03, 0x11, 0x0a, 0x10, 0xff, 0xe8, 0x07, 0x0c, 0x07, 0x03, 0x18, + 0x05, 0x08, 0xf8, 0xf8, 0x06, 0x18, 0xe9, 0xf9, 0xe0, 0x0f, 0x0d, 0x18, + 0x04, 0x01, 0xf0, 0x1c, 0xf6, 0x14, 0xfd, 0x12, 0x0c, 0x0c, 0x02, 0x34, + 0xf6, 0xe6, 0xfd, 0xf9, 0xf9, 0xfd, 0x00, 0x2a, 0xfc, 0xf9, 0xff, 0x0a, + 0xfe, 0x1b, 0xf5, 0x34, 0xdc, 0xf9, 0x15, 0x13, 0xe7, 0x1b, 0xf7, 0x25, + 0xfd, 0x09, 0x08, 0x0a, 0xf0, 0x17, 0x0f, 0x04, 0xf4, 0xe9, 0x06, 0x07, + 0xf5, 0x02, 0xfc, 0xf5, 0x09, 0xee, 0xf1, 0x07, 0x38, 0x03, 0x05, 0x0f, + 0x16, 0x0f, 0xed, 0xff, 0x21, 0xf8, 0x34, 0x07, 0xd1, 0xf9, 0x27, 0x00, + 0x0c, 0x21, 0x18, 0x42, 0xe6, 0x02, 0x1a, 0xf1, 0x2f, 0xf1, 0x0e, 0x3b, + 0xee, 0xf8, 0x08, 0xea, 0xfe, 0xf9, 0x03, 0x18, 0xf5, 0xf8, 0x0d, 0xeb, + 0x01, 0x10, 0x09, 0x02, 0x15, 0xfb, 0xf1, 0x0b, 0xf2, 0x06, 0x08, 0x09, + 0x2f, 0x19, 0x02, 0xfe, 0xe4, 0x06, 0x1f, 0x17, 0x49, 0xf2, 0xe2, 0x02, + 0xef, 0x04, 0x26, 0x16, 0x3f, 0x08, 0xf1, 0x0a, 0xfd, 0xf9, 0x28, 0x01, + 0x15, 0x0b, 0xf9, 0x10, 0xdc, 0x02, 0x20, 0xf7, 0x16, 0xe6, 0x09, 0x03, + 0xf1, 0xf5, 0x12, 0x1c, 0xfb, 0x2a, 0x08, 0xfa, 0x0a, 0x16, 0xf6, 0x15, + 0xf0, 0x06, 0x11, 0xfd, 0x0e, 0xf9, 0xf6, 0x12, 0xed, 0xf3, 0xfd, 0x1f, + 0x0b, 0xfa, 0x08, 0x30, 0xf8, 0xff, 0x0b, 0xeb, 0x10, 0xff, 0x07, 0x22, + 0x0d, 0x07, 0x09, 0x03, 0xf6, 0xf8, 0xfc, 0x26, 0xf8, 0xee, 0x11, 0x02, + 0x03, 0x0a, 0xef, 0x38, 0xfe, 0x13, 0x1b, 0x09, 0xfe, 0x06, 0x05, 0xf3, + 0x04, 0xdf, 0xfc, 0x00, 0xe7, 0x15, 0xec, 0xf1, 0xf8, 0xfc, 0xed, 0x05, + 0x0e, 0xf3, 0x15, 0x09, 0x01, 0x0d, 0xfd, 0x00, 0x24, 0xe2, 0x31, 0x13, + 0xd5, 0x1b, 0x2b, 0xe8, 0x03, 0x08, 0x1d, 0x33, 0xdc, 0xfd, 0x24, 0xe4, + 0x20, 0xfa, 0x07, 0x33, 0x01, 0x12, 0x06, 0xf5, 0xef, 0xf7, 0xfa, 0x13, + 0x01, 0xec, 0xee, 0xe0, 0xfd, 0x0d, 0xff, 0x09, 0xf6, 0x00, 0xed, 0x07, + 0xea, 0x0e, 0xff, 0x0e, 0x26, 0xfc, 0xf0, 0xe7, 0xe7, 0xfe, 0x30, 0xff, + 0x24, 0x04, 0x06, 0xf4, 0xf5, 0xf8, 0x23, 0x0e, 0x3d, 0xf2, 0xfd, 0x04, + 0xe8, 0xfb, 0x23, 0xfe, 0x33, 0xe1, 0x01, 0xfd, 0xdc, 0xfb, 0x0e, 0xfa, + 0x22, 0xfb, 0x11, 0xfa, 0xff, 0x08, 0x21, 0x30, 0x13, 0x03, 0xf2, 0x03, + 0xf8, 0x0f, 0xec, 0x0d, 0xef, 0x0f, 0x10, 0x10, 0x0f, 0xf6, 0xf9, 0x1e, + 0xf7, 0xe5, 0x08, 0xfa, 0x09, 0xff, 0x00, 0x15, 0x02, 0x00, 0x08, 0xfe, + 0xfb, 0x0e, 0x15, 0x28, 0xfa, 0xfb, 0x13, 0x06, 0xfb, 0x05, 0xf6, 0x11, + 0xf6, 0x0b, 0x06, 0x15, 0xe1, 0x00, 0xe9, 0x0f, 0xe1, 0x1d, 0x18, 0xfd, + 0x0b, 0x0f, 0xff, 0xf2, 0xf5, 0xfd, 0x14, 0xff, 0xf4, 0xfe, 0xe2, 0xf8, + 0x14, 0x0b, 0xeb, 0x07, 0x35, 0xe2, 0xeb, 0x0b, 0x04, 0x22, 0xfe, 0x0e, + 0x1d, 0xf2, 0x24, 0x11, 0xcc, 0xec, 0x25, 0xf7, 0xff, 0xf9, 0x06, 0x29, + 0xe4, 0x07, 0x1c, 0xdb, 0xf8, 0x1d, 0xfa, 0x44, 0xf2, 0x01, 0x0f, 0xe6, + 0x11, 0x03, 0xee, 0x17, 0x06, 0xe0, 0x0c, 0xd8, 0xe9, 0xfd, 0x11, 0xfe, + 0x07, 0xdd, 0xea, 0xff, 0xde, 0xdd, 0x0a, 0x09, 0x30, 0xf2, 0x01, 0xe4, + 0xe0, 0xeb, 0x2d, 0x12, 0x2d, 0xeb, 0xfc, 0xf0, 0xe8, 0xf9, 0x1f, 0x08, + 0x3f, 0xeb, 0x0e, 0x13, 0xf9, 0x0c, 0x1c, 0x02, 0x25, 0xec, 0xf6, 0x05, + 0xf3, 0xf4, 0x18, 0x08, 0x12, 0xe9, 0xfb, 0xfd, 0xf9, 0x08, 0x13, 0x1c, + 0x08, 0xec, 0xfe, 0x02, 0xf1, 0x19, 0xf3, 0x1d, 0xf1, 0x07, 0x11, 0x12, + 0xfa, 0xf2, 0xf6, 0x0d, 0xff, 0x17, 0x0a, 0xfb, 0x1f, 0xf8, 0x11, 0x24, + 0xf6, 0xfc, 0xfe, 0x07, 0xed, 0x05, 0x1c, 0x21, 0xfe, 0xfe, 0x16, 0x0d, + 0x08, 0x0f, 0x09, 0x33, 0xf4, 0x1f, 0x14, 0x0c, 0xfe, 0xf5, 0xeb, 0x2a, + 0xee, 0xf3, 0x12, 0x19, 0xec, 0x01, 0x06, 0xf7, 0x05, 0x22, 0x0b, 0xeb, + 0xeb, 0x06, 0xe1, 0xf5, 0x0d, 0xee, 0xfb, 0x0a, 0x31, 0xff, 0xe3, 0xea, + 0x18, 0x09, 0xe3, 0x07, 0x1a, 0xf8, 0x15, 0xfc, 0xcc, 0xf2, 0x2a, 0xe5, + 0x01, 0xea, 0x10, 0x1f, 0xd9, 0x02, 0x13, 0xf6, 0x16, 0x01, 0x0e, 0x3c, + 0x02, 0x17, 0x04, 0xf1, 0xf7, 0x02, 0x07, 0x0c, 0x02, 0x1f, 0xf4, 0xe6, + 0xf0, 0xe9, 0x05, 0xf4, 0xfd, 0xe4, 0xf7, 0xe9, 0xfc, 0xef, 0x06, 0x02, + 0x26, 0xf1, 0xf1, 0xeb, 0xe9, 0xe6, 0x30, 0x1c, 0x38, 0x0f, 0x03, 0xf1, + 0x10, 0x04, 0x30, 0x19, 0x1f, 0xfb, 0xfc, 0x05, 0xe2, 0xfe, 0x18, 0xf2, + 0x1c, 0xf2, 0xf5, 0x0e, 0xf2, 0x05, 0x1d, 0x28, 0x12, 0xf0, 0xf0, 0x0f, + 0x0a, 0x03, 0x1a, 0x1a, 0xf3, 0x08, 0x13, 0xef, 0xf5, 0x1c, 0x06, 0x00, + 0xee, 0x12, 0x1d, 0x03, 0x18, 0x06, 0x0a, 0x0e, 0xf0, 0xeb, 0xfa, 0x0d, + 0x08, 0xff, 0x06, 0x24, 0x0f, 0x03, 0x0a, 0x0f, 0x0e, 0xff, 0x08, 0x33, + 0xfc, 0x00, 0x0e, 0xfb, 0xfb, 0x05, 0x07, 0x19, 0xe8, 0xe7, 0x12, 0x11, + 0x15, 0xf7, 0x0c, 0x1a, 0xf6, 0x28, 0x08, 0xeb, 0xf2, 0x25, 0xee, 0x01, + 0x03, 0xec, 0xed, 0xfa, 0xf0, 0xf2, 0xef, 0xf1, 0x02, 0x23, 0xef, 0x01, + 0x41, 0xfa, 0xf4, 0xf4, 0x15, 0xf5, 0xf5, 0xf9, 0x28, 0xde, 0x20, 0xf6, + 0xc7, 0xde, 0x21, 0xe4, 0xfe, 0xec, 0x0d, 0x2c, 0xee, 0x24, 0x10, 0xf0, + 0x1d, 0x12, 0x0e, 0x2b, 0x06, 0xf8, 0xfd, 0x01, 0x08, 0xef, 0xfd, 0x0f, + 0xeb, 0xed, 0xe1, 0xdf, 0xf1, 0xe5, 0x16, 0xe3, 0x08, 0xfc, 0xf6, 0xf6, + 0xd8, 0xf0, 0x23, 0xfc, 0x2b, 0xf5, 0xff, 0xe7, 0xf4, 0xe9, 0x29, 0x09, + 0x2b, 0x0c, 0xff, 0x08, 0x0b, 0xed, 0x29, 0x14, 0x3c, 0xf5, 0xeb, 0x18, + 0xf6, 0x10, 0x22, 0xf9, 0x17, 0x23, 0x02, 0x0c, 0xf6, 0xfa, 0x2f, 0xfe, + 0x1e, 0xeb, 0xfd, 0x03, 0xf0, 0x07, 0x1c, 0x09, 0xfa, 0xe1, 0x0d, 0x0f, + 0x18, 0x03, 0xfe, 0xf0, 0xec, 0x0b, 0x10, 0x02, 0x14, 0x06, 0xef, 0xf7, + 0xea, 0x0b, 0x05, 0xfe, 0x1f, 0x06, 0x0e, 0x07, 0x00, 0xe1, 0x01, 0x01, + 0x07, 0x05, 0x09, 0xf7, 0xef, 0x15, 0xf7, 0x12, 0x05, 0x03, 0x04, 0x1d, + 0x04, 0x10, 0x12, 0x06, 0x05, 0x00, 0x08, 0x18, 0xd6, 0xf2, 0xfa, 0x07, + 0xf8, 0x12, 0x07, 0xfd, 0xdd, 0x00, 0x04, 0xfb, 0xf8, 0x09, 0xf3, 0x09, + 0xfb, 0xf0, 0xe8, 0x09, 0x27, 0xf5, 0xf8, 0x06, 0x01, 0x02, 0x0e, 0xf6, + 0x1f, 0xfa, 0x29, 0xf8, 0xd6, 0x01, 0x22, 0xf8, 0x1d, 0xe3, 0x1a, 0x39, + 0x0a, 0x0d, 0x19, 0xf5, 0x12, 0xfb, 0x1d, 0x2a, 0x03, 0xf6, 0x0c, 0xf2, + 0xfd, 0xec, 0x18, 0x13, 0xfe, 0x1a, 0xe8, 0xdd, 0x01, 0xf8, 0x30, 0x01, + 0xf8, 0xfe, 0xe4, 0xe7, 0xff, 0xeb, 0x23, 0xfa, 0x2c, 0xf0, 0xfc, 0xe7, + 0x0a, 0xf8, 0x18, 0x10, 0x23, 0x01, 0xfa, 0xe8, 0xf1, 0xfa, 0x1d, 0x0e, + 0x17, 0xe7, 0xe4, 0xf5, 0xf9, 0x0c, 0x17, 0x0c, 0x13, 0xe8, 0xe1, 0x17, + 0x19, 0x05, 0x0b, 0x0f, 0x23, 0xed, 0xff, 0xfe, 0xe0, 0x14, 0x16, 0x00, + 0x0d, 0x1c, 0x0b, 0xf5, 0xfb, 0x18, 0xee, 0xff, 0xff, 0xf3, 0x18, 0x0c, + 0x05, 0xfa, 0xf6, 0xfe, 0xfe, 0xf8, 0xf8, 0x09, 0xef, 0xf8, 0x0e, 0xf0, + 0x00, 0xf8, 0x0c, 0xf8, 0xf6, 0x07, 0x16, 0x11, 0xf8, 0xea, 0xff, 0xff, + 0x01, 0x20, 0x07, 0x08, 0xfd, 0x1c, 0xfc, 0x06, 0xed, 0x0d, 0x08, 0x15, + 0xf0, 0x25, 0x01, 0x1b, 0x00, 0x02, 0xfe, 0x01, 0x05, 0x01, 0xfd, 0xf1, + 0xe5, 0x0c, 0xe4, 0xe1, 0xf0, 0xfa, 0xee, 0x0e, 0x35, 0xee, 0x15, 0xef, + 0x0a, 0xf9, 0x01, 0xf5, 0x1f, 0x05, 0x1f, 0x0d, 0xe1, 0xf4, 0xff, 0xf5, + 0x23, 0x02, 0x18, 0x30, 0xfc, 0xf0, 0x0d, 0x04, 0x0d, 0x06, 0x29, 0x1d, + 0xf9, 0x08, 0x06, 0xe5, 0x13, 0xfd, 0x0d, 0x26, 0xef, 0x09, 0xdc, 0xf2, + 0x05, 0xdf, 0x0c, 0xf6, 0xf3, 0xd9, 0xf8, 0x08, 0xef, 0xeb, 0x0f, 0xf9, + 0x3a, 0x03, 0xff, 0xe0, 0xf7, 0xf0, 0x15, 0x12, 0x41, 0x0b, 0xf1, 0x04, + 0x04, 0xe2, 0x0e, 0x0b, 0x2c, 0x03, 0xea, 0x02, 0xfb, 0xe7, 0x08, 0xe9, + 0x22, 0xf3, 0xf2, 0x1c, 0xfa, 0xf3, 0x11, 0x04, 0x1f, 0xf5, 0x02, 0x0f, + 0x1a, 0x1f, 0x24, 0x0b, 0x06, 0x1f, 0xf3, 0x06, 0x00, 0x02, 0xe8, 0xf6, + 0xf4, 0xe8, 0x07, 0x2e, 0xfb, 0xf8, 0x10, 0x09, 0xf0, 0x0e, 0xff, 0xfe, + 0x1c, 0x14, 0x17, 0x06, 0xe2, 0xf1, 0xfa, 0x01, 0x11, 0x13, 0x12, 0x29, + 0xf1, 0x0f, 0x1f, 0xfa, 0xfd, 0xfd, 0x02, 0x07, 0x0e, 0xfb, 0x0e, 0x04, + 0x01, 0x01, 0xed, 0xfe, 0xde, 0xfd, 0x08, 0xef, 0xf6, 0x0a, 0xff, 0x0f, + 0xe7, 0xf2, 0x0f, 0x02, 0xea, 0x10, 0xf9, 0xec, 0xfd, 0x09, 0xea, 0x1f, + 0x46, 0xdd, 0xe2, 0xf7, 0x08, 0xf5, 0xf7, 0xe9, 0x33, 0xfb, 0x2f, 0xf6, + 0xb5, 0x1d, 0x15, 0xeb, 0x11, 0xf7, 0x2a, 0x2e, 0x08, 0x1d, 0xf4, 0xfb, + 0x15, 0xfa, 0x22, 0x34, 0xff, 0x06, 0xf6, 0xfd, 0xfa, 0xf9, 0x03, 0xf5, + 0xf4, 0xf4, 0xd5, 0xea, 0x01, 0x08, 0x22, 0xf1, 0xf2, 0x06, 0xd1, 0xe5, + 0x0c, 0xef, 0x12, 0x03, 0x08, 0x02, 0xf7, 0x05, 0x1b, 0x07, 0x39, 0x34, + 0x21, 0xe2, 0xe3, 0x0b, 0x0c, 0xf6, 0x29, 0xf7, 0x24, 0x0a, 0xfc, 0xff, + 0x1a, 0xfd, 0x05, 0xff, 0xff, 0x0e, 0x0a, 0x1a, 0x09, 0xfb, 0x15, 0x04, + 0x03, 0xf7, 0xfe, 0x00, 0xfc, 0xfb, 0x11, 0xfa, 0x1d, 0x0e, 0x06, 0xed, + 0xfc, 0x23, 0xd8, 0xf2, 0x04, 0xe5, 0x0f, 0x16, 0x29, 0xfe, 0xf5, 0xec, + 0xe2, 0x0e, 0xeb, 0x09, 0x1d, 0x11, 0x05, 0x11, 0xe4, 0x29, 0x12, 0x02, + 0x12, 0x19, 0x0e, 0x1a, 0xee, 0xf9, 0x05, 0x09, 0xf5, 0xfd, 0x05, 0x04, + 0xe4, 0xf1, 0x17, 0x01, 0xf2, 0xfe, 0x0b, 0xf4, 0x0d, 0x04, 0x06, 0xfe, + 0xff, 0xec, 0xe9, 0x00, 0xff, 0x03, 0x03, 0xfd, 0xf1, 0x15, 0xfc, 0xf3, + 0xff, 0xfe, 0x09, 0xee, 0x3c, 0x01, 0xec, 0x02, 0xf0, 0xf6, 0x20, 0xeb, + 0x16, 0x07, 0x32, 0xf3, 0xce, 0xf0, 0x02, 0xd4, 0x11, 0xe6, 0x28, 0x0e, + 0xe3, 0x21, 0xee, 0xce, 0x1e, 0xd9, 0x23, 0x26, 0x06, 0xfa, 0xf9, 0xf1, + 0x01, 0xe6, 0x0b, 0x07, 0xdc, 0x21, 0xbc, 0xe3, 0xef, 0xf8, 0x12, 0xfc, + 0xe6, 0xfe, 0xf5, 0xd4, 0x15, 0x0a, 0x00, 0x13, 0xfc, 0xec, 0xf3, 0xd6, + 0x1a, 0xe3, 0x21, 0x36, 0x2a, 0x03, 0xe9, 0xe3, 0xff, 0x00, 0x13, 0x1c, + 0x0e, 0x20, 0xe5, 0xf5, 0x24, 0x0b, 0x20, 0x14, 0x13, 0xf8, 0x04, 0x1b, + 0x2f, 0x0a, 0x15, 0x00, 0xf4, 0x1a, 0x11, 0x0d, 0x03, 0x18, 0x0f, 0x18, + 0x04, 0x1f, 0xfb, 0xf2, 0x1f, 0x15, 0x03, 0xfb, 0x0b, 0x17, 0xfb, 0x0b, + 0x1b, 0x1f, 0xf4, 0x07, 0xf9, 0xf9, 0xf8, 0xf4, 0x14, 0x0f, 0xf6, 0xfe, + 0xdd, 0x0b, 0xff, 0x01, 0x18, 0x04, 0x1b, 0x0a, 0xed, 0xe7, 0xf9, 0x16, + 0x02, 0x01, 0x00, 0xf7, 0xf1, 0x07, 0xf0, 0x06, 0xf8, 0x0b, 0x02, 0xf3, + 0xff, 0x20, 0xfd, 0x01, 0x04, 0xf5, 0xd9, 0xf4, 0xf4, 0xf2, 0xe8, 0xff, + 0x04, 0x00, 0xf0, 0xe2, 0xfe, 0xed, 0x1b, 0xef, 0x20, 0xfa, 0xfb, 0xf4, + 0x02, 0x18, 0x07, 0xfb, 0xef, 0xe4, 0x08, 0x0d, 0xe1, 0x0e, 0x25, 0xc6, + 0xfd, 0x0c, 0x1c, 0x0b, 0xf0, 0x01, 0x1c, 0xd4, 0x11, 0xf5, 0x1b, 0x09, + 0xfb, 0xda, 0x13, 0xe3, 0xf9, 0x10, 0x14, 0xf0, 0xf0, 0xfd, 0x1f, 0xcf, + 0xf4, 0xe4, 0xfb, 0x0e, 0x0a, 0x11, 0xed, 0xdc, 0xfc, 0xe6, 0xf7, 0xfc, + 0x13, 0xe1, 0x0b, 0xe4, 0x04, 0x11, 0xee, 0x21, 0x14, 0xe1, 0x07, 0xe4, + 0xfb, 0x08, 0x03, 0x2b, 0x27, 0xf6, 0x0d, 0x02, 0x1b, 0x09, 0x09, 0xf8, + 0x14, 0x19, 0x0f, 0x0b, 0x01, 0x10, 0x09, 0x12, 0x03, 0xf5, 0x18, 0xf3, + 0xfb, 0xf5, 0x02, 0x0e, 0x0d, 0x00, 0x07, 0xfc, 0x18, 0x25, 0x0b, 0xf0, + 0xf9, 0xe6, 0x08, 0x01, 0x24, 0x14, 0xfa, 0xed, 0xe5, 0x1f, 0x09, 0xfe, + 0x08, 0xee, 0x1a, 0x1a, 0x05, 0x00, 0xff, 0x0c, 0xfe, 0xf9, 0x11, 0x11, + 0xea, 0xfe, 0x08, 0xf9, 0xf0, 0xe4, 0x01, 0x0d, 0xf1, 0x00, 0x0b, 0xea, + 0x19, 0xea, 0xf3, 0xf8, 0x08, 0x12, 0x1c, 0x1f, 0xfb, 0xef, 0xf0, 0xf2, + 0x14, 0xe1, 0x03, 0xfa, 0xf9, 0xda, 0xe9, 0xfc, 0xf3, 0xff, 0x12, 0x04, + 0xf7, 0xfc, 0x17, 0x0f, 0xfc, 0x29, 0x03, 0xe5, 0xf2, 0xee, 0x1e, 0xfa, + 0x04, 0xed, 0x25, 0xf4, 0xe1, 0x15, 0x10, 0x1e, 0xef, 0x1c, 0x04, 0xde, + 0xe5, 0x08, 0x21, 0xfd, 0xfd, 0xea, 0x03, 0xca, 0xda, 0x26, 0x00, 0x0a, + 0xfd, 0x05, 0xf0, 0xd4, 0xe1, 0x1a, 0xe4, 0xf5, 0x07, 0xe7, 0xfa, 0xdf, + 0xd4, 0x03, 0xf0, 0x10, 0x15, 0x0c, 0xf4, 0xed, 0xe3, 0xfb, 0x0f, 0x1e, + 0x16, 0x09, 0x00, 0xec, 0xea, 0x13, 0x16, 0x0b, 0x01, 0xfb, 0xff, 0x00, + 0xfb, 0x07, 0x13, 0x08, 0xf4, 0xe4, 0x12, 0x00, 0xfb, 0xfa, 0xfc, 0x08, + 0xeb, 0x19, 0x02, 0x1c, 0xe8, 0x26, 0xf3, 0x10, 0x09, 0x0f, 0x19, 0x02, + 0xfb, 0xec, 0xf7, 0xe2, 0xfb, 0xfa, 0x11, 0xf3, 0x0b, 0x08, 0xff, 0xd9, + 0xf8, 0x12, 0x18, 0x06, 0x07, 0x22, 0xff, 0x19, 0xf5, 0x0b, 0x0a, 0x13, + 0xf2, 0xfa, 0x02, 0x21, 0xeb, 0x11, 0x17, 0x17, 0xec, 0xe1, 0x0e, 0xf7, + 0xe8, 0xd8, 0x0e, 0x01, 0xf1, 0xed, 0xed, 0xf0, 0x09, 0xf7, 0xe7, 0xfd, + 0xf0, 0xf9, 0xdb, 0xee, 0xdc, 0xfb, 0xf8, 0x0a, 0xf5, 0x0b, 0xd4, 0xd7, + 0x08, 0x06, 0x18, 0x06, 0x0c, 0x13, 0xfd, 0x09, 0x13, 0x26, 0x12, 0xf4, + 0xef, 0x00, 0xf5, 0x28, 0x18, 0xfe, 0x04, 0x0e, 0x21, 0x1a, 0x0a, 0x1e, + 0x09, 0xf0, 0x0d, 0x0f, 0xec, 0xf3, 0x17, 0x22, 0x00, 0xec, 0x0e, 0x01, + 0xe9, 0x08, 0x09, 0xf2, 0xf2, 0x08, 0xf0, 0x0b, 0xd9, 0x09, 0x14, 0xf5, + 0xf6, 0x04, 0x19, 0xf4, 0x11, 0xe9, 0xf2, 0x0d, 0x20, 0x17, 0x0a, 0x05, + 0x0c, 0x04, 0x01, 0xfd, 0xf4, 0xfb, 0x1b, 0x0c, 0xf2, 0x0b, 0xff, 0xfe, + 0x01, 0xd8, 0xfa, 0x0e, 0xf5, 0x14, 0xf9, 0x01, 0x04, 0xf8, 0xfa, 0x02, + 0xe8, 0xf9, 0xf9, 0xea, 0xf1, 0x07, 0xff, 0x1e, 0x01, 0x0b, 0xf7, 0x0a, + 0xf7, 0x0c, 0xfd, 0xec, 0xf3, 0x05, 0xf8, 0xda, 0x0b, 0x15, 0xf6, 0xee, + 0xf9, 0x10, 0xfa, 0xfe, 0x08, 0xf0, 0xe6, 0xec, 0x05, 0xff, 0x15, 0x19, + 0x1f, 0x11, 0xfc, 0x09, 0x08, 0x01, 0x06, 0xfe, 0x04, 0x08, 0xfb, 0xfb, + 0x08, 0xf4, 0xf6, 0x28, 0x10, 0xf9, 0x28, 0x0b, 0xf8, 0x0d, 0x01, 0x00, + 0xff, 0x02, 0x05, 0x08, 0xea, 0xe9, 0xf4, 0xf6, 0x01, 0xea, 0xdf, 0x1f, + 0xfe, 0x0a, 0xf9, 0xf7, 0x0c, 0x1b, 0x06, 0xed, 0xf6, 0xf2, 0x03, 0x03, + 0xfd, 0x04, 0xf5, 0x10, 0x0a, 0x0b, 0xf4, 0xf8, 0xf1, 0xe7, 0x05, 0xfe, + 0xe7, 0x0b, 0xf1, 0xec, 0xf4, 0xec, 0x06, 0xee, 0xde, 0x05, 0x1b, 0xfe, + 0x13, 0xf3, 0xd9, 0xea, 0x04, 0x10, 0x05, 0xed, 0x15, 0x02, 0x0b, 0x10, + 0xfa, 0x02, 0x05, 0x0b, 0x02, 0x07, 0xfc, 0xf5, 0x15, 0x14, 0x05, 0xf7, + 0x0c, 0xfe, 0xf6, 0xf4, 0xfa, 0x06, 0xfc, 0x13, 0xdc, 0xe4, 0x09, 0xfa, + 0x02, 0x23, 0xec, 0x06, 0x11, 0x13, 0xf8, 0xfa, 0x27, 0x28, 0x0b, 0x23, + 0xec, 0xf1, 0x09, 0x17, 0x0f, 0x13, 0xff, 0xf2, 0xfc, 0x0a, 0xf5, 0x0d, + 0x03, 0x26, 0x01, 0x0f, 0xfe, 0xf1, 0xfb, 0xe6, 0xf0, 0x02, 0xf2, 0xff, + 0x02, 0x11, 0xff, 0xfd, 0x1c, 0x02, 0x0b, 0xf6, 0x14, 0x0c, 0x0b, 0x21, + 0x28, 0xf0, 0x11, 0x05, 0x06, 0xed, 0xf9, 0x0a, 0xf2, 0xef, 0xf8, 0xf1, + 0xfe, 0x0d, 0xf9, 0xf7, 0xea, 0x00, 0x08, 0xdb, 0x02, 0x0f, 0xfe, 0x04, + 0xef, 0x20, 0x16, 0x01, 0xe8, 0xed, 0xe4, 0x22, 0xf6, 0x19, 0x00, 0x04, + 0x01, 0x13, 0xeb, 0x0d, 0xec, 0x01, 0x08, 0x05, 0x0c, 0x0e, 0xfe, 0x02, + 0x12, 0xf7, 0x27, 0xf9, 0xfd, 0x18, 0xfe, 0x24, 0xf7, 0x13, 0xed, 0x1e, + 0x09, 0xff, 0xd8, 0xf4, 0x12, 0xf8, 0x04, 0x0c, 0x1c, 0x11, 0xfd, 0x17, + 0x1d, 0x01, 0x13, 0xee, 0x11, 0xf3, 0xf8, 0x06, 0xf6, 0x16, 0xfe, 0x15, + 0x16, 0xdc, 0x1f, 0x00, 0x25, 0xee, 0xff, 0xf7, 0xf6, 0x02, 0xdd, 0x15, + 0xf1, 0x14, 0x08, 0xe8, 0xe5, 0x21, 0xea, 0xf0, 0x1a, 0x07, 0xea, 0x08, + 0xea, 0xe4, 0x1e, 0x00, 0x13, 0x17, 0xec, 0x11, 0xd6, 0x11, 0x18, 0x17, + 0x04, 0x15, 0x03, 0x3a, 0xd6, 0x02, 0x07, 0x04, 0xe6, 0xe5, 0xfe, 0x0e, + 0xff, 0xed, 0xfc, 0xfb, 0xff, 0x1c, 0x06, 0x0a, 0xfb, 0xf9, 0xea, 0x1a, + 0x21, 0xf5, 0x04, 0x06, 0x0a, 0xe3, 0x16, 0xea, 0x04, 0xe2, 0xf9, 0xf9, + 0xe6, 0xfb, 0x0f, 0xfc, 0x06, 0xfb, 0x10, 0x07, 0x07, 0x13, 0x07, 0xfc, + 0x16, 0xef, 0x07, 0xdc, 0x12, 0x1f, 0x08, 0xf4, 0xe9, 0x14, 0x06, 0xf7, + 0xf1, 0x0c, 0x01, 0x0c, 0xe6, 0x04, 0xf3, 0xf2, 0xe5, 0xf3, 0xef, 0x1d, + 0xf6, 0x20, 0x07, 0xfe, 0xf4, 0x05, 0xee, 0x10, 0xfd, 0x0e, 0x0b, 0x02, + 0x0d, 0xd8, 0x07, 0xfb, 0x26, 0x0a, 0x1c, 0x21, 0x06, 0x1f, 0xf4, 0x06, + 0x37, 0x18, 0xfa, 0x16, 0x1e, 0x24, 0xfb, 0xf0, 0x12, 0xf9, 0x02, 0x09, + 0x17, 0x16, 0xf3, 0xf9, 0x17, 0xf2, 0x02, 0x0a, 0x2d, 0xe7, 0xe3, 0x25, + 0xf0, 0xf9, 0x0f, 0xdd, 0x15, 0xe6, 0x04, 0xfc, 0xf1, 0x17, 0x0a, 0xea, + 0x24, 0x07, 0xf1, 0x11, 0x13, 0x29, 0xf4, 0xc5, 0xfb, 0x07, 0xef, 0x13, + 0x0b, 0xe1, 0xf1, 0xeb, 0xf8, 0x1b, 0x09, 0x08, 0x1f, 0x15, 0xf2, 0x05, + 0x02, 0xdd, 0x09, 0x0f, 0x16, 0x10, 0x01, 0x30, 0xf2, 0xe0, 0x27, 0xfe, + 0xf1, 0x0e, 0x0e, 0x07, 0xe6, 0x07, 0x0b, 0x18, 0xfe, 0x0f, 0x01, 0x07, + 0xf4, 0x07, 0x10, 0xe7, 0xfb, 0xf3, 0xf7, 0x0b, 0xf9, 0x15, 0x18, 0x25, + 0x0c, 0x14, 0x02, 0x08, 0x0a, 0x0f, 0x10, 0xec, 0xee, 0x1a, 0x03, 0x14, + 0x0f, 0xfa, 0x25, 0xff, 0x18, 0x0d, 0x0b, 0xea, 0x1f, 0x28, 0x10, 0x0c, + 0xe7, 0xee, 0xf7, 0xfa, 0x03, 0x15, 0x0c, 0x1d, 0x01, 0x00, 0x12, 0xee, + 0x01, 0xf1, 0xf8, 0x0b, 0xf3, 0xfd, 0x04, 0xf8, 0x02, 0x1e, 0x0e, 0xf3, + 0x02, 0x10, 0xfd, 0x07, 0x0b, 0x09, 0x03, 0x10, 0x3e, 0x08, 0x0e, 0x0c, + 0xf4, 0xe7, 0xfd, 0x1c, 0x27, 0x1a, 0xed, 0xe1, 0x08, 0xdc, 0xd9, 0xf1, + 0x1e, 0x07, 0x12, 0xf1, 0x10, 0xfb, 0xc8, 0x08, 0x0f, 0x03, 0x1d, 0xdc, + 0x23, 0x04, 0xf9, 0x0a, 0xff, 0x08, 0x0e, 0xc9, 0x39, 0x0a, 0x01, 0x07, + 0xec, 0xe0, 0x05, 0xe8, 0x14, 0xd8, 0xe1, 0xfa, 0xd6, 0xf8, 0xed, 0xdb, + 0xff, 0x1d, 0xf5, 0x17, 0x0f, 0x1c, 0xdc, 0xed, 0xff, 0xff, 0x04, 0x13, + 0xf5, 0xe7, 0xd2, 0x12, 0xdb, 0xe1, 0x13, 0x11, 0x23, 0x0e, 0xf9, 0x31, + 0xdc, 0xef, 0x07, 0x0a, 0x20, 0xf2, 0xf9, 0x13, 0xff, 0x1c, 0x2a, 0xdf, + 0xdb, 0xe7, 0x11, 0xf2, 0xfd, 0xfb, 0x28, 0x00, 0x15, 0x03, 0x02, 0x20, + 0x07, 0xf7, 0x19, 0x13, 0x13, 0xf6, 0x09, 0xfe, 0xfd, 0x20, 0x14, 0xf5, + 0xf5, 0xfc, 0x14, 0x0e, 0x17, 0xfe, 0x15, 0x04, 0xf9, 0xf6, 0x1d, 0xf6, + 0x1b, 0xe4, 0xee, 0xfd, 0x00, 0xe9, 0xee, 0xce, 0x0f, 0x20, 0x05, 0x02, + 0x0d, 0x06, 0x05, 0xf8, 0xef, 0xdf, 0x16, 0x17, 0xe6, 0xf1, 0x10, 0xf3, + 0x06, 0x04, 0xdb, 0xfb, 0xe7, 0xf8, 0x02, 0x11, 0xff, 0x0d, 0x0a, 0xfa, + 0x27, 0x0a, 0xfc, 0xe8, 0x11, 0x17, 0xf0, 0x0d, 0x0d, 0xee, 0xdf, 0xdd, + 0xf1, 0x15, 0xd6, 0xf7, 0x00, 0xef, 0x2e, 0xe6, 0x24, 0xfd, 0xd5, 0x04, + 0xf0, 0x08, 0x08, 0xed, 0x22, 0x07, 0xe1, 0x09, 0xd0, 0x0b, 0x18, 0xe6, + 0x3f, 0x0a, 0xe5, 0xe2, 0xf9, 0x08, 0x02, 0xd6, 0x13, 0x15, 0xbd, 0x00, + 0x0e, 0xf8, 0xe2, 0xca, 0xec, 0x0e, 0xe6, 0xef, 0x15, 0x11, 0xcb, 0xdf, + 0xf9, 0x03, 0x22, 0x10, 0xfb, 0xf9, 0xe5, 0x08, 0xe1, 0x11, 0x10, 0xfc, + 0xfa, 0x00, 0xf8, 0x30, 0xe5, 0x08, 0x14, 0xe8, 0x12, 0xe2, 0x04, 0x19, + 0x0b, 0xfa, 0x33, 0xf3, 0xec, 0xfe, 0xf8, 0x25, 0xf8, 0x21, 0x28, 0xef, + 0x00, 0xde, 0xff, 0x2b, 0x03, 0xfc, 0x10, 0x0c, 0xcf, 0xfd, 0x19, 0x0a, + 0x0c, 0xf2, 0xf7, 0x0c, 0xfd, 0x02, 0x1c, 0xdf, 0x26, 0x0d, 0xf0, 0x0b, + 0xce, 0x15, 0xfb, 0xec, 0x27, 0xf6, 0xf9, 0xe5, 0xe2, 0xfb, 0xfd, 0xd8, + 0x28, 0xec, 0xe9, 0xf2, 0xca, 0x09, 0x02, 0x06, 0x0c, 0xfa, 0x05, 0x01, + 0xd5, 0x0a, 0x02, 0xfb, 0x04, 0x17, 0xdd, 0xfe, 0xeb, 0xf1, 0x09, 0x10, + 0x12, 0xff, 0x00, 0xe0, 0x26, 0xf7, 0xed, 0xf4, 0x00, 0xf2, 0xfa, 0x07, + 0x02, 0xf5, 0x06, 0xe8, 0x03, 0xfd, 0xdc, 0xf2, 0xc2, 0xff, 0x0b, 0xd6, + 0x25, 0x04, 0xe9, 0xf0, 0xd9, 0x08, 0x09, 0xc5, 0x23, 0x12, 0xf6, 0x13, + 0x11, 0xf3, 0x18, 0xf0, 0x34, 0xfe, 0xfe, 0xed, 0xea, 0x02, 0x17, 0xdc, + 0x1b, 0x1b, 0xea, 0xfe, 0xea, 0xfe, 0xf2, 0xc4, 0xfd, 0x04, 0xe9, 0x0d, + 0x0d, 0x09, 0xca, 0xd4, 0xe1, 0x04, 0x1e, 0xff, 0x0f, 0xef, 0xd6, 0x0f, + 0xd5, 0xf8, 0x26, 0xd6, 0x33, 0xe8, 0xf5, 0x3b, 0xf1, 0xe8, 0x39, 0xe8, + 0x08, 0xe5, 0x01, 0x02, 0x04, 0xf6, 0x19, 0x0a, 0xd0, 0xeb, 0x0b, 0x15, + 0xf7, 0x0e, 0x23, 0xf6, 0xf4, 0xd8, 0xf4, 0x17, 0x23, 0x25, 0x14, 0x01, + 0xd7, 0xfd, 0xf9, 0x1f, 0x1b, 0x11, 0x0a, 0x18, 0xf5, 0xf5, 0x0f, 0xe0, + 0x2e, 0x01, 0xe5, 0xdb, 0xe2, 0xf2, 0x14, 0xfa, 0x2a, 0x00, 0xe2, 0xea, + 0xfd, 0x0e, 0xfc, 0xc1, 0x35, 0x08, 0xf6, 0xf9, 0xec, 0x00, 0x06, 0x00, + 0x0b, 0xf6, 0x01, 0xfe, 0xea, 0x0b, 0x08, 0x05, 0xe4, 0xea, 0xd7, 0xfd, + 0xee, 0xf3, 0x0c, 0x0c, 0x0d, 0x02, 0xfd, 0xee, 0x17, 0x10, 0x13, 0xfd, + 0x07, 0x03, 0xf8, 0x0c, 0xd4, 0xed, 0xfe, 0x07, 0xf4, 0xee, 0xf4, 0x03, + 0xc2, 0x18, 0x2c, 0xd1, 0x33, 0xd8, 0xdb, 0xfa, 0xed, 0x10, 0x1c, 0xe3, + 0x37, 0x0a, 0xea, 0xfe, 0xf6, 0xef, 0x20, 0xed, 0x32, 0xf7, 0xf5, 0xf3, + 0xca, 0xfd, 0x0a, 0xcf, 0x0d, 0x10, 0xde, 0x07, 0x18, 0x10, 0xf0, 0xd6, + 0x0c, 0x04, 0xeb, 0x1a, 0xf9, 0x08, 0xc4, 0xcb, 0xe4, 0x0b, 0x19, 0xfc, + 0x29, 0xf6, 0xec, 0x07, 0xf3, 0xed, 0x2b, 0xe9, 0xfa, 0x02, 0xec, 0x2b, + 0xf0, 0xf2, 0x2d, 0xe8, 0xed, 0x00, 0x12, 0x13, 0xed, 0x1a, 0x3d, 0xf0, + 0x05, 0x04, 0xfc, 0x13, 0x10, 0x01, 0x40, 0xf2, 0x06, 0x02, 0xf9, 0x22, + 0x24, 0xff, 0x18, 0x00, 0xeb, 0xe8, 0x14, 0xf9, 0x25, 0xe0, 0xff, 0x03, + 0xe5, 0xfd, 0x08, 0xea, 0x2e, 0x0b, 0x05, 0xe7, 0xde, 0xe4, 0xf5, 0xea, + 0x3a, 0xf4, 0xf4, 0xe7, 0xed, 0xec, 0xf8, 0xee, 0x30, 0x0a, 0xdb, 0x05, + 0xf7, 0x16, 0xff, 0xf7, 0xfa, 0x1f, 0xef, 0xe4, 0xce, 0xf8, 0x13, 0x04, + 0xf9, 0x01, 0xe1, 0x03, 0xf9, 0xf9, 0x08, 0x04, 0xfa, 0xe4, 0xe7, 0xf7, + 0x28, 0xfd, 0xfd, 0x00, 0xfc, 0xfb, 0xef, 0x0a, 0xec, 0x0c, 0x0a, 0xd2, + 0x05, 0xfb, 0xcd, 0xfb, 0x9d, 0xea, 0x1c, 0xe5, 0x25, 0xe8, 0xea, 0x0b, + 0xf0, 0xf3, 0x0d, 0xab, 0x49, 0x0e, 0xeb, 0x00, 0xe2, 0x03, 0x29, 0xe0, + 0x3d, 0x06, 0xf7, 0xf8, 0xcf, 0x0c, 0x1a, 0xd6, 0x1f, 0xef, 0xfd, 0xff, + 0xef, 0x0c, 0xdb, 0xe0, 0x20, 0x06, 0xdf, 0x1a, 0xe7, 0xfc, 0xb2, 0xd1, + 0xdf, 0x13, 0x07, 0x1f, 0x0c, 0xf7, 0xde, 0x0a, 0xdb, 0xdf, 0x1a, 0xf5, + 0x29, 0x0d, 0xeb, 0x2c, 0xcf, 0x0e, 0x26, 0xfe, 0xef, 0x04, 0xf5, 0x14, + 0x09, 0x13, 0x34, 0xff, 0xfe, 0x0e, 0x06, 0x0e, 0x10, 0xf9, 0x2a, 0x0b, + 0xe6, 0xfe, 0xf1, 0x1a, 0x36, 0x29, 0x29, 0x05, 0x05, 0xd8, 0x14, 0x12, + 0x26, 0x0b, 0x18, 0xff, 0xd7, 0xdf, 0x0f, 0xed, 0x31, 0xf7, 0xfc, 0xec, + 0x0b, 0xef, 0x0c, 0xd2, 0x30, 0xf9, 0x04, 0xfe, 0xef, 0xe4, 0xfb, 0xd1, + 0x32, 0xe5, 0xee, 0xf0, 0x0c, 0xe6, 0x13, 0xed, 0x1e, 0x0b, 0xe4, 0xe0, + 0xfa, 0xf4, 0x14, 0xf4, 0x18, 0xf7, 0xd9, 0xf6, 0xed, 0xea, 0xfc, 0x06, + 0xfc, 0xf5, 0xed, 0xeb, 0x05, 0x03, 0x1b, 0x0b, 0xff, 0x0b, 0xef, 0x01, + 0xf1, 0x16, 0x05, 0x00, 0xee, 0x0a, 0xdb, 0x10, 0xb4, 0x14, 0x0f, 0xe1, + 0x1c, 0xfd, 0xf0, 0xf8, 0xc3, 0x11, 0x17, 0xba, 0x47, 0x15, 0xe6, 0x01, + 0xea, 0xf1, 0x0c, 0x08, 0x4a, 0x15, 0xf0, 0xf7, 0xea, 0x00, 0xf5, 0xd4, + 0xf1, 0xff, 0xe0, 0x0c, 0xf4, 0x17, 0xd8, 0xea, 0x03, 0xff, 0xd5, 0x18, + 0xfb, 0x07, 0xc7, 0xc9, 0xdd, 0xf3, 0x15, 0x0d, 0x22, 0xea, 0xdb, 0x0a, + 0xd6, 0x09, 0x1d, 0xe5, 0x2d, 0x04, 0xfc, 0x35, 0xc6, 0x0e, 0x33, 0xf1, + 0xd7, 0xea, 0x01, 0x1b, 0x0e, 0x01, 0x2a, 0xff, 0xef, 0xf1, 0xf7, 0x0f, + 0xff, 0x00, 0x3b, 0xe8, 0x0a, 0xff, 0xf4, 0x0d, 0x1f, 0x04, 0x17, 0xf7, + 0xdf, 0xec, 0x12, 0x26, 0x36, 0x07, 0x0c, 0x06, 0xe7, 0xd6, 0x13, 0xe3, + 0x30, 0x09, 0x00, 0xf5, 0xe0, 0xf3, 0x11, 0xe2, 0x38, 0x0d, 0xf6, 0x05, + 0xec, 0x05, 0x00, 0xe5, 0x24, 0xef, 0xfe, 0xf8, 0x00, 0xd8, 0x18, 0xf1, + 0x26, 0x0b, 0xf2, 0xfc, 0xe0, 0xe4, 0x06, 0x0b, 0x1a, 0x05, 0xc6, 0xf6, + 0xe8, 0xde, 0xfe, 0x0c, 0x03, 0x09, 0xfe, 0xe2, 0x18, 0x1b, 0xfb, 0xf7, + 0x06, 0xf1, 0xfe, 0xf6, 0xef, 0x1b, 0x07, 0x0d, 0x01, 0x0a, 0xed, 0xf0, + 0xad, 0x1a, 0x17, 0xd6, 0x37, 0xfd, 0xd8, 0xec, 0xca, 0xf1, 0x15, 0xc4, + 0x33, 0xf1, 0xed, 0xf0, 0xe9, 0x15, 0x0d, 0xf2, 0x36, 0xde, 0xfd, 0x0e, + 0xfb, 0x10, 0x0f, 0xf6, 0xf9, 0x0c, 0xea, 0xf0, 0xe5, 0x0b, 0xee, 0xc1, + 0x10, 0xf4, 0xe8, 0x1f, 0xee, 0x00, 0xd0, 0xe4, 0xe7, 0x13, 0x07, 0x27, + 0x12, 0xea, 0xea, 0x0f, 0xea, 0xf4, 0x14, 0xee, 0xfe, 0x09, 0xfb, 0x31, + 0xdb, 0x1b, 0x1c, 0xe7, 0xef, 0xf5, 0xf7, 0x1a, 0x06, 0x01, 0x2c, 0xed, + 0xfb, 0x04, 0xfa, 0x07, 0x19, 0xec, 0x2b, 0x0d, 0xfc, 0xd8, 0xfc, 0x0f, + 0x1f, 0xfc, 0x2d, 0xf3, 0xc9, 0xda, 0x0a, 0xfe, 0x29, 0x00, 0xfa, 0x09, + 0xe8, 0xf6, 0x21, 0xf3, 0x4a, 0x1a, 0xf8, 0x00, 0xe7, 0xf0, 0x21, 0x01, + 0x22, 0xf3, 0x00, 0xe9, 0x06, 0xe3, 0x15, 0xd7, 0x3d, 0x0c, 0x07, 0xf1, + 0xf3, 0xec, 0x17, 0xdf, 0x29, 0x1b, 0xfd, 0xfe, 0xeb, 0xed, 0x17, 0xf6, + 0x23, 0x0a, 0xea, 0xee, 0xf9, 0xf3, 0x0f, 0x0c, 0xf8, 0xf5, 0xed, 0xe8, + 0x1c, 0x14, 0x07, 0x17, 0x0b, 0x0d, 0xed, 0xf7, 0xed, 0x10, 0x07, 0xd5, + 0xf2, 0x09, 0xd6, 0xf7, 0xb5, 0xf6, 0x19, 0xc9, 0x25, 0x15, 0xe8, 0xf5, + 0xc4, 0xf9, 0x2a, 0xb0, 0x39, 0x0e, 0x02, 0x11, 0xf0, 0xf7, 0x1d, 0xeb, + 0x39, 0x10, 0x02, 0x15, 0xe0, 0x08, 0x01, 0xee, 0x1c, 0x1e, 0x08, 0x04, + 0xf2, 0x02, 0xe8, 0xda, 0xfa, 0xfb, 0xe0, 0xfe, 0x05, 0x02, 0xd3, 0xca, + 0xf4, 0xec, 0x10, 0x16, 0x05, 0x0d, 0xd7, 0x09, 0xdc, 0xf6, 0x1e, 0xf8, + 0x10, 0xed, 0xf7, 0x27, 0xf5, 0x08, 0x28, 0xee, 0xec, 0xe0, 0xf8, 0x17, + 0xfb, 0x23, 0x2e, 0xf1, 0xfa, 0xf5, 0xfc, 0x1a, 0x10, 0xf7, 0x32, 0xfb, + 0xfb, 0xe8, 0xf1, 0x03, 0x24, 0xeb, 0x25, 0xf9, 0xca, 0xf1, 0xfe, 0x01, + 0x2e, 0x07, 0x18, 0x03, 0xe5, 0xea, 0x10, 0xfa, 0x3b, 0x07, 0x0f, 0x11, + 0x04, 0xf7, 0x1d, 0xf1, 0x24, 0xd9, 0x08, 0xef, 0x02, 0xdd, 0x07, 0xc8, + 0x2c, 0x0d, 0x06, 0xec, 0x17, 0xda, 0x21, 0xdf, 0x34, 0xd9, 0xfb, 0xf2, + 0xf4, 0xec, 0x0e, 0x0a, 0x0f, 0x0f, 0xdb, 0xf0, 0xfb, 0xe6, 0x0f, 0x00, + 0x04, 0xf9, 0x01, 0x05, 0x05, 0xfe, 0x08, 0xf3, 0x0e, 0xf2, 0xfb, 0x01, + 0xfd, 0x18, 0x1d, 0xf6, 0xee, 0x06, 0xcf, 0xfc, 0xae, 0x27, 0x21, 0xd2, + 0x33, 0x03, 0xe0, 0xe0, 0xc9, 0xfb, 0x3a, 0xbd, 0x4d, 0x04, 0xe8, 0xf5, + 0xe6, 0xeb, 0x19, 0xf2, 0x4b, 0x1d, 0xfc, 0xf7, 0xd9, 0xff, 0xfe, 0xea, + 0x0f, 0x04, 0x0e, 0x00, 0xed, 0x19, 0xe9, 0xe9, 0xff, 0x11, 0xef, 0x14, + 0x01, 0x17, 0xbc, 0xb5, 0xef, 0x0c, 0x22, 0x27, 0x0f, 0x01, 0xd4, 0x03, + 0xce, 0x01, 0x25, 0xff, 0xf9, 0xf0, 0x0a, 0x1c, 0xe5, 0x0f, 0x1c, 0xee, + 0xf4, 0xf1, 0xf4, 0x0c, 0x00, 0x08, 0x1c, 0xf4, 0xd5, 0xf1, 0xfc, 0x1f, + 0x11, 0x00, 0x18, 0x03, 0xf7, 0xe4, 0xff, 0x07, 0x09, 0x1a, 0x18, 0xff, + 0xea, 0xec, 0xfd, 0x13, 0x2b, 0xf8, 0x0c, 0xfa, 0xdf, 0xf6, 0x11, 0xda, + 0x2a, 0xdc, 0xfc, 0xff, 0xff, 0xec, 0x12, 0xe1, 0x37, 0xfd, 0xeb, 0xfe, + 0xea, 0xd1, 0x12, 0xfa, 0x28, 0x1a, 0x0d, 0xf0, 0xf7, 0xe0, 0x0c, 0xeb, + 0x35, 0x14, 0xeb, 0x00, 0xeb, 0xe7, 0x1b, 0xfc, 0x09, 0x00, 0xf2, 0x04, + 0xf9, 0xe5, 0x1a, 0x0e, 0x08, 0x12, 0xf8, 0xfe, 0x09, 0x0f, 0x0d, 0xea, + 0x03, 0xe1, 0xfe, 0xf2, 0xec, 0x0d, 0x02, 0xdb, 0x04, 0x1d, 0xd4, 0x01, + 0xca, 0x13, 0x29, 0xca, 0x28, 0x04, 0xe2, 0xf1, 0xdb, 0x0b, 0x2c, 0xcd, + 0x44, 0x00, 0xe7, 0xf4, 0xd0, 0x12, 0x15, 0xff, 0x42, 0x11, 0x05, 0xfd, + 0xd9, 0x11, 0x1c, 0xf4, 0x15, 0xec, 0xf2, 0x24, 0xd6, 0x1d, 0xec, 0xda, + 0xf5, 0xec, 0xe5, 0x22, 0xf2, 0x0b, 0xbd, 0xd0, 0xeb, 0x05, 0x07, 0x1b, + 0x01, 0xed, 0xf5, 0x02, 0xcf, 0x08, 0x15, 0xfd, 0x1c, 0xe5, 0x04, 0x19, + 0xc7, 0x25, 0x22, 0xf3, 0xde, 0xfb, 0xfb, 0x20, 0xf6, 0xeb, 0x25, 0xfe, + 0xf5, 0x08, 0xf5, 0x17, 0x0e, 0x04, 0x1c, 0xf9, 0xee, 0xec, 0xe1, 0x06, + 0x12, 0xff, 0x2a, 0x13, 0xed, 0xfe, 0x05, 0x18, 0x25, 0x20, 0x09, 0x13, + 0xea, 0xd7, 0x05, 0x06, 0x33, 0x25, 0xff, 0x0a, 0xf0, 0xea, 0x17, 0xe1, + 0x30, 0xfa, 0x0d, 0x0a, 0x04, 0x00, 0x0e, 0xe9, 0x16, 0x20, 0x0d, 0x02, + 0xe8, 0xed, 0x07, 0xe8, 0x3c, 0xf1, 0xd9, 0xfa, 0xe1, 0xed, 0x18, 0xfc, + 0xf0, 0x09, 0xe3, 0x05, 0xfe, 0xd1, 0x0b, 0x0e, 0xf5, 0x25, 0xfd, 0xfb, + 0x30, 0x1e, 0x08, 0xfc, 0x0c, 0x21, 0xea, 0xfc, 0xe5, 0x1e, 0x16, 0xf5, + 0xf4, 0xfc, 0xf0, 0xea, 0xc4, 0x21, 0x27, 0xe9, 0x2b, 0xdb, 0xdb, 0xec, + 0xe5, 0xfe, 0x37, 0xe2, 0x46, 0x25, 0xfa, 0xec, 0xe4, 0xf3, 0x19, 0xf2, + 0x4c, 0x06, 0x00, 0xfb, 0xeb, 0x10, 0x10, 0xf7, 0x2a, 0xf8, 0xe9, 0x18, + 0xee, 0x21, 0xe8, 0xd5, 0xf4, 0x0a, 0xed, 0x24, 0xfe, 0xf9, 0xb2, 0xbc, + 0xf3, 0x1d, 0x00, 0x2f, 0x07, 0x08, 0xe1, 0xf1, 0xed, 0x27, 0x27, 0xfe, + 0x22, 0xfd, 0x02, 0x20, 0xd8, 0x05, 0x25, 0xec, 0xf1, 0xff, 0x0a, 0x0f, + 0xe6, 0xfe, 0x46, 0xfd, 0xe1, 0xca, 0xf7, 0x22, 0x03, 0x08, 0x21, 0xf5, + 0x0f, 0xf7, 0xfb, 0x0c, 0xfb, 0x14, 0x2d, 0x03, 0xe5, 0xe4, 0x09, 0x0b, + 0x1a, 0xe6, 0x01, 0x28, 0xe9, 0xd6, 0x0b, 0xf7, 0x2c, 0xfb, 0x11, 0xee, + 0x0b, 0xed, 0x17, 0xf0, 0x3c, 0xf5, 0x08, 0xfa, 0xf8, 0xcd, 0x17, 0xfa, + 0x39, 0xea, 0x11, 0xf5, 0xed, 0xee, 0x0a, 0xec, 0x41, 0xd6, 0xe7, 0xf9, + 0xfa, 0xc8, 0x15, 0xf7, 0x08, 0x0e, 0xe3, 0x08, 0xe8, 0xec, 0xfd, 0xfe, + 0xf1, 0x00, 0xe9, 0xf4, 0x09, 0x26, 0x02, 0x16, 0xf0, 0x01, 0xef, 0x01, + 0xff, 0x03, 0x22, 0xdb, 0xfc, 0xf5, 0xde, 0xe5, 0xc4, 0x01, 0x28, 0xd4, + 0x38, 0x08, 0xd0, 0xec, 0xd5, 0x04, 0x2f, 0xce, 0x4e, 0xeb, 0xf9, 0xe7, + 0xdf, 0xf0, 0x1b, 0xf5, 0x42, 0xf1, 0xf6, 0x09, 0xd5, 0x0a, 0x0d, 0x08, + 0x04, 0x05, 0xe2, 0x0e, 0xd7, 0x19, 0xdb, 0xda, 0xe1, 0x25, 0xde, 0x15, + 0x0e, 0x14, 0xbd, 0xb0, 0xe3, 0xe5, 0x24, 0x1e, 0xf8, 0x0d, 0xd8, 0xf7, + 0xf2, 0xff, 0x18, 0xf5, 0x07, 0xf0, 0x02, 0x25, 0xd5, 0x1e, 0x2e, 0xdf, + 0xe7, 0x05, 0xef, 0x11, 0xe8, 0xe7, 0x47, 0xf4, 0xe1, 0xde, 0x09, 0x36, + 0x1a, 0x11, 0x11, 0xf5, 0x12, 0xe5, 0xe7, 0x18, 0x01, 0x17, 0x2a, 0x03, + 0x05, 0xea, 0x09, 0x0b, 0x12, 0x04, 0x17, 0xf0, 0xee, 0xd7, 0x11, 0xed, + 0x3c, 0x17, 0x16, 0xff, 0x02, 0xdc, 0x21, 0xf3, 0x2e, 0xe5, 0x13, 0xef, + 0xec, 0xe2, 0x10, 0xd0, 0x2e, 0xee, 0xff, 0x01, 0xe0, 0xe5, 0x0b, 0xda, + 0x1f, 0xf8, 0xf6, 0xfb, 0x07, 0xdb, 0x05, 0xf6, 0x0c, 0xf3, 0xf0, 0x10, + 0xf9, 0xf5, 0xf2, 0x0d, 0x10, 0xf7, 0xf6, 0xff, 0x2b, 0x0d, 0x06, 0x1e, + 0xf3, 0x0c, 0xe9, 0x01, 0xf2, 0x23, 0xfe, 0xe9, 0xdd, 0x12, 0xdd, 0xf7, + 0xbb, 0x22, 0x1b, 0xd4, 0x38, 0x29, 0xd4, 0xcf, 0xf5, 0xf9, 0x27, 0xdd, + 0x47, 0x00, 0xf2, 0xe5, 0x09, 0xfc, 0x0e, 0xf9, 0x34, 0x0a, 0x02, 0xfd, + 0xec, 0x25, 0x1d, 0x03, 0x15, 0x09, 0xf1, 0x1b, 0xd0, 0x17, 0xda, 0xda, + 0xe7, 0x07, 0xe3, 0x15, 0xf1, 0x02, 0xb9, 0xce, 0xe6, 0x0c, 0x10, 0x31, + 0xfe, 0xf7, 0xd9, 0xfa, 0xed, 0xed, 0x33, 0xf4, 0x19, 0xe7, 0xfe, 0x3f, + 0xe5, 0x06, 0x2e, 0xe6, 0xf2, 0xdc, 0xf5, 0x18, 0xe6, 0x01, 0x2f, 0xee, + 0xe7, 0xe4, 0xfe, 0x2c, 0x03, 0xf7, 0x20, 0x05, 0x07, 0xe2, 0x06, 0x1e, + 0x05, 0xed, 0x2f, 0x03, 0xea, 0xf8, 0x0e, 0x0c, 0x1f, 0xff, 0x20, 0xf4, + 0xe8, 0xe1, 0x1c, 0xec, 0x22, 0x1e, 0x05, 0xfd, 0xf5, 0xca, 0x30, 0xe9, + 0x30, 0xe4, 0x14, 0xff, 0xf2, 0xdc, 0x17, 0xf8, 0x26, 0xe1, 0x0b, 0x01, + 0x11, 0xc2, 0x02, 0xf1, 0x36, 0x10, 0x02, 0x05, 0xed, 0xf1, 0x15, 0xfa, + 0x17, 0xf8, 0xf7, 0xf1, 0xe8, 0xd3, 0xfd, 0x08, 0xfb, 0x27, 0xf5, 0xf5, + 0x13, 0x06, 0x0b, 0xf0, 0x01, 0xf9, 0xd7, 0x0e, 0xec, 0x12, 0xfe, 0xfd, + 0xee, 0x25, 0xd8, 0xf1, 0xb2, 0x09, 0x1c, 0xbf, 0x34, 0xea, 0xc8, 0xea, + 0xdb, 0x0e, 0x24, 0xde, 0x47, 0xfe, 0xdc, 0xe0, 0xf3, 0x06, 0x20, 0xfe, + 0x2b, 0xf6, 0x18, 0x14, 0xcd, 0x19, 0x16, 0xfe, 0x1a, 0x15, 0xf8, 0x11, + 0xf4, 0x22, 0xd7, 0xcc, 0xdd, 0x15, 0xdc, 0x14, 0xf9, 0x02, 0xbb, 0xca, + 0xe3, 0xf3, 0x0d, 0x1e, 0x2a, 0x0c, 0xe4, 0x05, 0xe0, 0x18, 0x2a, 0x07, + 0x20, 0xed, 0xf6, 0x17, 0xcf, 0xf4, 0x2a, 0xd6, 0xfb, 0xce, 0x03, 0x37, + 0xe2, 0xfd, 0x1d, 0xfb, 0xe5, 0xe0, 0x05, 0x29, 0xef, 0x16, 0x23, 0xf7, + 0x01, 0xf4, 0x0c, 0x14, 0xff, 0xee, 0x31, 0xf9, 0x12, 0xf9, 0x14, 0xf6, + 0x0c, 0xf6, 0x0b, 0x0f, 0xd8, 0xdc, 0xfe, 0x0f, 0x37, 0xfa, 0x01, 0x09, + 0x04, 0xd1, 0x0b, 0x0c, 0x29, 0xf3, 0x0a, 0xf9, 0xed, 0xc2, 0x18, 0xf4, + 0x25, 0x18, 0x0f, 0x08, 0xf7, 0xed, 0x1f, 0xf7, 0x4f, 0x0e, 0xf0, 0xe4, + 0x00, 0xeb, 0xfa, 0x1a, 0x0c, 0x03, 0xe9, 0xfc, 0xf0, 0xcc, 0x06, 0x05, + 0xf2, 0x12, 0x04, 0xe2, 0x16, 0x0a, 0x0a, 0xf3, 0x0b, 0xf3, 0xdc, 0xfd, + 0x10, 0xfc, 0x0e, 0xe2, 0xe0, 0xfe, 0xf0, 0xff, 0xb1, 0x06, 0x1b, 0xe4, + 0x30, 0x13, 0xc6, 0xc3, 0xfa, 0x0c, 0x1e, 0xd9, 0x57, 0x11, 0xe1, 0xd6, + 0xfa, 0xee, 0x1d, 0xf7, 0x37, 0xea, 0xf0, 0x05, 0xef, 0x24, 0x1e, 0xf1, + 0x10, 0xe8, 0xeb, 0x19, 0xd1, 0x18, 0xf5, 0xc8, 0xf8, 0xec, 0xf5, 0x1f, + 0xf2, 0xff, 0xb3, 0xd2, 0xe6, 0x0e, 0x06, 0x2e, 0x07, 0x17, 0xe0, 0xf5, + 0x02, 0xf9, 0x20, 0x07, 0x16, 0x08, 0xe8, 0x1d, 0xd3, 0x08, 0x34, 0xda, + 0xf2, 0xce, 0xfb, 0x1f, 0xe1, 0x00, 0x2d, 0xdb, 0xdf, 0xcc, 0x05, 0xfb, + 0xf7, 0x00, 0x33, 0xf9, 0x0b, 0x01, 0x13, 0x28, 0xf8, 0x07, 0x24, 0xf8, + 0x0f, 0x03, 0x0d, 0xe9, 0x06, 0xfe, 0x18, 0xf9, 0xed, 0xf5, 0x0c, 0xe0, + 0x2c, 0x0e, 0xf9, 0x06, 0xfb, 0xce, 0x27, 0xe8, 0x29, 0x19, 0xf9, 0x01, + 0x0e, 0xc8, 0x25, 0xed, 0x30, 0xeb, 0x01, 0xfe, 0x10, 0xdc, 0x1e, 0x00, + 0x1e, 0x10, 0xf9, 0x00, 0xfc, 0xc8, 0x0e, 0x04, 0x13, 0x04, 0xf0, 0x02, + 0xfe, 0xd8, 0x0f, 0x1b, 0xf7, 0xe1, 0xf8, 0xde, 0x12, 0xe2, 0xef, 0x0a, + 0x02, 0xe0, 0xdd, 0xf1, 0x0e, 0x2a, 0x25, 0x15, 0xeb, 0x02, 0xf4, 0xf0, + 0xbf, 0xfc, 0x27, 0xdc, 0x42, 0x0f, 0xe9, 0xbf, 0xe8, 0x20, 0x33, 0xc9, + 0x3f, 0x10, 0xec, 0xf3, 0x03, 0x02, 0x2c, 0x04, 0x38, 0x06, 0x0a, 0xf9, + 0xe5, 0x1c, 0x3f, 0x0f, 0x0c, 0x25, 0xe2, 0x06, 0xe6, 0x03, 0xf4, 0xd7, + 0xfe, 0xf6, 0xe7, 0x2f, 0xfa, 0x03, 0xb6, 0xcb, 0xf1, 0x11, 0x0a, 0x2c, + 0xfc, 0x1e, 0xe0, 0xff, 0xc2, 0xdd, 0x1d, 0xf3, 0x10, 0xfa, 0x07, 0x1e, + 0xf6, 0x20, 0x07, 0xe6, 0xf1, 0x0a, 0xe8, 0x27, 0xf1, 0xf5, 0x24, 0xed, + 0xfd, 0xee, 0x13, 0x15, 0xe9, 0xe2, 0x22, 0xe5, 0xf9, 0xdd, 0x1d, 0x32, + 0x04, 0xfa, 0x25, 0x00, 0xee, 0xfd, 0x0b, 0x0e, 0x23, 0xfa, 0x0f, 0x01, + 0xf8, 0xf0, 0x15, 0xe4, 0x21, 0xf7, 0x10, 0xf9, 0xe7, 0xc3, 0x19, 0xe1, + 0x34, 0xff, 0xed, 0xf4, 0xef, 0xd7, 0x21, 0x01, 0x31, 0xee, 0xf7, 0xf2, + 0xf3, 0xe5, 0x0a, 0xee, 0x2e, 0x1e, 0xf2, 0x0c, 0x07, 0xc2, 0x08, 0x0a, + 0x14, 0x14, 0x00, 0xfc, 0xf9, 0xd6, 0xfb, 0xf8, 0xe5, 0xf1, 0xfa, 0xe0, + 0x15, 0x21, 0xef, 0x06, 0xf9, 0x00, 0xf5, 0xf4, 0x0b, 0x0b, 0x18, 0x02, + 0xf5, 0x04, 0xdb, 0xfd, 0xcc, 0x32, 0x1d, 0xc9, 0x3b, 0x12, 0xd9, 0xaf, + 0xcf, 0x0f, 0x26, 0xde, 0x35, 0xe4, 0xdb, 0xd3, 0x22, 0x11, 0x2e, 0xfb, + 0x36, 0xfa, 0xfd, 0x02, 0xeb, 0x0f, 0x37, 0x0b, 0x14, 0x1d, 0xdd, 0x18, + 0xe0, 0x10, 0xe0, 0xdf, 0x14, 0xf9, 0xf0, 0x19, 0xf7, 0xfb, 0xc4, 0xe5, + 0xe7, 0x11, 0x01, 0x31, 0x1a, 0xf7, 0xd8, 0xf1, 0xe9, 0xf3, 0x21, 0xf9, + 0xfe, 0xe4, 0xe9, 0x02, 0xd0, 0x06, 0x14, 0xd7, 0xfc, 0xec, 0x06, 0x10, + 0xfc, 0xf0, 0x1c, 0xe7, 0xec, 0xe3, 0x03, 0x21, 0xe4, 0x04, 0x12, 0xf0, + 0xf3, 0xed, 0x16, 0x36, 0x02, 0xfd, 0x13, 0x11, 0xdf, 0xeb, 0x19, 0x07, + 0x10, 0x0c, 0xf9, 0x08, 0xf8, 0xf4, 0x1d, 0xfd, 0x1d, 0x16, 0xf4, 0x0a, + 0x08, 0xec, 0x0c, 0x09, 0x3d, 0xe0, 0x0b, 0xee, 0x10, 0xd1, 0x1e, 0x15, + 0x43, 0xeb, 0xfa, 0xf3, 0x05, 0xc7, 0xf2, 0xd9, 0x25, 0x20, 0xee, 0xe9, + 0xfd, 0xce, 0x16, 0x0c, 0x27, 0x06, 0x0a, 0x06, 0xf9, 0xd6, 0x0b, 0x05, + 0xe8, 0x02, 0xe8, 0xd2, 0x10, 0x01, 0xf2, 0x15, 0x09, 0x04, 0xd3, 0xe2, + 0xfe, 0xf0, 0x32, 0x1b, 0xd9, 0xf5, 0xea, 0xcc, 0xcb, 0x10, 0x1c, 0xf1, + 0x3b, 0x02, 0xd4, 0xbf, 0xca, 0xfe, 0x12, 0xdb, 0x3b, 0xf8, 0xd5, 0xe7, + 0x13, 0x10, 0x1a, 0xf4, 0x38, 0x09, 0x08, 0xee, 0xf4, 0xf4, 0x3c, 0xf7, + 0x15, 0x04, 0xe4, 0xfa, 0xf4, 0x04, 0xee, 0xf4, 0x07, 0xf8, 0xe9, 0x3b, + 0xe2, 0x1f, 0xd5, 0xed, 0xe6, 0xfd, 0x18, 0x49, 0x21, 0x06, 0xd8, 0xde, + 0xfa, 0xf0, 0x1b, 0xfe, 0xde, 0x08, 0xf7, 0x14, 0xc7, 0x0f, 0x1d, 0xcf, + 0x00, 0xea, 0xff, 0x1b, 0xd5, 0x08, 0x0d, 0xd9, 0xf1, 0xf4, 0x16, 0x23, + 0xd8, 0x0c, 0x29, 0xdc, 0xf1, 0xf2, 0x21, 0x49, 0xfc, 0xe2, 0x08, 0x01, + 0xf0, 0xf8, 0x17, 0xf9, 0x0f, 0xf5, 0xfa, 0x1a, 0xef, 0xec, 0x09, 0xeb, + 0x1a, 0x0c, 0x17, 0x09, 0x11, 0xe9, 0x1a, 0xf7, 0x29, 0xf9, 0xfd, 0x07, + 0x01, 0xdd, 0x0a, 0xec, 0x22, 0x15, 0x03, 0xfd, 0xe2, 0xd2, 0x15, 0xec, + 0x4d, 0xd7, 0xfc, 0xf6, 0x0b, 0xcc, 0x0e, 0x04, 0x03, 0xf7, 0xfb, 0xfb, + 0x0d, 0xeb, 0x19, 0x07, 0xf4, 0xf4, 0xe5, 0xde, 0x22, 0x07, 0xea, 0xf7, + 0xeb, 0x23, 0xc8, 0xee, 0x03, 0x04, 0x0f, 0x19, 0xc3, 0xf8, 0x06, 0xd0, + 0xf7, 0xfe, 0x0e, 0xe7, 0x0a, 0x02, 0xb0, 0xb8, 0x00, 0xfb, 0x18, 0x0f, + 0x22, 0xf7, 0xe9, 0xdc, 0x09, 0x15, 0x23, 0x0d, 0x22, 0x13, 0xe2, 0xed, + 0xeb, 0x18, 0x20, 0x0b, 0x12, 0xfc, 0x02, 0xf1, 0xdb, 0x0e, 0xe1, 0x04, + 0xdb, 0x0f, 0xf3, 0x1a, 0x06, 0xef, 0xdb, 0xdc, 0xdd, 0xfb, 0x00, 0x2a, + 0x20, 0xfd, 0xc1, 0xe3, 0xef, 0x01, 0x14, 0xf2, 0x14, 0x00, 0x0f, 0x28, + 0xd9, 0xff, 0xf4, 0xdc, 0x09, 0xfa, 0x1c, 0x08, 0xd1, 0x03, 0x0a, 0xf4, + 0xe4, 0xdb, 0x20, 0x30, 0xea, 0x06, 0x11, 0xe2, 0x26, 0xf7, 0x16, 0x22, + 0xf9, 0x07, 0x02, 0xf5, 0xf6, 0xfb, 0x1d, 0x0c, 0x16, 0x0a, 0x07, 0xf9, + 0x11, 0xde, 0x20, 0x08, 0x19, 0x04, 0x0a, 0x0b, 0x0c, 0xf7, 0xf4, 0xfc, + 0x41, 0xf1, 0xf8, 0x16, 0x09, 0xdc, 0x0e, 0x1a, 0x2b, 0x1f, 0xe7, 0xfe, + 0x01, 0xe0, 0xfd, 0xe2, 0x34, 0xec, 0xf3, 0xf5, 0x03, 0xec, 0x0b, 0xfb, + 0x04, 0xf6, 0xdd, 0xfd, 0x06, 0x14, 0x0d, 0xfa, 0xfc, 0xf1, 0x0a, 0xca, + 0x01, 0xec, 0x0e, 0x0e, 0xec, 0xd7, 0xee, 0xd4, 0xf2, 0xfe, 0x16, 0xfa, + 0xbd, 0x0d, 0xef, 0xcb, 0xc4, 0xee, 0xed, 0x13, 0x10, 0x19, 0xf8, 0xb1, + 0xf1, 0xe3, 0x00, 0xf3, 0x0c, 0xf6, 0xde, 0xc6, 0x15, 0x27, 0x14, 0x29, + 0x15, 0xf6, 0xf4, 0xf5, 0xe7, 0x00, 0x0b, 0x2f, 0x0c, 0xef, 0x03, 0x0f, + 0xfd, 0x08, 0xf3, 0xf9, 0xf9, 0x05, 0x0d, 0x34, 0x15, 0x1b, 0xc8, 0xd1, + 0xf2, 0x1b, 0x0a, 0x22, 0x12, 0x11, 0xe9, 0xf4, 0xe1, 0x2a, 0x20, 0x03, + 0xf2, 0xf8, 0x14, 0x0b, 0xd0, 0xf4, 0x0e, 0xbf, 0xc6, 0xd8, 0x04, 0x05, + 0xf8, 0xf4, 0x04, 0xc9, 0xea, 0xfd, 0xf7, 0xfa, 0xe3, 0x1b, 0x11, 0xde, + 0x0c, 0x11, 0x25, 0x29, 0xe5, 0x02, 0xef, 0xef, 0x02, 0xfa, 0x1a, 0x21, + 0x19, 0x09, 0x08, 0x05, 0x04, 0xe5, 0xfa, 0xed, 0x2d, 0x26, 0xfa, 0x17, + 0xf6, 0xe8, 0x12, 0x12, 0x31, 0xfc, 0x0d, 0x00, 0xf7, 0xeb, 0x19, 0xf1, + 0x2a, 0x06, 0x14, 0xec, 0x08, 0xd3, 0x21, 0x07, 0x32, 0xe3, 0x02, 0x0b, + 0xfb, 0xd8, 0x27, 0x07, 0x05, 0xe6, 0xf5, 0xf5, 0x0a, 0xf7, 0x2c, 0x2a, + 0xd8, 0x1b, 0xda, 0xf7, 0xea, 0xf6, 0xf9, 0x0e, 0xf8, 0x0c, 0x05, 0xc7, + 0xd6, 0x06, 0x12, 0xe3, 0xe1, 0xe1, 0xd8, 0xdb, 0xc6, 0xf8, 0xe6, 0xfa, + 0x0c, 0x07, 0xf8, 0xe7, 0xe1, 0x0f, 0x00, 0xf3, 0x03, 0xf0, 0xde, 0xcc, + 0xf5, 0xfc, 0xef, 0x1e, 0x16, 0x13, 0xfb, 0xf4, 0x03, 0xe9, 0xfc, 0xfa, + 0x15, 0xe8, 0x15, 0x09, 0xf1, 0x0d, 0xdb, 0x0a, 0xe8, 0x09, 0xf5, 0x1a, + 0x04, 0xf8, 0xd8, 0xd4, 0x04, 0xee, 0x25, 0x29, 0x09, 0xfe, 0xf3, 0xf5, + 0xd4, 0x0a, 0x15, 0x19, 0xf5, 0x12, 0xfe, 0x04, 0xe7, 0x01, 0xeb, 0xde, + 0xbe, 0xfe, 0x09, 0x12, 0xdf, 0x13, 0xe0, 0xef, 0xc7, 0xff, 0x03, 0x08, + 0xfe, 0xf2, 0x19, 0xe0, 0xe4, 0x0c, 0x22, 0x1e, 0x05, 0xf7, 0x16, 0xf2, + 0xf9, 0x06, 0x17, 0xf6, 0x0c, 0x1e, 0x23, 0x08, 0xfe, 0xdc, 0xfd, 0x17, + 0x11, 0xdf, 0xf5, 0x0f, 0x01, 0x03, 0x08, 0xee, 0x1b, 0x02, 0x0b, 0x1b, + 0x0c, 0x16, 0x1a, 0x00, 0x0f, 0x26, 0x14, 0xf8, 0xf4, 0xf3, 0x19, 0x16, + 0x22, 0x0a, 0xd0, 0xf9, 0xf1, 0x05, 0x2b, 0x1e, 0x1e, 0xef, 0xf5, 0x06, + 0x05, 0xe7, 0x3f, 0x2a, 0x06, 0xf0, 0x15, 0x14, 0x13, 0x20, 0x1b, 0xde, + 0x10, 0x05, 0x33, 0xf8, 0x08, 0x04, 0x17, 0x0d, 0x0f, 0xf6, 0x01, 0xed, + 0x28, 0x25, 0x1c, 0x13, 0xfb, 0xea, 0xfb, 0xf3, 0x1c, 0xf9, 0x1f, 0xf0, + 0xfb, 0x17, 0xf8, 0xff, 0x10, 0xf7, 0x0b, 0x24, 0x04, 0x00, 0x0d, 0x0c, + 0xf7, 0x0a, 0x16, 0x13, 0xf8, 0x05, 0x0a, 0xf1, 0xf5, 0xee, 0xf8, 0x14, + 0x0e, 0xed, 0xfe, 0x1b, 0xfe, 0x17, 0x13, 0x10, 0x12, 0x21, 0x1c, 0xfa, + 0xe5, 0x0b, 0x08, 0x0c, 0x10, 0x1b, 0x03, 0xef, 0x0d, 0x05, 0x0a, 0xf0, + 0x04, 0x11, 0x15, 0x00, 0xfd, 0xef, 0x02, 0x18, 0xf4, 0x09, 0xfa, 0xf6, + 0x02, 0xf7, 0xfd, 0x13, 0xef, 0x13, 0xf7, 0xf9, 0x17, 0x0f, 0xfa, 0xf8, + 0x15, 0xff, 0x04, 0xef, 0xf0, 0x15, 0xfa, 0xfe, 0xf0, 0xf4, 0xed, 0x06, + 0x1c, 0x02, 0xfb, 0xf7, 0x05, 0xfb, 0x0c, 0xef, 0xf4, 0xf0, 0xf6, 0xec, + 0x17, 0xf3, 0xf5, 0xef, 0x02, 0xfd, 0xe5, 0x21, 0x0c, 0xf1, 0x1e, 0x08, + 0xf1, 0x0b, 0xf7, 0x09, 0x1d, 0xf2, 0xf9, 0xf2, 0xfb, 0x0e, 0xed, 0xf8, + 0xfa, 0xdd, 0xf0, 0xfd, 0xdb, 0x1a, 0xf4, 0xef, 0x0c, 0x06, 0x0f, 0xdf, + 0xe2, 0x06, 0x06, 0xee, 0xfa, 0x0d, 0x17, 0xfc, 0xf9, 0x15, 0x1a, 0xe4, + 0xfb, 0x0c, 0x1a, 0xfc, 0x1b, 0x04, 0x07, 0x20, 0xff, 0x09, 0x0f, 0xf2, + 0x26, 0x19, 0x1f, 0x0d, 0x02, 0x16, 0x03, 0x03, 0xfd, 0x05, 0x01, 0x1b, + 0x0a, 0x11, 0xfa, 0x21, 0x13, 0xfb, 0x0c, 0x05, 0xf3, 0xdd, 0xe4, 0xdc, + 0x22, 0x1b, 0x15, 0x14, 0x0e, 0xe8, 0x00, 0xf7, 0xf8, 0xf4, 0x0b, 0x0b, + 0xfd, 0x21, 0xe3, 0x0f, 0xe1, 0x22, 0x01, 0x21, 0x0b, 0x1f, 0x09, 0x10, + 0xe2, 0x18, 0x11, 0x0e, 0xed, 0x01, 0x14, 0x12, 0xfd, 0x11, 0xf6, 0xe9, + 0x20, 0xe1, 0xf5, 0x1b, 0x27, 0x22, 0xfa, 0xf7, 0xfe, 0x13, 0xf6, 0xdc, + 0x06, 0x0d, 0xf4, 0x05, 0x20, 0x0d, 0x0b, 0xe4, 0x15, 0x28, 0x0c, 0x00, + 0xf5, 0x07, 0x0c, 0x0a, 0x06, 0x0e, 0xf3, 0xfb, 0xfe, 0x04, 0x08, 0xf4, + 0xef, 0x03, 0xe4, 0xeb, 0x06, 0xee, 0xed, 0xdb, 0xeb, 0x1d, 0xf4, 0xfa, + 0x0c, 0xfc, 0xfe, 0x11, 0xf7, 0xf8, 0xf5, 0xef, 0xe7, 0xfc, 0x1b, 0xdc, + 0x17, 0xfd, 0xfe, 0x00, 0xea, 0xf4, 0xf1, 0xf7, 0x0f, 0x21, 0x04, 0xfd, + 0x0d, 0x0c, 0x0a, 0x14, 0xfd, 0x19, 0x09, 0x01, 0xfd, 0xe2, 0x0c, 0x0c, + 0xe0, 0x25, 0xfb, 0xff, 0x0d, 0x18, 0xf6, 0x0b, 0x19, 0x12, 0x10, 0x09, + 0x0b, 0x06, 0x12, 0x1c, 0x10, 0x03, 0x13, 0x0a, 0x05, 0x0f, 0x09, 0x01, + 0x21, 0xe4, 0x01, 0x26, 0xf9, 0xf4, 0x05, 0x19, 0x00, 0xff, 0x0b, 0xff, + 0x16, 0x09, 0xe7, 0xee, 0xed, 0xf5, 0x0f, 0x2f, 0xee, 0x19, 0x03, 0x0a, + 0x10, 0xee, 0xf7, 0x2e, 0xf4, 0x08, 0xf7, 0xee, 0x07, 0x00, 0xfc, 0x0e, + 0xf0, 0x12, 0x08, 0x05, 0xed, 0x11, 0xfc, 0xfb, 0xf7, 0x25, 0xf1, 0x05, + 0x0c, 0xf9, 0xfa, 0x03, 0x0c, 0x16, 0x04, 0x25, 0xf8, 0xe7, 0xfc, 0x11, + 0x0d, 0x19, 0xd8, 0xfa, 0x0b, 0x06, 0xfd, 0xef, 0x13, 0xf6, 0xff, 0x0e, + 0xf9, 0x04, 0xf1, 0xdc, 0xfb, 0xe1, 0xf6, 0x0b, 0x15, 0x07, 0xf7, 0x02, + 0x0e, 0xf1, 0xfd, 0xe3, 0xeb, 0x07, 0xf1, 0xef, 0x03, 0xfe, 0xf8, 0x07, + 0x10, 0xf7, 0x00, 0xf9, 0xf2, 0x0e, 0xf9, 0xf2, 0x1d, 0xf5, 0xd8, 0xff, + 0xe6, 0x18, 0x2a, 0x1b, 0x03, 0x16, 0xfe, 0xf4, 0xf5, 0xfd, 0x04, 0x01, + 0xfe, 0xfe, 0x07, 0xfc, 0x0e, 0xfa, 0x15, 0xeb, 0x02, 0x15, 0xea, 0xfd, + 0x04, 0xe5, 0xfe, 0xed, 0xfe, 0x1a, 0x09, 0x2a, 0x1b, 0xdf, 0xfb, 0xf8, + 0xf1, 0x04, 0x1a, 0x34, 0x07, 0xf9, 0x0d, 0xf5, 0xef, 0xec, 0x10, 0x1a, + 0x0b, 0x0f, 0x13, 0xfe, 0x10, 0x22, 0x1e, 0x02, 0xe6, 0xf7, 0x11, 0xfa, + 0x11, 0xfc, 0x1b, 0x21, 0x12, 0xf4, 0x18, 0x16, 0x29, 0xe4, 0x0c, 0x2e, + 0x12, 0x07, 0x20, 0xf6, 0x1d, 0xf4, 0x12, 0x33, 0xf4, 0xee, 0xfe, 0x05, + 0x06, 0xfb, 0x13, 0x0c, 0x0e, 0xf0, 0x00, 0xf8, 0xee, 0xf3, 0x17, 0x00, + 0xf7, 0xfb, 0xfc, 0x0f, 0xf4, 0xd5, 0x0a, 0xed, 0xeb, 0xf5, 0xe9, 0xef, + 0xd8, 0xf0, 0xf8, 0xe2, 0x19, 0xf7, 0xf8, 0x0a, 0x0b, 0x09, 0xfa, 0xe7, + 0x0f, 0xfc, 0xe8, 0x02, 0x00, 0x1a, 0xfe, 0xfd, 0x1b, 0xe6, 0xef, 0x0f, + 0xe3, 0x10, 0xf1, 0xe2, 0x0b, 0x0e, 0x06, 0x29, 0x00, 0x01, 0xf3, 0x00, + 0x11, 0x04, 0xf2, 0xf7, 0xea, 0xf8, 0xe0, 0x09, 0x0e, 0x13, 0xf4, 0x00, + 0x09, 0xfa, 0xf5, 0x0c, 0xff, 0x18, 0x08, 0x0d, 0xfa, 0xde, 0xfa, 0x03, + 0xf2, 0xf3, 0x1b, 0xeb, 0x06, 0xea, 0xfb, 0xff, 0x0d, 0xf5, 0x10, 0x17, + 0xf8, 0xe8, 0xf1, 0xf1, 0xf5, 0x00, 0x03, 0x0a, 0x09, 0x0a, 0xf3, 0xfb, + 0x33, 0x26, 0xe7, 0x17, 0xe3, 0xfa, 0x1f, 0x24, 0xfc, 0x07, 0x02, 0xe2, + 0xeb, 0x08, 0x2c, 0xf8, 0x02, 0x1f, 0x04, 0xeb, 0x0b, 0x04, 0x17, 0xf7, + 0xff, 0x1c, 0xed, 0x00, 0x3f, 0xd5, 0x17, 0x1d, 0xfe, 0x03, 0xf1, 0x1c, + 0x17, 0xec, 0x0e, 0x54, 0xee, 0xf5, 0x25, 0xfa, 0x08, 0xee, 0x13, 0x32, + 0x0e, 0xd8, 0x09, 0x0f, 0xee, 0xe5, 0x06, 0x10, 0xf4, 0xfb, 0xe4, 0xfb, + 0x09, 0xde, 0x13, 0xff, 0x02, 0xf9, 0xec, 0x0a, 0x00, 0xe9, 0xfd, 0xdc, + 0x06, 0x04, 0xdb, 0x06, 0x01, 0xf8, 0x09, 0xe2, 0x0c, 0x14, 0xda, 0xfe, + 0x20, 0xe3, 0x09, 0xda, 0x14, 0x12, 0xe1, 0x05, 0xff, 0xf3, 0x00, 0x08, + 0xfb, 0xf1, 0xfd, 0xf3, 0x04, 0xfa, 0x08, 0xff, 0x01, 0x1d, 0x0b, 0xfd, + 0x0a, 0xf4, 0xfb, 0xfc, 0xf9, 0x19, 0xed, 0xfc, 0xf2, 0x06, 0xe7, 0x02, + 0xf6, 0x0c, 0xfc, 0xfb, 0x01, 0x0c, 0xeb, 0x1b, 0xff, 0xff, 0x08, 0x1d, + 0xf7, 0xe8, 0xfc, 0xf4, 0x0c, 0xfa, 0xf1, 0xee, 0xed, 0xdd, 0xfc, 0x06, + 0x05, 0xdc, 0x1a, 0xfc, 0xf9, 0x07, 0xdf, 0x1b, 0x14, 0x0c, 0xfc, 0x01, + 0x16, 0xe1, 0xed, 0x09, 0x34, 0xee, 0xe4, 0x1c, 0x1b, 0xfc, 0x3b, 0x03, + 0x15, 0xf2, 0xeb, 0x14, 0x00, 0xdd, 0x24, 0x04, 0xf1, 0xed, 0xfd, 0xe6, + 0x32, 0xf9, 0x24, 0x04, 0x0e, 0x22, 0x03, 0x14, 0x2f, 0xf5, 0x1a, 0x37, + 0xf4, 0x18, 0x03, 0x0f, 0x4b, 0xe6, 0x0d, 0x5c, 0xf7, 0x1f, 0x1c, 0xe6, + 0x23, 0x0c, 0x15, 0x4e, 0xe0, 0x05, 0x1c, 0xec, 0xff, 0x04, 0x13, 0x15, + 0xee, 0x07, 0xec, 0x0c, 0xdd, 0xf8, 0x0e, 0x03, 0x0c, 0x1f, 0xe8, 0x0e, + 0xf5, 0xec, 0xfc, 0xe2, 0xe8, 0xfb, 0xf6, 0x00, 0xe5, 0xea, 0xf3, 0xd3, + 0xf5, 0xfd, 0xd2, 0xfd, 0x1b, 0xed, 0x09, 0xd1, 0x23, 0xfa, 0xd4, 0xf7, + 0xe9, 0xf0, 0x0a, 0xd6, 0x14, 0x03, 0xe6, 0x10, 0xf4, 0x18, 0xfe, 0xe1, + 0x0b, 0x25, 0xf5, 0xfc, 0xe9, 0xf2, 0xe9, 0xf4, 0x0d, 0xf5, 0x00, 0xf9, + 0x17, 0x02, 0xfd, 0x03, 0x04, 0xf8, 0xf5, 0x14, 0xe3, 0xd3, 0xeb, 0xe7, + 0x09, 0xf3, 0x14, 0x17, 0xee, 0xe6, 0xf6, 0xff, 0x11, 0x26, 0xf4, 0xf7, + 0x02, 0xfa, 0x05, 0x08, 0x16, 0xff, 0x0d, 0xf7, 0xf1, 0xf7, 0xe6, 0xfb, + 0x04, 0x04, 0x07, 0x02, 0x04, 0x09, 0xf5, 0xfc, 0x5f, 0xd6, 0xe7, 0x2a, + 0x23, 0xf4, 0x1b, 0x06, 0x01, 0xea, 0xe7, 0x05, 0x25, 0xe3, 0x25, 0x07, + 0xea, 0xfb, 0xfb, 0x09, 0x25, 0xde, 0x37, 0x04, 0x07, 0xe5, 0xff, 0x14, + 0x2f, 0x0a, 0x30, 0x23, 0x04, 0xf0, 0x23, 0xfe, 0x1c, 0xd2, 0x2b, 0x55, + 0x01, 0xe5, 0x26, 0xfe, 0x14, 0xed, 0x24, 0x46, 0xe6, 0xee, 0x0f, 0xfd, + 0xed, 0xef, 0x0e, 0x1e, 0x05, 0x0a, 0x12, 0xff, 0xe4, 0xf5, 0x0c, 0xed, + 0xfd, 0xea, 0x0d, 0x13, 0x1a, 0xe5, 0xfc, 0xc2, 0xef, 0x0a, 0xe2, 0x0f, + 0xfe, 0xff, 0x0c, 0xf0, 0xff, 0xdf, 0xea, 0x00, 0xf6, 0xe1, 0x04, 0xd8, + 0x26, 0x20, 0xdc, 0xf4, 0x19, 0x06, 0xe8, 0xd2, 0x10, 0x04, 0xf1, 0x02, + 0x0c, 0x06, 0xf0, 0xf0, 0x04, 0x1f, 0xf4, 0xf5, 0xed, 0xf1, 0xfa, 0xf1, + 0x04, 0x02, 0xf8, 0xfb, 0x04, 0xf1, 0xe5, 0xe4, 0x0a, 0xf0, 0xfe, 0xef, + 0x1c, 0xe3, 0xeb, 0xf3, 0x00, 0x17, 0x01, 0x13, 0x19, 0xda, 0xf8, 0x06, + 0xde, 0x11, 0xea, 0xf7, 0xf4, 0xef, 0x03, 0x04, 0x0b, 0xe8, 0x08, 0x0e, + 0xe2, 0xee, 0xde, 0x06, 0x0e, 0x29, 0xfb, 0xfa, 0x00, 0x02, 0xec, 0x1b, + 0x52, 0xff, 0xde, 0x3a, 0x2f, 0x13, 0x30, 0xe9, 0xff, 0xf6, 0xe7, 0x15, + 0x1d, 0xd9, 0x3c, 0x0f, 0xe6, 0x14, 0xee, 0x13, 0x1f, 0xe7, 0x33, 0x08, + 0xfc, 0x06, 0x0c, 0x08, 0x19, 0xd9, 0x2b, 0x1f, 0x07, 0x10, 0x24, 0x16, + 0x29, 0xfc, 0x31, 0x4d, 0xf0, 0xd9, 0x3f, 0xf2, 0x20, 0xe2, 0x25, 0x49, + 0xe5, 0xec, 0x0a, 0xf5, 0xf2, 0xd9, 0x22, 0x1f, 0xed, 0x22, 0x02, 0x0a, + 0x16, 0x08, 0xf7, 0xfb, 0x0e, 0xfb, 0xfb, 0x1d, 0xf3, 0x1c, 0xf6, 0xe1, + 0xcf, 0x19, 0xf4, 0x0f, 0xee, 0xf9, 0x04, 0xd1, 0xf9, 0xe2, 0xda, 0xf1, + 0x24, 0xf5, 0x07, 0xdf, 0x1d, 0xf9, 0xdb, 0x18, 0x0b, 0xea, 0x08, 0xca, + 0xf2, 0xfa, 0xec, 0x04, 0x0e, 0x17, 0xed, 0xf1, 0x06, 0x15, 0xfc, 0xfd, + 0x08, 0xfa, 0xe3, 0xe4, 0x0a, 0xfc, 0xee, 0x08, 0xf5, 0x09, 0xef, 0xee, + 0x06, 0xef, 0xe1, 0x19, 0x07, 0xe8, 0xe6, 0xdf, 0xea, 0x0d, 0xf1, 0x16, + 0xee, 0xed, 0xf8, 0x09, 0xfa, 0xfb, 0x0c, 0xf8, 0xeb, 0xda, 0x00, 0xfc, + 0x04, 0xfe, 0xf5, 0xff, 0xf6, 0xe1, 0x0c, 0x0a, 0x13, 0x0d, 0xf6, 0xf5, + 0x15, 0x07, 0xca, 0xec, 0x50, 0x0e, 0xd0, 0x26, 0x4c, 0xf8, 0x23, 0xeb, + 0xff, 0x08, 0xe3, 0x11, 0x2c, 0xf9, 0x2a, 0xf1, 0xe9, 0x0b, 0xe9, 0x0f, + 0x15, 0xec, 0x33, 0x11, 0x0c, 0x0d, 0x01, 0x01, 0x32, 0xe3, 0x41, 0x27, + 0x11, 0x02, 0x2e, 0x07, 0x09, 0xe3, 0x22, 0x4d, 0xf1, 0x05, 0x27, 0x03, + 0x25, 0xf5, 0x2c, 0x3b, 0xf4, 0x00, 0x16, 0x0b, 0xec, 0xfe, 0x17, 0x0d, + 0xff, 0xe7, 0xfe, 0x24, 0x06, 0xee, 0xf0, 0xe9, 0xfa, 0x1c, 0xf2, 0x19, + 0x08, 0xfa, 0xff, 0xd2, 0x01, 0x02, 0xea, 0x05, 0xf2, 0xf4, 0x0b, 0xd2, + 0xf9, 0x0d, 0xcd, 0x0d, 0x12, 0xf2, 0x0e, 0xe1, 0x1f, 0x00, 0xe7, 0x14, + 0x04, 0xff, 0x09, 0xdb, 0xfc, 0xd9, 0x06, 0xf9, 0xeb, 0x01, 0xef, 0xfa, + 0xfb, 0xf5, 0xfc, 0xfb, 0x14, 0xe2, 0xf9, 0xf5, 0x02, 0xfd, 0xfc, 0x01, + 0xf7, 0xf3, 0x00, 0xec, 0xe7, 0xf2, 0x00, 0xf1, 0x11, 0xec, 0xf0, 0xe9, + 0x11, 0x0a, 0x07, 0x04, 0x01, 0xee, 0xfb, 0xf2, 0x14, 0x01, 0x12, 0xf0, + 0xf2, 0xf1, 0xf0, 0xfb, 0x08, 0x03, 0xf8, 0x01, 0xe8, 0xf9, 0x17, 0x26, + 0x0f, 0xea, 0xf7, 0xf8, 0x1e, 0xfe, 0xf2, 0xf8, 0x3f, 0x00, 0xd4, 0x1c, + 0x53, 0xfe, 0x1e, 0x0f, 0xef, 0xdd, 0xed, 0x10, 0x19, 0xe7, 0x34, 0x0e, + 0xde, 0xdf, 0xfa, 0x0e, 0x29, 0xe3, 0x16, 0x09, 0x06, 0x12, 0xeb, 0xf9, + 0x32, 0xe0, 0x1a, 0x1d, 0xf3, 0xed, 0x10, 0x07, 0x31, 0xf2, 0x12, 0x52, + 0xeb, 0xf7, 0x1e, 0xf7, 0x1a, 0xdc, 0x3e, 0x33, 0xe3, 0xfb, 0x1f, 0x0b, + 0x08, 0xfe, 0x13, 0x1a, 0xf4, 0xf8, 0xfe, 0x08, 0xfc, 0xe9, 0xfe, 0xeb, + 0xe6, 0xf6, 0x02, 0x18, 0x02, 0xe8, 0xfb, 0xf3, 0x01, 0x08, 0xd7, 0x13, + 0x04, 0xe6, 0x02, 0xe6, 0xd7, 0x01, 0xd4, 0xf0, 0x0e, 0x05, 0x18, 0xe5, + 0x08, 0xe5, 0xd2, 0x16, 0x12, 0xfe, 0x0e, 0xd3, 0xfc, 0x1f, 0xe9, 0xf8, + 0x11, 0x06, 0xf3, 0xd5, 0xf8, 0xff, 0xf0, 0x04, 0x0a, 0xd9, 0xf8, 0xfd, + 0xf5, 0x12, 0xff, 0x06, 0x1b, 0xe6, 0xfe, 0xfe, 0xde, 0xee, 0xf6, 0x18, + 0xf1, 0xf8, 0x06, 0xf3, 0x02, 0xea, 0x04, 0x14, 0xfc, 0xee, 0xe6, 0x09, + 0xf9, 0xee, 0xe3, 0xe7, 0xfc, 0xd9, 0xef, 0xfc, 0x0a, 0x0c, 0x03, 0xf6, + 0xe2, 0x11, 0x0f, 0x19, 0x18, 0x10, 0xef, 0xe5, 0x22, 0xf5, 0xe5, 0xe9, + 0x4b, 0xf7, 0xdb, 0x0c, 0x4f, 0xde, 0x22, 0x16, 0x09, 0x16, 0xd1, 0xf8, + 0x19, 0xe0, 0x24, 0xfe, 0xb8, 0xfb, 0xe5, 0x12, 0x1c, 0xe3, 0x22, 0x09, + 0x05, 0x29, 0xf7, 0x10, 0x31, 0xe1, 0x33, 0x3f, 0xfd, 0xed, 0x04, 0x03, + 0x2e, 0xed, 0x30, 0x36, 0xee, 0x16, 0x2f, 0xf5, 0x1b, 0xdc, 0x3a, 0x56, + 0xe5, 0xef, 0x26, 0xff, 0x03, 0xd7, 0x31, 0x16, 0xef, 0xf1, 0x08, 0x13, + 0x01, 0x02, 0x03, 0xf1, 0xf2, 0x08, 0xff, 0x05, 0x12, 0xf2, 0xee, 0xda, + 0xed, 0xec, 0xea, 0xf7, 0x0c, 0xf1, 0x09, 0xe6, 0xe6, 0x00, 0xcc, 0x10, + 0x0d, 0x0d, 0x20, 0xf4, 0x18, 0x23, 0xec, 0xf9, 0x00, 0xe4, 0x07, 0xd4, + 0xfb, 0x16, 0xd2, 0x01, 0xe6, 0x01, 0x06, 0xf0, 0xfe, 0x03, 0xf3, 0x09, + 0x01, 0x0d, 0x05, 0xf7, 0xd4, 0x02, 0xfb, 0xfb, 0x08, 0xf0, 0x1f, 0xf3, + 0xfe, 0xeb, 0x02, 0x0e, 0x1b, 0x0f, 0x04, 0xf5, 0xf0, 0x1f, 0x14, 0xf7, + 0x06, 0xdc, 0xf9, 0xe9, 0x01, 0xff, 0x08, 0xf2, 0x06, 0xff, 0xff, 0xf3, + 0x05, 0x1a, 0xfc, 0xfa, 0xeb, 0xfb, 0xfa, 0x12, 0x20, 0xf6, 0xe0, 0xe8, + 0x1c, 0xfa, 0xd6, 0x0d, 0x2c, 0x04, 0xe1, 0x09, 0x3b, 0xd3, 0x2a, 0xee, + 0xf7, 0xed, 0xf1, 0xf7, 0x0d, 0xf0, 0x32, 0x0f, 0xc9, 0x0e, 0x00, 0x10, + 0x24, 0xfb, 0x31, 0xf0, 0xf4, 0xdd, 0xf5, 0x04, 0x25, 0xc7, 0x27, 0x25, + 0x16, 0x11, 0x2e, 0x09, 0x30, 0xd1, 0x2c, 0x34, 0xe6, 0xf0, 0x21, 0xf5, + 0x21, 0xc8, 0x40, 0x39, 0xde, 0xf0, 0x12, 0xf3, 0x10, 0xe8, 0x1f, 0x18, + 0xfa, 0xea, 0x07, 0x11, 0xdf, 0xed, 0xfa, 0xf0, 0x07, 0xef, 0xf3, 0x05, + 0x10, 0xe5, 0xf3, 0xe9, 0xe9, 0xe8, 0xd6, 0x01, 0xf9, 0x05, 0x0b, 0xee, + 0xf9, 0x12, 0xe3, 0x05, 0xfd, 0xe6, 0x16, 0xe2, 0x1b, 0x12, 0xc5, 0x00, + 0xfd, 0x02, 0x04, 0xd2, 0xff, 0xec, 0xf6, 0xfd, 0x00, 0xe4, 0xf7, 0xf3, + 0xeb, 0xfa, 0xf8, 0x0d, 0x03, 0xfa, 0xfe, 0xe4, 0xdb, 0xe3, 0x06, 0xff, + 0xf4, 0xf2, 0x1b, 0xf1, 0xf7, 0x02, 0x01, 0x04, 0x13, 0xe5, 0x0c, 0x05, + 0xf7, 0x0a, 0x03, 0x03, 0x0b, 0x03, 0xee, 0xf7, 0x21, 0x20, 0xff, 0xf3, + 0x09, 0xe5, 0xff, 0xec, 0x17, 0x00, 0x06, 0x14, 0xeb, 0xf2, 0x18, 0x16, + 0x1f, 0xec, 0xee, 0xe1, 0x1e, 0x03, 0xfa, 0xfe, 0x28, 0x03, 0xc9, 0x0c, + 0x3f, 0xd8, 0x30, 0x16, 0x03, 0xf8, 0xe9, 0xfb, 0x28, 0xe1, 0x36, 0x0a, + 0xdf, 0xe5, 0xeb, 0x08, 0x1c, 0xcd, 0x29, 0xf2, 0xfc, 0x0a, 0xed, 0x01, + 0x29, 0xf1, 0x20, 0x13, 0x04, 0xec, 0x17, 0x0a, 0x35, 0xc3, 0x1a, 0x46, + 0xe0, 0xd7, 0x3c, 0x09, 0x28, 0xd1, 0x22, 0x20, 0xd5, 0xfa, 0x28, 0xfa, + 0xff, 0xea, 0x1d, 0x23, 0xe0, 0x07, 0x07, 0x0f, 0xf1, 0xf1, 0x08, 0xf0, + 0xf8, 0xff, 0x05, 0x1b, 0x05, 0xfa, 0xf0, 0xfb, 0xe3, 0xe4, 0xcc, 0x1a, + 0xf9, 0x09, 0x06, 0xee, 0xf4, 0x03, 0xd0, 0x14, 0xf4, 0xff, 0x1d, 0xe8, + 0x11, 0xf4, 0xd1, 0xf4, 0x04, 0x0b, 0xfb, 0xdc, 0x0a, 0x0c, 0xeb, 0xed, + 0x06, 0xf3, 0x04, 0xdd, 0xdf, 0xf9, 0xea, 0xfc, 0xf5, 0xf2, 0xfb, 0xea, + 0xe3, 0x03, 0xee, 0x0e, 0xff, 0xdb, 0x1e, 0x04, 0xf7, 0x1a, 0x04, 0x0c, + 0x0d, 0xda, 0x04, 0xe9, 0xff, 0x04, 0x00, 0x0c, 0xf9, 0xe4, 0xfb, 0xf6, + 0x14, 0xde, 0x1b, 0x00, 0x0b, 0xfe, 0x06, 0xf8, 0x0f, 0xdc, 0x01, 0xef, + 0xef, 0x0d, 0xf8, 0xf1, 0x0f, 0xf9, 0xf9, 0xdf, 0x0d, 0xe4, 0xd9, 0xf9, + 0x2b, 0xee, 0xe8, 0x09, 0x40, 0xf9, 0x2f, 0x0a, 0xfa, 0xe8, 0xe9, 0x01, + 0x0e, 0xe7, 0x23, 0x0a, 0xd0, 0x19, 0xd3, 0x0e, 0x04, 0xda, 0x2b, 0x0f, + 0xe7, 0xe6, 0xf3, 0xfb, 0x2c, 0xd3, 0x36, 0x19, 0x0e, 0xfe, 0x03, 0x1a, + 0x2e, 0xd0, 0x23, 0x32, 0xf1, 0xe1, 0x2a, 0x09, 0x1b, 0xf6, 0x29, 0x3e, + 0xce, 0x15, 0x0a, 0xe8, 0xec, 0xdf, 0x44, 0x28, 0xd9, 0xfd, 0xfa, 0x09, + 0xff, 0xe7, 0x08, 0xec, 0xf4, 0xef, 0x01, 0x19, 0x11, 0xf3, 0xeb, 0xeb, + 0xed, 0x1a, 0xdd, 0x15, 0x0f, 0x07, 0xfe, 0xeb, 0xff, 0xd6, 0xd5, 0x04, + 0xf5, 0x07, 0x10, 0xe6, 0x0c, 0xe4, 0xda, 0x0c, 0x08, 0xee, 0x06, 0xd8, + 0xf8, 0xf1, 0xe0, 0x01, 0x08, 0xfe, 0xf9, 0xf3, 0xdf, 0x03, 0xe6, 0xf4, + 0x0a, 0xff, 0xf2, 0xe0, 0xd9, 0xeb, 0x01, 0x10, 0x02, 0xfc, 0x0d, 0x14, + 0xea, 0xf8, 0x03, 0x18, 0xf3, 0x09, 0xfc, 0x0c, 0x0b, 0x1f, 0xf5, 0x05, + 0xf7, 0xf9, 0x00, 0xfd, 0x04, 0xfc, 0x16, 0x07, 0x00, 0xdf, 0xf9, 0xfa, + 0x0c, 0xfb, 0xf4, 0xf7, 0xf0, 0xeb, 0x07, 0x17, 0x20, 0xfb, 0xf0, 0xec, + 0x04, 0x00, 0xf8, 0xf2, 0x2d, 0xf9, 0xd9, 0x0b, 0x55, 0xec, 0x33, 0x26, + 0xf8, 0x0a, 0xf2, 0x0b, 0x25, 0xdf, 0x29, 0x05, 0xd1, 0x14, 0xe2, 0xf2, + 0x12, 0xdd, 0x28, 0xfc, 0xec, 0x08, 0xfd, 0x02, 0x3a, 0xe6, 0x29, 0x25, + 0x0d, 0x10, 0x09, 0x0a, 0x32, 0xf5, 0x17, 0x2d, 0xea, 0xfb, 0x35, 0xfc, + 0x28, 0xd0, 0x29, 0x2f, 0xcb, 0x06, 0x0f, 0x04, 0xf2, 0xf3, 0x34, 0x1c, + 0xf4, 0x08, 0x05, 0xfc, 0xfd, 0xed, 0x0f, 0xf8, 0xe9, 0xf0, 0x09, 0x16, + 0xfe, 0x02, 0xff, 0xd4, 0xea, 0x0a, 0xeb, 0x0c, 0xf8, 0xf4, 0x09, 0xf4, + 0xf2, 0x07, 0xd9, 0x0b, 0xfd, 0xe4, 0x1a, 0xef, 0x14, 0x08, 0xd8, 0xfc, + 0xf5, 0xe1, 0x03, 0xcf, 0xf1, 0x11, 0xdb, 0x15, 0x07, 0x10, 0xf8, 0xfc, + 0xe2, 0xf1, 0xf5, 0xde, 0xff, 0xe7, 0x01, 0xea, 0xee, 0xe9, 0x02, 0x0a, + 0x18, 0xec, 0xfe, 0xf9, 0x09, 0xf3, 0x0e, 0x02, 0xf1, 0xfc, 0xf9, 0x16, + 0x05, 0x07, 0x09, 0x0d, 0x0e, 0xf7, 0x04, 0xed, 0x04, 0xdb, 0x04, 0x04, + 0xf6, 0xdc, 0xee, 0xec, 0xf5, 0xfe, 0xf4, 0x02, 0xe4, 0x0b, 0xe0, 0x17, + 0x0a, 0xe0, 0xf7, 0xdc, 0x11, 0xd6, 0xfe, 0xfa, 0x35, 0xde, 0xe6, 0x06, + 0x44, 0xf9, 0x35, 0x0a, 0xfb, 0xff, 0xec, 0xfb, 0x16, 0xd9, 0x23, 0x0f, + 0xd4, 0xef, 0xdf, 0x06, 0x0b, 0xd9, 0x25, 0xff, 0xf8, 0xeb, 0xf4, 0x0a, + 0x20, 0xe5, 0x22, 0x1c, 0xeb, 0xf4, 0x0d, 0x0c, 0x19, 0xe1, 0x1e, 0x31, + 0xe9, 0xfb, 0x20, 0xf0, 0x23, 0xfe, 0x35, 0x28, 0xb4, 0x06, 0x28, 0xe7, + 0xfb, 0xe9, 0x2a, 0x1a, 0xef, 0x15, 0x0c, 0xed, 0xf1, 0x04, 0x0e, 0x0a, + 0xff, 0x16, 0x01, 0x04, 0x17, 0xea, 0xec, 0xdc, 0xf4, 0xf7, 0x04, 0x16, + 0x1f, 0x0a, 0x11, 0xef, 0x12, 0xdf, 0xd9, 0x0c, 0xf5, 0x10, 0x02, 0xf3, + 0x10, 0x03, 0xd3, 0xf5, 0x0b, 0x02, 0x00, 0xcb, 0xf6, 0x23, 0xf6, 0xf1, + 0x1f, 0xf9, 0xfc, 0xf0, 0xf6, 0xfe, 0xfa, 0xf8, 0xf9, 0xf4, 0xfb, 0x0a, + 0xd6, 0x29, 0x09, 0x02, 0x00, 0xfc, 0xfc, 0xee, 0xf5, 0x05, 0xfb, 0x1e, + 0xf1, 0xf1, 0xf3, 0x02, 0xec, 0x1c, 0x0c, 0x0e, 0x0b, 0x04, 0xf6, 0xe7, + 0x14, 0x08, 0x27, 0x01, 0xfe, 0xe5, 0xe7, 0x01, 0x1b, 0xf0, 0xf6, 0xff, + 0xf4, 0xe7, 0xee, 0x18, 0x0d, 0x08, 0xf8, 0xd6, 0x07, 0xf4, 0x08, 0xff, + 0x1d, 0x13, 0xe7, 0x0b, 0x42, 0xef, 0x28, 0x00, 0xf9, 0xf0, 0xf3, 0x00, + 0x15, 0xfd, 0x1a, 0x22, 0xc1, 0xf5, 0xe0, 0xf8, 0x09, 0xe6, 0x0e, 0x05, + 0xf9, 0xf6, 0x01, 0x01, 0x13, 0xdc, 0x1f, 0x0d, 0xfb, 0x04, 0x08, 0x0b, + 0x15, 0xdb, 0x28, 0x34, 0xed, 0x0b, 0x3a, 0xed, 0x16, 0xe3, 0x39, 0x32, + 0xc4, 0x0b, 0x20, 0xe7, 0xf7, 0x02, 0x35, 0x24, 0xfc, 0xe8, 0x1c, 0xf8, + 0xf1, 0xfa, 0x0c, 0x1d, 0xf2, 0x05, 0xff, 0x12, 0x0f, 0x01, 0xec, 0xea, + 0xf0, 0x03, 0xe7, 0x15, 0xfd, 0x05, 0x08, 0xe0, 0x1b, 0xf8, 0xe1, 0x1e, + 0xed, 0xdc, 0x11, 0xeb, 0xfd, 0x1a, 0xeb, 0x09, 0xf9, 0xf3, 0x00, 0xe8, + 0xe6, 0x08, 0xf7, 0xde, 0x1e, 0x00, 0x00, 0x00, 0xe4, 0x09, 0xf2, 0xf8, + 0xe7, 0xf2, 0x0d, 0xfa, 0xe2, 0x0f, 0x04, 0x08, 0xf2, 0x13, 0xf8, 0xf9, + 0xf1, 0xff, 0x03, 0x11, 0x12, 0xe9, 0xf4, 0x13, 0x07, 0x0c, 0x13, 0x2b, + 0xf7, 0xdd, 0xf9, 0xe9, 0xfa, 0xdb, 0x1d, 0xf6, 0xf6, 0xf9, 0xe4, 0xf6, + 0x0d, 0xeb, 0x0d, 0x08, 0xe7, 0xe7, 0xf2, 0x03, 0x1d, 0xd9, 0xd8, 0xe4, + 0xf7, 0xea, 0xdc, 0xdc, 0x26, 0x02, 0xee, 0xfa, 0x38, 0xfc, 0x1a, 0xef, + 0xda, 0xf1, 0xdf, 0x0b, 0x1a, 0xe0, 0x16, 0x16, 0xdc, 0x04, 0xfa, 0xf7, + 0xee, 0x02, 0x25, 0x02, 0xf5, 0xfb, 0x08, 0xf6, 0x11, 0xf5, 0x12, 0x08, + 0xf4, 0xe3, 0x1b, 0xf5, 0x3a, 0xdc, 0x20, 0x2e, 0xe0, 0xf5, 0x30, 0xe4, + 0x09, 0xf8, 0x3c, 0x45, 0xd3, 0x08, 0x23, 0xd8, 0x09, 0xe4, 0x35, 0x30, + 0xe4, 0xfe, 0x07, 0xf6, 0x05, 0x01, 0x05, 0xff, 0xf6, 0x0d, 0x02, 0xfd, + 0x03, 0x05, 0x0d, 0x00, 0xf5, 0xd6, 0xcf, 0x19, 0x06, 0xee, 0x0d, 0xf2, + 0x01, 0x18, 0xef, 0x12, 0x04, 0x02, 0x21, 0xd9, 0x02, 0x0d, 0xeb, 0xe9, + 0x13, 0x08, 0x15, 0xf0, 0xee, 0x03, 0xec, 0x06, 0x17, 0xed, 0x00, 0x1a, + 0xee, 0xf2, 0xfc, 0x09, 0xec, 0xf8, 0xf8, 0x18, 0xf4, 0x13, 0x04, 0xf6, + 0x02, 0xf0, 0xfc, 0xfe, 0xe3, 0x01, 0x0a, 0x1c, 0x1b, 0xec, 0x0e, 0x01, + 0xfb, 0x08, 0x11, 0xf5, 0x00, 0x14, 0xe6, 0x12, 0x07, 0xf4, 0x15, 0x07, + 0xfc, 0xfb, 0xf5, 0xf1, 0x01, 0x21, 0x01, 0xe9, 0xe8, 0xef, 0xdb, 0xdf, + 0x1f, 0x0a, 0xdd, 0xd1, 0x16, 0x04, 0xfd, 0xe1, 0x24, 0xf0, 0xec, 0xf4, + 0x38, 0xe1, 0x16, 0xfd, 0xe0, 0xec, 0xe7, 0x0c, 0x2a, 0x04, 0x0c, 0x17, + 0xdc, 0xe8, 0xf2, 0x03, 0xec, 0xfd, 0x19, 0xfe, 0xf3, 0xf0, 0xf3, 0xfb, + 0x18, 0xdf, 0x1c, 0x00, 0x09, 0xf4, 0x18, 0x0b, 0x1f, 0xf6, 0x34, 0x22, + 0xf4, 0x22, 0x45, 0xeb, 0x23, 0xcf, 0x32, 0x34, 0xf2, 0xf9, 0x29, 0xd4, + 0xf7, 0x0b, 0x38, 0x2a, 0x09, 0xe6, 0x05, 0x01, 0x0b, 0xfe, 0x17, 0xfb, + 0x00, 0xeb, 0x08, 0xfd, 0x0c, 0x02, 0x1d, 0xea, 0xfa, 0x0b, 0xeb, 0x09, + 0xfe, 0xfe, 0x10, 0xe0, 0xf6, 0x06, 0xf0, 0x15, 0xf3, 0x09, 0x11, 0xe4, + 0xf9, 0x07, 0xe1, 0xed, 0x17, 0x05, 0x0c, 0xe1, 0xdb, 0xf2, 0xf8, 0xea, + 0x22, 0xe9, 0x02, 0x00, 0xfd, 0xe7, 0xf2, 0xf8, 0xf9, 0xfc, 0xfa, 0xe8, + 0xe8, 0xeb, 0xe9, 0x0d, 0x04, 0xf8, 0xf8, 0xf7, 0xf8, 0x0d, 0x03, 0x0c, + 0x13, 0xf2, 0x0f, 0xf9, 0xe6, 0xfd, 0x0f, 0x19, 0x08, 0xf7, 0xfa, 0x01, + 0xf3, 0x12, 0x1e, 0x05, 0x0a, 0x09, 0xfd, 0x0b, 0x07, 0x08, 0x02, 0xfc, + 0xd6, 0xe8, 0x14, 0x01, 0x13, 0x19, 0xef, 0xda, 0x0e, 0x0a, 0x07, 0xef, + 0x34, 0xe0, 0x05, 0x1e, 0x4e, 0xe9, 0x19, 0xff, 0xe1, 0x04, 0xfb, 0x0e, + 0x11, 0x05, 0x1f, 0x15, 0xd4, 0xec, 0xf9, 0xe7, 0xf9, 0xfc, 0x25, 0xff, + 0x06, 0xf2, 0x01, 0xf6, 0x2a, 0x17, 0x24, 0x11, 0xf3, 0x1a, 0x1f, 0xfb, + 0x32, 0xeb, 0x33, 0x2f, 0x00, 0x08, 0x2c, 0xf0, 0x26, 0xf4, 0x25, 0x36, + 0xd9, 0xf1, 0x1a, 0xd5, 0xec, 0xf9, 0x32, 0x27, 0xfc, 0xf4, 0xf0, 0xe3, + 0xfa, 0x0c, 0x16, 0x17, 0xfa, 0xf9, 0xe5, 0x1f, 0x1f, 0xfa, 0xff, 0xfd, + 0x0d, 0x02, 0xe9, 0x0e, 0xf0, 0x12, 0x09, 0xda, 0x02, 0xea, 0xe5, 0x0a, + 0xff, 0x03, 0x13, 0xf0, 0x0a, 0xf9, 0xe9, 0xff, 0x10, 0xfc, 0x1a, 0xf3, + 0xf7, 0x0f, 0xf4, 0xfa, 0xf4, 0x05, 0x10, 0x0a, 0xdd, 0x09, 0xf7, 0xf0, + 0xe5, 0x07, 0x07, 0xfa, 0x02, 0xd7, 0xf8, 0xf7, 0x01, 0xfb, 0x0e, 0xf8, + 0x07, 0x0f, 0xfe, 0x03, 0x12, 0x05, 0x09, 0x13, 0xf8, 0xdc, 0xfd, 0x27, + 0x0f, 0xec, 0xf7, 0x07, 0x00, 0xfc, 0x12, 0xf8, 0xfb, 0xea, 0xe4, 0xe9, + 0xe9, 0xe0, 0xff, 0xdc, 0xd6, 0xeb, 0xf2, 0xf7, 0x0d, 0x1b, 0xe9, 0xc4, + 0x06, 0x00, 0xfd, 0x04, 0x46, 0xf9, 0xe9, 0x13, 0x2d, 0x0c, 0x1f, 0xf8, + 0xd3, 0x0c, 0x14, 0x11, 0x05, 0xe5, 0x27, 0x08, 0xc5, 0xef, 0xdf, 0xdd, + 0x04, 0xf8, 0x11, 0x10, 0xf0, 0xe7, 0xfb, 0x03, 0x3c, 0xe7, 0x14, 0x0c, + 0xf4, 0xf6, 0x1b, 0x0a, 0x23, 0xf2, 0x2d, 0x1a, 0x08, 0xff, 0x32, 0xe7, + 0x1a, 0x05, 0x2b, 0x34, 0xf1, 0x0a, 0x00, 0xe8, 0x02, 0xdf, 0x2c, 0x2a, + 0x03, 0xe6, 0xfc, 0xef, 0xfc, 0xe4, 0x03, 0x01, 0x03, 0xee, 0xe9, 0x15, + 0x05, 0x03, 0x13, 0x11, 0x0e, 0xee, 0xf5, 0x22, 0x1b, 0x0e, 0xfd, 0xf3, + 0x0a, 0x02, 0xdd, 0x20, 0xeb, 0x06, 0xf8, 0xe2, 0x06, 0x0e, 0xde, 0x0d, + 0xf9, 0x16, 0x1c, 0x0c, 0xe0, 0xf0, 0xec, 0x0c, 0x0f, 0xf2, 0x27, 0x1d, + 0xde, 0xe6, 0xf0, 0xf9, 0xf0, 0x02, 0x0a, 0x07, 0x06, 0xf9, 0x0f, 0xfa, + 0xf0, 0xee, 0xf1, 0xf7, 0xff, 0x02, 0x0b, 0x0d, 0x1b, 0xee, 0xf6, 0x05, + 0xff, 0x1c, 0x17, 0x04, 0x05, 0x17, 0x00, 0xff, 0x0d, 0xf3, 0x23, 0x10, + 0xfd, 0x05, 0xfb, 0xea, 0x03, 0x10, 0x07, 0xd7, 0xf7, 0xff, 0xf3, 0xf1, + 0x17, 0xed, 0xd3, 0xcb, 0x14, 0x1c, 0xf5, 0x03, 0x47, 0xf6, 0xf7, 0xf2, + 0x3e, 0xf2, 0x22, 0xf4, 0xed, 0xfc, 0xee, 0x0b, 0xf4, 0xf1, 0x25, 0x10, + 0xd0, 0xf6, 0x00, 0xef, 0x10, 0xfc, 0x15, 0xe5, 0xdb, 0xf3, 0xea, 0x10, + 0x22, 0xf2, 0x2b, 0x11, 0xf9, 0x0a, 0xfc, 0xf5, 0x53, 0x16, 0x25, 0x43, + 0xe0, 0x0e, 0x13, 0xfc, 0x2d, 0xe2, 0x55, 0x65, 0xf4, 0x08, 0x01, 0xdf, + 0x0a, 0x00, 0x49, 0x1c, 0xfe, 0xdf, 0xef, 0xf2, 0xf9, 0xf6, 0xfd, 0xff, + 0xf3, 0x02, 0xf6, 0x14, 0x0b, 0xe8, 0x09, 0xfc, 0xfc, 0xe2, 0xe5, 0x11, + 0x03, 0x09, 0xfb, 0x06, 0x10, 0x1a, 0xf3, 0x0d, 0xfa, 0x0a, 0xd5, 0xf5, + 0x1a, 0x11, 0xf2, 0xfc, 0x1f, 0xfe, 0x0e, 0xe4, 0xef, 0xd7, 0xee, 0x06, + 0x1e, 0x04, 0x12, 0x28, 0xf7, 0x0e, 0x06, 0xf8, 0xee, 0xf0, 0x1a, 0x01, + 0xf7, 0xfd, 0x03, 0x11, 0x19, 0x10, 0x04, 0xfb, 0xd7, 0xfa, 0x16, 0x06, + 0x07, 0x23, 0xfa, 0x14, 0x11, 0xf1, 0x12, 0x10, 0x04, 0xe1, 0xee, 0xf7, + 0x21, 0x0e, 0x0a, 0x0a, 0xf8, 0x07, 0x0a, 0xee, 0x03, 0x1f, 0xfa, 0xc4, + 0xec, 0x12, 0x01, 0x1e, 0xfd, 0xf1, 0xe8, 0xcc, 0xf4, 0x17, 0xff, 0xdd, + 0x45, 0x10, 0xee, 0xfa, 0x3d, 0xe7, 0x27, 0xdd, 0xd7, 0xf9, 0xf4, 0xf6, + 0x06, 0xf8, 0x1e, 0x13, 0xe7, 0xe2, 0xf1, 0xe3, 0xf3, 0xf7, 0x18, 0x12, + 0xe4, 0x0a, 0xdb, 0xff, 0xff, 0xfe, 0x20, 0x09, 0x00, 0xf7, 0x23, 0xf6, + 0x2d, 0x14, 0x26, 0x28, 0xe5, 0xff, 0x0f, 0xe3, 0x1d, 0xe8, 0x56, 0x43, + 0xe7, 0xfb, 0xf9, 0xe6, 0xe9, 0xe2, 0x19, 0x19, 0x08, 0xfa, 0xf3, 0xe5, + 0x23, 0x07, 0x0f, 0xf8, 0xf8, 0xf3, 0xfc, 0x11, 0x2a, 0x05, 0xf4, 0xf1, + 0xfa, 0xfb, 0xf1, 0x1e, 0x13, 0x0f, 0xf9, 0xf5, 0xfa, 0x09, 0xf9, 0x03, + 0xf0, 0xf0, 0xe7, 0xec, 0xf1, 0x0c, 0xe6, 0xee, 0xf6, 0x20, 0x0f, 0xe9, + 0x00, 0xf4, 0xfe, 0xf0, 0x13, 0x0a, 0x17, 0x13, 0xee, 0x13, 0xfb, 0xff, + 0xf8, 0xfd, 0xf4, 0xe2, 0xe8, 0x06, 0xfc, 0x14, 0x03, 0x17, 0x00, 0x03, + 0xe6, 0xfd, 0xf2, 0x12, 0x12, 0x20, 0xeb, 0x10, 0x02, 0xf7, 0x13, 0x0d, + 0x11, 0xfd, 0xde, 0xf5, 0x07, 0xf3, 0x04, 0xff, 0x06, 0x05, 0xfb, 0xea, + 0xf0, 0x0a, 0x00, 0xb5, 0xe8, 0x1a, 0x03, 0xfe, 0x0d, 0x1a, 0xe7, 0xc0, + 0xd6, 0xdc, 0xf6, 0xf8, 0x39, 0xf5, 0xd5, 0xf8, 0x22, 0xfa, 0x22, 0x05, + 0xd0, 0xf4, 0x2d, 0xfc, 0x00, 0x0a, 0x1b, 0xfc, 0xe6, 0x09, 0x14, 0xfa, + 0x00, 0x1d, 0x1a, 0xfd, 0xf3, 0x18, 0xfc, 0xeb, 0x15, 0xf5, 0x0e, 0x0a, + 0xf3, 0xf1, 0x1b, 0x05, 0x14, 0x03, 0x2d, 0x27, 0xfb, 0x18, 0x22, 0xef, + 0xf6, 0x06, 0x28, 0x2b, 0xde, 0xec, 0xef, 0xe8, 0xd3, 0xfe, 0x17, 0x12, + 0x01, 0x13, 0x05, 0xf7, 0x00, 0xde, 0xf3, 0xe5, 0x03, 0xfb, 0x07, 0x0b, + 0xfd, 0xdc, 0xdf, 0x03, 0x0c, 0x00, 0xfa, 0x06, 0x0e, 0x02, 0x05, 0xfa, + 0xfd, 0xed, 0x09, 0x0c, 0xfd, 0xfb, 0x0c, 0xf0, 0xe4, 0x04, 0xd6, 0xf3, + 0x09, 0x0a, 0xf9, 0xf8, 0xe2, 0xef, 0xdf, 0xf0, 0xf8, 0x03, 0x0f, 0x20, + 0xf4, 0xe3, 0xf8, 0x02, 0xe2, 0xe5, 0x25, 0x0f, 0xeb, 0xf8, 0xe9, 0xfd, + 0x04, 0x0c, 0x0c, 0xfe, 0x01, 0x08, 0xfc, 0xfc, 0x1b, 0x01, 0xe5, 0x13, + 0xf9, 0xe8, 0x07, 0x20, 0xfe, 0x06, 0xec, 0xfe, 0x09, 0xef, 0x14, 0x04, + 0x0b, 0xf5, 0xe7, 0xff, 0x0a, 0x02, 0x09, 0xe9, 0xc4, 0x16, 0x0d, 0xe7, + 0x15, 0x14, 0xf1, 0xd0, 0xec, 0xe7, 0xf0, 0xf0, 0x33, 0x05, 0xda, 0xf2, + 0x0b, 0x08, 0x38, 0x01, 0x07, 0xfd, 0xd8, 0x06, 0xd9, 0xf0, 0x16, 0x1f, + 0xff, 0xf7, 0xe0, 0xd8, 0xf3, 0xf7, 0x12, 0x08, 0x0e, 0x05, 0xf6, 0x03, + 0xef, 0x1b, 0x12, 0xf4, 0xe8, 0x0f, 0x02, 0xfd, 0xf2, 0x16, 0x26, 0x22, + 0xe0, 0x07, 0xf7, 0xe6, 0xeb, 0x16, 0x22, 0x1a, 0x0b, 0x01, 0xf5, 0xea, + 0xd2, 0x22, 0x0f, 0x13, 0x15, 0x08, 0xf0, 0xfb, 0xed, 0x11, 0xf3, 0xe9, + 0xff, 0xde, 0x0a, 0x18, 0x0f, 0x02, 0xfb, 0xf9, 0xfb, 0xe8, 0x12, 0x18, + 0x01, 0xf4, 0xf6, 0xf8, 0xf0, 0x1f, 0x24, 0x15, 0xf5, 0x00, 0x1c, 0xf9, + 0x01, 0x0a, 0x11, 0xd5, 0x01, 0x12, 0x02, 0xec, 0xfd, 0x07, 0xf2, 0xea, + 0xf9, 0xff, 0xf7, 0xfb, 0x15, 0xec, 0xe5, 0x01, 0xeb, 0x05, 0xf9, 0x10, + 0xfe, 0x28, 0xe5, 0x0a, 0xeb, 0x1b, 0x0e, 0xf9, 0xde, 0x02, 0x15, 0x0a, + 0xff, 0xfe, 0x11, 0x24, 0x03, 0xf8, 0x00, 0x08, 0xfd, 0x0e, 0xeb, 0xf3, + 0xf6, 0xf7, 0x14, 0x0e, 0xfc, 0xf5, 0xde, 0xf5, 0x9e, 0xfe, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xab, 0x01, 0x00, 0x00, + 0xfa, 0xfd, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xba, 0x00, 0x00, 0x00, + 0x24, 0xfc, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x54, 0x4f, 0x43, 0x4f, + 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0xfb, 0xff, 0xff, + 0x68, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xce, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x03, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1a, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x07, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xc4, 0xfc, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x10, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x1a, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x34, 0x04, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, + 0x4c, 0x03, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, + 0x20, 0x02, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0xfc, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x44, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf4, 0xfb, 0xff, 0xff, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x5f, 0x73, 0x6f, 0x66, 0x74, 0x6d, 0x61, 0x78, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, + 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x11, 0x1e, 0x23, 0x3a, 0x9e, 0xa1, 0x15, 0x39, + 0x23, 0x69, 0x45, 0x3a, 0x09, 0xe4, 0xe4, 0x39, 0x65, 0xd7, 0x13, 0x3a, + 0xe0, 0xb2, 0xfd, 0x39, 0x1b, 0xc1, 0x53, 0x3a, 0xc2, 0x50, 0x2d, 0x3a, + 0x12, 0x00, 0x00, 0x00, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3a, 0xfd, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x54, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0xfd, 0xff, 0xff, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb5, 0xfa, 0xfa, 0x39, 0x1f, 0x00, 0x00, 0x00, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x5f, 0x66, 0x63, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x73, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xa0, 0x0f, 0x00, 0x00, 0xa2, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x74, 0xfe, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, 0xdd, 0xbb, 0x3d, + 0x01, 0x00, 0x00, 0x00, 0x32, 0xa3, 0x25, 0x41, 0x01, 0x00, 0x00, 0x00, + 0xf6, 0xa0, 0x50, 0xc1, 0x05, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x5f, + 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0e, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, + 0x2c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, + 0x32, 0x2f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x4a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x5c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x50, 0xd0, 0x3d, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcf, 0x41, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, + 0x61, 0x70, 0x65, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xc2, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x58, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x94, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x50, 0xd0, 0x3d, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xcf, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, + 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xa8, 0x07, 0x00, 0x00, 0x2e, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x60, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x3a, 0x6a, 0xac, 0x3d, 0x01, 0x00, 0x00, 0x00, + 0xd0, 0xbd, 0xab, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x52, 0x65, 0x6c, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x9c, 0xff, 0xff, 0xff, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x96, 0x08, 0x29, 0x38, 0x0b, 0x00, 0x00, 0x00, + 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x18, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x9a, 0xbb, 0x84, 0x38, 0x83, 0x84, 0x73, 0x37, 0x5b, 0xa3, 0xa0, 0x38, + 0x16, 0x41, 0x3a, 0x38, 0xc7, 0x9a, 0x70, 0x38, 0xed, 0x70, 0x4e, 0x38, + 0x54, 0x4f, 0xac, 0x38, 0xfd, 0x07, 0x8d, 0x38, 0x0b, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x19, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0a, 0x00, 0x0e, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x03, 0x00, 0x00, 0x00}; +const int g_model_len = 18712; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.h new file mode 100644 index 0000000..deec2d6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/model.h @@ -0,0 +1,27 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a standard TensorFlow Lite FlatBuffer model file that has been +// converted into a C data array, so it can be easily compiled into a binary +// for devices that don't have a file system. It was created using the command: +// xxd -i model.tflite > model.cc + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ + +extern const unsigned char g_model[]; +extern const int g_model_len; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_MODEL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.cc new file mode 100644 index 0000000..2fa4556 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.cc @@ -0,0 +1,188 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h" + +// Golden test values for the expected spectrogram from a "no" sample file +// speech_commands_test_set_v0.02/no/f9643d42_nohash_4.wav. + +const int g_no_micro_f9643d42_nohash_4_width = 40; +const int g_no_micro_f9643d42_nohash_4_height = 49; +const signed char g_no_micro_f9643d42_nohash_4_data[] = { + 103, 78, 64, 76, 75, 54, 53, 67, 77, 60, 56, 70, + 76, 71, 68, 58, 74, 32, 23, -2, -18, 11, 13, 15, + 9, 20, 5, -7, -18, -2, -10, -18, -10, -12, 9, 7, + -33, -12, -4, -18, 57, 17, 55, 62, 70, 45, 61, 37, + 67, 52, 48, 47, 55, 46, 57, 47, 73, 17, 27, 20, + 19, 8, 15, -6, -1, 10, -12, -29, -6, -23, -18, -3, + -1, 5, 3, -4, -12, -8, -1, -14, 65, 48, 58, 43, + 48, 19, 39, 39, 57, 57, 58, 55, 67, 58, 49, 50, + 70, 27, 9, 16, 37, 4, 25, 4, 11, 9, 7, -33, + -7, -12, 3, -6, -29, -7, -7, -18, -12, -18, -2, -1, + 0, 31, 60, -8, 51, 59, 70, 40, 71, 57, 52, 38, + 66, 48, 17, 6, 59, 8, 15, 7, 18, 4, 18, -23, + -8, -4, -3, -12, -3, -26, 1, 10, 2, -29, -29, -37, + -7, -4, 6, -33, 67, 44, 59, -4, 64, 51, 68, 55, + 74, 9, 40, 15, 57, 33, 60, 18, 40, 25, 27, -20, + 25, -16, 6, 17, -10, -12, -23, -43, -23, -23, -29, -37, + -4, -16, -16, -60, -20, -23, -10, -29, -12, 15, 12, -37, + 27, 15, 61, 44, 50, 8, 48, 22, 49, -18, 46, 33, + 42, 34, 46, -8, 4, -18, -43, -43, -10, 1, -10, -16, + -10, -77, -16, -33, 11, -26, -23, -37, 0, -8, -16, -29, + 42, 40, 68, 24, 47, 46, 53, -128, 30, 2, 42, 21, + 21, -4, 43, 2, 43, 5, 32, -26, 7, -37, -43, -23, + -2, -8, 2, -37, -50, -60, -1, -7, -33, -77, -6, -18, + -16, -50, -12, -33, 53, 8, 52, 18, 51, 35, 69, 26, + 44, 8, 27, -128, 21, -33, 17, -14, 38, -128, -14, -18, + 17, -20, -14, -37, 8, -60, -33, -33, -33, -43, -12, -29, + -12, -128, -33, -60, -26, -77, -26, -50, 57, 29, 11, 30, + 53, -10, 45, 15, 18, -10, 42, 2, 31, -29, 10, -4, + 42, -37, -50, -128, -4, -43, -20, -77, -14, -26, -33, -128, + -12, -43, -8, -33, -33, -60, -43, -77, -12, -60, -26, -50, + 40, -23, 36, 35, 50, -2, 37, 27, 26, -77, 49, -7, + 28, -43, 6, 11, 41, -37, 33, -26, -14, -12, -6, -33, + -16, -26, -20, -77, -14, -43, -8, -50, -14, -37, -26, -77, + -26, -77, -14, -29, 50, -60, 25, -26, 57, 38, 51, 1, + 50, 1, 53, -18, 30, -23, 11, -128, 18, -43, 20, -26, + -10, -26, -12, -128, -50, -60, -37, -77, -20, -43, -50, -128, + -77, -128, -77, -128, -33, -77, -20, -60, 53, -10, -37, -128, + 10, -128, 60, 18, -8, 13, 37, -37, 8, -128, 3, -77, + 32, -29, 14, 10, -12, -77, -37, -77, -37, -60, -23, -128, + -43, -50, -16, -77, -6, -33, 0, -60, -43, -128, -16, -60, + 20, -2, 51, 19, 43, 2, 63, 20, 60, -4, 42, -50, + 4, -128, 2, -3, 32, -33, -26, -128, -18, -128, -33, -43, + -7, -60, -50, -77, -29, -77, -23, -128, -16, -26, -23, -60, + -37, -77, -37, -128, -1, -33, 39, 48, 60, 5, 8, -128, + 44, 11, 4, 0, 13, -77, -2, -20, 33, -128, -33, -77, + -8, -128, -14, -128, -33, -18, -12, -77, -16, -128, -37, -128, + -12, -77, -60, -128, -23, -60, -23, -128, 36, -50, 46, -128, + 66, 39, 18, -14, -12, -77, -20, -6, 24, -128, 28, -26, + 21, -77, -6, -33, 1, -128, -43, -128, -1, -50, -37, -128, + -50, -128, -33, -128, -18, -128, -60, -8, -7, -60, -60, -128, + -6, -29, 20, -1, 73, 40, -43, -14, 33, -43, 33, -3, + 15, -29, 29, -43, 20, -60, -29, -128, -20, -26, 4, -77, + -16, -60, -33, -50, -29, -128, -60, -128, -77, -128, -37, -50, + 0, -77, -33, -128, 39, 8, 47, 10, 62, 16, 2, 1, + 10, 7, 4, -7, 6, -128, -77, -50, 19, -77, -77, -128, + -77, -128, -50, -128, -60, -60, -33, -50, -37, -128, -128, -128, + -60, -128, -37, -60, -18, -128, -33, -77, 37, 23, 29, -128, + -128, -128, -16, -128, -16, -33, 21, -20, -8, -60, -2, -60, + 11, -128, -50, -128, -50, -128, -29, -77, -16, -128, -26, -128, + -50, -77, -43, -128, -128, -128, -50, -128, -33, -128, -33, -50, + -23, -128, 24, -128, -128, -77, 4, -23, 32, -128, 1, -26, + -14, -128, 10, -77, -4, -128, 1, -50, -8, -77, -77, -77, + -23, -128, -50, -43, -33, -128, -43, -128, -128, -128, -43, -128, + -50, -128, -128, -128, 44, 15, 14, -128, 9, -128, 21, 0, + 29, -7, 18, -7, -7, -128, -33, -50, 14, -60, -60, -128, + -60, -128, -37, -128, -43, -128, -20, -128, -50, -128, -43, -77, + -26, -128, -60, -50, -60, -128, -77, -128, -3, -128, 14, -77, + -26, 11, 47, -77, -7, -77, 45, -43, -12, 14, 37, -60, + 22, -4, 5, -77, -14, -128, -10, -60, 22, -77, -12, -60, + -50, -128, -60, -128, -60, -128, -43, -128, -50, -128, -77, -50, + 27, -37, 33, -128, 4, -29, -4, -50, -20, -128, 6, -37, + -33, -128, -50, -128, 34, 15, -43, -128, -20, -50, -3, -37, + -37, -77, -77, -128, -43, -128, -128, -128, 4, -26, -26, 27, + 0, -128, -29, -60, 35, -26, 23, -128, -29, -77, 19, 14, + 28, -128, -16, -7, 31, -1, 17, 11, 60, 44, 8, 11, + 18, -128, -33, -60, -1, -128, -43, -128, -23, -128, -128, -128, + 59, 43, 35, 61, 37, -77, -77, -50, 116, 88, 98, 69, + 78, 53, 78, 40, 48, 7, 29, -18, -2, -14, 5, 12, + 65, 35, 31, -12, 33, -2, -6, -1, 44, -29, -14, -60, + -4, -43, -37, -128, 29, 18, 38, 51, 8, -128, -12, -37, + 115, 91, 113, 77, 89, 36, 60, 44, 49, 36, 27, 31, + 63, 30, 62, 14, 55, 49, 42, 0, 45, 17, -23, 1, + 30, -37, -50, -77, -8, -60, 9, -60, -12, -50, 13, 4, + 23, -6, 28, 13, 107, 78, 101, 73, 89, 46, 63, 17, + 34, -43, -6, 30, 67, 40, 77, 21, 53, 39, 38, 12, + -6, 5, 28, -2, 18, -43, 0, -128, -29, -77, 18, -128, + -2, -77, 39, 35, 38, 35, 50, 29, 100, 70, 94, 69, + 86, 50, 45, 38, 45, 12, 58, 64, 74, 36, 77, 45, + 78, 62, 8, -60, 38, 6, 21, 7, 8, -37, -1, -20, + 48, -37, 8, -10, 8, 13, 45, 39, 38, 22, 49, 25, + 94, 63, 87, 66, 84, -128, 29, 20, 55, 51, 80, 36, + 62, 30, 81, 72, 68, 37, 51, 27, 54, 22, 16, -29, + 4, 9, 57, 15, 35, -43, -77, -20, 4, 6, 37, -1, + 40, 31, 47, 14, 89, 68, 96, 83, 111, 96, 115, 87, + 99, 76, 105, 84, 105, 86, 113, 91, 108, 87, 110, 78, + 80, 46, 22, 74, 88, 72, 103, 86, 80, 68, 48, 24, + 68, 48, 55, 36, 108, 90, 90, 63, 83, 63, 87, 64, + 90, 92, 113, 88, 102, 79, 109, 83, 100, 89, 109, 60, + 56, 21, 75, 62, 81, 45, 63, 73, 93, 65, 94, 80, + 89, 81, 73, 3, 43, 60, 102, 70, 84, 67, 99, 74, + 78, 57, 79, 50, 93, 82, 98, 56, 77, 70, 91, 71, + 85, 82, 86, 13, 45, -18, 48, 40, 53, 28, 85, 60, + 65, 52, 86, 78, 76, 46, 73, 19, 35, 54, 75, 40, + 71, 60, 82, 37, 69, 42, 62, 40, 96, 70, 85, 77, + 70, 68, 103, 84, 94, 69, 81, -128, -128, -128, -43, -37, + 40, 2, 48, 45, 76, 37, 65, 16, 43, 18, 58, 20, + 27, 12, 71, 31, 53, 44, 88, 47, 50, 33, 39, 8, + 89, 57, 88, 69, 72, 63, 100, 68, 81, -77, -10, -128, + -128, -128, -128, -128, 13, -77, 8, 27, 60, 28, 41, -128, + -37, -128, 28, -43, -18, -128, 47, -37, 45, 27, 51, -29, + 15, 39, 52, 30, 49, -33, 65, 15, 76, 71, 90, 19, + 46, -128, -16, -128, -128, -128, -128, -128, -128, -128, -18, -128, + -20, -128, 32, -128, 21, -33, 45, -128, -128, -128, -12, -128, + -6, -14, 43, -128, -128, -128, -128, -128, 52, -18, 69, -43, + 78, 55, 42, -128, -29, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, 14, -128, -16, -128, -128, -128, 7, -128, + -128, -128, -128, -128, -128, -128, 12, -128, -128, -128, -128, -16, + 59, -50, 35, -128, 42, 0, 47, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -33, -128, -23, -128, + -128, -128, -23, -128, -128, -128, -128, -128, -128, -128, -33, -128, + -128, -128, -128, -128, -128, -128, -8, -128, 36, -50, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -37, -128, -128, -60, -10, -128, -128, -128, -128, -128, + -128, -128, 21, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -12, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -77, -128, -128, -128, -29, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -29, -128, -128, -128, -128, -128, -128, -128, -128, -128, -50, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, +}; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h new file mode 100644 index 0000000..8c1b6d5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h @@ -0,0 +1,23 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ + +extern const int g_no_micro_f9643d42_nohash_4_width; +extern const int g_no_micro_f9643d42_nohash_4_height; +extern const signed char g_no_micro_f9643d42_nohash_4_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_NO_MICRO_FEATURES_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.cc new file mode 100644 index 0000000..6d9137a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.cc @@ -0,0 +1,188 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h" + +// Golden test values for the expected spectrogram from a "yes" sample file +// speech_commands_test_set_v0.02/yes/f2e59fea_nohash_1.wav. + +const int g_yes_micro_f2e59fea_nohash_1_width = 40; +const int g_yes_micro_f2e59fea_nohash_1_height = 49; +const signed char g_yes_micro_f2e59fea_nohash_1_data[] = { + 116, 98, 118, 95, 106, 85, 101, 81, 67, -18, -33, -12, + -26, -128, 9, 34, 56, 45, 9, -12, 5, 30, 23, 28, + 0, -18, 0, -128, -60, -50, -50, -37, -60, -60, -50, -26, + -33, -50, -33, -50, 83, 61, 81, 55, 76, 61, 73, 64, + 38, -8, -37, -20, -18, -20, 48, 29, 52, 41, 55, 18, + 25, 37, 44, 37, 8, 15, -6, -60, -128, -50, -37, -37, + -18, -37, -26, -29, -37, -60, -50, -60, 95, 59, 52, -4, + 54, -18, 68, 43, 31, -18, -26, -33, -37, -29, 33, 7, + -3, 8, 26, 24, 36, 6, 36, 23, 14, 8, -29, -37, + -37, -37, -50, -50, -26, -8, -26, -37, -18, -37, -60, -77, + 50, 48, 83, 44, 56, -128, -33, -60, 1, -26, -60, -43, + -14, -23, -18, -43, -26, -33, 13, -77, -43, -77, -33, -37, + 16, -12, -37, -50, -50, -77, -20, -43, -60, -128, -60, -77, + -37, -77, -60, -128, 37, -10, 65, -7, 28, -128, 10, -77, + -37, -128, -77, -128, -77, -43, -128, -128, -77, -128, -128, -128, + -128, -128, -14, -128, -43, -50, -37, -77, -128, -128, -77, -43, + -29, -43, -20, -60, -37, -43, -50, -128, -77, -128, -18, -128, + -60, -128, -128, -128, -77, -128, -77, -128, -128, -128, -60, -37, + -20, -128, -60, -128, -128, -128, -60, -128, -77, -60, -128, -50, + -60, -128, -77, -128, -50, -60, -37, -60, -50, -77, -77, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -37, -128, + -128, -128, -128, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -77, -60, -128, -128, -50, -128, -50, -128, + -50, -128, -77, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -77, -128, -77, -128, -77, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, -128, -128, + -128, -77, -50, -128, -128, -77, -77, -128, -128, -128, -50, -128, + 85, 43, 65, 53, 69, 60, 45, 3, 46, -12, 9, -23, + 32, -1, -128, -128, -128, -128, -1, 37, 38, 33, 43, 36, + 58, 70, 68, 39, 6, 10, 32, 6, 8, -23, -77, -128, + -29, -128, -77, -128, 101, 87, 102, 91, 110, 88, 101, 83, + 110, 95, 111, 83, 81, 84, 106, 90, 93, 82, 98, 91, + 108, 95, 118, 97, 118, 97, 116, 96, 113, 90, 110, 96, + 107, 85, 94, 66, 69, 36, 29, 0, 100, 60, 105, 68, + 92, 93, 113, 92, 107, 85, 107, 83, 104, 91, 105, 85, + 112, 88, 101, 80, 101, 79, 96, 80, 98, 80, 105, 83, + 98, 81, 103, 71, 100, 79, 83, 78, 91, 47, 50, 13, + 108, 81, 93, 78, 98, 76, 105, 76, 98, 40, 77, 72, + 81, 62, 93, 77, 96, 80, 98, 61, 97, 69, 88, 61, + 71, 56, 98, 68, 97, 72, 89, 51, 81, 61, 88, 75, + 86, 56, 48, 13, 71, 22, 84, 66, 76, -7, 48, 61, + 77, 62, 91, 65, 95, 74, 88, 59, 75, 58, 83, 55, + 87, 55, 76, 43, 76, -3, 56, 60, 79, 57, 71, 54, + 82, 33, 74, 71, 91, 45, 18, -7, 61, 56, 77, 41, + 73, 42, 82, 49, 59, 63, 82, 65, 66, 38, 83, 34, + 48, -8, 46, 20, 54, 33, 54, 6, 48, 16, 60, 37, + 58, 22, 58, 14, 65, 53, 75, -4, 42, 16, 16, -50, + 22, -128, 80, 54, 43, -50, 42, -128, -10, -77, 28, -29, + 68, 43, 73, 2, 25, -60, 47, 14, 45, 7, 66, 4, + 62, 37, 71, 7, 46, -10, 44, 22, 55, 53, 57, -29, + 26, -10, -3, -128, 38, -128, 46, -10, 16, -128, -10, -26, + 60, -7, 65, 38, 70, -60, 35, -8, 42, -29, 6, -128, + 34, -128, 36, -60, 44, -12, -2, -128, -7, -60, -60, -128, + -23, -128, 31, -33, 22, -77, -37, -43, -128, -128, 3, -128, + -23, -128, 17, -77, 43, -77, -7, -128, -20, -128, 17, -43, + 32, -128, -43, -128, -128, -77, 21, -128, -50, -128, -128, -128, + -128, -128, -128, -128, -37, -128, -16, -128, -50, -26, -6, -128, + -128, -128, -128, -128, -23, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -16, -128, 36, -7, 16, -128, -128, -128, -128, -128, + -77, -128, -37, -128, -50, -128, -128, -128, -128, -128, -18, -128, + 11, -128, -16, -77, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -26, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -20, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -50, -128, -77, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -77, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -1, -18, 5, -128, + 40, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, 4, -128, 63, 66, 75, -128, + 70, 60, 34, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 87, 86, 95, 76, 91, 62, 72, -6, -50, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, 64, 83, 104, 70, + 98, 90, 111, 89, 109, 80, 71, -128, -128, -128, -128, -128, + -20, -6, 27, 33, 86, 88, 108, 75, 108, 76, 98, 64, + 75, 61, 71, 66, 85, -1, -77, -128, 46, 61, 92, 69, + 100, 93, 113, 80, 108, 93, 113, 91, 110, 80, 85, 15, + -33, -128, 12, -50, 34, 50, 70, 55, 84, 72, 108, 81, + 111, 88, 100, 80, 84, 73, 97, 86, 99, 65, 85, 43, + 96, 78, 107, 94, 118, 98, 115, 92, 118, 94, 111, 93, + 111, 86, 99, 52, 32, -16, 48, 31, 81, 74, 85, 64, + 78, 64, 98, 70, 110, 92, 96, 73, 100, 72, 94, 73, + 98, 76, 85, 67, 101, 83, 101, 83, 112, 89, 98, 85, + 105, 78, 98, 72, 102, 80, 95, 23, 19, -8, 52, 57, + 103, 91, 95, 65, 74, 8, 77, 49, 96, 76, 100, 87, + 105, 81, 94, 62, 94, 78, 81, 72, 99, 82, 101, 78, + 108, 65, 82, 70, 100, 63, 79, 58, 80, 59, 87, 48, + 50, 57, 93, 67, 86, 80, 103, 56, 77, 31, 81, 57, + 62, 41, 96, 85, 91, 71, 101, 76, 89, 78, 95, 76, + 96, 79, 103, 81, 103, 48, 70, 57, 88, 66, 84, 11, + 85, 67, 104, 37, 38, 67, 90, 54, 81, 62, 90, 52, + 78, -60, 54, -8, 68, 40, 55, 8, 77, 52, 66, 31, + 55, 13, 60, 26, 69, 42, 63, -29, 57, -128, -3, -128, + 3, -128, -29, -60, 52, -43, 63, 56, 86, 75, 95, 75, + 85, 63, 82, 10, 50, -128, 31, -77, 0, -77, -23, -128, + 12, -77, 51, -3, 58, -14, 44, 0, 48, 4, 53, 47, + 28, -128, -128, -128, -37, -128, -3, -128, 49, 61, 100, 90, + 117, 88, 107, 94, 112, 64, 96, 83, -128, -128, 7, -128, + -77, -128, -23, -128, -23, -128, 16, -37, 65, -8, 48, 20, + 14, -77, 57, -18, -43, -128, -128, -128, -128, -128, -128, -128, + 24, 12, 74, 76, 105, 76, 99, 80, 108, 79, 103, 85, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + 42, -128, -8, -128, -50, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -60, -128, -128, 5, 73, 53, 93, 70, 101, 73, + 94, 57, 86, 66, -18, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -50, -128, 36, -128, -128, -128, -128, -128, -20, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 23, 37, + 75, 54, 97, 70, 83, 52, 85, 65, 7, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -43, -128, 23, -128, -43, -128, + -33, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -26, -37, 65, 33, 76, 37, 73, 50, 77, 47, + -12, -128, -128, -128, -128, -128, -128, -128, -128, -128, -7, -14, + -4, -128, -14, -128, 18, -60, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -26, -60, 71, 42, 68, 53, + 81, 49, 73, 36, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -18, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, 15, -26, + 44, -18, 59, 39, 57, 20, 62, 26, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, 49, -128, 30, 8, 69, 27, 62, 38, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -43, -128, 28, -37, 48, -10, + 48, 11, 74, 37, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -77, -128, 11, -128, -7, -60, -77, -4, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -8, -128, -50, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, +}; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h new file mode 100644 index 0000000..cd1ad10 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h @@ -0,0 +1,23 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ + +extern const int g_yes_micro_f2e59fea_nohash_1_width; +extern const int g_yes_micro_f2e59fea_nohash_1_height; +extern const signed char g_yes_micro_f2e59fea_nohash_1_data[]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_MICRO_FEATURES_YES_MICRO_FEATURES_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_speech_test.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_speech_test.cc new file mode 100644 index 0000000..31e509a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/micro_speech_test.cc @@ -0,0 +1,143 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +/* +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/model.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/no_micro_features_data.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/yes_micro_features_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/micro/testing/micro_test.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/version.h" + +TF_LITE_MICRO_TESTS_BEGIN + +TF_LITE_MICRO_TEST(TestInvoke) { + // Set up logging. + tflite::MicroErrorReporter micro_error_reporter; + + // Map the model into a usable data structure. This doesn't involve any + // copying or parsing, it's a very lightweight operation. + const tflite::Model* model = ::tflite::GetModel(g_model); + if (model->version() != TFLITE_SCHEMA_VERSION) { + TF_LITE_REPORT_ERROR(µ_error_reporter, + "Model provided is schema version %d not equal " + "to supported version %d.\n", + model->version(), TFLITE_SCHEMA_VERSION); + } + + // Pull in only the operation implementations we need. + // This relies on a complete list of all the ops needed by this graph. + // An easier approach is to just use the AllOpsResolver, but this will + // incur some penalty in code space for op implementations that are not + // needed by this graph. + // + // tflite::AllOpsResolver resolver; + tflite::MicroMutableOpResolver<4> micro_op_resolver; + micro_op_resolver.AddDepthwiseConv2D(); + micro_op_resolver.AddFullyConnected(); + micro_op_resolver.AddReshape(); + micro_op_resolver.AddSoftmax(); + + // Create an area of memory to use for input, output, and intermediate arrays. + const int tensor_arena_size = 10 * 1024; + uint8_t tensor_arena[tensor_arena_size]; + + // Build an interpreter to run the model with. + tflite::MicroInterpreter interpreter(model, micro_op_resolver, tensor_arena, + tensor_arena_size, + µ_error_reporter); + interpreter.AllocateTensors(); + + // Get information about the memory area to use for the model's input. + TfLiteTensor* input = interpreter.input(0); + + // Make sure the input has the properties we expect. + TF_LITE_MICRO_EXPECT_NE(nullptr, input); + TF_LITE_MICRO_EXPECT_EQ(2, input->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(1960, input->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, input->type); + + // Copy a spectrogram created from a .wav audio file of someone saying "Yes", + // into the memory area used for the input. + const int8_t* yes_features_data = g_yes_micro_f2e59fea_nohash_1_data; + for (size_t i = 0; i < input->bytes; ++i) { + input->data.int8[i] = yes_features_data[i]; + } + + // Run the model on this input and make sure it succeeds. + TfLiteStatus invoke_status = interpreter.Invoke(); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(µ_error_reporter, "Invoke failed\n"); + } + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status); + + // Get the output from the model, and make sure it's the expected size and + // type. + TfLiteTensor* output = interpreter.output(0); + TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(4, output->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type); + + // There are four possible classes in the output, each with a score. + const int kSilenceIndex = 0; + const int kUnknownIndex = 1; + const int kYesIndex = 2; + const int kNoIndex = 3; + + // Make sure that the expected "Yes" score is higher than the other classes. + uint8_t silence_score = output->data.uint8[kSilenceIndex] + 128; + uint8_t unknown_score = output->data.uint8[kUnknownIndex] + 128; + uint8_t yes_score = output->data.int8[kYesIndex] + 128; + uint8_t no_score = output->data.int8[kNoIndex] + 128; + TF_LITE_MICRO_EXPECT_GT(yes_score, silence_score); + TF_LITE_MICRO_EXPECT_GT(yes_score, unknown_score); + TF_LITE_MICRO_EXPECT_GT(yes_score, no_score); + + // Now test with a different input, from a recording of "No". + const int8_t* no_features_data = g_no_micro_f9643d42_nohash_4_data; + for (size_t i = 0; i < input->bytes; ++i) { + input->data.int8[i] = no_features_data[i]; + } + + // Run the model on this "No" input. + invoke_status = interpreter.Invoke(); + if (invoke_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(µ_error_reporter, "Invoke failed\n"); + } + TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status); + + // Get the output from the model, and make sure it's the expected size and + // type. + output = interpreter.output(0); + TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size); + TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]); + TF_LITE_MICRO_EXPECT_EQ(4, output->dims->data[1]); + TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type); + + // Make sure that the expected "No" score is higher than the other classes. + silence_score = output->data.int8[kSilenceIndex] + 128; + unknown_score = output->data.int8[kUnknownIndex] + 128; + yes_score = output->data.int8[kYesIndex] + 128; + no_score = output->data.int8[kNoIndex] + 128; + TF_LITE_MICRO_EXPECT_GT(no_score, silence_score); + TF_LITE_MICRO_EXPECT_GT(no_score, unknown_score); + TF_LITE_MICRO_EXPECT_GT(no_score, yes_score); + + TF_LITE_REPORT_ERROR(µ_error_reporter, "Ran successfully\n"); +} + +TF_LITE_MICRO_TESTS_END +*/ \ No newline at end of file diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.cc new file mode 100644 index 0000000..265c494 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.cc @@ -0,0 +1,142 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/micro_speech/recognize_commands.h" + +#include + +RecognizeCommands::RecognizeCommands(tflite::ErrorReporter* error_reporter, + int32_t average_window_duration_ms, + uint8_t detection_threshold, + int32_t suppression_ms, + int32_t minimum_count) + : error_reporter_(error_reporter), + average_window_duration_ms_(average_window_duration_ms), + detection_threshold_(detection_threshold), + suppression_ms_(suppression_ms), + minimum_count_(minimum_count), + previous_results_(error_reporter) { + previous_top_label_ = "silence"; + previous_top_label_time_ = std::numeric_limits::min(); +} + +TfLiteStatus RecognizeCommands::ProcessLatestResults( + const TfLiteTensor* latest_results, const int32_t current_time_ms, + const char** found_command, uint8_t* score, bool* is_new_command) { + if ((latest_results->dims->size != 2) || + (latest_results->dims->data[0] != 1) || + (latest_results->dims->data[1] != kCategoryCount)) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "The results for recognition should contain %d elements, but there are " + "%d in an %d-dimensional shape", + kCategoryCount, latest_results->dims->data[1], + latest_results->dims->size); + return kTfLiteError; + } + + if (latest_results->type != kTfLiteInt8) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "The results for recognition should be int8_t elements, but are %d", + latest_results->type); + return kTfLiteError; + } + + if ((!previous_results_.empty()) && + (current_time_ms < previous_results_.front().time_)) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Results must be fed in increasing time order, but received a " + "timestamp of %d that was earlier than the previous one of %d", + current_time_ms, previous_results_.front().time_); + return kTfLiteError; + } + + // Add the latest results to the head of the queue. + previous_results_.push_back({current_time_ms, latest_results->data.int8}); + + // Prune any earlier results that are too old for the averaging window. + const int64_t time_limit = current_time_ms - average_window_duration_ms_; + while ((!previous_results_.empty()) && + previous_results_.front().time_ < time_limit) { + previous_results_.pop_front(); + } + + // If there are too few results, assume the result will be unreliable and + // bail. + const int64_t how_many_results = previous_results_.size(); + const int64_t earliest_time = previous_results_.front().time_; + const int64_t samples_duration = current_time_ms - earliest_time; + if ((how_many_results < minimum_count_) || + (samples_duration < (average_window_duration_ms_ / 4))) { + *found_command = previous_top_label_; + *score = 0; + *is_new_command = false; + return kTfLiteOk; + } + + // Calculate the average score across all the results in the window. + int32_t average_scores[kCategoryCount]; + for (int offset = 0; offset < previous_results_.size(); ++offset) { + PreviousResultsQueue::Result previous_result = + previous_results_.from_front(offset); + const int8_t* scores = previous_result.scores; + for (int i = 0; i < kCategoryCount; ++i) { + if (offset == 0) { + average_scores[i] = scores[i] + 128; + } else { + average_scores[i] += scores[i] + 128; + } + } + } + for (int i = 0; i < kCategoryCount; ++i) { + average_scores[i] /= how_many_results; + } + + // Find the current highest scoring category. + int current_top_index = 0; + int32_t current_top_score = 0; + for (int i = 0; i < kCategoryCount; ++i) { + if (average_scores[i] > current_top_score) { + current_top_score = average_scores[i]; + current_top_index = i; + } + } + const char* current_top_label = kCategoryLabels[current_top_index]; + + // If we've recently had another label trigger, assume one that occurs too + // soon afterwards is a bad result. + int64_t time_since_last_top; + if ((previous_top_label_ == kCategoryLabels[0]) || + (previous_top_label_time_ == std::numeric_limits::min())) { + time_since_last_top = std::numeric_limits::max(); + } else { + time_since_last_top = current_time_ms - previous_top_label_time_; + } + if ((current_top_score > detection_threshold_) && + ((current_top_label != previous_top_label_) || + (time_since_last_top > suppression_ms_))) { + previous_top_label_ = current_top_label; + previous_top_label_time_ = current_time_ms; + *is_new_command = true; + } else { + *is_new_command = false; + } + *found_command = current_top_label; + *score = current_top_score; + + return kTfLiteOk; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.h new file mode 100644 index 0000000..67bdb31 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/micro_speech/recognize_commands.h @@ -0,0 +1,159 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ + +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/examples/micro_speech/micro_features/micro_model_settings.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Partial implementation of std::dequeue, just providing the functionality +// that's needed to keep a record of previous neural network results over a +// short time period, so they can be averaged together to produce a more +// accurate overall prediction. This doesn't use any dynamic memory allocation +// so it's a better fit for microcontroller applications, but this does mean +// there are hard limits on the number of results it can store. +class PreviousResultsQueue { + public: + PreviousResultsQueue(tflite::ErrorReporter* error_reporter) + : error_reporter_(error_reporter), front_index_(0), size_(0) {} + + // Data structure that holds an inference result, and the time when it + // was recorded. + struct Result { + Result() : time_(0), scores() {} + Result(int32_t time, int8_t* input_scores) : time_(time) { + for (int i = 0; i < kCategoryCount; ++i) { + scores[i] = input_scores[i]; + } + } + int32_t time_; + int8_t scores[kCategoryCount]; + }; + + int size() { return size_; } + bool empty() { return size_ == 0; } + Result& front() { return results_[front_index_]; } + Result& back() { + int back_index = front_index_ + (size_ - 1); + if (back_index >= kMaxResults) { + back_index -= kMaxResults; + } + return results_[back_index]; + } + + void push_back(const Result& entry) { + if (size() >= kMaxResults) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Couldn't push_back latest result, too many already!"); + return; + } + size_ += 1; + back() = entry; + } + + Result pop_front() { + if (size() <= 0) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Couldn't pop_front result, none present!"); + return Result(); + } + Result result = front(); + front_index_ += 1; + if (front_index_ >= kMaxResults) { + front_index_ = 0; + } + size_ -= 1; + return result; + } + + // Most of the functions are duplicates of dequeue containers, but this + // is a helper that makes it easy to iterate through the contents of the + // queue. + Result& from_front(int offset) { + if ((offset < 0) || (offset >= size_)) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Attempt to read beyond the end of the queue!"); + offset = size_ - 1; + } + int index = front_index_ + offset; + if (index >= kMaxResults) { + index -= kMaxResults; + } + return results_[index]; + } + + private: + tflite::ErrorReporter* error_reporter_; + static constexpr int kMaxResults = 50; + Result results_[kMaxResults]; + + int front_index_; + int size_; +}; + +// This class is designed to apply a very primitive decoding model on top of the +// instantaneous results from running an audio recognition model on a single +// window of samples. It applies smoothing over time so that noisy individual +// label scores are averaged, increasing the confidence that apparent matches +// are real. +// To use it, you should create a class object with the configuration you +// want, and then feed results from running a TensorFlow model into the +// processing method. The timestamp for each subsequent call should be +// increasing from the previous, since the class is designed to process a stream +// of data over time. +class RecognizeCommands { + public: + // labels should be a list of the strings associated with each one-hot score. + // The window duration controls the smoothing. Longer durations will give a + // higher confidence that the results are correct, but may miss some commands. + // The detection threshold has a similar effect, with high values increasing + // the precision at the cost of recall. The minimum count controls how many + // results need to be in the averaging window before it's seen as a reliable + // average. This prevents erroneous results when the averaging window is + // initially being populated for example. The suppression argument disables + // further recognitions for a set time after one has been triggered, which can + // help reduce spurious recognitions. + explicit RecognizeCommands(tflite::ErrorReporter* error_reporter, + int32_t average_window_duration_ms = 1000, + uint8_t detection_threshold = 200, + int32_t suppression_ms = 1500, + int32_t minimum_count = 3); + + // Call this with the results of running a model on sample data. + TfLiteStatus ProcessLatestResults(const TfLiteTensor* latest_results, + const int32_t current_time_ms, + const char** found_command, uint8_t* score, + bool* is_new_command); + + private: + // Configuration + tflite::ErrorReporter* error_reporter_; + int32_t average_window_duration_ms_; + uint8_t detection_threshold_; + int32_t suppression_ms_; + int32_t minimum_count_; + + // Working variables + PreviousResultsQueue previous_results_; + const char* previous_top_label_; + int32_t previous_top_label_time_; +}; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_MICRO_SPEECH_RECOGNIZE_COMMANDS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.cc new file mode 100644 index 0000000..bc409b5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.cc @@ -0,0 +1,25 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.h" + +// This dummy implementation writes person and no person scores to the error +// console. Real applications will want to take some custom action instead, and +// should implement their own versions of this function. +void RespondToDetection(tflite::ErrorReporter* error_reporter, + int8_t person_score, int8_t no_person_score) { + TF_LITE_REPORT_ERROR(error_reporter, "person score:%d no person score %d", + person_score, no_person_score); +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.h new file mode 100644 index 0000000..aadad3b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.h @@ -0,0 +1,34 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Provides an interface to take an action based on the output from the person +// detection model. + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_DETECTION_RESPONDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_DETECTION_RESPONDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// Called every time the results of a person detection run are available. The +// `person_score` has the numerical confidence that the captured image contains +// a person, and `no_person_score` has the numerical confidence that the image +// does not contain a person. Typically if person_score > no person score, the +// image is considered to contain a person. This threshold may be adjusted for +// particular applications. +void RespondToDetection(tflite::ErrorReporter* error_reporter, + int8_t person_score, int8_t no_person_score); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_DETECTION_RESPONDER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.cc new file mode 100644 index 0000000..1ff05f4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.cc @@ -0,0 +1,30 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/person_detection_experimental/image_provider.h" +#include "tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h" + +#include "tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.h" +#include "tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.h" + +TfLiteStatus GetImage(tflite::ErrorReporter* error_reporter, int image_width, + int image_height, int channels, int8_t* image_data, + uint8_t * hardware_input) { + for (int i = 0; i < image_width * image_height * channels; ++i) { + //image_data[i] = hardware_input[i]; + image_data[i] = g_no_person_data[i]; + } + return kTfLiteOk; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.h new file mode 100644 index 0000000..4d18c4d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/image_provider.h @@ -0,0 +1,40 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_IMAGE_PROVIDER_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_IMAGE_PROVIDER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +// This is an abstraction around an image source like a camera, and is +// expected to return 8-bit sample data. The assumption is that this will be +// called in a low duty-cycle fashion in a low-power application. In these +// cases, the imaging sensor need not be run in a streaming mode, but rather can +// be idled in a relatively low-power mode between calls to GetImage(). The +// assumption is that the overhead and time of bringing the low-power sensor out +// of this standby mode is commensurate with the expected duty cycle of the +// application. The underlying sensor may actually be put into a streaming +// configuration, but the image buffer provided to GetImage should not be +// overwritten by the driver code until the next call to GetImage(); +// +// The reference implementation can have no platform-specific dependencies, so +// it just returns a static image. For real applications, you should +// ensure there's a specialized implementation that accesses hardware APIs. +TfLiteStatus GetImage(tflite::ErrorReporter* error_reporter, int image_width, + int image_height, int channels, int8_t* image_data, + uint8_t * hardware_input); + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_IMAGE_PROVIDER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.cc new file mode 100644 index 0000000..b096b5c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.cc @@ -0,0 +1,119 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/person_detection_experimental/main_functions.h" + +#include "tensorflow/lite/micro/examples/person_detection_experimental/detection_responder.h" +#include "tensorflow/lite/micro/examples/person_detection_experimental/image_provider.h" +#include "tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h" +#include "tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/version.h" + +// Globals, used for compatibility with Arduino-style sketches. +namespace { +tflite::ErrorReporter* error_reporter = nullptr; +const tflite::Model* model = nullptr; +tflite::MicroInterpreter* interpreter = nullptr; +TfLiteTensor* input = nullptr; + +// In order to use optimized tensorflow lite kernels, a signed int8_t quantized +// model is preferred over the legacy unsigned model format. This means that +// throughout this project, input images must be converted from unisgned to +// signed format. The easiest and quickest way to convert from unsigned to +// signed 8-bit integers is to subtract 128 from the unsigned value to get a +// signed value. + +// An area of memory to use for input, output, and intermediate arrays. +constexpr int kTensorArenaSize = 115 * 1024; +static uint8_t tensor_arena[kTensorArenaSize]; +} // namespace + +// The name of this function is important for Arduino compatibility. +void person_detect_init(unsigned char* model_data) { + // Set up logging. Google style is to avoid globals or statics because of + // lifetime uncertainty, but since this has a trivial destructor it's okay. + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroErrorReporter micro_error_reporter; + error_reporter = µ_error_reporter; + + // Map the model into a usable data structure. This doesn't involve any + // copying or parsing, it's a very lightweight operation. + model = tflite::GetModel(model_data); + if (model->version() != TFLITE_SCHEMA_VERSION) { + TF_LITE_REPORT_ERROR(error_reporter, + "Model provided is schema version %d not equal " + "to supported version %d.", + model->version(), TFLITE_SCHEMA_VERSION); + return; + } + + // Pull in only the operation implementations we need. + // This relies on a complete list of all the ops needed by this graph. + // An easier approach is to just use the AllOpsResolver, but this will + // incur some penalty in code space for op implementations that are not + // needed by this graph. + // + // tflite::AllOpsResolver resolver; + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroMutableOpResolver<5> micro_op_resolver; + micro_op_resolver.AddAveragePool2D(); + micro_op_resolver.AddConv2D(); + micro_op_resolver.AddDepthwiseConv2D(); + micro_op_resolver.AddReshape(); + micro_op_resolver.AddSoftmax(); + + // Build an interpreter to run the model with. + // NOLINTNEXTLINE(runtime-global-variables) + static tflite::MicroInterpreter static_interpreter( + model, micro_op_resolver, tensor_arena, kTensorArenaSize, error_reporter); + interpreter = &static_interpreter; + + // Allocate memory from the tensor_arena for the model's tensors. + TfLiteStatus allocate_status = interpreter->AllocateTensors(); + if (allocate_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed"); + return; + } + + // Get information about the memory area to use for the model's input. + input = interpreter->input(0); +} + +// The name of this function is important for Arduino compatibility. +int person_detect(uint8_t * hardware_input) { + // Get image from provider. + if (kTfLiteOk != GetImage(error_reporter, kNumCols, kNumRows, kNumChannels, + input->data.int8, hardware_input)) { + TF_LITE_REPORT_ERROR(error_reporter, "Image capture failed."); + } + + // Run the model on this input and make sure it succeeds. + if (kTfLiteOk != interpreter->Invoke()) { + TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed."); + } + + TfLiteTensor* output = interpreter->output(0); + + // Process the inference results. + int8_t person_score = output->data.uint8[kPersonIndex]; + int8_t no_person_score = output->data.uint8[kNotAPersonIndex]; + RespondToDetection(error_reporter, person_score, no_person_score); + if(person_score >= no_person_score + 50) return 1; + else return 0; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.h new file mode 100644 index 0000000..3e44b08 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/main_functions.h @@ -0,0 +1,37 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MAIN_FUNCTIONS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MAIN_FUNCTIONS_H_ + +#include "tensorflow/lite/c/common.h" + +// Initializes all data needed for the example. The name is important, and needs +// to be setup() for Arduino compatibility. +#ifdef __cplusplus +extern "C" { +#endif + +void person_detect_init(unsigned char* model_data); + +// Runs one iteration of data gathering and inference. This should be called +// repeatedly from the application code. The name needs to be loop() for Arduino +// compatibility. +int person_detect(uint8_t * hardware_input); + +#ifdef __cplusplus +} +#endif +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MAIN_FUNCTIONS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.cc new file mode 100644 index 0000000..c7359b8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.cc @@ -0,0 +1,21 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h" + +const char* kCategoryLabels[kCategoryCount] = { + "notperson", + "person", +}; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h new file mode 100644 index 0000000..f6c968e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h @@ -0,0 +1,35 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MODEL_SETTINGS_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MODEL_SETTINGS_H_ + +// Keeping these as constant expressions allow us to allocate fixed-sized arrays +// on the stack for our working memory. + +// All of these values are derived from the values used during model training, +// if you change your model you'll need to update these constants. +constexpr int kNumCols = 96; +constexpr int kNumRows = 96; +constexpr int kNumChannels = 1; + +constexpr int kMaxImageSize = kNumCols * kNumRows * kNumChannels; + +constexpr int kCategoryCount = 2; +constexpr int kPersonIndex = 1; +constexpr int kNotAPersonIndex = 0; +extern const char* kCategoryLabels[kCategoryCount]; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_MODEL_SETTINGS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.cc new file mode 100644 index 0000000..7849ae5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.cc @@ -0,0 +1,792 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.h" + +#include "tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h" + +const int g_no_person_data_size = kMaxImageSize; +const uint8_t g_no_person_data[g_no_person_data_size] = { + 0x67, 0x67, 0x65, 0x61, 0x65, 0x68, 0x6f, 0x70, 0x79, 0x7b, 0x82, 0x83, + 0x8c, 0x92, 0x9c, 0x9f, 0xb0, 0xc1, 0xd3, 0xdd, 0xe2, 0xf1, 0xf7, 0xe6, + 0xf4, 0xf4, 0xff, 0xff, 0xf5, 0xff, 0xe4, 0x6e, 0x48, 0x34, 0x6c, 0x6c, + 0xff, 0xff, 0xff, 0xfe, 0xe5, 0xf9, 0xfa, 0xf1, 0xe5, 0xf9, 0xf3, 0xd3, + 0xdc, 0xd3, 0xc8, 0xbd, 0x99, 0xa8, 0x9e, 0x99, 0x95, 0x92, 0x88, 0x87, + 0x85, 0x85, 0x82, 0x80, 0x79, 0x7b, 0x81, 0x83, 0x87, 0x89, 0x89, 0x88, + 0x92, 0x97, 0xa0, 0xad, 0xaf, 0xc3, 0xca, 0xd5, 0xde, 0xe0, 0xd6, 0xee, + 0xf4, 0xfc, 0xfe, 0xff, 0xf4, 0xff, 0xf2, 0xef, 0xff, 0xfa, 0xff, 0xff, + 0x66, 0x67, 0x63, 0x65, 0x5b, 0x66, 0x6d, 0x6f, 0x73, 0x77, 0x7a, 0x83, + 0x8b, 0x8f, 0x99, 0xa6, 0x9b, 0xc1, 0xd3, 0xe1, 0xf1, 0xe8, 0xfa, 0xf6, + 0xff, 0xff, 0xe9, 0xfc, 0xff, 0xff, 0xd0, 0x6a, 0x49, 0x32, 0x6f, 0x6b, + 0xff, 0xff, 0xfa, 0xf8, 0xf1, 0xfb, 0xff, 0xf6, 0xea, 0xf6, 0xe2, 0xee, + 0xd0, 0xd3, 0xc1, 0xb1, 0x9f, 0xa4, 0x99, 0x95, 0x8d, 0x8b, 0x87, 0x87, + 0x86, 0x82, 0x81, 0x7a, 0x78, 0x83, 0x84, 0x87, 0x8a, 0x8a, 0x8e, 0x93, + 0x97, 0xa4, 0xa9, 0xb5, 0xc4, 0xce, 0xd5, 0xe9, 0xe9, 0xe3, 0xdc, 0xfa, + 0xfa, 0xf0, 0xef, 0xf2, 0xdc, 0xfc, 0xf5, 0xff, 0xfe, 0xff, 0xff, 0xff, + 0x66, 0x63, 0x65, 0x65, 0x5f, 0x5c, 0x64, 0x68, 0x70, 0x71, 0x73, 0x80, + 0x80, 0x88, 0x8f, 0x98, 0x97, 0xb2, 0xc6, 0xcf, 0xd0, 0xd8, 0xe7, 0xfc, + 0xef, 0xff, 0xff, 0xff, 0xfc, 0xee, 0xf3, 0x61, 0x4c, 0x30, 0x6d, 0x6d, + 0xff, 0xf1, 0xff, 0xf7, 0xfc, 0xf6, 0xed, 0xdb, 0xfe, 0xd5, 0xe9, 0xd0, + 0xc9, 0xbd, 0xac, 0x96, 0x95, 0x94, 0x91, 0x8d, 0x89, 0x86, 0x80, 0x85, + 0x7e, 0x80, 0x7c, 0x72, 0x82, 0x82, 0x85, 0x86, 0x8b, 0x8e, 0x97, 0x9b, + 0x9f, 0xad, 0xb9, 0xbf, 0xcf, 0xda, 0xe6, 0xe3, 0xee, 0xf2, 0xfa, 0xff, + 0xf6, 0xef, 0xff, 0xff, 0xfb, 0xfe, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xfb, + 0x61, 0x5e, 0x62, 0x5d, 0x62, 0x58, 0x5b, 0x61, 0x68, 0x6c, 0x6e, 0x74, + 0x79, 0x83, 0x86, 0x8c, 0x91, 0x96, 0xb5, 0xbe, 0xb0, 0x8e, 0xd9, 0xff, + 0xe4, 0xf3, 0xff, 0xfc, 0xee, 0xf9, 0xea, 0x5e, 0x4e, 0x2e, 0x6a, 0x6c, + 0xfe, 0xea, 0xf5, 0xff, 0xf4, 0xff, 0xf2, 0xf8, 0xff, 0xe9, 0xe4, 0xd0, + 0xc8, 0xba, 0xb2, 0x8f, 0x9e, 0x95, 0x91, 0x88, 0x82, 0x7b, 0x78, 0x78, + 0x76, 0x74, 0x71, 0x79, 0x7e, 0x84, 0x83, 0x8b, 0x8e, 0x95, 0x9a, 0xa0, + 0xad, 0xb5, 0xc3, 0xcc, 0xd7, 0xd7, 0xdd, 0xf6, 0xef, 0xfc, 0xf9, 0xf0, + 0xf9, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x62, 0x60, 0x5d, 0x5e, 0x5b, 0x5b, 0x52, 0x5d, 0x5d, 0x5e, 0x62, 0x6f, + 0x78, 0x81, 0x82, 0x87, 0x87, 0x86, 0xa7, 0xb2, 0xbb, 0xc3, 0xdc, 0xea, + 0xfb, 0xf4, 0xf7, 0xea, 0xf6, 0xf7, 0xff, 0x5c, 0x4b, 0x2e, 0x67, 0x6c, + 0xfa, 0xfb, 0xf7, 0xf3, 0xe0, 0xff, 0xee, 0xff, 0xe1, 0xd3, 0xa8, 0xc5, + 0xc3, 0xae, 0x9d, 0xa1, 0x9b, 0x91, 0x8e, 0x84, 0x80, 0x7c, 0x80, 0x7a, + 0x79, 0x78, 0x74, 0x7f, 0x83, 0x87, 0x88, 0x8b, 0x8c, 0x98, 0x9f, 0xae, + 0xb4, 0xbf, 0xd4, 0xda, 0xdb, 0xe0, 0xee, 0xfb, 0xec, 0xee, 0xf9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xfd, 0xff, 0xff, 0xfc, 0xff, + 0x61, 0x60, 0x5f, 0x5e, 0x59, 0x58, 0x57, 0x53, 0x58, 0x46, 0x48, 0x56, + 0x5d, 0x82, 0x6e, 0x73, 0x76, 0x7b, 0x84, 0x94, 0x9e, 0xad, 0xbe, 0xd8, + 0xd0, 0xe0, 0xf5, 0xff, 0xff, 0xe2, 0xff, 0x4e, 0x47, 0x2d, 0x5b, 0x66, + 0xec, 0xff, 0xe6, 0xf5, 0xf7, 0xe8, 0xe6, 0xf6, 0xdb, 0xb6, 0xa7, 0xba, + 0xb0, 0xa6, 0x8c, 0x9a, 0x91, 0x8d, 0x8c, 0x8b, 0x81, 0x7e, 0x82, 0x7d, + 0x7c, 0x71, 0x7e, 0x82, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9e, 0xa5, 0xb6, + 0xbf, 0xca, 0xdd, 0xd9, 0xee, 0xe6, 0xe8, 0xf2, 0xfc, 0xff, 0xf9, 0xff, + 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf4, + 0x5d, 0x5e, 0x59, 0x5a, 0x57, 0x5a, 0x56, 0x50, 0x53, 0x56, 0x51, 0x53, + 0x51, 0x5c, 0x6a, 0x6d, 0x73, 0x77, 0x76, 0x8f, 0x97, 0x9e, 0xb0, 0xbd, + 0xcf, 0xdf, 0xf1, 0xff, 0xf9, 0xf0, 0xff, 0x3e, 0x2c, 0x30, 0x34, 0x52, + 0xe2, 0xff, 0xd9, 0xe2, 0xef, 0xf4, 0xea, 0xd1, 0xcb, 0xbe, 0xb5, 0xac, + 0xa2, 0x93, 0x8a, 0x91, 0x8d, 0x86, 0x82, 0x86, 0x80, 0x7c, 0x7c, 0x7d, + 0x73, 0x7b, 0x7d, 0x85, 0x88, 0x87, 0x91, 0x99, 0x9c, 0xa9, 0xb0, 0xc2, + 0xc7, 0xd5, 0xe1, 0xed, 0xf1, 0xfb, 0xf9, 0xf5, 0xf0, 0xf0, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf8, + 0x5c, 0x5b, 0x5a, 0x56, 0x58, 0x57, 0x56, 0x51, 0x4b, 0x53, 0x51, 0x54, + 0x5b, 0x5e, 0x60, 0x65, 0x66, 0x6c, 0x6b, 0x77, 0x82, 0x89, 0x95, 0x9a, + 0xa7, 0xb5, 0xca, 0xdb, 0xdb, 0xec, 0xd8, 0x4b, 0x4e, 0x2c, 0x67, 0x62, + 0xc8, 0xdd, 0xef, 0xd8, 0xcc, 0xde, 0xcb, 0xc5, 0xb7, 0xab, 0x9f, 0x98, + 0x92, 0x7c, 0x83, 0x81, 0x7c, 0x7c, 0x7a, 0x7b, 0x7a, 0x7c, 0x78, 0x75, + 0x70, 0x7b, 0x7d, 0x82, 0x8b, 0x8f, 0x97, 0x9b, 0xa9, 0xb2, 0xbf, 0xcb, + 0xd8, 0xe2, 0xf3, 0xe0, 0xed, 0xf9, 0xff, 0xf2, 0xfe, 0xe8, 0xff, 0xff, + 0xff, 0xfa, 0xf3, 0xfe, 0xff, 0xff, 0xff, 0xf9, 0xf9, 0xfe, 0xf2, 0xf5, + 0x58, 0x59, 0x56, 0x56, 0x54, 0x53, 0x51, 0x50, 0x4c, 0x4b, 0x50, 0x52, + 0x54, 0x56, 0x59, 0x5c, 0x5f, 0x61, 0x64, 0x5e, 0x6c, 0x75, 0x79, 0x7e, + 0x83, 0x8e, 0x9d, 0xa6, 0xad, 0xaf, 0xc4, 0x45, 0x56, 0x2d, 0x74, 0x5f, + 0xd8, 0xd9, 0xca, 0xb5, 0xbd, 0xb2, 0xab, 0xba, 0xb5, 0x94, 0x93, 0x8d, + 0x85, 0x73, 0x82, 0x7f, 0x79, 0x77, 0x77, 0x78, 0x75, 0x73, 0x73, 0x6c, + 0x79, 0x7b, 0x7e, 0x86, 0x8d, 0x92, 0x94, 0x9e, 0xa9, 0xb7, 0xc7, 0xcf, + 0xde, 0xdc, 0xe6, 0xe5, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, + 0xf9, 0xe9, 0xff, 0xff, 0xff, 0xef, 0xfd, 0xff, 0xff, 0xe0, 0xff, 0xf0, + 0x5b, 0x51, 0x50, 0x50, 0x4b, 0x4e, 0x4c, 0x4d, 0x4c, 0x48, 0x42, 0x43, + 0x42, 0x45, 0x46, 0x4a, 0x4c, 0x4c, 0x52, 0x4f, 0x5c, 0x61, 0x62, 0x68, + 0x6a, 0x71, 0x78, 0x7f, 0x84, 0x75, 0x8d, 0x48, 0x57, 0x2d, 0x74, 0x5d, + 0x9f, 0xa4, 0x96, 0x8c, 0x97, 0x8b, 0x8a, 0x77, 0x76, 0x6c, 0x82, 0x7a, + 0x76, 0x77, 0x79, 0x76, 0x71, 0x72, 0x73, 0x6f, 0x72, 0x78, 0x70, 0x77, + 0x7a, 0x79, 0x70, 0x63, 0x51, 0x49, 0x3d, 0x37, 0x33, 0x30, 0x2f, 0x2e, + 0x2b, 0x2c, 0x30, 0x31, 0x34, 0x3f, 0x45, 0x57, 0x6e, 0x89, 0xb1, 0xd7, + 0xf4, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xe9, 0xff, 0xf0, 0x89, + 0x53, 0x54, 0x4d, 0x4a, 0x4a, 0x4a, 0x47, 0x4a, 0x47, 0x47, 0x43, 0x39, + 0x3a, 0x39, 0x3a, 0x3a, 0x3b, 0x40, 0x42, 0x40, 0x50, 0x56, 0x59, 0x5a, + 0x5b, 0x5f, 0x5f, 0x62, 0x64, 0x59, 0x6a, 0x45, 0x53, 0x2e, 0x76, 0x53, + 0x7a, 0x77, 0x70, 0x6e, 0x71, 0x75, 0x72, 0x73, 0x72, 0x73, 0x75, 0x72, + 0x67, 0x6e, 0x71, 0x6e, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x73, 0x70, 0x72, + 0x3c, 0x1d, 0x17, 0x15, 0x13, 0x15, 0x12, 0x12, 0x13, 0x13, 0x12, 0x14, + 0x16, 0x15, 0x17, 0x16, 0x15, 0x18, 0x19, 0x1a, 0x1e, 0x1e, 0x24, 0x25, + 0x2c, 0x30, 0x33, 0x3a, 0x49, 0x91, 0xfb, 0xf5, 0xff, 0xb2, 0x60, 0x66, + 0x4f, 0x4d, 0x50, 0x49, 0x47, 0x48, 0x45, 0x49, 0x48, 0x47, 0x45, 0x40, + 0x3c, 0x37, 0x39, 0x36, 0x39, 0x39, 0x38, 0x3c, 0x43, 0x4b, 0x4c, 0x4e, + 0x4d, 0x4d, 0x4e, 0x4f, 0x53, 0x4c, 0x58, 0x46, 0x53, 0x2d, 0x77, 0x52, + 0x66, 0x63, 0x5f, 0x63, 0x68, 0x66, 0x68, 0x6b, 0x68, 0x6b, 0x6c, 0x67, + 0x62, 0x6b, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x70, 0x6e, 0x71, 0x2e, + 0x13, 0x11, 0x0f, 0x11, 0x10, 0x10, 0x12, 0x11, 0x11, 0x10, 0x11, 0x11, + 0x12, 0x12, 0x13, 0x14, 0x14, 0x13, 0x15, 0x15, 0x16, 0x17, 0x18, 0x1a, + 0x1b, 0x1c, 0x1f, 0x20, 0x22, 0x27, 0x5a, 0xd8, 0x6a, 0x4c, 0x4f, 0x4b, + 0x54, 0x53, 0x53, 0x54, 0x4e, 0x4a, 0x46, 0x48, 0x46, 0x43, 0x43, 0x40, + 0x3d, 0x3c, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x39, 0x48, 0x4a, 0x4b, + 0x4d, 0x49, 0x49, 0x46, 0x48, 0x46, 0x49, 0x47, 0x47, 0x2d, 0x6f, 0x53, + 0x58, 0x55, 0x50, 0x56, 0x57, 0x5c, 0x5c, 0x60, 0x61, 0x62, 0x63, 0x63, + 0x66, 0x68, 0x6c, 0x6d, 0x71, 0x6b, 0x6f, 0x73, 0x6b, 0x72, 0x5d, 0x14, + 0x10, 0x10, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x0e, 0x10, 0x10, 0x10, 0x10, + 0x11, 0x10, 0x11, 0x12, 0x11, 0x12, 0x11, 0x13, 0x12, 0x14, 0x15, 0x17, + 0x18, 0x18, 0x1a, 0x1a, 0x1c, 0x1d, 0x23, 0x45, 0x42, 0x40, 0x56, 0xa5, + 0x45, 0x43, 0x45, 0x4c, 0x4b, 0x49, 0x47, 0x47, 0x49, 0x46, 0x47, 0x46, + 0x43, 0x48, 0x48, 0x45, 0x46, 0x46, 0x49, 0x4a, 0x47, 0x44, 0x4c, 0x4f, + 0x4e, 0x49, 0x48, 0x45, 0x42, 0x40, 0x42, 0x42, 0x3d, 0x2e, 0x63, 0x54, + 0x53, 0x2f, 0x2a, 0x2d, 0x35, 0x40, 0x49, 0x50, 0x5a, 0x5e, 0x5f, 0x62, + 0x6d, 0x6c, 0x6f, 0x6e, 0x6c, 0x71, 0x70, 0x68, 0x70, 0x79, 0x38, 0x10, + 0x11, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x0f, 0x10, 0x10, 0x10, 0x11, 0x10, + 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x11, 0x13, 0x13, 0x15, 0x16, + 0x16, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1e, 0x3b, 0x50, 0x94, 0xbd, 0xbb, + 0x72, 0x74, 0x72, 0x74, 0x74, 0x75, 0x73, 0x73, 0x74, 0x77, 0x75, 0x78, + 0x78, 0x73, 0x75, 0x70, 0x71, 0x6d, 0x6d, 0x6b, 0x65, 0x5e, 0x6c, 0x77, + 0x77, 0x50, 0x5e, 0x62, 0x5c, 0x59, 0x53, 0x51, 0x4e, 0x45, 0x60, 0x56, + 0x51, 0x2e, 0x25, 0x23, 0x1f, 0x1e, 0x22, 0x23, 0x29, 0x2f, 0x40, 0x53, + 0x6d, 0x85, 0x8b, 0x8d, 0x7a, 0x7a, 0x77, 0x67, 0x81, 0x80, 0x26, 0x10, + 0x10, 0x10, 0x0e, 0x0f, 0x0e, 0x10, 0x0f, 0x10, 0x11, 0x10, 0x10, 0x11, + 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x12, 0x13, 0x13, 0x13, 0x15, + 0x15, 0x17, 0x16, 0x17, 0x18, 0x1a, 0x1e, 0x78, 0xba, 0xb7, 0xb4, 0xad, + 0x3b, 0x38, 0x36, 0x36, 0x33, 0x34, 0x32, 0x32, 0x36, 0x35, 0x38, 0x37, + 0x39, 0x3b, 0x3c, 0x3f, 0x45, 0x47, 0x4d, 0x54, 0x5e, 0x87, 0x7a, 0x7f, + 0x7e, 0x5f, 0x8d, 0x81, 0x8a, 0x87, 0x8f, 0x8f, 0x94, 0x93, 0x97, 0x97, + 0x8b, 0x30, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x29, 0x25, 0x24, 0x21, 0x1f, + 0x21, 0x40, 0x2e, 0x32, 0x3d, 0x4a, 0x53, 0x6c, 0x7b, 0x7c, 0x1e, 0x10, + 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x11, 0x12, 0x11, 0x10, 0x10, 0x12, 0x11, 0x12, 0x11, 0x12, 0x13, 0x13, + 0x15, 0x14, 0x16, 0x17, 0x17, 0x18, 0x1f, 0xa1, 0xb1, 0xac, 0xa1, 0x9d, + 0x9d, 0x95, 0x8c, 0x7c, 0x70, 0x6e, 0x6e, 0x60, 0x58, 0x57, 0x52, 0x51, + 0x51, 0x51, 0x4d, 0x4c, 0x4f, 0x4e, 0x4c, 0x4d, 0x52, 0x86, 0x7c, 0x81, + 0x7e, 0x61, 0x90, 0x4c, 0x47, 0x49, 0x47, 0x4c, 0x45, 0x46, 0x46, 0x46, + 0x47, 0x30, 0x2b, 0x2c, 0x2b, 0x2a, 0x2a, 0x29, 0x29, 0x27, 0x26, 0x26, + 0x27, 0x25, 0x24, 0x24, 0x21, 0x21, 0x20, 0x21, 0x26, 0x2a, 0x16, 0x10, + 0x10, 0x0f, 0x0f, 0x0e, 0x10, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, 0x13, 0x13, 0x14, + 0x15, 0x16, 0x15, 0x15, 0x16, 0x18, 0x20, 0x98, 0xa9, 0xa1, 0x9a, 0x97, + 0xe7, 0xde, 0xe4, 0xd1, 0xb4, 0x9e, 0x8e, 0x89, 0x72, 0x68, 0x61, 0x5e, + 0x5b, 0x5a, 0x58, 0x59, 0x58, 0x5d, 0x5e, 0x61, 0x6c, 0x89, 0x7a, 0x7d, + 0x7d, 0x65, 0x98, 0x63, 0x60, 0x6b, 0x5c, 0x76, 0xa7, 0xb4, 0xb0, 0xa5, + 0xb4, 0x37, 0x2b, 0x2d, 0x29, 0x2a, 0x29, 0x29, 0x27, 0x25, 0x29, 0x25, + 0x27, 0x25, 0x26, 0x26, 0x26, 0x25, 0x26, 0x25, 0x25, 0x20, 0x12, 0x0f, + 0x0f, 0x0f, 0x10, 0x10, 0x0d, 0x0f, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x10, + 0x10, 0x0e, 0x10, 0x11, 0x11, 0x11, 0x10, 0x10, 0x12, 0x10, 0x13, 0x13, + 0x12, 0x13, 0x13, 0x13, 0x15, 0x18, 0x1f, 0x90, 0x98, 0x99, 0x9d, 0xa0, + 0xff, 0xff, 0xf1, 0xe8, 0xd2, 0xcd, 0xba, 0xa6, 0x9d, 0x86, 0x7b, 0x73, + 0x6e, 0x67, 0x65, 0x66, 0x64, 0x67, 0x6b, 0x6c, 0x76, 0x87, 0x7d, 0x83, + 0x80, 0x62, 0x98, 0x6e, 0x62, 0x6a, 0x70, 0xf5, 0xdf, 0xee, 0xff, 0xf2, + 0xf7, 0x45, 0x2b, 0x2d, 0x2c, 0x2c, 0x2a, 0x2a, 0x29, 0x2a, 0x29, 0x29, + 0x27, 0x29, 0x27, 0x27, 0x27, 0x29, 0x26, 0x26, 0x26, 0x22, 0x11, 0x0f, + 0x10, 0x0d, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x0f, 0x0e, 0x10, + 0x10, 0x0f, 0x0f, 0x10, 0x12, 0x10, 0x10, 0x12, 0x12, 0x13, 0x13, 0x12, + 0x13, 0x13, 0x13, 0x15, 0x16, 0x17, 0x21, 0x89, 0x9b, 0xa1, 0xa6, 0xb4, + 0xff, 0xfb, 0xe0, 0xd7, 0xb8, 0x99, 0xd8, 0xd7, 0xc3, 0xb4, 0x9b, 0x8d, + 0x86, 0x7a, 0x74, 0x70, 0x6b, 0x6e, 0x70, 0x71, 0x7e, 0x83, 0x7a, 0x7d, + 0x80, 0x61, 0x96, 0x6f, 0x5f, 0x82, 0xe6, 0xfd, 0xff, 0xfd, 0xd3, 0xff, + 0xf3, 0x56, 0x2e, 0x2c, 0x2a, 0x2a, 0x2c, 0x2a, 0x2a, 0x2a, 0x29, 0x27, + 0x29, 0x29, 0x27, 0x27, 0x29, 0x26, 0x26, 0x26, 0x25, 0x20, 0x10, 0x0f, + 0x0f, 0x0f, 0x0d, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x0e, 0x10, 0x0e, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, + 0x12, 0x13, 0x14, 0x13, 0x14, 0x17, 0x22, 0x96, 0x9c, 0x99, 0x8e, 0x8b, + 0xf3, 0xf9, 0x9d, 0xa6, 0xa8, 0x9e, 0xcd, 0xdf, 0xde, 0xcf, 0xbb, 0xa9, + 0x9a, 0x8a, 0x86, 0x7c, 0x7a, 0x72, 0x7a, 0x7b, 0x87, 0x82, 0x79, 0x81, + 0x80, 0x62, 0x94, 0x6a, 0x7a, 0xff, 0xff, 0xff, 0xf4, 0xf8, 0xf5, 0xfe, + 0xf8, 0x64, 0x30, 0x2e, 0x2c, 0x2a, 0x2a, 0x29, 0x2b, 0x29, 0x2c, 0x2a, + 0x29, 0x29, 0x29, 0x29, 0x27, 0x27, 0x26, 0x29, 0x27, 0x20, 0x0f, 0x0f, + 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x10, + 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x0f, 0x10, 0x11, 0x10, 0x11, 0x12, 0x11, + 0x12, 0x13, 0x13, 0x12, 0x15, 0x15, 0x22, 0x54, 0x57, 0x5c, 0x66, 0x74, + 0xf9, 0xf5, 0x4a, 0x75, 0xff, 0xf4, 0xe7, 0xfd, 0xef, 0xe2, 0xce, 0xc7, + 0xb0, 0x9f, 0x92, 0x88, 0x8b, 0x80, 0x7e, 0x86, 0x88, 0x82, 0x7a, 0x7d, + 0x82, 0x62, 0x95, 0x85, 0xf7, 0xe9, 0xfb, 0xff, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0x6b, 0x2f, 0x2c, 0x2c, 0x2a, 0x2b, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, + 0x2a, 0x2a, 0x2a, 0x29, 0x29, 0x27, 0x26, 0x26, 0x26, 0x1f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0d, 0x0d, 0x0e, 0x0d, 0x0f, 0x0e, 0x10, 0x10, 0x0f, + 0x0f, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x0e, 0x11, 0x11, 0x11, 0x13, + 0x12, 0x11, 0x13, 0x12, 0x14, 0x17, 0x2d, 0xc6, 0xd8, 0xea, 0xfa, 0xe9, + 0xea, 0xec, 0x57, 0x7a, 0xb8, 0xe9, 0xff, 0xff, 0xff, 0xe8, 0xdb, 0xdd, + 0xcc, 0xb5, 0xa4, 0x98, 0x92, 0x8f, 0x88, 0x8f, 0x8c, 0x85, 0x7c, 0x81, + 0x7f, 0x60, 0x96, 0xdf, 0xff, 0xea, 0xf6, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x6e, 0x2f, 0x2f, 0x2b, 0x2c, 0x2d, 0x2b, 0x2b, 0x2c, 0x29, 0x2a, + 0x2c, 0x2b, 0x2b, 0x2c, 0x2a, 0x29, 0x29, 0x29, 0x29, 0x1c, 0x10, 0x0f, + 0x0e, 0x0e, 0x0e, 0x0d, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, + 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, + 0x12, 0x11, 0x12, 0x11, 0x12, 0x17, 0x39, 0xf1, 0xdc, 0xf4, 0xf3, 0xff, + 0x5d, 0x4a, 0x3c, 0x64, 0xea, 0xef, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xf4, + 0xde, 0xc9, 0xb3, 0xa9, 0x9f, 0x96, 0x90, 0x7d, 0x5d, 0x89, 0x7d, 0x7e, + 0x81, 0x61, 0x98, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x6d, 0x30, 0x2f, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2d, 0x2c, 0x2c, + 0x2b, 0x2d, 0x2c, 0x2c, 0x2c, 0x2c, 0x2b, 0x2a, 0x2b, 0x1b, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f, + 0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x12, 0x12, 0x12, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x12, 0x15, 0x1a, 0x57, 0xf5, 0xf3, 0xff, 0xff, 0xff, + 0x7e, 0x32, 0x2e, 0x62, 0xe6, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xee, 0xe1, + 0xf9, 0xe9, 0xce, 0xbb, 0xb0, 0x98, 0x59, 0x55, 0x59, 0x88, 0x7d, 0x83, + 0x80, 0x5f, 0x96, 0xec, 0xff, 0xf8, 0xfb, 0xff, 0xff, 0xe7, 0xd5, 0xf4, + 0xff, 0x6f, 0x2e, 0x2e, 0x2d, 0x2c, 0x29, 0x2c, 0x2b, 0x2c, 0x2d, 0x2d, + 0x2d, 0x2c, 0x2d, 0x2d, 0x2c, 0x2c, 0x2d, 0x2a, 0x2a, 0x19, 0x0f, 0x0e, + 0x0e, 0x0e, 0x0d, 0x0d, 0x0e, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, 0x0f, 0x0d, + 0x0e, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x12, 0x0f, 0x10, 0x11, + 0x12, 0x12, 0x12, 0x11, 0x14, 0x1b, 0x86, 0xff, 0xf8, 0xff, 0xff, 0xe7, + 0x2b, 0x24, 0x3a, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xe8, 0xf6, + 0xf4, 0xf7, 0xdc, 0xda, 0xc4, 0x72, 0x63, 0x67, 0x6f, 0x87, 0x7e, 0x81, + 0x7c, 0x60, 0x98, 0xe4, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xd7, 0x63, 0xc7, + 0xff, 0x6c, 0x2e, 0x2d, 0x2e, 0x2c, 0x2c, 0x2b, 0x2e, 0x2c, 0x2c, 0x2e, + 0x2e, 0x2f, 0x2e, 0x2d, 0x2d, 0x2b, 0x2c, 0x2b, 0x2a, 0x18, 0x0e, 0x0d, + 0x0f, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x10, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x12, 0x11, 0x11, 0x12, + 0x12, 0x12, 0x12, 0x13, 0x15, 0x1e, 0xbc, 0xf0, 0xff, 0xff, 0xfb, 0xfd, + 0x27, 0x24, 0x3f, 0x54, 0x86, 0x9e, 0xad, 0xa0, 0xb5, 0xbc, 0xc5, 0xc6, + 0xbe, 0xbe, 0x97, 0x93, 0x91, 0x8a, 0x8b, 0x8d, 0x8b, 0x80, 0x7e, 0x7f, + 0x7d, 0x5b, 0x90, 0xb4, 0xd4, 0xe8, 0xe6, 0xf4, 0xf8, 0xc9, 0x73, 0xb6, + 0xe8, 0x5c, 0x2b, 0x2e, 0x2d, 0x2b, 0x2b, 0x2c, 0x2d, 0x2d, 0x2e, 0x30, + 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x2c, 0x2b, 0x2d, 0x27, 0x15, 0x0e, 0x0f, + 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, 0x0d, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x11, 0x11, 0x10, + 0x13, 0x12, 0x13, 0x14, 0x15, 0x1d, 0xce, 0xff, 0xea, 0xfb, 0xff, 0xea, + 0x22, 0x20, 0x29, 0x59, 0x70, 0x7b, 0x82, 0x88, 0x92, 0x9b, 0xab, 0xaf, + 0xb4, 0xb1, 0x72, 0x6f, 0x6f, 0x6f, 0x73, 0x74, 0x72, 0x68, 0x79, 0x7e, + 0x7d, 0x4f, 0x75, 0x80, 0x84, 0x86, 0x89, 0x8c, 0x8d, 0x83, 0x7b, 0x72, + 0x68, 0x34, 0x27, 0x2f, 0x2d, 0x2b, 0x2d, 0x2d, 0x2d, 0x2f, 0x2d, 0x2d, + 0x2f, 0x2f, 0x30, 0x2e, 0x2f, 0x2f, 0x2d, 0x2c, 0x29, 0x14, 0x0f, 0x0e, + 0x0e, 0x0e, 0x0f, 0x0e, 0x0e, 0x0f, 0x0e, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, + 0x0f, 0x0e, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, 0x11, + 0x10, 0x12, 0x13, 0x14, 0x15, 0x1d, 0xa2, 0xf7, 0xed, 0xe3, 0xd8, 0xca, + 0x1f, 0x20, 0x2c, 0x49, 0x65, 0x6c, 0x77, 0x7d, 0x85, 0x89, 0x8e, 0xa0, + 0xab, 0xac, 0x6c, 0x6c, 0x66, 0x6c, 0x67, 0x6d, 0x67, 0x5e, 0x73, 0x7d, + 0x79, 0x4d, 0x5e, 0x66, 0x65, 0x66, 0x66, 0x61, 0x61, 0x5c, 0x5a, 0x56, + 0x4e, 0x30, 0x26, 0x2a, 0x29, 0x2b, 0x2c, 0x2d, 0x2c, 0x30, 0x2f, 0x2e, + 0x2f, 0x30, 0x2f, 0x2e, 0x30, 0x2e, 0x2c, 0x2c, 0x2a, 0x15, 0x0f, 0x10, + 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0d, 0x0e, 0x0f, 0x0f, 0x0e, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x10, 0x0f, 0x10, 0x10, 0x11, 0x10, 0x12, + 0x12, 0x13, 0x13, 0x12, 0x15, 0x1c, 0x7e, 0xcc, 0xd3, 0xc0, 0xc4, 0xb9, + 0x1e, 0x1b, 0x2a, 0x44, 0x66, 0x64, 0x56, 0x5d, 0x64, 0x77, 0x9e, 0xa6, + 0xab, 0xab, 0x6b, 0x67, 0x64, 0x6b, 0x6b, 0x6a, 0x67, 0x60, 0x71, 0x81, + 0x7b, 0x4b, 0x5b, 0x65, 0x65, 0x64, 0x63, 0x62, 0x5f, 0x5d, 0x5a, 0x52, + 0x50, 0x2c, 0x21, 0x25, 0x27, 0x29, 0x27, 0x2b, 0x2c, 0x2c, 0x2d, 0x2f, + 0x2d, 0x2e, 0x2e, 0x2f, 0x2f, 0x2e, 0x2e, 0x2d, 0x2a, 0x11, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x15, 0x1a, 0x63, 0x9e, 0xac, 0x8e, 0x72, 0x62, + 0x1f, 0x1f, 0x44, 0x4c, 0x64, 0x70, 0x6e, 0x77, 0x7d, 0x82, 0x9b, 0xa7, + 0xa6, 0xa4, 0x67, 0x6a, 0x66, 0x64, 0x6a, 0x68, 0x67, 0x5d, 0x73, 0x7b, + 0x78, 0x48, 0x58, 0x65, 0x62, 0x63, 0x5f, 0x5e, 0x5f, 0x5d, 0x57, 0x53, + 0x52, 0x2f, 0x20, 0x20, 0x20, 0x21, 0x22, 0x23, 0x22, 0x26, 0x26, 0x29, + 0x2b, 0x2b, 0x2b, 0x2c, 0x2d, 0x29, 0x2c, 0x2b, 0x29, 0x12, 0x0f, 0x0f, + 0x10, 0x0f, 0x0e, 0x0f, 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x0e, 0x10, 0x0f, + 0x10, 0x0e, 0x10, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, + 0x12, 0x11, 0x13, 0x14, 0x16, 0x1b, 0x4e, 0x74, 0x74, 0x70, 0x68, 0x5e, + 0x1d, 0x2b, 0x48, 0x54, 0x63, 0x70, 0x7a, 0x82, 0x7e, 0x82, 0x99, 0x9e, + 0x9f, 0xa4, 0x68, 0x65, 0x64, 0x66, 0x64, 0x67, 0x64, 0x5a, 0x6e, 0x77, + 0x77, 0x47, 0x5a, 0x60, 0x62, 0x62, 0x60, 0x61, 0x5d, 0x58, 0x58, 0x54, + 0x4f, 0x48, 0x3f, 0x39, 0x33, 0x31, 0x2d, 0x29, 0x20, 0x1d, 0x15, 0x17, + 0x17, 0x1c, 0x20, 0x1f, 0x1f, 0x20, 0x1f, 0x1e, 0x1e, 0x10, 0x0f, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, + 0x0e, 0x0f, 0x0e, 0x0f, 0x10, 0x0e, 0x10, 0x0f, 0x10, 0x10, 0x10, 0x12, + 0x12, 0x12, 0x13, 0x13, 0x14, 0x1a, 0x4e, 0x6f, 0x6e, 0x6b, 0x68, 0x6a, + 0x21, 0x33, 0x4b, 0x57, 0x5e, 0x6b, 0x6e, 0x7e, 0x82, 0x76, 0x91, 0x9a, + 0x9d, 0x9d, 0x64, 0x64, 0x64, 0x64, 0x65, 0x67, 0x65, 0x5a, 0x67, 0x76, + 0x73, 0x47, 0x59, 0x62, 0x61, 0x5f, 0x61, 0x60, 0x5c, 0x5a, 0x58, 0x56, + 0x4f, 0x4a, 0x46, 0x42, 0x3f, 0x3c, 0x38, 0x38, 0x2c, 0x23, 0x12, 0x10, + 0x12, 0x27, 0x2b, 0x2f, 0x2b, 0x29, 0x27, 0x27, 0x24, 0x11, 0x10, 0x0e, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0d, + 0x0e, 0x0e, 0x0f, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x0f, 0x11, 0x12, 0x12, + 0x12, 0x12, 0x13, 0x14, 0x15, 0x18, 0x50, 0x6d, 0x72, 0x68, 0x67, 0x63, + 0x22, 0x3d, 0x50, 0x55, 0x61, 0x6c, 0x79, 0x83, 0x84, 0x7b, 0x91, 0x9b, + 0xa0, 0x9e, 0x61, 0x60, 0x66, 0x64, 0x64, 0x61, 0x63, 0x5a, 0x66, 0x71, + 0x6f, 0x40, 0x57, 0x61, 0x63, 0x61, 0x5f, 0x60, 0x5c, 0x59, 0x58, 0x54, + 0x52, 0x4e, 0x49, 0x42, 0x40, 0x3b, 0x39, 0x36, 0x32, 0x1e, 0x19, 0x1c, + 0x1a, 0x2a, 0x2d, 0x2f, 0x2d, 0x2c, 0x2c, 0x2b, 0x25, 0x11, 0x0f, 0x10, + 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, 0x0e, + 0x0f, 0x0f, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x0f, 0x11, 0x11, 0x10, 0x11, + 0x11, 0x14, 0x11, 0x12, 0x14, 0x1b, 0x55, 0x6e, 0x6d, 0x6b, 0x6a, 0x61, + 0x2c, 0x3d, 0x4e, 0x58, 0x6e, 0x7a, 0x75, 0x71, 0x75, 0x87, 0x90, 0x9a, + 0x9b, 0x98, 0x63, 0x61, 0x63, 0x61, 0x65, 0x61, 0x60, 0x59, 0x63, 0x6d, + 0x68, 0x40, 0x57, 0x60, 0x61, 0x5f, 0x61, 0x5d, 0x5b, 0x59, 0x58, 0x59, + 0x54, 0x4c, 0x49, 0x43, 0x42, 0x3a, 0x38, 0x37, 0x35, 0x25, 0x17, 0x1d, + 0x1a, 0x2d, 0x32, 0x34, 0x33, 0x34, 0x32, 0x31, 0x2b, 0x11, 0x0e, 0x0d, + 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, + 0x0f, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12, + 0x11, 0x12, 0x13, 0x13, 0x12, 0x16, 0x52, 0x6d, 0x6a, 0x6a, 0x64, 0x61, + 0x38, 0x35, 0x35, 0x4d, 0xa7, 0x9e, 0x52, 0x60, 0x5f, 0x54, 0x53, 0x5a, + 0x5b, 0x5d, 0x60, 0x62, 0x60, 0x61, 0x63, 0x60, 0x60, 0x58, 0x62, 0x6b, + 0x60, 0x3c, 0x4e, 0x58, 0x59, 0x5d, 0x5c, 0x5a, 0x59, 0x59, 0x58, 0x54, + 0x4f, 0x4e, 0x48, 0x44, 0x43, 0x3a, 0x3a, 0x38, 0x36, 0x2b, 0x17, 0x17, + 0x1b, 0x35, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x39, 0x30, 0x12, 0x10, 0x0f, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0d, 0x0e, 0x0d, + 0x0e, 0x0f, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, 0x10, 0x11, 0x12, 0x10, 0x12, + 0x12, 0x12, 0x14, 0x12, 0x16, 0x1a, 0x50, 0x6d, 0x6b, 0x68, 0x64, 0x62, + 0x32, 0x32, 0x38, 0x8b, 0xa2, 0x92, 0x4b, 0x4a, 0x4e, 0x49, 0x53, 0x58, + 0x5c, 0x5c, 0x5e, 0x5c, 0x62, 0x5f, 0x5d, 0x5f, 0x5e, 0x56, 0x5e, 0x5d, + 0x2b, 0x1f, 0x21, 0x23, 0x22, 0x23, 0x24, 0x23, 0x24, 0x26, 0x25, 0x24, + 0x26, 0x23, 0x22, 0x25, 0x22, 0x23, 0x23, 0x23, 0x25, 0x27, 0x1e, 0x19, + 0x19, 0x21, 0x26, 0x25, 0x26, 0x27, 0x24, 0x27, 0x1d, 0x12, 0x11, 0x10, + 0x0f, 0x10, 0x0f, 0x0f, 0x10, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0e, 0x10, 0x10, 0x10, 0x11, 0x12, 0x11, 0x12, 0x13, + 0x13, 0x13, 0x14, 0x14, 0x17, 0x1b, 0x6b, 0x92, 0x91, 0x73, 0x60, 0x5e, + 0x26, 0x32, 0x45, 0x9a, 0x9d, 0x92, 0x4c, 0x4d, 0x4e, 0x4c, 0x53, 0x57, + 0x58, 0x5b, 0x5e, 0x5f, 0x5f, 0x59, 0x55, 0x51, 0x53, 0x50, 0x5c, 0x5b, + 0x1a, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x13, 0x12, + 0x13, 0x13, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x10, 0x11, 0x13, 0x11, + 0x10, 0x11, 0x12, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, 0x12, 0x10, 0x0f, + 0x0e, 0x10, 0x0f, 0x0e, 0x0f, 0x0e, 0x10, 0x0e, 0x0e, 0x0e, 0x10, 0x10, + 0x0f, 0x0e, 0x0f, 0x10, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, + 0x14, 0x14, 0x14, 0x12, 0x18, 0x1a, 0x37, 0x48, 0x4e, 0x47, 0x41, 0x42, + 0x5e, 0x61, 0x7d, 0x94, 0x96, 0x97, 0x4d, 0x4d, 0x52, 0x46, 0x51, 0x54, + 0x57, 0x5b, 0x5c, 0x5b, 0x5c, 0x50, 0x43, 0x40, 0x42, 0x3a, 0x31, 0x5b, + 0x41, 0x13, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, + 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0d, + 0x0c, 0x0e, 0x0e, 0x0e, 0x10, 0x10, 0x0f, 0x0f, 0x11, 0x12, 0x12, 0x11, + 0x10, 0x11, 0x11, 0x10, 0x10, 0x10, 0x11, 0x10, 0x0f, 0x10, 0x10, 0x11, + 0x10, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x15, 0x13, 0x15, 0x16, + 0x16, 0x16, 0x16, 0x15, 0x17, 0x19, 0x22, 0x29, 0x29, 0x20, 0x1c, 0x1a, + 0x70, 0x7b, 0x8a, 0x8e, 0x8e, 0x8c, 0x62, 0x5c, 0x56, 0x48, 0x4e, 0x53, + 0x57, 0x58, 0x58, 0x56, 0x5b, 0x53, 0x51, 0x50, 0x4f, 0x40, 0x20, 0x2a, + 0x4a, 0x2e, 0x15, 0x0e, 0x1f, 0x21, 0x17, 0x10, 0x10, 0x0f, 0x0f, 0x0f, + 0x15, 0x11, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, + 0x0c, 0x12, 0x17, 0x17, 0x18, 0x18, 0x18, 0x11, 0x10, 0x13, 0x12, 0x13, + 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x17, + 0x18, 0x17, 0x17, 0x15, 0x19, 0x1b, 0x1b, 0x1a, 0x19, 0x1a, 0x16, 0x11, + 0x4c, 0x5e, 0x7c, 0x93, 0x91, 0x99, 0x93, 0x85, 0x79, 0x71, 0x49, 0x47, + 0x4a, 0x48, 0x4b, 0x4b, 0x4c, 0x4e, 0x51, 0x4f, 0x4e, 0x3d, 0x18, 0x1a, + 0x23, 0x29, 0x2a, 0x0f, 0x0e, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, + 0x0e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0e, + 0x0b, 0x0d, 0x0c, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0f, 0x13, 0x13, 0x12, + 0x10, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x13, 0x14, + 0x13, 0x13, 0x12, 0x13, 0x14, 0x13, 0x14, 0x17, 0x15, 0x17, 0x18, 0x19, + 0x19, 0x19, 0x19, 0x15, 0x19, 0x1b, 0x14, 0x0c, 0x0e, 0x0f, 0x0e, 0x0e, + 0x19, 0x1b, 0x22, 0x27, 0x25, 0x26, 0x2b, 0x29, 0x31, 0x47, 0x43, 0x45, + 0x4a, 0x4e, 0x51, 0x51, 0x52, 0x50, 0x4c, 0x4c, 0x4b, 0x3c, 0x17, 0x19, + 0x1e, 0x24, 0x30, 0x11, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f, 0x10, + 0x10, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0e, 0x0d, 0x0e, 0x14, 0x13, 0x14, + 0x11, 0x14, 0x15, 0x14, 0x13, 0x15, 0x14, 0x15, 0x14, 0x14, 0x14, 0x14, + 0x15, 0x13, 0x12, 0x13, 0x15, 0x14, 0x14, 0x16, 0x18, 0x19, 0x1a, 0x19, + 0x1a, 0x1a, 0x1b, 0x16, 0x1a, 0x1c, 0x16, 0x0e, 0x10, 0x10, 0x0e, 0x0d, + 0x0f, 0x0e, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x13, 0x17, 0x18, + 0x1d, 0x27, 0x3c, 0x44, 0x48, 0x49, 0x47, 0x4a, 0x48, 0x39, 0x16, 0x16, + 0x19, 0x1d, 0x2b, 0x1a, 0x0f, 0x0e, 0x0f, 0x0d, 0x0e, 0x0d, 0x0d, 0x0c, + 0x0e, 0x0e, 0x0e, 0x0f, 0x0d, 0x0e, 0x0d, 0x0e, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0d, 0x0c, 0x0d, 0x0d, 0x0c, 0x0a, 0x0d, 0x0f, 0x11, 0x14, 0x14, 0x15, + 0x11, 0x18, 0x15, 0x16, 0x15, 0x16, 0x15, 0x17, 0x16, 0x16, 0x15, 0x14, + 0x16, 0x16, 0x15, 0x16, 0x14, 0x15, 0x17, 0x17, 0x18, 0x1a, 0x1b, 0x1b, + 0x1a, 0x1b, 0x1b, 0x17, 0x1d, 0x1e, 0x18, 0x0e, 0x10, 0x12, 0x10, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, 0x0c, 0x0f, 0x0f, 0x10, 0x0e, 0x11, + 0x11, 0x12, 0x15, 0x18, 0x1f, 0x3c, 0x47, 0x46, 0x49, 0x3c, 0x16, 0x14, + 0x15, 0x1b, 0x24, 0x1e, 0x14, 0x11, 0x10, 0x10, 0x0e, 0x0f, 0x0d, 0x10, + 0x0f, 0x10, 0x11, 0x10, 0x11, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, + 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0f, 0x10, 0x13, 0x16, 0x15, 0x15, + 0x11, 0x17, 0x18, 0x16, 0x16, 0x17, 0x16, 0x18, 0x18, 0x16, 0x16, 0x18, + 0x16, 0x16, 0x15, 0x17, 0x16, 0x15, 0x17, 0x18, 0x1a, 0x1a, 0x1b, 0x1b, + 0x1c, 0x1a, 0x1d, 0x19, 0x1d, 0x1e, 0x19, 0x0f, 0x16, 0x1b, 0x1c, 0x12, + 0x19, 0x16, 0x0f, 0x0e, 0x0d, 0x0d, 0x0c, 0x12, 0x14, 0x13, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x13, 0x17, 0x2e, 0x43, 0x43, 0x46, 0x3d, 0x16, 0x12, + 0x15, 0x19, 0x22, 0x1c, 0x1a, 0x17, 0x17, 0x12, 0x0e, 0x0f, 0x0e, 0x0f, + 0x0f, 0x10, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x0f, 0x0e, 0x10, 0x0f, 0x0c, + 0x0e, 0x0e, 0x0e, 0x0d, 0x0f, 0x13, 0x0f, 0x10, 0x12, 0x16, 0x16, 0x15, + 0x12, 0x17, 0x17, 0x18, 0x18, 0x17, 0x17, 0x15, 0x16, 0x18, 0x17, 0x17, + 0x18, 0x18, 0x17, 0x18, 0x16, 0x16, 0x18, 0x18, 0x19, 0x1a, 0x19, 0x1c, + 0x1c, 0x1b, 0x1a, 0x18, 0x1d, 0x1f, 0x1a, 0x19, 0x1c, 0x27, 0x2b, 0x14, + 0x1f, 0x20, 0x1c, 0x16, 0x0e, 0x0d, 0x0d, 0x0e, 0x14, 0x17, 0x16, 0x14, + 0x14, 0x14, 0x13, 0x11, 0x15, 0x2b, 0x44, 0x42, 0x41, 0x39, 0x15, 0x12, + 0x12, 0x15, 0x1e, 0x1b, 0x1b, 0x1a, 0x19, 0x15, 0x10, 0x0f, 0x0e, 0x0e, + 0x0e, 0x0d, 0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0a, 0x0b, 0x0c, 0x0b, 0x0a, + 0x0b, 0x0b, 0x0b, 0x0b, 0x10, 0x13, 0x10, 0x0b, 0x0f, 0x17, 0x16, 0x16, + 0x12, 0x19, 0x19, 0x18, 0x18, 0x19, 0x17, 0x18, 0x18, 0x18, 0x19, 0x19, + 0x18, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x1b, 0x1a, 0x1b, 0x1c, + 0x1c, 0x1c, 0x1d, 0x19, 0x1c, 0x1f, 0x1c, 0x19, 0x1f, 0x2a, 0x2f, 0x15, + 0x15, 0x14, 0x14, 0x0f, 0x0e, 0x0d, 0x0e, 0x0e, 0x10, 0x10, 0x14, 0x13, + 0x14, 0x10, 0x10, 0x11, 0x15, 0x2a, 0x40, 0x41, 0x42, 0x38, 0x16, 0x10, + 0x12, 0x15, 0x1a, 0x1c, 0x1b, 0x1d, 0x1c, 0x19, 0x11, 0x0f, 0x10, 0x0e, + 0x0f, 0x0e, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0c, 0x0a, 0x0a, 0x0c, 0x11, 0x14, 0x10, 0x0c, 0x11, 0x18, 0x16, 0x17, + 0x13, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x18, 0x18, 0x19, 0x18, + 0x19, 0x18, 0x19, 0x19, 0x18, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1d, 0x18, 0x1e, 0x20, 0x1d, 0x1b, 0x21, 0x2c, 0x2c, 0x15, + 0x11, 0x13, 0x11, 0x10, 0x10, 0x0f, 0x0e, 0x0e, 0x10, 0x10, 0x13, 0x12, + 0x0f, 0x0d, 0x0d, 0x0f, 0x15, 0x27, 0x40, 0x3e, 0x40, 0x38, 0x16, 0x10, + 0x11, 0x14, 0x1b, 0x1b, 0x1c, 0x1d, 0x1c, 0x19, 0x0f, 0x0f, 0x0f, 0x10, + 0x0d, 0x0e, 0x0e, 0x0e, 0x0c, 0x0c, 0x0c, 0x0e, 0x0d, 0x0e, 0x0d, 0x0d, + 0x0e, 0x0d, 0x0e, 0x0e, 0x11, 0x12, 0x10, 0x0f, 0x11, 0x18, 0x17, 0x17, + 0x14, 0x17, 0x17, 0x18, 0x17, 0x16, 0x17, 0x17, 0x18, 0x16, 0x17, 0x18, + 0x18, 0x17, 0x18, 0x18, 0x17, 0x18, 0x17, 0x17, 0x19, 0x1b, 0x19, 0x1b, + 0x1a, 0x1c, 0x1c, 0x18, 0x1d, 0x1e, 0x1f, 0x17, 0x22, 0x2e, 0x2a, 0x14, + 0x10, 0x11, 0x0f, 0x10, 0x0f, 0x0c, 0x0e, 0x12, 0x15, 0x16, 0x17, 0x14, + 0x0f, 0x0f, 0x0f, 0x12, 0x14, 0x26, 0x3b, 0x3d, 0x3f, 0x37, 0x17, 0x13, + 0x12, 0x12, 0x19, 0x1b, 0x1d, 0x1e, 0x1e, 0x1b, 0x12, 0x12, 0x12, 0x0e, + 0x10, 0x11, 0x10, 0x0f, 0x11, 0x11, 0x11, 0x0f, 0x11, 0x13, 0x10, 0x12, + 0x11, 0x11, 0x0f, 0x11, 0x13, 0x14, 0x12, 0x13, 0x12, 0x17, 0x17, 0x18, + 0x15, 0x14, 0x17, 0x16, 0x18, 0x15, 0x16, 0x16, 0x16, 0x17, 0x18, 0x18, + 0x16, 0x16, 0x17, 0x17, 0x16, 0x17, 0x18, 0x17, 0x19, 0x1a, 0x1a, 0x1b, + 0x1c, 0x1c, 0x19, 0x19, 0x1e, 0x1e, 0x1d, 0x19, 0x23, 0x2d, 0x2b, 0x13, + 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0d, 0x16, 0x17, 0x18, 0x18, 0x15, + 0x0e, 0x0e, 0x0f, 0x11, 0x14, 0x22, 0x38, 0x39, 0x39, 0x33, 0x15, 0x12, + 0x10, 0x12, 0x17, 0x1b, 0x1e, 0x1f, 0x20, 0x1b, 0x13, 0x11, 0x11, 0x10, + 0x14, 0x14, 0x14, 0x13, 0x12, 0x14, 0x13, 0x14, 0x13, 0x15, 0x12, 0x15, + 0x14, 0x13, 0x12, 0x14, 0x13, 0x12, 0x11, 0x15, 0x11, 0x16, 0x19, 0x17, + 0x16, 0x15, 0x12, 0x11, 0x12, 0x11, 0x10, 0x11, 0x11, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x13, 0x14, + 0x14, 0x16, 0x19, 0x1a, 0x1d, 0x1d, 0x1c, 0x17, 0x21, 0x29, 0x27, 0x17, + 0x0c, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x14, 0x18, 0x17, 0x17, 0x16, + 0x11, 0x12, 0x12, 0x15, 0x17, 0x22, 0x35, 0x35, 0x37, 0x32, 0x16, 0x13, + 0x13, 0x12, 0x19, 0x1a, 0x1e, 0x20, 0x1e, 0x1c, 0x14, 0x13, 0x11, 0x15, + 0x17, 0x14, 0x17, 0x16, 0x17, 0x17, 0x16, 0x16, 0x18, 0x18, 0x13, 0x17, + 0x19, 0x18, 0x15, 0x16, 0x14, 0x11, 0x13, 0x17, 0x13, 0x18, 0x18, 0x17, + 0x17, 0x15, 0x15, 0x15, 0x16, 0x16, 0x15, 0x15, 0x15, 0x15, 0x14, 0x13, + 0x13, 0x15, 0x14, 0x15, 0x14, 0x14, 0x15, 0x16, 0x15, 0x16, 0x16, 0x17, + 0x19, 0x19, 0x19, 0x1b, 0x1b, 0x1c, 0x1c, 0x17, 0x10, 0x0c, 0x0d, 0x0c, + 0x0f, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x14, 0x15, 0x17, 0x17, 0x16, + 0x17, 0x17, 0x16, 0x18, 0x1f, 0x1e, 0x2d, 0x31, 0x34, 0x2f, 0x17, 0x12, + 0x11, 0x12, 0x17, 0x18, 0x1f, 0x21, 0x21, 0x1d, 0x13, 0x11, 0x13, 0x15, + 0x16, 0x18, 0x17, 0x16, 0x16, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x17, + 0x17, 0x18, 0x16, 0x17, 0x14, 0x10, 0x11, 0x19, 0x17, 0x15, 0x14, 0x17, + 0x16, 0x10, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, + 0x0e, 0x0d, 0x0e, 0x0d, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x16, 0x1a, 0x1b, 0x1a, 0x14, 0x10, 0x0c, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0e, 0x12, 0x1c, 0x1b, 0x26, 0x2c, 0x30, 0x2c, 0x16, 0x12, + 0x11, 0x11, 0x15, 0x19, 0x1f, 0x20, 0x21, 0x1d, 0x12, 0x0f, 0x14, 0x17, + 0x18, 0x17, 0x17, 0x17, 0x17, 0x18, 0x17, 0x17, 0x18, 0x14, 0x17, 0x16, + 0x18, 0x18, 0x16, 0x15, 0x12, 0x10, 0x11, 0x18, 0x1c, 0x17, 0x16, 0x15, + 0x15, 0x0d, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x0e, + 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0d, 0x0e, 0x0d, 0x0d, 0x0c, 0x0d, + 0x0c, 0x0e, 0x0e, 0x12, 0x19, 0x1a, 0x16, 0x14, 0x10, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0d, + 0x0d, 0x0d, 0x0e, 0x11, 0x1c, 0x1b, 0x25, 0x26, 0x2b, 0x2c, 0x17, 0x12, + 0x12, 0x11, 0x17, 0x1a, 0x21, 0x22, 0x21, 0x1f, 0x13, 0x0f, 0x14, 0x16, + 0x17, 0x18, 0x17, 0x16, 0x18, 0x19, 0x17, 0x19, 0x17, 0x16, 0x16, 0x18, + 0x17, 0x18, 0x17, 0x14, 0x12, 0x13, 0x11, 0x1a, 0x1e, 0x14, 0x13, 0x13, + 0x15, 0x11, 0x0d, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x10, 0x10, 0x10, 0x10, 0x0d, 0x10, 0x0f, 0x0f, 0x0f, 0x0d, 0x0d, + 0x0e, 0x0e, 0x0e, 0x13, 0x18, 0x16, 0x16, 0x16, 0x0f, 0x0c, 0x0c, 0x0c, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a, + 0x0c, 0x0b, 0x0c, 0x0f, 0x18, 0x18, 0x1f, 0x24, 0x25, 0x25, 0x15, 0x11, + 0x10, 0x10, 0x16, 0x17, 0x20, 0x1e, 0x1f, 0x1d, 0x0e, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0e, 0x0f, 0x0e, 0x15, 0x16, 0x18, 0x18, 0x14, 0x16, 0x17, 0x17, + 0x18, 0x17, 0x16, 0x14, 0x13, 0x11, 0x11, 0x12, 0x16, 0x10, 0x0f, 0x0f, + 0x0e, 0x0f, 0x0d, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0d, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, 0x0d, 0x0e, 0x0e, 0x0b, 0x0c, 0x0b, 0x0c, + 0x0d, 0x10, 0x0e, 0x10, 0x0f, 0x10, 0x10, 0x11, 0x0e, 0x0a, 0x0b, 0x0b, + 0x0e, 0x0c, 0x0e, 0x0e, 0x0e, 0x0d, 0x0e, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x10, 0x18, 0x18, 0x1e, 0x22, 0x25, 0x23, 0x16, 0x11, + 0x11, 0x12, 0x16, 0x19, 0x20, 0x21, 0x1f, 0x1b, 0x10, 0x0f, 0x11, 0x10, + 0x0e, 0x10, 0x0f, 0x0f, 0x10, 0x16, 0x17, 0x16, 0x15, 0x19, 0x18, 0x17, + 0x17, 0x18, 0x16, 0x14, 0x12, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, 0x0e, 0x0c, + 0x0d, 0x0d, 0x11, 0x0c, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0d, 0x0c, + 0x0e, 0x0c, 0x0d, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0f, + 0x0f, 0x10, 0x10, 0x0f, 0x0e, 0x0f, 0x0d, 0x0d, 0x0e, 0x0c, 0x0c, 0x0d, + 0x11, 0x12, 0x15, 0x15, 0x16, 0x15, 0x0d, 0x0c, 0x0d, 0x0c, 0x0d, 0x0c, + 0x0b, 0x0c, 0x0c, 0x0f, 0x19, 0x19, 0x1f, 0x22, 0x25, 0x22, 0x16, 0x11, + 0x11, 0x10, 0x18, 0x18, 0x1f, 0x21, 0x1e, 0x18, 0x13, 0x12, 0x14, 0x13, + 0x13, 0x14, 0x13, 0x13, 0x13, 0x14, 0x17, 0x16, 0x18, 0x18, 0x18, 0x19, + 0x16, 0x17, 0x17, 0x16, 0x17, 0x13, 0x13, 0x15, 0x12, 0x0c, 0x0d, 0x0d, + 0x0d, 0x0e, 0x0f, 0x14, 0x0d, 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0d, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0c, 0x0b, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x10, + 0x12, 0x11, 0x0f, 0x0e, 0x0e, 0x0d, 0x0b, 0x0c, 0x0d, 0x0b, 0x0d, 0x0a, + 0x2b, 0x27, 0x26, 0x21, 0x1b, 0x16, 0x0e, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0e, 0x18, 0x15, 0x1c, 0x20, 0x22, 0x22, 0x14, 0x11, + 0x0f, 0x10, 0x16, 0x16, 0x1d, 0x1d, 0x1b, 0x15, 0x0e, 0x0d, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0a, 0x0b, 0x0c, 0x10, 0x12, 0x14, 0x15, 0x17, 0x18, 0x17, + 0x16, 0x16, 0x18, 0x18, 0x18, 0x14, 0x16, 0x1b, 0x18, 0x0d, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0c, 0x0e, 0x11, 0x11, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0e, + 0x0d, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x11, 0x10, + 0x10, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, + 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0d, 0x17, 0x16, 0x1d, 0x1f, 0x1e, 0x21, 0x15, 0x10, + 0x0e, 0x0e, 0x14, 0x15, 0x1b, 0x1b, 0x1a, 0x15, 0x11, 0x0d, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1a, 0x17, + 0x1b, 0x1b, 0x1b, 0x19, 0x1a, 0x18, 0x17, 0x19, 0x18, 0x0d, 0x0b, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0c, 0x0d, 0x10, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, + 0x12, 0x12, 0x0f, 0x0f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x10, 0x0d, + 0x0c, 0x0c, 0x0e, 0x0a, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0a, + 0x0b, 0x0a, 0x0c, 0x0e, 0x15, 0x16, 0x1c, 0x1d, 0x1f, 0x20, 0x13, 0x0f, + 0x10, 0x0f, 0x13, 0x15, 0x19, 0x19, 0x19, 0x15, 0x11, 0x0c, 0x0f, 0x10, + 0x11, 0x11, 0x11, 0x0e, 0x0d, 0x12, 0x17, 0x16, 0x19, 0x19, 0x1a, 0x17, + 0x17, 0x1d, 0x1e, 0x1d, 0x1b, 0x1d, 0x1a, 0x1a, 0x19, 0x0d, 0x0d, 0x0b, + 0x0d, 0x10, 0x16, 0x15, 0x10, 0x0e, 0x0c, 0x0d, 0x0f, 0x12, 0x12, 0x12, + 0x13, 0x13, 0x12, 0x11, 0x11, 0x11, 0x0f, 0x0f, 0x0d, 0x0d, 0x0d, 0x0c, + 0x0f, 0x0d, 0x0e, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0c, 0x0b, 0x0a, 0x0a, + 0x0c, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0f, 0x16, 0x17, 0x1c, 0x1d, 0x1e, 0x1e, 0x15, 0x0f, + 0x0f, 0x0f, 0x13, 0x14, 0x18, 0x1a, 0x19, 0x15, 0x0e, 0x10, 0x43, 0x4b, + 0x49, 0x4b, 0x50, 0x1f, 0x0e, 0x15, 0x1f, 0x23, 0x27, 0x27, 0x29, 0x2b, + 0x27, 0x20, 0x21, 0x2d, 0x1b, 0x21, 0x26, 0x24, 0x25, 0x1f, 0x17, 0x16, + 0x17, 0x0f, 0x0e, 0x12, 0x12, 0x16, 0x12, 0x0d, 0x0b, 0x0c, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0e, 0x0c, 0x0f, 0x0e, 0x10, 0x0f, 0x0e, 0x0e, 0x0d, + 0x0e, 0x0d, 0x0d, 0x0b, 0x0c, 0x0b, 0x0a, 0x0b, 0x0c, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0a, 0x0c, 0x0b, 0x0d, 0x14, 0x16, 0x1b, 0x1b, 0x1e, 0x1d, 0x12, 0x10, + 0x0f, 0x0d, 0x12, 0x14, 0x19, 0x1b, 0x17, 0x14, 0x0d, 0x11, 0x49, 0x4d, + 0x41, 0x46, 0x42, 0x1a, 0x0f, 0x1a, 0x2f, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x2a, 0x21, 0x23, 0x34, 0x31, 0x2c, 0x29, 0x27, 0x21, 0x27, 0x1a, 0x18, + 0x1b, 0x1a, 0x13, 0x0f, 0x0c, 0x0f, 0x12, 0x11, 0x0e, 0x10, 0x0e, 0x0c, + 0x0f, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0e, + 0x0d, 0x0e, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0a, 0x0b, 0x0c, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0b, 0x0c, + 0x0c, 0x0a, 0x0b, 0x0d, 0x14, 0x15, 0x1b, 0x19, 0x1e, 0x1d, 0x13, 0x0f, + 0x0d, 0x0d, 0x12, 0x14, 0x18, 0x19, 0x17, 0x15, 0x0d, 0x0d, 0x10, 0x12, + 0x11, 0x11, 0x10, 0x0f, 0x0d, 0x19, 0x30, 0x33, 0x35, 0x36, 0x34, 0x36, + 0x27, 0x20, 0x25, 0x37, 0x36, 0x1d, 0x1e, 0x1d, 0x1d, 0x25, 0x1b, 0x18, + 0x1b, 0x17, 0x15, 0x15, 0x16, 0x16, 0x13, 0x0f, 0x10, 0x11, 0x0c, 0x0d, + 0x10, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0c, + 0x0e, 0x0e, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0a, 0x0b, 0x0c, 0x0a, + 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, + 0x0a, 0x0a, 0x0a, 0x0d, 0x13, 0x15, 0x19, 0x1b, 0x1d, 0x1d, 0x13, 0x10, + 0x0e, 0x0d, 0x0f, 0x13, 0x18, 0x19, 0x19, 0x13, 0x0d, 0x0d, 0x0c, 0x0d, + 0x0e, 0x0e, 0x0c, 0x0d, 0x0e, 0x19, 0x2f, 0x33, 0x31, 0x35, 0x33, 0x36, + 0x23, 0x1e, 0x22, 0x30, 0x36, 0x2a, 0x37, 0x33, 0x33, 0x31, 0x19, 0x18, + 0x19, 0x17, 0x17, 0x14, 0x15, 0x16, 0x14, 0x12, 0x11, 0x10, 0x0e, 0x0d, + 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0c, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x09, 0x0b, 0x0b, + 0x0b, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, + 0x0b, 0x0c, 0x0c, 0x0d, 0x13, 0x15, 0x19, 0x1a, 0x1d, 0x1c, 0x13, 0x0f, + 0x0e, 0x0e, 0x11, 0x12, 0x15, 0x17, 0x16, 0x14, 0x0d, 0x0f, 0x0d, 0x0d, + 0x0d, 0x0e, 0x0d, 0x0e, 0x0e, 0x18, 0x30, 0x33, 0x33, 0x35, 0x37, 0x2d, + 0x12, 0x10, 0x0f, 0x12, 0x35, 0x33, 0x36, 0x32, 0x36, 0x36, 0x1c, 0x17, + 0x17, 0x17, 0x16, 0x15, 0x15, 0x13, 0x14, 0x12, 0x10, 0x10, 0x0d, 0x0e, + 0x0f, 0x11, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, + 0x0b, 0x0d, 0x0b, 0x0a, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0a, 0x0c, 0x0d, 0x13, 0x14, 0x19, 0x1c, 0x1c, 0x1d, 0x14, 0x0f, + 0x0e, 0x0c, 0x11, 0x12, 0x17, 0x19, 0x17, 0x14, 0x0d, 0x0e, 0x0c, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x19, 0x31, 0x36, 0x3a, 0x3c, 0x3d, 0x3c, + 0x35, 0x36, 0x36, 0x37, 0x3d, 0x3b, 0x2d, 0x27, 0x35, 0x37, 0x1b, 0x17, + 0x14, 0x14, 0x14, 0x15, 0x15, 0x13, 0x12, 0x12, 0x11, 0x11, 0x0e, 0x0d, + 0x11, 0x0f, 0x11, 0x10, 0x10, 0x0e, 0x0f, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0b, 0x0a, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0c, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, + 0x0c, 0x0d, 0x0c, 0x0e, 0x14, 0x15, 0x17, 0x1b, 0x1b, 0x1d, 0x14, 0x0f, + 0x0f, 0x0d, 0x11, 0x11, 0x15, 0x18, 0x17, 0x16, 0x0d, 0x0d, 0x0c, 0x0d, + 0x0d, 0x0b, 0x0b, 0x0c, 0x0d, 0x18, 0x34, 0x39, 0x38, 0x2c, 0x2c, 0x2e, + 0x2e, 0x34, 0x2e, 0x30, 0x31, 0x35, 0x36, 0x2f, 0x39, 0x38, 0x19, 0x16, + 0x13, 0x0d, 0x0c, 0x12, 0x15, 0x13, 0x13, 0x13, 0x11, 0x12, 0x0e, 0x0d, + 0x12, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, + 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, + 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x15, 0x13, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, + 0x0c, 0x0b, 0x0c, 0x0e, 0x14, 0x14, 0x19, 0x1a, 0x19, 0x1c, 0x14, 0x0e, + 0x0e, 0x0f, 0x10, 0x10, 0x15, 0x19, 0x16, 0x14, 0x0f, 0x0d, 0x0c, 0x0c, + 0x0b, 0x0c, 0x0d, 0x0c, 0x0d, 0x18, 0x34, 0x3a, 0x3a, 0x32, 0x2c, 0x30, + 0x35, 0x38, 0x3c, 0x30, 0x37, 0x3b, 0x3f, 0x3e, 0x3e, 0x37, 0x14, 0x14, + 0x15, 0x11, 0x11, 0x12, 0x11, 0x10, 0x11, 0x12, 0x13, 0x12, 0x0f, 0x0f, + 0x1c, 0x1e, 0x20, 0x1c, 0x10, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, + 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0b, 0x0a, 0x0c, 0x0b, 0x0c, + 0x3c, 0x42, 0x3c, 0x31, 0x23, 0x17, 0x0e, 0x0d, 0x0c, 0x0b, 0x0c, 0x0d, + 0x0c, 0x0d, 0x0d, 0x0d, 0x13, 0x15, 0x17, 0x1a, 0x1c, 0x1d, 0x15, 0x0e, + 0x0e, 0x0d, 0x10, 0x0f, 0x16, 0x19, 0x18, 0x16, 0x0d, 0x0d, 0x0b, 0x0c, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x17, 0x35, 0x39, 0x3e, 0x3b, 0x3f, 0x3c, + 0x3f, 0x43, 0x40, 0x3f, 0x41, 0x41, 0x3f, 0x3e, 0x3b, 0x37, 0x0f, 0x0f, + 0x13, 0x12, 0x0d, 0x11, 0x0e, 0x0e, 0x10, 0x10, 0x10, 0x10, 0x0d, 0x0e, + 0x13, 0x15, 0x13, 0x13, 0x11, 0x13, 0x11, 0x11, 0x10, 0x0f, 0x0d, 0x0c, + 0x0f, 0x0e, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0f, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0d, 0x12, 0x13, 0x16, 0x18, 0x1a, 0x1b, 0x15, 0x0e, + 0x0e, 0x0d, 0x0f, 0x10, 0x14, 0x17, 0x16, 0x15, 0x0e, 0x0d, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x16, 0x35, 0x3c, 0x3c, 0x40, 0x42, 0x43, + 0x49, 0x46, 0x45, 0x45, 0x44, 0x44, 0x3f, 0x3d, 0x3c, 0x36, 0x12, 0x0f, + 0x11, 0x12, 0x0e, 0x0e, 0x0d, 0x0e, 0x0e, 0x0c, 0x0e, 0x0e, 0x0e, 0x0d, + 0x0f, 0x12, 0x12, 0x11, 0x11, 0x10, 0x12, 0x11, 0x12, 0x11, 0x0f, 0x11, + 0x0e, 0x0f, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0a, 0x0c, 0x0c, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0c, 0x0d, 0x0d, 0x0c, 0x13, 0x15, 0x17, 0x19, 0x1a, 0x1a, 0x14, 0x10, + 0x0e, 0x0d, 0x0e, 0x0f, 0x14, 0x19, 0x19, 0x15, 0x0e, 0x0e, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0c, 0x0d, 0x0e, 0x17, 0x38, 0x3c, 0x3f, 0x42, 0x44, 0x45, + 0x47, 0x46, 0x47, 0x43, 0x46, 0x43, 0x3d, 0x3d, 0x3d, 0x37, 0x13, 0x10, + 0x10, 0x10, 0x11, 0x10, 0x0f, 0x10, 0x11, 0x11, 0x10, 0x0e, 0x0e, 0x0c, + 0x0e, 0x11, 0x13, 0x14, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x10, 0x11, + 0x11, 0x0f, 0x0e, 0x0c, 0x0b, 0x0c, 0x0d, 0x0d, 0x0b, 0x0c, 0x0d, 0x0b, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0b, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0c, 0x0e, 0x13, 0x15, 0x16, 0x18, 0x1b, 0x1a, 0x16, 0x0f, + 0x0d, 0x0e, 0x0e, 0x0e, 0x13, 0x1b, 0x19, 0x15, 0x0e, 0x0d, 0x0c, 0x0d, + 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x15, 0x36, 0x3c, 0x40, 0x45, 0x41, 0x43, + 0x49, 0x46, 0x45, 0x44, 0x43, 0x44, 0x41, 0x3f, 0x3e, 0x39, 0x11, 0x10, + 0x10, 0x0f, 0x10, 0x10, 0x10, 0x0f, 0x10, 0x11, 0x11, 0x0f, 0x0d, 0x0d, + 0x0e, 0x11, 0x12, 0x10, 0x12, 0x12, 0x11, 0x13, 0x12, 0x12, 0x12, 0x11, + 0x0f, 0x0f, 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0b, 0x0c, 0x0d, 0x0d, 0x0b, 0x0c, + 0x0d, 0x0d, 0x0c, 0x0d, 0x12, 0x14, 0x15, 0x18, 0x19, 0x19, 0x17, 0x0e, + 0x0d, 0x0b, 0x0e, 0x0e, 0x13, 0x19, 0x1a, 0x15, 0x0d, 0x0c, 0x0b, 0x0b, + 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x15, 0x36, 0x3c, 0x40, 0x3f, 0x41, 0x46, + 0x46, 0x46, 0x47, 0x45, 0x42, 0x41, 0x3d, 0x3c, 0x2f, 0x21, 0x11, 0x0f, + 0x0f, 0x10, 0x0f, 0x0f, 0x11, 0x0f, 0x11, 0x0f, 0x10, 0x0e, 0x0e, 0x0d, + 0x0d, 0x0f, 0x0f, 0x0f, 0x0d, 0x0f, 0x11, 0x10, 0x12, 0x11, 0x12, 0x11, + 0x10, 0x10, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0d, 0x0d, 0x0d, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0b, 0x0c, + 0x0b, 0x0c, 0x0d, 0x0d, 0x10, 0x12, 0x15, 0x16, 0x19, 0x1b, 0x17, 0x0f, + 0x0d, 0x0d, 0x0d, 0x0e, 0x12, 0x1a, 0x19, 0x15, 0x0c, 0x0d, 0x0b, 0x0d, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x14, 0x36, 0x3c, 0x41, 0x42, 0x41, 0x42, + 0x47, 0x45, 0x46, 0x43, 0x3d, 0x3d, 0x3a, 0x37, 0x18, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x10, 0x10, 0x0f, 0x10, 0x0f, + 0x10, 0x0e, 0x0e, 0x0d, 0x0d, 0x0e, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x10, 0x0e, 0x0e, 0x0c, 0x0f, 0x0d, 0x0f, 0x11, 0x15, 0x1c, + 0x0d, 0x0c, 0x0d, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0e, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0e, 0x11, 0x13, 0x15, 0x18, 0x19, 0x19, 0x17, 0x0e, + 0x0d, 0x0d, 0x0f, 0x10, 0x14, 0x1b, 0x19, 0x16, 0x0e, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0e, 0x0d, 0x0d, 0x15, 0x34, 0x3b, 0x3f, 0x42, 0x41, 0x45, + 0x45, 0x44, 0x43, 0x3f, 0x3b, 0x3c, 0x37, 0x2a, 0x17, 0x0d, 0x0e, 0x0e, + 0x0e, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, 0x0f, 0x11, 0x13, + 0x11, 0x10, 0x10, 0x10, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x12, 0x13, 0x15, + 0x14, 0x14, 0x17, 0x17, 0x1a, 0x1c, 0x25, 0x38, 0x50, 0x7a, 0xad, 0xc0, + 0x0d, 0x0e, 0x0c, 0x0d, 0x0c, 0x0c, 0x0b, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, + 0x0d, 0x0c, 0x0c, 0x0d, 0x11, 0x14, 0x14, 0x17, 0x17, 0x19, 0x16, 0x0f, + 0x0f, 0x10, 0x11, 0x11, 0x17, 0x1c, 0x19, 0x16, 0x0e, 0x0c, 0x0d, 0x0d, + 0x0c, 0x0c, 0x0d, 0x0c, 0x0b, 0x14, 0x32, 0x3a, 0x3e, 0x3d, 0x3d, 0x40, + 0x42, 0x40, 0x3d, 0x3b, 0x37, 0x35, 0x30, 0x1e, 0x10, 0x0c, 0x0d, 0x0f, + 0x10, 0x10, 0x10, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, 0x0f, + 0x10, 0x0f, 0x0e, 0x10, 0x10, 0x10, 0x12, 0x12, 0x16, 0x19, 0x1c, 0x21, + 0x2d, 0x41, 0x57, 0x6f, 0x87, 0x94, 0xa7, 0xb1, 0xc5, 0xc6, 0xc8, 0xc8, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0d, 0x0d, 0x10, 0x13, 0x13, 0x17, 0x18, 0x19, 0x16, 0x0f, + 0x0f, 0x10, 0x11, 0x13, 0x1b, 0x1c, 0x1a, 0x18, 0x0f, 0x0d, 0x0c, 0x0d, + 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x12, 0x2e, 0x33, 0x35, 0x36, 0x36, 0x32, + 0x34, 0x31, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x1b, 0x0e, 0x0e, 0x0d, 0x0e, + 0x10, 0x10, 0x0e, 0x0f, 0x0e, 0x10, 0x10, 0x0f, 0x0f, 0x10, 0x0e, 0x0f, + 0x11, 0x12, 0x15, 0x18, 0x1f, 0x2c, 0x3a, 0x50, 0x63, 0x78, 0x8a, 0x93, + 0xa1, 0xa6, 0xb0, 0xc2, 0xca, 0xf1, 0xf4, 0xe0, 0xf0, 0xda, 0xdc, 0xe7, + 0x0c, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0b, 0x0c, 0x10, 0x13, 0x11, 0x17, 0x18, 0x18, 0x16, 0x0f, + 0x13, 0x13, 0x13, 0x15, 0x1e, 0x1d, 0x1c, 0x19, 0x0f, 0x0e, 0x0b, 0x0b, + 0x0d, 0x0c, 0x0d, 0x0d, 0x0f, 0x0e, 0x18, 0x18, 0x15, 0x17, 0x13, 0x14, + 0x18, 0x19, 0x18, 0x16, 0x16, 0x16, 0x17, 0x14, 0x10, 0x0d, 0x0f, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x0f, 0x12, 0x13, 0x15, 0x18, 0x1e, 0x2b, 0x39, + 0x4d, 0x60, 0x78, 0x8a, 0x95, 0xa3, 0xa9, 0xae, 0xb7, 0xb8, 0xbd, 0xba, + 0xb8, 0xb8, 0xbe, 0xc8, 0xd4, 0xe8, 0xf0, 0xfa, 0xe5, 0xe5, 0xd9, 0xcd, + 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0d, 0x10, 0x13, 0x12, 0x17, 0x18, 0x19, 0x17, 0x13, + 0x12, 0x15, 0x15, 0x19, 0x20, 0x1f, 0x1e, 0x1c, 0x0f, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0e, 0x14, 0x0e, 0x13, 0x15, 0x15, 0x18, 0x19, 0x18, + 0x18, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x16, 0x15, 0x10, 0x11, 0x12, 0x15, + 0x16, 0x19, 0x20, 0x2f, 0x3c, 0x4d, 0x60, 0x74, 0x89, 0x96, 0xa0, 0xab, + 0xb7, 0xb9, 0xbd, 0xc4, 0xc0, 0xca, 0xd0, 0xd4, 0xd4, 0xc3, 0xc9, 0xc7, + 0xbc, 0xbe, 0xc2, 0xc6, 0xc3, 0xc6, 0xcf, 0xcb, 0xcd, 0xc6, 0xca, 0xc6, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0e, 0x0e, 0x0d, 0x0e, 0x10, 0x12, 0x11, 0x17, 0x17, 0x16, 0x14, 0x16, + 0x16, 0x18, 0x17, 0x1f, 0x25, 0x23, 0x23, 0x22, 0x14, 0x1d, 0x0e, 0x0e, + 0x0d, 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, 0x12, 0x16, 0x18, 0x19, 0x1a, 0x1b, + 0x1b, 0x1d, 0x1c, 0x1c, 0x1c, 0x1d, 0x22, 0x29, 0x36, 0x41, 0x54, 0x66, + 0x78, 0x89, 0x98, 0xa0, 0xaf, 0xb6, 0xb5, 0xbe, 0xc3, 0xc6, 0xca, 0xcc, + 0xc4, 0xd4, 0xd4, 0xd1, 0xd6, 0xcd, 0xd6, 0xcb, 0xd4, 0xcd, 0xd4, 0xd3, + 0xca, 0xd6, 0xce, 0xd3, 0xcd, 0xc5, 0xc3, 0xce, 0xd5, 0xc5, 0xc7, 0xd0, + 0x0f, 0x0f, 0x0c, 0x0f, 0x0e, 0x0d, 0x0e, 0x0d, 0x0d, 0x0e, 0x0c, 0x0d, + 0x0d, 0x0e, 0x0d, 0x0d, 0x0e, 0x0e, 0x11, 0x12, 0x12, 0x11, 0x11, 0x16, + 0x15, 0x16, 0x15, 0x27, 0x2d, 0x2b, 0x2e, 0x2d, 0x14, 0x13, 0x11, 0x13, + 0x13, 0x14, 0x14, 0x17, 0x14, 0x16, 0x1a, 0x1f, 0x20, 0x24, 0x2a, 0x32, + 0x40, 0x49, 0x56, 0x64, 0x76, 0x86, 0x94, 0xa0, 0xaf, 0xb9, 0xbc, 0xc1, + 0xc2, 0xba, 0xc6, 0xca, 0xc5, 0xc1, 0xcd, 0xcb, 0xcc, 0xd7, 0xcc, 0xd1, + 0xcb, 0xc5, 0xc0, 0xc3, 0xc4, 0xc4, 0xc5, 0xbf, 0xc4, 0xd5, 0xd8, 0xd6, + 0xc7, 0xcc, 0xc7, 0xd2, 0xd4, 0xcd, 0xcc, 0xd9, 0xd8, 0xd0, 0xdd, 0xc9, + 0x0d, 0x0e, 0x0d, 0x0e, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0e, 0x0d, 0x0d, + 0x0b, 0x0d, 0x0d, 0x0d, 0x10, 0x13, 0x16, 0x19, 0x19, 0x19, 0x18, 0x17, + 0x17, 0x14, 0x13, 0x36, 0x41, 0x3e, 0x40, 0x38, 0x1b, 0x1d, 0x1e, 0x1c, + 0x1d, 0x1f, 0x24, 0x2b, 0x37, 0x47, 0x53, 0x66, 0x77, 0x89, 0x98, 0xa5, + 0xb3, 0xb2, 0xbf, 0xc9, 0xcd, 0xcb, 0xd2, 0xd1, 0xcf, 0xcd, 0xd2, 0xd0, + 0xcc, 0xca, 0xd5, 0xcd, 0xd0, 0xca, 0xd4, 0xd4, 0xd1, 0xcc, 0xcd, 0xcb, + 0xcc, 0xca, 0xc6, 0xbf, 0xbe, 0xc4, 0xc1, 0xc6, 0xc4, 0xca, 0xcc, 0xc4, + 0xdc, 0xe4, 0xda, 0xd0, 0xcf, 0xde, 0xda, 0xf4, 0xe2, 0xde, 0xcc, 0xde, + 0x0f, 0x10, 0x0e, 0x0e, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0c, 0x0d, 0x0e, 0x0d, 0x10, 0x13, 0x17, 0x19, 0x1a, 0x1a, 0x1b, 0x19, + 0x18, 0x1b, 0x1a, 0x27, 0x2f, 0x31, 0x32, 0x39, 0x44, 0x54, 0x65, 0x76, + 0x8d, 0x9a, 0xa0, 0xa5, 0xb1, 0xbd, 0xc5, 0xc1, 0xd0, 0xd2, 0xd5, 0xd0, + 0xd1, 0xd5, 0xd8, 0xcc, 0xd0, 0xd9, 0xd4, 0xce, 0xcf, 0xd2, 0xd7, 0xd3, + 0xd7, 0xd6, 0xc1, 0xd3, 0xda, 0xd4, 0xd3, 0xcf, 0xc3, 0xca, 0xc5, 0xb7, + 0xc5, 0xc8, 0xcb, 0xcd, 0xc5, 0xcc, 0xcd, 0xd1, 0xda, 0xdd, 0xd1, 0xd3, + 0xe6, 0xef, 0xf7, 0xf3, 0xfa, 0xff, 0xf4, 0xfc, 0xec, 0xee, 0xef, 0xf2, + 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0e, 0x0e, 0x0e, + 0x0d, 0x0f, 0x0f, 0x0e, 0x11, 0x17, 0x1c, 0x20, 0x24, 0x29, 0x32, 0x3b, + 0x48, 0x59, 0x68, 0x75, 0x8a, 0x9b, 0xac, 0xbb, 0xc1, 0xb0, 0xc3, 0xc8, + 0xcd, 0xce, 0xe6, 0xea, 0xde, 0xe5, 0xdb, 0xe7, 0xe2, 0xda, 0xd5, 0xc9, + 0xdc, 0xd7, 0xd1, 0xcf, 0xd8, 0xd2, 0xd7, 0xdb, 0xce, 0xd3, 0xcd, 0xd5, + 0xcc, 0xd2, 0xc9, 0xcd, 0xcb, 0xcf, 0xcf, 0xc8, 0xc5, 0xc4, 0xad, 0xb1, + 0xc3, 0xc9, 0xca, 0xcd, 0xd6, 0xda, 0xce, 0xd9, 0xe1, 0xda, 0xdb, 0xe9, + 0xde, 0xe0, 0xe2, 0xf2, 0xff, 0xff, 0xf5, 0xd9, 0xe5, 0xcd, 0xe3, 0xe2, + 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x14, 0x17, 0x1a, + 0x1d, 0x25, 0x31, 0x3d, 0x4e, 0x63, 0x70, 0x84, 0x8f, 0x9d, 0xa8, 0xb3, + 0xbb, 0xc6, 0xce, 0xcb, 0xdd, 0xdb, 0xe5, 0xd2, 0xd3, 0xcb, 0xc6, 0xd0, + 0xd5, 0xf0, 0xfb, 0xe6, 0xe8, 0xef, 0xea, 0xe0, 0xe3, 0xd6, 0xe5, 0xe3, + 0xdc, 0xe2, 0xd5, 0xd8, 0xd9, 0xd7, 0xdb, 0xdc, 0xd5, 0xd8, 0xd3, 0xd2, + 0xce, 0xd4, 0xce, 0xd3, 0xd1, 0xcf, 0xce, 0xd0, 0xca, 0xc7, 0xbd, 0xbc, + 0xc9, 0xc8, 0xcd, 0xd0, 0xd8, 0xd9, 0xdf, 0xe1, 0xe0, 0xea, 0xe8, 0xff, + 0xf0, 0xdd, 0xe6, 0xef, 0xfa, 0xff, 0xef, 0xec, 0xf6, 0xec, 0xd6, 0xef, + 0x17, 0x19, 0x1f, 0x22, 0x2a, 0x33, 0x41, 0x50, 0x62, 0x75, 0x8a, 0x94, + 0x9b, 0xa5, 0xae, 0xaf, 0xb0, 0xb7, 0xba, 0xbf, 0xc3, 0xc8, 0xc8, 0xd5, + 0xcf, 0xdd, 0xe4, 0xd7, 0xe6, 0xf7, 0xf6, 0xef, 0xce, 0xcf, 0xc6, 0xd2, + 0xea, 0xe4, 0xee, 0xf3, 0xee, 0xef, 0xf0, 0xd6, 0xdc, 0xe4, 0xde, 0xd7, + 0xde, 0xdc, 0xcf, 0xd7, 0xd2, 0xd7, 0xd9, 0xc7, 0xd7, 0xd8, 0xd2, 0xcd, + 0xd0, 0xcd, 0xcf, 0xd0, 0xd5, 0xce, 0xd4, 0xd3, 0xc3, 0xcf, 0xce, 0xce, + 0xcb, 0xc5, 0xd3, 0xd7, 0xdc, 0xd6, 0xd2, 0xe3, 0xf1, 0xf3, 0xe7, 0xe0, + 0xf1, 0xf6, 0xe1, 0xdd, 0xe7, 0xe1, 0xda, 0xce, 0xc2, 0xe3, 0xee, 0xe3, + 0x82, 0x93, 0xa0, 0x9e, 0x9e, 0xa5, 0xac, 0xac, 0xaf, 0xb0, 0xb3, 0xb9, + 0xbc, 0xbb, 0xbb, 0xbd, 0xc2, 0xc2, 0xc5, 0xc6, 0xd2, 0xc6, 0xdc, 0xdc, + 0xe2, 0xe0, 0xec, 0xd4, 0xff, 0xea, 0xff, 0xea, 0xcd, 0xcc, 0xcd, 0xd1, + 0xdc, 0xde, 0xff, 0xef, 0xed, 0xf2, 0xe3, 0xde, 0xe4, 0xe0, 0xdd, 0xd0, + 0xe2, 0xd9, 0xdf, 0xda, 0xe2, 0xdb, 0xdc, 0xd5, 0xd4, 0xd4, 0xd7, 0xd1, + 0xd3, 0xd2, 0xd1, 0xd3, 0xcb, 0xd0, 0xd4, 0xc8, 0xce, 0xce, 0xc7, 0xd5, + 0xcb, 0xd1, 0xd8, 0xd8, 0xd2, 0xd5, 0xd6, 0xde, 0xdd, 0xf7, 0xe4, 0xdd, + 0xec, 0xdf, 0xf2, 0xe2, 0xe8, 0xe5, 0x96, 0x97, 0x98, 0x98, 0xc7, 0xba, + 0xac, 0xab, 0xa9, 0xa9, 0xae, 0xb2, 0xb3, 0xb5, 0xb7, 0xb6, 0xbd, 0xbe, + 0xb9, 0xbf, 0xc2, 0xc2, 0xc9, 0xc7, 0xcb, 0xc8, 0xc9, 0xd2, 0xd6, 0xda, + 0xe2, 0xe3, 0xf1, 0xe5, 0xd8, 0xff, 0xf8, 0xe4, 0xce, 0xc9, 0xc2, 0xce, + 0xd4, 0xee, 0xff, 0xde, 0xf1, 0xe3, 0xef, 0xe9, 0xd7, 0xdb, 0xe3, 0xdd, + 0xd5, 0xde, 0xd3, 0xda, 0xd6, 0xd7, 0xd8, 0xd6, 0xd2, 0xce, 0xc3, 0xcc, + 0xd2, 0xce, 0xcb, 0xd2, 0xd0, 0xd2, 0xca, 0xd2, 0xca, 0xd6, 0xc6, 0xd2, + 0xca, 0xce, 0xcd, 0xcc, 0xd5, 0xd5, 0xc8, 0xbd, 0xb8, 0xb6, 0xbb, 0xc1, + 0xbd, 0xd6, 0xe0, 0xe7, 0xf0, 0xf4, 0xe4, 0xba, 0x91, 0x91, 0x8a, 0x9b, + 0xab, 0xab, 0xac, 0xab, 0xb0, 0xae, 0xab, 0xb4, 0xb4, 0xbb, 0xbb, 0xc3, + 0xc2, 0xc8, 0xbe, 0xc5, 0xc8, 0xc3, 0xcd, 0xd2, 0xcf, 0xce, 0xdb, 0xdb, + 0xd9, 0xda, 0xf3, 0xdd, 0xf1, 0xe5, 0xec, 0xd9, 0xcd, 0xcb, 0xc8, 0xc9, + 0xd2, 0xf3, 0xff, 0xe2, 0xe8, 0xe6, 0xe4, 0xd9, 0xe9, 0xda, 0xd9, 0xdc, + 0xd4, 0xdb, 0xd7, 0xd6, 0xda, 0xcf, 0xd5, 0xce, 0xd2, 0xcc, 0xd0, 0xcc, + 0xcc, 0xd2, 0xcf, 0xcc, 0xcd, 0xd4, 0xcc, 0xce, 0xc5, 0xca, 0xc8, 0xc2, + 0xcb, 0xc5, 0xae, 0x99, 0x82, 0x66, 0x58, 0x4e, 0x4a, 0x4c, 0x53, 0x56, + 0x5a, 0x5e, 0x6e, 0x8c, 0xba, 0xdf, 0xe2, 0xe4, 0xd9, 0xa9, 0x81, 0x71, + 0xa8, 0xac, 0xa7, 0xae, 0xaf, 0xb3, 0xb0, 0xb4, 0xb5, 0xb8, 0xb7, 0xbb, + 0xc1, 0xc4, 0xc6, 0xc6, 0xc9, 0xca, 0xd2, 0xcf, 0xcc, 0xd7, 0xdc, 0xde, + 0xd8, 0xcf, 0xe7, 0xf0, 0xf9, 0xe8, 0xff, 0xf4, 0xcd, 0xca, 0xc8, 0xca, + 0xd0, 0xde, 0xf9, 0xef, 0xdf, 0xe5, 0xdb, 0xf2, 0xd3, 0xe5, 0xe7, 0xd8, + 0xd7, 0xd8, 0xdb, 0xdc, 0xd3, 0xd8, 0xd1, 0xcf, 0xd4, 0xcd, 0xd6, 0xd1, + 0xd1, 0xd2, 0xd2, 0xcd, 0xcd, 0xc6, 0xc3, 0xb9, 0xb1, 0x9c, 0x9b, 0xc2, + 0xcb, 0xc8, 0x8a, 0x42, 0x33, 0x30, 0x33, 0x31, 0x48, 0x63, 0x79, 0x7a, + 0x75, 0x67, 0x5e, 0x58, 0x59, 0x75, 0x9a, 0xcd, 0xef, 0xd4, 0xd4, 0x91, + 0xa6, 0xac, 0xac, 0xa9, 0xb0, 0xb1, 0xb3, 0xb3, 0xb6, 0xb9, 0xbd, 0xbd, + 0xbc, 0xbe, 0xbf, 0xc5, 0xc6, 0xca, 0xcc, 0xd1, 0xd6, 0xd1, 0xdc, 0xe7, + 0xec, 0xe9, 0xf4, 0xde, 0xe5, 0xec, 0xf2, 0xea, 0xc7, 0xc6, 0xc2, 0xc8, + 0xc7, 0xde, 0xf2, 0xf6, 0xe3, 0xed, 0xee, 0xe8, 0xe7, 0xe0, 0xdf, 0xdc, + 0xda, 0xde, 0xde, 0xcc, 0xd5, 0xd0, 0xcf, 0xd9, 0xd3, 0xcc, 0xd7, 0xd1, + 0xd5, 0xcc, 0xba, 0xac, 0x9d, 0x82, 0x6b, 0x56, 0x46, 0x3a, 0x38, 0x72, + 0xbf, 0xc7, 0xbf, 0x8e, 0x3c, 0x2e, 0x2d, 0x31, 0x4f, 0x9f, 0xc5, 0xce, + 0xd3, 0xc4, 0xbb, 0x9a, 0x6e, 0x67, 0x6f, 0x81, 0x9c, 0xdd, 0xdd, 0xda, + 0xa4, 0xa8, 0xa8, 0xad, 0xae, 0xb4, 0xb2, 0xb5, 0xba, 0xb5, 0xb9, 0xc1, + 0xba, 0xbf, 0xc2, 0xc5, 0xbd, 0xc0, 0xca, 0xcc, 0xd6, 0xcd, 0xdb, 0xd3, + 0xdc, 0xdd, 0xdd, 0xe7, 0xd5, 0xe7, 0xe7, 0xf0, 0xcd, 0xcc, 0xc7, 0xc1, + 0xc6, 0xcf, 0xe2, 0xe4, 0xde, 0xf2, 0xe7, 0xe4, 0xea, 0xdb, 0xd9, 0xd9, + 0xd3, 0xd7, 0xdc, 0xd8, 0xcf, 0xd1, 0xd2, 0xd0, 0xd3, 0xd5, 0xce, 0xd0, + 0xca, 0x9b, 0x5b, 0x46, 0x3a, 0x2f, 0x25, 0x25, 0x2d, 0x35, 0x42, 0x59, + 0xa0, 0xc3, 0xc8, 0xc1, 0x99, 0x48, 0x2d, 0x2b, 0x2d, 0x4b, 0x96, 0xc6, + 0xd7, 0xd1, 0xd9, 0xcc, 0xb1, 0x61, 0x57, 0x5d, 0x7a, 0x97, 0xdb, 0xe5, + 0xa8, 0xa5, 0xa9, 0xa8, 0xae, 0xb0, 0xb0, 0xb0, 0xb8, 0xb8, 0xba, 0xbb, + 0xbd, 0xbb, 0xc1, 0xc5, 0xc1, 0xc8, 0xc2, 0xcb, 0xd0, 0xda, 0xd5, 0xdf, + 0xdd, 0xe9, 0xe0, 0xd1, 0xe3, 0xff, 0xf2, 0xd9, 0xca, 0xc7, 0xc2, 0xc5, + 0xc5, 0xbf, 0xd8, 0xee, 0xe9, 0xed, 0xd0, 0xe4, 0xdb, 0xde, 0xe0, 0xcf, + 0xd3, 0xd6, 0xd5, 0xdb, 0xd5, 0xd6, 0xd1, 0xd2, 0xd6, 0xd4, 0xd3, 0xd1, + 0xcb, 0xb5, 0x52, 0x26, 0x21, 0x20, 0x20, 0x2f, 0x71, 0x93, 0xa4, 0xb0, + 0xb3, 0xb4, 0xc4, 0xc2, 0xc5, 0xa6, 0x51, 0x2d, 0x2a, 0x2d, 0x3d, 0x71, + 0xc0, 0xce, 0xd3, 0xce, 0xd1, 0x9e, 0x4d, 0x48, 0x5a, 0x71, 0x9d, 0xec, + 0xa1, 0xa5, 0xa7, 0xac, 0xac, 0xae, 0xb3, 0xb0, 0xb1, 0xb5, 0xbc, 0xbc, + 0xbe, 0xbd, 0xbf, 0xc6, 0xc1, 0xc4, 0xc5, 0xcb, 0xd3, 0xcc, 0xd8, 0xe0, + 0xd4, 0xdb, 0xdf, 0xee, 0xd4, 0xde, 0xe9, 0xd6, 0xbe, 0xc6, 0xbe, 0xc9, + 0xcb, 0xd8, 0xe6, 0xf1, 0xd8, 0xea, 0xea, 0xf2, 0xe2, 0xe3, 0xd1, 0xdf, + 0xdd, 0xdf, 0xdc, 0xda, 0xd4, 0xd0, 0xd2, 0xd3, 0xcc, 0xd2, 0xd0, 0xd4, + 0xd1, 0xc9, 0xa5, 0x46, 0x22, 0x20, 0x1e, 0x24, 0x5f, 0x98, 0x91, 0x7e, + 0x67, 0x54, 0x72, 0xb0, 0xc5, 0xc5, 0xac, 0x62, 0x2f, 0x2a, 0x2d, 0x35, + 0x56, 0xa8, 0xc6, 0xca, 0xc8, 0xa8, 0x5e, 0x4c, 0x4e, 0x59, 0x79, 0xda, + 0xa7, 0xa5, 0xa5, 0xae, 0xa9, 0xae, 0xae, 0xb1, 0xb1, 0xb6, 0xb8, 0xbb, + 0xb8, 0xbf, 0xbe, 0xc4, 0xbe, 0xc6, 0xc8, 0xc6, 0xc9, 0xca, 0xcd, 0xd4, + 0xd6, 0xdc, 0xe0, 0xec, 0xf4, 0xe4, 0xe6, 0xdc, 0xcf, 0xc2, 0xc7, 0xc8, + 0xd4, 0xdf, 0xe9, 0xea, 0xed, 0xed, 0xf0, 0xe8, 0xe7, 0xe1, 0xe4, 0xe7, + 0xdd, 0xdf, 0xd2, 0xcf, 0xcf, 0xd7, 0xda, 0xd5, 0xd4, 0xd1, 0xd0, 0xcd, + 0xd1, 0xcd, 0xc8, 0x99, 0x3b, 0x22, 0x1f, 0x21, 0x26, 0x39, 0x30, 0x2b, + 0x2b, 0x29, 0x31, 0x64, 0xb8, 0xbe, 0xc4, 0xb3, 0x7a, 0x34, 0x2b, 0x2c, + 0x35, 0x42, 0x81, 0x80, 0x67, 0x4a, 0x4f, 0x51, 0x51, 0x57, 0x85, 0xd2, + 0xa2, 0xa0, 0xa5, 0xa8, 0xa8, 0xac, 0xac, 0xb0, 0xb1, 0xb3, 0xb2, 0xb5, + 0xbe, 0xba, 0xbd, 0xbb, 0xbd, 0xc0, 0xbc, 0xcb, 0xc9, 0xd0, 0xcf, 0xd6, + 0xd4, 0xdb, 0xd7, 0xe7, 0xe9, 0xe3, 0xec, 0xdb, 0xd4, 0xc6, 0xbe, 0xcb, + 0xcb, 0xea, 0xf5, 0xd1, 0xe0, 0xe9, 0xe0, 0xe5, 0xe1, 0xd6, 0xe0, 0xdd, + 0xdd, 0xdf, 0xd3, 0xd1, 0xd7, 0xd7, 0xda, 0xca, 0xd7, 0xd3, 0xcf, 0xd5, + 0xcd, 0xcc, 0xc8, 0xbe, 0x8a, 0x34, 0x20, 0x1e, 0x20, 0x1d, 0x22, 0x27, + 0x32, 0x46, 0x65, 0x7d, 0xab, 0xc0, 0xc5, 0xc2, 0xbc, 0x8e, 0x3d, 0x2d, + 0x2c, 0x30, 0x34, 0x3b, 0x39, 0x38, 0x3c, 0x44, 0x56, 0x78, 0xb8, 0xd1}; +unsigned int _tmp_dump_no_person_3_bmp_len = 9216; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.h new file mode 100644 index 0000000..64cc05b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/no_person_image_data.h @@ -0,0 +1,30 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This data was created from a sample image from without a person in it. +// Convert original image to simpler format: +// convert -resize 96x96\! noperson.PNG noperson.bmp3 +// Skip the 54 byte bmp3 header and add the reset of the bytes to a C array: +// xxd -s 54 -i /tmp/noperson.bmp3 > /tmp/noperson.cc + +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_NO_PERSON_IMAGE_DATA_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_NO_PERSON_IMAGE_DATA_H_ + +#include + +extern const int g_no_person_data_size; +extern const uint8_t g_no_person_data[]; + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_NO_PERSON_IMAGE_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.cc new file mode 100644 index 0000000..0b9916d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.cc @@ -0,0 +1,23148 @@ + +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a TensorFlow Lite model file that has been converted into a C data +// array using the tensorflow.lite.util.convert_bytes_to_c_source() function. +// This form is useful for compiling into a binary for devices that don't have a +// file system. + +#include "tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.h" + +// Keep model aligned to 8 bytes to guarantee aligned 64-bit accesses. +alignas(8) const unsigned char g_person_detect_model_data[] = { + 0x1c, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x84, 0x95, 0x04, + 0x00, 0xec, 0x5b, 0x03, 0x00, 0xd4, 0x5b, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x5a, 0x00, 0x00, 0x00, 0xc4, 0x5b, 0x03, 0x00, 0xac, 0x5b, 0x03, 0x00, 0x94, + 0x5b, 0x03, 0x00, 0x84, 0x59, 0x03, 0x00, 0x74, 0x55, 0x03, 0x00, 0x64, 0x55, + 0x02, 0x00, 0x54, 0x51, 0x02, 0x00, 0x44, 0x48, 0x02, 0x00, 0x34, 0x44, 0x02, + 0x00, 0x24, 0x42, 0x02, 0x00, 0x94, 0x3d, 0x02, 0x00, 0x84, 0x3b, 0x02, 0x00, + 0x74, 0xfb, 0x01, 0x00, 0xe4, 0xf6, 0x01, 0x00, 0xd4, 0xb6, 0x01, 0x00, 0xc4, + 0xb4, 0x01, 0x00, 0xb4, 0x74, 0x01, 0x00, 0xa4, 0x72, 0x01, 0x00, 0x94, 0x70, + 0x01, 0x00, 0x84, 0x6e, 0x01, 0x00, 0x74, 0x2e, 0x01, 0x00, 0x64, 0xee, 0x00, + 0x00, 0x54, 0xec, 0x00, 0x00, 0xc4, 0xe7, 0x00, 0x00, 0xb4, 0xe5, 0x00, 0x00, + 0xa4, 0xc5, 0x00, 0x00, 0x94, 0xc4, 0x00, 0x00, 0x44, 0xc2, 0x00, 0x00, 0x34, + 0xb2, 0x00, 0x00, 0x24, 0xb1, 0x00, 0x00, 0x14, 0xa9, 0x00, 0x00, 0x84, 0xa8, + 0x00, 0x00, 0x54, 0xa7, 0x00, 0x00, 0x44, 0xa3, 0x00, 0x00, 0xb4, 0xa2, 0x00, + 0x00, 0x84, 0xa1, 0x00, 0x00, 0x34, 0xa1, 0x00, 0x00, 0x2c, 0xa1, 0x00, 0x00, + 0x24, 0xa1, 0x00, 0x00, 0x1c, 0xa1, 0x00, 0x00, 0x14, 0xa1, 0x00, 0x00, 0x0c, + 0xa1, 0x00, 0x00, 0x04, 0xa1, 0x00, 0x00, 0xfc, 0xa0, 0x00, 0x00, 0xf4, 0xa0, + 0x00, 0x00, 0xec, 0xa0, 0x00, 0x00, 0xe4, 0xa0, 0x00, 0x00, 0xdc, 0xa0, 0x00, + 0x00, 0x8c, 0xa0, 0x00, 0x00, 0x84, 0xa0, 0x00, 0x00, 0x7c, 0xa0, 0x00, 0x00, + 0x74, 0xa0, 0x00, 0x00, 0x6c, 0xa0, 0x00, 0x00, 0x64, 0xa0, 0x00, 0x00, 0x5c, + 0xa0, 0x00, 0x00, 0x4c, 0x9e, 0x00, 0x00, 0x1c, 0x9e, 0x00, 0x00, 0x14, 0x9e, + 0x00, 0x00, 0x74, 0x9d, 0x00, 0x00, 0xe4, 0x9c, 0x00, 0x00, 0x8c, 0x9c, 0x00, + 0x00, 0x7c, 0x9a, 0x00, 0x00, 0xec, 0x99, 0x00, 0x00, 0x5c, 0x99, 0x00, 0x00, + 0x54, 0x99, 0x00, 0x00, 0x4c, 0x99, 0x00, 0x00, 0x44, 0x99, 0x00, 0x00, 0x3c, + 0x99, 0x00, 0x00, 0xe4, 0x98, 0x00, 0x00, 0xd4, 0x18, 0x00, 0x00, 0xc4, 0x16, + 0x00, 0x00, 0x34, 0x12, 0x00, 0x00, 0xa4, 0x0d, 0x00, 0x00, 0x9c, 0x0d, 0x00, + 0x00, 0x94, 0x0d, 0x00, 0x00, 0x8c, 0x0d, 0x00, 0x00, 0x7c, 0x0c, 0x00, 0x00, + 0x2c, 0x0a, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0x84, + 0x03, 0x00, 0x00, 0x7c, 0x03, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, 0x3c, 0x01, + 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x7c, 0xfc, 0xfb, 0xff, 0x80, 0xfc, 0xfb, 0xff, 0x84, 0xfc, 0xfb, 0xff, 0x88, + 0xfc, 0xfb, 0xff, 0x8c, 0xfc, 0xfb, 0xff, 0xba, 0xa4, 0xfc, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x37, 0x0f, 0x00, 0x00, 0x5d, 0xe6, 0xff, + 0xff, 0x75, 0xdd, 0xff, 0xff, 0xee, 0xf7, 0xff, 0xff, 0xa4, 0xfa, 0xff, 0xff, + 0xc7, 0xf5, 0xff, 0xff, 0x0a, 0x0c, 0x00, 0x00, 0xdb, 0x16, 0x00, 0x00, 0x06, + 0x09, 0x00, 0x00, 0x81, 0x1b, 0x00, 0x00, 0xc1, 0x29, 0x00, 0x00, 0xd2, 0x18, + 0x00, 0x00, 0xd0, 0xf6, 0xff, 0xff, 0x93, 0x5c, 0x00, 0x00, 0xf3, 0xb9, 0xff, + 0xff, 0x0a, 0x28, 0x00, 0x00, 0xed, 0xe9, 0xff, 0xff, 0x86, 0xc9, 0xff, 0xff, + 0x28, 0x27, 0x00, 0x00, 0x77, 0x04, 0x00, 0x00, 0x7a, 0xd0, 0xff, 0xff, 0xad, + 0x58, 0x00, 0x00, 0x1c, 0x4b, 0x00, 0x00, 0xb0, 0x9b, 0xff, 0xff, 0xb5, 0xce, + 0xff, 0xff, 0xfc, 0x12, 0x00, 0x00, 0x3e, 0xfd, 0xff, 0xff, 0x4b, 0xf5, 0xff, + 0xff, 0xae, 0xcb, 0xff, 0xff, 0xc3, 0x39, 0x00, 0x00, 0x56, 0xd1, 0xff, 0xff, + 0x3d, 0x19, 0x00, 0x00, 0x4b, 0x18, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0xc6, + 0x6a, 0x00, 0x00, 0xca, 0xb0, 0xff, 0xff, 0xb4, 0x08, 0x00, 0x00, 0x3b, 0x4b, + 0x00, 0x00, 0xc9, 0xbe, 0xff, 0xff, 0xd4, 0x12, 0x00, 0x00, 0xe2, 0xf4, 0xff, + 0xff, 0x36, 0xff, 0xff, 0xff, 0xd0, 0xef, 0xff, 0xff, 0x08, 0xcc, 0xff, 0xff, + 0xa7, 0xd3, 0xff, 0xff, 0x9c, 0x08, 0x00, 0x00, 0x03, 0x1b, 0x00, 0x00, 0xaf, + 0xa2, 0xff, 0xff, 0x71, 0x13, 0x00, 0x00, 0x0c, 0x7b, 0x00, 0x00, 0xf2, 0x03, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1e, 0x29, 0x00, 0x00, 0x0c, 0x04, 0x00, + 0x00, 0x92, 0x59, 0x00, 0x00, 0x27, 0xd4, 0xff, 0xff, 0x30, 0x0c, 0x00, 0x00, + 0xfa, 0xfb, 0xff, 0xff, 0x17, 0xca, 0xff, 0xff, 0x92, 0xd3, 0xff, 0xff, 0x6c, + 0x11, 0x00, 0x00, 0xc9, 0xff, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, 0x4f, 0x43, + 0x00, 0x00, 0xc6, 0xa5, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x6e, 0xcc, 0xff, 0xff, 0x69, 0x36, 0x00, 0x00, 0xfb, 0xee, 0xff, 0xff, + 0x24, 0x4c, 0x00, 0x00, 0xb3, 0x07, 0x00, 0x00, 0x96, 0x3f, 0x00, 0x00, 0xe1, + 0xd2, 0xff, 0xff, 0xf7, 0xfd, 0xff, 0xff, 0x01, 0x4f, 0x00, 0x00, 0x9b, 0xea, + 0xff, 0xff, 0xcc, 0xe4, 0xff, 0xff, 0xb2, 0x00, 0x00, 0x00, 0x52, 0xed, 0xff, + 0xff, 0xef, 0xad, 0xff, 0xff, 0xef, 0x34, 0x00, 0x00, 0x37, 0x0c, 0x00, 0x00, + 0xea, 0x47, 0x00, 0x00, 0xf8, 0xed, 0xff, 0xff, 0xa0, 0xef, 0xff, 0xff, 0xea, + 0x43, 0x00, 0x00, 0x17, 0xed, 0xff, 0xff, 0xab, 0xfd, 0xff, 0xff, 0x0b, 0xf8, + 0xff, 0xff, 0x37, 0x26, 0x00, 0x00, 0x33, 0xea, 0xff, 0xff, 0x0e, 0x1e, 0x00, + 0x00, 0xc4, 0x09, 0x00, 0x00, 0x6f, 0x1f, 0x00, 0x00, 0xfc, 0x69, 0xff, 0xff, + 0x9c, 0xd9, 0xff, 0xff, 0xc1, 0xf0, 0xff, 0xff, 0x89, 0x19, 0x00, 0x00, 0x9c, + 0x29, 0x00, 0x00, 0x10, 0xb7, 0xff, 0xff, 0x2f, 0xd9, 0xff, 0xff, 0x23, 0xe9, + 0xff, 0xff, 0xaf, 0x57, 0x00, 0x00, 0x05, 0x48, 0x00, 0x00, 0x30, 0xf7, 0xff, + 0xff, 0x1c, 0x12, 0x00, 0x00, 0xa7, 0xcc, 0xff, 0xff, 0xd0, 0xc6, 0xff, 0xff, + 0x9d, 0xea, 0xff, 0xff, 0x9a, 0xfc, 0xff, 0xff, 0xc1, 0xcc, 0xff, 0xff, 0x63, + 0xcf, 0xff, 0xff, 0xa8, 0x11, 0x00, 0x00, 0x1d, 0xfd, 0xff, 0xff, 0xfc, 0xfa, + 0xff, 0xff, 0x14, 0xe9, 0xff, 0xff, 0xb5, 0x37, 0x00, 0x00, 0x46, 0x21, 0x00, + 0x00, 0x3e, 0x02, 0x00, 0x00, 0x77, 0xd2, 0xff, 0xff, 0x0e, 0xe5, 0xff, 0xff, + 0xde, 0x24, 0x00, 0x00, 0xe9, 0x28, 0x00, 0x00, 0xdc, 0x6d, 0xff, 0xff, 0x59, + 0xb6, 0xff, 0xff, 0xb8, 0x0d, 0x00, 0x00, 0x89, 0xf5, 0xff, 0xff, 0xf5, 0x25, + 0x00, 0x00, 0xd6, 0x1e, 0x00, 0x00, 0x03, 0x32, 0x00, 0x00, 0x2f, 0x1f, 0x00, + 0x00, 0xe1, 0xfa, 0xff, 0xff, 0x59, 0xd8, 0xff, 0xff, 0x85, 0x3e, 0x00, 0x00, + 0xae, 0xea, 0xff, 0xff, 0x72, 0x3e, 0x00, 0x00, 0x87, 0xfd, 0xff, 0xff, 0x27, + 0x57, 0x00, 0x00, 0x0b, 0xf2, 0xff, 0xff, 0xc2, 0x1c, 0x00, 0x00, 0xd9, 0x20, + 0x00, 0x00, 0xf9, 0x2e, 0x00, 0x00, 0x84, 0xfd, 0xff, 0xff, 0x6b, 0x22, 0x00, + 0x00, 0x2b, 0x94, 0xff, 0xff, 0xdf, 0xfd, 0xff, 0xff, 0x80, 0xee, 0xff, 0xff, + 0x4d, 0xe6, 0xff, 0xff, 0x71, 0xd4, 0xff, 0xff, 0xd6, 0xd8, 0xff, 0xff, 0xdc, + 0x4d, 0x00, 0x00, 0xfc, 0xb8, 0xff, 0xff, 0xa6, 0x45, 0x00, 0x00, 0xa5, 0xf1, + 0xff, 0xff, 0x63, 0x31, 0x00, 0x00, 0x3c, 0xd8, 0xff, 0xff, 0x12, 0x29, 0x00, + 0x00, 0x34, 0xdb, 0xff, 0xff, 0xae, 0x57, 0x00, 0x00, 0x6c, 0xc9, 0xff, 0xff, + 0x1b, 0x2f, 0x00, 0x00, 0x44, 0x28, 0x00, 0x00, 0x34, 0xf3, 0xff, 0xff, 0xdd, + 0x1c, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0xaa, 0x02, 0x00, 0x00, 0x23, 0x41, + 0x00, 0x00, 0x97, 0x0e, 0x00, 0x00, 0xcf, 0x1b, 0x00, 0x00, 0x50, 0x17, 0x00, + 0x00, 0x67, 0x8b, 0xff, 0xff, 0x22, 0x0b, 0x00, 0x00, 0x56, 0xd1, 0xff, 0xff, + 0xfe, 0xe8, 0xff, 0xff, 0x8d, 0x31, 0x00, 0x00, 0xc9, 0xd1, 0xff, 0xff, 0x98, + 0x10, 0x00, 0x00, 0x9c, 0x44, 0x00, 0x00, 0x0f, 0x0b, 0x00, 0x00, 0xd4, 0x3e, + 0x00, 0x00, 0x64, 0x19, 0x00, 0x00, 0x0c, 0xe8, 0xff, 0xff, 0xcc, 0x04, 0x00, + 0x00, 0xcc, 0xb7, 0xff, 0xff, 0xea, 0x3d, 0x00, 0x00, 0x30, 0x19, 0x00, 0x00, + 0x70, 0x06, 0x00, 0x00, 0x14, 0x2f, 0x00, 0x00, 0xcb, 0xd4, 0xff, 0xff, 0xd2, + 0xee, 0xff, 0xff, 0x4e, 0x26, 0x00, 0x00, 0xd4, 0x23, 0x00, 0x00, 0xa0, 0x55, + 0x00, 0x00, 0x2e, 0x15, 0x00, 0x00, 0xd2, 0xa7, 0xfc, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0xbe, 0x0e, 0x00, 0x00, 0x95, 0xff, 0xff, 0xff, + 0x56, 0xb6, 0xfe, 0xff, 0xac, 0xc9, 0xff, 0xff, 0xd9, 0x50, 0x00, 0x00, 0xfa, + 0xff, 0xff, 0xff, 0xdf, 0x2c, 0x00, 0x00, 0x9a, 0xcb, 0xfd, 0xff, 0xd4, 0xff, + 0xfb, 0xff, 0x02, 0xa8, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, + 0x00, 0x5e, 0xac, 0x7e, 0x7f, 0xdc, 0xf2, 0xcc, 0x39, 0x8c, 0x81, 0x5e, 0xa5, + 0xa7, 0x7f, 0xbd, 0x37, 0x45, 0x1b, 0xf3, 0x74, 0x7f, 0x1e, 0xc4, 0xfb, 0x00, + 0xbe, 0xfc, 0xfa, 0x03, 0x22, 0x7f, 0x59, 0x38, 0xac, 0x75, 0xeb, 0x56, 0xa8, + 0x9e, 0x00, 0x9a, 0x99, 0xf4, 0xa2, 0x5f, 0x08, 0x7f, 0x44, 0xc9, 0x01, 0x36, + 0x0d, 0xde, 0xc2, 0xbf, 0xa4, 0x01, 0x7f, 0xf8, 0x1a, 0xd2, 0xec, 0x01, 0x41, + 0x41, 0x0f, 0x0c, 0xd8, 0x05, 0xd6, 0x4f, 0x81, 0x37, 0x2e, 0x63, 0x7f, 0x2e, + 0x1c, 0xd1, 0xab, 0xbe, 0x52, 0xb3, 0x7f, 0x7f, 0x14, 0xa3, 0xe0, 0xad, 0x7f, + 0xc1, 0x69, 0xc3, 0xc7, 0xf7, 0x71, 0xc6, 0xaf, 0x81, 0x25, 0x7f, 0x75, 0x18, + 0xc4, 0xcf, 0xdd, 0x4f, 0x1d, 0x9b, 0x04, 0xa4, 0xe9, 0x81, 0xb0, 0x31, 0x89, + 0x4f, 0x1f, 0x14, 0x4d, 0x78, 0x24, 0x81, 0x7f, 0xfb, 0x81, 0xf5, 0xe8, 0x4f, + 0xc5, 0x7f, 0x10, 0x26, 0x50, 0xce, 0xe5, 0xf4, 0x00, 0x0c, 0xac, 0xd6, 0x4f, + 0x50, 0x42, 0x7f, 0x0d, 0xe7, 0x35, 0x3c, 0xfd, 0x4b, 0xf1, 0xae, 0x18, 0xfb, + 0xc9, 0x1f, 0xe3, 0x52, 0x3d, 0x7f, 0xe8, 0x44, 0x7f, 0x3a, 0xd7, 0xe1, 0x3d, + 0x8b, 0xba, 0xc4, 0x57, 0x3b, 0x1d, 0x1b, 0x26, 0x8e, 0x45, 0x3b, 0xcd, 0x4d, + 0xcc, 0x14, 0xb0, 0x2e, 0x60, 0xed, 0xf8, 0xb0, 0xfe, 0xf9, 0x30, 0xfc, 0x22, + 0x7c, 0xc0, 0x15, 0x70, 0x70, 0x20, 0x7f, 0x9c, 0x4d, 0x06, 0x11, 0xc8, 0xb5, + 0xc7, 0xc1, 0x2a, 0xb8, 0x51, 0x1b, 0x4e, 0xbd, 0x9d, 0x5e, 0x30, 0xd3, 0x47, + 0xc5, 0x49, 0xe9, 0x20, 0xc7, 0x2c, 0xf0, 0x59, 0xdf, 0x47, 0x2e, 0xd5, 0x9e, + 0x9e, 0xa7, 0xd1, 0x81, 0xf9, 0xd7, 0x15, 0x9c, 0xa6, 0x6d, 0xfe, 0x7f, 0x79, + 0x7f, 0xd7, 0x7f, 0x4f, 0xdf, 0x7a, 0x00, 0xbf, 0x7f, 0xd6, 0x48, 0x93, 0x3d, + 0x5a, 0x7f, 0xca, 0x81, 0x42, 0xbc, 0xb6, 0x67, 0xb7, 0xae, 0x40, 0xc0, 0x7f, + 0x2f, 0x12, 0x3a, 0x7f, 0x22, 0x43, 0x42, 0xec, 0xc1, 0x21, 0x07, 0xf0, 0x18, + 0xc9, 0x11, 0x30, 0x21, 0xef, 0x26, 0x44, 0xdd, 0xc0, 0xaf, 0x9d, 0xa9, 0x20, + 0xb5, 0x00, 0xbd, 0x0d, 0x54, 0x45, 0x7f, 0x0d, 0x3b, 0x03, 0x1a, 0xaa, 0x21, + 0xc4, 0xec, 0x63, 0xf9, 0x09, 0x08, 0x0b, 0x20, 0x2e, 0xd4, 0x56, 0x73, 0x13, + 0xed, 0x76, 0x81, 0xd7, 0x4d, 0xfb, 0x14, 0xf4, 0xf7, 0x23, 0xc4, 0x99, 0xbc, + 0x1c, 0x14, 0x6a, 0x05, 0xe0, 0x8a, 0x5c, 0x8a, 0xf7, 0xb1, 0x30, 0xf4, 0xf3, + 0x08, 0x0b, 0xfb, 0x7f, 0xaf, 0x39, 0x78, 0x77, 0x25, 0xda, 0xbd, 0x9e, 0xcf, + 0x26, 0xf3, 0x1e, 0xd8, 0x08, 0x5c, 0xcc, 0x77, 0xaa, 0x07, 0xfa, 0x08, 0x14, + 0xce, 0x11, 0xa1, 0x71, 0xa8, 0x8c, 0x5a, 0xf2, 0xd5, 0x9f, 0x60, 0x54, 0xd5, + 0x21, 0xbe, 0x7f, 0xa4, 0xa3, 0x7f, 0x74, 0x81, 0x5c, 0x81, 0xd4, 0x15, 0x13, + 0x7f, 0x68, 0x19, 0x7f, 0xda, 0x68, 0xf9, 0x20, 0x64, 0x1e, 0xcd, 0xe3, 0x03, + 0x16, 0x4f, 0xbe, 0x45, 0xe8, 0xfd, 0x8d, 0xd9, 0xf3, 0xd1, 0xa0, 0x90, 0x81, + 0xfc, 0x81, 0x2c, 0x68, 0xca, 0x21, 0x0a, 0x17, 0xff, 0x81, 0xe5, 0x81, 0x39, + 0x04, 0x00, 0xc6, 0xb3, 0x7f, 0x2a, 0xd7, 0x1b, 0xd8, 0x35, 0xa4, 0x7f, 0x47, + 0x5c, 0xf7, 0x76, 0x67, 0x24, 0xef, 0x4e, 0x41, 0xab, 0xcc, 0xd2, 0x7f, 0x81, + 0x4f, 0x35, 0x7f, 0xb8, 0x99, 0xf9, 0x25, 0x98, 0x7f, 0x81, 0x6f, 0xf5, 0x7f, + 0xd5, 0xc3, 0xc9, 0xd7, 0x59, 0x92, 0x2b, 0xcd, 0x99, 0x94, 0x7f, 0x1e, 0xb1, + 0x40, 0xcc, 0x15, 0x8d, 0x77, 0x63, 0xba, 0x24, 0x2b, 0x28, 0x46, 0xd1, 0x7f, + 0xa2, 0xc3, 0xd2, 0xa1, 0x3b, 0x05, 0x26, 0xd1, 0x1c, 0x19, 0xe1, 0x04, 0x9a, + 0x15, 0x81, 0xb9, 0x41, 0x05, 0x9f, 0xe8, 0x49, 0x18, 0x1b, 0x05, 0x30, 0x71, + 0xe4, 0x17, 0x7f, 0x7f, 0x02, 0x6f, 0x64, 0xee, 0x30, 0xcd, 0x04, 0x27, 0x4b, + 0xeb, 0x7f, 0x7f, 0xf4, 0xca, 0xc5, 0x7f, 0xb9, 0x08, 0x84, 0x3c, 0x43, 0x8b, + 0x6f, 0x6b, 0x1c, 0x42, 0x28, 0x81, 0xeb, 0xae, 0xcf, 0x9f, 0x04, 0x00, 0x7f, + 0xf8, 0xc1, 0x0c, 0xd8, 0x1e, 0x49, 0x9a, 0x50, 0xaf, 0xed, 0x26, 0xb0, 0x49, + 0x45, 0x21, 0xe4, 0xf8, 0x7f, 0x7f, 0xd7, 0xd1, 0xa9, 0x41, 0x38, 0xc6, 0x38, + 0x7f, 0xfd, 0xf8, 0x7f, 0x12, 0xa8, 0xfb, 0xae, 0x7f, 0x07, 0x65, 0x81, 0x59, + 0x94, 0xff, 0xaf, 0xc0, 0x7f, 0xdf, 0xa3, 0x17, 0x05, 0x7f, 0x03, 0xe9, 0xb5, + 0x6c, 0xd5, 0x35, 0x15, 0xf7, 0x56, 0x7f, 0x54, 0xe8, 0x3b, 0x34, 0x06, 0xd6, + 0x81, 0x20, 0x18, 0x25, 0x7f, 0xc6, 0x4f, 0x5a, 0xd2, 0x1b, 0xf4, 0x56, 0xb4, + 0xa3, 0xee, 0x19, 0x89, 0x5c, 0x58, 0x25, 0x11, 0x27, 0x6e, 0x1a, 0x0f, 0x36, + 0x33, 0xee, 0x03, 0x7f, 0x28, 0xbc, 0x42, 0x01, 0xdd, 0x3f, 0x38, 0x05, 0x69, + 0xc8, 0xfa, 0xe0, 0xd3, 0xd1, 0xbb, 0x55, 0x81, 0x70, 0xc9, 0xab, 0x1a, 0x7f, + 0x6c, 0x51, 0x09, 0x00, 0xf5, 0x9e, 0x57, 0xab, 0x2a, 0x08, 0xcf, 0xb5, 0xe5, + 0x3b, 0x13, 0x7f, 0x04, 0x7f, 0x7f, 0x61, 0xfa, 0x7f, 0xb7, 0x31, 0x2d, 0x48, + 0x3f, 0xf0, 0xf1, 0x37, 0xde, 0x9a, 0xc1, 0xf0, 0x5f, 0x30, 0x2e, 0xd9, 0xb9, + 0x53, 0xe4, 0x02, 0x07, 0x09, 0xad, 0x3d, 0x01, 0x3c, 0x31, 0x12, 0xdf, 0x6d, + 0x2f, 0xd4, 0x54, 0x9b, 0x81, 0x81, 0xcd, 0x28, 0xa8, 0x01, 0x81, 0x7f, 0x03, + 0x5a, 0x12, 0x8e, 0x1e, 0x3f, 0x0d, 0x7f, 0x99, 0x2a, 0xa1, 0xe8, 0xac, 0xae, + 0x74, 0xf2, 0xb8, 0xb9, 0x31, 0xf0, 0xe9, 0x76, 0xfd, 0x15, 0xc4, 0x8f, 0x28, + 0x7f, 0x0a, 0xfa, 0xaf, 0xd5, 0x02, 0x56, 0x28, 0x6b, 0xeb, 0x6d, 0x0f, 0x03, + 0x7f, 0x1a, 0x7f, 0x7f, 0x06, 0xb7, 0xd0, 0xc7, 0xa0, 0xbd, 0xd2, 0xfa, 0x58, + 0x7f, 0x89, 0xbe, 0x81, 0x81, 0xeb, 0x82, 0x90, 0x8b, 0xf9, 0xe3, 0xca, 0xca, + 0x42, 0x6a, 0x50, 0xd8, 0x56, 0x45, 0x79, 0xe5, 0x0f, 0x7f, 0xea, 0xdb, 0x7f, + 0x2b, 0x7f, 0xf9, 0x9b, 0xb0, 0x29, 0x5e, 0xfa, 0x59, 0xff, 0x7f, 0x7f, 0xe3, + 0x7a, 0x04, 0xb1, 0x95, 0xe0, 0x60, 0xd8, 0xff, 0xe9, 0x47, 0x8f, 0x5b, 0xa2, + 0x01, 0x81, 0x53, 0xed, 0x51, 0x34, 0x57, 0x0d, 0xcd, 0x9b, 0x2e, 0x09, 0xa9, + 0x13, 0xa4, 0xa1, 0xa6, 0x40, 0x16, 0xdc, 0x61, 0xa0, 0xee, 0xb5, 0x76, 0x8b, + 0xbc, 0xeb, 0xda, 0x00, 0x31, 0x0c, 0x2f, 0xe3, 0x8d, 0x9e, 0x93, 0x16, 0x5f, + 0x86, 0x81, 0x02, 0xa7, 0xba, 0x6a, 0xb8, 0xc7, 0xc9, 0x87, 0xa6, 0xfd, 0xe0, + 0x73, 0xf0, 0xb1, 0x26, 0x2c, 0xef, 0x71, 0xe7, 0x3f, 0x09, 0x6b, 0x1b, 0xad, + 0x53, 0x1e, 0x25, 0xfc, 0x1d, 0x99, 0x1d, 0xcf, 0xbc, 0x15, 0x7f, 0x65, 0xdc, + 0x1b, 0xd2, 0x6e, 0xe0, 0x1e, 0x81, 0xad, 0x0c, 0xdf, 0xe0, 0x81, 0xf7, 0x43, + 0x7f, 0xab, 0x7e, 0xfc, 0x3a, 0xde, 0xfd, 0x10, 0xba, 0xdd, 0x5c, 0x6b, 0x5c, + 0xd3, 0x2e, 0x77, 0xfb, 0x5a, 0xd1, 0x6e, 0x3c, 0x3a, 0x4b, 0xe4, 0x0f, 0x4d, + 0xb0, 0xf3, 0x81, 0x11, 0x2c, 0xbc, 0xc4, 0x51, 0xaa, 0x7f, 0x40, 0x49, 0xbe, + 0xf9, 0x10, 0x64, 0x7f, 0x0a, 0x9f, 0x2b, 0xcb, 0x49, 0xd0, 0x81, 0x38, 0x89, + 0xdb, 0x9a, 0xf7, 0x3b, 0xe8, 0x24, 0x9c, 0x21, 0x8d, 0x60, 0xcf, 0xd2, 0xdd, + 0x10, 0x1e, 0xc0, 0xf5, 0x79, 0xad, 0x8e, 0xbe, 0xce, 0x36, 0x61, 0xae, 0xc2, + 0x1a, 0x32, 0xf2, 0x7f, 0xd1, 0xef, 0x8b, 0xca, 0x08, 0xef, 0x20, 0x2c, 0x4c, + 0xc0, 0xf6, 0x7f, 0x76, 0x56, 0xdf, 0x44, 0xcf, 0xec, 0x5d, 0xe0, 0x0b, 0xad, + 0x7f, 0x7f, 0xe8, 0x81, 0x42, 0x81, 0x2f, 0xfa, 0x0c, 0x32, 0x81, 0xc8, 0xca, + 0x3b, 0xfd, 0x3f, 0xa9, 0x1c, 0x0d, 0x16, 0xf7, 0xda, 0x7f, 0x67, 0x21, 0xe6, + 0x7f, 0x77, 0x7f, 0xb1, 0xd1, 0x69, 0x81, 0x54, 0x5a, 0xef, 0x34, 0xde, 0xc1, + 0x7f, 0xd3, 0x52, 0xdf, 0x66, 0xec, 0x41, 0x21, 0xe0, 0x04, 0xf6, 0x81, 0x81, + 0xfd, 0x48, 0x10, 0xf9, 0xbf, 0xb0, 0x81, 0x60, 0xc0, 0xdc, 0xa3, 0xc3, 0xec, + 0x6d, 0x0c, 0x1d, 0x05, 0x08, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0x81, 0xea, 0xcf, + 0xac, 0x11, 0xc6, 0x7f, 0xe9, 0x1c, 0xd7, 0x7f, 0x81, 0x81, 0xd7, 0xdc, 0xf2, + 0x38, 0x13, 0x6a, 0x9f, 0xad, 0xb5, 0x83, 0x02, 0x7f, 0x64, 0x04, 0xfc, 0xff, + 0x92, 0xac, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7f, + 0xf0, 0xff, 0xff, 0x8a, 0xf8, 0xff, 0xff, 0x87, 0xf6, 0xff, 0xff, 0x8e, 0xff, + 0xff, 0xff, 0x68, 0x11, 0x00, 0x00, 0x24, 0xea, 0xff, 0xff, 0x95, 0x27, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x58, 0xe5, 0xff, 0xff, 0x96, 0xef, 0xff, 0xff, + 0xe7, 0xf7, 0xff, 0xff, 0x63, 0x00, 0x00, 0x00, 0x4f, 0xf8, 0xff, 0xff, 0xac, + 0xff, 0xff, 0xff, 0x5d, 0x25, 0x00, 0x00, 0x5a, 0xff, 0xff, 0xff, 0xc1, 0xff, + 0xff, 0xff, 0xe0, 0x07, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x9a, 0xfd, 0xff, + 0xff, 0xf8, 0x04, 0x00, 0x00, 0xe0, 0xfc, 0xff, 0xff, 0xa2, 0xfd, 0xff, 0xff, + 0xf5, 0xee, 0xff, 0xff, 0x02, 0xfb, 0xff, 0xff, 0x19, 0x20, 0x00, 0x00, 0xd6, + 0x26, 0x00, 0x00, 0xc9, 0xfc, 0xff, 0xff, 0x8e, 0x22, 0x00, 0x00, 0x21, 0xff, + 0xff, 0xff, 0xbf, 0x31, 0x00, 0x00, 0x6b, 0x27, 0x00, 0x00, 0xce, 0xe7, 0xff, + 0xff, 0x52, 0xfd, 0xff, 0xff, 0xfc, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, + 0x8e, 0x20, 0x00, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x2f, 0xfc, 0xff, 0xff, 0xc2, + 0x29, 0x00, 0x00, 0x34, 0xf3, 0xff, 0xff, 0xfd, 0xec, 0xff, 0xff, 0x52, 0xf9, + 0xff, 0xff, 0x66, 0xeb, 0xff, 0xff, 0x90, 0x21, 0x00, 0x00, 0xef, 0x39, 0x00, + 0x00, 0xb4, 0x03, 0x00, 0x00, 0xe5, 0x01, 0x00, 0x00, 0x37, 0xfb, 0xff, 0xff, + 0xf5, 0xf8, 0xff, 0xff, 0xac, 0xf9, 0xff, 0xff, 0x05, 0xf5, 0xff, 0xff, 0x74, + 0xff, 0xff, 0xff, 0xd7, 0xf8, 0xff, 0xff, 0x3a, 0x1e, 0x00, 0x00, 0x43, 0x2e, + 0x00, 0x00, 0xf0, 0xf2, 0xff, 0xff, 0x1f, 0xfd, 0xff, 0xff, 0x4d, 0x1c, 0x00, + 0x00, 0xe9, 0xff, 0xff, 0xff, 0xb6, 0xfc, 0xff, 0xff, 0x45, 0x2c, 0x00, 0x00, + 0xf4, 0x08, 0x00, 0x00, 0xbe, 0xff, 0xff, 0xff, 0x92, 0x29, 0x00, 0x00, 0xf6, + 0x32, 0x00, 0x00, 0x01, 0xf7, 0xff, 0xff, 0xe3, 0xf6, 0xff, 0xff, 0xf2, 0xfd, + 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0x1a, 0xf4, 0xff, 0xff, 0x22, 0x00, 0x00, + 0x00, 0x32, 0xeb, 0xff, 0xff, 0xed, 0x22, 0x00, 0x00, 0x3c, 0xfc, 0xff, 0xff, + 0x95, 0x00, 0x00, 0x00, 0xcb, 0x0b, 0x00, 0x00, 0xc6, 0x32, 0x00, 0x00, 0xf8, + 0xf8, 0xff, 0xff, 0x28, 0x27, 0x00, 0x00, 0x1b, 0x05, 0x00, 0x00, 0xfb, 0xfe, + 0xff, 0xff, 0x05, 0xf9, 0xff, 0xff, 0xb3, 0x27, 0x00, 0x00, 0xb7, 0x2d, 0x00, + 0x00, 0x78, 0x0e, 0x00, 0x00, 0x0e, 0xf7, 0xff, 0xff, 0xe2, 0xf3, 0xff, 0xff, + 0xc4, 0xfe, 0xff, 0xff, 0x35, 0xff, 0xff, 0xff, 0x1b, 0xf6, 0xff, 0xff, 0xa4, + 0xfd, 0xff, 0xff, 0x1d, 0xfd, 0xff, 0xff, 0xe7, 0x28, 0x00, 0x00, 0x1e, 0xf6, + 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0x12, 0xf8, 0xff, 0xff, 0x04, 0xf8, 0xff, + 0xff, 0x51, 0xf8, 0xff, 0xff, 0xde, 0xff, 0xff, 0xff, 0x15, 0x07, 0x00, 0x00, + 0xa4, 0xfa, 0xff, 0xff, 0xb4, 0xf8, 0xff, 0xff, 0x8b, 0x2d, 0x00, 0x00, 0xd5, + 0x2f, 0x00, 0x00, 0x47, 0xf9, 0xff, 0xff, 0xbb, 0xf8, 0xff, 0xff, 0xda, 0x39, + 0x00, 0x00, 0xa0, 0x14, 0x00, 0x00, 0x2c, 0xfb, 0xff, 0xff, 0x20, 0x01, 0x00, + 0x00, 0xf5, 0xfc, 0xff, 0xff, 0x4b, 0x29, 0x00, 0x00, 0x80, 0xfd, 0xff, 0xff, + 0x4c, 0x22, 0x00, 0x00, 0xd7, 0x07, 0x00, 0x00, 0xb3, 0x28, 0x00, 0x00, 0x21, + 0xff, 0xff, 0xff, 0xf3, 0xf7, 0xff, 0xff, 0x17, 0xfe, 0xff, 0xff, 0xa3, 0xf4, + 0xff, 0xff, 0x4d, 0x38, 0x00, 0x00, 0x2a, 0xfd, 0xff, 0xff, 0x3b, 0x38, 0x00, + 0x00, 0x7a, 0xfc, 0xff, 0xff, 0x78, 0xfd, 0xff, 0xff, 0x5e, 0x01, 0x00, 0x00, + 0xb6, 0x43, 0x00, 0x00, 0x9e, 0xae, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x40, + 0x02, 0x00, 0x00, 0x47, 0xc3, 0xfe, 0xec, 0xfe, 0x7f, 0xd6, 0x81, 0x3d, 0x37, + 0x29, 0x0b, 0xb8, 0x1b, 0x0c, 0x3a, 0x13, 0xc8, 0xde, 0x81, 0xd3, 0x01, 0xf4, + 0xbc, 0x3c, 0xf7, 0x44, 0xac, 0x0b, 0xf6, 0x81, 0xc9, 0x30, 0x13, 0xe8, 0x31, + 0x0f, 0x2c, 0x8d, 0xc6, 0x7f, 0x28, 0x0d, 0xf9, 0xb9, 0xa3, 0x4d, 0x81, 0x0b, + 0xed, 0x7f, 0xfb, 0xe2, 0x7f, 0xbf, 0x91, 0x7f, 0xc9, 0xa9, 0x72, 0x30, 0xfb, + 0xe1, 0x42, 0x48, 0x81, 0x1f, 0x3c, 0x7f, 0x7c, 0xac, 0x93, 0x51, 0x7f, 0xdd, + 0x15, 0xf1, 0x13, 0x47, 0x7f, 0x34, 0x90, 0x63, 0xb4, 0xfd, 0x89, 0x7f, 0xb9, + 0x7f, 0x17, 0x31, 0xb5, 0x5f, 0xa1, 0x3d, 0x4c, 0x60, 0x9c, 0x38, 0x81, 0xe9, + 0xf7, 0x82, 0xb6, 0xfd, 0xcf, 0xed, 0x39, 0x81, 0x89, 0xba, 0x8a, 0x19, 0x27, + 0xe8, 0xde, 0x81, 0x44, 0x86, 0xb3, 0x5b, 0xa5, 0x81, 0x37, 0x8b, 0xd5, 0xab, + 0xac, 0x0c, 0xc4, 0x03, 0xfb, 0xea, 0xb8, 0xd5, 0xa4, 0xe3, 0xcd, 0xeb, 0xea, + 0xec, 0x24, 0xce, 0x10, 0xdc, 0xee, 0xdb, 0xe8, 0xe0, 0x35, 0x08, 0xcc, 0xea, + 0xf1, 0x3e, 0xf8, 0xc7, 0xf9, 0x9a, 0xfe, 0x4a, 0x30, 0xf9, 0xdd, 0x1a, 0xec, + 0x0b, 0xd9, 0xd0, 0xd7, 0xf9, 0xd0, 0xfb, 0x9e, 0xf0, 0xbb, 0xdf, 0xf5, 0x0a, + 0xdd, 0xfd, 0xdf, 0xd2, 0x07, 0xe0, 0xfe, 0x05, 0x96, 0x42, 0xf2, 0xec, 0xb9, + 0x3d, 0xf1, 0x66, 0x81, 0x18, 0x77, 0xf4, 0x89, 0x7f, 0xbe, 0x7f, 0x20, 0xf1, + 0x7f, 0xeb, 0xf5, 0x55, 0x81, 0x42, 0xbb, 0xdf, 0xba, 0x00, 0xef, 0x47, 0x03, + 0x8b, 0x81, 0xd6, 0xe0, 0xac, 0xab, 0x70, 0xa4, 0x81, 0xb3, 0x93, 0xa3, 0x75, + 0x7f, 0x4c, 0x24, 0x7f, 0x2d, 0x9b, 0x81, 0x7f, 0x8a, 0x4f, 0x02, 0x5f, 0xa6, + 0xfd, 0x4f, 0x8d, 0x81, 0xe0, 0xcf, 0xcd, 0x7f, 0xf6, 0x81, 0xca, 0xc7, 0x7f, + 0x0a, 0x6b, 0x5d, 0x2c, 0x28, 0x81, 0xbe, 0xa6, 0xdf, 0xba, 0x7f, 0x2c, 0x7e, + 0x7f, 0xf4, 0x7f, 0x94, 0x7f, 0x93, 0x81, 0x81, 0xb1, 0x81, 0x4c, 0x7f, 0x81, + 0x98, 0x7f, 0x81, 0xc2, 0x7f, 0x7f, 0x81, 0x6b, 0x82, 0xe3, 0x81, 0x7f, 0x22, + 0x3b, 0x7f, 0x89, 0x7f, 0x81, 0xab, 0xdb, 0x1e, 0x7f, 0x7f, 0x1b, 0x22, 0x65, + 0x4f, 0x81, 0x99, 0xaa, 0x81, 0x8b, 0x7f, 0x81, 0xef, 0x81, 0x81, 0x08, 0x23, + 0xf6, 0x7d, 0xab, 0xaf, 0xd9, 0x83, 0xc5, 0xfc, 0x0a, 0xf1, 0xea, 0x00, 0x3e, + 0xf3, 0x07, 0xdd, 0x16, 0x17, 0xd4, 0x54, 0x03, 0xfb, 0xec, 0x05, 0xde, 0xb3, + 0x32, 0x13, 0x9d, 0x34, 0xfc, 0xdc, 0x72, 0xdb, 0x7f, 0xc5, 0xfc, 0x1e, 0xf8, + 0xcd, 0xea, 0x02, 0xa3, 0xb8, 0xbf, 0xb4, 0x05, 0x0d, 0x11, 0x7f, 0x08, 0x13, + 0xcf, 0xf2, 0xf7, 0xcf, 0xef, 0xb7, 0x0f, 0xbe, 0xdf, 0x2c, 0xe1, 0x11, 0xad, + 0xb7, 0xf7, 0xbc, 0x58, 0x14, 0xeb, 0x02, 0xfe, 0x01, 0xfa, 0x12, 0xea, 0x07, + 0xf0, 0xd0, 0xf8, 0xfe, 0xe0, 0xee, 0x0c, 0x36, 0x16, 0xf1, 0x17, 0xc2, 0xea, + 0xd2, 0xfb, 0xdc, 0xe0, 0xef, 0x00, 0xc5, 0xd6, 0x32, 0x46, 0x77, 0x01, 0xcf, + 0x2f, 0x0f, 0xc0, 0xd8, 0xec, 0x8b, 0xe7, 0xdb, 0xaa, 0xb9, 0x0a, 0xe6, 0x1d, + 0x22, 0xa5, 0x36, 0xd8, 0xb0, 0x30, 0x8a, 0xf3, 0xf3, 0x14, 0x0e, 0x81, 0xea, + 0xf3, 0xd0, 0xfc, 0xb0, 0xd1, 0xed, 0xea, 0x21, 0x7f, 0x61, 0x01, 0xb2, 0x07, + 0xa0, 0x0e, 0xfd, 0x98, 0x08, 0xd3, 0xe9, 0x07, 0xf0, 0xf2, 0xb4, 0x33, 0xdc, + 0x96, 0xd9, 0x10, 0xcc, 0xd5, 0xb5, 0x02, 0x63, 0x56, 0x1d, 0x2a, 0x5a, 0xea, + 0x2d, 0xba, 0xbd, 0x1c, 0x0d, 0x1f, 0x1e, 0x3a, 0x3f, 0x2e, 0xe4, 0xfc, 0xe4, + 0xb9, 0xd2, 0xb4, 0xd0, 0xb2, 0xc9, 0xd8, 0x2b, 0xe6, 0xf6, 0xe7, 0x2e, 0xef, + 0xf5, 0x28, 0xf0, 0xfd, 0x0b, 0xec, 0xfd, 0x15, 0xcd, 0xee, 0xee, 0xf1, 0x0f, + 0xa1, 0x0b, 0xce, 0xea, 0xf6, 0x07, 0xea, 0xf8, 0xf0, 0x22, 0xfe, 0x0b, 0xe0, + 0x0f, 0x01, 0xf2, 0xed, 0x22, 0x1b, 0x48, 0xd7, 0xf9, 0x05, 0xf5, 0xd1, 0xe1, + 0xe2, 0xf0, 0xf2, 0xb1, 0xf3, 0xee, 0x0c, 0x4d, 0xf4, 0xe9, 0x2d, 0x1d, 0x0e, + 0xd2, 0x08, 0x1e, 0x2c, 0x11, 0x40, 0x28, 0xea, 0xb0, 0xfc, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x8b, 0x31, 0x00, 0x00, 0xe5, 0x8e, 0x00, + 0x00, 0x3e, 0x18, 0x00, 0x00, 0xd4, 0x04, 0x00, 0x00, 0xda, 0x3d, 0x00, 0x00, + 0x9d, 0xf1, 0xff, 0xff, 0x5e, 0x56, 0x00, 0x00, 0xe2, 0x3c, 0x00, 0x00, 0xef, + 0xde, 0xff, 0xff, 0x58, 0x35, 0x00, 0x00, 0x4a, 0x14, 0x00, 0x00, 0x9f, 0xf0, + 0xff, 0xff, 0x0e, 0x10, 0x00, 0x00, 0x1f, 0xdc, 0xff, 0xff, 0xf1, 0x08, 0x00, + 0x00, 0x47, 0x32, 0x00, 0x00, 0x12, 0x43, 0x00, 0x00, 0x6d, 0x1c, 0x00, 0x00, + 0x44, 0x7d, 0xff, 0xff, 0x96, 0x0b, 0x00, 0x00, 0xd3, 0x11, 0x00, 0x00, 0x13, + 0x1b, 0x00, 0x00, 0xb4, 0xa8, 0xff, 0xff, 0x1e, 0x1c, 0x00, 0x00, 0x2b, 0xd2, + 0xff, 0xff, 0x4b, 0x8b, 0x00, 0x00, 0x20, 0x27, 0x00, 0x00, 0xcd, 0xff, 0xff, + 0xff, 0x50, 0xce, 0xff, 0xff, 0x02, 0x39, 0x00, 0x00, 0x08, 0x30, 0x00, 0x00, + 0x91, 0xf1, 0xff, 0xff, 0x61, 0x12, 0x00, 0x00, 0xa9, 0x50, 0x00, 0x00, 0x28, + 0x1a, 0x00, 0x00, 0x4a, 0x0d, 0x00, 0x00, 0x60, 0x3b, 0x00, 0x00, 0x07, 0x37, + 0x00, 0x00, 0x15, 0x63, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x00, 0xbe, 0x37, 0x00, + 0x00, 0xfd, 0x2d, 0x00, 0x00, 0x1a, 0x3c, 0x00, 0x00, 0x08, 0x4b, 0x00, 0x00, + 0x05, 0x17, 0x00, 0x00, 0x0a, 0x70, 0x00, 0x00, 0xde, 0xec, 0x00, 0x00, 0x12, + 0xef, 0xff, 0xff, 0xa8, 0xa0, 0xff, 0xff, 0x5d, 0x4b, 0x00, 0x00, 0x62, 0x1f, + 0x00, 0x00, 0x27, 0xfe, 0xff, 0xff, 0x8b, 0x23, 0x00, 0x00, 0xc5, 0xfe, 0xff, + 0xff, 0xc4, 0x02, 0x00, 0x00, 0xfc, 0x6a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, + 0xf9, 0x44, 0x00, 0x00, 0x15, 0x65, 0x00, 0x00, 0xae, 0x0c, 0x00, 0x00, 0x0d, + 0x6d, 0x00, 0x00, 0x37, 0x14, 0x00, 0x00, 0x86, 0x39, 0x00, 0x00, 0xfd, 0x60, + 0x00, 0x00, 0xcc, 0x09, 0xfc, 0xff, 0xd0, 0x09, 0xfc, 0xff, 0xd4, 0x09, 0xfc, + 0xff, 0x02, 0xb2, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, + 0x57, 0xc3, 0x64, 0x7f, 0x09, 0x99, 0x87, 0xf8, 0x13, 0x56, 0x0d, 0xbb, 0xe5, + 0x1d, 0xec, 0x1c, 0x72, 0xd5, 0x92, 0xc5, 0xa9, 0x79, 0x1a, 0xb3, 0xfc, 0x07, + 0xed, 0x44, 0x0f, 0x7f, 0x67, 0x4b, 0xee, 0x81, 0xd9, 0xd1, 0x2f, 0x7b, 0x81, + 0x81, 0xb8, 0xa1, 0x81, 0x7f, 0xc1, 0xf0, 0xc3, 0x7f, 0xc8, 0xc6, 0x63, 0x24, + 0x25, 0x26, 0x81, 0x9d, 0x4d, 0x81, 0x57, 0x81, 0xba, 0x12, 0xe7, 0x55, 0xed, + 0x95, 0x5c, 0x22, 0xe0, 0x14, 0x38, 0x33, 0xf9, 0x73, 0xf8, 0x19, 0xaf, 0xb6, + 0x7f, 0x76, 0xa7, 0xd2, 0xca, 0xb2, 0x98, 0xad, 0x40, 0x23, 0x56, 0xdd, 0x59, + 0xd4, 0x23, 0x50, 0xf4, 0xf0, 0xcd, 0x40, 0x56, 0xb8, 0x81, 0xc0, 0x94, 0xd0, + 0xca, 0xb9, 0x2f, 0xf3, 0xf1, 0x0a, 0x3a, 0x7f, 0xbe, 0x6e, 0x7f, 0x73, 0xda, + 0x81, 0x58, 0x87, 0x49, 0x9f, 0xd5, 0x7f, 0x09, 0x5f, 0x1b, 0x16, 0x3e, 0xc1, + 0xb0, 0x26, 0xd9, 0x0c, 0x8c, 0x00, 0xde, 0x25, 0x2e, 0xe7, 0xb7, 0x7f, 0xd7, + 0x65, 0xef, 0x0f, 0x81, 0x8b, 0x9a, 0xf4, 0x5b, 0x0c, 0xd1, 0xaf, 0xdc, 0x05, + 0x10, 0xf8, 0xbf, 0x7d, 0xd9, 0xc6, 0xe2, 0xe2, 0xe5, 0x7f, 0xe3, 0x0d, 0xab, + 0x99, 0x28, 0x22, 0xce, 0x4c, 0xdf, 0x63, 0x0f, 0x9d, 0x7f, 0x7f, 0x19, 0x31, + 0xe7, 0xd4, 0x7f, 0xc5, 0x29, 0x88, 0xe5, 0x06, 0xd2, 0x4e, 0xc7, 0x3b, 0x2b, + 0xf5, 0x7f, 0xd6, 0x2d, 0x02, 0x8c, 0x50, 0xdc, 0xa3, 0xb2, 0x99, 0x32, 0x7f, + 0x56, 0xc7, 0x2a, 0x36, 0xcb, 0xfa, 0xba, 0x40, 0x3e, 0x05, 0x7f, 0xdc, 0x29, + 0x2c, 0xec, 0xfb, 0xc9, 0x7f, 0x08, 0x4a, 0x04, 0xdc, 0xa1, 0x50, 0xdb, 0xe7, + 0xf8, 0x91, 0xe9, 0xfc, 0x67, 0x3b, 0x99, 0x32, 0x69, 0x10, 0xeb, 0x17, 0xa6, + 0xae, 0xf2, 0x78, 0xf3, 0x5d, 0x08, 0x72, 0x35, 0x09, 0x16, 0x83, 0xa1, 0x41, + 0x44, 0x34, 0x55, 0x28, 0x23, 0xd8, 0x44, 0xb6, 0x2b, 0x65, 0xe3, 0xcd, 0x7f, + 0xeb, 0xf3, 0x25, 0xb2, 0x81, 0x7f, 0x15, 0xb4, 0xae, 0x9a, 0x1a, 0x0d, 0xca, + 0x81, 0x1f, 0x81, 0xb7, 0xf8, 0xb6, 0x78, 0x27, 0xa7, 0xab, 0xab, 0xae, 0xdc, + 0xfe, 0xaa, 0x1b, 0x34, 0xf9, 0x38, 0x97, 0x2c, 0x14, 0x37, 0x3e, 0xb8, 0x9a, + 0x4c, 0xc0, 0x7f, 0xdf, 0x9d, 0xca, 0x1d, 0x8f, 0xdd, 0x7f, 0x7f, 0x1a, 0xf2, + 0xef, 0x7f, 0x7f, 0xca, 0x4b, 0xea, 0xd7, 0xb1, 0xfd, 0x61, 0x74, 0x1c, 0xa6, + 0x7f, 0x1b, 0x81, 0x7f, 0xe4, 0x07, 0x7f, 0xee, 0x40, 0xbd, 0x28, 0xf4, 0xe2, + 0x7f, 0xcc, 0x64, 0x2f, 0xf3, 0x92, 0x9b, 0x8c, 0xf5, 0xa0, 0xdc, 0x0d, 0xc2, + 0x03, 0x22, 0x4f, 0x47, 0xbc, 0x17, 0x1d, 0x2e, 0xd5, 0x3a, 0xbd, 0xbd, 0x22, + 0x72, 0xf8, 0x25, 0xfe, 0x7e, 0x7f, 0x04, 0x10, 0xe0, 0x7f, 0x10, 0x46, 0xf1, + 0xad, 0x46, 0x7f, 0x35, 0xff, 0xde, 0xe7, 0xcf, 0xf5, 0x7f, 0x55, 0xf0, 0xbc, + 0xc2, 0xda, 0x7b, 0x51, 0x34, 0x0c, 0xb0, 0x1c, 0x0e, 0x08, 0x26, 0x79, 0x35, + 0x8b, 0x35, 0x0d, 0xe2, 0x6d, 0x14, 0x28, 0x81, 0xa9, 0x81, 0x41, 0x26, 0xf1, + 0x3a, 0xa9, 0x55, 0x81, 0x8f, 0xcc, 0x5f, 0x7f, 0x7f, 0xd2, 0x13, 0xd9, 0xbc, + 0x00, 0x86, 0xc6, 0x7f, 0x25, 0xf6, 0x9b, 0xc2, 0x43, 0x7f, 0xf2, 0x1f, 0x23, + 0x37, 0x53, 0x3f, 0x3e, 0x1a, 0xbb, 0x08, 0x61, 0xdc, 0xf9, 0x9a, 0x22, 0xcf, + 0x9d, 0x2d, 0x7f, 0x35, 0xac, 0xe8, 0xf6, 0x9b, 0x7f, 0x03, 0xdc, 0xe5, 0xfa, + 0xfe, 0x7f, 0x96, 0xc0, 0x81, 0xbf, 0x39, 0xae, 0x4b, 0x29, 0x3d, 0x1e, 0xf0, + 0xaf, 0xe6, 0xc3, 0x7f, 0x8f, 0x22, 0xf3, 0x92, 0x7f, 0xaf, 0x79, 0x83, 0x22, + 0x27, 0x20, 0x7f, 0xb1, 0xdb, 0x54, 0x1b, 0x0a, 0xd2, 0x7f, 0x7f, 0xd1, 0x22, + 0xff, 0x21, 0x29, 0xf1, 0xc6, 0x20, 0x3d, 0x7a, 0xc1, 0xd2, 0xb7, 0xca, 0x7f, + 0x14, 0x2b, 0x7f, 0xf7, 0xa8, 0x4c, 0x1f, 0x08, 0x08, 0x5d, 0x7f, 0xbd, 0x31, + 0x02, 0x32, 0xf6, 0xbf, 0xa5, 0x90, 0x7f, 0x11, 0x9e, 0xf6, 0x28, 0x2d, 0x3d, + 0xfe, 0xda, 0x31, 0x2f, 0x01, 0x15, 0x0b, 0xcc, 0x26, 0x54, 0xb2, 0xf5, 0xd8, + 0x9d, 0x3b, 0xfd, 0x81, 0xca, 0x28, 0x69, 0xef, 0x52, 0x41, 0xd3, 0xec, 0x23, + 0x7f, 0x30, 0x53, 0x81, 0x3d, 0x23, 0xe0, 0x7f, 0xc2, 0xe7, 0x54, 0x68, 0x2a, + 0xd2, 0x11, 0x1e, 0xcf, 0xe0, 0xcd, 0x38, 0x7f, 0x7f, 0x37, 0x7f, 0xf1, 0x75, + 0x57, 0xf9, 0x0c, 0xf3, 0x17, 0xfa, 0x6a, 0x22, 0x11, 0x7f, 0xe2, 0x08, 0x36, + 0x14, 0x5f, 0xbb, 0x0e, 0xf7, 0x78, 0x59, 0x33, 0x78, 0x6c, 0xf9, 0x64, 0x0e, + 0x02, 0xc2, 0x02, 0x7f, 0xe7, 0x82, 0x1f, 0x31, 0x2e, 0x7f, 0x7f, 0x69, 0x16, + 0x7f, 0x20, 0xb3, 0x02, 0x3c, 0xeb, 0x5c, 0xd3, 0x07, 0x81, 0x54, 0x9a, 0x20, + 0xd1, 0xa8, 0x81, 0xdf, 0x33, 0x09, 0xc5, 0xf5, 0x7c, 0xe9, 0xf7, 0x18, 0x13, + 0x7f, 0xf0, 0xd8, 0xcf, 0xc8, 0xcf, 0xcb, 0xf4, 0xd1, 0x1c, 0x35, 0xc9, 0x26, + 0xba, 0xae, 0x3f, 0x31, 0x45, 0xf2, 0x26, 0xf6, 0xca, 0x10, 0xca, 0x94, 0x03, + 0x22, 0xd3, 0x81, 0x29, 0x4b, 0x73, 0x65, 0xea, 0x26, 0x3b, 0x42, 0x78, 0x29, + 0x0f, 0xc6, 0x1e, 0x5c, 0x85, 0x39, 0x81, 0x05, 0x7f, 0x89, 0x28, 0x52, 0x2c, + 0xda, 0x18, 0xdc, 0x1a, 0x43, 0x07, 0x29, 0x5a, 0xee, 0xf4, 0x14, 0x7f, 0xed, + 0xff, 0xbf, 0xe7, 0xa2, 0x3e, 0x7f, 0xb6, 0x1a, 0xf8, 0x2d, 0xfc, 0x97, 0xd9, + 0x12, 0x3f, 0x63, 0xff, 0x2e, 0x81, 0x2b, 0x39, 0x43, 0xf5, 0xfa, 0x77, 0x44, + 0x4e, 0x12, 0x7f, 0x3c, 0x74, 0x15, 0xb7, 0xd2, 0x3a, 0x4a, 0x72, 0xf4, 0x04, + 0x81, 0xad, 0xd9, 0x5a, 0xd8, 0x7f, 0xc2, 0x95, 0xeb, 0x2d, 0xde, 0x52, 0x7f, + 0xe8, 0xa0, 0x01, 0x0e, 0x1c, 0x39, 0x57, 0x01, 0x49, 0x7f, 0xf0, 0xfc, 0x24, + 0x24, 0xfe, 0xe6, 0x8b, 0xd0, 0x02, 0xba, 0x60, 0x10, 0x23, 0xc0, 0xac, 0xa5, + 0xa5, 0x2e, 0x1d, 0x8a, 0x7f, 0xfb, 0xca, 0xf9, 0xe7, 0xec, 0x29, 0x12, 0x94, + 0xab, 0xb6, 0x39, 0x3f, 0xe2, 0x7f, 0xf4, 0x24, 0x48, 0x51, 0x7f, 0x6f, 0x9c, + 0x3a, 0x33, 0xc8, 0x03, 0xe3, 0xb0, 0xf5, 0xad, 0x1d, 0x4b, 0xec, 0xd6, 0x01, + 0xc0, 0x7f, 0xb0, 0x3e, 0xe6, 0xf0, 0xe6, 0x97, 0x7c, 0x8b, 0xb7, 0x1a, 0x81, + 0x37, 0x81, 0x29, 0x33, 0x33, 0xc0, 0x7f, 0x81, 0x96, 0x81, 0xc3, 0x92, 0x62, + 0x30, 0xba, 0xb1, 0xc6, 0x6f, 0xc9, 0x32, 0xc1, 0x7f, 0x0e, 0xe6, 0x25, 0xde, + 0x4c, 0xc8, 0xff, 0x16, 0x37, 0xd7, 0xe8, 0xf3, 0x7f, 0xfc, 0x3a, 0xf3, 0xe2, + 0x81, 0xff, 0xd4, 0x5f, 0xaf, 0xea, 0xe4, 0xe8, 0x52, 0x60, 0x1c, 0x9c, 0x81, + 0x30, 0x7f, 0xaa, 0xa5, 0xb4, 0x54, 0x1f, 0x5b, 0x7f, 0x1c, 0x0f, 0xfc, 0xab, + 0x9e, 0xb0, 0xc6, 0xc9, 0x81, 0x7f, 0x20, 0x8d, 0xd4, 0xa1, 0x93, 0xb2, 0xe9, + 0xf9, 0xe5, 0x34, 0x5a, 0x86, 0xaa, 0x8a, 0x81, 0x2d, 0x03, 0xc6, 0xc0, 0x26, + 0x0e, 0xd4, 0xe3, 0x4f, 0xf3, 0x4c, 0x60, 0xd2, 0x61, 0x1c, 0x1e, 0x7f, 0xdc, + 0xba, 0x25, 0xcb, 0x9a, 0x50, 0xbd, 0x7f, 0xaa, 0x81, 0xc1, 0xeb, 0xb9, 0x52, + 0xe5, 0x1d, 0xff, 0xdd, 0xba, 0xdc, 0x18, 0x5e, 0xd1, 0x9f, 0xac, 0x7f, 0xe9, + 0x7f, 0xf3, 0x7f, 0x2d, 0x7e, 0xed, 0xb5, 0x15, 0xda, 0x9d, 0x23, 0x56, 0x6b, + 0xa2, 0xcc, 0x2f, 0x81, 0x36, 0xb8, 0x07, 0x45, 0xaf, 0x01, 0x0d, 0x73, 0x2f, + 0x45, 0xf3, 0x19, 0xd8, 0x21, 0x4f, 0x31, 0xe4, 0x7f, 0xdb, 0xb9, 0xdf, 0xa5, + 0x0c, 0x10, 0xad, 0xa0, 0x5c, 0xd0, 0x6d, 0xc1, 0xe9, 0x20, 0xa4, 0x7f, 0x35, + 0xfe, 0xc3, 0x23, 0x7e, 0x43, 0x42, 0x13, 0x07, 0x21, 0xcc, 0x15, 0xac, 0x8e, + 0xca, 0xcc, 0x47, 0x5c, 0x7f, 0xc7, 0x2f, 0x81, 0x09, 0x37, 0xda, 0xee, 0x96, + 0x4a, 0x03, 0x93, 0xcf, 0xc4, 0xd7, 0xe2, 0x7f, 0xca, 0xba, 0x2d, 0x1a, 0xf6, + 0x1c, 0xec, 0xf7, 0xc9, 0x7f, 0x40, 0x48, 0x7f, 0x97, 0x74, 0x43, 0xda, 0x74, + 0x14, 0xe1, 0x3e, 0x96, 0x32, 0x25, 0xd9, 0x21, 0x7f, 0xba, 0x53, 0xd3, 0x76, + 0xd2, 0x14, 0xc2, 0xa9, 0xd5, 0x2c, 0xa3, 0x9d, 0x9e, 0x45, 0x87, 0x14, 0x0a, + 0xae, 0xdc, 0x1a, 0x1c, 0xe1, 0xbb, 0xc1, 0x83, 0x7f, 0x7f, 0xe6, 0xba, 0xcd, + 0x7f, 0x4b, 0x7f, 0xcc, 0x49, 0xd8, 0x36, 0x7f, 0x8e, 0xb6, 0xfc, 0xff, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x81, 0xd9, 0xb1, 0x81, 0x51, 0x0d, + 0x56, 0x42, 0xa4, 0x72, 0xe6, 0xd3, 0x0e, 0x5e, 0xae, 0x23, 0xd1, 0x7f, 0x4a, + 0xe6, 0x0b, 0x0f, 0x24, 0xb8, 0x60, 0x38, 0xf1, 0x3c, 0xf2, 0xeb, 0xed, 0xf8, + 0xe3, 0x37, 0xd9, 0x14, 0x40, 0x35, 0xa9, 0x1c, 0x98, 0x2c, 0x7f, 0x7f, 0xbe, + 0x27, 0x22, 0x37, 0xe3, 0xdd, 0x54, 0xce, 0x9d, 0x11, 0xf6, 0xf4, 0x2b, 0xf3, + 0x40, 0x6d, 0x0b, 0xf5, 0x7f, 0xab, 0xac, 0x0b, 0xaf, 0x81, 0xf5, 0x6e, 0xf4, + 0xd1, 0xd0, 0x81, 0xdb, 0x44, 0x91, 0x99, 0x27, 0xbc, 0x46, 0xa7, 0xd6, 0x20, + 0x0c, 0xa1, 0x81, 0x2e, 0xba, 0xda, 0xc8, 0x2b, 0xd6, 0xa1, 0xdd, 0x15, 0x12, + 0xdf, 0x26, 0x4d, 0xe2, 0xe8, 0xeb, 0xe7, 0x08, 0xd4, 0xb5, 0xd2, 0xa0, 0x7f, + 0xb0, 0x4b, 0xe0, 0x95, 0xb9, 0xc3, 0xb6, 0xcf, 0xc3, 0xc5, 0xad, 0xeb, 0x12, + 0xd4, 0x2f, 0x0a, 0xb1, 0x5e, 0x5d, 0x7f, 0x1e, 0xbb, 0x49, 0xc0, 0x10, 0x7f, + 0xea, 0x8a, 0xa7, 0x4b, 0x47, 0x7f, 0x40, 0x7f, 0xa5, 0x46, 0xf6, 0xda, 0x27, + 0x2f, 0x3a, 0xdc, 0xb6, 0x7f, 0x59, 0x6e, 0xf0, 0x1b, 0x2b, 0x76, 0x1b, 0x72, + 0x8f, 0x77, 0x7f, 0xf3, 0xeb, 0x06, 0xb2, 0xdc, 0x22, 0x38, 0x40, 0x5e, 0x59, + 0x1e, 0x49, 0x6d, 0xe0, 0xe8, 0x09, 0x7f, 0x34, 0x7f, 0x7f, 0x3f, 0x52, 0x34, + 0x7f, 0x99, 0x39, 0xf0, 0xd0, 0x2b, 0xb6, 0x96, 0x87, 0x62, 0xd9, 0x91, 0x93, + 0x8a, 0x3d, 0x0a, 0x8b, 0xf9, 0x97, 0x7f, 0x7f, 0xb0, 0x04, 0x72, 0x4d, 0xb1, + 0x22, 0x7f, 0xae, 0x34, 0xf1, 0x3a, 0xd1, 0x81, 0xac, 0xa0, 0x27, 0x7f, 0x26, + 0x7f, 0xa1, 0xc0, 0xa7, 0x7f, 0x81, 0xc8, 0x81, 0x18, 0xad, 0xdc, 0x9d, 0x0c, + 0x51, 0xd5, 0xb4, 0xf0, 0xb0, 0xdf, 0x16, 0xf0, 0x87, 0x92, 0xf3, 0x1a, 0x7f, + 0x8c, 0x83, 0x55, 0x7c, 0x43, 0xe8, 0x9d, 0x07, 0xf3, 0x7f, 0x24, 0x81, 0xbb, + 0x19, 0x20, 0x2a, 0x1a, 0xa2, 0x61, 0xcb, 0xa2, 0x24, 0xde, 0xc2, 0x39, 0x16, + 0xa4, 0xa6, 0x57, 0xfe, 0x61, 0xd6, 0x46, 0xf0, 0xec, 0x7f, 0x24, 0xcf, 0xe1, + 0x4c, 0xe6, 0x0f, 0xfb, 0xeb, 0xc2, 0x60, 0x7c, 0x53, 0x55, 0xcd, 0x7f, 0xd9, + 0x06, 0xe5, 0xd4, 0xde, 0x1b, 0x0e, 0x38, 0x35, 0x22, 0x27, 0x17, 0x19, 0x29, + 0x59, 0xe0, 0xce, 0xf3, 0x81, 0x9f, 0xd6, 0x74, 0xf2, 0x65, 0xe4, 0x9a, 0x7f, + 0xd5, 0xd1, 0xc3, 0xb8, 0xe2, 0x50, 0x9e, 0x4b, 0x35, 0xfb, 0xab, 0x46, 0x0b, + 0xd1, 0xdc, 0xdb, 0x22, 0xc6, 0xbf, 0xce, 0xe7, 0x08, 0x51, 0xfa, 0xcf, 0x9a, + 0x99, 0xad, 0x30, 0x9c, 0xa9, 0x8b, 0xef, 0x9e, 0xec, 0x98, 0x7f, 0x7f, 0xd5, + 0x7f, 0x35, 0xb1, 0xdb, 0x22, 0xba, 0xe9, 0xc2, 0xf2, 0xdf, 0x89, 0x24, 0xe7, + 0x23, 0xfb, 0xdd, 0x23, 0xd3, 0x12, 0x94, 0x2a, 0x13, 0xd8, 0x8f, 0x81, 0xc8, + 0x3d, 0xca, 0xbc, 0x55, 0xd4, 0x71, 0xe2, 0xc3, 0x01, 0x34, 0xb2, 0xf4, 0x5c, + 0xa8, 0x13, 0xe8, 0x7c, 0x97, 0xe9, 0xeb, 0x9c, 0x7f, 0xb1, 0x32, 0x2b, 0x7f, + 0xcb, 0x1b, 0xb0, 0x7f, 0x24, 0x33, 0x49, 0x7f, 0x34, 0xe3, 0x13, 0xb8, 0x61, + 0xb8, 0x7f, 0x3a, 0x37, 0xd1, 0x27, 0x65, 0xeb, 0x0f, 0x0c, 0xc7, 0x5e, 0x6b, + 0xc6, 0x22, 0x03, 0x8a, 0xf3, 0x81, 0xc6, 0xeb, 0x14, 0xd7, 0x14, 0xf7, 0xb3, + 0xd3, 0x51, 0x0e, 0x41, 0x92, 0x03, 0x7f, 0x45, 0xd8, 0x8d, 0xe6, 0x18, 0x07, + 0x00, 0x69, 0xd1, 0x98, 0xa1, 0x8d, 0x23, 0xd1, 0xe7, 0x2e, 0xe3, 0x72, 0xe0, + 0xf2, 0xdf, 0x93, 0x21, 0xf6, 0xf6, 0x2d, 0x81, 0xf7, 0xe2, 0xfd, 0xa8, 0x14, + 0xad, 0xa6, 0x94, 0x99, 0xcc, 0xcd, 0x7f, 0xfe, 0x35, 0x89, 0x8e, 0x2b, 0x4c, + 0x2e, 0xdf, 0xb3, 0x36, 0x81, 0xbc, 0x32, 0xa4, 0x81, 0xa6, 0x7f, 0x47, 0x43, + 0x8e, 0x68, 0x7f, 0x26, 0x7f, 0xbb, 0x7f, 0x7f, 0xa1, 0xcb, 0x0f, 0x17, 0x7f, + 0x77, 0x4f, 0x57, 0xb2, 0xef, 0x0a, 0x28, 0xb6, 0x2f, 0x19, 0xf7, 0x89, 0x23, + 0xbd, 0xdc, 0x10, 0x26, 0x7f, 0x3e, 0x7f, 0x07, 0x7f, 0x47, 0x9b, 0x81, 0x68, + 0x1f, 0x7f, 0x10, 0x2f, 0x7f, 0x7f, 0xfc, 0x58, 0x81, 0xfa, 0x7f, 0xb6, 0x7f, + 0xcb, 0x8e, 0x40, 0xcb, 0x67, 0xd9, 0x7f, 0x9d, 0xfe, 0xbf, 0xd8, 0xa6, 0x7f, + 0x3e, 0x5f, 0xd2, 0xaf, 0x00, 0x7f, 0x81, 0xd6, 0x18, 0x07, 0x52, 0x2b, 0x79, + 0xeb, 0xaf, 0xcd, 0xb0, 0x4d, 0x4b, 0x4a, 0x6d, 0xe6, 0x7f, 0xaf, 0x5e, 0x9c, + 0xc6, 0x46, 0x38, 0x18, 0xd2, 0xc0, 0xff, 0x4a, 0xf3, 0xb7, 0xe1, 0xe5, 0x81, + 0x7f, 0xb4, 0xbb, 0x7f, 0x7f, 0x7f, 0xdc, 0x81, 0xdb, 0x4f, 0x3b, 0x09, 0x02, + 0xc1, 0x19, 0xfb, 0xff, 0x23, 0xdc, 0xa5, 0x00, 0x52, 0x7f, 0xfe, 0x9d, 0x4d, + 0xe9, 0xed, 0xe5, 0xd5, 0x05, 0x37, 0xd5, 0xeb, 0xdd, 0xe9, 0x22, 0x7f, 0x04, + 0x7f, 0xc5, 0x7f, 0x68, 0x5c, 0x81, 0xc8, 0x27, 0x29, 0x8f, 0xe8, 0x81, 0xa3, + 0x03, 0x35, 0x40, 0x61, 0x26, 0x0a, 0x4d, 0xcd, 0xf6, 0xac, 0x07, 0x0d, 0xf8, + 0x72, 0x03, 0x17, 0x34, 0x14, 0x01, 0xb7, 0x3c, 0xa9, 0xd4, 0x0b, 0xcd, 0xb3, + 0xfa, 0x86, 0x40, 0x7f, 0x16, 0x8b, 0x4f, 0x98, 0x42, 0xc0, 0x37, 0x03, 0xc4, + 0xc4, 0x94, 0x43, 0x02, 0xd2, 0x23, 0xf9, 0xf3, 0xde, 0xd1, 0x7f, 0xe8, 0x8b, + 0x81, 0x81, 0x05, 0x0a, 0x5b, 0x0c, 0x81, 0x43, 0xf7, 0x3c, 0x9a, 0xcc, 0x5b, + 0xfd, 0xf6, 0xc7, 0x98, 0x0b, 0x0e, 0xf0, 0x58, 0x77, 0x81, 0x98, 0xff, 0xa0, + 0xb4, 0x2d, 0x7a, 0xdd, 0xaf, 0xa5, 0x78, 0x2e, 0x7d, 0xc6, 0x7f, 0xb3, 0x22, + 0x43, 0xc3, 0x09, 0xb6, 0x8b, 0xe9, 0xe9, 0x37, 0x5d, 0x81, 0xcc, 0xde, 0x94, + 0xcb, 0x9c, 0x1f, 0xd8, 0xac, 0x81, 0x6e, 0xb3, 0xb5, 0xc7, 0x4e, 0xb3, 0x40, + 0x0e, 0xf2, 0xe9, 0x82, 0x16, 0xe8, 0x4b, 0x81, 0x7f, 0xdc, 0x40, 0xd4, 0xfb, + 0x7c, 0xbe, 0xeb, 0xec, 0x48, 0xe8, 0x7f, 0xaa, 0x3b, 0x2c, 0x1d, 0xbd, 0xc5, + 0xc1, 0xc4, 0x7f, 0xec, 0xfe, 0xda, 0x33, 0x81, 0x0f, 0x8c, 0xe7, 0x07, 0x13, + 0xb6, 0xf6, 0x33, 0x3b, 0x36, 0x81, 0xc5, 0x81, 0xf9, 0xf7, 0xcf, 0xb8, 0x07, + 0x1b, 0x25, 0x8c, 0xeb, 0x0a, 0x61, 0x24, 0xe7, 0xe5, 0x64, 0xd8, 0x8c, 0xb5, + 0x89, 0xad, 0x14, 0xa5, 0xa7, 0x5f, 0x9f, 0xec, 0x9d, 0xdb, 0x1f, 0xeb, 0x38, + 0x12, 0x50, 0x04, 0x05, 0x7f, 0xd5, 0x0d, 0xdf, 0xaf, 0x07, 0xaa, 0x88, 0xe9, + 0x22, 0x03, 0x42, 0xbb, 0x81, 0xb6, 0x5f, 0xb5, 0x74, 0x92, 0x7f, 0x4b, 0x89, + 0xe2, 0x95, 0x9e, 0x85, 0xfd, 0x11, 0x32, 0xb3, 0x58, 0x2e, 0xe0, 0xc8, 0xa2, + 0x1a, 0x6f, 0x81, 0x97, 0x7f, 0x97, 0xc6, 0x28, 0x41, 0x5a, 0x7f, 0xdc, 0xec, + 0x98, 0xba, 0x7f, 0x00, 0x1b, 0xa0, 0x6e, 0xc7, 0xc6, 0xd2, 0x1c, 0x33, 0xcf, + 0x3b, 0xe3, 0x5b, 0x68, 0x04, 0xb6, 0x39, 0x4d, 0x3d, 0xb0, 0x8c, 0x51, 0x26, + 0x5e, 0xd6, 0x9d, 0xeb, 0x1a, 0x05, 0xf7, 0xbe, 0xc8, 0x7f, 0x67, 0x7f, 0xc1, + 0x70, 0x3d, 0xf9, 0xb8, 0x6e, 0xbc, 0x37, 0xd4, 0xf9, 0xe2, 0x7f, 0x23, 0x33, + 0xe7, 0x9a, 0xf9, 0x7f, 0x7f, 0x7f, 0x61, 0x7f, 0xa7, 0xc2, 0xcc, 0x81, 0x01, + 0x7f, 0xd7, 0xa5, 0x6a, 0x81, 0xca, 0x88, 0x81, 0x4d, 0x59, 0x75, 0xb6, 0xc3, + 0xfd, 0x0c, 0x17, 0xcc, 0x7f, 0xab, 0xb6, 0x01, 0x89, 0x09, 0x22, 0x70, 0xf5, + 0xc1, 0xba, 0xf8, 0xfb, 0xd6, 0xfc, 0x65, 0x8c, 0x32, 0x63, 0xfd, 0xf1, 0xce, + 0x15, 0xbe, 0x13, 0x25, 0x73, 0xa2, 0xbf, 0xe6, 0xbe, 0xbb, 0x81, 0x2c, 0x53, + 0xe7, 0xa1, 0x48, 0x8d, 0xeb, 0xf5, 0x7f, 0x05, 0x13, 0x2f, 0x23, 0x02, 0xbd, + 0xf1, 0xff, 0xf5, 0xec, 0x4c, 0xd4, 0xe9, 0xca, 0xd4, 0x30, 0xf1, 0xb0, 0xe9, + 0x29, 0x7f, 0x42, 0x02, 0x30, 0x5b, 0x61, 0xa1, 0xed, 0x32, 0x31, 0x33, 0x0d, + 0x00, 0xda, 0xae, 0x91, 0x1f, 0x8e, 0x01, 0x2e, 0x46, 0x55, 0x36, 0x1c, 0x17, + 0x1e, 0xe2, 0x7f, 0xa1, 0x0f, 0xff, 0x6d, 0x81, 0x19, 0x28, 0xf6, 0xb1, 0xe9, + 0x0b, 0xb0, 0x4c, 0xb7, 0xa9, 0x3b, 0xe7, 0x84, 0x98, 0xc7, 0x26, 0xda, 0xa6, + 0x95, 0x27, 0xb7, 0x07, 0x20, 0xde, 0x4a, 0x7f, 0x7f, 0xcc, 0xf6, 0x01, 0x32, + 0xea, 0x31, 0x74, 0x93, 0x9e, 0xf0, 0x81, 0x81, 0xee, 0xf6, 0xfe, 0xae, 0xd6, + 0x55, 0x81, 0x1a, 0xbb, 0xfc, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0xcc, 0x1b, 0x00, 0x00, 0x82, 0x1f, 0x00, 0x00, 0xeb, 0x2d, 0x00, 0x00, + 0x9a, 0x2d, 0x00, 0x00, 0xff, 0x26, 0x00, 0x00, 0x2f, 0x35, 0x00, 0x00, 0x95, + 0xd4, 0xff, 0xff, 0xef, 0x14, 0x00, 0x00, 0xf3, 0x2f, 0x00, 0x00, 0xad, 0xe7, + 0xff, 0xff, 0x14, 0xd3, 0xff, 0xff, 0xcf, 0x0b, 0x00, 0x00, 0xb5, 0x19, 0x00, + 0x00, 0x22, 0x01, 0x00, 0x00, 0x2c, 0x18, 0x00, 0x00, 0xe6, 0xea, 0xff, 0xff, + 0xbf, 0x0a, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, 0x15, 0xcc, 0xff, 0xff, 0xf9, + 0xf0, 0xff, 0xff, 0xfc, 0xea, 0xff, 0xff, 0x04, 0xe3, 0xff, 0xff, 0x68, 0x9d, + 0xff, 0xff, 0x8a, 0xdd, 0xff, 0xff, 0x7f, 0x15, 0x00, 0x00, 0x14, 0xee, 0xff, + 0xff, 0x7e, 0x12, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0xe3, 0x42, 0x00, 0x00, + 0xb2, 0xee, 0xff, 0xff, 0x2a, 0xed, 0xff, 0xff, 0x67, 0x1a, 0x00, 0x00, 0xbf, + 0xff, 0xff, 0xff, 0xdd, 0x3a, 0x00, 0x00, 0xff, 0xc9, 0xff, 0xff, 0x0a, 0xf7, + 0xff, 0xff, 0x89, 0xdb, 0xff, 0xff, 0x97, 0xf0, 0xff, 0xff, 0x30, 0x16, 0x00, + 0x00, 0x15, 0xfd, 0xff, 0xff, 0x52, 0x18, 0x00, 0x00, 0xbb, 0xf5, 0xff, 0xff, + 0xf4, 0xff, 0xff, 0xff, 0xb8, 0x23, 0x00, 0x00, 0x58, 0x2d, 0x00, 0x00, 0xc3, + 0xfe, 0xff, 0xff, 0xe7, 0x34, 0x00, 0x00, 0x8d, 0xcf, 0xff, 0xff, 0x3c, 0x34, + 0x00, 0x00, 0x21, 0x52, 0x00, 0x00, 0x98, 0x26, 0x00, 0x00, 0xc3, 0xef, 0xff, + 0xff, 0x40, 0xf3, 0xff, 0xff, 0xd8, 0x1f, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, + 0x6e, 0xf8, 0xff, 0xff, 0x67, 0x13, 0x00, 0x00, 0x53, 0x17, 0x00, 0x00, 0xcd, + 0xb2, 0xff, 0xff, 0xaf, 0xe6, 0xff, 0xff, 0x6a, 0x1d, 0x00, 0x00, 0xda, 0x27, + 0x00, 0x00, 0xf1, 0x1c, 0x00, 0x00, 0x99, 0x15, 0x00, 0x00, 0x40, 0x08, 0x00, + 0x00, 0x75, 0xd8, 0xff, 0xff, 0x19, 0xdf, 0xff, 0xff, 0x49, 0xfa, 0xff, 0xff, + 0xc0, 0x26, 0x00, 0x00, 0x61, 0x26, 0x00, 0x00, 0xa6, 0x41, 0x00, 0x00, 0x1b, + 0xf3, 0xff, 0xff, 0x64, 0x05, 0x00, 0x00, 0x38, 0x17, 0x00, 0x00, 0x80, 0x3e, + 0x00, 0x00, 0x7e, 0xe7, 0xff, 0xff, 0xd2, 0xd5, 0xff, 0xff, 0xd6, 0xcd, 0xff, + 0xff, 0xe7, 0xde, 0xff, 0xff, 0xad, 0xf9, 0xff, 0xff, 0xc2, 0xe6, 0xff, 0xff, + 0xaf, 0xe5, 0xff, 0xff, 0x35, 0x43, 0x00, 0x00, 0xc1, 0x02, 0x00, 0x00, 0xcf, + 0xfe, 0xff, 0xff, 0x29, 0x1d, 0x00, 0x00, 0x7c, 0xef, 0xff, 0xff, 0x37, 0x0e, + 0x00, 0x00, 0x81, 0x13, 0x00, 0x00, 0x15, 0x31, 0x00, 0x00, 0xb6, 0x26, 0x00, + 0x00, 0x2b, 0x21, 0x00, 0x00, 0x1b, 0xf9, 0xff, 0xff, 0x1d, 0x03, 0x00, 0x00, + 0x71, 0xfd, 0xff, 0xff, 0xf0, 0x1e, 0x00, 0x00, 0x33, 0x21, 0x00, 0x00, 0x03, + 0xfd, 0xff, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0x92, 0xea, 0xff, 0xff, 0x33, 0x08, + 0x00, 0x00, 0x3e, 0xe2, 0xff, 0xff, 0x7e, 0xe2, 0xff, 0xff, 0xc3, 0x12, 0x00, + 0x00, 0x3b, 0xda, 0xff, 0xff, 0x81, 0xf0, 0xff, 0xff, 0x5f, 0x28, 0x00, 0x00, + 0x6f, 0x2c, 0x00, 0x00, 0x8e, 0xf4, 0xff, 0xff, 0xe4, 0xd7, 0xff, 0xff, 0xa7, + 0x23, 0x00, 0x00, 0xe5, 0xe8, 0xff, 0xff, 0xc9, 0xee, 0xff, 0xff, 0xdf, 0x15, + 0x00, 0x00, 0x10, 0x2e, 0x00, 0x00, 0xf9, 0x14, 0x00, 0x00, 0x99, 0xc5, 0xff, + 0xff, 0x47, 0x17, 0x00, 0x00, 0x25, 0x1e, 0x00, 0x00, 0x31, 0x40, 0x00, 0x00, + 0x01, 0xfd, 0xff, 0xff, 0x9e, 0x0c, 0x00, 0x00, 0x50, 0x20, 0x00, 0x00, 0xba, + 0x50, 0x00, 0x00, 0x3e, 0xf3, 0xff, 0xff, 0x5b, 0xfe, 0xff, 0xff, 0x16, 0xe2, + 0xff, 0xff, 0x45, 0xfc, 0xff, 0xff, 0x26, 0xbd, 0xfc, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x2f, 0xf6, 0xb9, 0xd7, 0x23, 0xf5, 0x3b, 0xe2, + 0x24, 0xbf, 0x2c, 0xf9, 0x38, 0x0f, 0x25, 0xc9, 0x00, 0x27, 0xe0, 0xd5, 0x10, + 0x9f, 0xf4, 0x11, 0xd1, 0x25, 0xf0, 0x28, 0x73, 0xc2, 0x11, 0xd8, 0xfc, 0x1f, + 0x3b, 0x1a, 0xed, 0x16, 0xf3, 0xcc, 0x01, 0xdd, 0xce, 0x45, 0x1d, 0xd9, 0x3a, + 0x3c, 0xfc, 0xa9, 0x3c, 0x31, 0xe4, 0xb8, 0xc3, 0x7f, 0xfd, 0x63, 0x00, 0x12, + 0xdf, 0xfd, 0x56, 0xe6, 0x38, 0xf7, 0x0d, 0x27, 0xee, 0xef, 0x1a, 0xe2, 0xc2, + 0xf7, 0x06, 0x01, 0xe1, 0xa3, 0x6a, 0x00, 0xc4, 0x02, 0x24, 0x34, 0xfc, 0xeb, + 0xd5, 0x10, 0xcf, 0xc8, 0x10, 0xeb, 0x49, 0xf9, 0x04, 0x14, 0xf7, 0xc7, 0xff, + 0x23, 0x4b, 0x3c, 0x4f, 0x0c, 0x21, 0x22, 0xb5, 0xf6, 0xd4, 0xd4, 0xde, 0x02, + 0xe6, 0x39, 0x16, 0xfe, 0x73, 0xb6, 0x04, 0x16, 0x12, 0xee, 0xf4, 0x66, 0xe3, + 0x00, 0x0c, 0xd6, 0xbf, 0x2e, 0xd9, 0x02, 0xd9, 0xc6, 0x35, 0x25, 0xdb, 0x3e, + 0x04, 0xc1, 0x17, 0xe5, 0x40, 0x9c, 0x0e, 0xf6, 0xc8, 0xa8, 0x00, 0x54, 0x4a, + 0x2d, 0xd2, 0xb7, 0xb5, 0xfe, 0xe2, 0x4c, 0x30, 0x34, 0xfe, 0xfc, 0x05, 0x32, + 0x46, 0x19, 0xca, 0xe6, 0x77, 0x17, 0x81, 0x62, 0xf0, 0xc7, 0x04, 0x4a, 0x51, + 0x18, 0x0f, 0x07, 0xa3, 0x1b, 0xe3, 0xc0, 0x63, 0x03, 0x01, 0x33, 0x14, 0x17, + 0x35, 0x2e, 0x78, 0x2f, 0x03, 0xdd, 0xf6, 0x53, 0x1c, 0x11, 0x59, 0x23, 0x14, + 0xdc, 0xd7, 0x04, 0xcb, 0x3c, 0x46, 0x0c, 0x2c, 0xa5, 0xf5, 0xf1, 0xef, 0xd8, + 0x4a, 0xcd, 0x3f, 0xb5, 0x37, 0x46, 0xef, 0x56, 0x07, 0x39, 0x19, 0xe7, 0x64, + 0xf1, 0x37, 0x28, 0xe5, 0x24, 0x18, 0x36, 0xe3, 0xc9, 0x64, 0x4c, 0x25, 0x76, + 0xd8, 0x00, 0xfd, 0x83, 0xfd, 0x4c, 0x0c, 0x3a, 0xe9, 0xc3, 0x17, 0x6c, 0xeb, + 0xe0, 0x48, 0x36, 0x07, 0xd7, 0xe2, 0x15, 0xd5, 0xf9, 0xff, 0x05, 0x0a, 0xee, + 0xae, 0x15, 0x09, 0x34, 0xb7, 0x0f, 0xc5, 0xbb, 0xf9, 0xca, 0xbe, 0x13, 0xa9, + 0xa8, 0xd5, 0x60, 0x81, 0xfb, 0x0c, 0x33, 0xf4, 0xd9, 0xf8, 0x31, 0xff, 0x23, + 0x13, 0x13, 0xda, 0x95, 0xfa, 0xe7, 0x4c, 0xc5, 0xe7, 0x5e, 0xf3, 0xc6, 0x1f, + 0x3e, 0xbd, 0x32, 0xe7, 0xe6, 0x35, 0xd5, 0x02, 0x42, 0x3d, 0x05, 0x08, 0xde, + 0xc0, 0x2d, 0x31, 0x94, 0xf4, 0x2c, 0x05, 0xd2, 0xf3, 0xd2, 0xf9, 0xc5, 0x13, + 0x63, 0x22, 0x1e, 0xfa, 0xea, 0x12, 0xc4, 0xb4, 0x22, 0xdf, 0xf0, 0xf9, 0x0d, + 0xfb, 0x35, 0xdd, 0xe9, 0xe4, 0xdb, 0x46, 0xe1, 0x91, 0x1b, 0x2b, 0x10, 0xc4, + 0xc6, 0x16, 0xff, 0xfe, 0xe2, 0x12, 0xfa, 0xbf, 0x18, 0x0d, 0xe0, 0xf1, 0xc6, + 0x1a, 0x49, 0x14, 0xf2, 0x04, 0xf3, 0xe1, 0x1a, 0xbd, 0x0e, 0x5b, 0xa7, 0x41, + 0x2a, 0xed, 0xf0, 0x00, 0x35, 0xe8, 0x1c, 0xe5, 0x2a, 0x35, 0x0b, 0x73, 0x23, + 0xe6, 0x00, 0x0d, 0xf8, 0x09, 0x1e, 0xe4, 0x26, 0x0e, 0x2b, 0xc3, 0x3e, 0x08, + 0x17, 0x15, 0xb7, 0xd5, 0xfe, 0xb7, 0xd1, 0x1a, 0x0e, 0xbd, 0x56, 0x13, 0xcd, + 0x2b, 0x19, 0x06, 0xca, 0xd2, 0x31, 0xcf, 0x0c, 0x3a, 0x0b, 0x19, 0x44, 0xe3, + 0x10, 0xe1, 0x15, 0x18, 0x00, 0x0c, 0x1c, 0x0d, 0xe9, 0x05, 0xdb, 0x3e, 0x40, + 0xeb, 0xb1, 0x08, 0x72, 0xe5, 0x31, 0x56, 0xd7, 0xde, 0xfb, 0x31, 0x00, 0x55, + 0x10, 0xc3, 0x12, 0xfa, 0xf1, 0x15, 0x7b, 0xef, 0xdd, 0x04, 0x20, 0xc7, 0x15, + 0x13, 0xf9, 0x35, 0x0b, 0xe8, 0x2a, 0xff, 0xf8, 0x7f, 0xdd, 0x47, 0xf7, 0xd1, + 0x19, 0x02, 0xfb, 0x02, 0x55, 0xd5, 0x15, 0xe5, 0x43, 0x21, 0xbf, 0x0b, 0xd8, + 0x14, 0x28, 0x0a, 0xd9, 0x12, 0x36, 0x40, 0xf4, 0xfc, 0x22, 0xf2, 0x25, 0x7f, + 0x06, 0x23, 0x01, 0x39, 0xfb, 0xeb, 0xfb, 0xff, 0xdd, 0x1f, 0xee, 0xcd, 0xd0, + 0x10, 0x07, 0xed, 0x17, 0x3e, 0x09, 0xdf, 0x1a, 0xfa, 0x07, 0x36, 0xd5, 0x31, + 0xdf, 0xf3, 0x06, 0xe7, 0x00, 0x1b, 0x10, 0x13, 0x01, 0xee, 0xf5, 0xdc, 0xe9, + 0xe6, 0x24, 0x13, 0x03, 0x00, 0x07, 0xde, 0xe7, 0xdc, 0x02, 0x32, 0xeb, 0xf7, + 0xcf, 0x06, 0xc1, 0xde, 0xba, 0xf4, 0x07, 0x2a, 0x06, 0xf2, 0xeb, 0xce, 0x1e, + 0xe7, 0xcf, 0xfa, 0x01, 0xce, 0xdb, 0x08, 0x24, 0x42, 0xe2, 0x1b, 0x0e, 0xd8, + 0xe8, 0xde, 0xeb, 0xa9, 0xe9, 0xe5, 0x1b, 0x33, 0xe7, 0xe7, 0xde, 0x30, 0x33, + 0x6f, 0xfd, 0xc5, 0x1c, 0xe7, 0x0a, 0xf3, 0xdb, 0xf0, 0x11, 0xf4, 0x07, 0x30, + 0xe8, 0x00, 0x04, 0xc8, 0x13, 0x3e, 0x0a, 0x52, 0x2a, 0xba, 0x31, 0x13, 0xee, + 0x1e, 0x07, 0x1e, 0x10, 0xe8, 0xe6, 0xf8, 0xe6, 0xd5, 0x2a, 0x06, 0x0b, 0xc5, + 0xdb, 0xff, 0x45, 0xf8, 0x0d, 0x25, 0x26, 0x1b, 0xe4, 0xc6, 0x1c, 0xe5, 0x07, + 0xfc, 0x12, 0x70, 0xfe, 0xd3, 0x1c, 0x00, 0xc5, 0xcf, 0xbd, 0x11, 0x01, 0x1e, + 0xe7, 0xe5, 0x25, 0x06, 0x02, 0xfc, 0xbc, 0x01, 0x4b, 0xc3, 0xe8, 0xf1, 0xa9, + 0x54, 0x1d, 0x03, 0x32, 0xaf, 0xd1, 0x0e, 0xdd, 0xf6, 0x37, 0xe9, 0x81, 0x0b, + 0x41, 0x29, 0x92, 0x0a, 0x56, 0x0d, 0xd2, 0xe0, 0x08, 0xfb, 0xf6, 0xa3, 0xf3, + 0x1f, 0xe6, 0xd9, 0xcb, 0x28, 0x4d, 0x34, 0x43, 0x75, 0xdd, 0x1f, 0x47, 0xf8, + 0xea, 0xfd, 0xd7, 0x0e, 0xf8, 0xd8, 0x09, 0xf8, 0x3c, 0x03, 0xee, 0x1c, 0xe1, + 0x2b, 0xdd, 0x06, 0xdc, 0x07, 0xc9, 0xc4, 0xc1, 0xe0, 0xca, 0x2c, 0xe3, 0x30, + 0xfc, 0x2e, 0xe6, 0xf3, 0xff, 0x0f, 0x78, 0x18, 0x60, 0x15, 0x06, 0xf5, 0xbf, + 0x01, 0x00, 0xf0, 0x39, 0x01, 0xfd, 0xcb, 0x03, 0xff, 0xbb, 0xca, 0x09, 0xe9, + 0xe7, 0x81, 0xf5, 0x28, 0xb2, 0x4d, 0x05, 0xc4, 0xe0, 0x27, 0x14, 0x02, 0x0e, + 0x30, 0xf4, 0xee, 0x13, 0xd4, 0x58, 0x0f, 0x07, 0x16, 0x13, 0x48, 0x05, 0x17, + 0xc1, 0x13, 0xf0, 0xdf, 0x00, 0xcd, 0xe6, 0xf3, 0x0c, 0x05, 0x00, 0x2c, 0x0d, + 0xfe, 0x0a, 0x25, 0x03, 0xf8, 0x09, 0xf9, 0x2d, 0x08, 0xf8, 0x00, 0xf4, 0x20, + 0x0c, 0xf3, 0x34, 0x16, 0x0e, 0xee, 0xe7, 0x0a, 0xce, 0xeb, 0x0d, 0xe6, 0xff, + 0x52, 0xe3, 0xdb, 0xff, 0x17, 0x9d, 0x32, 0xd5, 0xe2, 0x0e, 0xd3, 0xec, 0x2a, + 0x4d, 0xf8, 0xe7, 0x47, 0x12, 0x1e, 0x20, 0x01, 0xfe, 0x01, 0xdf, 0x1a, 0xf4, + 0xfe, 0xea, 0xfa, 0xbd, 0x24, 0x3c, 0x0a, 0x2b, 0xef, 0xe8, 0x31, 0x1c, 0xe8, + 0xf9, 0xec, 0xf6, 0x07, 0xf1, 0x1e, 0xdb, 0x0c, 0x35, 0x0f, 0x0b, 0xf6, 0x01, + 0x76, 0x22, 0x1a, 0xc8, 0x07, 0x0f, 0x07, 0xd7, 0x12, 0x1f, 0x1f, 0x04, 0xef, + 0xfa, 0xf7, 0x22, 0x1d, 0x3e, 0x1b, 0x98, 0x0e, 0x0b, 0xf8, 0x0e, 0x1a, 0x06, + 0xff, 0xf8, 0xbf, 0x3f, 0x0f, 0xd3, 0x49, 0xff, 0xdf, 0x7f, 0xd8, 0xcd, 0xe7, + 0x1d, 0xd8, 0x26, 0x2a, 0xdb, 0xed, 0x14, 0x5f, 0xe3, 0xdd, 0x20, 0xe8, 0x0d, + 0xfe, 0x45, 0xfc, 0x39, 0xf8, 0x07, 0xda, 0xfc, 0xff, 0xd9, 0xf0, 0x38, 0x1b, + 0xed, 0x08, 0xf6, 0x05, 0xfc, 0x23, 0xeb, 0xfc, 0x31, 0x19, 0xe3, 0x5c, 0x42, + 0x11, 0xa9, 0x58, 0xcd, 0x1e, 0x20, 0x16, 0xc5, 0x23, 0xe6, 0xf3, 0x06, 0xfd, + 0xea, 0x0a, 0x07, 0x29, 0xe9, 0xee, 0xc4, 0x1d, 0x0f, 0x30, 0x3f, 0xc9, 0x0f, + 0x18, 0xd6, 0x3d, 0x06, 0x0c, 0x10, 0xbf, 0xdd, 0xfa, 0xf6, 0xdd, 0x1f, 0x1a, + 0x0f, 0xd4, 0xe0, 0x2a, 0x26, 0x19, 0x36, 0x0e, 0xec, 0x07, 0xf5, 0x33, 0x28, + 0xc3, 0xae, 0x1e, 0xe5, 0xeb, 0x29, 0xfb, 0x11, 0xeb, 0x34, 0x06, 0x06, 0x1e, + 0x7f, 0x11, 0xfb, 0xe6, 0xf8, 0x0d, 0x0f, 0x34, 0x30, 0x10, 0xc0, 0x0f, 0xf0, + 0x22, 0x65, 0x29, 0xed, 0x1c, 0xbd, 0x21, 0x15, 0x09, 0xde, 0x1c, 0x20, 0xdc, + 0xff, 0x12, 0x22, 0x0b, 0x38, 0x34, 0xf4, 0xc6, 0x37, 0xff, 0x18, 0x49, 0x11, + 0x08, 0xc9, 0x24, 0x12, 0x11, 0x51, 0x09, 0x25, 0xfd, 0xff, 0xd6, 0xff, 0xde, + 0x1b, 0x2d, 0xcc, 0xef, 0xd6, 0xef, 0xfb, 0x18, 0x30, 0x05, 0x35, 0xf3, 0xe7, + 0x2e, 0xfd, 0x08, 0xee, 0x22, 0xda, 0x0e, 0x1e, 0x5c, 0x2a, 0xda, 0x09, 0x04, + 0x07, 0x2f, 0xdb, 0xfd, 0x31, 0xf6, 0x04, 0x24, 0x02, 0xea, 0x1b, 0xed, 0x4f, + 0xfd, 0xd3, 0x1a, 0xf6, 0xd4, 0x04, 0x0c, 0x38, 0x0d, 0xdf, 0xdb, 0x26, 0x04, + 0x26, 0xdb, 0x4c, 0x22, 0x1b, 0xfc, 0xda, 0x19, 0x09, 0x28, 0x17, 0x1f, 0x58, + 0xe5, 0xe1, 0xda, 0x7f, 0xdc, 0x04, 0x16, 0x1d, 0x5b, 0x0b, 0x0f, 0xea, 0xdd, + 0xe1, 0xbc, 0xfa, 0x0e, 0x1c, 0xf8, 0x11, 0x1c, 0xcb, 0x2c, 0xad, 0x3c, 0x23, + 0x06, 0x2d, 0x42, 0xbc, 0xfe, 0xf9, 0x06, 0x5e, 0xee, 0xe2, 0xe6, 0xce, 0x12, + 0x24, 0xec, 0x53, 0xd7, 0x17, 0xd7, 0xdb, 0xe0, 0x04, 0x43, 0xeb, 0x1a, 0xff, + 0x65, 0xd0, 0x00, 0x3c, 0x58, 0xe3, 0xc6, 0xbe, 0x24, 0xc9, 0xde, 0xe3, 0xfa, + 0x1a, 0x38, 0xe8, 0x0f, 0xd8, 0x33, 0xf7, 0x3f, 0x32, 0x19, 0xbe, 0x11, 0xf0, + 0x19, 0x0e, 0x15, 0xed, 0x23, 0xc8, 0x08, 0xc9, 0xec, 0x0b, 0x1a, 0xd1, 0xb9, + 0x15, 0xdf, 0x23, 0x1e, 0x11, 0xf1, 0xf7, 0x35, 0x23, 0x28, 0xff, 0xcf, 0xf6, + 0x2d, 0xc8, 0xeb, 0x2b, 0xd9, 0x45, 0xcf, 0x14, 0x33, 0x69, 0x0d, 0x16, 0xcb, + 0x25, 0x33, 0x40, 0x20, 0xbd, 0x26, 0x19, 0x2d, 0x2a, 0x0e, 0x20, 0xc7, 0xd4, + 0xda, 0x03, 0xd0, 0xfe, 0x13, 0xfa, 0xb9, 0xf2, 0x29, 0x1d, 0x25, 0x04, 0xe8, + 0xd0, 0xf4, 0x21, 0x1b, 0x20, 0x03, 0x60, 0xfc, 0x10, 0xee, 0x6a, 0xf8, 0xfd, + 0x2a, 0xe8, 0xf8, 0xef, 0xf6, 0xbe, 0x28, 0xf9, 0xec, 0xff, 0xd3, 0x0e, 0xca, + 0xf6, 0x00, 0xe2, 0xda, 0x5a, 0xe1, 0x08, 0x15, 0x65, 0xe9, 0xfc, 0x19, 0x19, + 0x20, 0xf2, 0xf6, 0xdf, 0xf6, 0x2a, 0x10, 0xfa, 0x0f, 0xee, 0x08, 0xef, 0x1e, + 0xf5, 0xd5, 0xec, 0x00, 0xf6, 0x2b, 0xcc, 0xea, 0xb5, 0x77, 0x81, 0xfc, 0xc1, + 0xdb, 0xe2, 0xfd, 0xcf, 0x66, 0x53, 0xc2, 0x1b, 0xe0, 0x02, 0x1b, 0x02, 0xe2, + 0x01, 0xee, 0x09, 0x08, 0xc6, 0xfc, 0x0a, 0x16, 0xe6, 0xe9, 0x11, 0x05, 0x34, + 0x0a, 0xfe, 0x11, 0x17, 0x1f, 0xd9, 0xd6, 0xf9, 0x04, 0x21, 0xd8, 0x1a, 0x1f, + 0xfd, 0x13, 0xf6, 0x21, 0x07, 0xeb, 0x06, 0xeb, 0xc8, 0xa4, 0x2a, 0xae, 0x4d, + 0xb9, 0x3f, 0x60, 0x9e, 0x19, 0xe7, 0x11, 0x73, 0xff, 0xec, 0x3c, 0xe4, 0x33, + 0x4f, 0x02, 0xd1, 0xf5, 0xd0, 0xe9, 0x97, 0xb2, 0xa3, 0x46, 0xf9, 0x02, 0xe1, + 0x2a, 0xd0, 0x16, 0xe3, 0x08, 0xf3, 0xf1, 0x32, 0xfe, 0xd4, 0xf3, 0x3a, 0xc8, + 0x20, 0x85, 0xd2, 0x19, 0x73, 0x40, 0x5e, 0xcc, 0xdd, 0x07, 0xa5, 0xba, 0xcf, + 0x60, 0xfe, 0xe7, 0x1e, 0x01, 0xf5, 0xd1, 0x1c, 0x3a, 0xd0, 0x18, 0x19, 0xbe, + 0x1a, 0x2b, 0x7f, 0x4c, 0xef, 0x2f, 0x8b, 0x39, 0xf2, 0x30, 0xb5, 0x59, 0xf1, + 0x6f, 0x02, 0xcc, 0xd4, 0xdf, 0x2e, 0x05, 0xd5, 0x47, 0xd9, 0xec, 0xea, 0xaf, + 0xd2, 0x20, 0x5b, 0x49, 0xd7, 0x30, 0xc3, 0xad, 0xba, 0x05, 0x0b, 0xd9, 0xf4, + 0x3d, 0x72, 0xec, 0x30, 0xb5, 0x48, 0x2e, 0xc7, 0xe7, 0xde, 0xe2, 0xc4, 0x50, + 0xdc, 0x43, 0xf4, 0xe4, 0x2f, 0x14, 0x47, 0xca, 0x04, 0x33, 0x16, 0xf3, 0xae, + 0x0a, 0x66, 0x23, 0x35, 0x21, 0x37, 0xd8, 0x10, 0x12, 0xf5, 0x7f, 0x08, 0x58, + 0x6b, 0x3d, 0xb0, 0xd7, 0x08, 0x18, 0xf4, 0x00, 0x41, 0x29, 0x89, 0x07, 0xfd, + 0xe3, 0x1d, 0x15, 0xee, 0x09, 0x0e, 0x18, 0x07, 0x21, 0x01, 0xd2, 0x23, 0x3f, + 0x30, 0xc5, 0x1e, 0x51, 0x31, 0xbe, 0xd7, 0x5c, 0x1c, 0x11, 0x50, 0xcb, 0xd6, + 0x3c, 0xfc, 0xbd, 0x1a, 0x5d, 0xe9, 0xde, 0x2d, 0xed, 0xae, 0x09, 0x44, 0x4a, + 0x7b, 0x5f, 0x05, 0x22, 0x4c, 0x4f, 0x04, 0x36, 0xf8, 0x07, 0x17, 0xaf, 0xea, + 0x3d, 0xd3, 0x3c, 0xee, 0x21, 0xe4, 0x30, 0x59, 0xf3, 0xce, 0x3f, 0x03, 0x1e, + 0xc4, 0x05, 0x35, 0xd0, 0x12, 0x17, 0xfa, 0x22, 0xfa, 0xf0, 0x24, 0x24, 0xe3, + 0xe9, 0xf9, 0x2d, 0x6a, 0xf6, 0x2e, 0xe4, 0x3b, 0x25, 0xc5, 0xf6, 0x3a, 0xc6, + 0xf2, 0x29, 0xca, 0x2c, 0x7c, 0xf9, 0xeb, 0x00, 0xde, 0xd7, 0x27, 0xd3, 0x22, + 0x21, 0x73, 0x38, 0xec, 0x05, 0xfb, 0xdb, 0xfa, 0xf9, 0x3a, 0xa1, 0xf0, 0xdb, + 0x7f, 0xec, 0xe7, 0x12, 0x1a, 0x3a, 0xfb, 0xc7, 0x10, 0x0e, 0x11, 0x09, 0xf5, + 0xdf, 0xf7, 0xe5, 0xe9, 0x1b, 0x38, 0x12, 0x1e, 0xf3, 0xfa, 0xde, 0x17, 0x04, + 0x06, 0xe3, 0x1e, 0x03, 0xe7, 0xa9, 0xca, 0xb2, 0xdb, 0x0a, 0xde, 0x24, 0x11, + 0x02, 0x19, 0xd3, 0xf7, 0xef, 0xdc, 0x03, 0xfb, 0xe5, 0x22, 0x39, 0x13, 0x3a, + 0x04, 0xe7, 0xf3, 0x41, 0xed, 0xf2, 0xc1, 0x52, 0x03, 0xd4, 0xe9, 0xf9, 0xbb, + 0xc0, 0xee, 0x0f, 0xf0, 0xe1, 0xd4, 0xc4, 0x0e, 0x0d, 0x2b, 0x41, 0xc4, 0xea, + 0xf6, 0x3e, 0xe6, 0xfc, 0xdf, 0x35, 0x15, 0x08, 0x1d, 0x01, 0xd1, 0xe3, 0xf7, + 0xf6, 0xea, 0x1a, 0x1b, 0xfd, 0x1b, 0x08, 0x00, 0xcb, 0x05, 0x12, 0xfb, 0x43, + 0xe1, 0xff, 0x22, 0x0a, 0x02, 0x08, 0xf7, 0xea, 0x13, 0xf3, 0x1a, 0xd8, 0xe4, + 0x25, 0xed, 0x0d, 0x0f, 0xf6, 0x00, 0x0f, 0x12, 0xe1, 0xdd, 0x0c, 0xd3, 0x0b, + 0x03, 0xef, 0x1d, 0xdb, 0xe9, 0x16, 0xe4, 0x3c, 0x25, 0x02, 0xbe, 0x44, 0xe5, + 0x11, 0x39, 0x5b, 0x0c, 0xda, 0x1f, 0x11, 0xee, 0x2c, 0x2d, 0xea, 0x1b, 0x00, + 0x16, 0x1c, 0x0e, 0x07, 0x00, 0xe5, 0x15, 0x1b, 0xfb, 0x16, 0x13, 0xf3, 0x1a, + 0x0e, 0x0b, 0x2d, 0x15, 0xf4, 0xed, 0xfb, 0x22, 0x1f, 0x0a, 0x21, 0xfa, 0x03, + 0xcc, 0x21, 0x0a, 0x03, 0xf5, 0x42, 0xf0, 0xee, 0xfe, 0xf1, 0x0a, 0x7f, 0xdb, + 0x03, 0x14, 0x30, 0x2d, 0x1b, 0xf7, 0x02, 0x11, 0x1f, 0x0b, 0x01, 0x14, 0x3f, + 0xf1, 0x04, 0x08, 0x21, 0xf7, 0x03, 0xe7, 0xf1, 0x18, 0xf3, 0x11, 0x02, 0x41, + 0xee, 0x2b, 0xf3, 0xf1, 0x29, 0x10, 0xe2, 0x17, 0x04, 0xed, 0x2d, 0x02, 0xfb, + 0xc9, 0x09, 0xf9, 0xec, 0x0f, 0x16, 0xdf, 0xf4, 0x0e, 0x1a, 0x07, 0x28, 0x14, + 0x2b, 0xf5, 0x09, 0xe5, 0xfa, 0x0d, 0x31, 0x35, 0x4f, 0x11, 0xfd, 0x10, 0xf5, + 0x7f, 0xf8, 0xee, 0x36, 0xf8, 0x0f, 0xe0, 0xfc, 0xf8, 0x29, 0xe4, 0x0d, 0x02, + 0x10, 0x18, 0xeb, 0x08, 0x11, 0xe6, 0xfe, 0x0c, 0x0e, 0x01, 0x0f, 0xf6, 0xf0, + 0xf3, 0xed, 0xfa, 0xe6, 0x0e, 0x0f, 0xe7, 0xfd, 0xf4, 0x05, 0xfa, 0x05, 0xf5, + 0xe2, 0xed, 0xfe, 0x10, 0xf2, 0x0a, 0x00, 0xc4, 0x42, 0xec, 0xef, 0xfa, 0x1d, + 0xd4, 0x1f, 0xe6, 0xfd, 0x1d, 0xe9, 0xf0, 0x00, 0x0a, 0x02, 0x12, 0xec, 0x05, + 0xfb, 0x03, 0xf6, 0xf8, 0xea, 0x1e, 0x2a, 0x17, 0x15, 0xf5, 0x02, 0xfa, 0x1c, + 0xe8, 0x19, 0xf9, 0x23, 0xdc, 0xea, 0x00, 0x2e, 0x29, 0xee, 0xe8, 0xf8, 0x27, + 0xf4, 0xf6, 0x01, 0xbe, 0xe0, 0x0c, 0x21, 0x0f, 0x65, 0x24, 0xf6, 0xda, 0xf3, + 0x14, 0x39, 0xfa, 0x09, 0xe3, 0xe2, 0x1e, 0xdc, 0x75, 0xcf, 0x2e, 0x31, 0xeb, + 0xf2, 0xe0, 0x24, 0x55, 0xeb, 0xb4, 0xe7, 0x7f, 0xc0, 0x25, 0xea, 0xe5, 0xf9, + 0x23, 0xed, 0x47, 0xf7, 0x01, 0xd3, 0x48, 0xe1, 0x2d, 0xe3, 0xe0, 0xa2, 0xf6, + 0x3b, 0xee, 0xc8, 0x18, 0x08, 0x06, 0x28, 0x2d, 0x26, 0xc9, 0x06, 0xfd, 0x9a, + 0x11, 0x1d, 0xe1, 0x10, 0xd9, 0xdf, 0x1a, 0x0d, 0xf8, 0xe6, 0x04, 0x23, 0x26, + 0xe4, 0xee, 0x0a, 0x4b, 0xeb, 0x3c, 0xbf, 0xfe, 0xe7, 0x4a, 0xf7, 0xec, 0xe7, + 0x28, 0x2f, 0xfa, 0x09, 0xef, 0x06, 0xdf, 0x11, 0x40, 0xdb, 0xfe, 0x18, 0xee, + 0xdf, 0x34, 0x00, 0x09, 0x15, 0xf5, 0x57, 0xe8, 0x4d, 0xeb, 0xd5, 0x15, 0x39, + 0x45, 0x28, 0x14, 0x16, 0x13, 0xd8, 0xca, 0xea, 0x27, 0xe0, 0x21, 0x1d, 0xd3, + 0xf8, 0x26, 0x02, 0x38, 0xff, 0x43, 0xd6, 0x10, 0x42, 0xb5, 0xec, 0xfb, 0xca, + 0x37, 0xe3, 0x10, 0x23, 0x2b, 0xf6, 0x28, 0x47, 0x4c, 0xe0, 0xc9, 0x16, 0x28, + 0xf2, 0xeb, 0x28, 0x7d, 0x7f, 0xe3, 0xf2, 0xf3, 0x04, 0xe5, 0xf6, 0x19, 0x35, + 0xe1, 0x31, 0x4e, 0x00, 0xdc, 0x36, 0xd6, 0xa5, 0x27, 0x4f, 0xe7, 0x2a, 0x1c, + 0x1e, 0x05, 0xfb, 0x33, 0x11, 0x04, 0x30, 0xe4, 0xf4, 0xe6, 0x1e, 0xd6, 0xd7, + 0x12, 0x0b, 0x19, 0x4b, 0xe5, 0xda, 0x4c, 0x26, 0x20, 0x24, 0xe9, 0x0d, 0xdf, + 0xe1, 0x23, 0x33, 0x36, 0x16, 0xd0, 0xbe, 0x4b, 0x6a, 0x48, 0x49, 0xf1, 0x49, + 0xfa, 0xf5, 0x33, 0x21, 0x30, 0xe3, 0xef, 0xef, 0xe4, 0x45, 0xfe, 0xd7, 0x01, + 0x2f, 0x00, 0x10, 0xcf, 0xfe, 0x15, 0x36, 0x15, 0xe6, 0xec, 0x00, 0x28, 0x13, + 0x13, 0xe4, 0x3b, 0xd0, 0xdb, 0xdd, 0x19, 0x0c, 0xfc, 0x0a, 0x59, 0x26, 0xcb, + 0xc8, 0xf1, 0x0a, 0x19, 0x34, 0x06, 0x40, 0x1e, 0x4a, 0x0a, 0x12, 0x07, 0xce, + 0xb9, 0xb5, 0xc8, 0xee, 0x3d, 0x3b, 0x0f, 0x35, 0xc7, 0xf6, 0xda, 0xf2, 0x19, + 0x4b, 0xed, 0xf1, 0x1c, 0x92, 0xd6, 0xbc, 0xda, 0x22, 0x52, 0xf2, 0x57, 0xe0, + 0xea, 0x0d, 0xde, 0xff, 0xe2, 0x54, 0xef, 0xcb, 0xf1, 0xae, 0xee, 0xff, 0xc0, + 0xae, 0xe9, 0x6d, 0xd1, 0xf0, 0x35, 0xd8, 0xfc, 0x0d, 0x60, 0xe9, 0x3a, 0xec, + 0xd0, 0x2a, 0x1f, 0x19, 0x48, 0x33, 0xea, 0xb7, 0xde, 0xbd, 0x48, 0x8e, 0x13, + 0xff, 0x0a, 0x18, 0x17, 0xea, 0xfc, 0xda, 0xbc, 0x7f, 0xf1, 0x2e, 0xdf, 0xfd, + 0xe7, 0x26, 0xce, 0x1d, 0x02, 0x2a, 0xf9, 0xd3, 0x13, 0xfc, 0xe6, 0xd9, 0xb3, + 0xf5, 0x03, 0xfb, 0xd1, 0x34, 0xcc, 0xcf, 0xe8, 0x45, 0xd1, 0x0a, 0xdc, 0x0f, + 0xfa, 0x9d, 0xe7, 0xc2, 0x06, 0xe6, 0x58, 0x35, 0xd0, 0x24, 0xef, 0x04, 0xea, + 0x4b, 0x3c, 0x16, 0x09, 0xaf, 0x24, 0x0d, 0x23, 0x25, 0x1a, 0xf4, 0x2a, 0x39, + 0xcf, 0xd3, 0x0f, 0xaf, 0xe0, 0x1b, 0x39, 0x08, 0x08, 0xb7, 0x38, 0xb1, 0xfb, + 0x01, 0xd1, 0x35, 0x00, 0x17, 0xe8, 0xdc, 0xc7, 0x11, 0xd4, 0xff, 0x4a, 0xa9, + 0x54, 0xd5, 0xdd, 0x31, 0xfd, 0x23, 0xf9, 0xf3, 0xb2, 0xbb, 0x23, 0xe0, 0xef, + 0xfd, 0x02, 0x5a, 0xd4, 0xf6, 0x19, 0xdd, 0xe0, 0x0f, 0xaf, 0xe0, 0x0f, 0xb5, + 0x1c, 0x16, 0xcc, 0xda, 0x10, 0x78, 0xcc, 0x40, 0x0d, 0xd1, 0xe6, 0xf8, 0x51, + 0xef, 0x1f, 0x47, 0x54, 0xef, 0x45, 0xcd, 0xdd, 0x06, 0x36, 0x48, 0xf9, 0xd3, + 0xc5, 0x9d, 0xbb, 0xc7, 0xbd, 0xf2, 0xae, 0x1f, 0x43, 0x39, 0xf8, 0xf2, 0x0a, + 0xea, 0xd1, 0x04, 0x0b, 0xfe, 0xb8, 0xb3, 0x7f, 0x0f, 0x16, 0x1d, 0x5a, 0x00, + 0x12, 0xef, 0x01, 0x55, 0x2a, 0x23, 0xe4, 0xec, 0xf1, 0xb9, 0x5c, 0x08, 0x05, + 0xf8, 0x19, 0x1b, 0xc1, 0x11, 0x1a, 0xe7, 0xe4, 0xc4, 0x02, 0xeb, 0xcc, 0xea, + 0x0e, 0xe9, 0xb3, 0x0c, 0xf4, 0xdb, 0x58, 0xdc, 0x1d, 0xbf, 0x03, 0x19, 0x30, + 0x10, 0xea, 0xf4, 0xf2, 0xe8, 0x5f, 0xf3, 0xe9, 0x13, 0x11, 0xd2, 0x28, 0x34, + 0xeb, 0x2a, 0x04, 0xe0, 0x1f, 0xd8, 0xc6, 0x7f, 0xef, 0x2b, 0xe7, 0xca, 0x0a, + 0xee, 0x31, 0x31, 0xd1, 0x94, 0xf5, 0x11, 0xd6, 0x57, 0xf8, 0x33, 0x12, 0x23, + 0x0e, 0x1c, 0x07, 0x01, 0xeb, 0x16, 0xfb, 0x08, 0xf9, 0x1c, 0xe6, 0x0c, 0x14, + 0xdc, 0xe5, 0xd9, 0xfe, 0xcc, 0xf8, 0xfa, 0xfd, 0x28, 0x01, 0xc6, 0x50, 0xec, + 0x22, 0x61, 0xe2, 0xed, 0x1d, 0x63, 0x17, 0xac, 0x05, 0x5b, 0xbf, 0xc1, 0xe4, + 0xf2, 0xf9, 0xcf, 0xf1, 0xfc, 0x68, 0x0e, 0x31, 0x30, 0x01, 0xe9, 0x1f, 0x05, + 0xfc, 0x0a, 0x17, 0xc3, 0x54, 0xbb, 0x06, 0x5b, 0xec, 0xc3, 0x0d, 0x15, 0x38, + 0x16, 0xbd, 0xce, 0xda, 0xff, 0x30, 0xc9, 0xfa, 0xfb, 0x00, 0xf8, 0xe2, 0x4e, + 0xee, 0x01, 0x0f, 0x1c, 0x1c, 0x1a, 0x49, 0x3b, 0xdc, 0x2a, 0xc9, 0xcd, 0xef, + 0xeb, 0x20, 0x1e, 0xd3, 0xe7, 0xe1, 0x3a, 0x19, 0xe0, 0x05, 0x04, 0xf2, 0x09, + 0xf9, 0x5d, 0x11, 0x5a, 0x18, 0x14, 0xe6, 0xcf, 0x01, 0xfb, 0xfd, 0x27, 0x5d, + 0xfd, 0x27, 0xf8, 0x10, 0x07, 0x0a, 0x09, 0xf2, 0x29, 0x08, 0xda, 0x11, 0xf8, + 0xd2, 0x16, 0x26, 0xe3, 0xfe, 0x2a, 0x7a, 0xe1, 0x07, 0x54, 0x27, 0xf2, 0xce, + 0x38, 0x0f, 0x0d, 0x38, 0xe4, 0xce, 0x4a, 0x3d, 0xee, 0x10, 0x3a, 0xf8, 0x1d, + 0x1b, 0x2c, 0xea, 0x05, 0x2e, 0xef, 0x01, 0x0a, 0xec, 0xda, 0xee, 0x6c, 0xed, + 0xfd, 0x16, 0xf2, 0x2a, 0xe7, 0xce, 0x05, 0x39, 0xf1, 0xf3, 0x44, 0x7f, 0x04, + 0xeb, 0x0b, 0xfc, 0x14, 0x1d, 0x0a, 0x15, 0x21, 0x0c, 0x34, 0x16, 0x15, 0xf8, + 0x34, 0x0e, 0xda, 0xbf, 0xe7, 0x01, 0x04, 0xe2, 0x0e, 0xdd, 0x34, 0x07, 0x03, + 0x03, 0x09, 0xa6, 0x44, 0x1f, 0xc8, 0xfe, 0x06, 0x49, 0x22, 0x29, 0xe2, 0x32, + 0xeb, 0xd7, 0xf0, 0xe3, 0x2c, 0x46, 0xf2, 0xba, 0xd3, 0x1c, 0xc9, 0xe1, 0x47, + 0x01, 0xe6, 0x09, 0x7f, 0xa5, 0xd4, 0x48, 0xff, 0x7a, 0xf3, 0x33, 0xfb, 0x2b, + 0xfc, 0x4a, 0xef, 0xf0, 0x05, 0xd0, 0x27, 0x15, 0x2a, 0x0f, 0xe9, 0xf9, 0xed, + 0xff, 0xfc, 0xc7, 0xcb, 0x25, 0xdb, 0xe3, 0x63, 0x16, 0xe4, 0xab, 0x73, 0xd7, + 0x32, 0xff, 0x10, 0xf7, 0xfd, 0xcb, 0x26, 0xda, 0xeb, 0xfe, 0xf0, 0x26, 0xee, + 0x1c, 0x08, 0xbc, 0x48, 0x28, 0x10, 0x1f, 0x06, 0xf8, 0xfc, 0xe9, 0x3f, 0x17, + 0x14, 0xd5, 0xfd, 0xd2, 0xe3, 0x3f, 0x14, 0x30, 0x27, 0xcc, 0xda, 0xe1, 0x03, + 0xfe, 0x07, 0x20, 0x12, 0xd3, 0x07, 0x1d, 0xfb, 0x0c, 0xc5, 0xda, 0xf9, 0xa8, + 0xcd, 0xce, 0xef, 0x35, 0xef, 0xc8, 0x0a, 0x47, 0xc4, 0xc9, 0x09, 0x06, 0x4d, + 0x09, 0xf3, 0x11, 0xdf, 0xea, 0x0d, 0x0a, 0x0c, 0xc2, 0xd0, 0xcd, 0xec, 0xe7, + 0xf6, 0x3c, 0x04, 0xd9, 0x04, 0xea, 0xe4, 0x09, 0x20, 0x3b, 0xdb, 0xd6, 0x4e, + 0x9f, 0xb1, 0x23, 0xca, 0x81, 0x13, 0xc0, 0x21, 0xab, 0x10, 0x3a, 0x8d, 0xfb, + 0xd4, 0x07, 0xe1, 0x15, 0x26, 0x4f, 0xe1, 0x06, 0xce, 0x34, 0x1f, 0x0d, 0x53, + 0x0e, 0x23, 0x00, 0xf0, 0xb5, 0x09, 0x44, 0xfb, 0xf8, 0xef, 0xde, 0xc8, 0x08, + 0xea, 0x56, 0xf4, 0x47, 0x40, 0x19, 0x4f, 0xe2, 0x96, 0x27, 0xff, 0x03, 0xb2, + 0xf3, 0xc4, 0xdf, 0xdd, 0x06, 0xfc, 0xf7, 0xf7, 0x40, 0xaf, 0xc4, 0x10, 0x2b, + 0xfa, 0xdd, 0xf3, 0xe4, 0xc7, 0x20, 0xa3, 0xfb, 0xe2, 0x0a, 0xc3, 0x11, 0xd7, + 0xf5, 0xff, 0x38, 0xf2, 0x0d, 0xdc, 0x55, 0x2b, 0x2e, 0x34, 0xf8, 0x46, 0xc8, + 0xca, 0x20, 0x0c, 0x15, 0xdf, 0x30, 0x31, 0x0f, 0x25, 0x51, 0xf3, 0xde, 0xdc, + 0xea, 0xcf, 0xa0, 0x9a, 0xd0, 0x28, 0xfc, 0xee, 0xf4, 0x26, 0x0d, 0x09, 0x09, + 0x27, 0xef, 0x13, 0xbf, 0x1a, 0x0d, 0xd4, 0xfe, 0x18, 0xd2, 0x04, 0x4d, 0xde, + 0x21, 0x10, 0x08, 0xcf, 0xfc, 0x0b, 0x12, 0x29, 0xd9, 0xf4, 0xd6, 0xeb, 0x3b, + 0x1e, 0xf3, 0xf0, 0x5a, 0xd3, 0x10, 0x2c, 0x04, 0xfe, 0x20, 0x44, 0x05, 0x12, + 0x6f, 0xfd, 0x08, 0x5b, 0x1f, 0xf5, 0xc2, 0x0c, 0x3d, 0x2c, 0xfc, 0xf6, 0x0a, + 0x7f, 0x2a, 0xe7, 0x62, 0x3e, 0xf1, 0x0c, 0xec, 0x03, 0x18, 0x12, 0xc2, 0xf8, + 0x1d, 0x12, 0x02, 0x04, 0xd2, 0x44, 0x38, 0xd9, 0x17, 0x09, 0xb6, 0x46, 0x1d, + 0x17, 0x6a, 0xf1, 0xe6, 0xd5, 0x2d, 0x0e, 0xd3, 0xfe, 0xee, 0xe9, 0x1c, 0x11, + 0x3e, 0xb8, 0x1a, 0x29, 0x01, 0xcd, 0xb6, 0xfb, 0x1c, 0x05, 0xe6, 0xfd, 0xdd, + 0xd0, 0xea, 0x1e, 0xec, 0xfb, 0xeb, 0x00, 0xe1, 0x0d, 0x19, 0xbd, 0xfa, 0xf8, + 0x34, 0x7f, 0x0b, 0xf8, 0xf3, 0x01, 0x1f, 0xdf, 0xdf, 0xec, 0x02, 0x00, 0xf6, + 0xef, 0x1f, 0xe0, 0xe1, 0x00, 0xec, 0x44, 0x17, 0xda, 0xd6, 0xf3, 0xe9, 0x08, + 0xda, 0x3c, 0x1a, 0xbc, 0x1e, 0x06, 0x05, 0xe1, 0x06, 0xde, 0xe2, 0x23, 0xd4, + 0x28, 0xef, 0x18, 0x08, 0x0b, 0xdc, 0xd1, 0xf4, 0x11, 0xe9, 0xe9, 0xf8, 0xf0, + 0xca, 0x19, 0xeb, 0x07, 0x0e, 0x1e, 0xe6, 0x51, 0x13, 0xe2, 0x18, 0xfb, 0x24, + 0x27, 0x30, 0x13, 0x04, 0xf3, 0xe4, 0xd9, 0x08, 0x07, 0x13, 0x2e, 0xca, 0x4c, + 0x1d, 0xd8, 0x09, 0xcc, 0xbf, 0x02, 0xf2, 0xe6, 0xf6, 0x40, 0xd7, 0x05, 0xd0, + 0xec, 0xe0, 0xd7, 0xd2, 0x02, 0x19, 0x29, 0x32, 0xfd, 0xeb, 0x1c, 0x03, 0x3d, + 0xf1, 0xde, 0x1e, 0x1f, 0x0b, 0xdc, 0x1f, 0xea, 0xf3, 0x44, 0x2c, 0x45, 0xf8, + 0xf8, 0xed, 0xde, 0xc6, 0x0e, 0xdf, 0x17, 0x04, 0x05, 0x52, 0xa5, 0xe7, 0xd3, + 0x62, 0xcd, 0x28, 0x2e, 0x2e, 0xab, 0x12, 0x7f, 0x00, 0x1d, 0xab, 0xcc, 0xfa, + 0xde, 0x1f, 0x5e, 0x55, 0x0f, 0xdd, 0x37, 0x4a, 0xf1, 0x30, 0x29, 0x18, 0xda, + 0x09, 0x23, 0xdc, 0x25, 0xdf, 0x61, 0x09, 0x21, 0x4c, 0xa0, 0x2c, 0xbd, 0x16, + 0xef, 0x1f, 0xe2, 0xff, 0x51, 0x44, 0x08, 0x19, 0xe6, 0xb7, 0xd4, 0x29, 0x2c, + 0xf8, 0x21, 0xdd, 0x2e, 0x08, 0x03, 0x4a, 0xde, 0x05, 0x92, 0xe8, 0xe7, 0xe6, + 0x73, 0x07, 0x3a, 0xa3, 0x02, 0xcf, 0xea, 0x0f, 0x3c, 0x12, 0xd4, 0x00, 0x40, + 0x07, 0xfe, 0x3f, 0xd4, 0xbc, 0x21, 0xe8, 0xbc, 0xd3, 0x5f, 0xf3, 0x45, 0x1a, + 0x29, 0x07, 0xff, 0x1d, 0xb4, 0x2d, 0xfa, 0xfa, 0x27, 0xc9, 0xc0, 0x11, 0x42, + 0xcf, 0xb4, 0xcb, 0xf7, 0xce, 0x0f, 0x00, 0x11, 0x54, 0xc4, 0xd8, 0xc6, 0x04, + 0x10, 0x23, 0x33, 0xd5, 0xf9, 0xe4, 0xc5, 0x19, 0x22, 0xe6, 0xe3, 0x0f, 0x2b, + 0x05, 0x40, 0x23, 0x18, 0x28, 0xc2, 0x49, 0x10, 0xb1, 0xfd, 0xd9, 0xf3, 0x29, + 0x14, 0x21, 0xdb, 0xf7, 0x1d, 0x1c, 0x2f, 0x37, 0xe4, 0x12, 0xd2, 0x15, 0xe4, + 0xfc, 0x02, 0x3d, 0xad, 0xbc, 0xbd, 0xd9, 0xeb, 0x3b, 0xdb, 0xd0, 0x35, 0xf4, + 0xf7, 0x11, 0xee, 0x32, 0x3d, 0x59, 0x2d, 0x1c, 0xe7, 0x05, 0xdb, 0x15, 0x18, + 0x1f, 0xd2, 0xe0, 0x0c, 0x5a, 0xca, 0x08, 0xda, 0x20, 0xbe, 0xf3, 0xf3, 0xb5, + 0x56, 0x08, 0x07, 0xfd, 0x65, 0x16, 0xe9, 0x12, 0x2b, 0x07, 0xbc, 0xdd, 0xf1, + 0xdb, 0xdf, 0xea, 0xde, 0x4c, 0xfc, 0xc5, 0xfb, 0xbc, 0xf8, 0x08, 0x07, 0xde, + 0xea, 0x2c, 0x20, 0x2a, 0x0a, 0x2c, 0x0f, 0x0e, 0xc3, 0x01, 0x24, 0xcf, 0x81, + 0xc2, 0x48, 0xb6, 0xf3, 0xba, 0xda, 0xe0, 0xd2, 0xea, 0x0b, 0xdf, 0x4a, 0x42, + 0x1b, 0xd0, 0xd6, 0xd4, 0x2d, 0x1f, 0xd7, 0x8f, 0xcc, 0x41, 0xda, 0xfc, 0xe1, + 0x36, 0x15, 0xfe, 0x4e, 0xaa, 0x08, 0xe5, 0x0d, 0x8f, 0x11, 0xc3, 0xed, 0xfb, + 0xec, 0x37, 0xa9, 0x65, 0xc2, 0x0d, 0xe4, 0x1a, 0x1c, 0x45, 0x03, 0x08, 0xf4, + 0xf7, 0xbb, 0x23, 0xe4, 0xeb, 0x0e, 0xed, 0x29, 0xfd, 0xff, 0xe9, 0xd5, 0xe8, + 0xb5, 0x0b, 0x0a, 0xdb, 0xb1, 0x3b, 0x2d, 0xf5, 0x42, 0xc1, 0x12, 0x84, 0x10, + 0xe9, 0xe9, 0xe7, 0x3c, 0xa3, 0xd0, 0xe2, 0x11, 0xbc, 0x94, 0x4d, 0xba, 0x00, + 0x0e, 0x53, 0xe8, 0xef, 0xf0, 0xd9, 0xf9, 0xcf, 0xf3, 0xed, 0x5e, 0xe4, 0xf1, + 0x14, 0x2a, 0xfd, 0x0d, 0xea, 0xee, 0x1a, 0xcb, 0xea, 0x2b, 0xa8, 0x48, 0x3e, + 0xf0, 0x0c, 0x18, 0xec, 0x1e, 0xaa, 0x16, 0xb9, 0x75, 0x61, 0x7f, 0xcb, 0xfd, + 0x40, 0x14, 0x3b, 0x41, 0xd5, 0xf7, 0x2b, 0x27, 0x00, 0x10, 0x3b, 0x0a, 0xb9, + 0x31, 0x03, 0x1f, 0xf5, 0x55, 0x12, 0x13, 0x4b, 0x04, 0x0c, 0x25, 0x07, 0xf5, + 0x96, 0x1f, 0x5f, 0xe4, 0x43, 0x11, 0x32, 0xe1, 0xe7, 0x39, 0xfb, 0x1b, 0x0c, + 0x36, 0xfe, 0x0b, 0x08, 0xff, 0x3e, 0x03, 0x1e, 0xe7, 0x0a, 0xf0, 0xe1, 0x34, + 0x18, 0x0e, 0xe1, 0x02, 0xe5, 0xbf, 0xe3, 0x13, 0x05, 0x0e, 0xeb, 0x7f, 0x06, + 0xce, 0x0c, 0x14, 0xcd, 0x09, 0x2f, 0xde, 0x1c, 0x00, 0x09, 0x4b, 0x17, 0x45, + 0xe8, 0x32, 0x28, 0xf5, 0xc4, 0x17, 0xeb, 0xe1, 0xda, 0xdf, 0x03, 0x18, 0x0a, + 0x07, 0x24, 0x21, 0x0d, 0xd4, 0x11, 0xdb, 0x0b, 0xf4, 0xba, 0x10, 0xd0, 0xf6, + 0xd4, 0x0f, 0xec, 0x1f, 0x0b, 0x27, 0xe4, 0x4f, 0xee, 0x4e, 0x3b, 0x32, 0x11, + 0xe0, 0xe8, 0xb8, 0x11, 0xdd, 0x22, 0x27, 0x1d, 0xeb, 0xef, 0xec, 0xe8, 0x21, + 0xee, 0xff, 0xd6, 0xb9, 0xf6, 0x08, 0xc9, 0x30, 0xef, 0x06, 0xb6, 0x9b, 0xe3, + 0x05, 0x21, 0xfd, 0x01, 0x4f, 0xe6, 0xe5, 0xf2, 0x1d, 0xbd, 0xfe, 0xa4, 0x41, + 0x1f, 0xdf, 0xd3, 0xdd, 0xb7, 0x1c, 0xd8, 0xfc, 0xdd, 0xee, 0xfb, 0xd5, 0xc8, + 0xb8, 0x96, 0xdd, 0xb8, 0x11, 0x02, 0xe7, 0xee, 0xbb, 0xd6, 0x19, 0xda, 0xde, + 0x07, 0x19, 0x16, 0x27, 0x0e, 0xfd, 0x17, 0xa9, 0xc4, 0xd2, 0xec, 0xd2, 0x04, + 0xa0, 0xe2, 0x08, 0xb1, 0x08, 0xab, 0xd5, 0x0a, 0xf4, 0xe5, 0xea, 0xcf, 0x06, + 0x1f, 0x8f, 0xd4, 0x0b, 0x02, 0xf5, 0x47, 0xca, 0x05, 0xf3, 0xf2, 0x10, 0x1c, + 0xfb, 0xea, 0x1c, 0xfc, 0x02, 0x08, 0xc5, 0x81, 0xa1, 0xc3, 0x59, 0xb2, 0x59, + 0xfe, 0x29, 0xd2, 0xbf, 0x1f, 0xce, 0xb2, 0x08, 0x27, 0xf1, 0x0a, 0x11, 0xc4, + 0x13, 0xa3, 0x19, 0xfe, 0xee, 0xe5, 0xe5, 0x0f, 0xec, 0x28, 0xe3, 0x1d, 0xc0, + 0xeb, 0xf6, 0xe1, 0x31, 0x0c, 0xd3, 0xea, 0xf6, 0xf6, 0xdc, 0x12, 0x48, 0xd4, + 0xdf, 0xf1, 0x6b, 0xdf, 0xd6, 0xfb, 0x04, 0x4d, 0xec, 0x09, 0x1c, 0xa7, 0xf0, + 0x6d, 0x09, 0xdd, 0x1f, 0x1b, 0xe1, 0xe2, 0xf2, 0xf6, 0xe2, 0xef, 0xeb, 0xfc, + 0xd6, 0xfb, 0x2d, 0xe8, 0x19, 0x0e, 0x0d, 0x07, 0x35, 0xdd, 0xab, 0x29, 0x49, + 0x25, 0xdd, 0xee, 0xed, 0x1a, 0x3c, 0xe0, 0x22, 0x11, 0xde, 0x20, 0x0d, 0x2f, + 0xcc, 0x45, 0x12, 0xf2, 0xd3, 0x40, 0xde, 0xb8, 0xe5, 0x13, 0x17, 0xd5, 0xf3, + 0xd9, 0xe7, 0xe7, 0xeb, 0x03, 0x03, 0x32, 0xf6, 0xd1, 0xf6, 0xe8, 0x22, 0xd7, + 0x1d, 0x06, 0x2b, 0x2a, 0x28, 0x33, 0xe1, 0xdf, 0x21, 0x2c, 0x10, 0xd0, 0xcf, + 0x7f, 0xc9, 0x31, 0x35, 0x21, 0x1b, 0x01, 0x17, 0x3b, 0x09, 0xce, 0x2f, 0xc3, + 0x1a, 0xbb, 0xf6, 0xed, 0x33, 0x0f, 0xec, 0xfa, 0xf4, 0x42, 0xe3, 0xf9, 0x17, + 0x0b, 0x21, 0xdd, 0x57, 0x06, 0xff, 0x2b, 0xec, 0xce, 0x0b, 0x1a, 0x00, 0x1d, + 0xd3, 0xdb, 0x03, 0x12, 0x2f, 0x0f, 0xf2, 0x0b, 0xbe, 0xd7, 0xd7, 0xbd, 0x33, + 0xda, 0x1a, 0xf5, 0xbb, 0x02, 0x66, 0xfd, 0xf6, 0x53, 0x3d, 0x16, 0xcf, 0xfb, + 0x02, 0x4e, 0xf9, 0x51, 0x0b, 0xfa, 0xa4, 0x1b, 0xfe, 0xe6, 0x9a, 0x4f, 0x1f, + 0xf8, 0x0e, 0xd9, 0x7f, 0xbd, 0xfb, 0xd9, 0x05, 0xbd, 0x36, 0x20, 0x12, 0xc6, + 0xec, 0xd4, 0x14, 0xc7, 0x5e, 0xae, 0xe1, 0x31, 0xf4, 0x37, 0x1d, 0xca, 0x13, + 0x0e, 0xbb, 0xda, 0x19, 0x27, 0xf2, 0x01, 0xf4, 0x02, 0x41, 0xeb, 0x0d, 0x02, + 0x11, 0x0c, 0xf9, 0xcd, 0x13, 0x08, 0x19, 0xf2, 0x01, 0x5a, 0x34, 0x06, 0xcf, + 0xff, 0xa1, 0xf9, 0xd6, 0x21, 0xea, 0x25, 0xd6, 0x0e, 0xd0, 0x11, 0x08, 0xc2, + 0xfb, 0xc6, 0xf4, 0x74, 0x7f, 0x17, 0x3a, 0x0e, 0xf9, 0x0b, 0xcd, 0xe0, 0xe3, + 0x17, 0xf4, 0xfa, 0x2d, 0xe0, 0xec, 0xd7, 0x06, 0xe6, 0xff, 0xf8, 0xd6, 0xdd, + 0xfe, 0xea, 0xfb, 0xff, 0xda, 0xfc, 0x2b, 0x63, 0xeb, 0xec, 0xce, 0x61, 0xf9, + 0xdc, 0xf9, 0xfc, 0xe8, 0x01, 0xe0, 0x73, 0x29, 0x08, 0x75, 0xf0, 0x12, 0x6f, + 0x38, 0x07, 0x22, 0x07, 0x20, 0xdc, 0xe2, 0x2e, 0xea, 0xe2, 0x01, 0x2e, 0xde, + 0xff, 0x29, 0x13, 0x11, 0x27, 0xec, 0x08, 0xfc, 0x21, 0x2a, 0x1d, 0x5d, 0xe0, + 0x78, 0x35, 0x07, 0xc8, 0x2f, 0xd9, 0xf6, 0xfb, 0x0b, 0x3a, 0xf8, 0xf8, 0xe1, + 0xfa, 0xce, 0xef, 0x40, 0xcf, 0x3c, 0xeb, 0x67, 0x2e, 0xff, 0x01, 0x1d, 0xdf, + 0xfe, 0xfd, 0x07, 0x0b, 0xfe, 0x27, 0x0d, 0x70, 0x08, 0xfd, 0xf3, 0xf7, 0xfa, + 0xc7, 0xde, 0x0e, 0x53, 0xfc, 0x12, 0x0f, 0xe3, 0xe6, 0x01, 0xe6, 0x12, 0xb3, + 0xad, 0x25, 0x4c, 0xc2, 0x20, 0x1a, 0x28, 0xba, 0x12, 0x31, 0x44, 0x1a, 0x41, + 0x3a, 0x13, 0x06, 0xeb, 0xfd, 0xf4, 0x37, 0x78, 0x0e, 0x31, 0x4b, 0x02, 0xf7, + 0x08, 0x2e, 0x3e, 0xed, 0x03, 0xd3, 0x0f, 0xcf, 0x3a, 0xeb, 0xfb, 0x96, 0xe9, + 0xdb, 0x0f, 0x53, 0x00, 0x2f, 0xec, 0xda, 0x0d, 0x52, 0xf6, 0x6f, 0xd7, 0x3c, + 0x14, 0xa5, 0xe9, 0x81, 0xcd, 0x36, 0x18, 0xee, 0xcb, 0xda, 0xd6, 0xf1, 0xec, + 0x17, 0x27, 0xeb, 0xff, 0x21, 0x1c, 0x0b, 0x7c, 0x34, 0x1c, 0xe7, 0x03, 0x0f, + 0x00, 0xe9, 0x00, 0x19, 0x3e, 0x01, 0xa2, 0xc3, 0x74, 0xe8, 0x31, 0xed, 0xf1, + 0x09, 0xeb, 0xdd, 0xe5, 0x42, 0x52, 0xff, 0xf4, 0xdf, 0xf0, 0xf3, 0x62, 0x01, + 0xfc, 0x12, 0x2c, 0xde, 0xf8, 0xe2, 0x19, 0x1c, 0x1d, 0x15, 0x34, 0x1d, 0xf1, + 0xf0, 0x09, 0x1c, 0xd8, 0x1e, 0xee, 0xfa, 0x30, 0xdf, 0xec, 0x0c, 0x03, 0x1f, + 0x28, 0x20, 0x0a, 0x09, 0xff, 0xf3, 0x43, 0x68, 0xe7, 0x21, 0xe8, 0xfd, 0x7f, + 0xc0, 0xd2, 0xf0, 0x1f, 0xf9, 0x1b, 0x04, 0x25, 0x3b, 0x4a, 0xfc, 0xb2, 0x2c, + 0xf0, 0xcb, 0x42, 0xf7, 0xc6, 0x31, 0x21, 0x35, 0x2b, 0x0a, 0xfa, 0xd3, 0xe6, + 0x35, 0xd2, 0x0f, 0xdc, 0x97, 0x02, 0xc5, 0x19, 0x51, 0xd5, 0xdb, 0xd9, 0xbe, + 0xcc, 0xd8, 0xdd, 0xc8, 0x3b, 0xe6, 0x0b, 0xee, 0xf1, 0x28, 0xc7, 0xdd, 0xec, + 0x11, 0xf2, 0x0d, 0xa5, 0xd9, 0x03, 0x1f, 0xbc, 0xe1, 0x19, 0x3d, 0xf7, 0x00, + 0x60, 0xf4, 0xe9, 0x22, 0x13, 0xd2, 0x02, 0x1a, 0xf3, 0xfe, 0xea, 0xb3, 0xc5, + 0x06, 0xf7, 0xb8, 0x45, 0xc5, 0x27, 0x00, 0x0d, 0xfb, 0x03, 0x3d, 0xd2, 0xf4, + 0x22, 0xcd, 0x23, 0xf7, 0x29, 0x06, 0x9d, 0x26, 0xfd, 0x0f, 0x1a, 0x30, 0x14, + 0x3e, 0xcc, 0xee, 0xe2, 0xba, 0x0d, 0x07, 0x02, 0x68, 0x30, 0xf8, 0x24, 0xe7, + 0x06, 0xdd, 0xed, 0xf2, 0xf2, 0x7f, 0x0f, 0x1c, 0xec, 0x3a, 0xfa, 0x01, 0x18, + 0x03, 0x1e, 0xf4, 0x01, 0xde, 0xfd, 0xe1, 0xf4, 0x08, 0x0a, 0x09, 0xf9, 0x19, + 0x23, 0xff, 0x2e, 0x00, 0xf3, 0xee, 0xf3, 0xf9, 0x03, 0xe4, 0x23, 0xfe, 0x29, + 0x0c, 0x12, 0xec, 0x21, 0x04, 0x03, 0x0c, 0x20, 0x08, 0x23, 0x1e, 0x40, 0xee, + 0x1e, 0x14, 0x08, 0x08, 0x03, 0x0a, 0xfe, 0xdf, 0x00, 0x19, 0xff, 0xf3, 0x04, + 0x0a, 0xf2, 0x01, 0x1e, 0x19, 0x0a, 0x23, 0x09, 0x21, 0xee, 0xff, 0x00, 0x01, + 0x03, 0xfa, 0x1a, 0xfd, 0xf3, 0x0c, 0xee, 0x14, 0x08, 0x0e, 0x03, 0x15, 0xf3, + 0xfe, 0xe9, 0x01, 0xd7, 0x03, 0x03, 0xf0, 0x2c, 0x3a, 0x03, 0x03, 0x04, 0x0b, + 0xe4, 0x05, 0xeb, 0x34, 0xff, 0x00, 0x25, 0x21, 0xdb, 0xd4, 0x0b, 0xd8, 0x06, + 0xec, 0xfe, 0x05, 0x04, 0x04, 0x1c, 0xf2, 0xd9, 0xfb, 0x09, 0xc1, 0xaa, 0x13, + 0x1c, 0x54, 0x8d, 0xcb, 0xd9, 0xc4, 0x1e, 0xc4, 0x21, 0x1f, 0xd4, 0xd7, 0x00, + 0x1a, 0xef, 0xfc, 0x0f, 0x4e, 0x02, 0x10, 0xe8, 0xcf, 0xb2, 0xdd, 0x21, 0x2f, + 0xf4, 0xbe, 0xe3, 0xfb, 0xea, 0xdf, 0x98, 0x03, 0xf0, 0x7f, 0x7c, 0x57, 0x15, + 0xfb, 0x0e, 0xda, 0xd0, 0x5a, 0x20, 0xf6, 0x3a, 0xfb, 0x4a, 0xec, 0xf5, 0xee, + 0x0c, 0xf8, 0xeb, 0xc8, 0xed, 0x03, 0xee, 0x27, 0x28, 0x08, 0xe9, 0xfd, 0x6b, + 0xcf, 0xf3, 0x48, 0x06, 0xba, 0xc5, 0x9d, 0xf3, 0xc6, 0x19, 0xd7, 0xa5, 0x27, + 0x40, 0x27, 0x2b, 0x16, 0x2c, 0xc5, 0x11, 0xe6, 0x23, 0x13, 0xf7, 0xe9, 0x21, + 0x77, 0xab, 0xcd, 0xed, 0x44, 0xfa, 0xeb, 0xca, 0x04, 0xf3, 0xdb, 0xb4, 0xd2, + 0xd5, 0xe0, 0xf4, 0xd4, 0xfa, 0xa4, 0x1c, 0xd7, 0xd1, 0x88, 0xd2, 0x14, 0xcf, + 0x10, 0x0c, 0x05, 0x3d, 0x26, 0x0b, 0x1e, 0xd9, 0xcf, 0x0e, 0xca, 0x01, 0x36, + 0xfe, 0x22, 0xd5, 0x37, 0xd6, 0xd0, 0xbf, 0x19, 0xc9, 0xc9, 0xde, 0x08, 0xb8, + 0x07, 0xf6, 0x2e, 0xdd, 0x10, 0x2e, 0xf8, 0x0e, 0xcb, 0x93, 0xbb, 0xbf, 0x2a, + 0x1d, 0x50, 0x01, 0x0a, 0xdc, 0x2c, 0xed, 0x08, 0xcc, 0x87, 0x5d, 0x1d, 0xee, + 0xed, 0xd0, 0xfb, 0x7f, 0xd5, 0x47, 0x24, 0xa5, 0xd3, 0xe7, 0x02, 0x25, 0xd3, + 0x17, 0xe2, 0xf5, 0xf5, 0xe6, 0xf3, 0x40, 0xca, 0x18, 0xda, 0x4c, 0x01, 0xdf, + 0x67, 0xf2, 0xdf, 0x18, 0x39, 0xf6, 0x12, 0xa3, 0x21, 0xcd, 0x21, 0x62, 0x55, + 0x07, 0x7b, 0xde, 0xea, 0x08, 0xe3, 0xce, 0x00, 0xfe, 0xf6, 0xc4, 0x4f, 0xf3, + 0x39, 0xff, 0xea, 0x31, 0x7e, 0x24, 0xf3, 0xc2, 0x47, 0xaf, 0x10, 0x09, 0x34, + 0xd0, 0xc9, 0xf0, 0x4e, 0xf1, 0x06, 0x1d, 0x58, 0x07, 0x4b, 0x01, 0x0b, 0xd1, + 0x25, 0xe8, 0x0a, 0x40, 0xc4, 0x2f, 0xfd, 0xf9, 0xe5, 0xcf, 0xea, 0x09, 0x00, + 0x1e, 0x07, 0xdd, 0x50, 0x0c, 0xfa, 0xd8, 0x64, 0xe7, 0xdd, 0x0d, 0x1b, 0x06, + 0xcb, 0x7f, 0xf4, 0x18, 0x11, 0x15, 0xe8, 0xdf, 0xeb, 0x03, 0xe0, 0x30, 0x0d, + 0x00, 0xba, 0xe9, 0xe1, 0xb5, 0x05, 0xfb, 0xce, 0xea, 0x3d, 0xc7, 0xd0, 0xd7, + 0x26, 0xde, 0xcc, 0xfb, 0x32, 0xed, 0xdb, 0xec, 0x16, 0x0e, 0x4e, 0x27, 0xfe, + 0x1a, 0x25, 0x15, 0x24, 0xde, 0x0c, 0x20, 0xe3, 0x38, 0xde, 0x0d, 0xf2, 0x22, + 0xd9, 0x2d, 0x47, 0xb7, 0x08, 0xf7, 0xcc, 0x12, 0x13, 0xd6, 0x3a, 0x1b, 0xc4, + 0xaa, 0x06, 0xf7, 0xf2, 0xf0, 0x14, 0xeb, 0x0a, 0xfe, 0x2b, 0xf1, 0x0a, 0x07, + 0x1c, 0xf1, 0xf4, 0x36, 0xba, 0xe2, 0x5c, 0x1a, 0x36, 0xd7, 0xf8, 0xfd, 0x35, + 0xf2, 0xf1, 0x2f, 0x08, 0x07, 0xde, 0x00, 0x39, 0x08, 0xe0, 0xe5, 0x1b, 0xc8, + 0xe9, 0x40, 0xc1, 0xe8, 0x17, 0x18, 0x07, 0x28, 0xd0, 0xc5, 0xd7, 0xf0, 0xc3, + 0x0a, 0xb7, 0xe3, 0x49, 0x2c, 0x15, 0xdb, 0xd8, 0xed, 0x11, 0xc4, 0x96, 0xf5, + 0x19, 0x22, 0x23, 0x05, 0xd7, 0xfa, 0x5e, 0xd6, 0xcc, 0xb0, 0xf5, 0xd4, 0xc0, + 0xff, 0x06, 0x5c, 0xef, 0x0d, 0xe2, 0x29, 0x0b, 0xc1, 0xe1, 0x0d, 0x2d, 0xe6, + 0x04, 0xd3, 0xd8, 0xc0, 0x2c, 0x0b, 0x43, 0x15, 0x09, 0x1b, 0xd5, 0x29, 0xde, + 0xf4, 0x0f, 0x01, 0xf1, 0x04, 0xfb, 0x05, 0x0f, 0xad, 0x26, 0xe7, 0xf1, 0x34, + 0x08, 0xfc, 0xf8, 0x1c, 0xcb, 0xf9, 0x3d, 0x04, 0xf0, 0xf1, 0xd4, 0x02, 0x42, + 0x3b, 0x31, 0x39, 0x1d, 0xe3, 0x30, 0xfc, 0x1f, 0xd5, 0xfd, 0x36, 0x34, 0x00, + 0x3a, 0x0f, 0x0c, 0xd8, 0x53, 0x0a, 0xef, 0x11, 0x1c, 0x7f, 0xaf, 0xd0, 0xfe, + 0x06, 0x05, 0x66, 0xd2, 0xe3, 0xe0, 0xe0, 0x2b, 0xf1, 0xe0, 0xe1, 0x45, 0x56, + 0x12, 0xde, 0xf8, 0x1a, 0xfc, 0x07, 0xcd, 0x0e, 0x03, 0x16, 0x70, 0x2e, 0x30, + 0x35, 0xac, 0x8e, 0x10, 0x14, 0xdd, 0x35, 0x4f, 0x16, 0xfa, 0xeb, 0x0c, 0xf3, + 0xe2, 0x26, 0xbd, 0xfc, 0xd6, 0x2b, 0x92, 0x4d, 0xfa, 0xfa, 0x03, 0xf9, 0xd6, + 0xf2, 0x3a, 0xcc, 0xcc, 0xe0, 0xe9, 0xe7, 0x0f, 0x04, 0xfa, 0xd9, 0xea, 0xe2, + 0xd9, 0x0d, 0xf4, 0xbb, 0xfd, 0x17, 0xfa, 0x29, 0xee, 0xf1, 0x7f, 0xc5, 0xd0, + 0x04, 0x08, 0xeb, 0x14, 0x18, 0xe2, 0x01, 0xca, 0xfc, 0xe2, 0xfc, 0x47, 0x4b, + 0x1c, 0x46, 0xcc, 0x19, 0x08, 0xb8, 0xe4, 0xff, 0x28, 0x3c, 0xfc, 0x25, 0xfe, + 0xc9, 0x03, 0xd9, 0x27, 0xe8, 0x0c, 0x14, 0xda, 0xf7, 0x20, 0xf3, 0x0a, 0x2e, + 0x1d, 0x28, 0xeb, 0x1c, 0x03, 0x18, 0xde, 0xec, 0x42, 0x67, 0x09, 0x16, 0x43, + 0xc6, 0xfe, 0xeb, 0x0e, 0x01, 0xce, 0xe6, 0xe5, 0x01, 0x46, 0x05, 0xef, 0x0c, + 0xe2, 0xe5, 0xe1, 0x9a, 0x27, 0xe8, 0xdf, 0xe6, 0x35, 0xc1, 0x10, 0xf7, 0xcd, + 0x2e, 0x00, 0xda, 0xfd, 0xd8, 0xf8, 0xea, 0x7f, 0xb8, 0xdf, 0xd9, 0xa9, 0x2e, + 0x03, 0xfa, 0xfb, 0xf3, 0x20, 0x1a, 0x64, 0xe2, 0x2c, 0xf7, 0xf7, 0xf8, 0xef, + 0x65, 0xee, 0xe3, 0xc9, 0xf3, 0xf4, 0xdb, 0xf6, 0x65, 0xe3, 0x1d, 0xb0, 0xc7, + 0xdf, 0x00, 0xc7, 0xf8, 0xde, 0x2d, 0xe9, 0x08, 0x3b, 0xde, 0x38, 0x54, 0x06, + 0x22, 0x10, 0xf3, 0x62, 0x0e, 0x43, 0x20, 0x22, 0xe7, 0xd2, 0xfa, 0x3c, 0xe0, + 0xef, 0xe4, 0x39, 0x42, 0x2b, 0xe5, 0x31, 0xf4, 0xe9, 0xfa, 0xcf, 0x37, 0x0c, + 0xf7, 0x18, 0x11, 0xc2, 0x15, 0x3e, 0x24, 0x25, 0x2a, 0xef, 0xf3, 0xe0, 0xd4, + 0x44, 0xff, 0xf8, 0xc4, 0x20, 0xff, 0x0f, 0x07, 0x68, 0xf7, 0x1c, 0x16, 0xa4, + 0x22, 0x0f, 0xda, 0xf4, 0x42, 0xea, 0xee, 0x79, 0x4c, 0x07, 0x1f, 0xe1, 0xd8, + 0x03, 0xfb, 0xf2, 0xf7, 0x05, 0xea, 0x40, 0xf4, 0x1c, 0x3d, 0x1b, 0x11, 0x12, + 0x13, 0x20, 0x47, 0x34, 0x40, 0x19, 0xdf, 0xd1, 0xe1, 0x3e, 0x07, 0x1e, 0x34, + 0xf3, 0x2b, 0x0d, 0xd8, 0x22, 0xea, 0x11, 0x23, 0x03, 0x19, 0xda, 0xf6, 0xf9, + 0x38, 0xcd, 0x06, 0x48, 0xe6, 0x37, 0x46, 0x1a, 0x1b, 0x01, 0x28, 0xf9, 0xed, + 0xfd, 0xea, 0xf2, 0x30, 0x01, 0xe7, 0x0a, 0x0a, 0x22, 0x32, 0xe4, 0x47, 0xdd, + 0x02, 0x23, 0x29, 0x58, 0x22, 0x22, 0xcf, 0xd8, 0x55, 0x44, 0xc2, 0x07, 0x20, + 0xe1, 0x3c, 0xf0, 0x79, 0x13, 0x06, 0x04, 0xfd, 0x01, 0xf3, 0xf0, 0x13, 0xf3, + 0xdb, 0x10, 0xee, 0x29, 0xf7, 0x2e, 0x42, 0x1a, 0xdb, 0xea, 0xeb, 0x02, 0xed, + 0x02, 0xe5, 0x51, 0x0e, 0xf0, 0x12, 0x7f, 0xd8, 0x14, 0xef, 0x45, 0xf7, 0xe9, + 0xce, 0x23, 0x16, 0x16, 0x43, 0x00, 0xec, 0xf2, 0xda, 0xcc, 0x4b, 0xf3, 0x3b, + 0xd5, 0xe8, 0x32, 0xe5, 0x39, 0xe0, 0xc1, 0x56, 0xdb, 0x11, 0xf1, 0xe8, 0x35, + 0x07, 0x1a, 0xd6, 0x25, 0xa4, 0x30, 0xf2, 0xf4, 0xc7, 0x19, 0x69, 0x54, 0xfc, + 0xa8, 0x23, 0xfd, 0xee, 0x07, 0x01, 0xd0, 0xaf, 0x28, 0xfd, 0xdf, 0x20, 0x81, + 0x19, 0x36, 0x03, 0xf2, 0x0f, 0x0d, 0x28, 0xce, 0xc4, 0xc1, 0xc6, 0x26, 0xc9, + 0xe8, 0xa0, 0xe4, 0x8e, 0xd2, 0x24, 0xda, 0xf7, 0xfd, 0xa3, 0xf8, 0xfc, 0xb0, + 0x08, 0x2b, 0x2c, 0x0d, 0x19, 0x17, 0x1b, 0xa3, 0x77, 0x76, 0xfc, 0xdd, 0x2e, + 0x0e, 0xf3, 0xc0, 0x6c, 0x1f, 0xd5, 0x06, 0xb9, 0xe5, 0xd7, 0x00, 0x03, 0xc7, + 0xbd, 0x13, 0x3e, 0xe0, 0x34, 0x0a, 0x36, 0xed, 0x2c, 0xd0, 0xe4, 0xa3, 0x16, + 0xdd, 0xc0, 0x1f, 0xfa, 0xbc, 0xb2, 0x14, 0xf3, 0xea, 0xf7, 0xd6, 0xe9, 0xe6, + 0xf6, 0x23, 0x2d, 0x00, 0xb8, 0xeb, 0x40, 0x17, 0x12, 0x77, 0xd1, 0xc4, 0x01, + 0x11, 0x46, 0xd1, 0x52, 0x36, 0x4c, 0xef, 0x05, 0xe0, 0x29, 0xc1, 0x6b, 0x14, + 0x04, 0x1d, 0x07, 0x2a, 0x41, 0x04, 0x15, 0x1e, 0x25, 0x04, 0x0d, 0x41, 0xe0, + 0xf6, 0xfc, 0xf5, 0xe6, 0xe7, 0x07, 0x37, 0x30, 0x30, 0x27, 0x47, 0xe7, 0xec, + 0x33, 0x00, 0x22, 0x08, 0x02, 0x1c, 0x26, 0x6a, 0xf9, 0x1c, 0xb8, 0xc9, 0xda, + 0xe0, 0xfc, 0xfa, 0x1c, 0xeb, 0x31, 0xf3, 0xc6, 0x22, 0x1b, 0xf6, 0x04, 0xd0, + 0x10, 0xe7, 0x36, 0x0f, 0x7f, 0x08, 0x1d, 0x03, 0xde, 0xc1, 0x30, 0x30, 0x1e, + 0x08, 0xbd, 0xcc, 0x29, 0xe2, 0x06, 0x21, 0xe3, 0xd7, 0x59, 0xe9, 0xcd, 0xf0, + 0x17, 0x07, 0x31, 0xc3, 0xbb, 0xcf, 0xfa, 0x14, 0xe1, 0x67, 0xea, 0x15, 0x0b, + 0x08, 0x23, 0x37, 0x33, 0xdb, 0x29, 0xc0, 0x0e, 0x1f, 0xef, 0xfd, 0x0c, 0x59, + 0x13, 0x1d, 0x71, 0xfa, 0x1b, 0x02, 0xe3, 0xe7, 0xde, 0xcf, 0x54, 0xff, 0x2b, + 0xdd, 0x33, 0x3d, 0xd6, 0xed, 0xb0, 0xd8, 0xe3, 0x0b, 0x0c, 0xfe, 0x3c, 0x0a, + 0x10, 0xf7, 0xd5, 0x48, 0x20, 0xc4, 0xdf, 0x04, 0xe6, 0x12, 0x20, 0x01, 0x38, + 0xfe, 0xd8, 0xea, 0x57, 0xde, 0x9a, 0x45, 0xe4, 0x16, 0x1f, 0x59, 0x17, 0x23, + 0xda, 0x0c, 0xfb, 0xe1, 0x33, 0xe5, 0xcd, 0xd7, 0x17, 0xe6, 0xe1, 0xc5, 0xff, + 0x9a, 0xd3, 0xc8, 0xe6, 0xf5, 0xdf, 0xd5, 0xd5, 0xfc, 0x19, 0xe3, 0x27, 0xb5, + 0xf5, 0xed, 0x27, 0xff, 0xe0, 0xd7, 0x34, 0x0f, 0xe2, 0xd2, 0xfa, 0x08, 0x00, + 0x57, 0xcf, 0xe7, 0xf4, 0x20, 0x09, 0x0f, 0x7f, 0x07, 0x42, 0xda, 0xfc, 0xf9, + 0x0a, 0xdf, 0xda, 0xf7, 0x23, 0xd3, 0x2a, 0x04, 0x04, 0x0b, 0xc2, 0x0e, 0x0d, + 0xf4, 0x13, 0x06, 0xf4, 0x25, 0xe6, 0xf5, 0xed, 0xd3, 0x0e, 0xa7, 0xee, 0xed, + 0x1b, 0x05, 0x3f, 0x4c, 0x1c, 0xd0, 0x34, 0xb3, 0x3a, 0xf8, 0xf4, 0x45, 0x3f, + 0x24, 0xc4, 0xaa, 0xf1, 0xc1, 0x16, 0x0d, 0xf0, 0x5d, 0x2d, 0x2d, 0xeb, 0xfc, + 0xe8, 0xf1, 0x18, 0x0e, 0x22, 0x28, 0xd1, 0xb4, 0x3c, 0x0b, 0xfc, 0x18, 0x11, + 0xe0, 0xfc, 0xe2, 0x3e, 0x01, 0x43, 0xdf, 0x02, 0x72, 0x05, 0x20, 0xec, 0xd3, + 0xc3, 0xfa, 0x35, 0xe5, 0xf7, 0xf7, 0xd9, 0xde, 0xf2, 0xf0, 0xc3, 0xfb, 0xfa, + 0xb7, 0x04, 0x01, 0xc2, 0x55, 0xb4, 0xfa, 0x04, 0xf0, 0x02, 0xa5, 0x2d, 0xe6, + 0x37, 0xb7, 0x16, 0xb1, 0xca, 0x1e, 0xc9, 0xd0, 0x47, 0x1b, 0x2e, 0x52, 0x2f, + 0xbf, 0xd7, 0x06, 0xa3, 0xde, 0x33, 0xef, 0xa4, 0x01, 0x5f, 0xd8, 0xe9, 0xb3, + 0x3d, 0xf8, 0x35, 0x2e, 0xf7, 0x13, 0x27, 0xde, 0xd2, 0x70, 0x1b, 0xd0, 0x12, + 0xfb, 0xac, 0xf0, 0xed, 0xd9, 0xc2, 0xe7, 0x15, 0x05, 0xc8, 0x0e, 0x81, 0x08, + 0x07, 0x12, 0xbc, 0xcb, 0x4a, 0x00, 0xee, 0xd5, 0xdd, 0xd8, 0x2b, 0x2b, 0x0c, + 0x39, 0xc7, 0xf7, 0xc2, 0x30, 0xd1, 0x1c, 0x0c, 0x20, 0x30, 0x0d, 0x26, 0x3e, + 0x2a, 0x28, 0xcf, 0x0e, 0x01, 0x7f, 0xe2, 0xf5, 0xc3, 0x28, 0x05, 0x20, 0x08, + 0xf2, 0x10, 0x04, 0xf7, 0xed, 0xd8, 0x43, 0xf3, 0xf7, 0xd4, 0x2b, 0x26, 0xdd, + 0xe1, 0x51, 0xf2, 0x3f, 0x39, 0xaa, 0xf6, 0x24, 0xd6, 0x2c, 0x15, 0xde, 0xf4, + 0xf9, 0xf6, 0x17, 0xdd, 0x1d, 0xe7, 0xf8, 0x02, 0xd2, 0xbd, 0xe4, 0x13, 0x0c, + 0x42, 0x12, 0x1e, 0x09, 0xfb, 0x40, 0x3c, 0x1f, 0xe2, 0xdc, 0x09, 0x1c, 0x12, + 0x4d, 0x3e, 0x16, 0x37, 0x0a, 0x37, 0x15, 0xf0, 0x24, 0xd1, 0xbb, 0xe7, 0x07, + 0xe3, 0xd8, 0xc9, 0x4f, 0xc1, 0x04, 0x05, 0xd4, 0x1d, 0xae, 0xc1, 0xcc, 0x15, + 0x0d, 0x07, 0x0e, 0x13, 0xcf, 0x0b, 0x07, 0x01, 0x0e, 0xf7, 0xc4, 0x1a, 0x36, + 0xea, 0x15, 0xed, 0xe3, 0x15, 0x7f, 0x2d, 0x2d, 0xf6, 0x10, 0xdd, 0xe4, 0xdf, + 0xf8, 0xf2, 0xe7, 0x06, 0x5d, 0xff, 0xc0, 0x04, 0x06, 0xdb, 0x2e, 0xf5, 0xc1, + 0x52, 0xd1, 0x04, 0xe1, 0x28, 0xdb, 0x15, 0x03, 0x17, 0xda, 0x10, 0xe6, 0x35, + 0xe6, 0xcc, 0xea, 0x33, 0x46, 0x04, 0xc9, 0xd0, 0x4c, 0xf4, 0xfc, 0x64, 0x30, + 0xe0, 0x48, 0xc0, 0x17, 0xd0, 0x1c, 0xdb, 0xfa, 0xe4, 0xf4, 0x1d, 0xe1, 0xb4, + 0x17, 0x13, 0xe0, 0xff, 0xf6, 0xc2, 0x24, 0xea, 0x61, 0x34, 0xf7, 0xfe, 0x1f, + 0xf3, 0xfd, 0xb0, 0x3a, 0xe1, 0xeb, 0x6c, 0x1d, 0x17, 0xf3, 0xec, 0x17, 0xda, + 0xf0, 0x21, 0xf4, 0x00, 0xe5, 0x3d, 0xe3, 0x16, 0x03, 0x07, 0xd3, 0xec, 0x11, + 0x26, 0xde, 0xe1, 0xbb, 0xd8, 0x04, 0x2a, 0x24, 0x11, 0xeb, 0x3c, 0x25, 0x1f, + 0xf3, 0x10, 0xed, 0x2e, 0x3f, 0xff, 0xa3, 0xdf, 0x3a, 0x49, 0xe4, 0xdd, 0x1f, + 0xf1, 0xc8, 0x60, 0xec, 0xe7, 0xe9, 0x36, 0xe9, 0x08, 0xf9, 0xcf, 0xeb, 0x03, + 0x04, 0x17, 0x38, 0xdb, 0xe1, 0x10, 0x11, 0xdf, 0xfe, 0xe9, 0x2f, 0xe0, 0xed, + 0xfc, 0xc0, 0xfd, 0xff, 0xea, 0xdd, 0xd9, 0xdb, 0x25, 0xf9, 0x2a, 0x2f, 0xe7, + 0x1f, 0x31, 0xec, 0xef, 0x71, 0x16, 0x54, 0xe5, 0x03, 0x1d, 0xf8, 0x22, 0xf8, + 0x0e, 0x00, 0x18, 0xf4, 0x03, 0x05, 0x0c, 0x02, 0x29, 0xfb, 0xe3, 0xe3, 0x27, + 0x1c, 0x30, 0x15, 0x35, 0xe6, 0x1d, 0x42, 0xf9, 0xe3, 0xfe, 0xeb, 0xec, 0x19, + 0xb7, 0xf9, 0x02, 0x1c, 0xd3, 0xff, 0xf5, 0xf3, 0x17, 0x0a, 0xfd, 0x08, 0x7f, + 0xf9, 0xfd, 0x06, 0x30, 0xdd, 0x1e, 0xf0, 0x0c, 0x1e, 0x3b, 0xff, 0xf2, 0x2a, + 0xfe, 0x15, 0xde, 0xcf, 0x2c, 0xf9, 0x0d, 0xff, 0x02, 0x01, 0xeb, 0xe9, 0x19, + 0xfe, 0x39, 0x31, 0x03, 0xe1, 0x00, 0x15, 0xea, 0xda, 0x00, 0xca, 0xf7, 0x3f, + 0xfc, 0xfe, 0x13, 0x03, 0xf2, 0xe5, 0x3e, 0x14, 0x44, 0xdf, 0x07, 0x38, 0x05, + 0xda, 0xe0, 0x15, 0x3b, 0x1b, 0x02, 0xe0, 0x06, 0x7f, 0x46, 0x29, 0xf3, 0x0f, + 0xeb, 0x14, 0xf6, 0x0f, 0x07, 0x1a, 0xd8, 0x09, 0xff, 0xee, 0xd4, 0x1e, 0x41, + 0xeb, 0xdf, 0xdb, 0x01, 0xae, 0x1c, 0x35, 0xe0, 0xea, 0xe4, 0xcd, 0xfe, 0x08, + 0xeb, 0xfa, 0x2f, 0x00, 0x09, 0x24, 0x0b, 0x02, 0x15, 0xed, 0x5d, 0xe6, 0x00, + 0x11, 0xfa, 0x34, 0x12, 0xd6, 0xca, 0xc3, 0xd2, 0x31, 0xde, 0xce, 0x29, 0x15, + 0xdc, 0xd0, 0xfc, 0xc8, 0x3b, 0x0f, 0xf9, 0xd5, 0xe4, 0x06, 0xc8, 0x31, 0xfd, + 0x13, 0xf3, 0xf6, 0x1e, 0xf9, 0xec, 0x39, 0xbd, 0x77, 0xdf, 0xde, 0xd3, 0xb6, + 0x51, 0xf0, 0xb0, 0x07, 0xf0, 0xde, 0x11, 0xb8, 0xda, 0x24, 0xe6, 0x23, 0xd4, + 0xec, 0x21, 0x56, 0xb5, 0xbc, 0x13, 0x2c, 0x21, 0x06, 0x03, 0x06, 0xf8, 0x2b, + 0x14, 0x31, 0xc5, 0x65, 0x40, 0xbc, 0xe9, 0x9b, 0x18, 0xe6, 0x0d, 0xf8, 0xf2, + 0x07, 0xf4, 0xea, 0x01, 0x26, 0x46, 0xe4, 0x1b, 0xfb, 0x0e, 0xd0, 0x43, 0x40, + 0xe1, 0xe8, 0x33, 0xc5, 0x44, 0xe9, 0x81, 0xf5, 0xe3, 0xe2, 0x08, 0x0a, 0x40, + 0x14, 0x2c, 0xd6, 0xd9, 0xed, 0xee, 0x54, 0x02, 0xcf, 0xfe, 0x1a, 0xcf, 0xf5, + 0x1d, 0x26, 0xfe, 0xca, 0x30, 0xc5, 0xd8, 0x33, 0x9c, 0xed, 0x1f, 0xf2, 0xdf, + 0xd4, 0x63, 0xdf, 0x20, 0xbf, 0xf8, 0x3c, 0x27, 0xd1, 0xde, 0x00, 0x32, 0xdf, + 0xc2, 0xb4, 0x09, 0xdd, 0x03, 0x0f, 0x0c, 0x08, 0x9c, 0xd2, 0xe0, 0x5a, 0xf8, + 0xb3, 0xe6, 0x15, 0x14, 0xf0, 0x0f, 0x29, 0x11, 0xd8, 0x15, 0x32, 0xda, 0x04, + 0xba, 0xe4, 0xee, 0x44, 0xf2, 0xae, 0x22, 0x25, 0xe0, 0xc2, 0xe7, 0x54, 0xfd, + 0x2d, 0x93, 0x30, 0x1c, 0xf3, 0x49, 0x37, 0xbe, 0x1a, 0xb9, 0x68, 0xec, 0x06, + 0x0b, 0x33, 0xb7, 0xc4, 0xd0, 0x1a, 0xf4, 0x09, 0x13, 0x0c, 0x27, 0xe5, 0x07, + 0xae, 0xf4, 0x20, 0xea, 0xf1, 0xfc, 0xd4, 0x03, 0x3b, 0x35, 0xc4, 0xdd, 0xc4, + 0xf4, 0xea, 0x2f, 0xfb, 0x85, 0x66, 0x02, 0xce, 0x1c, 0xf1, 0xa5, 0x2b, 0xe6, + 0xf8, 0xd7, 0xde, 0xd7, 0xc6, 0x02, 0x81, 0x22, 0x3b, 0xd7, 0x9c, 0x37, 0x20, + 0xe2, 0xee, 0xfe, 0xee, 0x21, 0x0a, 0xe6, 0x0e, 0x18, 0xf7, 0x50, 0x11, 0xe7, + 0x45, 0xa7, 0xd6, 0x07, 0xe8, 0x1b, 0xe1, 0x38, 0xac, 0x04, 0xf6, 0xba, 0x01, + 0xec, 0xec, 0xea, 0xfd, 0xfc, 0x00, 0x51, 0x32, 0xf9, 0xa5, 0xc8, 0xe5, 0xd4, + 0x05, 0x31, 0x04, 0x1e, 0xe0, 0xf0, 0xeb, 0x0e, 0x55, 0xf5, 0x3c, 0x13, 0xe3, + 0x43, 0x1b, 0xb0, 0x30, 0xec, 0x58, 0xda, 0x3f, 0x01, 0x06, 0xc5, 0x1e, 0x58, + 0x27, 0xcb, 0x13, 0x22, 0x67, 0x25, 0xf6, 0x03, 0x0e, 0xeb, 0xcb, 0x10, 0x2f, + 0xdd, 0x0a, 0x06, 0xf8, 0x0e, 0x01, 0x32, 0xf2, 0xdc, 0xf3, 0xc2, 0x4e, 0xfd, + 0xae, 0xc7, 0x5a, 0x13, 0xfb, 0xc4, 0xd0, 0x35, 0x41, 0x15, 0xf6, 0xdf, 0xef, + 0x17, 0x52, 0xc8, 0xdc, 0xf9, 0xc7, 0x51, 0xf8, 0xc2, 0xd2, 0x45, 0x49, 0xde, + 0xe4, 0x58, 0xad, 0x08, 0x0d, 0x26, 0xf4, 0xc8, 0xd3, 0xe6, 0xb3, 0xf7, 0xfa, + 0x16, 0x0f, 0xcf, 0xdf, 0xf5, 0x0e, 0x0f, 0xe4, 0x14, 0xeb, 0x2c, 0x81, 0xfd, + 0xef, 0xf9, 0x4a, 0xf9, 0xfa, 0x01, 0x9a, 0xe2, 0xa3, 0x5b, 0x14, 0x63, 0xe2, + 0xd9, 0xe0, 0xe8, 0xfc, 0x00, 0xf5, 0xdf, 0x07, 0x65, 0xd4, 0x14, 0x10, 0x21, + 0xd9, 0x00, 0xa9, 0x14, 0x2d, 0x05, 0x13, 0xdb, 0x05, 0x27, 0x39, 0xe2, 0x17, + 0xcd, 0xf3, 0xf5, 0xeb, 0xc2, 0xd0, 0xe3, 0x1d, 0xd8, 0x06, 0xfd, 0xc9, 0xcb, + 0x4c, 0xf7, 0xd6, 0xff, 0x0c, 0x28, 0x02, 0x08, 0xbc, 0x31, 0xdb, 0x37, 0xe3, + 0xf7, 0x81, 0x2e, 0xd1, 0xc7, 0x00, 0x41, 0xd2, 0xc4, 0x13, 0x12, 0x04, 0x0e, + 0x19, 0xee, 0xd6, 0x3c, 0x4d, 0xe4, 0xe2, 0x1f, 0x28, 0x04, 0xd7, 0x3d, 0xf5, + 0xcb, 0xeb, 0xb1, 0x1e, 0xbb, 0x17, 0xee, 0x36, 0x2c, 0xf8, 0x15, 0x09, 0xfd, + 0x33, 0xc4, 0xc2, 0xf2, 0xd5, 0xf9, 0xbe, 0x0c, 0xbc, 0x50, 0xb9, 0xed, 0xc4, + 0xd6, 0xdd, 0xed, 0x13, 0x06, 0xfe, 0x1d, 0x0d, 0xf5, 0xa3, 0x0d, 0xd3, 0x6b, + 0xe6, 0xff, 0x65, 0x29, 0xb4, 0x0e, 0xf0, 0xec, 0xe1, 0x1b, 0xee, 0xe4, 0xeb, + 0xf5, 0xec, 0x7b, 0x24, 0x2b, 0x26, 0x06, 0xc8, 0x27, 0x04, 0xfe, 0x2d, 0x12, + 0xa1, 0xe0, 0xe2, 0x18, 0x43, 0x24, 0x57, 0x1f, 0x0a, 0x1c, 0xfc, 0x1b, 0xe5, + 0xdd, 0x1d, 0xe0, 0xf5, 0x16, 0xe0, 0xf0, 0xef, 0xb0, 0x26, 0xdd, 0x17, 0xcf, + 0xe7, 0x0e, 0x11, 0xf7, 0xdf, 0x34, 0x21, 0xfd, 0xbc, 0xd4, 0x07, 0x0b, 0x10, + 0x3a, 0xbb, 0xdb, 0xdc, 0x31, 0x56, 0xfb, 0xf8, 0xff, 0x60, 0x04, 0xb5, 0x7f, + 0xdf, 0xfd, 0x06, 0x2c, 0xd8, 0xea, 0x16, 0xbd, 0xe1, 0x2a, 0x0c, 0xd4, 0xf6, + 0x44, 0x05, 0xd4, 0x19, 0xe1, 0xb8, 0xe8, 0x04, 0x06, 0xd6, 0xcc, 0x53, 0xdb, + 0xef, 0xfe, 0xd1, 0xf0, 0xe5, 0xfa, 0xc1, 0xc1, 0x1a, 0xbf, 0xea, 0x07, 0x08, + 0x52, 0x0d, 0xb8, 0x0d, 0x07, 0x26, 0x4e, 0xe0, 0x02, 0x06, 0x08, 0xe8, 0xfe, + 0xc3, 0xea, 0x50, 0x21, 0x05, 0xe5, 0x10, 0xc3, 0x1c, 0xfd, 0xf9, 0x06, 0x1e, + 0xdb, 0x49, 0x22, 0x1c, 0x07, 0xfd, 0xfe, 0x14, 0xea, 0x0e, 0xdf, 0xfb, 0xed, + 0x12, 0xef, 0x0b, 0x79, 0x1c, 0x2d, 0xc7, 0x11, 0x06, 0x1b, 0x0c, 0xf6, 0x07, + 0x21, 0x0d, 0x0f, 0xf6, 0x39, 0xc0, 0x1c, 0x23, 0xfa, 0xe3, 0x1a, 0x1f, 0x1c, + 0x01, 0xcc, 0xd6, 0x3a, 0x12, 0x3d, 0x97, 0x1e, 0x0d, 0x34, 0x16, 0x39, 0x33, + 0x23, 0xe1, 0xd4, 0x2b, 0x11, 0xfd, 0x1e, 0xd2, 0x2c, 0x9f, 0x01, 0x65, 0x10, + 0xca, 0x1f, 0xca, 0xfb, 0xce, 0x06, 0xbe, 0x29, 0x28, 0xea, 0x7f, 0x06, 0xa3, + 0x15, 0xdc, 0x18, 0x1e, 0xe4, 0x61, 0x0c, 0x0d, 0xeb, 0xcf, 0xf9, 0xb4, 0xe1, + 0x12, 0xb3, 0xff, 0x14, 0xe4, 0xc2, 0xe7, 0x02, 0xe7, 0x03, 0x0e, 0x34, 0x7c, + 0x46, 0x3c, 0x3f, 0x05, 0x06, 0x87, 0xba, 0xdf, 0xdb, 0x28, 0x01, 0x1b, 0xdf, + 0xf9, 0xf1, 0xba, 0x0d, 0xe3, 0xe2, 0xc2, 0xf3, 0x0a, 0xf7, 0xd2, 0x39, 0xea, + 0xb4, 0x11, 0x3b, 0xcb, 0x3d, 0xe9, 0xcd, 0xad, 0xcd, 0xac, 0x46, 0xf3, 0x5c, + 0x14, 0x56, 0xd0, 0xcb, 0xee, 0xc3, 0x12, 0x4c, 0x9d, 0xfa, 0xde, 0x03, 0x30, + 0xe7, 0xd0, 0x00, 0x2c, 0x2f, 0x3d, 0xe9, 0x15, 0x51, 0x18, 0x17, 0xe4, 0xf9, + 0x7f, 0x22, 0xd7, 0xfa, 0x1e, 0x10, 0xfc, 0xea, 0x64, 0x4b, 0xff, 0x2e, 0x12, + 0xda, 0xd0, 0xdb, 0x0a, 0x2c, 0x7a, 0xf3, 0x2d, 0x99, 0xab, 0x23, 0x22, 0x16, + 0x45, 0xcb, 0x1d, 0x0b, 0xfe, 0x0f, 0x00, 0x1c, 0xe2, 0xd1, 0xf4, 0xac, 0x73, + 0xec, 0x01, 0x27, 0xf8, 0x50, 0x3b, 0xd5, 0xdb, 0xef, 0x15, 0xfd, 0x19, 0x14, + 0xe4, 0x49, 0xe4, 0x2f, 0xf2, 0x10, 0x0f, 0x0e, 0x01, 0x23, 0x51, 0x1e, 0x23, + 0x46, 0x14, 0xde, 0xf9, 0x23, 0x2f, 0x03, 0xf4, 0x12, 0x18, 0x63, 0xdb, 0xf7, + 0xf7, 0x07, 0xb7, 0xed, 0x2d, 0xbd, 0xea, 0xdb, 0xdd, 0x2f, 0xfe, 0xe8, 0xff, + 0xf5, 0xf3, 0x08, 0xe7, 0x2d, 0x2e, 0xe9, 0x07, 0xdd, 0xca, 0x1d, 0x4b, 0xf8, + 0xd6, 0x0e, 0x6e, 0xce, 0xc3, 0x17, 0x18, 0xe7, 0xf5, 0xde, 0xf9, 0xcd, 0x31, + 0x78, 0xfd, 0x1b, 0x7c, 0x32, 0x40, 0x43, 0x05, 0xdd, 0x03, 0xf6, 0xe7, 0x0a, + 0xc9, 0x27, 0x26, 0xe8, 0x12, 0xd7, 0xf2, 0xc9, 0x07, 0xf6, 0xe1, 0xea, 0xf3, + 0xfd, 0xd9, 0x05, 0xd8, 0x2a, 0x17, 0x18, 0xe6, 0x1b, 0x25, 0x11, 0x12, 0x35, + 0xe1, 0x32, 0x06, 0xfb, 0x12, 0x2b, 0x3b, 0x14, 0xed, 0xd4, 0xe8, 0x09, 0x02, + 0x10, 0x7f, 0xe2, 0xf8, 0xbd, 0xe4, 0xe7, 0xc3, 0xeb, 0xff, 0x13, 0x04, 0xf8, + 0xdd, 0x11, 0xba, 0x27, 0xf4, 0xc7, 0x00, 0xd8, 0x5b, 0x24, 0x60, 0x44, 0xd7, + 0xfe, 0xc8, 0xce, 0x41, 0xe4, 0x27, 0xd5, 0x1b, 0x36, 0xca, 0xe8, 0x4f, 0xdf, + 0x22, 0x15, 0x18, 0x2e, 0x01, 0x06, 0x27, 0xed, 0xe8, 0xff, 0x29, 0x08, 0xd3, + 0x2b, 0xfe, 0xf1, 0xee, 0xfc, 0xe3, 0x15, 0xb6, 0xe8, 0x6d, 0x05, 0xf3, 0x1b, + 0x4f, 0x4f, 0x0c, 0x0b, 0x6c, 0x1c, 0xda, 0xfa, 0xd4, 0xf9, 0x0e, 0x11, 0xf8, + 0xf1, 0x25, 0x32, 0xfc, 0xfc, 0xef, 0x13, 0xf7, 0xf4, 0x23, 0x40, 0xde, 0x2b, + 0x3e, 0x19, 0xe4, 0xf1, 0x2d, 0xf3, 0xf3, 0x0e, 0x2a, 0x3c, 0x1e, 0x20, 0x09, + 0x12, 0x7a, 0x1d, 0x0d, 0x1f, 0x15, 0x35, 0x0e, 0xfd, 0x1e, 0xf0, 0xff, 0x0e, + 0xde, 0x1f, 0x19, 0xe5, 0x20, 0x1d, 0xee, 0xe5, 0x7f, 0x0b, 0x0e, 0xfa, 0xea, + 0xfd, 0xe9, 0xdf, 0x02, 0xe1, 0xec, 0x01, 0x12, 0x00, 0xe7, 0x11, 0x35, 0xf2, + 0xe2, 0xf9, 0xfb, 0xec, 0x08, 0xd9, 0x0f, 0xea, 0xf4, 0xf0, 0xee, 0x02, 0xf3, + 0xf1, 0x38, 0x1d, 0x1c, 0x37, 0xdf, 0x0b, 0xe2, 0x16, 0xf9, 0xfd, 0x09, 0xe8, + 0xed, 0xef, 0x00, 0x0d, 0x17, 0xf7, 0xeb, 0x0c, 0xf2, 0x12, 0xf3, 0xef, 0x39, + 0xfa, 0xd9, 0x02, 0xdf, 0x0a, 0xe5, 0xf2, 0x1c, 0xf7, 0x0e, 0x19, 0x05, 0x21, + 0x04, 0xf9, 0x24, 0xd9, 0xdf, 0xfc, 0xfa, 0x02, 0x34, 0x16, 0x34, 0x21, 0xff, + 0xd7, 0xf2, 0x1f, 0xf1, 0xec, 0x0d, 0xfe, 0xfd, 0xfe, 0x2a, 0x2f, 0xf7, 0x33, + 0xef, 0x4b, 0xce, 0x36, 0xef, 0xd4, 0xee, 0xf5, 0x5c, 0xee, 0x1a, 0xd5, 0xe9, + 0xe0, 0x51, 0xe4, 0xcb, 0x09, 0x43, 0xd4, 0xfb, 0x12, 0x27, 0xe5, 0x17, 0x21, + 0x05, 0x7f, 0x1e, 0x0c, 0xfe, 0xf0, 0xea, 0xda, 0xe9, 0x47, 0xfc, 0x07, 0x0d, + 0xed, 0xdb, 0xd2, 0xdb, 0xfa, 0xe5, 0x13, 0x08, 0x09, 0xf8, 0x15, 0x15, 0x16, + 0xe7, 0xe7, 0x46, 0x24, 0x18, 0xf2, 0x2d, 0xf8, 0xfc, 0x11, 0x02, 0x2c, 0x13, + 0xce, 0xe5, 0xef, 0x1a, 0x49, 0x21, 0xcd, 0xe7, 0xe9, 0xf6, 0x17, 0x2f, 0xfc, + 0xc3, 0x20, 0xf0, 0x07, 0x06, 0xf3, 0x12, 0x0f, 0x1c, 0xf3, 0xd9, 0xfc, 0xf7, + 0x0b, 0xfd, 0xf9, 0x00, 0x0f, 0x1e, 0xf4, 0xd2, 0xdb, 0x0d, 0xdc, 0x07, 0xee, + 0xf6, 0xe8, 0x22, 0xff, 0x30, 0xd3, 0x19, 0x27, 0x2c, 0xfa, 0xfa, 0x4a, 0xf3, + 0x2a, 0xe8, 0xd6, 0x39, 0xe9, 0x04, 0x0b, 0x1b, 0x34, 0xec, 0xf7, 0x3d, 0xa3, + 0x08, 0x5b, 0x26, 0xdc, 0xc2, 0x48, 0xdd, 0x2f, 0x2d, 0xf6, 0x60, 0x02, 0x37, + 0x59, 0xa4, 0x3a, 0x06, 0x02, 0x36, 0xff, 0x16, 0x1e, 0xf2, 0x68, 0x0b, 0x01, + 0x0e, 0xe8, 0xea, 0x30, 0x6a, 0x4d, 0x37, 0x38, 0xfb, 0xdb, 0xf4, 0x2a, 0x0d, + 0xfb, 0x14, 0xef, 0xe7, 0xce, 0x00, 0xeb, 0x0b, 0x05, 0xb8, 0x10, 0xcb, 0x2c, + 0xf5, 0xbf, 0x2f, 0x27, 0x65, 0x6d, 0x0b, 0x9f, 0x27, 0x4b, 0xfe, 0xe3, 0xee, + 0x24, 0xdd, 0x6a, 0xf1, 0xf3, 0xd5, 0x9d, 0x14, 0xdc, 0xf7, 0xfe, 0x15, 0xca, + 0xaa, 0x52, 0xf5, 0x16, 0xdb, 0xdb, 0x47, 0x10, 0x30, 0xcb, 0x0c, 0xf4, 0x00, + 0x0c, 0xf4, 0xb6, 0x7f, 0xc8, 0xe8, 0xe9, 0x23, 0x37, 0x00, 0x09, 0xf0, 0x0b, + 0xf6, 0xe6, 0xf3, 0x30, 0xe7, 0x37, 0x56, 0x45, 0xd3, 0x10, 0xc1, 0xfc, 0xbb, + 0x8c, 0x32, 0x0d, 0x11, 0xb7, 0x6d, 0xdd, 0x18, 0x5b, 0x46, 0x14, 0xc5, 0x17, + 0x2e, 0xf3, 0x2b, 0x02, 0x45, 0xdb, 0x3c, 0x03, 0xbe, 0xf0, 0x3a, 0x7d, 0x37, + 0xdd, 0xb1, 0xb5, 0x2c, 0x06, 0x3c, 0xb6, 0x66, 0xaf, 0x5d, 0x09, 0xdb, 0xf4, + 0xfb, 0x1f, 0xe7, 0xe7, 0x01, 0x21, 0xe9, 0x34, 0xfd, 0x3d, 0xc6, 0xef, 0xe7, + 0x0a, 0x3d, 0x20, 0x54, 0xdf, 0x0b, 0x07, 0x34, 0x96, 0x01, 0x65, 0x24, 0x63, + 0x28, 0x7f, 0x4e, 0x0b, 0x0e, 0xcb, 0x20, 0x46, 0xc5, 0xa7, 0x55, 0x02, 0xc1, + 0x18, 0x0c, 0xda, 0xe3, 0x3b, 0xbd, 0x3a, 0x22, 0x47, 0x10, 0xe5, 0x21, 0xdf, + 0x3b, 0xdd, 0x0f, 0x0e, 0x05, 0xc6, 0x9b, 0x06, 0x66, 0xf0, 0x3a, 0xd6, 0x20, + 0xba, 0xf3, 0x0a, 0xd1, 0xe6, 0x40, 0xe1, 0xe7, 0xf4, 0x1d, 0x05, 0xf1, 0x2c, + 0xef, 0xd0, 0xe1, 0x18, 0x11, 0x1c, 0x5e, 0x27, 0xfd, 0xff, 0xfb, 0xe9, 0xfb, + 0xf1, 0x1a, 0x40, 0x0d, 0x1d, 0x30, 0x3a, 0xdd, 0xde, 0xd2, 0x13, 0xdf, 0x35, + 0xfe, 0xe8, 0xeb, 0x1c, 0x02, 0x24, 0x10, 0x25, 0x00, 0x0a, 0x0d, 0x04, 0xf7, + 0xfb, 0xfd, 0xee, 0xc9, 0x14, 0xd1, 0x27, 0xd4, 0xdd, 0x21, 0xbd, 0xc6, 0x53, + 0xfd, 0xf2, 0x0d, 0xef, 0x0a, 0xf2, 0xe7, 0x0a, 0x1e, 0x1c, 0xe5, 0xff, 0xf5, + 0xed, 0xd9, 0xf8, 0x1e, 0xe2, 0xfd, 0x04, 0xfd, 0xe3, 0x14, 0xe6, 0x1a, 0x7f, + 0x05, 0x2a, 0xf0, 0xf8, 0xf2, 0x07, 0xfa, 0x11, 0xe4, 0xf8, 0xed, 0xe7, 0xfe, + 0xfc, 0xf9, 0xcf, 0x08, 0xe2, 0xf6, 0xea, 0xec, 0x07, 0x13, 0x0f, 0x25, 0x06, + 0xee, 0xdf, 0xf2, 0x19, 0x1e, 0xd5, 0x18, 0x0b, 0xe5, 0xf5, 0x11, 0xfc, 0x0e, + 0x19, 0xf4, 0xf7, 0xf5, 0xf5, 0x0c, 0x00, 0xf5, 0xfe, 0xfd, 0x04, 0xdf, 0xf0, + 0x0f, 0x43, 0xf2, 0xf9, 0x0a, 0xe1, 0x29, 0xea, 0xdf, 0x63, 0xf5, 0x21, 0xc6, + 0xf2, 0xf5, 0x2c, 0xd1, 0x3b, 0x2e, 0xee, 0x12, 0xc1, 0xe8, 0x0b, 0x05, 0x0a, + 0x1d, 0xbf, 0x57, 0xb8, 0xc4, 0xb4, 0xcc, 0x2c, 0x36, 0xda, 0x2a, 0x9e, 0x46, + 0x05, 0x18, 0xe3, 0x0d, 0x18, 0x03, 0x0f, 0xe6, 0x05, 0xe3, 0xd9, 0xd0, 0x2a, + 0xf6, 0x4c, 0x45, 0xe3, 0x25, 0xec, 0xfa, 0x18, 0xef, 0xfb, 0x9f, 0x10, 0xf5, + 0xfc, 0xd6, 0x08, 0x1e, 0x1b, 0xdf, 0x5a, 0x29, 0xf6, 0xe8, 0xfd, 0x3a, 0xfd, + 0x13, 0x0d, 0xfa, 0xa6, 0xf4, 0x32, 0x5a, 0xd4, 0xfa, 0xf9, 0xbe, 0xa4, 0x17, + 0xae, 0xa6, 0xe7, 0x0c, 0xe7, 0x02, 0x75, 0x05, 0x13, 0xc6, 0x48, 0x42, 0xb6, + 0xf0, 0x10, 0xd3, 0x81, 0xd5, 0xd4, 0xc7, 0x09, 0xea, 0x02, 0x6a, 0xd7, 0xdd, + 0xff, 0x2f, 0x17, 0x00, 0x34, 0xfd, 0xfc, 0x0b, 0xf5, 0x1d, 0xf0, 0x7e, 0xf6, + 0xfc, 0xa9, 0xf6, 0x1e, 0x39, 0x3e, 0x05, 0xd6, 0xfe, 0xf1, 0x62, 0x56, 0xba, + 0x79, 0x58, 0x11, 0x07, 0x05, 0x08, 0x14, 0xd8, 0x24, 0xe0, 0xe6, 0x2c, 0x5f, + 0x18, 0x26, 0x3a, 0x24, 0x0f, 0x4c, 0x5e, 0x5a, 0xb0, 0x31, 0x32, 0x24, 0xb8, + 0x11, 0xba, 0x12, 0x26, 0xc2, 0x3a, 0x11, 0x36, 0xea, 0xfd, 0x21, 0xca, 0xe6, + 0x14, 0x0b, 0xe7, 0x37, 0x4d, 0x05, 0x00, 0xea, 0xbb, 0xd5, 0xfc, 0xdb, 0x27, + 0x24, 0xbc, 0xf5, 0xfd, 0x12, 0xef, 0x0b, 0x59, 0xff, 0xdf, 0x03, 0xf0, 0x14, + 0x9e, 0x08, 0x1e, 0xcf, 0xf4, 0x10, 0xdf, 0xd0, 0xc2, 0x8d, 0x29, 0x2e, 0x1b, + 0xf1, 0xdb, 0xee, 0x46, 0xf3, 0x0f, 0xfc, 0xf4, 0xe7, 0xe6, 0x11, 0x9a, 0x2c, + 0xd1, 0xf3, 0xe3, 0xd3, 0x29, 0x16, 0x05, 0x00, 0xed, 0x75, 0xbb, 0x50, 0x4c, + 0x31, 0x2b, 0x67, 0xd7, 0xd8, 0xd0, 0xe5, 0x0e, 0x00, 0x08, 0xea, 0x7f, 0xb1, + 0xc8, 0x0f, 0xfa, 0xf0, 0x12, 0x2b, 0xfe, 0x7f, 0xe1, 0x29, 0x0a, 0x2f, 0x18, + 0xe1, 0xf3, 0xd3, 0x0f, 0x12, 0x08, 0x1d, 0xf4, 0x10, 0x1c, 0xfd, 0x16, 0xc9, + 0x11, 0xa5, 0x1f, 0xce, 0xbd, 0x11, 0xc4, 0xec, 0xeb, 0x09, 0x09, 0x24, 0xdd, + 0x72, 0xf2, 0xf2, 0x30, 0xea, 0x5a, 0x17, 0x17, 0x18, 0x61, 0xd3, 0x21, 0xe0, + 0xe8, 0xd0, 0x47, 0xf1, 0x2b, 0xb4, 0x2d, 0xf2, 0xf0, 0xcf, 0xcc, 0x34, 0xe2, + 0xf7, 0xf8, 0xdc, 0xc5, 0xe7, 0xd1, 0xed, 0x27, 0x2c, 0xa2, 0x0a, 0x6c, 0x51, + 0x0f, 0x48, 0x1b, 0x15, 0x06, 0xc6, 0xce, 0x0f, 0x1b, 0xdb, 0x1c, 0x49, 0x07, + 0xde, 0x16, 0xfb, 0x21, 0x29, 0xec, 0xf1, 0x2c, 0x4c, 0x18, 0xef, 0xe4, 0x01, + 0xdf, 0xfa, 0x29, 0x1b, 0x43, 0x12, 0xde, 0xd0, 0x06, 0x49, 0x42, 0x2a, 0x21, + 0x14, 0x01, 0x19, 0xf5, 0xf6, 0xe1, 0x1f, 0xc2, 0xfa, 0xcd, 0xe0, 0xf1, 0x3e, + 0xe4, 0x4f, 0x56, 0xcb, 0xc2, 0x0d, 0x79, 0x2d, 0x04, 0x32, 0xf3, 0x0d, 0xe2, + 0xb3, 0xf2, 0xab, 0x29, 0x06, 0xe8, 0x0a, 0xdf, 0xc3, 0x10, 0x1d, 0x26, 0xb1, + 0x17, 0x08, 0x13, 0xfc, 0x03, 0x30, 0x33, 0x2e, 0x0a, 0x24, 0xcf, 0x05, 0x36, + 0x00, 0xea, 0x04, 0xcf, 0x44, 0x21, 0x06, 0x6e, 0xd2, 0xd3, 0xe2, 0xc3, 0x2c, + 0x3c, 0x20, 0x0e, 0x26, 0xb2, 0xbd, 0xf4, 0xfa, 0xe7, 0xc8, 0xbe, 0x15, 0xf1, + 0xc0, 0x3e, 0xe4, 0x0f, 0x6d, 0xdf, 0x1a, 0xe7, 0x0a, 0x3f, 0x22, 0x43, 0x3d, + 0xd1, 0x02, 0x4d, 0xf5, 0xcb, 0x7f, 0x32, 0x43, 0x0e, 0xeb, 0xd6, 0xf1, 0xb5, + 0xf6, 0x2b, 0x02, 0x10, 0x14, 0xef, 0x01, 0xf7, 0x62, 0xec, 0x07, 0x05, 0x62, + 0xad, 0x1c, 0xee, 0xea, 0x2e, 0xed, 0x1e, 0xfa, 0x37, 0xfc, 0x40, 0x0c, 0xfb, + 0x26, 0xf5, 0x0e, 0xa6, 0x07, 0x5a, 0x19, 0x0e, 0xd7, 0x42, 0xd0, 0xe4, 0xe3, + 0x31, 0xc0, 0x21, 0xe4, 0x29, 0xac, 0xdc, 0xf8, 0xee, 0xbe, 0xd7, 0x37, 0xdc, + 0x47, 0xed, 0xfe, 0x20, 0xcc, 0xc6, 0x7f, 0x09, 0xed, 0x08, 0xcb, 0x16, 0xf7, + 0xdf, 0xd8, 0xfa, 0x21, 0x28, 0x3f, 0xc1, 0x95, 0x02, 0xcd, 0xd9, 0xf7, 0xa8, + 0xe6, 0xb9, 0x01, 0xce, 0xe2, 0x06, 0x19, 0x14, 0x31, 0x45, 0x23, 0xe1, 0xd1, + 0x0b, 0xec, 0xed, 0xeb, 0xbe, 0xc6, 0xba, 0xd1, 0xf3, 0xfe, 0x08, 0xf6, 0x3b, + 0x1a, 0xcc, 0xa5, 0xc6, 0x0e, 0x38, 0xd1, 0x00, 0xd5, 0xd6, 0x0e, 0x13, 0xd2, + 0x20, 0x4a, 0xad, 0x1b, 0xb9, 0x4d, 0xe7, 0x0d, 0xf7, 0x13, 0x67, 0xb4, 0xf8, + 0xf3, 0x39, 0x48, 0xf4, 0xf9, 0xe2, 0xe1, 0x22, 0x42, 0x2f, 0x11, 0x37, 0xc8, + 0x01, 0x17, 0xd1, 0xc6, 0x00, 0xc8, 0x29, 0x00, 0x2c, 0xa5, 0xce, 0xd7, 0x66, + 0x2b, 0x00, 0xb7, 0xf8, 0x03, 0x2f, 0x3b, 0x16, 0xf7, 0xf9, 0xf8, 0x49, 0x17, + 0x19, 0xda, 0x08, 0xf3, 0x04, 0xf6, 0x28, 0x15, 0x16, 0x03, 0x0a, 0xf3, 0x04, + 0x30, 0x51, 0x2f, 0xfa, 0xe0, 0xfa, 0x31, 0x10, 0xde, 0xea, 0xe8, 0x1e, 0x27, + 0x6d, 0xde, 0x11, 0x0f, 0x2e, 0xef, 0xd7, 0x2a, 0x0b, 0x5b, 0x18, 0x3f, 0xfb, + 0xd9, 0x49, 0x1d, 0x10, 0xeb, 0x0a, 0x38, 0xfe, 0x34, 0x27, 0x30, 0x20, 0x07, + 0xf5, 0x29, 0x0c, 0x18, 0x23, 0x1d, 0xd7, 0xec, 0x07, 0xff, 0x05, 0xfc, 0x10, + 0xec, 0x56, 0xfd, 0xd8, 0xef, 0xe8, 0x56, 0x29, 0x4c, 0xed, 0x11, 0xcb, 0x04, + 0xdf, 0x1f, 0x32, 0xec, 0xf9, 0xe4, 0xc8, 0x0b, 0xf8, 0x23, 0xed, 0x16, 0xf1, + 0x19, 0x17, 0xe3, 0xeb, 0x0e, 0xf3, 0x18, 0xd3, 0x04, 0x19, 0xed, 0xd3, 0x32, + 0x37, 0x0b, 0xba, 0x7f, 0x3d, 0x3e, 0x3c, 0x2d, 0x70, 0xd6, 0x04, 0x07, 0xfb, + 0xf5, 0xe8, 0x24, 0x4c, 0x60, 0x27, 0xe2, 0xd5, 0xe5, 0xf5, 0xcd, 0x15, 0xc4, + 0xd9, 0xeb, 0x08, 0x0f, 0xe5, 0xc2, 0xf1, 0x36, 0xd3, 0x0e, 0x2b, 0xe0, 0xdb, + 0xed, 0xd2, 0x4b, 0xc7, 0x02, 0xce, 0xfa, 0x55, 0x0f, 0x14, 0xf2, 0xf7, 0x1b, + 0x51, 0xeb, 0x31, 0x9f, 0x3e, 0xcb, 0xed, 0xa2, 0xfb, 0x16, 0xea, 0x33, 0xf3, + 0xd2, 0xf9, 0x4c, 0xdf, 0x28, 0x06, 0x47, 0xa5, 0x1e, 0x17, 0x30, 0xd7, 0x07, + 0x07, 0x02, 0xf0, 0xdf, 0x33, 0xf4, 0x1c, 0x2d, 0xe3, 0xd7, 0x06, 0xed, 0x12, + 0x01, 0xee, 0xc4, 0xba, 0xbf, 0xe2, 0xc6, 0x19, 0x04, 0x0c, 0x47, 0xf3, 0xf5, + 0xe0, 0x7f, 0xd7, 0x2a, 0x0d, 0xee, 0xb7, 0xe5, 0xd3, 0xc2, 0x1b, 0x0b, 0x0e, + 0x05, 0xc7, 0x30, 0x42, 0x02, 0x5b, 0x03, 0xd0, 0xe0, 0xd0, 0xf9, 0xe5, 0xf8, + 0xe1, 0x0f, 0x3e, 0xfa, 0x08, 0x0c, 0xe6, 0x03, 0xdd, 0x11, 0x1e, 0x0b, 0x11, + 0x41, 0x10, 0x15, 0xa3, 0xfb, 0xf3, 0xe1, 0xc3, 0x05, 0x23, 0xef, 0x17, 0x17, + 0x0b, 0x12, 0x19, 0xf3, 0x2f, 0xda, 0xec, 0xed, 0xf5, 0xc7, 0xe8, 0x4d, 0x0b, + 0x6d, 0x07, 0xf8, 0x00, 0x1c, 0x2c, 0xf7, 0x1a, 0xff, 0xdc, 0xf0, 0x42, 0x00, + 0xee, 0xd0, 0xeb, 0xfe, 0x13, 0xee, 0x4a, 0xf1, 0xe0, 0x07, 0x25, 0xda, 0xd8, + 0x12, 0xf0, 0xff, 0xe2, 0xdc, 0x22, 0xb3, 0x7f, 0x18, 0x05, 0xec, 0xe5, 0xe9, + 0xd8, 0xcd, 0x13, 0xd3, 0x0d, 0x01, 0xd7, 0x52, 0xfa, 0xc0, 0xf1, 0xf1, 0xe3, + 0xef, 0x03, 0x19, 0x09, 0xd9, 0xfc, 0x0b, 0xce, 0xdb, 0x21, 0x2e, 0x10, 0xf1, + 0xe8, 0xd8, 0xf3, 0x1a, 0x41, 0xd2, 0x0c, 0xeb, 0x21, 0x39, 0x14, 0x00, 0xfa, + 0xf2, 0x3a, 0x0d, 0xf9, 0x02, 0xb3, 0x04, 0x47, 0xfc, 0xd5, 0x2b, 0xe0, 0x1a, + 0xd2, 0x25, 0xf9, 0xcc, 0x1f, 0x07, 0xe5, 0x28, 0xe4, 0xfb, 0x06, 0x0e, 0x03, + 0x08, 0xfb, 0xf8, 0xed, 0x01, 0xc5, 0xea, 0x1f, 0x03, 0x19, 0x00, 0x11, 0x62, + 0x23, 0x4e, 0xff, 0x06, 0xc2, 0x36, 0x0f, 0xef, 0xee, 0x24, 0x49, 0xf4, 0xef, + 0xd3, 0x05, 0xd2, 0x10, 0x06, 0xdb, 0x3e, 0x1b, 0x03, 0x01, 0xfe, 0x13, 0x0c, + 0x01, 0x7a, 0x23, 0xf5, 0x60, 0x34, 0xc2, 0xfa, 0xfa, 0x0c, 0x44, 0x02, 0x2d, + 0xe0, 0x14, 0xe8, 0x2d, 0xd8, 0xee, 0xde, 0x1e, 0x06, 0xf4, 0xf5, 0xef, 0xf5, + 0xee, 0xfc, 0xf4, 0xde, 0xb7, 0xed, 0x2d, 0x11, 0x0f, 0x31, 0x02, 0xb8, 0xb7, + 0x7f, 0xe6, 0x2b, 0xec, 0x44, 0x0f, 0x01, 0xe8, 0x12, 0xf8, 0x0a, 0xcb, 0x3a, + 0x04, 0x03, 0x13, 0xeb, 0xf2, 0x1f, 0x35, 0xf6, 0xfa, 0x0f, 0x37, 0x26, 0xd2, + 0xf3, 0x24, 0xeb, 0x03, 0xfa, 0x14, 0xeb, 0x22, 0x38, 0xe7, 0xed, 0xd3, 0xe0, + 0xfa, 0x07, 0x22, 0x11, 0xdb, 0x0c, 0xf4, 0x22, 0xec, 0x32, 0x06, 0xfd, 0xe4, + 0x42, 0x01, 0xfa, 0x25, 0x1a, 0x0c, 0x04, 0x19, 0x33, 0xdf, 0x01, 0xe3, 0xd4, + 0xe1, 0x1b, 0x2c, 0x18, 0xdf, 0xbc, 0xcc, 0x06, 0xdf, 0x7c, 0x12, 0x18, 0xd6, + 0xc7, 0xee, 0xd0, 0x0e, 0xea, 0x06, 0xb1, 0xda, 0x1a, 0xf9, 0x94, 0xe6, 0xfe, + 0x05, 0xd0, 0xe3, 0xcc, 0xbb, 0xf2, 0xca, 0xe6, 0x27, 0xf8, 0xd7, 0x04, 0xe2, + 0xbc, 0x7f, 0xe3, 0xfe, 0x5a, 0xea, 0xc6, 0xc3, 0xe4, 0xc3, 0xf0, 0x16, 0xe5, + 0xf2, 0x19, 0xeb, 0x0c, 0x06, 0xaf, 0xf3, 0x06, 0x16, 0xe5, 0xf9, 0xd2, 0x08, + 0x10, 0x0b, 0x18, 0x03, 0xec, 0xd7, 0x27, 0xe0, 0xc6, 0xea, 0x40, 0x08, 0x3e, + 0x46, 0xa8, 0xff, 0x4b, 0x65, 0x70, 0xfc, 0x3d, 0x03, 0x04, 0x67, 0x08, 0x19, + 0xdc, 0xe1, 0xeb, 0x11, 0x12, 0xf2, 0x32, 0xf1, 0xfb, 0xdb, 0x0c, 0xd2, 0x16, + 0x85, 0xcf, 0xef, 0x2b, 0x09, 0xdf, 0x75, 0xce, 0x14, 0x73, 0xeb, 0xe8, 0x47, + 0xee, 0x2b, 0x11, 0xab, 0x3b, 0xef, 0x37, 0xed, 0x10, 0x06, 0xb2, 0xdd, 0xa3, + 0xb6, 0x3f, 0xfc, 0x34, 0x5e, 0x3d, 0xe9, 0x43, 0xf9, 0x03, 0x21, 0xee, 0xd0, + 0xfb, 0xf5, 0x23, 0x06, 0x45, 0xfc, 0xff, 0xc9, 0x25, 0xa2, 0x6d, 0xfb, 0xdc, + 0x11, 0x25, 0x07, 0x18, 0x58, 0x2e, 0x1d, 0xfa, 0x00, 0xe2, 0x28, 0xf8, 0xdb, + 0xc4, 0x12, 0xeb, 0xbf, 0xed, 0xc8, 0xf3, 0xdf, 0xa9, 0xc0, 0xf1, 0x10, 0xce, + 0x01, 0xc5, 0x0c, 0xd2, 0x0f, 0xf9, 0xb8, 0x1f, 0x3d, 0x52, 0x1c, 0x4a, 0xee, + 0x12, 0xe4, 0xef, 0xd7, 0xe0, 0x23, 0xd7, 0x47, 0x05, 0xf6, 0xc3, 0xfd, 0xfc, + 0xf7, 0x7f, 0xfa, 0x1d, 0xe6, 0x04, 0xdd, 0x02, 0xe2, 0x81, 0xca, 0x0f, 0xd0, + 0x2a, 0xca, 0xe7, 0x21, 0xf9, 0x1a, 0x57, 0x1d, 0x1b, 0xf8, 0x2f, 0x2d, 0xba, + 0xc8, 0xc7, 0xf1, 0x22, 0x20, 0x10, 0x30, 0x3e, 0xfd, 0x33, 0x16, 0x13, 0xcf, + 0xe6, 0x21, 0x1b, 0xe3, 0xf0, 0x07, 0x5c, 0xfe, 0x3a, 0x3d, 0x20, 0xbc, 0x44, + 0xf8, 0x09, 0xe8, 0xf8, 0xf5, 0x3b, 0x12, 0xea, 0x1c, 0xf2, 0x13, 0x5a, 0xf0, + 0xfb, 0x18, 0x13, 0xc8, 0x21, 0x31, 0xe7, 0x4b, 0x25, 0xb7, 0x5b, 0x52, 0x18, + 0x2a, 0xd9, 0x17, 0x17, 0x29, 0x33, 0x19, 0x0f, 0x0c, 0xd3, 0x27, 0xf3, 0x27, + 0xf7, 0xe7, 0xdb, 0x18, 0x05, 0x04, 0x17, 0x36, 0x28, 0xf0, 0xe8, 0xcc, 0xef, + 0x22, 0x44, 0xe4, 0x4c, 0x15, 0xfe, 0x02, 0x4b, 0xd9, 0x33, 0x1f, 0xe8, 0xd2, + 0x26, 0x29, 0x22, 0xfe, 0x7f, 0x0e, 0x32, 0xfc, 0x15, 0xf5, 0x1c, 0x10, 0x4b, + 0x04, 0x10, 0x3a, 0xed, 0x24, 0x31, 0xf6, 0x1a, 0x15, 0x48, 0x59, 0x0f, 0x01, + 0x08, 0xed, 0x33, 0x0a, 0x1f, 0x15, 0xfd, 0xe4, 0xde, 0xed, 0xfe, 0x12, 0x14, + 0x0b, 0x18, 0x09, 0x47, 0x11, 0x0a, 0xd9, 0x01, 0xb6, 0xf9, 0x10, 0x23, 0x00, + 0x70, 0x01, 0xfc, 0xe6, 0xec, 0xf7, 0xad, 0x19, 0x47, 0x3d, 0x27, 0x06, 0xe6, + 0xf7, 0x02, 0x1a, 0x16, 0xd4, 0x36, 0x03, 0xcf, 0xe7, 0x4a, 0x0f, 0xd5, 0x0d, + 0x02, 0x25, 0x96, 0x3f, 0x0b, 0xe6, 0xcd, 0x2f, 0x40, 0xce, 0x02, 0xdf, 0xe6, + 0xc0, 0x0e, 0x1e, 0x3e, 0x10, 0x39, 0xed, 0xef, 0x32, 0xed, 0xb3, 0xe2, 0xfa, + 0xd0, 0xf9, 0x0b, 0xf8, 0xfc, 0x07, 0x65, 0x18, 0x0a, 0x49, 0x38, 0x00, 0xe8, + 0x34, 0xe4, 0x06, 0x0d, 0xab, 0xa7, 0xd2, 0x14, 0xfd, 0xdd, 0x06, 0x10, 0x2b, + 0xd2, 0x52, 0x7f, 0xfc, 0xeb, 0xdf, 0x29, 0xc1, 0xf0, 0xdb, 0x05, 0xe2, 0xdc, + 0x24, 0x0e, 0xe3, 0x16, 0x3d, 0xf3, 0xee, 0x0e, 0xf8, 0xea, 0xd1, 0xea, 0x26, + 0x74, 0x1a, 0x3d, 0x1c, 0xd4, 0xb0, 0xf4, 0x09, 0xf5, 0xe7, 0x03, 0xf6, 0xcb, + 0xe5, 0xe6, 0xbf, 0x1d, 0xd1, 0xfd, 0x08, 0xd9, 0x3b, 0xfb, 0xff, 0x1a, 0x00, + 0x0a, 0x00, 0x7a, 0x3b, 0xf1, 0x3a, 0x01, 0xa7, 0xf7, 0x08, 0x22, 0xff, 0xf9, + 0x00, 0xe5, 0x13, 0xf0, 0x35, 0x07, 0x18, 0x50, 0x81, 0x0d, 0x45, 0x08, 0xb0, + 0x2b, 0xdc, 0xc0, 0x34, 0x03, 0x04, 0x6e, 0x38, 0x9d, 0xf5, 0x1a, 0x3c, 0xf0, + 0x26, 0x36, 0x15, 0xf2, 0x0d, 0xd6, 0xf9, 0x39, 0x2d, 0x04, 0xe9, 0xea, 0x14, + 0x15, 0xd2, 0x3b, 0x14, 0x69, 0xee, 0x1b, 0xe4, 0x23, 0x4f, 0x1f, 0xd6, 0x36, + 0xf1, 0xee, 0xc7, 0x2c, 0xda, 0xc1, 0x03, 0xd5, 0xb3, 0x15, 0x19, 0x59, 0xed, + 0x51, 0x05, 0x0b, 0xf7, 0xf9, 0x05, 0x08, 0xe4, 0x14, 0x31, 0x06, 0x22, 0x10, + 0x14, 0x44, 0xc1, 0xdc, 0x1a, 0xc0, 0x0a, 0x0a, 0x06, 0x19, 0xfb, 0x08, 0x08, + 0x05, 0x34, 0xfb, 0xe8, 0xfb, 0x06, 0x20, 0xee, 0x3a, 0x0f, 0x10, 0xed, 0x2b, + 0x14, 0x00, 0xd7, 0xfb, 0xfb, 0xd8, 0x04, 0xe2, 0xfc, 0xfb, 0xff, 0xeb, 0xf3, + 0x13, 0x1b, 0xfa, 0x09, 0x18, 0xb3, 0xf5, 0xf0, 0x14, 0x04, 0xff, 0xea, 0xef, + 0x03, 0xf2, 0x1c, 0xfa, 0xfb, 0x23, 0xce, 0xf6, 0xfd, 0x18, 0xe5, 0x25, 0xf5, + 0xee, 0x11, 0x05, 0xf8, 0x20, 0x04, 0x07, 0xef, 0x02, 0x22, 0xed, 0x04, 0x13, + 0xfb, 0x0a, 0xee, 0x07, 0xf4, 0x09, 0x18, 0xf6, 0xe9, 0x03, 0x05, 0xfc, 0xe5, + 0xd3, 0x04, 0x26, 0x02, 0x13, 0x25, 0x1e, 0xf8, 0x0d, 0xf9, 0x29, 0xea, 0xeb, + 0xf2, 0x33, 0xd2, 0xeb, 0x0e, 0x15, 0xee, 0x08, 0x0f, 0x3d, 0x1b, 0x7f, 0x03, + 0x05, 0xee, 0x23, 0xfa, 0xfb, 0x17, 0x06, 0x1f, 0x23, 0x06, 0x0e, 0xf5, 0x1a, + 0xfd, 0xfe, 0x08, 0x0c, 0xfc, 0x17, 0x19, 0x0f, 0xed, 0x06, 0x07, 0xde, 0x27, + 0xec, 0x00, 0xe8, 0x2d, 0x12, 0x13, 0xfd, 0x12, 0x09, 0xf2, 0x04, 0xd4, 0x0c, + 0xf9, 0x19, 0xca, 0xe8, 0x1f, 0xe7, 0x21, 0xe7, 0x09, 0x05, 0xf5, 0x1d, 0x00, + 0xfd, 0xec, 0x01, 0xe6, 0xf3, 0xf6, 0x26, 0xb6, 0xe9, 0xec, 0xf9, 0xee, 0xf1, + 0xe6, 0x01, 0xda, 0xda, 0xfd, 0xf6, 0xdb, 0x09, 0xf2, 0x0a, 0x1d, 0xef, 0xf6, + 0xdc, 0x27, 0x00, 0x09, 0xb8, 0xb7, 0xf5, 0xba, 0xdf, 0x18, 0xfd, 0xba, 0x0f, + 0x42, 0xdb, 0xff, 0xf9, 0xfc, 0x3a, 0x57, 0x06, 0x00, 0xfb, 0x1d, 0x81, 0x13, + 0x50, 0x32, 0x2c, 0x43, 0x09, 0x02, 0x17, 0x19, 0x0c, 0x1d, 0x28, 0xe9, 0xb2, + 0x32, 0xfb, 0xf4, 0x19, 0xfe, 0xd5, 0xe9, 0x20, 0xbd, 0x07, 0xd0, 0xbc, 0xa9, + 0x06, 0x03, 0xc2, 0xe2, 0xca, 0x27, 0xdb, 0xe5, 0x23, 0x3d, 0x13, 0xf6, 0xec, + 0xc6, 0x06, 0x0e, 0x21, 0x24, 0xef, 0xed, 0xad, 0x35, 0xc7, 0x1c, 0x15, 0x12, + 0x9e, 0xb8, 0xf0, 0xfb, 0x07, 0xe7, 0x07, 0x21, 0xfd, 0x10, 0x23, 0x15, 0x10, + 0x02, 0x28, 0xf2, 0xb0, 0x0d, 0xe1, 0xa9, 0xe7, 0xf9, 0x60, 0x28, 0x77, 0xb4, + 0xfe, 0xf5, 0x16, 0xf9, 0xed, 0xba, 0xd2, 0x46, 0x00, 0xfc, 0xef, 0x71, 0xca, + 0xe9, 0x0d, 0xf3, 0x1f, 0xed, 0x1a, 0x8c, 0xcc, 0x13, 0x2c, 0xb4, 0x4b, 0x0d, + 0xca, 0x3c, 0x38, 0xf2, 0xe3, 0x3b, 0x05, 0xf4, 0x1b, 0xd6, 0xef, 0xd5, 0x22, + 0x40, 0x0b, 0xf2, 0xeb, 0x24, 0xde, 0xc9, 0x0a, 0x22, 0xe8, 0xf6, 0x1a, 0x48, + 0x07, 0xfd, 0xe0, 0x33, 0x44, 0xd9, 0x3e, 0x10, 0xf8, 0x81, 0x0f, 0xc8, 0x09, + 0xe2, 0x1b, 0x97, 0xe5, 0xe1, 0x6a, 0xea, 0xce, 0x21, 0xed, 0xef, 0xd7, 0x08, + 0xf5, 0x46, 0xf5, 0x26, 0x17, 0xd2, 0xf2, 0x11, 0xfd, 0xec, 0x23, 0xfb, 0x3b, + 0xa3, 0x51, 0x03, 0x0a, 0x02, 0x05, 0x02, 0xe2, 0xd9, 0x31, 0x77, 0x20, 0x47, + 0xe5, 0xfa, 0x00, 0xfa, 0x21, 0xd8, 0x67, 0x27, 0x2f, 0x06, 0x5c, 0x02, 0x03, + 0x9d, 0x3f, 0x19, 0xd8, 0xde, 0x04, 0x37, 0xcb, 0x14, 0x15, 0x33, 0x08, 0x20, + 0x29, 0x4e, 0xc9, 0xe5, 0xf3, 0x5c, 0xba, 0x1e, 0xf9, 0xd9, 0x00, 0xed, 0x29, + 0x27, 0xb2, 0xe2, 0xc1, 0x43, 0x14, 0xf2, 0xcf, 0x00, 0xf6, 0x37, 0x47, 0x28, + 0x06, 0x17, 0x03, 0x0b, 0x22, 0x48, 0x11, 0xb2, 0x44, 0x1f, 0x3e, 0xe4, 0x9f, + 0x69, 0xf5, 0xfb, 0xe7, 0x3a, 0xce, 0x0b, 0xdc, 0xd5, 0x2c, 0xda, 0xbd, 0x50, + 0x1b, 0xb1, 0x50, 0x01, 0xc6, 0x03, 0x01, 0x14, 0x55, 0x27, 0x37, 0xc7, 0x0b, + 0x2c, 0xb1, 0xdb, 0x0e, 0xb9, 0x1c, 0x25, 0x8e, 0x00, 0xf2, 0x10, 0xdc, 0x1b, + 0x40, 0x03, 0x04, 0xd6, 0xff, 0xec, 0x26, 0x09, 0xbd, 0xca, 0xf2, 0xee, 0xeb, + 0x1c, 0xe8, 0xab, 0x81, 0x07, 0x20, 0x15, 0x39, 0xb8, 0x0a, 0xe5, 0xdb, 0xf3, + 0x03, 0xe6, 0x06, 0x07, 0xfc, 0xdf, 0x30, 0x1a, 0x32, 0x0b, 0xd2, 0x22, 0xe0, + 0x9d, 0xae, 0x21, 0x33, 0xc7, 0x7d, 0x38, 0x13, 0xc2, 0xdc, 0x27, 0x09, 0xb5, + 0xfe, 0xfe, 0x1a, 0x29, 0x0c, 0xe0, 0xf7, 0x79, 0xf9, 0x04, 0x30, 0xec, 0x5a, + 0xb5, 0x3a, 0x28, 0xf0, 0xe1, 0x2d, 0xba, 0x1a, 0x3d, 0xdd, 0x50, 0x5d, 0xb9, + 0xd7, 0x57, 0x1e, 0x07, 0xbc, 0x4b, 0xdc, 0xe3, 0xb1, 0xf0, 0xd9, 0xf4, 0x1b, + 0x69, 0xe9, 0xdf, 0xf4, 0xe0, 0xe1, 0xd2, 0xcf, 0xec, 0x01, 0xfa, 0xde, 0x5a, + 0xdd, 0xdf, 0x54, 0xcb, 0xf6, 0x81, 0x46, 0xef, 0x39, 0x0e, 0x1a, 0xe3, 0x0c, + 0x2e, 0x09, 0xe3, 0xd7, 0x04, 0xa0, 0xe7, 0xe1, 0x32, 0xfa, 0x02, 0x00, 0x0d, + 0xef, 0xaa, 0x20, 0xf3, 0xfd, 0xe5, 0xf2, 0xe6, 0x48, 0xc0, 0xfc, 0xf4, 0x34, + 0xfd, 0xd0, 0x28, 0x12, 0xf5, 0x32, 0x13, 0x35, 0xf0, 0xd3, 0xd5, 0x0a, 0xdb, + 0x19, 0x36, 0x4a, 0x50, 0x58, 0xcf, 0x37, 0x1f, 0x3e, 0xda, 0x32, 0xef, 0xcb, + 0x4d, 0xce, 0xfc, 0x2f, 0x19, 0xf1, 0xfe, 0xdb, 0x1d, 0x28, 0x1f, 0xfb, 0x4d, + 0xdd, 0xde, 0xc2, 0x3a, 0x0b, 0xf5, 0xb3, 0xe0, 0x68, 0x33, 0x09, 0xd7, 0x11, + 0xeb, 0x3e, 0xb6, 0x39, 0x2c, 0x1d, 0xfe, 0xd5, 0x30, 0xde, 0xe1, 0xc3, 0x0e, + 0xec, 0x1c, 0x64, 0x32, 0xf4, 0x41, 0x2f, 0xee, 0xcb, 0xfe, 0x31, 0x2e, 0xd1, + 0x9e, 0x89, 0xb2, 0x2d, 0x13, 0x17, 0x24, 0xf9, 0xdf, 0xec, 0x0b, 0x3a, 0x6f, + 0x2c, 0xd1, 0x0f, 0xf7, 0x00, 0xea, 0xc7, 0xf3, 0xe6, 0x6c, 0x2d, 0xb9, 0xc6, + 0x26, 0x7f, 0x25, 0x91, 0x07, 0xce, 0xf1, 0xa8, 0xed, 0x7c, 0x09, 0xc6, 0x01, + 0x4b, 0x0c, 0xdc, 0xd4, 0x69, 0x15, 0x0b, 0xdf, 0xf9, 0x2b, 0x0d, 0x62, 0x0a, + 0xc7, 0xf6, 0x28, 0x14, 0xaa, 0xef, 0xb6, 0xef, 0x26, 0xc0, 0xa4, 0x2b, 0xf3, + 0x15, 0xf2, 0x37, 0x1e, 0xdb, 0xc3, 0x34, 0xb6, 0x34, 0x38, 0xf6, 0xe5, 0xf6, + 0x26, 0xd2, 0xe4, 0x1b, 0x4b, 0x3a, 0xb5, 0x15, 0x2b, 0xeb, 0xb6, 0xba, 0x31, + 0xc4, 0x36, 0xfa, 0xdd, 0xec, 0x60, 0xdd, 0x7f, 0xb5, 0x2e, 0xe8, 0x6c, 0xfc, + 0x23, 0x0d, 0x07, 0xd2, 0x14, 0x62, 0xd2, 0x12, 0x36, 0x03, 0x10, 0xb7, 0xd4, + 0xe7, 0xa9, 0x3b, 0x25, 0xb2, 0xce, 0xd1, 0x9b, 0xc0, 0xe5, 0xdb, 0x1d, 0x24, + 0xb3, 0x5b, 0xec, 0x2b, 0x1e, 0x59, 0x35, 0x54, 0xef, 0xef, 0x20, 0x06, 0x70, + 0x20, 0xc7, 0xc5, 0xb7, 0xee, 0x3b, 0xe5, 0x1d, 0x46, 0xe6, 0xde, 0xfb, 0xf5, + 0xb5, 0x19, 0x34, 0x07, 0xe5, 0xfa, 0x18, 0xfa, 0x13, 0xa9, 0x33, 0xb6, 0xfa, + 0x08, 0xdd, 0x0d, 0x22, 0x8e, 0x57, 0xcd, 0x07, 0xd9, 0xec, 0x48, 0xe0, 0xd5, + 0x04, 0xf8, 0xc6, 0xd2, 0xd7, 0xf8, 0x08, 0xf1, 0x48, 0xac, 0x3e, 0x1f, 0x1d, + 0xe7, 0xc9, 0xc5, 0xd9, 0x38, 0x4a, 0xc6, 0x2d, 0x35, 0x3e, 0x1a, 0x1b, 0xf6, + 0x2d, 0xd1, 0x08, 0xe3, 0xa9, 0xc3, 0x2a, 0x6a, 0x17, 0xfd, 0xd9, 0xdb, 0x23, + 0xda, 0xde, 0x1d, 0x1d, 0x06, 0xf5, 0xaa, 0x85, 0xf3, 0x07, 0x30, 0xfb, 0x04, + 0xde, 0xe3, 0x51, 0xea, 0x0d, 0xfc, 0x17, 0x1e, 0x18, 0xd0, 0xdc, 0x28, 0x00, + 0x16, 0x1d, 0x51, 0x81, 0xd4, 0xc6, 0x22, 0xe0, 0x01, 0x02, 0x15, 0x0f, 0x4a, + 0x1e, 0x1e, 0xc4, 0x10, 0x03, 0xf8, 0x19, 0x0d, 0xbd, 0x16, 0x02, 0x1b, 0xf1, + 0x4a, 0xe5, 0x97, 0x39, 0x15, 0xcf, 0x25, 0xb8, 0xfa, 0xf0, 0x2c, 0x19, 0x17, + 0xd4, 0x03, 0x1c, 0x33, 0xde, 0xf3, 0xdc, 0xe9, 0x0c, 0xe3, 0xeb, 0xd2, 0x22, + 0x98, 0x2b, 0xf4, 0xea, 0xd7, 0x11, 0x15, 0xee, 0xd8, 0xf9, 0x0f, 0xfd, 0xd9, + 0xfc, 0xed, 0xed, 0x3d, 0xe2, 0xdf, 0xef, 0x2e, 0x24, 0xf8, 0x1d, 0xd6, 0x37, + 0x52, 0xd0, 0xa6, 0xea, 0x25, 0x07, 0x7f, 0x47, 0x1c, 0xff, 0x1f, 0x05, 0xfa, + 0x4b, 0x1e, 0x44, 0xee, 0x0e, 0x0e, 0xf5, 0xec, 0x1d, 0x10, 0x28, 0xe0, 0x28, + 0xe5, 0xe5, 0x38, 0x02, 0x1b, 0xb0, 0x10, 0xd8, 0x15, 0x2b, 0x00, 0xfb, 0xe2, + 0x26, 0x3d, 0x35, 0xeb, 0x13, 0x3a, 0x13, 0x02, 0x25, 0x39, 0x33, 0xe7, 0x06, + 0x1f, 0xdf, 0x06, 0x2e, 0xf8, 0x25, 0xe5, 0x33, 0xd5, 0xea, 0x17, 0x44, 0xb5, + 0xe3, 0xe6, 0xec, 0x67, 0xeb, 0xcd, 0xcf, 0x05, 0x45, 0x15, 0xec, 0xf8, 0x20, + 0xf9, 0x0f, 0x55, 0xe1, 0xc3, 0x2b, 0xef, 0xc0, 0x0f, 0xf4, 0x84, 0x0b, 0x04, + 0x09, 0xeb, 0xcc, 0xff, 0x40, 0xea, 0x03, 0x5f, 0xeb, 0xee, 0x44, 0xfa, 0xc3, + 0xef, 0x42, 0x09, 0xb4, 0xde, 0xde, 0x30, 0x46, 0x13, 0x45, 0xf7, 0x0a, 0x26, + 0xfc, 0xba, 0x26, 0xfb, 0x3e, 0x11, 0x1e, 0xfd, 0xc5, 0x54, 0xc1, 0xec, 0x37, + 0x08, 0x51, 0xf5, 0x5c, 0xcb, 0x1b, 0xb6, 0x6f, 0x02, 0x1b, 0xdf, 0x2e, 0xf5, + 0x1d, 0x18, 0xe7, 0x23, 0x0c, 0xd0, 0xb8, 0x04, 0xf5, 0x0d, 0x0a, 0x03, 0x3d, + 0x18, 0xc2, 0x3e, 0x2a, 0x10, 0xf1, 0x1c, 0x43, 0xdb, 0x2f, 0x18, 0x07, 0xfd, + 0x1a, 0xf6, 0x01, 0xf1, 0x03, 0xda, 0x1c, 0x69, 0x36, 0x01, 0x05, 0x2a, 0xf3, + 0x34, 0x0f, 0x1f, 0x07, 0x47, 0x40, 0xc3, 0x55, 0x08, 0x14, 0x44, 0x27, 0xeb, + 0x09, 0x05, 0x22, 0x0d, 0x5a, 0x66, 0x2d, 0x04, 0xa5, 0x23, 0x13, 0xf0, 0xe6, + 0xc0, 0x02, 0x7f, 0x1c, 0x54, 0x5a, 0x51, 0xd8, 0xdb, 0xf3, 0x01, 0x26, 0xe9, + 0xe6, 0xc6, 0x18, 0x20, 0x2a, 0x13, 0xfe, 0x48, 0x22, 0xf4, 0x4b, 0x07, 0x27, + 0xec, 0xd7, 0x0f, 0x4c, 0xd9, 0xff, 0xe1, 0x58, 0xcc, 0xbd, 0x04, 0x57, 0x1d, + 0x58, 0x17, 0xf2, 0xea, 0xc8, 0x41, 0x1b, 0x69, 0x41, 0x3a, 0x2c, 0x35, 0x3a, + 0xef, 0xe2, 0xeb, 0x07, 0xc2, 0x46, 0xf3, 0x06, 0x27, 0x0d, 0xfe, 0xc9, 0x0b, + 0x03, 0xff, 0x02, 0x03, 0xf1, 0xc7, 0x10, 0xe9, 0xc7, 0xe1, 0x03, 0x55, 0x7f, + 0xe1, 0xc3, 0x1b, 0x15, 0x05, 0xa2, 0x06, 0xe1, 0xf1, 0xf4, 0xcf, 0x40, 0x07, + 0x10, 0x44, 0x13, 0xf1, 0x51, 0xfd, 0x12, 0xfd, 0x24, 0xe2, 0xdb, 0x06, 0x34, + 0xd2, 0x2c, 0xd0, 0x1b, 0xc6, 0x1a, 0x0f, 0xce, 0x07, 0xf8, 0xe3, 0x28, 0xd8, + 0x11, 0x59, 0xf1, 0x02, 0x19, 0x2a, 0xec, 0xd5, 0xff, 0x59, 0xd3, 0x01, 0x19, + 0xf9, 0xfa, 0x15, 0xdc, 0x2a, 0x27, 0xc9, 0x00, 0xdc, 0x1c, 0x06, 0xfc, 0xec, + 0x37, 0x0b, 0xcd, 0xe8, 0xf3, 0xf1, 0x24, 0xcc, 0x32, 0x04, 0x05, 0x01, 0x0e, + 0x24, 0x03, 0xf1, 0x4a, 0xe9, 0x0e, 0x2c, 0x47, 0xee, 0x94, 0x25, 0x03, 0xfc, + 0xde, 0xfb, 0xbc, 0x20, 0xd2, 0xfb, 0x27, 0xdb, 0xf7, 0xfe, 0x0b, 0x11, 0x04, + 0x2b, 0xf4, 0x35, 0xef, 0x39, 0x0a, 0x0d, 0xcf, 0x0c, 0x06, 0x34, 0xe1, 0x1a, + 0x01, 0x0d, 0x7f, 0x1d, 0x08, 0x0a, 0x46, 0xf8, 0xdd, 0x1c, 0x2c, 0xda, 0x37, + 0x08, 0x40, 0xdd, 0x06, 0x21, 0xc6, 0xeb, 0x09, 0x07, 0x26, 0x4f, 0x34, 0x28, + 0x2e, 0x17, 0xe2, 0x3b, 0xed, 0xd6, 0xbc, 0xf1, 0x44, 0x1b, 0xe8, 0xe7, 0x0e, + 0xeb, 0xe1, 0x24, 0x12, 0x11, 0xed, 0x32, 0xcc, 0xec, 0x12, 0x19, 0xfc, 0x18, + 0x01, 0x2d, 0xe5, 0x12, 0xb0, 0x0d, 0xf5, 0xe3, 0xf7, 0x35, 0xe6, 0xf1, 0xf3, + 0x26, 0x02, 0xf0, 0x02, 0x33, 0x55, 0xe6, 0x28, 0x3a, 0x0b, 0xf8, 0x0f, 0xf9, + 0x1d, 0xce, 0xfd, 0xe1, 0xda, 0xfb, 0x16, 0x04, 0x3a, 0xc8, 0x1b, 0x26, 0x0d, + 0x3e, 0xd8, 0x1c, 0x34, 0x0c, 0xf3, 0x0d, 0x5d, 0xf0, 0xfa, 0x05, 0x13, 0xec, + 0x0f, 0x05, 0x1c, 0xed, 0xeb, 0x0c, 0xef, 0xfd, 0x10, 0x22, 0xfb, 0xee, 0x1e, + 0x3c, 0xfa, 0x32, 0x32, 0x04, 0xea, 0x18, 0xf3, 0x08, 0x07, 0x08, 0x2c, 0x44, + 0x40, 0x10, 0x20, 0x13, 0x7f, 0x1a, 0xf6, 0x11, 0x45, 0x16, 0xda, 0x0f, 0x12, + 0xf4, 0x09, 0x0c, 0xf6, 0x12, 0xfb, 0xed, 0x18, 0x1d, 0x01, 0xe5, 0x1d, 0xe9, + 0xf9, 0xeb, 0xfe, 0x00, 0x00, 0x06, 0x14, 0x11, 0xf1, 0x05, 0x14, 0x05, 0xfb, + 0x03, 0xf4, 0x0e, 0xf5, 0xf9, 0xf7, 0xf8, 0xfc, 0xf0, 0x05, 0x0a, 0xe5, 0x1f, + 0x03, 0xf3, 0xf9, 0x1b, 0xe1, 0x07, 0x28, 0x07, 0xca, 0x09, 0xed, 0x09, 0xf8, + 0xf8, 0xf7, 0xfa, 0x09, 0x1e, 0x09, 0x21, 0xf7, 0xfb, 0x21, 0xf1, 0x0c, 0xf8, + 0xf7, 0x04, 0x0f, 0x00, 0xe4, 0xee, 0xfd, 0xf0, 0xee, 0xf2, 0x04, 0x2b, 0x30, + 0xf3, 0x01, 0x0a, 0xe9, 0xfe, 0x1d, 0x00, 0xf5, 0x05, 0x10, 0xda, 0x12, 0x3a, + 0x13, 0x00, 0xf8, 0x07, 0xfe, 0x03, 0xd6, 0xf6, 0x0a, 0xfa, 0x51, 0xfc, 0x1c, + 0xcb, 0xfa, 0xec, 0xe0, 0x1c, 0x1e, 0xe0, 0x00, 0xfb, 0x37, 0x5c, 0x0b, 0xc5, + 0xf7, 0xe5, 0x20, 0xe5, 0x1a, 0x56, 0x2e, 0xf7, 0xd0, 0x71, 0x7f, 0xc4, 0x38, + 0x1a, 0xd0, 0xc6, 0x5f, 0x2c, 0xc5, 0x26, 0x1b, 0x24, 0xfd, 0xe3, 0x00, 0x40, + 0xe3, 0x20, 0x10, 0x25, 0xec, 0xfc, 0x07, 0xaf, 0xfd, 0x20, 0x9e, 0x0a, 0x4a, + 0xa2, 0xc4, 0x68, 0xdf, 0x28, 0xf3, 0x15, 0x0a, 0xc3, 0x44, 0xc3, 0xe0, 0xce, + 0xb9, 0x2c, 0x2a, 0xeb, 0x1b, 0x75, 0x56, 0x1d, 0xf6, 0xbd, 0x36, 0xa9, 0x08, + 0x67, 0x1a, 0xff, 0x1e, 0xdd, 0x05, 0xb3, 0xfd, 0xc2, 0x0c, 0xe3, 0xe5, 0xe3, + 0xda, 0xdc, 0xd6, 0x13, 0x62, 0x00, 0x31, 0xc6, 0x0c, 0x8e, 0xfa, 0x5c, 0xec, + 0xd8, 0x40, 0xbd, 0xdc, 0xbf, 0x0e, 0xc8, 0x3f, 0xc7, 0x15, 0x10, 0x55, 0xe2, + 0xf7, 0xc3, 0x39, 0x42, 0x1f, 0x08, 0x0f, 0x40, 0xf4, 0xd3, 0x07, 0x15, 0xd4, + 0x5c, 0xfe, 0xe9, 0xda, 0x59, 0x1f, 0xdd, 0x35, 0x5a, 0x9f, 0x04, 0x32, 0xe0, + 0x13, 0xcb, 0xe6, 0xe6, 0xb5, 0x1b, 0x12, 0xcb, 0xdc, 0xc7, 0x1d, 0x0f, 0xf6, + 0x48, 0xe8, 0x16, 0xdb, 0xfe, 0x1a, 0xe7, 0x0f, 0x27, 0xf5, 0x3c, 0xe6, 0xd8, + 0x0f, 0x06, 0x49, 0x09, 0xe8, 0x21, 0xf8, 0x17, 0x06, 0x22, 0x14, 0x50, 0x06, + 0x67, 0xe1, 0xc5, 0xa6, 0xca, 0x04, 0xf4, 0x22, 0xf5, 0xd9, 0xff, 0xf3, 0x67, + 0xef, 0x48, 0xf5, 0x57, 0xcd, 0xb1, 0xf7, 0x09, 0xfb, 0x30, 0x24, 0x10, 0x0a, + 0x3d, 0x0f, 0x15, 0x24, 0x35, 0x0e, 0x10, 0xeb, 0x48, 0xf8, 0x1b, 0xcd, 0x14, + 0xd2, 0x2d, 0x01, 0xe9, 0x51, 0x07, 0xe4, 0x46, 0xff, 0x2d, 0x7f, 0xeb, 0x18, + 0x1b, 0x4f, 0x0e, 0x27, 0x03, 0xdb, 0x42, 0xc1, 0x3c, 0x3b, 0x05, 0xd7, 0x29, + 0x16, 0xec, 0x5a, 0xa4, 0x04, 0xa0, 0x04, 0x1d, 0x1a, 0x08, 0x4a, 0x3b, 0x0d, + 0xf5, 0xf2, 0xdd, 0xd1, 0x34, 0xe9, 0x18, 0xf5, 0x0c, 0xfe, 0x39, 0xd4, 0x41, + 0xeb, 0x09, 0xdb, 0x02, 0x29, 0x35, 0xe9, 0x07, 0xe3, 0xfb, 0xe3, 0xef, 0x0d, + 0xd4, 0x33, 0xfa, 0x1b, 0xe1, 0x13, 0xfc, 0xf8, 0x0b, 0x00, 0xff, 0xee, 0xc8, + 0xdc, 0x31, 0x31, 0x41, 0xe5, 0xff, 0xef, 0x14, 0x4f, 0xee, 0x01, 0xe7, 0xf9, + 0xe7, 0xf1, 0xef, 0x16, 0xfa, 0x00, 0x07, 0xee, 0xf0, 0x1d, 0xd3, 0x1d, 0x04, + 0xf7, 0x7f, 0xbc, 0xf7, 0xd6, 0xfb, 0xd5, 0xe7, 0x31, 0x12, 0xf4, 0x13, 0xe1, + 0xea, 0xfc, 0xdf, 0x15, 0x45, 0xcf, 0xe3, 0x06, 0xed, 0x07, 0xf4, 0x04, 0x1b, + 0xe3, 0xf3, 0x1d, 0x11, 0xf1, 0xf6, 0xf6, 0xfb, 0x24, 0x32, 0x45, 0xf1, 0xeb, + 0xeb, 0x19, 0x26, 0xc0, 0x10, 0x12, 0x04, 0x26, 0x55, 0xe6, 0x25, 0xe1, 0x04, + 0x0e, 0xf1, 0x45, 0x00, 0xda, 0xc1, 0xbb, 0x65, 0x0e, 0x20, 0x18, 0xe3, 0xde, + 0xf3, 0x1b, 0xd1, 0x11, 0xc8, 0xe0, 0xed, 0x04, 0xda, 0xfc, 0x07, 0xe2, 0xe2, + 0xd5, 0xeb, 0xbb, 0xe0, 0xfc, 0x12, 0xf7, 0x1d, 0x16, 0x3d, 0xe9, 0x10, 0x53, + 0x03, 0x02, 0xe7, 0xd4, 0xfc, 0x7f, 0x39, 0x24, 0x2f, 0x22, 0xd8, 0x16, 0xf1, + 0xec, 0xfe, 0x20, 0xf4, 0xdd, 0x0c, 0x04, 0x07, 0x02, 0xb8, 0x0d, 0x03, 0x58, + 0x24, 0x21, 0xd1, 0x28, 0x35, 0xfd, 0x15, 0x05, 0x08, 0xdd, 0x10, 0x0a, 0xdb, + 0x58, 0x06, 0x31, 0x07, 0xfe, 0x22, 0xd4, 0x4b, 0xfe, 0x04, 0xf6, 0x06, 0x15, + 0x3f, 0x24, 0x0b, 0x12, 0x0e, 0x11, 0x10, 0x05, 0xee, 0x14, 0x06, 0xfc, 0xda, + 0x21, 0x22, 0x48, 0xec, 0xff, 0xb5, 0xee, 0xc3, 0xec, 0xbe, 0x0f, 0xfa, 0x23, + 0x11, 0x2f, 0x04, 0xf0, 0x23, 0x0c, 0x14, 0x5e, 0xe2, 0x02, 0xd9, 0x2c, 0xf4, + 0xe7, 0xdd, 0xef, 0xf3, 0x0f, 0x40, 0x35, 0x26, 0x0a, 0xe6, 0x81, 0x23, 0x18, + 0x4d, 0x18, 0x48, 0x0c, 0xf7, 0xf9, 0x2a, 0x5c, 0x17, 0x4d, 0xff, 0xe7, 0xfa, + 0x47, 0xeb, 0xda, 0x0b, 0x09, 0xe2, 0x22, 0x0b, 0xfb, 0x41, 0x20, 0xe1, 0xee, + 0x14, 0x18, 0x1a, 0x4b, 0x3b, 0x1b, 0xf0, 0x13, 0xfb, 0xf0, 0x10, 0x11, 0x13, + 0xee, 0xea, 0x0e, 0x08, 0xde, 0x0f, 0xe9, 0xfa, 0x0e, 0x27, 0xfc, 0xf5, 0x4a, + 0x36, 0x1f, 0x5b, 0x20, 0xf8, 0x10, 0x4f, 0xb4, 0x17, 0x19, 0x26, 0xdf, 0xf3, + 0x0c, 0x6d, 0x24, 0x2b, 0xf4, 0xed, 0x0f, 0x12, 0xe8, 0x0e, 0x1d, 0x12, 0xf8, + 0x08, 0xf1, 0x12, 0x14, 0x58, 0xd5, 0xf4, 0x05, 0x0a, 0xfe, 0xfe, 0x3a, 0x0c, + 0x2d, 0x09, 0xbb, 0x0f, 0x5c, 0x05, 0x33, 0x25, 0x3f, 0x22, 0xe9, 0xef, 0x0b, + 0xf3, 0xf9, 0xf6, 0x01, 0x01, 0xc6, 0x2b, 0x49, 0xac, 0x4e, 0x05, 0x2e, 0x09, + 0x28, 0xb4, 0x26, 0xfe, 0x3a, 0x28, 0xfa, 0xf5, 0x0e, 0x35, 0x11, 0x6a, 0x52, + 0x12, 0x8e, 0x02, 0x3e, 0xec, 0x3f, 0x31, 0x31, 0x3a, 0x9e, 0xe6, 0x5c, 0x00, + 0xbb, 0x00, 0xd7, 0xda, 0x41, 0x19, 0xaa, 0xd9, 0xcd, 0xe7, 0x08, 0xb2, 0xe0, + 0x09, 0x25, 0x46, 0x5d, 0x05, 0x36, 0x20, 0xdb, 0xf6, 0x24, 0xe4, 0x1f, 0x21, + 0x00, 0x26, 0x22, 0x28, 0x52, 0x13, 0x14, 0xe7, 0xe0, 0x17, 0x33, 0xe8, 0x0c, + 0x5d, 0x33, 0xdc, 0xb6, 0x10, 0x0f, 0xb0, 0xe3, 0xae, 0xf6, 0x39, 0xa9, 0x52, + 0x25, 0xf8, 0xc9, 0xf2, 0x2f, 0xf1, 0xe8, 0x44, 0x2e, 0x08, 0xda, 0x35, 0x46, + 0x0f, 0x02, 0x7f, 0xfe, 0xba, 0x04, 0xe8, 0x74, 0x00, 0xe1, 0xe8, 0x2f, 0xee, + 0xe2, 0x27, 0x59, 0x3b, 0x38, 0x33, 0x02, 0x01, 0x0f, 0xb6, 0x11, 0x18, 0x05, + 0x0c, 0xfb, 0x53, 0xeb, 0x0f, 0x18, 0x2b, 0xda, 0x14, 0xe3, 0x5a, 0x0d, 0xff, + 0xef, 0xff, 0xf3, 0x13, 0xdb, 0x28, 0x08, 0xdf, 0xe8, 0xf2, 0xc9, 0xfc, 0x42, + 0xd5, 0x10, 0x09, 0xe0, 0x4b, 0x3b, 0xdc, 0x13, 0xe4, 0xd6, 0x32, 0x45, 0x08, + 0xfb, 0x36, 0xcb, 0x04, 0x59, 0xf6, 0x17, 0xd2, 0x07, 0x46, 0x25, 0xd6, 0xe9, + 0xdb, 0xfc, 0xfd, 0xe2, 0xf3, 0xe6, 0xde, 0xf5, 0xae, 0x04, 0x13, 0xda, 0x55, + 0xd9, 0x4a, 0xde, 0x0f, 0x07, 0x0d, 0xa5, 0xc6, 0xe9, 0xd4, 0xbb, 0xda, 0xf3, + 0x45, 0x81, 0x18, 0xaf, 0xfc, 0x08, 0xfd, 0xb0, 0xe5, 0xcb, 0xda, 0x01, 0x01, + 0xf8, 0x59, 0xf0, 0x02, 0x17, 0x39, 0x0a, 0xdb, 0xac, 0x06, 0x16, 0xdc, 0xf4, + 0xf7, 0xf8, 0x1d, 0x10, 0xc2, 0x0b, 0xcc, 0x21, 0xdb, 0xc9, 0xde, 0x02, 0x11, + 0x57, 0x0c, 0x31, 0xec, 0x29, 0x40, 0x27, 0xe3, 0xe9, 0xed, 0x1e, 0xc0, 0x43, + 0xcf, 0xc0, 0x37, 0x3c, 0xbf, 0xfb, 0xd4, 0x1d, 0xef, 0xd1, 0x64, 0xe8, 0xf3, + 0x18, 0xf4, 0xee, 0x05, 0xeb, 0x03, 0xe0, 0xfb, 0xc2, 0xe7, 0xab, 0x24, 0xc5, + 0xf8, 0x7f, 0x2a, 0x00, 0xc4, 0xe9, 0xf0, 0x04, 0xfc, 0x1c, 0xf1, 0x05, 0xff, + 0xc7, 0x35, 0x15, 0xcd, 0xea, 0xfb, 0x0a, 0xb8, 0x6c, 0x2c, 0x0a, 0x10, 0xde, + 0xf3, 0xfa, 0x9a, 0x33, 0xda, 0x08, 0x24, 0xda, 0x0d, 0x18, 0x4e, 0x11, 0xf2, + 0xfe, 0x1c, 0xe6, 0xd2, 0xe3, 0xf1, 0x3a, 0xdc, 0x01, 0x2f, 0xe2, 0xf1, 0xdb, + 0xfa, 0x28, 0xbc, 0xef, 0x5e, 0xed, 0x05, 0xcf, 0xe9, 0xf2, 0xcb, 0xfa, 0x3a, + 0x2f, 0xf8, 0x28, 0xfa, 0xdf, 0xe9, 0xd7, 0x29, 0x07, 0x02, 0xf0, 0x3a, 0xf0, + 0xd3, 0x08, 0x15, 0x0d, 0x2d, 0xe4, 0x2a, 0x30, 0xe3, 0xc1, 0x1d, 0x2f, 0x17, + 0x14, 0xf9, 0x31, 0x11, 0xff, 0xfd, 0xc9, 0x1b, 0x1c, 0x0e, 0x55, 0xf3, 0xe2, + 0x16, 0xd7, 0xc7, 0xd8, 0x2f, 0xfc, 0xe1, 0x1f, 0x03, 0xcc, 0x32, 0x33, 0x30, + 0xeb, 0xe3, 0xbf, 0x13, 0xf9, 0x06, 0xe7, 0x03, 0x0e, 0xee, 0xf9, 0x3d, 0x51, + 0x05, 0xef, 0x22, 0xef, 0x02, 0xf4, 0x17, 0xdc, 0xbb, 0xf0, 0x0b, 0xcd, 0x48, + 0xf2, 0xd4, 0x32, 0x01, 0xef, 0xd6, 0x15, 0x12, 0x1c, 0xff, 0x2c, 0xf9, 0xca, + 0xd4, 0x15, 0x08, 0xdc, 0x03, 0x0a, 0xf0, 0xe1, 0x1b, 0xf4, 0xd4, 0xbd, 0xed, + 0xdc, 0xff, 0xeb, 0xce, 0x09, 0x25, 0xef, 0x31, 0xee, 0xee, 0x81, 0xfd, 0xf1, + 0xfb, 0xf7, 0x50, 0xaf, 0xd7, 0xcd, 0xec, 0xe3, 0x0a, 0x0c, 0x0c, 0xd7, 0x18, + 0x02, 0x18, 0xf2, 0xe2, 0x0d, 0x21, 0xd1, 0x0b, 0x00, 0x0c, 0x14, 0x41, 0xf3, + 0x14, 0xbc, 0x26, 0xe4, 0x26, 0x37, 0xfc, 0x0a, 0xe3, 0xd4, 0x06, 0x2a, 0xe3, + 0x27, 0x0a, 0xd4, 0xf6, 0xfd, 0xf1, 0xe8, 0x5b, 0xfa, 0xd2, 0xc6, 0x42, 0xdd, + 0x07, 0xe8, 0xed, 0x09, 0x32, 0x5b, 0xf8, 0xfb, 0x2a, 0x0d, 0x3f, 0xd4, 0x16, + 0xd4, 0x23, 0x06, 0xd3, 0x2c, 0xbb, 0x24, 0xd2, 0x14, 0x09, 0xed, 0x01, 0x5d, + 0x7f, 0xbb, 0xfb, 0xd5, 0x14, 0x2d, 0xfe, 0x13, 0xbe, 0x0c, 0xe5, 0x1a, 0x05, + 0x24, 0xd9, 0xbc, 0xef, 0x05, 0xfc, 0x16, 0x32, 0x31, 0x14, 0xd6, 0x33, 0xfc, + 0xe6, 0xe1, 0x1c, 0xe3, 0xef, 0xd8, 0xa7, 0xce, 0xd8, 0x11, 0xca, 0xf8, 0xf8, + 0xdd, 0x1b, 0xf5, 0x51, 0x08, 0x34, 0x09, 0xfb, 0xb7, 0x2f, 0xbf, 0x3e, 0xf2, + 0xda, 0x4a, 0xdc, 0xe2, 0x14, 0xf5, 0x7f, 0x37, 0x42, 0xd3, 0x10, 0xeb, 0xe0, + 0xf8, 0xd8, 0x10, 0xf4, 0xee, 0x48, 0x32, 0x0a, 0xcb, 0x1b, 0xc0, 0xf9, 0x19, + 0x01, 0x1c, 0xd1, 0x04, 0xe9, 0xd6, 0xb9, 0x5a, 0xe8, 0x0a, 0xe1, 0x25, 0x21, + 0x0d, 0xc6, 0xf8, 0xfa, 0xcc, 0x36, 0xe9, 0x22, 0x69, 0x2d, 0xec, 0x4d, 0x36, + 0xc1, 0xee, 0xcb, 0xe1, 0x4b, 0xfe, 0xd5, 0x31, 0xe0, 0xf9, 0x1d, 0xf3, 0xab, + 0x2b, 0x24, 0x4b, 0x15, 0x66, 0xd9, 0x29, 0x14, 0x40, 0x6d, 0xa1, 0xe4, 0xca, + 0x21, 0xb7, 0x07, 0xfb, 0xff, 0xc0, 0x2b, 0xf8, 0xe9, 0xfe, 0xe2, 0xe8, 0xad, + 0x23, 0xc0, 0x3e, 0x17, 0x09, 0xbc, 0x30, 0xcf, 0xd0, 0xf4, 0xd8, 0x1c, 0x5d, + 0xf6, 0x3c, 0x0f, 0xd9, 0x1c, 0x24, 0x0d, 0xd0, 0xc1, 0xd4, 0xd7, 0x00, 0xfd, + 0xe3, 0xa1, 0xde, 0xe1, 0x11, 0x0d, 0x36, 0x29, 0x48, 0x27, 0xf6, 0x3e, 0xf1, + 0x2b, 0x2b, 0x21, 0xc3, 0xe6, 0xf8, 0x10, 0xe3, 0xd8, 0x02, 0xf2, 0x45, 0x4f, + 0xd8, 0xfc, 0xf4, 0x6b, 0xf7, 0xfe, 0xac, 0x18, 0xe8, 0x12, 0xfd, 0x14, 0x1f, + 0x2a, 0xd1, 0x26, 0x56, 0xb8, 0xae, 0x0f, 0x36, 0xac, 0x16, 0xd7, 0x06, 0x0d, + 0x1d, 0x3f, 0xfa, 0x18, 0x40, 0x01, 0x7f, 0xfe, 0x35, 0xed, 0xc8, 0xcc, 0x04, + 0x3a, 0x2f, 0xdd, 0x32, 0x2c, 0xfb, 0x17, 0xf0, 0x0c, 0x17, 0x0e, 0x11, 0xd6, + 0xa7, 0x75, 0xd0, 0xf6, 0x23, 0xd8, 0x46, 0x01, 0x10, 0x06, 0xd1, 0x38, 0xc9, + 0xb7, 0xb0, 0xea, 0xf8, 0xe9, 0x10, 0x55, 0xcd, 0x17, 0x3c, 0x99, 0x0e, 0x81, + 0x27, 0xd5, 0xd3, 0x05, 0x2f, 0x2d, 0xab, 0xfa, 0x41, 0xc5, 0x7a, 0x44, 0xe9, + 0xca, 0xd8, 0xce, 0x0e, 0xc1, 0x23, 0x29, 0xdb, 0xda, 0x32, 0x09, 0x2a, 0xcd, + 0x2b, 0x61, 0xf4, 0x09, 0xf2, 0xe8, 0x18, 0x29, 0x03, 0x47, 0xee, 0xe5, 0xab, + 0xd3, 0xe6, 0x3a, 0x23, 0xe0, 0xb0, 0xcd, 0x2d, 0xce, 0xfd, 0x25, 0x95, 0x24, + 0x46, 0x27, 0x20, 0x49, 0x97, 0xb6, 0xe1, 0x2f, 0x8c, 0xf1, 0x11, 0x08, 0x1a, + 0xa8, 0x0f, 0x2d, 0x11, 0x20, 0x3a, 0xfd, 0x20, 0xfd, 0x20, 0xcc, 0x20, 0x31, + 0x5f, 0x1b, 0x47, 0x24, 0xd8, 0xf1, 0xc5, 0xb3, 0xe5, 0x25, 0xd5, 0x4f, 0x42, + 0x01, 0xbd, 0x27, 0x09, 0xac, 0x37, 0x3f, 0xd4, 0x50, 0xcc, 0xb6, 0x38, 0x1e, + 0xe6, 0x0d, 0x19, 0x0f, 0xd0, 0x1d, 0x0f, 0xf2, 0xa3, 0xf9, 0xe9, 0x07, 0xf4, + 0x09, 0x0c, 0xf6, 0xe8, 0x48, 0x18, 0xdd, 0x47, 0xaa, 0x17, 0x02, 0x00, 0x06, + 0x4b, 0xec, 0x2e, 0xf0, 0xe4, 0x28, 0xea, 0x31, 0x54, 0xa3, 0xe9, 0xb8, 0xee, + 0x2e, 0xa5, 0x9f, 0x00, 0xfa, 0xd0, 0x06, 0x13, 0x0f, 0x24, 0x16, 0x19, 0x58, + 0x1e, 0x07, 0x2e, 0x2f, 0xef, 0xfb, 0xcf, 0xeb, 0x3b, 0xa5, 0xf4, 0xcd, 0xb4, + 0x4e, 0x08, 0x7f, 0x06, 0xee, 0x2d, 0xcc, 0x04, 0x69, 0xe7, 0xe2, 0x1f, 0x00, + 0xe7, 0x00, 0xe5, 0xdb, 0xfb, 0x19, 0xb8, 0x00, 0x42, 0xd2, 0x3d, 0xb0, 0xd0, + 0x1a, 0x07, 0x24, 0xe9, 0xfc, 0x20, 0xec, 0x1a, 0xb8, 0x28, 0xc5, 0x24, 0x14, + 0xc9, 0x9e, 0x11, 0x00, 0xdf, 0xbd, 0x1d, 0xea, 0x19, 0xd5, 0xb0, 0x52, 0xf2, + 0xf3, 0x1d, 0xbe, 0xe9, 0xad, 0x3b, 0xe2, 0xff, 0xaa, 0xd6, 0xf1, 0xfe, 0x1f, + 0xda, 0xfa, 0x0f, 0x06, 0xb1, 0xf8, 0x20, 0x22, 0x67, 0x12, 0xea, 0xda, 0xa1, + 0xc3, 0xd6, 0x25, 0x57, 0xcb, 0xea, 0x1c, 0xf4, 0xcb, 0xb9, 0x44, 0xf7, 0x1f, + 0x3b, 0xe6, 0xb9, 0x9e, 0xd4, 0xd3, 0x2d, 0x4e, 0xe6, 0x09, 0xd8, 0x04, 0x58, + 0xf8, 0xc3, 0x9b, 0xe8, 0x14, 0xec, 0x41, 0xec, 0x01, 0xfe, 0x03, 0x19, 0xcd, + 0xc1, 0x90, 0x0b, 0xef, 0xda, 0x1d, 0xfa, 0x3d, 0xf5, 0x09, 0x11, 0xaa, 0x1d, + 0xe4, 0x10, 0x05, 0x14, 0xff, 0x1d, 0xe7, 0x36, 0x69, 0xee, 0x01, 0xfc, 0xd9, + 0x48, 0xe0, 0x06, 0x40, 0xfa, 0xcb, 0xf8, 0x65, 0x53, 0xfb, 0x0b, 0x7f, 0x53, + 0x2b, 0xed, 0x89, 0x50, 0x07, 0x03, 0x06, 0xf3, 0x12, 0x1c, 0xca, 0x1f, 0x72, + 0xd0, 0xce, 0x1e, 0x99, 0x20, 0x10, 0xbd, 0xf0, 0xd1, 0x48, 0xe1, 0x2b, 0xb6, + 0x38, 0xd0, 0x06, 0x05, 0xf6, 0x04, 0x19, 0x53, 0x1b, 0xbf, 0xaa, 0xd0, 0x06, + 0x26, 0xc4, 0x57, 0x46, 0xff, 0x0f, 0xa3, 0xfb, 0xf1, 0x0c, 0x2b, 0x33, 0xdc, + 0x10, 0x0f, 0x0e, 0xbd, 0x05, 0xbf, 0x2f, 0xe7, 0x2b, 0x0a, 0x00, 0x15, 0xfc, + 0xb1, 0x22, 0x01, 0x1e, 0x17, 0x08, 0x53, 0xfa, 0xcd, 0xf4, 0x39, 0xf7, 0xd6, + 0xe9, 0xd4, 0x01, 0xce, 0xcd, 0x27, 0x48, 0x91, 0xff, 0xd7, 0xaf, 0xbc, 0x32, + 0xb2, 0x26, 0xd4, 0xf6, 0x33, 0xc5, 0x29, 0x0d, 0xc3, 0x5a, 0xfd, 0x7c, 0x24, + 0xfc, 0xf8, 0xc3, 0x31, 0xba, 0xb5, 0x3d, 0xc7, 0xf0, 0x3f, 0xbf, 0x51, 0x17, + 0xd9, 0x79, 0xce, 0x17, 0xba, 0x29, 0xc4, 0x94, 0x33, 0xf9, 0xe9, 0xcb, 0x21, + 0xf7, 0x2e, 0x1e, 0xab, 0xeb, 0xc3, 0xfa, 0x0c, 0x0a, 0xc6, 0x81, 0x40, 0x00, + 0xfb, 0x0a, 0x0c, 0x01, 0xe3, 0x81, 0x00, 0x7e, 0xee, 0x48, 0x23, 0xd7, 0xde, + 0x42, 0x5e, 0xea, 0x11, 0xca, 0x47, 0xe9, 0x02, 0xf7, 0xd2, 0x28, 0x03, 0xf7, + 0xfa, 0x13, 0xc1, 0x2a, 0xdf, 0x01, 0xe7, 0xc8, 0x0b, 0xf6, 0xce, 0x42, 0x38, + 0x0c, 0x23, 0xc8, 0xd8, 0xed, 0x10, 0x22, 0xea, 0xfc, 0x28, 0xf9, 0xc7, 0x00, + 0xd6, 0xeb, 0x7a, 0x31, 0x33, 0xf2, 0xf6, 0xf4, 0x0c, 0x98, 0xe9, 0xd3, 0x2a, + 0xdf, 0x09, 0x1a, 0xf9, 0xf8, 0xfd, 0xe0, 0x1d, 0xec, 0x41, 0x28, 0x72, 0xf9, + 0xa4, 0xe1, 0xbf, 0xf1, 0xd7, 0xde, 0xf3, 0x05, 0x43, 0xf2, 0xcf, 0xc3, 0x1a, + 0xef, 0x05, 0x20, 0xef, 0xff, 0xeb, 0xfb, 0x16, 0x30, 0xc9, 0xe4, 0xcc, 0x1f, + 0xf4, 0xfb, 0xc3, 0x19, 0xf4, 0xa5, 0x32, 0x11, 0x07, 0x13, 0xec, 0x23, 0x50, + 0x0d, 0x02, 0xe1, 0xb0, 0x5c, 0xf8, 0x20, 0xd2, 0x44, 0x2e, 0xd0, 0x19, 0xc8, + 0xf8, 0xe1, 0x0f, 0xed, 0xed, 0xd3, 0x3d, 0xe5, 0x63, 0x4d, 0x3a, 0x32, 0xdb, + 0x31, 0x08, 0x3b, 0x56, 0x2c, 0xc2, 0x05, 0x2f, 0xfe, 0x16, 0xff, 0x17, 0x10, + 0xa0, 0xb7, 0x2a, 0x49, 0xb2, 0xf7, 0x0b, 0xbf, 0x33, 0xf8, 0xb9, 0x46, 0xfd, + 0x1a, 0x27, 0xd4, 0x12, 0x12, 0xe7, 0x25, 0x23, 0xf1, 0x1c, 0xda, 0x23, 0x47, + 0x22, 0xf4, 0x13, 0xda, 0x2d, 0xdc, 0xf1, 0xea, 0xda, 0x21, 0x35, 0xfc, 0x24, + 0xf2, 0xe3, 0x20, 0x0d, 0x39, 0xe8, 0x18, 0xe8, 0x7f, 0xde, 0xd8, 0x11, 0x33, + 0xcb, 0x20, 0xf4, 0x6f, 0x4a, 0xfe, 0x05, 0xf9, 0x2b, 0xff, 0x04, 0xe2, 0x28, + 0xec, 0x32, 0xdc, 0xf2, 0x07, 0x09, 0x43, 0xec, 0x11, 0xef, 0xdf, 0x11, 0xf0, + 0xfa, 0x10, 0xeb, 0xdb, 0x13, 0xc7, 0x19, 0xea, 0xd8, 0x06, 0x32, 0x19, 0x14, + 0x3c, 0x28, 0x09, 0xe4, 0x5b, 0x41, 0x1f, 0xfb, 0x57, 0x61, 0x57, 0x2d, 0x13, + 0xbd, 0x25, 0x38, 0x1b, 0x27, 0x2e, 0x34, 0x11, 0xbe, 0xda, 0x2a, 0x2a, 0xbe, + 0x0c, 0x02, 0x43, 0xe5, 0x1b, 0xf7, 0x08, 0xd8, 0x69, 0xd4, 0x27, 0x19, 0x4b, + 0xc6, 0x04, 0xc0, 0xf2, 0xe9, 0x3a, 0x25, 0xda, 0xc7, 0xf1, 0xd3, 0xae, 0x9e, + 0xc5, 0x2a, 0xea, 0x07, 0xd2, 0x04, 0xb9, 0x05, 0x5e, 0xda, 0x47, 0x81, 0xf6, + 0xf8, 0x01, 0x0a, 0x08, 0xe8, 0x11, 0xcb, 0xe2, 0xd7, 0xbe, 0x02, 0xb5, 0x2e, + 0x15, 0xf4, 0xce, 0xd6, 0x26, 0xf5, 0x28, 0x28, 0x39, 0xcb, 0xf1, 0x2f, 0xac, + 0xcc, 0x91, 0xed, 0x15, 0x0f, 0xd3, 0xd0, 0xed, 0xb8, 0x05, 0x0d, 0x47, 0xe9, + 0x18, 0x03, 0x1e, 0xdf, 0x18, 0xe0, 0xcf, 0xda, 0x5e, 0x99, 0x29, 0xc1, 0x3e, + 0xed, 0xf9, 0x4b, 0x9e, 0x06, 0xf6, 0x68, 0x27, 0xf2, 0xe2, 0xca, 0xf6, 0xc8, + 0xe6, 0xd7, 0xe7, 0xf7, 0xc3, 0xdd, 0x07, 0xf7, 0x17, 0xdb, 0xff, 0x05, 0x09, + 0x02, 0x01, 0xec, 0x0d, 0x01, 0x1d, 0xdf, 0x18, 0xb8, 0x15, 0xff, 0x35, 0xcf, + 0x06, 0x5f, 0x26, 0x1c, 0xdf, 0x05, 0xeb, 0x16, 0x42, 0x4d, 0xf8, 0x1f, 0xcd, + 0x20, 0xc4, 0xd5, 0x11, 0xf6, 0xea, 0x00, 0x23, 0x0b, 0xee, 0x37, 0x12, 0xe2, + 0xf2, 0x41, 0xea, 0x04, 0x0d, 0xd6, 0xd1, 0xd8, 0x18, 0xd5, 0xf1, 0x0f, 0xc1, + 0x01, 0x4a, 0x29, 0xeb, 0xd0, 0xfe, 0x00, 0x27, 0xf8, 0x11, 0x6d, 0x18, 0x5f, + 0x55, 0x47, 0x01, 0xe3, 0xf9, 0x09, 0xee, 0xdd, 0xdc, 0x2a, 0xbc, 0xaf, 0xd5, + 0xe1, 0xbd, 0x12, 0xe8, 0x0e, 0xf7, 0xec, 0xf7, 0xf3, 0x20, 0x1e, 0xc1, 0x19, + 0xfe, 0xe3, 0x1b, 0xff, 0xc1, 0xdc, 0xc3, 0xf0, 0xf7, 0x0b, 0x01, 0x35, 0x7f, + 0xeb, 0x2c, 0x3c, 0x0c, 0x0e, 0x43, 0xd6, 0xf2, 0xec, 0xf1, 0x10, 0xc7, 0xf1, + 0x13, 0x5a, 0x28, 0x0b, 0x0a, 0xf8, 0xe7, 0x2f, 0x02, 0x00, 0xf5, 0x0c, 0xeb, + 0x1b, 0xf8, 0x11, 0xfc, 0xfd, 0x12, 0x06, 0x0c, 0xdc, 0xcf, 0xbc, 0xeb, 0xde, + 0x41, 0x0a, 0xd7, 0x2a, 0xe4, 0x1b, 0x2d, 0x00, 0x0f, 0x39, 0xea, 0xf0, 0x02, + 0xe7, 0xdc, 0x1a, 0x2b, 0xf1, 0xe1, 0x3e, 0x05, 0x17, 0x00, 0x05, 0xe5, 0xef, + 0x32, 0x47, 0xe1, 0x17, 0x2e, 0x08, 0xe3, 0x25, 0x49, 0xfb, 0xff, 0x04, 0xf8, + 0x2b, 0x1e, 0x08, 0x46, 0x3e, 0xeb, 0x0b, 0xeb, 0x5b, 0x1d, 0x65, 0x39, 0xec, + 0x07, 0xb4, 0x15, 0xf9, 0xf5, 0x22, 0xfc, 0xcd, 0x79, 0x02, 0xed, 0xf7, 0x26, + 0xf3, 0xce, 0xc8, 0x21, 0x0e, 0x1e, 0xf1, 0x0f, 0x10, 0x1c, 0x1f, 0xf0, 0x11, + 0x2f, 0xda, 0xfc, 0xfb, 0xf8, 0x13, 0xd2, 0xca, 0xf2, 0x4b, 0xf0, 0x07, 0x31, + 0x7f, 0x05, 0x15, 0xe2, 0x1f, 0x04, 0x4f, 0x1e, 0x1b, 0x07, 0xd9, 0x4c, 0x48, + 0x3d, 0xf9, 0xfa, 0x05, 0xea, 0xe6, 0x14, 0x2b, 0xff, 0xef, 0x29, 0x04, 0xff, + 0xeb, 0x0d, 0x04, 0xeb, 0x16, 0x09, 0x06, 0xd3, 0xec, 0xfd, 0xdc, 0x3b, 0xd7, + 0x31, 0x10, 0x22, 0x7f, 0x3e, 0xc5, 0x24, 0x10, 0x14, 0x49, 0xfa, 0xf0, 0xcb, + 0xcc, 0xcb, 0x2a, 0xe0, 0x18, 0x18, 0xdc, 0xf5, 0xff, 0xed, 0xb0, 0x50, 0xf9, + 0x1a, 0xb7, 0xb4, 0x18, 0xd7, 0x0a, 0x35, 0xfc, 0x06, 0xc7, 0x0f, 0x62, 0xf6, + 0xdf, 0x06, 0xcc, 0x23, 0xbc, 0x45, 0x23, 0x14, 0x2a, 0xe7, 0x3e, 0xe0, 0x09, + 0xf3, 0xf0, 0x10, 0x00, 0xf3, 0x33, 0x3d, 0x37, 0x1d, 0xba, 0x1f, 0xf8, 0xf1, + 0x38, 0x01, 0xd3, 0x9f, 0x19, 0xc8, 0x1f, 0xe0, 0xc3, 0x12, 0xf6, 0x20, 0x57, + 0x24, 0x18, 0x01, 0xf0, 0x08, 0xd0, 0xed, 0x40, 0x0c, 0xdd, 0x17, 0x39, 0x2a, + 0xff, 0x85, 0xfa, 0x22, 0xf7, 0x09, 0xec, 0x02, 0x0f, 0x16, 0xb7, 0xc0, 0xc4, + 0xbd, 0xf0, 0xc4, 0x07, 0xc4, 0xea, 0x00, 0x13, 0xff, 0xd2, 0xf0, 0xf4, 0x0b, + 0xe3, 0xf6, 0xea, 0x0f, 0x36, 0xc2, 0xf9, 0xa8, 0xe1, 0xee, 0xd9, 0x1e, 0x0c, + 0xea, 0xd0, 0x1f, 0xd6, 0xf9, 0x18, 0x46, 0xdb, 0x22, 0xf2, 0xf5, 0x06, 0xda, + 0x39, 0x41, 0xfc, 0x48, 0xe8, 0xf9, 0xf7, 0x48, 0x27, 0x1e, 0x33, 0x0e, 0xd3, + 0xc5, 0xd3, 0x17, 0x7f, 0x05, 0x01, 0x2b, 0x21, 0xef, 0xef, 0x27, 0xf3, 0x12, + 0xfa, 0x01, 0x06, 0x0b, 0x26, 0x08, 0x25, 0x12, 0xf3, 0xf2, 0xc5, 0x0e, 0x07, + 0xd9, 0x07, 0x00, 0x25, 0xeb, 0x1e, 0x0c, 0x18, 0x1e, 0x03, 0xc6, 0x29, 0x20, + 0xfc, 0x04, 0xf0, 0xfa, 0xfe, 0x07, 0xf6, 0x1a, 0x18, 0x51, 0xf0, 0x17, 0xb8, + 0xfc, 0x03, 0x18, 0xe6, 0x0f, 0x36, 0xb9, 0xef, 0x1f, 0x3e, 0x34, 0x01, 0xe2, + 0x4e, 0x0d, 0xf4, 0x21, 0xfb, 0x2c, 0x0b, 0x28, 0x53, 0xef, 0xf7, 0x7b, 0x25, + 0xdb, 0xc9, 0xea, 0xe1, 0xf2, 0x45, 0x4a, 0xe8, 0x0a, 0xdc, 0x5b, 0xb3, 0xb8, + 0x9e, 0xb0, 0xe3, 0xf9, 0x5c, 0xc4, 0x05, 0xf4, 0xf5, 0x09, 0x0d, 0x24, 0xb0, + 0x42, 0x25, 0x22, 0xca, 0x3f, 0xd7, 0xfb, 0x81, 0x23, 0xd2, 0xea, 0x26, 0xf1, + 0xfc, 0x1c, 0x02, 0x0e, 0x4d, 0x06, 0xff, 0xc8, 0x78, 0xb6, 0xdf, 0xb7, 0x11, + 0xf3, 0x15, 0xf9, 0xf9, 0xe8, 0xec, 0x00, 0x67, 0xea, 0xd8, 0xc7, 0xfe, 0xb8, + 0x08, 0xd5, 0xed, 0x5a, 0xd7, 0x30, 0xe5, 0x0c, 0x14, 0x5f, 0xee, 0x23, 0x2b, + 0x32, 0x6c, 0xe8, 0x11, 0x30, 0xc4, 0x32, 0xdb, 0xfe, 0xd9, 0xd5, 0x51, 0xd9, + 0xda, 0x1d, 0x49, 0xdc, 0xe1, 0x04, 0xe1, 0x24, 0x16, 0xbd, 0xe6, 0x1d, 0xf0, + 0x34, 0x20, 0x0b, 0xfa, 0xf2, 0xc7, 0xcd, 0xd2, 0x36, 0x3e, 0xfa, 0x58, 0xf6, + 0xd0, 0x00, 0x0c, 0xde, 0x06, 0x40, 0x14, 0x96, 0x3b, 0xe9, 0x31, 0xe5, 0x34, + 0x0c, 0xf8, 0xf8, 0x63, 0x44, 0x0d, 0x1e, 0x4c, 0xf8, 0x0d, 0xfe, 0xe2, 0xe4, + 0x07, 0x2f, 0x09, 0x41, 0x16, 0xd8, 0x0d, 0x01, 0x36, 0x17, 0xe3, 0x28, 0xd7, + 0xf8, 0x5b, 0xde, 0x33, 0xf5, 0x2e, 0xea, 0x17, 0x07, 0x0f, 0x27, 0xfe, 0x31, + 0xe7, 0xea, 0x4a, 0xfa, 0xfa, 0x32, 0x0c, 0x06, 0xf4, 0x22, 0xfd, 0x5e, 0x3c, + 0x0f, 0x12, 0xfb, 0x1c, 0x23, 0x03, 0xdf, 0xe7, 0x1a, 0x0f, 0xfd, 0xff, 0xd9, + 0x20, 0xdd, 0x30, 0x12, 0xf7, 0xcc, 0xc8, 0x34, 0xfe, 0x19, 0xf6, 0x33, 0x0f, + 0x3d, 0x09, 0x50, 0x53, 0xcc, 0x03, 0x03, 0xd2, 0x10, 0x32, 0x00, 0xeb, 0x02, + 0xf4, 0x25, 0xd1, 0xf3, 0xf1, 0x45, 0xfe, 0xf6, 0x04, 0xee, 0x05, 0xfb, 0x0c, + 0xfb, 0x3d, 0xe8, 0xd9, 0xff, 0x7f, 0xdc, 0xd9, 0xe2, 0x42, 0x02, 0x1a, 0x17, + 0xe8, 0xff, 0x2e, 0x01, 0xfb, 0x0e, 0xfa, 0xff, 0xf4, 0x29, 0x2c, 0x20, 0xf1, + 0xd8, 0xfe, 0x05, 0xf9, 0xf6, 0xcf, 0x15, 0x0f, 0x0d, 0xd3, 0xdc, 0x25, 0x02, + 0xfa, 0xa1, 0xd1, 0xb7, 0xf6, 0x04, 0xe6, 0x19, 0x4d, 0x10, 0x1d, 0xc7, 0xe9, + 0x1d, 0x03, 0x18, 0xf5, 0x0a, 0x09, 0x09, 0x02, 0x12, 0x03, 0xc1, 0xf6, 0x1a, + 0xe0, 0x1b, 0x11, 0xd4, 0xc2, 0xf9, 0xf5, 0x54, 0xeb, 0x52, 0xeb, 0x0e, 0x19, + 0x1f, 0x06, 0xf6, 0x19, 0xf4, 0xf9, 0x1d, 0x10, 0x07, 0x18, 0xfa, 0xe1, 0x7f, + 0x0f, 0xf3, 0xf9, 0x2f, 0x10, 0xd7, 0xf9, 0xe7, 0x1c, 0xed, 0x0b, 0xd2, 0xce, + 0x24, 0x11, 0x50, 0xf3, 0x01, 0x36, 0xec, 0x08, 0xf2, 0x13, 0xc4, 0xfb, 0xdc, + 0x30, 0xf4, 0x0e, 0x14, 0xfa, 0xe6, 0x1f, 0xf5, 0xf4, 0x0a, 0xe6, 0x29, 0xea, + 0x1f, 0x36, 0xd2, 0xd9, 0x0a, 0xfb, 0xe8, 0xfd, 0x2a, 0x20, 0xed, 0xe1, 0x07, + 0x1b, 0xf6, 0xe9, 0xfc, 0x60, 0x01, 0x14, 0xde, 0x04, 0xb5, 0x13, 0x00, 0x1c, + 0x29, 0x27, 0xf9, 0x2c, 0x12, 0x33, 0xee, 0x26, 0xcb, 0x18, 0x01, 0xe6, 0xeb, + 0x27, 0xc1, 0x24, 0x03, 0xb9, 0x12, 0x0a, 0xe4, 0x3a, 0x12, 0x48, 0xeb, 0x22, + 0xef, 0xd6, 0xd1, 0x0d, 0xb7, 0x05, 0x72, 0xfa, 0xf4, 0xf4, 0x28, 0xb3, 0xce, + 0xdc, 0xf1, 0xb9, 0x05, 0x06, 0xd5, 0xfe, 0xf2, 0xaa, 0x23, 0xff, 0x1e, 0x18, + 0xf8, 0x25, 0xd3, 0xf4, 0x06, 0xf1, 0xff, 0x17, 0x0a, 0xef, 0xdc, 0xef, 0x11, + 0xf3, 0xf0, 0xae, 0x11, 0x47, 0xf4, 0xbc, 0xf3, 0xe2, 0x0b, 0xbd, 0xbd, 0x39, + 0xbb, 0x2b, 0x81, 0xe6, 0x04, 0xaa, 0xd1, 0x1b, 0xd2, 0x1f, 0x36, 0xc0, 0xd4, + 0xe0, 0x32, 0xf7, 0xb3, 0xba, 0x17, 0xa5, 0x02, 0xe9, 0x36, 0xf0, 0xcf, 0x2b, + 0xe3, 0x13, 0x05, 0x30, 0x20, 0x14, 0xe6, 0x13, 0x1d, 0xda, 0xfd, 0x58, 0x14, + 0x21, 0x48, 0xc8, 0x13, 0xe8, 0xd4, 0xcd, 0x0a, 0xf3, 0xce, 0xf2, 0xde, 0xff, + 0xe7, 0x03, 0x01, 0x06, 0xff, 0x14, 0xf2, 0x1d, 0xb2, 0xc5, 0x02, 0xd3, 0xf2, + 0x37, 0xc9, 0xf7, 0xfa, 0x36, 0x3d, 0xd5, 0x0c, 0xed, 0xe0, 0xdc, 0x13, 0x16, + 0xf1, 0x0e, 0xd5, 0xd3, 0x03, 0x47, 0x2e, 0xc1, 0x35, 0xe4, 0xd8, 0x1b, 0x04, + 0xce, 0x1c, 0x4e, 0xcd, 0xf3, 0xf8, 0xf5, 0x19, 0x3f, 0xfa, 0x00, 0xda, 0x1b, + 0xe9, 0x36, 0xfe, 0x1e, 0x17, 0x30, 0xf0, 0x0c, 0x3f, 0x10, 0x23, 0xe1, 0x01, + 0xbf, 0xf3, 0x15, 0x1c, 0x0e, 0xf4, 0xf2, 0x51, 0xfe, 0xf0, 0x46, 0x2e, 0x17, + 0xf6, 0x23, 0x05, 0xf8, 0xed, 0xfe, 0xd5, 0xf5, 0xd9, 0xed, 0xce, 0x33, 0x7f, + 0x03, 0x0f, 0xfd, 0x2b, 0x13, 0x0c, 0xff, 0x1b, 0xf9, 0xf3, 0x2d, 0x01, 0x32, + 0xfe, 0xfe, 0xee, 0x06, 0x1c, 0x20, 0x22, 0xeb, 0x24, 0xcd, 0x37, 0x02, 0x3d, + 0x1b, 0x20, 0x20, 0xfa, 0xb2, 0xf0, 0x32, 0xb9, 0xda, 0xf3, 0xdd, 0xf3, 0x19, + 0xe3, 0x0f, 0x17, 0x17, 0xe0, 0xe6, 0xd5, 0x14, 0x38, 0x24, 0xdf, 0x05, 0xce, + 0x28, 0xc7, 0xfa, 0x39, 0x57, 0x34, 0x08, 0xbc, 0x21, 0xcd, 0xf8, 0x1d, 0xee, + 0x21, 0x1a, 0x21, 0x0d, 0xea, 0x3a, 0xda, 0x43, 0xda, 0xf2, 0xe6, 0xf8, 0xd2, + 0xe1, 0x1a, 0xd6, 0xf6, 0xc4, 0x21, 0x3f, 0xd9, 0x1f, 0x02, 0x01, 0xe5, 0xf1, + 0x55, 0x0f, 0xd7, 0x24, 0x18, 0x1c, 0xff, 0xed, 0x0b, 0xef, 0xe2, 0xc8, 0x11, + 0xec, 0xd3, 0x1a, 0x01, 0x7f, 0x64, 0xee, 0x29, 0xde, 0x33, 0x2b, 0xb1, 0x06, + 0x18, 0x21, 0xf0, 0x01, 0x04, 0x1c, 0xc1, 0x07, 0x17, 0x3f, 0x17, 0xce, 0xe3, + 0xce, 0xf9, 0x26, 0x06, 0xdf, 0x21, 0xd4, 0x0c, 0xdd, 0x08, 0x05, 0x2b, 0xf9, + 0x15, 0xd0, 0xdb, 0xde, 0xc6, 0x00, 0xcb, 0xd5, 0x08, 0x1d, 0x09, 0xc9, 0x1f, + 0xdd, 0x1c, 0x57, 0xc6, 0xc9, 0xe7, 0x3b, 0xe7, 0xdb, 0xf8, 0x28, 0xfd, 0xdd, + 0xae, 0xe6, 0xf9, 0x0b, 0x37, 0xe5, 0x1a, 0x06, 0x00, 0x04, 0xd5, 0x18, 0xf4, + 0x1b, 0xc7, 0xd4, 0x06, 0xcc, 0x14, 0x1c, 0x13, 0xd3, 0xc0, 0xe4, 0xc9, 0x5e, + 0xfb, 0xe6, 0xbc, 0xf2, 0x13, 0x15, 0xf2, 0x0f, 0xfd, 0x00, 0xfe, 0xc9, 0xd7, + 0xf3, 0x3f, 0x24, 0x2a, 0xdb, 0xdc, 0xd7, 0xd7, 0x2f, 0xf5, 0xd8, 0xfe, 0x12, + 0x06, 0xdb, 0xf3, 0x08, 0x00, 0xe0, 0xd4, 0xf2, 0xf9, 0xf6, 0xbd, 0xf9, 0x0f, + 0x13, 0xef, 0xfb, 0xfd, 0x47, 0x7f, 0xdc, 0xe6, 0x3a, 0x05, 0xdc, 0xe3, 0xf1, + 0x0f, 0xe9, 0xdc, 0x37, 0x04, 0xd2, 0xe5, 0x0b, 0xe0, 0xf9, 0xc3, 0x19, 0xe9, + 0xe9, 0x02, 0xdc, 0x01, 0xd3, 0xad, 0xea, 0xed, 0xd8, 0x2f, 0x1b, 0xfa, 0x08, + 0x0b, 0x0c, 0xff, 0xc3, 0x0d, 0xf2, 0xe6, 0x22, 0x30, 0x27, 0x10, 0x40, 0x3e, + 0xed, 0xe3, 0xff, 0x44, 0x14, 0x15, 0x1d, 0xff, 0x5e, 0xf6, 0xf0, 0x06, 0x00, + 0x23, 0xe7, 0xe4, 0xcc, 0xf1, 0xa5, 0xd1, 0xde, 0x18, 0x12, 0x1f, 0x0b, 0xf9, + 0xbd, 0xe5, 0xfd, 0xd3, 0xba, 0x29, 0x01, 0xc7, 0x22, 0x6d, 0x39, 0x3d, 0x06, + 0xcc, 0xd2, 0xc6, 0xe9, 0xfd, 0x0e, 0xcf, 0x08, 0x0a, 0x0e, 0xe3, 0xea, 0xd3, + 0xdb, 0x18, 0xc9, 0x3c, 0xfc, 0x08, 0x38, 0xf4, 0x04, 0x14, 0xea, 0x0d, 0x12, + 0xfd, 0x5a, 0xed, 0x44, 0x7f, 0x34, 0x42, 0xb8, 0xd2, 0xf4, 0xc7, 0x0d, 0xc5, + 0x01, 0x17, 0xf4, 0xec, 0xc9, 0x44, 0xad, 0x6f, 0x39, 0x1a, 0xd6, 0xfa, 0xfa, + 0x17, 0xd5, 0x31, 0xf9, 0x1a, 0xdf, 0x25, 0x2b, 0xea, 0xd1, 0x08, 0xe8, 0x13, + 0xd8, 0xef, 0x6d, 0xcd, 0x40, 0xd6, 0x51, 0xe3, 0x55, 0x19, 0x21, 0xde, 0x1d, + 0x57, 0x21, 0x34, 0xd8, 0x3f, 0x46, 0x44, 0x97, 0x1f, 0xe7, 0x09, 0x19, 0x35, + 0x17, 0x1d, 0x3c, 0x5b, 0x23, 0xbb, 0x60, 0x13, 0xc6, 0xeb, 0x6b, 0x1d, 0xe2, + 0x7f, 0x4b, 0xd8, 0xd2, 0xeb, 0x1e, 0xd1, 0x39, 0x10, 0x27, 0x42, 0xfa, 0x1f, + 0xdd, 0xf1, 0xf1, 0xd5, 0xcf, 0x32, 0xe2, 0xf0, 0x31, 0xfd, 0x3d, 0xb8, 0x0f, + 0x32, 0x5e, 0x2e, 0x2e, 0x75, 0x40, 0x08, 0x1c, 0x48, 0x50, 0xe2, 0xf1, 0xe2, + 0xc2, 0x25, 0xf5, 0x21, 0x68, 0xfa, 0xd3, 0x17, 0xeb, 0xdb, 0x0a, 0x0a, 0x0c, + 0x27, 0xed, 0x0e, 0xd6, 0x40, 0x3c, 0x39, 0x0d, 0xb2, 0xed, 0x18, 0xd9, 0xf6, + 0x06, 0x4b, 0x2b, 0xcc, 0x05, 0xdd, 0xd0, 0x35, 0x23, 0x02, 0x4f, 0x4e, 0x05, + 0xdd, 0xe8, 0x18, 0xf5, 0x03, 0x07, 0xdb, 0xe9, 0xe8, 0x46, 0x24, 0x27, 0x1d, + 0xfb, 0xbe, 0xff, 0xfb, 0xab, 0x55, 0xd1, 0x40, 0x06, 0xf7, 0x09, 0x32, 0xf0, + 0x08, 0xe6, 0xeb, 0x53, 0xe6, 0xf0, 0x67, 0x0f, 0x05, 0x11, 0xd6, 0xe1, 0xbf, + 0xd4, 0x24, 0xe9, 0x25, 0xfe, 0xed, 0xce, 0x00, 0x16, 0x21, 0xf8, 0x10, 0x71, + 0xcb, 0xeb, 0xdc, 0xf1, 0xef, 0xfd, 0x06, 0xe2, 0x24, 0xd4, 0xe9, 0xf4, 0x23, + 0x10, 0xff, 0xf8, 0x28, 0xf5, 0xee, 0xf0, 0xe2, 0xe6, 0xe1, 0xab, 0xcf, 0x39, + 0x2a, 0xad, 0xe2, 0xd9, 0xbf, 0xf4, 0x62, 0xa9, 0xcf, 0x2a, 0x24, 0x1c, 0x0d, + 0xd7, 0x1a, 0xd0, 0xa2, 0xfb, 0x14, 0x08, 0xe0, 0xda, 0xd7, 0xf4, 0xd6, 0xec, + 0x16, 0xf1, 0xf7, 0xcd, 0x2e, 0xf4, 0x81, 0xd3, 0x31, 0x89, 0x9d, 0xae, 0x04, + 0xe6, 0x5e, 0x17, 0xd3, 0xf0, 0xd2, 0x2e, 0x19, 0x06, 0x0e, 0xf1, 0x13, 0x14, + 0xf4, 0xda, 0xc4, 0xf6, 0xa9, 0xba, 0x3b, 0xdf, 0xf3, 0xbb, 0x11, 0xee, 0xf4, + 0x20, 0xef, 0x04, 0x1a, 0x02, 0x06, 0x32, 0x06, 0x0e, 0x12, 0xba, 0x14, 0x14, + 0x39, 0xf2, 0xcc, 0x05, 0xf3, 0x03, 0xd6, 0xfc, 0x03, 0xf2, 0x36, 0xee, 0xfe, + 0x2f, 0x42, 0xe1, 0x35, 0xc8, 0x10, 0xed, 0xe6, 0x1b, 0xf0, 0xcc, 0x05, 0x77, + 0xf8, 0x13, 0x0e, 0xc3, 0xcc, 0x19, 0x6c, 0x7f, 0xd9, 0xdd, 0xdc, 0xf9, 0xc8, + 0xf0, 0x08, 0xce, 0xd1, 0x4f, 0xee, 0x4c, 0xf7, 0x22, 0x22, 0xfb, 0x0d, 0x5d, + 0xcb, 0xfc, 0x16, 0xf7, 0xef, 0xfd, 0xe4, 0xf6, 0xe2, 0x27, 0x9d, 0xe0, 0xc4, + 0xec, 0xf9, 0xe7, 0xef, 0xf8, 0xf2, 0x21, 0x10, 0xf9, 0x02, 0x34, 0x15, 0x33, + 0xe2, 0xe9, 0xf5, 0xa7, 0x61, 0x27, 0xcd, 0x16, 0x0a, 0xcf, 0xed, 0xb9, 0xf0, + 0xed, 0x05, 0xf0, 0xb1, 0xf5, 0xb4, 0x00, 0x1e, 0xe9, 0xa4, 0xd5, 0x2c, 0x0d, + 0x3d, 0xd3, 0xc5, 0xd5, 0x0f, 0xd1, 0xea, 0xc0, 0x01, 0xea, 0xbb, 0xf3, 0xee, + 0xd7, 0x0c, 0x0e, 0xf1, 0xa8, 0x05, 0x17, 0xe9, 0x17, 0xfa, 0xfb, 0xfb, 0x1d, + 0xdd, 0xc3, 0x0f, 0x02, 0xe8, 0x1a, 0x0c, 0xdf, 0x48, 0x4c, 0x41, 0xca, 0x27, + 0x12, 0xd2, 0x93, 0xf6, 0xd5, 0xd7, 0xf0, 0x4c, 0x51, 0xeb, 0xf3, 0x56, 0x1b, + 0xa9, 0x39, 0x03, 0x04, 0x7f, 0xd8, 0x26, 0x0e, 0x23, 0xdc, 0x06, 0xeb, 0xce, + 0xb8, 0x2f, 0xe3, 0xec, 0x37, 0x07, 0x26, 0x23, 0x4f, 0x32, 0x09, 0xd4, 0x2f, + 0xff, 0xa4, 0x7d, 0x19, 0x32, 0x67, 0x07, 0xe3, 0x00, 0xab, 0xde, 0xc9, 0xf3, + 0xe5, 0x0f, 0xee, 0xbe, 0x29, 0xf1, 0xd8, 0x1b, 0xcb, 0x12, 0xe2, 0xf8, 0xe2, + 0xe8, 0x20, 0x26, 0xda, 0x63, 0x0c, 0xd6, 0x28, 0xff, 0xc1, 0x49, 0x5f, 0x20, + 0xde, 0xed, 0xf7, 0xee, 0x02, 0x3c, 0x10, 0x22, 0x06, 0x1a, 0xe4, 0xe9, 0x0d, + 0xf6, 0xe8, 0xff, 0xef, 0xe7, 0x00, 0x2b, 0xf3, 0x33, 0xfb, 0x16, 0xd8, 0x52, + 0xfe, 0x2e, 0x07, 0x01, 0x25, 0x06, 0x20, 0x35, 0x25, 0x02, 0x2e, 0x0f, 0xfe, + 0x2f, 0xdb, 0x45, 0x0e, 0x43, 0x2e, 0xe5, 0x02, 0xe5, 0x01, 0x1f, 0xe7, 0x18, + 0xf4, 0x22, 0x06, 0x1d, 0x18, 0xf7, 0x2d, 0xe3, 0xbb, 0xc9, 0x12, 0xce, 0x10, + 0x1e, 0x67, 0xf2, 0x9d, 0xfa, 0x09, 0xd3, 0xca, 0x38, 0x56, 0xed, 0x3f, 0x0e, + 0xb3, 0x71, 0x34, 0xe0, 0xbb, 0xde, 0xd8, 0xad, 0x20, 0x3b, 0x23, 0x2a, 0x01, + 0xdd, 0xc4, 0xcd, 0xec, 0xec, 0x01, 0x37, 0xfe, 0x06, 0xb6, 0xbe, 0x3e, 0xd9, + 0xfb, 0x09, 0xc9, 0x58, 0x2e, 0xf2, 0x29, 0x7c, 0x3d, 0xe1, 0xa0, 0x26, 0xdc, + 0xf5, 0x34, 0xa1, 0x1f, 0x19, 0xb1, 0xe0, 0x1f, 0x7c, 0xfa, 0xde, 0xf2, 0x0d, + 0x10, 0xdb, 0x30, 0xf5, 0x0e, 0x9d, 0xdf, 0xfd, 0xed, 0x52, 0x20, 0x06, 0x0a, + 0xe3, 0xc9, 0x24, 0xe9, 0x0d, 0x52, 0xe1, 0xdf, 0x37, 0x48, 0xb3, 0xa4, 0x23, + 0xac, 0x37, 0x09, 0xd4, 0x24, 0xfa, 0x28, 0x7f, 0xcb, 0x0e, 0x17, 0x29, 0x0c, + 0xc4, 0xcf, 0xfa, 0xdb, 0xb5, 0xe9, 0xb8, 0x0e, 0x15, 0xb1, 0xfd, 0xe1, 0xd8, + 0x0b, 0xf3, 0x20, 0xe9, 0xff, 0xcc, 0x1f, 0xc4, 0xde, 0x08, 0x22, 0x38, 0xe0, + 0x00, 0xf4, 0x1a, 0x36, 0xaa, 0x34, 0x1d, 0x29, 0xcf, 0x2f, 0xea, 0x05, 0x30, + 0x4e, 0x03, 0xdf, 0x07, 0xc9, 0xba, 0x52, 0xf3, 0x39, 0x1f, 0xfa, 0xc2, 0x47, + 0xba, 0xc5, 0xef, 0xf9, 0xf9, 0x2c, 0xfd, 0xf4, 0xf9, 0xe2, 0x24, 0xf8, 0x15, + 0x10, 0xf5, 0x4d, 0xf5, 0x08, 0x3c, 0xe9, 0xf9, 0xc2, 0x0f, 0xba, 0x3f, 0xe3, + 0x81, 0x37, 0xf5, 0x21, 0xb9, 0x3d, 0x10, 0x0a, 0xb9, 0x08, 0x11, 0xf8, 0x15, + 0x12, 0x4b, 0x27, 0xe1, 0xe4, 0xdd, 0xe1, 0x30, 0xd9, 0x76, 0xfd, 0xf2, 0x0f, + 0x09, 0xf5, 0xef, 0x27, 0xfc, 0x90, 0x0a, 0xf5, 0x12, 0xd0, 0x39, 0xf4, 0x0b, + 0xfa, 0x11, 0x06, 0xfa, 0x0b, 0x51, 0x38, 0xe3, 0x36, 0xdd, 0x9c, 0xe8, 0xff, + 0x22, 0x28, 0xaf, 0x26, 0x11, 0xd0, 0xc6, 0xf1, 0x0d, 0xeb, 0x25, 0xce, 0xac, + 0x33, 0x0b, 0xd3, 0x0f, 0xc0, 0xd8, 0xe5, 0x47, 0xcd, 0xb4, 0x59, 0xa6, 0x5b, + 0xff, 0xdb, 0xf8, 0xed, 0xb7, 0x24, 0x37, 0x07, 0x96, 0xee, 0x7f, 0xb8, 0xe6, + 0x1e, 0xa0, 0xc6, 0x3f, 0xc2, 0x48, 0x8c, 0x33, 0x23, 0xe3, 0xea, 0xc5, 0xf1, + 0xf0, 0x28, 0x07, 0x3b, 0x2c, 0xbc, 0x10, 0xc3, 0x3a, 0xf5, 0xdf, 0x35, 0x17, + 0x92, 0x58, 0xc3, 0xf7, 0x50, 0xdf, 0xc0, 0xaf, 0x02, 0xfd, 0x1b, 0xed, 0x05, + 0x3c, 0xf3, 0x08, 0x19, 0x67, 0xd3, 0xe9, 0x39, 0xbf, 0xc1, 0xc2, 0x24, 0xe1, + 0xbc, 0xb0, 0x17, 0xd6, 0xe1, 0x3d, 0x26, 0xc6, 0x34, 0x23, 0xcd, 0xf5, 0xfd, + 0x0c, 0x0f, 0x33, 0x03, 0x09, 0xeb, 0xb3, 0x08, 0x12, 0xfc, 0xfa, 0x00, 0xe9, + 0x39, 0xc3, 0xf3, 0xf3, 0xfe, 0xb7, 0x19, 0x25, 0x17, 0xee, 0xe4, 0xe9, 0xdd, + 0xd4, 0xd0, 0xd4, 0x1c, 0xd8, 0x22, 0x36, 0x1e, 0x1e, 0x7f, 0x2e, 0x18, 0x29, + 0x2e, 0x14, 0x41, 0xed, 0xed, 0x3c, 0x01, 0xd1, 0x1b, 0x14, 0xc5, 0x30, 0xdb, + 0xf9, 0x22, 0xc5, 0x14, 0x10, 0x0f, 0x31, 0x03, 0x3e, 0xca, 0xe3, 0xff, 0x1e, + 0xf7, 0xe7, 0x2d, 0x33, 0x24, 0x17, 0xe6, 0x11, 0x0f, 0xd4, 0xd1, 0x21, 0x0c, + 0x18, 0xfa, 0x1a, 0x52, 0x24, 0x18, 0x49, 0xf6, 0x1e, 0xf4, 0xe7, 0x18, 0x25, + 0x38, 0xf7, 0xf2, 0xdd, 0x44, 0x46, 0x62, 0x51, 0xd5, 0x3d, 0x12, 0x14, 0x19, + 0x1e, 0x5a, 0x03, 0xe5, 0x18, 0x03, 0x11, 0x11, 0x17, 0xe8, 0xfa, 0x1c, 0x3a, + 0xfc, 0x05, 0x2a, 0xf5, 0x06, 0xf4, 0xd2, 0x28, 0x1f, 0xe8, 0xd3, 0x16, 0x21, + 0x32, 0xfa, 0x07, 0x54, 0xfc, 0x00, 0xe4, 0x53, 0x17, 0xf1, 0xf3, 0xf6, 0x25, + 0x17, 0x25, 0x4c, 0xfa, 0x1a, 0x07, 0x0e, 0xca, 0xe1, 0xea, 0x08, 0xde, 0xc8, + 0xdf, 0xc9, 0x13, 0x0a, 0x26, 0x02, 0x23, 0xf9, 0x1c, 0xff, 0xcb, 0xa1, 0xfc, + 0x29, 0xdd, 0x06, 0xcf, 0x49, 0x23, 0x5e, 0x29, 0xfd, 0x7a, 0xf3, 0x03, 0x0f, + 0x1f, 0xe1, 0xe7, 0xb5, 0x26, 0x31, 0xc4, 0x2f, 0x97, 0xbf, 0x20, 0x1d, 0x18, + 0x23, 0xf7, 0x09, 0x15, 0x11, 0x81, 0x2f, 0x3e, 0x66, 0xf4, 0xe9, 0xc3, 0xfb, + 0xe9, 0x49, 0xcb, 0xce, 0x0a, 0xf9, 0xa4, 0xf3, 0xc8, 0x44, 0x14, 0xec, 0x21, + 0x06, 0xff, 0xa9, 0xea, 0x16, 0xfb, 0xd0, 0x17, 0x14, 0xc8, 0x36, 0x1b, 0xbd, + 0xe3, 0x2e, 0xe7, 0xf4, 0x0c, 0x2b, 0x05, 0xa9, 0xcf, 0x45, 0xf0, 0x9e, 0x13, + 0x19, 0x60, 0xbc, 0xea, 0x1a, 0x5a, 0xd9, 0x41, 0x72, 0x31, 0x02, 0x67, 0xfd, + 0x1e, 0xdf, 0x15, 0x2c, 0x41, 0x0f, 0x08, 0x14, 0x10, 0xdb, 0xfc, 0xda, 0x50, + 0x0f, 0x19, 0x02, 0x08, 0xf9, 0x31, 0x04, 0xce, 0xb8, 0x23, 0xc6, 0x08, 0x07, + 0x26, 0xfd, 0xee, 0x05, 0xf9, 0xd2, 0xeb, 0x1e, 0xbd, 0x01, 0xe4, 0xa2, 0xcd, + 0xd4, 0xd3, 0xe8, 0x70, 0xec, 0x0e, 0x06, 0xd8, 0xd5, 0xcb, 0x02, 0x1f, 0xc8, + 0xfc, 0xc1, 0x16, 0x0e, 0x18, 0x2e, 0x05, 0xf2, 0xf4, 0xec, 0xfe, 0x3a, 0xfb, + 0x02, 0x0b, 0xfa, 0x36, 0x92, 0x01, 0x20, 0xef, 0xed, 0xec, 0x23, 0x3b, 0x11, + 0x1f, 0xd3, 0xfa, 0x11, 0xa6, 0xe2, 0x9b, 0xda, 0x28, 0xf0, 0x08, 0xa9, 0x73, + 0xf4, 0xd7, 0xd3, 0xbf, 0xe6, 0xef, 0x33, 0xad, 0xc9, 0x1f, 0x25, 0x19, 0x3f, + 0x0d, 0x25, 0xe2, 0xee, 0x13, 0xf8, 0x2f, 0xbf, 0x04, 0x09, 0x7f, 0xf1, 0x2a, + 0xfa, 0xd2, 0x2a, 0x20, 0x04, 0x47, 0xfe, 0x10, 0x09, 0xae, 0x17, 0x41, 0xd6, + 0x46, 0x2f, 0xea, 0x16, 0x34, 0x12, 0xea, 0x0d, 0x4c, 0x27, 0xf6, 0x05, 0x87, + 0x2b, 0x01, 0x10, 0xe8, 0x1a, 0xdc, 0x0d, 0xf8, 0x03, 0xee, 0x26, 0x44, 0x18, + 0xce, 0x14, 0xf1, 0x35, 0x1c, 0x11, 0xe8, 0x31, 0xfa, 0xdc, 0x03, 0x05, 0x33, + 0x01, 0xd0, 0x03, 0x21, 0xc7, 0x26, 0x2f, 0x1a, 0x0e, 0x23, 0x2b, 0xee, 0x39, + 0x1c, 0xe9, 0xda, 0x55, 0x10, 0x01, 0x09, 0x13, 0x09, 0xf6, 0x25, 0x08, 0x0e, + 0x27, 0x19, 0xbd, 0x06, 0x12, 0x30, 0xee, 0xe7, 0x38, 0x05, 0x27, 0x20, 0x0f, + 0x41, 0xd1, 0x08, 0x33, 0x51, 0x51, 0x17, 0x0f, 0x2b, 0x3f, 0x0b, 0xcb, 0x01, + 0xeb, 0x28, 0x1c, 0xde, 0xf7, 0x4b, 0x14, 0x01, 0x10, 0x45, 0x0e, 0xe6, 0x0f, + 0x00, 0xf1, 0xf3, 0xff, 0x13, 0x16, 0x06, 0x29, 0xc4, 0xdf, 0x4d, 0x5f, 0xe7, + 0x0e, 0xf9, 0xff, 0xeb, 0x19, 0x27, 0x59, 0xe6, 0x0c, 0x04, 0x7f, 0x13, 0xe0, + 0x09, 0x28, 0x23, 0x61, 0xf6, 0xe7, 0x16, 0xc8, 0x36, 0x19, 0x43, 0x02, 0xfe, + 0xb9, 0xe2, 0x05, 0xe8, 0xf5, 0x26, 0x05, 0xcd, 0x31, 0x28, 0xfc, 0x21, 0x18, + 0xfc, 0xd1, 0x23, 0xe7, 0x14, 0xc8, 0x25, 0xea, 0xd3, 0xf6, 0xee, 0x24, 0x1f, + 0x0d, 0xe8, 0xb8, 0x01, 0x30, 0xe1, 0xe6, 0x0c, 0x0a, 0x03, 0x3d, 0x3d, 0x15, + 0x3d, 0xf9, 0x19, 0xff, 0xc4, 0xf2, 0x13, 0xea, 0xe6, 0x3a, 0xf9, 0x29, 0xdb, + 0x5a, 0xe6, 0xdc, 0x18, 0xff, 0xe2, 0x44, 0x15, 0x1d, 0xf6, 0xf6, 0x24, 0xcf, + 0xf1, 0x08, 0xe0, 0x54, 0x0d, 0x1b, 0x3a, 0xf9, 0x04, 0xd5, 0x35, 0xfd, 0x3a, + 0x5b, 0xd4, 0xf7, 0x51, 0xe4, 0xd8, 0x1c, 0xf6, 0x11, 0xdf, 0xd9, 0x07, 0xd1, + 0xfe, 0xff, 0x04, 0xff, 0xfd, 0x02, 0xff, 0x0f, 0x7f, 0xe9, 0xe6, 0x1b, 0x0c, + 0x0b, 0x35, 0xf9, 0x12, 0x66, 0xe8, 0x2e, 0xe8, 0x6a, 0x15, 0x09, 0xfb, 0xfc, + 0xd7, 0xec, 0xf3, 0x05, 0x0b, 0xfb, 0x4a, 0x0c, 0x32, 0xe7, 0x10, 0xe7, 0x01, + 0xe3, 0xca, 0x0c, 0xd6, 0xf1, 0xed, 0x37, 0x13, 0xea, 0xff, 0x01, 0xbd, 0x1b, + 0x00, 0x15, 0xf3, 0xf4, 0xee, 0xff, 0x17, 0xf7, 0x34, 0x01, 0xff, 0x2a, 0x0c, + 0x1f, 0x10, 0xe0, 0xfc, 0x16, 0xfe, 0x06, 0xee, 0x08, 0xe2, 0xcd, 0x06, 0xf2, + 0xf6, 0xe4, 0xea, 0xeb, 0xd6, 0xbe, 0x1f, 0x16, 0xe4, 0xf0, 0xce, 0xfd, 0x05, + 0x0b, 0x0c, 0x03, 0xf3, 0x03, 0x18, 0x06, 0xf6, 0xe2, 0x1e, 0x00, 0x07, 0xe5, + 0x13, 0xf7, 0xea, 0x18, 0xf8, 0x27, 0xcf, 0xd3, 0xda, 0xe4, 0x0b, 0x20, 0xd4, + 0x03, 0x33, 0xf5, 0x18, 0x16, 0x7f, 0xe2, 0xf9, 0x18, 0xcb, 0x2e, 0xe4, 0x05, + 0xed, 0x19, 0xf7, 0x15, 0x14, 0xea, 0x34, 0xe8, 0x19, 0xf6, 0x09, 0x0a, 0xfb, + 0xbd, 0xfe, 0xeb, 0x01, 0x03, 0x44, 0x1a, 0x11, 0xc7, 0xb3, 0xf6, 0x19, 0x35, + 0xf7, 0x07, 0xeb, 0x20, 0x1f, 0x12, 0xf4, 0xf7, 0xdf, 0x12, 0xff, 0xda, 0x2d, + 0xfb, 0xc2, 0xbc, 0x2d, 0x07, 0x33, 0xdd, 0xfa, 0xf8, 0x33, 0xef, 0x10, 0x2b, + 0xe4, 0x1b, 0xc5, 0x65, 0xb2, 0x4a, 0x06, 0x0f, 0xb7, 0x6a, 0x56, 0x55, 0xe2, + 0xf7, 0xbd, 0x16, 0xdd, 0x10, 0xf2, 0xd3, 0xe9, 0x55, 0x53, 0x03, 0x7f, 0xc0, + 0xe1, 0xf6, 0xf8, 0x22, 0x13, 0x06, 0x4d, 0xdc, 0x1a, 0xe9, 0xfa, 0x37, 0xf0, + 0xaa, 0xc3, 0xe9, 0x08, 0xd3, 0x27, 0xcc, 0x06, 0x1e, 0xd9, 0xef, 0xf3, 0x15, + 0xdc, 0x18, 0x27, 0x32, 0xdd, 0x03, 0xfb, 0xed, 0x0e, 0x19, 0xc3, 0xd6, 0xed, + 0xca, 0xf7, 0xb1, 0x08, 0xf2, 0x04, 0xf8, 0xd4, 0x1b, 0xe4, 0x15, 0x5b, 0xd0, + 0xab, 0xd1, 0x41, 0xe4, 0x12, 0xcb, 0xc9, 0x0d, 0xf4, 0xf6, 0xc2, 0x0f, 0xcc, + 0xdd, 0x9e, 0x02, 0x2b, 0xdd, 0x1d, 0xf6, 0xf8, 0xec, 0xcb, 0xea, 0xef, 0xf3, + 0x0d, 0x2b, 0x1b, 0x0f, 0xfe, 0xfd, 0xe9, 0x55, 0x32, 0x49, 0xca, 0x04, 0x29, + 0xe9, 0x3f, 0xca, 0x09, 0x59, 0x05, 0xd7, 0xf5, 0x14, 0xe0, 0xfd, 0x7f, 0x02, + 0xd6, 0x08, 0xf0, 0xd8, 0xfc, 0xae, 0xea, 0xce, 0xeb, 0x04, 0xfa, 0x55, 0xe0, + 0x19, 0x0b, 0xd3, 0xc7, 0xaf, 0x0a, 0xf3, 0xcc, 0xff, 0x2e, 0x0d, 0x16, 0x10, + 0x00, 0xe0, 0xb5, 0xe4, 0xae, 0xba, 0x20, 0x02, 0xe6, 0x19, 0xd9, 0xfd, 0xd6, + 0xf8, 0x02, 0x32, 0xeb, 0xfa, 0xc4, 0xe4, 0xaf, 0x17, 0xcd, 0xfe, 0x02, 0x1d, + 0x11, 0xd8, 0x53, 0x28, 0x6a, 0x44, 0x10, 0xfa, 0xde, 0xee, 0xef, 0x2d, 0x30, + 0xc8, 0xa9, 0x49, 0xdc, 0x14, 0xf9, 0xee, 0xff, 0xf1, 0x3e, 0xf5, 0xec, 0x51, + 0xf6, 0xea, 0xde, 0xc4, 0x28, 0xb0, 0x33, 0x2e, 0x4a, 0xf3, 0x08, 0x01, 0x36, + 0x10, 0x42, 0x01, 0x09, 0xf7, 0xfd, 0x73, 0xbb, 0x33, 0xd0, 0xbf, 0x0e, 0x30, + 0x08, 0xf5, 0xf6, 0x64, 0xd4, 0x1d, 0xc0, 0x3b, 0x13, 0xbb, 0x1b, 0xe7, 0x70, + 0xec, 0x36, 0x20, 0xb3, 0xc1, 0x50, 0x09, 0xb9, 0xf9, 0x4f, 0x72, 0x62, 0x76, + 0x1c, 0x09, 0x22, 0x3c, 0xf1, 0x11, 0xb4, 0x26, 0xe5, 0x26, 0xff, 0xbd, 0x09, + 0xb1, 0x06, 0xe8, 0x31, 0x43, 0xed, 0xf4, 0x33, 0xae, 0xc8, 0x40, 0x46, 0xde, + 0xa9, 0x1e, 0x07, 0xc2, 0x7e, 0xe0, 0x33, 0x5b, 0xa9, 0xee, 0xd7, 0xd5, 0x12, + 0xa8, 0xb4, 0x96, 0xbb, 0xd7, 0xff, 0x2d, 0xbe, 0xae, 0xd4, 0x82, 0xdd, 0x14, + 0xf7, 0xd8, 0x50, 0x00, 0x35, 0x27, 0xbc, 0xd6, 0xef, 0x0f, 0x04, 0x97, 0x1d, + 0x13, 0x09, 0xfd, 0xf8, 0xc4, 0xd6, 0xee, 0x09, 0xbc, 0x12, 0x19, 0x16, 0xdf, + 0x9a, 0xcd, 0x01, 0xfc, 0x0c, 0x9f, 0x34, 0xbe, 0x5a, 0xa0, 0x1b, 0x2a, 0xfd, + 0xd3, 0x2b, 0x3b, 0xb3, 0x7f, 0x05, 0xc6, 0xec, 0x33, 0x00, 0xb2, 0xf9, 0xe6, + 0x38, 0xf9, 0xcd, 0xe7, 0x6c, 0x74, 0xd7, 0xcc, 0x76, 0x27, 0x19, 0x0a, 0x0f, + 0x54, 0x1f, 0xc4, 0xb4, 0x09, 0xbf, 0xd0, 0x5b, 0x54, 0x07, 0x1a, 0x11, 0xd9, + 0x15, 0x23, 0x17, 0xc2, 0x1f, 0x20, 0xdd, 0xf3, 0xe5, 0xdb, 0xf2, 0xbf, 0x06, + 0xdc, 0xbe, 0xe4, 0xe8, 0x3a, 0xab, 0xbd, 0xf4, 0x67, 0x1b, 0x4a, 0xc7, 0x17, + 0xd9, 0xc2, 0x4d, 0xa9, 0xd6, 0xd8, 0x03, 0xfb, 0xf0, 0xdf, 0xea, 0x1e, 0xb6, + 0xdd, 0xd3, 0xd0, 0xa6, 0x00, 0xca, 0x12, 0xfe, 0x13, 0xf8, 0x0b, 0x17, 0xf1, + 0x31, 0xe1, 0x46, 0xe7, 0x09, 0xc4, 0xec, 0xc1, 0xc9, 0x4a, 0xf0, 0x0e, 0x31, + 0xcf, 0xe1, 0x45, 0xc0, 0x37, 0x53, 0x1d, 0xc5, 0x0e, 0x32, 0xe6, 0xff, 0x1e, + 0x81, 0x02, 0x34, 0xba, 0xff, 0xf9, 0x1c, 0x30, 0xb2, 0x40, 0x59, 0x0c, 0x09, + 0x26, 0xa5, 0xee, 0x0f, 0xfc, 0x13, 0xb5, 0x12, 0xfb, 0x2a, 0xdd, 0xf7, 0x42, + 0xe4, 0xe3, 0xd0, 0xe8, 0xda, 0xd3, 0xda, 0x08, 0xe5, 0xbf, 0x3a, 0xdf, 0xc2, + 0x06, 0xe7, 0xc6, 0x2f, 0x00, 0xe8, 0xef, 0xec, 0xd7, 0xf0, 0xae, 0x4e, 0xdd, + 0x0d, 0xe2, 0xb2, 0xc2, 0xdf, 0x5c, 0x16, 0xc0, 0x59, 0xfc, 0xbe, 0xdc, 0x16, + 0x64, 0xf1, 0xef, 0x1c, 0xf6, 0x08, 0xc6, 0x16, 0x7f, 0xe4, 0x5b, 0x0b, 0xf9, + 0xf0, 0xeb, 0xd5, 0xf6, 0x2d, 0x05, 0x19, 0xf1, 0x10, 0xb3, 0xe9, 0xd2, 0xed, + 0xfd, 0x20, 0x07, 0xe5, 0x38, 0xf3, 0x0b, 0x64, 0xbf, 0xf5, 0xf8, 0xc5, 0x08, + 0x25, 0xeb, 0xfb, 0x6a, 0xc9, 0xbb, 0xe9, 0x30, 0xeb, 0x39, 0xc3, 0xff, 0x13, + 0xe8, 0x11, 0xe5, 0x39, 0xc1, 0x64, 0xc9, 0x0d, 0x32, 0x07, 0xd1, 0xdd, 0x00, + 0x39, 0xf0, 0x00, 0x1f, 0x13, 0x27, 0xe3, 0x02, 0x4a, 0xbe, 0x12, 0xfc, 0xfd, + 0x15, 0xf1, 0xe1, 0x11, 0x26, 0x3c, 0xe1, 0x10, 0x4b, 0x6a, 0xf0, 0xc8, 0xe8, + 0x47, 0xfa, 0x31, 0x1c, 0xcd, 0xd5, 0xce, 0x59, 0xe5, 0xf3, 0xd5, 0x35, 0xcf, + 0xd9, 0xe4, 0xfd, 0xc1, 0xd2, 0xbf, 0x4e, 0xe9, 0x0f, 0xe5, 0xcc, 0x10, 0xe2, + 0xab, 0x17, 0xd9, 0xfa, 0xd4, 0x4d, 0x19, 0x04, 0x02, 0x03, 0xad, 0xf5, 0x3b, + 0xd8, 0xed, 0x4c, 0xc4, 0xe5, 0xd7, 0x0b, 0xec, 0xeb, 0x28, 0x4b, 0xed, 0xcf, + 0x45, 0xca, 0xc3, 0x04, 0x1e, 0x39, 0x25, 0xc0, 0x39, 0xfb, 0x21, 0x20, 0x05, + 0x1e, 0x35, 0xfd, 0xcc, 0x2f, 0xdd, 0x15, 0x44, 0xfb, 0xf5, 0xe5, 0xbe, 0x0f, + 0xe1, 0x23, 0x19, 0xdd, 0x11, 0x20, 0xd9, 0xe3, 0x08, 0xfb, 0x0f, 0x07, 0x2a, + 0x15, 0xf2, 0x13, 0xbd, 0x2b, 0xf3, 0x19, 0xf5, 0x81, 0xe5, 0x16, 0xd1, 0x3d, + 0xbf, 0x09, 0x1c, 0x16, 0xfe, 0xd6, 0xd8, 0x3f, 0x2c, 0xff, 0x16, 0xf8, 0xfa, + 0x5a, 0xe0, 0x05, 0xb9, 0x00, 0xcb, 0xb1, 0xf1, 0x1e, 0xcf, 0x3b, 0xf7, 0xb9, + 0xe6, 0xfb, 0x0c, 0xef, 0x24, 0x19, 0xd3, 0xd8, 0xbf, 0x36, 0x5b, 0x04, 0xf6, + 0xc8, 0xdf, 0x19, 0x06, 0xd5, 0x1c, 0x08, 0x0d, 0xe7, 0xdd, 0xea, 0xbf, 0xec, + 0xea, 0x70, 0xe3, 0xcd, 0xba, 0x26, 0xe5, 0x08, 0x7f, 0xd1, 0x0d, 0x09, 0x12, + 0x0a, 0xc1, 0xed, 0xf8, 0xfd, 0xf5, 0x33, 0x01, 0x0f, 0xde, 0xcc, 0xf6, 0xb5, + 0x2c, 0xea, 0xfa, 0xe3, 0x07, 0x0e, 0x4e, 0x28, 0x04, 0xd2, 0xda, 0xfe, 0xdf, + 0x21, 0xdd, 0xe7, 0x4a, 0x00, 0xcb, 0x99, 0x10, 0x28, 0xed, 0x0e, 0xee, 0xef, + 0x0a, 0xeb, 0xd9, 0x50, 0xf8, 0xcb, 0x3f, 0x01, 0xfe, 0x0c, 0xd6, 0x00, 0x16, + 0x30, 0x0b, 0xeb, 0xf3, 0x20, 0x12, 0x07, 0x50, 0x1e, 0x05, 0xc0, 0x20, 0xdf, + 0xdb, 0x23, 0xce, 0xe5, 0xeb, 0x25, 0xdf, 0xe9, 0xe9, 0xcc, 0xf3, 0x2e, 0x1d, + 0xf1, 0x1b, 0x04, 0x4a, 0x41, 0x73, 0xa9, 0x65, 0x01, 0x2d, 0xbb, 0xee, 0x0f, + 0xd4, 0xb7, 0x4c, 0xb2, 0x34, 0xeb, 0x05, 0xa4, 0xc1, 0x10, 0xd3, 0xe2, 0x9e, + 0x90, 0x27, 0x29, 0xf9, 0xc5, 0x2b, 0xee, 0xc2, 0xe6, 0xff, 0xe6, 0x35, 0xfe, + 0xcf, 0x3a, 0xe0, 0xea, 0x37, 0xd9, 0x06, 0xf4, 0xbe, 0x42, 0x42, 0xe0, 0xe4, + 0xe7, 0x3f, 0x35, 0x4c, 0x0c, 0xe4, 0xb3, 0xaf, 0x1f, 0xbc, 0xcb, 0x4d, 0x05, + 0x10, 0xf9, 0xf4, 0x7f, 0x1b, 0x0e, 0x26, 0xef, 0x16, 0x02, 0xfb, 0x2a, 0x12, + 0x48, 0x1d, 0x07, 0xde, 0x95, 0xda, 0x37, 0x3f, 0xdd, 0x1f, 0x2a, 0x0e, 0xfe, + 0xd9, 0xf6, 0xd3, 0x00, 0x13, 0xf2, 0xd6, 0x43, 0x0a, 0x0c, 0xbf, 0xcf, 0x3f, + 0xf5, 0xe6, 0xfb, 0xec, 0x01, 0xf5, 0xd2, 0x18, 0x1c, 0x44, 0xcf, 0xfd, 0x31, + 0xcc, 0x3f, 0x12, 0x10, 0x1e, 0x04, 0xa2, 0x4f, 0xcd, 0x12, 0x10, 0xb6, 0xc8, + 0x40, 0x1b, 0x25, 0x17, 0xb9, 0xff, 0xdd, 0x0c, 0xfc, 0xe1, 0x1b, 0x0f, 0xd7, + 0xd7, 0x3b, 0xfe, 0x02, 0xbc, 0xda, 0xdf, 0xaf, 0xd7, 0xd8, 0xe8, 0x44, 0xd1, + 0x7b, 0xee, 0x27, 0xca, 0xd1, 0x10, 0xce, 0x8f, 0x3f, 0xcc, 0x36, 0x0f, 0x23, + 0xf1, 0xff, 0x0e, 0xd3, 0xc3, 0x1f, 0xfe, 0x35, 0x09, 0x64, 0xbd, 0xf9, 0x0c, + 0x49, 0xcc, 0x0e, 0x26, 0x07, 0x1e, 0xd8, 0x10, 0xd8, 0xef, 0x2f, 0xda, 0x40, + 0x02, 0xa9, 0xf9, 0xd2, 0xf7, 0xf8, 0xf5, 0x1c, 0x4f, 0x0b, 0x0e, 0x2b, 0x26, + 0xf3, 0x78, 0x4b, 0x35, 0x2d, 0xf7, 0x3b, 0xe1, 0x48, 0x8c, 0x00, 0x12, 0x01, + 0x81, 0xf9, 0xe9, 0x2e, 0x2d, 0xe5, 0x40, 0x15, 0x55, 0x12, 0xe0, 0x17, 0x0b, + 0x28, 0xd3, 0xab, 0xf7, 0x04, 0xaf, 0x67, 0x02, 0x69, 0xef, 0x25, 0x10, 0xfa, + 0xec, 0xcb, 0x2a, 0x03, 0x1b, 0xef, 0xe7, 0x0d, 0x04, 0x55, 0xfc, 0x2b, 0x20, + 0xbc, 0xaa, 0x2e, 0xde, 0xd5, 0x59, 0x1e, 0x19, 0xd8, 0x04, 0xdd, 0xeb, 0x54, + 0x01, 0x04, 0x4a, 0x1c, 0xe1, 0x15, 0x27, 0x35, 0xdd, 0xc1, 0xe3, 0x2e, 0x04, + 0x2d, 0x0e, 0xd2, 0xfa, 0xd0, 0x38, 0xf0, 0xd7, 0xaf, 0x4c, 0xf5, 0x08, 0x14, + 0x03, 0x2a, 0xcf, 0x07, 0x1a, 0x08, 0xf9, 0xc1, 0x13, 0xb4, 0xde, 0x27, 0x7f, + 0xc9, 0x34, 0x37, 0x24, 0xe6, 0x3c, 0xd8, 0xaf, 0x06, 0x0c, 0x19, 0xbe, 0x2a, + 0xf4, 0xbe, 0x54, 0x17, 0xdf, 0xfe, 0x33, 0xda, 0x53, 0x0e, 0x4b, 0xe8, 0xf0, + 0xaf, 0x1a, 0x0b, 0x00, 0xc8, 0xcd, 0x56, 0x10, 0xe6, 0x51, 0x1b, 0x4c, 0xe8, + 0xd6, 0x14, 0xd8, 0x31, 0x18, 0xd0, 0x07, 0xde, 0xe5, 0xea, 0x11, 0xdb, 0xe3, + 0x5d, 0x26, 0x5f, 0x09, 0xc5, 0x28, 0x31, 0x15, 0x0e, 0x59, 0x09, 0xf6, 0x5a, + 0xee, 0xab, 0x26, 0x29, 0x3b, 0x31, 0xd7, 0x21, 0xea, 0x1c, 0x52, 0xe5, 0x25, + 0x18, 0xc1, 0xe0, 0xf0, 0x18, 0x30, 0xf8, 0xdb, 0xd2, 0x34, 0x08, 0x29, 0xff, + 0xe0, 0xec, 0x0c, 0x44, 0xf3, 0xde, 0xec, 0x16, 0xbd, 0x06, 0xf3, 0x0f, 0x04, + 0xe4, 0x15, 0x28, 0xf2, 0xea, 0x3a, 0xb9, 0x16, 0xf7, 0x49, 0x10, 0x01, 0xca, + 0x44, 0x14, 0xe9, 0x2e, 0x17, 0xea, 0x37, 0xdb, 0x05, 0x30, 0x06, 0x7f, 0xfe, + 0xff, 0x24, 0xfb, 0xeb, 0x2c, 0x2a, 0xe5, 0x20, 0xf9, 0xf4, 0xe9, 0x09, 0xf4, + 0xdc, 0xe0, 0x36, 0xed, 0xef, 0xfe, 0x08, 0xfb, 0x58, 0xe5, 0xee, 0x11, 0xb6, + 0x17, 0x49, 0xfa, 0xfd, 0x27, 0xc5, 0x01, 0xdb, 0xa4, 0xef, 0x1a, 0xe5, 0x21, + 0x39, 0x0b, 0xf9, 0xf1, 0x2e, 0xf6, 0x10, 0x2e, 0x08, 0xf9, 0x22, 0xd7, 0xc4, + 0x16, 0x0f, 0xfb, 0xf7, 0x2c, 0x0c, 0x09, 0xdc, 0xdf, 0xff, 0xe9, 0xe2, 0xf9, + 0x09, 0x13, 0x10, 0xc9, 0xe5, 0x25, 0x0a, 0xd0, 0x26, 0xfd, 0xff, 0xee, 0xef, + 0x0d, 0x29, 0x10, 0xec, 0x0d, 0xc8, 0xfb, 0x09, 0xed, 0xfe, 0xe6, 0xfc, 0x20, + 0xf4, 0xfb, 0x09, 0xce, 0x08, 0xf9, 0xdc, 0xe7, 0x6b, 0xe1, 0xf0, 0x02, 0x03, + 0xa8, 0x25, 0x22, 0x13, 0x63, 0x1f, 0x65, 0xf3, 0xf6, 0xff, 0x15, 0x08, 0xdb, + 0x09, 0xed, 0x78, 0xf4, 0x03, 0x11, 0x12, 0xec, 0xfe, 0xea, 0xe8, 0xe6, 0x09, + 0x7f, 0x39, 0xfc, 0x00, 0x0c, 0xf0, 0x0f, 0x20, 0xff, 0x05, 0x09, 0xe4, 0x08, + 0xf2, 0x0b, 0x02, 0xde, 0x1a, 0x32, 0xf3, 0x10, 0x0f, 0xde, 0xdb, 0xd7, 0xf3, + 0x2a, 0xf4, 0x29, 0x34, 0x1d, 0xe2, 0x2c, 0xd4, 0xf5, 0x14, 0x09, 0x0f, 0x35, + 0x00, 0xba, 0x04, 0x0c, 0x0d, 0xe0, 0x41, 0x01, 0xe0, 0x55, 0x58, 0x1d, 0xf3, + 0x4f, 0xfb, 0xdc, 0xfc, 0xf5, 0x41, 0x0f, 0x0f, 0x2e, 0xeb, 0x2a, 0xff, 0x22, + 0xb9, 0xe3, 0xe8, 0xfa, 0xe6, 0x26, 0xee, 0x3a, 0x17, 0x2b, 0xf4, 0x21, 0x07, + 0x28, 0xb9, 0x28, 0x81, 0xad, 0xf8, 0xf2, 0xc5, 0xb2, 0x1c, 0x36, 0x4f, 0xe2, + 0x41, 0x2e, 0xd3, 0xc6, 0xf3, 0x6a, 0xc0, 0x02, 0x96, 0x09, 0xd5, 0x04, 0xb4, + 0x3f, 0xe8, 0x17, 0x09, 0x23, 0xff, 0xf0, 0xf9, 0xe0, 0x04, 0x0e, 0x2d, 0xc8, + 0x23, 0x56, 0xd5, 0x15, 0x09, 0xe0, 0xcb, 0xc5, 0x36, 0x4d, 0xcb, 0xcd, 0x0f, + 0x3f, 0xfa, 0x69, 0x0d, 0x5f, 0x29, 0x27, 0xf2, 0xae, 0x38, 0xeb, 0x1f, 0x34, + 0xde, 0x3e, 0x24, 0x13, 0xf5, 0xf0, 0x06, 0xb5, 0xe8, 0xf6, 0xf4, 0x18, 0xbd, + 0x12, 0xe9, 0x22, 0x22, 0xf2, 0xcf, 0x2b, 0xe0, 0x74, 0x06, 0xd5, 0xc9, 0xea, + 0xe6, 0xbf, 0xfe, 0xec, 0xf7, 0xf5, 0xe6, 0xcb, 0x03, 0xfe, 0xfc, 0x67, 0xfd, + 0xae, 0x2b, 0x25, 0xd2, 0x64, 0x0d, 0xc3, 0x0e, 0x4d, 0x15, 0xf7, 0xcc, 0xea, + 0x0b, 0x16, 0x12, 0x1c, 0xec, 0xa2, 0x5f, 0x4b, 0x3b, 0x3c, 0xdf, 0x32, 0xe6, + 0xd8, 0xfe, 0x3b, 0xdf, 0x1d, 0x14, 0x60, 0x5b, 0x09, 0xd1, 0xb2, 0xf2, 0xbf, + 0x39, 0x2e, 0xf4, 0xe4, 0xf7, 0x28, 0x22, 0xf5, 0x01, 0xc0, 0x40, 0xc6, 0xe4, + 0xa3, 0x59, 0xd0, 0x07, 0xb9, 0xd6, 0x09, 0x05, 0xe8, 0xf7, 0x7f, 0x97, 0x18, + 0x28, 0x3c, 0xfe, 0x32, 0x54, 0x49, 0xec, 0xf9, 0x3f, 0x03, 0x0d, 0xbf, 0x0a, + 0xe3, 0xf9, 0xc8, 0xe0, 0xe9, 0xe9, 0xd2, 0x2d, 0xd8, 0x9b, 0x15, 0xeb, 0x29, + 0x78, 0x4d, 0x20, 0xc0, 0x07, 0x0c, 0x2c, 0xc5, 0xe7, 0xf1, 0xfc, 0x2d, 0x2f, + 0x02, 0xff, 0xfe, 0x39, 0x2c, 0x0d, 0xfa, 0x03, 0x00, 0x1b, 0x15, 0x49, 0x03, + 0xf6, 0x1f, 0x17, 0xee, 0x4b, 0x13, 0x9e, 0xe7, 0x04, 0xfe, 0x1e, 0x30, 0xf2, + 0x1c, 0xe0, 0xf3, 0xea, 0x63, 0xfa, 0x2a, 0x26, 0xec, 0xfb, 0xec, 0xfa, 0xcc, + 0xde, 0xb8, 0xf4, 0x16, 0xc1, 0x27, 0xf0, 0xf3, 0x12, 0x1a, 0x4d, 0xd2, 0x26, + 0x23, 0x1c, 0x08, 0x43, 0x08, 0x7f, 0xf5, 0xc7, 0xc6, 0xeb, 0xd9, 0x2b, 0x3a, + 0xe7, 0xfe, 0x10, 0xf6, 0xda, 0xfa, 0x07, 0xdf, 0x1c, 0x15, 0x13, 0xfe, 0x19, + 0xfe, 0x20, 0xf0, 0xd6, 0xf0, 0x02, 0xfa, 0x0f, 0x50, 0xe9, 0xf7, 0x1f, 0xeb, + 0xf7, 0x4c, 0x17, 0x23, 0x03, 0x10, 0x32, 0x26, 0xf8, 0xd5, 0x1e, 0x12, 0xf8, + 0xcd, 0xe9, 0xef, 0xe9, 0xe8, 0xf7, 0x12, 0xf6, 0xcd, 0x01, 0x04, 0x32, 0x1b, + 0x23, 0x00, 0x0a, 0x44, 0xee, 0xd7, 0x50, 0xff, 0xf3, 0x31, 0xe6, 0xe4, 0xde, + 0xf8, 0xd5, 0xe0, 0x10, 0xfe, 0x11, 0xfd, 0xe9, 0xe4, 0x53, 0x07, 0x0d, 0xea, + 0x2f, 0xd5, 0x09, 0xf4, 0x01, 0x03, 0x2d, 0xc1, 0x12, 0x1c, 0xf8, 0xf7, 0xe7, + 0x1c, 0xf7, 0xf1, 0x10, 0x00, 0x25, 0xb9, 0xee, 0xf0, 0x15, 0xec, 0xea, 0x42, + 0x18, 0xa7, 0x09, 0x37, 0x0c, 0xc7, 0x0f, 0xd6, 0xd7, 0x08, 0x79, 0x6e, 0xd7, + 0xf9, 0x25, 0x0c, 0xcb, 0x41, 0xdb, 0xe0, 0x73, 0x12, 0x0a, 0xd7, 0xd0, 0xc9, + 0x25, 0x39, 0x0f, 0x07, 0x21, 0xd4, 0xc9, 0xaf, 0x20, 0x07, 0xfc, 0xcc, 0xed, + 0x2f, 0xde, 0xf0, 0x66, 0x0f, 0x3b, 0x1d, 0xb0, 0xf4, 0x89, 0x33, 0xeb, 0x43, + 0x1e, 0xfe, 0xd0, 0x3c, 0x73, 0x26, 0xe9, 0x0e, 0x25, 0xf0, 0x25, 0xfa, 0xf2, + 0xd8, 0x7d, 0xf3, 0x1f, 0x06, 0x03, 0xf7, 0xc3, 0x1c, 0xfa, 0x47, 0x53, 0xd4, + 0x01, 0xb1, 0xd7, 0x30, 0x11, 0xd6, 0xcd, 0x39, 0x08, 0xa0, 0xe9, 0x3d, 0xf5, + 0xe6, 0xa9, 0x08, 0x3e, 0x2b, 0x0d, 0x30, 0x67, 0xac, 0x4e, 0x47, 0xfb, 0xd5, + 0xf3, 0xdb, 0x93, 0xff, 0x42, 0xd9, 0xfa, 0x2e, 0x01, 0x1f, 0x81, 0x1d, 0x06, + 0x51, 0xca, 0x51, 0xe4, 0x30, 0xe7, 0x1d, 0xf1, 0x13, 0x3b, 0xda, 0x20, 0x13, + 0x3d, 0x36, 0x30, 0xf8, 0xe6, 0xf2, 0x0d, 0x1b, 0x0b, 0x3a, 0xf9, 0xc9, 0x23, + 0x7f, 0x2d, 0xbb, 0xed, 0x04, 0xe5, 0x06, 0x2e, 0x19, 0x42, 0xc6, 0x40, 0xed, + 0x0b, 0xf9, 0x05, 0x07, 0xf7, 0x05, 0x08, 0x38, 0xcb, 0xed, 0xf0, 0xe2, 0xfc, + 0xb1, 0x59, 0xef, 0x20, 0x03, 0xde, 0x21, 0xf8, 0x3d, 0xe8, 0x15, 0xdd, 0x15, + 0x2a, 0xe8, 0xd8, 0x4a, 0x1d, 0x10, 0x28, 0xed, 0x0f, 0xcc, 0x04, 0x39, 0x40, + 0xd0, 0x04, 0xf0, 0xee, 0x0f, 0x04, 0x18, 0xe7, 0xc4, 0x16, 0x0b, 0xe5, 0x14, + 0x62, 0x13, 0x22, 0xec, 0x62, 0xd0, 0xfd, 0x1d, 0x78, 0xf1, 0xf7, 0xde, 0x3d, + 0xfc, 0xd8, 0x1f, 0xeb, 0x51, 0x07, 0xf8, 0x55, 0xf2, 0x42, 0xc7, 0xcb, 0xd4, + 0xf1, 0x02, 0xec, 0x28, 0xf9, 0xc7, 0x6d, 0xca, 0x23, 0xee, 0xd7, 0x0a, 0x38, + 0x0c, 0x08, 0xe2, 0xea, 0x08, 0xde, 0xfc, 0x26, 0x09, 0xea, 0x24, 0x1d, 0xe9, + 0x26, 0x15, 0x03, 0xf6, 0xfe, 0xf7, 0x01, 0x03, 0xde, 0x04, 0xea, 0xec, 0xe7, + 0x2f, 0xf7, 0x37, 0x02, 0x15, 0xc5, 0xe7, 0xd4, 0x30, 0x5c, 0xae, 0xf9, 0xef, + 0xf1, 0xb8, 0x02, 0x1b, 0xa5, 0x0f, 0xe4, 0xf8, 0xdf, 0xfd, 0xd4, 0x2f, 0xba, + 0x32, 0xa7, 0xdb, 0xf7, 0xca, 0x11, 0xb8, 0xd9, 0xe8, 0x16, 0xf2, 0xfa, 0x08, + 0xda, 0xfd, 0xf4, 0xb7, 0x40, 0xbf, 0xcb, 0x0b, 0x34, 0xf5, 0xcd, 0xf7, 0x9e, + 0x16, 0x07, 0x07, 0x0e, 0xf0, 0xc6, 0x27, 0x26, 0x33, 0x01, 0xd3, 0xc0, 0xaf, + 0xdf, 0xe0, 0x15, 0x04, 0x0b, 0xbe, 0xc0, 0xce, 0xc6, 0x1f, 0xdc, 0xd3, 0x0b, + 0xfa, 0xa9, 0x03, 0xf4, 0x4e, 0x0f, 0xb7, 0xed, 0x0a, 0xf6, 0x71, 0x81, 0x05, + 0xe5, 0xf0, 0x06, 0xd9, 0x06, 0x35, 0x1a, 0xaf, 0x05, 0x49, 0x08, 0xf1, 0xe5, + 0xdf, 0xf6, 0xb7, 0x56, 0xfd, 0xe4, 0x05, 0xe3, 0xc4, 0x30, 0xf0, 0x2a, 0xfc, + 0x1a, 0x8d, 0xb1, 0x16, 0x9b, 0x00, 0x48, 0xe2, 0x15, 0xf9, 0x04, 0xe8, 0xc8, + 0x30, 0xce, 0xe9, 0xf3, 0x03, 0x3f, 0xd1, 0x99, 0x15, 0x05, 0x77, 0x28, 0xc7, + 0xd4, 0xc0, 0x5a, 0xed, 0x07, 0xdf, 0xe3, 0xf2, 0xf0, 0xca, 0x74, 0x18, 0xc6, + 0x0d, 0xd1, 0xee, 0x93, 0x0f, 0x2a, 0x6a, 0xc3, 0x02, 0x1c, 0xff, 0xd3, 0x0b, + 0xc0, 0xa0, 0x35, 0x05, 0x37, 0xf2, 0x4a, 0x21, 0xe3, 0xbb, 0xb9, 0xcd, 0x1b, + 0x1f, 0xcb, 0x44, 0x14, 0xc5, 0x2d, 0x07, 0x09, 0xfc, 0x03, 0x10, 0xfd, 0xe9, + 0xe4, 0x17, 0xe7, 0xa8, 0x87, 0xe5, 0xee, 0x30, 0xe9, 0x05, 0x07, 0xca, 0x02, + 0x04, 0x25, 0x08, 0x49, 0xcc, 0xfd, 0xf2, 0x51, 0xe9, 0xdc, 0xbf, 0x31, 0xd2, + 0xf1, 0xf7, 0x29, 0x4f, 0xb4, 0x31, 0x5b, 0xcd, 0xf5, 0x50, 0x20, 0x5f, 0xe6, + 0x01, 0x13, 0x03, 0x03, 0xd2, 0x22, 0x7f, 0x43, 0x8b, 0x2a, 0xe0, 0xed, 0xd2, + 0x1d, 0xe2, 0xec, 0xdb, 0x05, 0x06, 0x66, 0xfe, 0x27, 0x03, 0xf4, 0xf2, 0x09, + 0x16, 0xca, 0xfa, 0xde, 0x05, 0xc9, 0xef, 0x07, 0x1f, 0x12, 0xe8, 0x41, 0x01, + 0x0a, 0xdd, 0xb2, 0xf3, 0xe7, 0x0e, 0x16, 0xfa, 0x0f, 0xdf, 0x2e, 0x31, 0xcd, + 0xf7, 0xbb, 0x03, 0x14, 0x1f, 0xed, 0x36, 0x34, 0xf4, 0xba, 0x7f, 0xd2, 0xba, + 0x16, 0x0b, 0x05, 0xf2, 0x1d, 0x36, 0xfc, 0xff, 0xee, 0xf5, 0x0f, 0x1a, 0xeb, + 0x0a, 0xfa, 0xe7, 0x27, 0x17, 0xf8, 0xec, 0x27, 0x15, 0x2d, 0xea, 0x06, 0xd8, + 0xdb, 0xad, 0xfb, 0xe4, 0x14, 0xeb, 0x08, 0x21, 0x01, 0xd4, 0x05, 0x0b, 0x3f, + 0xd7, 0xc7, 0x20, 0x0a, 0xf7, 0xd6, 0x0b, 0x67, 0xc1, 0x03, 0x05, 0x20, 0x0a, + 0xb5, 0xe0, 0x2d, 0xc1, 0xf6, 0xd2, 0xfb, 0xf0, 0x2e, 0xfd, 0x0d, 0x0d, 0x07, + 0x1e, 0xf4, 0x07, 0x3f, 0xfa, 0x09, 0x27, 0x0d, 0x17, 0xfa, 0xfe, 0x05, 0xfd, + 0x17, 0x0d, 0xf9, 0x15, 0x20, 0xe9, 0x25, 0x03, 0xf3, 0xdc, 0x0a, 0x03, 0xf5, + 0x2a, 0xef, 0x0a, 0x05, 0x0a, 0xdc, 0x02, 0x1a, 0xe9, 0x04, 0xe1, 0xf6, 0xf3, + 0xee, 0x03, 0x09, 0x07, 0xce, 0x1d, 0xed, 0x1c, 0x01, 0x22, 0x22, 0x03, 0x03, + 0x07, 0x17, 0x7f, 0x16, 0x1b, 0xf7, 0x08, 0xe5, 0x05, 0xf6, 0xed, 0x1c, 0xf7, + 0x02, 0xe9, 0xec, 0xed, 0x27, 0xfd, 0x00, 0xe1, 0xf7, 0xed, 0x07, 0x05, 0x0d, + 0x1a, 0x24, 0x04, 0xef, 0x21, 0x16, 0xf9, 0x0b, 0x05, 0xf8, 0x25, 0xf0, 0x01, + 0xec, 0x0f, 0xeb, 0x06, 0x0e, 0x03, 0xf7, 0xee, 0xf2, 0x04, 0x45, 0xe7, 0x0e, + 0xee, 0x1a, 0xf5, 0x11, 0x14, 0x0c, 0xfe, 0xfa, 0x0f, 0xf4, 0x12, 0xf7, 0x0a, + 0xfc, 0xf9, 0x00, 0xff, 0xec, 0xe8, 0x09, 0xee, 0xf6, 0x12, 0xea, 0xf4, 0x01, + 0x17, 0xfd, 0xe0, 0x15, 0x13, 0x37, 0x5c, 0xfb, 0xea, 0xae, 0xe3, 0xeb, 0xfe, + 0x95, 0xee, 0x54, 0xf1, 0x14, 0xe2, 0x2f, 0xd9, 0xf8, 0xc5, 0xea, 0xb0, 0xbb, + 0xac, 0x10, 0xfc, 0xd6, 0xfa, 0x2b, 0xff, 0xdd, 0xdb, 0x28, 0x05, 0xbd, 0xc5, + 0x48, 0x0c, 0x08, 0x10, 0xe5, 0xf6, 0x7f, 0xfe, 0x03, 0x1d, 0xed, 0x02, 0x02, + 0x06, 0x16, 0x34, 0x01, 0x35, 0x9e, 0x03, 0x12, 0xd3, 0x3d, 0x0d, 0x0f, 0x3f, + 0xee, 0x30, 0x4b, 0x1e, 0xfa, 0x1a, 0xe7, 0xea, 0x05, 0x50, 0x0b, 0x5e, 0x78, + 0xfb, 0x2f, 0xbf, 0x17, 0xf7, 0xf2, 0x50, 0xf6, 0x24, 0x52, 0xf3, 0xe5, 0x76, + 0x43, 0x37, 0xec, 0x3e, 0xea, 0xf2, 0x2e, 0x21, 0xef, 0x0f, 0xcf, 0x2c, 0x11, + 0xf1, 0x1c, 0xf4, 0xff, 0x1f, 0x57, 0xe7, 0x07, 0xbe, 0x05, 0x70, 0xdf, 0x22, + 0xef, 0x63, 0x41, 0x69, 0xae, 0x07, 0x2d, 0x4e, 0xd6, 0x08, 0xe8, 0xfb, 0x29, + 0x24, 0x11, 0x16, 0xe9, 0x20, 0x2f, 0xf4, 0x12, 0x24, 0xef, 0x02, 0xf5, 0xe6, + 0x2f, 0xef, 0x07, 0xb4, 0xd0, 0xf2, 0x2f, 0xf9, 0x28, 0x00, 0xec, 0xa0, 0x39, + 0xd9, 0x23, 0x06, 0x11, 0xda, 0x1c, 0xea, 0x07, 0x32, 0x0d, 0x1f, 0x0b, 0x20, + 0xee, 0x0d, 0x76, 0x1d, 0xb1, 0xed, 0xde, 0x02, 0x28, 0xeb, 0x53, 0x11, 0xe9, + 0x26, 0xde, 0xf5, 0x3c, 0x1f, 0x21, 0xb4, 0xf3, 0xe3, 0x06, 0xfc, 0xe0, 0x4b, + 0xcf, 0x2f, 0x49, 0xfe, 0xf9, 0x03, 0xab, 0x1f, 0x62, 0xa0, 0x1e, 0x20, 0xfb, + 0x27, 0xd4, 0xda, 0x01, 0x2b, 0x14, 0x0e, 0x09, 0x45, 0xbb, 0x33, 0x16, 0xf8, + 0x16, 0x3e, 0xfa, 0x15, 0x0c, 0xfd, 0x10, 0x21, 0x19, 0x16, 0xed, 0x2e, 0x5e, + 0x7f, 0x10, 0x53, 0xca, 0x4b, 0x22, 0x49, 0x06, 0x32, 0xc3, 0x2a, 0x1f, 0x26, + 0xef, 0x37, 0x13, 0x16, 0x16, 0xd1, 0x40, 0x04, 0x23, 0xe6, 0x41, 0xe2, 0x33, + 0xcf, 0x24, 0x03, 0x0b, 0x18, 0xf1, 0xfa, 0xfa, 0xb5, 0x32, 0x0c, 0x1b, 0x07, + 0x28, 0xea, 0xb8, 0x81, 0xfa, 0x06, 0x34, 0x16, 0x26, 0x02, 0x1b, 0x04, 0xfe, + 0x16, 0x18, 0xe2, 0x0b, 0xf4, 0xbf, 0xfc, 0xff, 0xdf, 0x24, 0xc9, 0xf4, 0xfa, + 0x0b, 0xfb, 0xcf, 0x02, 0x08, 0xda, 0x0f, 0x15, 0x03, 0xf8, 0xdd, 0x18, 0x02, + 0xf5, 0x1b, 0x25, 0x0c, 0x39, 0x1b, 0xda, 0xef, 0xe9, 0x0c, 0x08, 0xec, 0xd2, + 0xf8, 0xe5, 0xe1, 0x1c, 0xed, 0xe4, 0x0d, 0xc4, 0x10, 0xec, 0x22, 0x23, 0x1c, + 0xbc, 0x0d, 0xf0, 0x05, 0xe7, 0xf7, 0xe3, 0x56, 0xde, 0x1d, 0xf6, 0x01, 0xe8, + 0xf7, 0xf7, 0x0e, 0x22, 0xef, 0x02, 0x0f, 0xe1, 0x1e, 0xda, 0xd7, 0xee, 0xe6, + 0x03, 0x2b, 0xd0, 0x17, 0xf0, 0x2b, 0xea, 0x04, 0x08, 0xf7, 0xdd, 0x14, 0x0d, + 0x1d, 0xd0, 0x1e, 0xdc, 0xf2, 0xbe, 0x20, 0xeb, 0x1c, 0x23, 0x0c, 0x1c, 0x37, + 0x02, 0x04, 0x3a, 0x05, 0x01, 0xc3, 0x43, 0xf9, 0xc6, 0x10, 0x54, 0x2c, 0xf4, + 0xd2, 0xfc, 0x04, 0x06, 0x11, 0xb5, 0xe6, 0x00, 0x10, 0xf9, 0x0d, 0x25, 0x17, + 0x08, 0xf7, 0x32, 0x57, 0xbd, 0xf1, 0x42, 0xfc, 0xe7, 0x00, 0xf4, 0x17, 0x1a, + 0xe0, 0x30, 0xf9, 0x15, 0x2a, 0x45, 0x24, 0x21, 0xfa, 0xed, 0xef, 0xe6, 0x11, + 0xf0, 0x69, 0x39, 0x23, 0x12, 0xc8, 0xf8, 0x08, 0xfd, 0xd9, 0xf3, 0x08, 0x01, + 0x0f, 0x22, 0xd4, 0xf2, 0x3a, 0xe2, 0xec, 0xf2, 0xf8, 0x62, 0xe5, 0x68, 0x23, + 0x01, 0x50, 0xef, 0xe2, 0xd2, 0x1d, 0xee, 0x19, 0x0c, 0x01, 0x01, 0x07, 0xdd, + 0xdd, 0xfc, 0x10, 0x06, 0x26, 0xf5, 0xe9, 0x0d, 0xc6, 0x08, 0xf1, 0x02, 0xfe, + 0x1e, 0xf7, 0x2f, 0xd7, 0xee, 0xe7, 0xff, 0x02, 0x0c, 0x04, 0xfa, 0x2b, 0xd1, + 0x0b, 0xf2, 0xfe, 0x06, 0x19, 0xf9, 0x02, 0x7f, 0x0f, 0x03, 0xf9, 0xdd, 0xf4, + 0x4f, 0xfc, 0x31, 0xf0, 0x37, 0xdd, 0x1c, 0x5d, 0x0e, 0x3a, 0xe4, 0xa5, 0xe2, + 0xfd, 0xe4, 0xc4, 0x7f, 0x19, 0x26, 0xf7, 0x20, 0xca, 0xfa, 0x02, 0x46, 0x5a, + 0xe2, 0x00, 0x1b, 0xff, 0x36, 0x2d, 0x12, 0x0c, 0xd1, 0xf5, 0x32, 0xc7, 0x01, + 0xf4, 0xd7, 0x66, 0x14, 0xd9, 0x08, 0xdf, 0xf1, 0xd8, 0xdc, 0x01, 0x36, 0x25, + 0xff, 0x3f, 0xf8, 0xf5, 0xae, 0xdc, 0x1c, 0xd9, 0x0a, 0x7d, 0xde, 0xe6, 0x1d, + 0x27, 0x1c, 0x27, 0x02, 0xea, 0x98, 0xdb, 0xdb, 0x08, 0xdd, 0xf2, 0x10, 0xe8, + 0xfc, 0x26, 0x11, 0x14, 0xf7, 0x3e, 0x07, 0x07, 0x3c, 0x27, 0xff, 0xfa, 0x24, + 0xe0, 0x45, 0x05, 0x2e, 0xce, 0x01, 0xfd, 0x56, 0xed, 0xe9, 0x4e, 0x2f, 0xfe, + 0x0d, 0xe1, 0xe6, 0x1b, 0x06, 0xea, 0x3b, 0x15, 0xea, 0xa9, 0x00, 0x05, 0x15, + 0xde, 0x82, 0x36, 0xdb, 0x11, 0xbe, 0xe1, 0x2b, 0x09, 0x28, 0x46, 0x5d, 0xde, + 0x36, 0x27, 0xfc, 0x50, 0xd0, 0x33, 0x0d, 0x10, 0x3b, 0xfd, 0xe3, 0xdf, 0x01, + 0xf6, 0xbc, 0x48, 0x2e, 0xfe, 0x1b, 0x2f, 0x20, 0xed, 0xf8, 0xfb, 0x8e, 0xf5, + 0xc3, 0x2e, 0x48, 0x68, 0xef, 0x3b, 0x40, 0xf1, 0xe8, 0xaf, 0x23, 0xeb, 0x16, + 0x37, 0x44, 0x93, 0x12, 0x07, 0x1c, 0x9a, 0xfb, 0xf5, 0xff, 0x78, 0x15, 0x18, + 0xf9, 0x42, 0xbc, 0xe2, 0x07, 0x2b, 0xc8, 0xdd, 0xa1, 0xbe, 0xc4, 0x0a, 0x1d, + 0xd6, 0xc1, 0xe9, 0xa4, 0xf3, 0x15, 0x3b, 0xe3, 0xf7, 0x0a, 0x1a, 0xee, 0xd8, + 0xe3, 0x6a, 0xf7, 0xd2, 0xf6, 0xdf, 0xf3, 0xdd, 0xd4, 0x9d, 0x22, 0x0b, 0xc2, + 0x16, 0x42, 0x58, 0x23, 0xf0, 0x03, 0xee, 0x1d, 0x1b, 0xf4, 0x18, 0xea, 0x2b, + 0xc2, 0x62, 0x2a, 0x9a, 0xfb, 0x2d, 0x28, 0xcf, 0x9f, 0xdb, 0xfa, 0xe9, 0xd5, + 0xcf, 0xef, 0xda, 0x0b, 0x9f, 0x7f, 0xec, 0x10, 0xca, 0x4d, 0xc4, 0x05, 0x09, + 0x33, 0x2b, 0x0f, 0x08, 0x0f, 0x27, 0x33, 0x0e, 0xec, 0xf3, 0x20, 0x19, 0xdf, + 0x31, 0xda, 0x10, 0x06, 0xf1, 0xcc, 0x08, 0xd9, 0x0a, 0x01, 0x14, 0x31, 0x0b, + 0x26, 0x14, 0x03, 0xf6, 0xcd, 0xd2, 0x0e, 0x1a, 0x39, 0x1a, 0x2c, 0xab, 0x1f, + 0xfb, 0x2f, 0x37, 0x25, 0x2c, 0xe8, 0x07, 0xec, 0x4d, 0xdf, 0x1c, 0x09, 0x0c, + 0x09, 0x06, 0xe4, 0xf2, 0x27, 0x05, 0x08, 0x1a, 0xfe, 0x06, 0x29, 0xce, 0x5e, + 0x21, 0xe6, 0xf9, 0xf6, 0x00, 0x49, 0x20, 0x14, 0xeb, 0xe6, 0x70, 0xd7, 0x32, + 0x77, 0xb3, 0xef, 0x07, 0xc4, 0x0b, 0x12, 0x05, 0x06, 0xc3, 0xdd, 0x45, 0x00, + 0xcf, 0x00, 0x22, 0x3d, 0xd0, 0xe1, 0xf7, 0xde, 0xe7, 0xe2, 0x03, 0x7f, 0xdf, + 0x13, 0x4b, 0x76, 0xe7, 0x23, 0x16, 0x5a, 0x21, 0xf8, 0xeb, 0xcc, 0xdf, 0xbc, + 0x1d, 0x0f, 0x28, 0x25, 0x33, 0x29, 0x1e, 0x15, 0xf7, 0x07, 0x19, 0x36, 0x40, + 0xbe, 0x56, 0x25, 0x41, 0xe4, 0xe4, 0xd1, 0x6f, 0xea, 0x04, 0x32, 0x41, 0x7f, + 0x1a, 0x3b, 0xe3, 0x43, 0x15, 0x02, 0x2f, 0x3e, 0x64, 0x63, 0xbc, 0xff, 0xc2, + 0x0b, 0x05, 0x31, 0x05, 0x11, 0x38, 0x22, 0x78, 0xff, 0xf6, 0x38, 0xb2, 0x19, + 0x00, 0x54, 0x10, 0x31, 0xde, 0x49, 0x19, 0x37, 0x2b, 0x41, 0xe2, 0x08, 0x1a, + 0x39, 0x0a, 0x20, 0xd4, 0x04, 0x35, 0x22, 0x06, 0x21, 0x57, 0x41, 0x66, 0xb6, + 0xfd, 0x0e, 0x3f, 0xd1, 0x58, 0x1e, 0x2d, 0x2f, 0x68, 0x14, 0xfd, 0x18, 0x9e, + 0xe5, 0x36, 0xf9, 0x15, 0xe4, 0x22, 0x13, 0x4b, 0xdd, 0x3c, 0x4f, 0xf0, 0xfa, + 0x03, 0x03, 0x19, 0xe5, 0x0d, 0x05, 0x1c, 0x58, 0xfa, 0x2c, 0x35, 0x07, 0x22, + 0x2f, 0x3a, 0x22, 0xe9, 0xf2, 0x37, 0x11, 0x3e, 0x23, 0x50, 0x23, 0x1b, 0x45, + 0x1d, 0xed, 0xce, 0x1b, 0xef, 0x28, 0x3e, 0xe5, 0x34, 0x17, 0xbf, 0x92, 0x4f, + 0xfb, 0xd7, 0xd0, 0x07, 0xeb, 0xf1, 0x2e, 0xce, 0xf3, 0xd2, 0xfa, 0x14, 0x33, + 0x02, 0x07, 0xee, 0xc7, 0xda, 0xd8, 0xd9, 0x0e, 0xf3, 0xdf, 0xfe, 0xf1, 0x19, + 0x0d, 0x1f, 0x0f, 0xe1, 0x5a, 0x74, 0x1b, 0xd3, 0xe1, 0xd2, 0x24, 0x43, 0x73, + 0x33, 0xdd, 0xd6, 0x25, 0xce, 0xec, 0x30, 0x05, 0x0f, 0xe1, 0xef, 0xd5, 0xea, + 0xbf, 0x02, 0xe0, 0xea, 0xf7, 0x0c, 0x66, 0xc9, 0x7f, 0x51, 0xf2, 0xc8, 0x02, + 0xec, 0x0e, 0x73, 0x0c, 0x02, 0x0a, 0xec, 0xd8, 0xd0, 0xeb, 0xe5, 0xe7, 0xdc, + 0x13, 0x00, 0xf9, 0xef, 0xc2, 0x5e, 0xd9, 0x17, 0x0e, 0xf0, 0x0a, 0x2d, 0x13, + 0xd8, 0x01, 0x26, 0xbb, 0x21, 0x2d, 0xec, 0x32, 0x08, 0x15, 0x10, 0x1c, 0x38, + 0xd8, 0xf7, 0x39, 0xe3, 0x1c, 0x2a, 0x1c, 0x21, 0x79, 0xd9, 0xeb, 0x43, 0xfa, + 0x20, 0xca, 0xec, 0x21, 0xd2, 0xea, 0xfa, 0x10, 0xdd, 0x3a, 0xf8, 0x14, 0xd3, + 0xdd, 0xc4, 0xda, 0xce, 0x02, 0x16, 0x05, 0x0c, 0x04, 0xd8, 0x0c, 0xf7, 0x16, + 0xe1, 0x45, 0x17, 0xe7, 0xb9, 0xeb, 0xfa, 0x11, 0x0b, 0x15, 0x9f, 0x49, 0xec, + 0x14, 0xe4, 0xde, 0xc0, 0xd3, 0x0b, 0xb7, 0x08, 0x12, 0xfe, 0x26, 0x17, 0x29, + 0x48, 0xe4, 0x0a, 0x22, 0x51, 0x21, 0x16, 0x12, 0xf0, 0x0e, 0xd6, 0xf2, 0x32, + 0x1b, 0x0c, 0xf4, 0x31, 0x12, 0x4b, 0xf0, 0x06, 0x0e, 0x03, 0xfe, 0x81, 0xcb, + 0x0d, 0x1d, 0xe9, 0x17, 0xff, 0xf5, 0x27, 0x05, 0x75, 0x01, 0xf7, 0x07, 0x15, + 0xec, 0xb4, 0xba, 0xf4, 0xe4, 0x04, 0x16, 0x09, 0x47, 0x30, 0xe9, 0xa5, 0x43, + 0x0e, 0x93, 0x05, 0xfa, 0xe8, 0x09, 0xfa, 0x53, 0xc5, 0x11, 0x0e, 0xf5, 0xb4, + 0xd3, 0x4e, 0xf8, 0x02, 0xd7, 0x10, 0xdd, 0xbb, 0xa7, 0xdd, 0x26, 0xd1, 0xdc, + 0xfc, 0x11, 0x3a, 0x13, 0x27, 0x10, 0x05, 0xaa, 0x13, 0x00, 0xe1, 0x25, 0xea, + 0xf7, 0xed, 0x0a, 0xa3, 0x0b, 0xe8, 0xec, 0x16, 0xfa, 0x12, 0xf8, 0xdc, 0xed, + 0x14, 0x23, 0xd1, 0x0a, 0x10, 0x03, 0xed, 0xf5, 0x26, 0xef, 0x08, 0x13, 0xb9, + 0xf6, 0x7f, 0x05, 0x25, 0xf9, 0xe0, 0x4a, 0x06, 0x68, 0x18, 0xf6, 0xef, 0xf6, + 0xf9, 0x0c, 0xee, 0x0d, 0xf1, 0xe9, 0x05, 0xb5, 0x12, 0xe4, 0xee, 0xde, 0x10, + 0x10, 0xfc, 0x23, 0xea, 0x1c, 0x3b, 0x10, 0xf9, 0x3c, 0x17, 0x09, 0xf4, 0x4b, + 0xbd, 0x12, 0xf7, 0xf7, 0x0b, 0xfb, 0xdf, 0xf9, 0xf8, 0xfb, 0x30, 0x1c, 0xff, + 0x19, 0x54, 0x15, 0xf6, 0x09, 0x27, 0x04, 0x1e, 0xef, 0x14, 0xe5, 0x07, 0xfd, + 0x13, 0x40, 0xcf, 0x67, 0xec, 0xe4, 0x21, 0xe1, 0x05, 0x02, 0xfd, 0xf9, 0x07, + 0xf9, 0xe5, 0x20, 0xeb, 0xf7, 0xe1, 0x31, 0xe2, 0x27, 0xe0, 0xe3, 0xf4, 0xea, + 0x0a, 0xe7, 0xd4, 0xc8, 0x14, 0x1c, 0x07, 0x1a, 0x44, 0xed, 0xe1, 0x1b, 0x19, + 0x19, 0x10, 0xe3, 0xe5, 0xe7, 0xe7, 0xd9, 0xe2, 0xf9, 0x3b, 0x0b, 0x37, 0xf2, + 0x5f, 0xfe, 0x2c, 0xed, 0xf5, 0xfa, 0xf1, 0xf0, 0x26, 0x13, 0xfc, 0x20, 0xec, + 0x27, 0xd8, 0xf7, 0xf7, 0xd0, 0xe5, 0xfd, 0xe5, 0xee, 0xe0, 0xf8, 0xf9, 0xfa, + 0x16, 0x2f, 0x33, 0xf2, 0x1d, 0x7f, 0xc5, 0xe7, 0xfd, 0xdc, 0x21, 0x03, 0xf6, + 0x0b, 0x06, 0x1b, 0xe5, 0x2a, 0xda, 0x4e, 0xe9, 0x39, 0xd0, 0x0f, 0x76, 0xfe, + 0x10, 0x20, 0xcc, 0xff, 0xf9, 0x0f, 0x0c, 0x14, 0x19, 0xfb, 0x23, 0xd1, 0xcf, + 0xed, 0xfd, 0xf6, 0xd9, 0xfe, 0x12, 0x0c, 0xd3, 0x25, 0xf2, 0x1a, 0x2a, 0x10, + 0xfa, 0x23, 0xd2, 0xe8, 0xe4, 0x0c, 0xff, 0x12, 0xfb, 0x1a, 0x0f, 0x05, 0xf9, + 0xf9, 0x2c, 0x14, 0x03, 0xca, 0x39, 0x19, 0x21, 0xef, 0x07, 0x1b, 0x38, 0x09, + 0xe6, 0xff, 0x38, 0xfc, 0x4f, 0x52, 0x17, 0x03, 0xd4, 0xb5, 0xfd, 0xbd, 0x46, + 0x6a, 0xef, 0x19, 0x04, 0x38, 0xf4, 0x38, 0xfb, 0x52, 0x51, 0x00, 0xb5, 0x22, + 0x07, 0x18, 0xe7, 0x17, 0x20, 0xf0, 0x03, 0xe5, 0x05, 0x4f, 0x2a, 0x12, 0x35, + 0x4b, 0x21, 0x11, 0xd7, 0x39, 0x0d, 0xe8, 0x01, 0x7f, 0xe3, 0x57, 0xe8, 0xe4, + 0xd4, 0xe5, 0xe9, 0xfb, 0x21, 0xe5, 0xf3, 0x1a, 0xb3, 0xde, 0xfe, 0x11, 0xe2, + 0xd6, 0xf5, 0x08, 0xed, 0x43, 0x31, 0xe8, 0x40, 0x44, 0x1f, 0xde, 0x0d, 0x0b, + 0x68, 0xd7, 0xf1, 0xb8, 0x2a, 0xe9, 0xdd, 0x4d, 0x23, 0x07, 0x33, 0x26, 0xe0, + 0x05, 0x16, 0xec, 0xf5, 0xc0, 0x0b, 0xfd, 0xff, 0xca, 0x01, 0xfd, 0xfe, 0xe9, + 0x18, 0xbd, 0x08, 0xf2, 0x1a, 0xfe, 0x3f, 0xd1, 0xf6, 0xcf, 0x1d, 0xfc, 0xe8, + 0x2a, 0x23, 0xa6, 0x02, 0x3a, 0xe9, 0xd9, 0xd6, 0xdc, 0x18, 0x0a, 0x1f, 0xbe, + 0xfd, 0xef, 0xf6, 0x15, 0x18, 0x15, 0xf8, 0x0e, 0x23, 0x2b, 0x1d, 0xda, 0xf0, + 0x26, 0xf9, 0xef, 0x2c, 0x25, 0x0c, 0xeb, 0x13, 0x53, 0xf5, 0x09, 0x1a, 0x5f, + 0xbc, 0xe9, 0x3a, 0xca, 0xf6, 0xfa, 0x03, 0xd9, 0xc1, 0x2d, 0x03, 0xf3, 0xfc, + 0x26, 0x2f, 0x07, 0x22, 0x20, 0x0e, 0xd5, 0xed, 0xcf, 0xfb, 0x17, 0xfa, 0x2c, + 0xe9, 0x5e, 0x18, 0xba, 0x3c, 0xd9, 0xff, 0x21, 0x1c, 0xff, 0x18, 0x13, 0x1c, + 0xc7, 0xe7, 0xa4, 0x19, 0x1a, 0x0b, 0x46, 0xdf, 0x17, 0xcf, 0xa3, 0xd0, 0x78, + 0xca, 0xfb, 0xc8, 0xcc, 0x01, 0xf8, 0xfa, 0x41, 0x0b, 0x38, 0xfe, 0x34, 0xf6, + 0xb1, 0x29, 0x1e, 0xd5, 0x0b, 0xff, 0xc4, 0x01, 0x3d, 0xf9, 0x2b, 0xf2, 0x04, + 0x7f, 0xde, 0xfd, 0xf7, 0xc2, 0x3c, 0x34, 0x22, 0x1b, 0x20, 0x10, 0x35, 0x06, + 0x0b, 0x00, 0xd0, 0xe3, 0x0f, 0x41, 0x59, 0xbe, 0x20, 0x45, 0xf9, 0xe3, 0xe8, + 0xec, 0xee, 0xd8, 0x1d, 0x04, 0xeb, 0x48, 0xf9, 0xdc, 0xe9, 0x08, 0xbf, 0xe7, + 0x22, 0xe7, 0x37, 0x0b, 0xcd, 0xd1, 0x05, 0xd4, 0x28, 0x33, 0xc3, 0xed, 0x2c, + 0x01, 0xfe, 0x42, 0xf5, 0xc1, 0x4a, 0x3a, 0x03, 0x05, 0xd0, 0xe5, 0xf2, 0xfb, + 0x0a, 0xd2, 0x30, 0x09, 0xf8, 0xff, 0x1f, 0x25, 0xe5, 0xf4, 0x10, 0x26, 0x1b, + 0x4c, 0x07, 0x00, 0xf2, 0xe6, 0xe5, 0xe4, 0x09, 0xdf, 0x16, 0x4d, 0xf4, 0x35, + 0x81, 0x0e, 0x18, 0x24, 0x06, 0xf6, 0xe4, 0xf6, 0xe8, 0xee, 0x79, 0x0b, 0x16, + 0xf7, 0xdc, 0xe5, 0x2d, 0x28, 0xeb, 0x2b, 0xfa, 0x0a, 0x21, 0xff, 0xf4, 0x00, + 0x1a, 0x36, 0x1e, 0x17, 0xda, 0xcd, 0xed, 0xc9, 0x43, 0xe5, 0x08, 0x0e, 0x33, + 0xf6, 0xdf, 0xdb, 0x1e, 0xc8, 0x11, 0xe3, 0x00, 0xfe, 0x21, 0xf7, 0x1b, 0xe5, + 0xd0, 0x08, 0xe0, 0x1a, 0x1a, 0x2e, 0xf7, 0xb5, 0x16, 0x2f, 0x28, 0x1f, 0xdf, + 0xe3, 0xcf, 0x34, 0xf8, 0xe0, 0xf7, 0x2b, 0xeb, 0x11, 0xd0, 0x1c, 0xe8, 0x03, + 0x03, 0xe5, 0x06, 0x54, 0xbf, 0xcf, 0xea, 0x3a, 0xe0, 0xff, 0xcf, 0x2c, 0x02, + 0xd4, 0xf4, 0xf9, 0xcf, 0x7f, 0xf2, 0x0d, 0x23, 0x2e, 0xe0, 0xc6, 0x38, 0xe7, + 0xe8, 0x1c, 0xbd, 0x30, 0xeb, 0x10, 0x10, 0xe8, 0x24, 0x0b, 0xf1, 0xfd, 0x23, + 0x07, 0x0e, 0xe4, 0x12, 0xcd, 0x50, 0x33, 0xfe, 0xf6, 0x0a, 0x03, 0x38, 0x00, + 0xf2, 0xec, 0x0b, 0xe2, 0xdd, 0xf2, 0x38, 0xd6, 0xdc, 0xf8, 0x40, 0x39, 0xe0, + 0x12, 0x03, 0x04, 0xe6, 0x0c, 0x00, 0xd1, 0x1a, 0xff, 0xd3, 0x40, 0x05, 0x50, + 0xf7, 0x0f, 0xfe, 0xcc, 0xee, 0xf0, 0x1d, 0x16, 0x2b, 0xec, 0xf4, 0xf4, 0xf8, + 0x25, 0xee, 0x09, 0xd3, 0x2f, 0x02, 0x07, 0xde, 0xa7, 0xeb, 0xd3, 0x3a, 0xdf, + 0x2d, 0x2f, 0xf0, 0x49, 0xfe, 0x0c, 0x81, 0xf8, 0xb3, 0xe8, 0xfb, 0x18, 0x24, + 0xd0, 0xc1, 0xef, 0x44, 0x9d, 0x0c, 0x15, 0xc4, 0xc0, 0xe1, 0xd6, 0x09, 0x1f, + 0x04, 0x0b, 0x0e, 0x19, 0xab, 0xac, 0x32, 0x10, 0x11, 0xb7, 0x02, 0xfe, 0x70, + 0x48, 0xe7, 0xcb, 0xd3, 0x9f, 0x2a, 0x28, 0x69, 0xe6, 0x97, 0xfe, 0xab, 0x14, + 0x3e, 0xd6, 0x26, 0xd1, 0x44, 0xf3, 0x0c, 0xf7, 0x18, 0xec, 0xcc, 0xe4, 0xf3, + 0xbe, 0x26, 0x1a, 0xa6, 0x0a, 0xdd, 0xa2, 0x87, 0x07, 0x43, 0x50, 0xd8, 0x46, + 0xa9, 0xf7, 0x36, 0xb1, 0xb4, 0x23, 0x14, 0x10, 0x4a, 0x2a, 0xfc, 0x35, 0xef, + 0xd5, 0x1e, 0x36, 0x40, 0x1c, 0xac, 0x23, 0x37, 0x03, 0xaa, 0xc0, 0xb5, 0x2b, + 0x3f, 0x54, 0x62, 0x0a, 0xaa, 0x92, 0xf0, 0x1a, 0xe9, 0x02, 0x31, 0xdc, 0x13, + 0x2e, 0xee, 0x15, 0x13, 0x13, 0x07, 0x3c, 0xcc, 0x05, 0x37, 0x5a, 0x02, 0x32, + 0x0f, 0x1d, 0x3a, 0x39, 0x0f, 0x2c, 0x0b, 0x3f, 0x6e, 0x51, 0xfc, 0x44, 0xcc, + 0xf9, 0xed, 0x23, 0xbf, 0x63, 0x0d, 0xd9, 0xdf, 0x16, 0x43, 0x0f, 0xbc, 0xf8, + 0xc1, 0x29, 0x26, 0xff, 0xb3, 0x11, 0xdd, 0x3d, 0x12, 0x2d, 0x0b, 0x7f, 0xfb, + 0x05, 0x01, 0xd6, 0x38, 0xea, 0xff, 0xf6, 0x37, 0xcd, 0x29, 0xa9, 0xde, 0x1a, + 0xce, 0xf7, 0x1f, 0xfb, 0x26, 0x17, 0x16, 0x45, 0x22, 0xde, 0x21, 0x0f, 0xeb, + 0xe3, 0x05, 0x0b, 0xee, 0x2b, 0x37, 0x2e, 0xd9, 0x7c, 0xf4, 0x18, 0x15, 0x1a, + 0xd1, 0xf9, 0xe1, 0x58, 0x1f, 0x20, 0x0f, 0x35, 0x17, 0x0f, 0xde, 0x52, 0x03, + 0xf9, 0xf6, 0xfa, 0x3a, 0x07, 0x22, 0x52, 0xc2, 0x21, 0x1a, 0x1d, 0xb0, 0xe5, + 0xfd, 0x0a, 0x1f, 0xc0, 0x3e, 0x4d, 0x53, 0x08, 0xf8, 0xd1, 0xf2, 0x0d, 0xf8, + 0x18, 0x2d, 0x21, 0xe8, 0x56, 0xe9, 0x06, 0x03, 0x1d, 0x16, 0x0e, 0x16, 0xf4, + 0x0d, 0xe6, 0xfc, 0x3a, 0x0d, 0x25, 0x19, 0x20, 0x03, 0x29, 0x13, 0x2a, 0xf3, + 0x4d, 0xc3, 0xc9, 0x10, 0x1e, 0x15, 0xcc, 0x56, 0x24, 0xb7, 0xea, 0xf8, 0x00, + 0x72, 0xe9, 0x0a, 0x51, 0x00, 0xc6, 0xda, 0x18, 0x1e, 0x15, 0xab, 0xf7, 0xe4, + 0xa4, 0xfb, 0x2d, 0x4f, 0x03, 0x9b, 0x17, 0x04, 0x3e, 0xc1, 0xcc, 0xe7, 0x0f, + 0x92, 0xfe, 0x22, 0x07, 0x20, 0xe7, 0xcf, 0xe2, 0xdf, 0xfa, 0x18, 0xda, 0x0e, + 0xe0, 0xe0, 0xe6, 0xb4, 0x2e, 0x38, 0x35, 0x28, 0x23, 0xd6, 0x02, 0x1d, 0xfc, + 0xed, 0x83, 0xe6, 0xfd, 0x1a, 0xad, 0xb4, 0xf9, 0x0a, 0x1a, 0xcb, 0x16, 0xd1, + 0x11, 0xc9, 0x24, 0xef, 0x0c, 0xfd, 0xf5, 0x00, 0x17, 0x02, 0x11, 0x14, 0x28, + 0x0a, 0x91, 0xf2, 0x2d, 0xf2, 0xf7, 0x3f, 0x25, 0xee, 0xe7, 0xd3, 0xf8, 0xdd, + 0x25, 0x20, 0x11, 0x7f, 0x42, 0xb3, 0x08, 0xe4, 0x2f, 0xda, 0xf7, 0xf3, 0x92, + 0x1f, 0x1c, 0x12, 0xae, 0xdc, 0xc3, 0xe1, 0x17, 0xef, 0xf5, 0x05, 0xcd, 0x15, + 0xf2, 0xf5, 0x21, 0xff, 0x26, 0xc2, 0x1b, 0xce, 0xfa, 0x03, 0xea, 0x02, 0xfc, + 0xe1, 0xca, 0xda, 0x1a, 0x02, 0x61, 0x20, 0xeb, 0xc7, 0xe2, 0x84, 0xfc, 0x00, + 0x1b, 0xca, 0xa8, 0xd0, 0x29, 0xef, 0x20, 0xcf, 0x2b, 0xfe, 0x40, 0x17, 0xff, + 0xf8, 0xf1, 0x29, 0x91, 0x07, 0xa8, 0xfe, 0xc0, 0xff, 0xff, 0x07, 0xfc, 0xd5, + 0xe2, 0x00, 0xed, 0xd7, 0x09, 0x29, 0xbc, 0x07, 0x68, 0xb1, 0xc3, 0x81, 0x10, + 0xf1, 0x00, 0x1d, 0xf8, 0xd1, 0x0d, 0xf5, 0xe8, 0xf1, 0xe3, 0xd4, 0x47, 0xf7, + 0xec, 0xe0, 0xe7, 0xde, 0x24, 0xf4, 0x61, 0xe3, 0xfe, 0xcb, 0x26, 0xe9, 0xb7, + 0x03, 0xd7, 0xb5, 0xe9, 0x2b, 0xec, 0xef, 0x17, 0xde, 0x29, 0xcf, 0x08, 0xf1, + 0xe5, 0xd0, 0xa9, 0x00, 0x1f, 0xee, 0x1e, 0xe9, 0x4f, 0x03, 0x18, 0xe0, 0x20, + 0xfc, 0x13, 0x6b, 0x0a, 0x01, 0xb8, 0xd3, 0x13, 0xf4, 0x09, 0x1e, 0x33, 0x44, + 0xec, 0x02, 0xff, 0x50, 0x5b, 0x00, 0xc7, 0x34, 0xea, 0xe1, 0x1e, 0x45, 0xde, + 0xf2, 0x29, 0xd1, 0xe2, 0x14, 0xd4, 0x36, 0x61, 0x7f, 0x12, 0x49, 0xdd, 0xec, + 0xe9, 0xf8, 0xc2, 0xf9, 0xc7, 0x05, 0x1d, 0xf9, 0xe2, 0x20, 0x04, 0xf4, 0xe2, + 0xe9, 0x2f, 0xeb, 0x0b, 0xef, 0x1f, 0xc0, 0xb8, 0xe8, 0xdd, 0xf9, 0xf3, 0xb4, + 0x39, 0x41, 0x18, 0xf8, 0xf0, 0xf3, 0x45, 0xd1, 0xc8, 0xd6, 0x3d, 0xf3, 0xee, + 0xec, 0x00, 0x2f, 0x03, 0xf7, 0x1d, 0x20, 0xf5, 0xe8, 0xfd, 0x24, 0xe2, 0x17, + 0xf3, 0x07, 0xee, 0xed, 0xd8, 0x2b, 0x3d, 0x18, 0x08, 0xf5, 0x24, 0x0e, 0xf7, + 0xed, 0x35, 0x22, 0x0e, 0x30, 0xf4, 0xc6, 0xb9, 0x21, 0xfc, 0x09, 0x06, 0x10, + 0xed, 0xfc, 0x38, 0x2b, 0x21, 0x96, 0x05, 0xdb, 0x09, 0xbe, 0x2e, 0xba, 0x52, + 0xfc, 0x3d, 0xd4, 0xd0, 0x04, 0x27, 0xae, 0x9d, 0x13, 0x57, 0x34, 0x0c, 0x11, + 0xe6, 0x3f, 0x1f, 0xb8, 0x2c, 0xf8, 0x2e, 0xe8, 0xe6, 0x06, 0x32, 0xe6, 0x23, + 0xc6, 0x29, 0x11, 0xcd, 0x06, 0xe6, 0xf8, 0x1a, 0x2f, 0x0e, 0x18, 0xc0, 0x11, + 0xeb, 0xdb, 0xec, 0x7f, 0xfe, 0xe4, 0xfe, 0xe0, 0xf2, 0xc8, 0x1b, 0x19, 0x0d, + 0xe3, 0xcb, 0xdd, 0xc8, 0xd9, 0xde, 0x09, 0xb5, 0xfc, 0x03, 0xef, 0xe9, 0xf0, + 0x3e, 0xfc, 0x12, 0xe9, 0xdf, 0xe7, 0xe8, 0xf9, 0xfd, 0xea, 0xff, 0x25, 0x03, + 0xd3, 0xd8, 0x14, 0x28, 0x0b, 0x31, 0x52, 0xd9, 0xfd, 0x0a, 0xe0, 0xe0, 0x02, + 0xec, 0xc5, 0x12, 0xf0, 0x17, 0xc8, 0x2a, 0xf0, 0x34, 0xd0, 0x1e, 0xea, 0xd5, + 0x47, 0x34, 0x29, 0xd0, 0xeb, 0xd4, 0x04, 0x0c, 0x38, 0x0d, 0xc7, 0x10, 0xd1, + 0x1d, 0x05, 0xdc, 0xe8, 0xeb, 0x0e, 0xe6, 0x17, 0xf3, 0x30, 0x26, 0xee, 0xf9, + 0x50, 0x25, 0xc7, 0x2e, 0x11, 0xd5, 0xbe, 0xfa, 0xca, 0xe5, 0xec, 0xa8, 0x05, + 0x00, 0x01, 0xd9, 0xb2, 0x1e, 0x37, 0xee, 0x81, 0x22, 0x0a, 0xb5, 0x26, 0x2e, + 0xbf, 0x56, 0x26, 0xfb, 0xe9, 0xbf, 0xee, 0xff, 0x21, 0x02, 0x18, 0xfc, 0x52, + 0xe8, 0x20, 0x28, 0xf7, 0xfe, 0xfe, 0xf2, 0x0c, 0x3f, 0xfe, 0xf8, 0x30, 0xfd, + 0x1f, 0xdc, 0xfb, 0x20, 0x77, 0x3e, 0xca, 0x3d, 0x2e, 0xf7, 0xca, 0xef, 0xfc, + 0x04, 0xec, 0xf6, 0xf4, 0x55, 0x11, 0xfd, 0xef, 0x0e, 0xed, 0xd4, 0x01, 0x09, + 0xf6, 0xe5, 0x01, 0x20, 0x04, 0x1a, 0xf2, 0xdf, 0x00, 0x44, 0x9e, 0xfc, 0x0a, + 0xe6, 0xff, 0xe8, 0xc8, 0x28, 0x5d, 0x26, 0x04, 0xeb, 0xd5, 0xf9, 0x04, 0xf9, + 0xb4, 0xd1, 0x14, 0x1d, 0x38, 0xf4, 0xf0, 0x33, 0x2e, 0x19, 0xd7, 0xe8, 0x13, + 0xe7, 0x15, 0x2f, 0x07, 0x00, 0x10, 0x00, 0x6f, 0x31, 0x31, 0x13, 0x3d, 0x28, + 0xda, 0x2d, 0xf0, 0x14, 0x2d, 0x13, 0x81, 0xd6, 0xe7, 0x2a, 0x1e, 0x34, 0x2b, + 0x0f, 0xc1, 0x1c, 0xcb, 0x21, 0xb7, 0x2f, 0x28, 0xe1, 0x3f, 0x23, 0xf6, 0x3b, + 0x20, 0xad, 0x41, 0xe4, 0xe4, 0x11, 0x3c, 0x27, 0x4c, 0x3a, 0x26, 0x23, 0x1f, + 0xec, 0x35, 0xe6, 0x1f, 0xf5, 0x3e, 0xfa, 0x07, 0x38, 0x28, 0x20, 0x03, 0x14, + 0x31, 0xfa, 0x4b, 0xf5, 0x1a, 0x47, 0x07, 0x32, 0xdc, 0x3d, 0x11, 0xd2, 0x05, + 0xf9, 0xd8, 0x08, 0x41, 0x33, 0x01, 0x11, 0x2b, 0x1c, 0x0a, 0x0b, 0xe7, 0x03, + 0x0a, 0xdc, 0x39, 0x39, 0x10, 0x24, 0xe5, 0x34, 0xfe, 0xf8, 0xe9, 0xec, 0xd9, + 0xd6, 0x07, 0x1b, 0x30, 0x3b, 0xf6, 0xcc, 0x53, 0xd1, 0xf6, 0x09, 0x1e, 0x20, + 0xee, 0x13, 0x14, 0xe8, 0xa4, 0x63, 0xc6, 0x1f, 0x0f, 0x0f, 0xd0, 0xe1, 0x5a, + 0x13, 0x0c, 0xb3, 0x1a, 0x21, 0x37, 0xc3, 0x58, 0xbf, 0x43, 0xcc, 0x09, 0xe9, + 0xc0, 0x63, 0xd6, 0xe0, 0xd9, 0x03, 0xbd, 0x10, 0x19, 0xe9, 0xc1, 0x13, 0xbc, + 0xd0, 0x51, 0x0a, 0xa9, 0x39, 0x0b, 0xca, 0x3c, 0xdf, 0xd2, 0x12, 0xbf, 0xcc, + 0x15, 0xe5, 0x1d, 0x08, 0xcb, 0xe5, 0x0e, 0xcb, 0x3c, 0xf2, 0xb1, 0x3b, 0xcc, + 0xb2, 0x0e, 0x12, 0x35, 0xfa, 0xff, 0xc8, 0x2d, 0xed, 0xfa, 0x3b, 0x04, 0xfc, + 0x09, 0xfd, 0xf4, 0xff, 0xf6, 0xe4, 0x02, 0xd4, 0x00, 0x92, 0x26, 0x17, 0xd2, + 0xe2, 0xad, 0x27, 0xef, 0xd9, 0x06, 0x64, 0xfe, 0x2d, 0x18, 0x2e, 0xe1, 0xb7, + 0x45, 0x30, 0x43, 0xde, 0xdc, 0xff, 0xaf, 0x18, 0xdb, 0xc9, 0xee, 0xf2, 0xd3, + 0x3c, 0x13, 0x06, 0x00, 0xf7, 0x13, 0x08, 0xdc, 0xf9, 0xf9, 0xfd, 0x2a, 0xf9, + 0xdb, 0xc5, 0x05, 0x23, 0x1c, 0x7f, 0x31, 0xe3, 0xdd, 0x51, 0xe8, 0x05, 0xf5, + 0x51, 0xbf, 0xa1, 0x2a, 0x46, 0xdf, 0x73, 0xec, 0xdb, 0xd6, 0xc7, 0x1a, 0xc8, + 0xfa, 0xcc, 0x08, 0xbe, 0x05, 0xe6, 0xf8, 0x04, 0x2e, 0x43, 0x08, 0x0f, 0x90, + 0x12, 0xe1, 0x25, 0xbb, 0xdd, 0xd8, 0x16, 0x3e, 0xda, 0x5f, 0x12, 0x19, 0xe5, + 0xf0, 0xf7, 0x2b, 0x02, 0x1e, 0xf4, 0xef, 0xaf, 0x2e, 0xcf, 0x49, 0xc2, 0xdc, + 0xea, 0x1f, 0xc1, 0xee, 0x09, 0x08, 0xf9, 0x36, 0x2a, 0xf0, 0x0d, 0x2b, 0xf0, + 0x11, 0x28, 0x28, 0x2a, 0x36, 0xda, 0xb5, 0x7f, 0xe7, 0xdd, 0x32, 0x03, 0x06, + 0xfe, 0x07, 0xfc, 0xf6, 0x4a, 0xfc, 0xe9, 0x04, 0x0f, 0xff, 0x0d, 0x4f, 0x1b, + 0x07, 0xf7, 0x1f, 0x04, 0xcf, 0xdc, 0x15, 0x0b, 0x2d, 0x47, 0x18, 0xf6, 0xb9, + 0xb4, 0xc4, 0xd8, 0x0c, 0x76, 0xe0, 0x06, 0xa8, 0xf5, 0xe0, 0x17, 0x1e, 0x07, + 0xe2, 0x5a, 0xec, 0xd7, 0x03, 0xdf, 0xf5, 0x01, 0x04, 0xeb, 0x05, 0xea, 0xdf, + 0x42, 0xe6, 0xe4, 0xce, 0x09, 0xfa, 0x38, 0x53, 0x02, 0xda, 0x16, 0xe7, 0x19, + 0x41, 0x14, 0xf2, 0xf9, 0xf6, 0x17, 0x03, 0x2d, 0x24, 0x20, 0x6b, 0xf3, 0x55, + 0x23, 0xf5, 0xe2, 0x0e, 0x4c, 0xe0, 0x0f, 0xd2, 0x7f, 0xba, 0x1e, 0xd3, 0x1a, + 0xd8, 0x3b, 0x18, 0x01, 0x0b, 0xe6, 0xfd, 0x20, 0xde, 0x14, 0xe0, 0x15, 0xf8, + 0x0c, 0xfd, 0xd1, 0x0c, 0x3c, 0x04, 0x09, 0x1f, 0xfa, 0xc3, 0x2e, 0x06, 0xf2, + 0xf5, 0x0d, 0xa2, 0x19, 0x37, 0xe7, 0xe3, 0xcb, 0xfd, 0x18, 0xdf, 0xf9, 0x02, + 0xf0, 0x0c, 0x2e, 0xd7, 0xff, 0xf5, 0x0c, 0xfa, 0xf5, 0x2b, 0x17, 0xe8, 0xb4, + 0xfd, 0xe4, 0x25, 0x2e, 0x0b, 0x31, 0x27, 0x1c, 0x03, 0x04, 0x06, 0xdb, 0xd1, + 0xff, 0x23, 0x15, 0x21, 0x43, 0xab, 0x20, 0xfb, 0x24, 0x02, 0xf6, 0x28, 0x03, + 0xfc, 0xcd, 0x2f, 0xed, 0x34, 0x21, 0x2f, 0x3c, 0xfa, 0xf9, 0x1b, 0xd3, 0xe6, + 0x13, 0x4d, 0xe2, 0x1d, 0x7a, 0x01, 0xc6, 0xd7, 0x14, 0xdf, 0x57, 0x4f, 0xdc, + 0xd1, 0xaf, 0x97, 0xc7, 0x52, 0xa2, 0x4d, 0x38, 0x6f, 0xe4, 0xe2, 0x60, 0x4b, + 0xcb, 0xf8, 0xd5, 0xbd, 0x33, 0x1d, 0xfa, 0x6a, 0x14, 0xf8, 0xed, 0x1e, 0x57, + 0x5f, 0xdb, 0xcf, 0xc5, 0xbf, 0xf2, 0xe4, 0x3c, 0xc5, 0xf2, 0x12, 0xee, 0x15, + 0x0e, 0x44, 0x3c, 0xde, 0x20, 0x23, 0x21, 0x48, 0xd5, 0x32, 0x5d, 0x07, 0xf7, + 0xe3, 0x26, 0x7f, 0xe2, 0xe3, 0xe7, 0xcd, 0x27, 0x5f, 0xe4, 0x37, 0x49, 0x21, + 0x2c, 0xd7, 0x39, 0xd5, 0x39, 0x2f, 0x00, 0xad, 0x24, 0x2f, 0xfb, 0xef, 0xf7, + 0x24, 0x2f, 0xe8, 0x02, 0x17, 0xb8, 0xdd, 0xf5, 0x41, 0x8f, 0x06, 0x34, 0x65, + 0xfe, 0xf5, 0x8b, 0x5b, 0x22, 0xfa, 0x24, 0x13, 0x0d, 0xdf, 0xec, 0x5f, 0xd9, + 0xca, 0x0e, 0xd0, 0xf1, 0x0e, 0xeb, 0x4b, 0xc4, 0xcf, 0xda, 0xce, 0xea, 0xec, + 0xd9, 0x1c, 0xc6, 0xc8, 0xf3, 0x05, 0xbd, 0x04, 0xf9, 0xea, 0x06, 0xd8, 0x26, + 0xaa, 0x08, 0x31, 0xc3, 0xe1, 0xef, 0xec, 0xfe, 0x55, 0x1e, 0x15, 0x03, 0xfe, + 0x06, 0x15, 0xf1, 0xdd, 0x0e, 0xe2, 0xf3, 0x9e, 0xb7, 0x30, 0x2a, 0x9c, 0x47, + 0xfb, 0xe6, 0xdb, 0xff, 0xcb, 0x2e, 0xce, 0x0a, 0xfd, 0x05, 0xde, 0xb3, 0xd8, + 0xe4, 0x34, 0x34, 0xed, 0x10, 0xb7, 0xf3, 0x37, 0xcf, 0xd4, 0xb5, 0xdc, 0xf4, + 0xe7, 0xca, 0xff, 0xcb, 0x2e, 0x31, 0xff, 0x25, 0xf7, 0x29, 0xb9, 0xc4, 0xf5, + 0x2f, 0x0d, 0x16, 0x04, 0xe0, 0x11, 0x10, 0x17, 0x08, 0x1e, 0xed, 0xef, 0x0e, + 0xf0, 0x06, 0xdf, 0xc6, 0xcf, 0xfa, 0xff, 0x08, 0x2d, 0xca, 0xe1, 0x15, 0xc5, + 0xa9, 0xfb, 0xea, 0xf8, 0xa8, 0x08, 0xf3, 0xdd, 0xc0, 0x7f, 0x34, 0x20, 0x01, + 0x19, 0xde, 0xd3, 0x96, 0x11, 0x27, 0xea, 0xd5, 0xfc, 0x02, 0xcb, 0xac, 0x16, + 0xbe, 0x62, 0xe5, 0x3e, 0xf6, 0xdd, 0x1a, 0xd5, 0x24, 0xd8, 0x37, 0xf9, 0xe1, + 0xcc, 0x8e, 0xe8, 0x4e, 0x04, 0x1b, 0xe3, 0xe0, 0xdf, 0x08, 0xe6, 0x6c, 0x02, + 0x97, 0xf2, 0x1c, 0x2d, 0xed, 0xc1, 0xc9, 0x29, 0x1b, 0x0f, 0xfb, 0x15, 0xb3, + 0xf1, 0xd4, 0xcd, 0x7a, 0xce, 0x01, 0xf9, 0x56, 0x02, 0xf6, 0x06, 0xe4, 0x46, + 0x71, 0xf4, 0xb4, 0x5b, 0x14, 0x2b, 0x34, 0x10, 0x17, 0xd1, 0xea, 0x1a, 0xe9, + 0xe5, 0xbe, 0xc0, 0xf4, 0xb0, 0xb1, 0x3a, 0x8d, 0x47, 0xc0, 0xfb, 0x20, 0xdf, + 0xff, 0xf0, 0xf7, 0x15, 0x64, 0x2a, 0xe2, 0x42, 0x49, 0xf2, 0xcf, 0xfa, 0x1f, + 0x22, 0x00, 0x2d, 0x03, 0x2d, 0xbb, 0xfc, 0x7f, 0x31, 0x15, 0xdf, 0xd3, 0x0b, + 0xfb, 0xf4, 0x1e, 0x20, 0xc4, 0xdd, 0x0c, 0xef, 0xe4, 0xc4, 0xfd, 0x14, 0x2e, + 0xe1, 0xd0, 0xec, 0x03, 0x01, 0xf0, 0x31, 0x2b, 0x13, 0xd7, 0x1f, 0xf7, 0x08, + 0x24, 0x35, 0xe8, 0x18, 0x00, 0xfc, 0x0d, 0xf6, 0x15, 0xf8, 0x24, 0x1b, 0xc0, + 0xd2, 0xf8, 0x0e, 0xee, 0xd1, 0xee, 0x0d, 0xd0, 0xfb, 0x42, 0xfd, 0x42, 0x39, + 0x18, 0x26, 0xbb, 0x09, 0x02, 0x2c, 0x2c, 0x37, 0x01, 0x31, 0xe5, 0xe9, 0x16, + 0xdb, 0x1f, 0x02, 0x31, 0x04, 0xec, 0x3d, 0x1a, 0xe3, 0x21, 0xf8, 0x0a, 0x1b, + 0xf3, 0x7f, 0x0e, 0x3c, 0x3b, 0x0f, 0x0e, 0x15, 0x12, 0x35, 0xee, 0x17, 0x09, + 0xf3, 0x36, 0x2f, 0xdd, 0x06, 0x40, 0x0c, 0x2f, 0x08, 0x23, 0xe8, 0xe1, 0x10, + 0x49, 0xeb, 0x03, 0x03, 0xd5, 0x10, 0x44, 0xf0, 0x5d, 0xf8, 0xf3, 0x00, 0xda, + 0x4a, 0xe4, 0x2a, 0xf4, 0xdb, 0x0d, 0x49, 0xee, 0x1b, 0x12, 0xf4, 0xed, 0x0d, + 0x12, 0xf9, 0xec, 0xbe, 0x05, 0xf4, 0x19, 0x49, 0xf7, 0x07, 0xb6, 0xfa, 0xc2, + 0x06, 0xd0, 0xa0, 0x0d, 0x45, 0x03, 0x8e, 0x34, 0x40, 0xe3, 0xc7, 0x19, 0x17, + 0xfc, 0xa3, 0x15, 0xea, 0xf1, 0x9f, 0xe4, 0xaa, 0x11, 0xbc, 0x30, 0xdb, 0xad, + 0x7f, 0x41, 0xf5, 0x34, 0x3e, 0xec, 0xfd, 0xf0, 0xfe, 0xa0, 0x13, 0x28, 0xf6, + 0xdf, 0xc4, 0xfd, 0xe8, 0x2a, 0xc0, 0xed, 0x54, 0x93, 0x4e, 0xfd, 0xd4, 0xec, + 0xf3, 0x24, 0xd1, 0x39, 0xd3, 0xd1, 0xe6, 0xd5, 0xe6, 0xd9, 0xef, 0xb6, 0xd3, + 0x2a, 0x04, 0xd8, 0x33, 0xd6, 0xc9, 0xd3, 0xb6, 0xdc, 0xbb, 0x19, 0x16, 0xfe, + 0xfa, 0xe1, 0x09, 0x9b, 0xb0, 0xa0, 0x44, 0x17, 0xfc, 0xd1, 0xcf, 0xd6, 0xdb, + 0x51, 0x0e, 0xec, 0x37, 0xc3, 0xe0, 0x0d, 0xbb, 0xda, 0xfa, 0xe2, 0xf0, 0xcf, + 0x2c, 0xa2, 0x25, 0xf8, 0xc1, 0xde, 0x42, 0x27, 0x09, 0xd7, 0x27, 0x9a, 0x53, + 0xf5, 0x14, 0x43, 0x69, 0x6f, 0x14, 0x23, 0x0d, 0xda, 0x4b, 0xf4, 0xf2, 0x0b, + 0x4c, 0x7f, 0x19, 0x36, 0x33, 0x1b, 0xca, 0xe9, 0x1e, 0x0c, 0x04, 0x48, 0x04, + 0xdb, 0xe1, 0xf2, 0xf2, 0x1f, 0xf4, 0x24, 0xec, 0x29, 0xf2, 0x16, 0x0f, 0xfb, + 0xdf, 0xb9, 0xe1, 0x41, 0xfa, 0x2c, 0x0d, 0xe7, 0xdf, 0xd4, 0xb9, 0xf4, 0x37, + 0x16, 0x25, 0xf8, 0xfd, 0xc9, 0x29, 0x02, 0x2a, 0xea, 0x40, 0xf1, 0x04, 0x1b, + 0x12, 0x02, 0x5b, 0xbb, 0xd4, 0x23, 0x0c, 0xd4, 0xe5, 0xd0, 0x02, 0x13, 0xec, + 0x0d, 0x0e, 0xeb, 0x01, 0x1c, 0x41, 0x04, 0xfa, 0x21, 0x1e, 0xf3, 0x14, 0x1b, + 0xc8, 0x15, 0xf2, 0xe1, 0xd8, 0xf2, 0xfa, 0x21, 0xe8, 0xd5, 0x5e, 0xfa, 0x02, + 0x00, 0xeb, 0x13, 0xdb, 0xa7, 0xf3, 0x16, 0x26, 0x18, 0xf5, 0x29, 0x0b, 0xd2, + 0x18, 0x1f, 0x3c, 0x18, 0x2f, 0x1c, 0x0b, 0x00, 0x25, 0xed, 0xb2, 0xe0, 0x47, + 0x3a, 0x05, 0x55, 0x12, 0xe4, 0x08, 0x7f, 0xe7, 0xbc, 0x53, 0xc3, 0xab, 0x2a, + 0x37, 0x05, 0x03, 0x1e, 0xed, 0xdf, 0xbf, 0x0d, 0x2b, 0xea, 0xd2, 0xee, 0xde, + 0x01, 0xbb, 0x07, 0xf6, 0x22, 0x2e, 0x69, 0x08, 0x30, 0xf6, 0xe6, 0x0e, 0xe9, + 0xc0, 0xf5, 0xf7, 0xf5, 0x09, 0x0d, 0x26, 0xf6, 0xbf, 0xd6, 0xa7, 0x00, 0x07, + 0x0f, 0x32, 0xb5, 0x17, 0x98, 0x22, 0x1c, 0x0b, 0x51, 0x32, 0xf3, 0xdb, 0x13, + 0x41, 0x94, 0x1a, 0x0a, 0x1e, 0x25, 0xf5, 0x19, 0x6f, 0x3d, 0x00, 0x3b, 0x19, + 0x33, 0xc7, 0xc3, 0xff, 0xee, 0xe8, 0x20, 0xc6, 0xe8, 0xf3, 0xe2, 0xfe, 0xf1, + 0xd9, 0xfd, 0x37, 0x22, 0xfc, 0xea, 0xf4, 0xfe, 0x75, 0xef, 0x16, 0xef, 0x4e, + 0x2f, 0xfe, 0xd0, 0xca, 0x09, 0xfa, 0xee, 0x01, 0x1e, 0x1b, 0xfe, 0x13, 0x0a, + 0x12, 0x07, 0x01, 0xf7, 0x03, 0xee, 0x31, 0x41, 0xa8, 0x09, 0xef, 0x3b, 0x13, + 0x05, 0xfc, 0x09, 0x20, 0x30, 0x18, 0xf3, 0x19, 0xf9, 0x42, 0x30, 0x74, 0xdb, + 0x07, 0xc7, 0xb7, 0xef, 0xde, 0xee, 0x18, 0xd2, 0xb3, 0xb9, 0x01, 0x04, 0x11, + 0xff, 0xb9, 0xc3, 0x01, 0xd4, 0x24, 0xd2, 0xcc, 0x1a, 0x4a, 0xd2, 0xe4, 0x2d, + 0xa8, 0xad, 0xa9, 0xe7, 0xaf, 0x2d, 0xe0, 0x69, 0x07, 0xfc, 0xb7, 0x40, 0xe2, + 0xe8, 0xf3, 0xb1, 0xfd, 0x1c, 0xfd, 0x51, 0x03, 0xe1, 0xeb, 0xf1, 0x9f, 0xca, + 0xe1, 0x46, 0xd6, 0xce, 0xe5, 0x27, 0x34, 0xdf, 0x4a, 0xeb, 0x09, 0x09, 0xb3, + 0xdc, 0xf5, 0xb2, 0xd9, 0x44, 0x34, 0x0c, 0xf0, 0xf2, 0xcf, 0xe7, 0xc1, 0x90, + 0xbf, 0x0a, 0x10, 0xc0, 0x23, 0xf7, 0x67, 0xbd, 0xca, 0x28, 0xd7, 0x14, 0xc3, + 0x54, 0xea, 0xb6, 0x7f, 0xd3, 0xc8, 0xd3, 0x10, 0xe4, 0xe5, 0x3a, 0x43, 0x0b, + 0xdb, 0xc8, 0xb5, 0xec, 0x53, 0x34, 0x26, 0xc9, 0x1d, 0xcc, 0xc7, 0xf0, 0x1c, + 0x25, 0x0a, 0x27, 0xe1, 0x08, 0xec, 0xd4, 0x15, 0xb4, 0x49, 0xe5, 0x60, 0x6c, + 0xf9, 0xd0, 0xa3, 0x41, 0xea, 0x2a, 0xf3, 0xfa, 0x29, 0xc0, 0x06, 0xe3, 0xe3, + 0x39, 0x29, 0xd8, 0x61, 0x16, 0xf4, 0x27, 0x42, 0x07, 0xb8, 0x15, 0x27, 0xd2, + 0xe9, 0xc2, 0x7f, 0x07, 0xe1, 0x6d, 0x2a, 0xec, 0x35, 0xf3, 0x09, 0xf3, 0x3d, + 0xf1, 0xeb, 0x34, 0x01, 0x07, 0xf4, 0xfd, 0x00, 0xd8, 0x1f, 0x1d, 0xfd, 0xe5, + 0x07, 0xe5, 0xfc, 0xfe, 0x24, 0x3f, 0xe3, 0x3e, 0x19, 0x09, 0x4a, 0xe3, 0xe7, + 0x6d, 0xdd, 0x17, 0xee, 0x16, 0x38, 0x13, 0xea, 0xb1, 0xf5, 0xf4, 0xd2, 0x0d, + 0x10, 0x01, 0xdb, 0x11, 0xfb, 0xef, 0xd3, 0x27, 0xe9, 0x22, 0x31, 0xe6, 0x47, + 0x14, 0x24, 0xc8, 0x14, 0xd1, 0xeb, 0x04, 0x11, 0x0d, 0xee, 0xf6, 0xe2, 0x14, + 0xdf, 0xfe, 0xdd, 0x0a, 0xf8, 0xf6, 0x27, 0x75, 0xe1, 0xa7, 0xde, 0x5c, 0x0f, + 0xcc, 0xd7, 0xe9, 0xf9, 0xcd, 0x0d, 0x91, 0xef, 0xf1, 0xf2, 0x7f, 0xd7, 0xd4, + 0x12, 0xf5, 0x0e, 0xd4, 0xdb, 0x3f, 0x4c, 0xcd, 0x10, 0xf9, 0x4d, 0x05, 0xe9, + 0x3d, 0x1b, 0x4e, 0xdc, 0x13, 0x33, 0x0a, 0x16, 0xf0, 0xeb, 0xa6, 0xe0, 0xdf, + 0x12, 0x08, 0xd6, 0x12, 0x00, 0x1b, 0x1b, 0xf6, 0x06, 0x38, 0xf5, 0xd2, 0x57, + 0xf5, 0xfa, 0x0b, 0xf3, 0x2f, 0x14, 0xfe, 0x26, 0xf2, 0xd3, 0xe5, 0x1e, 0xfb, + 0xdb, 0xea, 0xbe, 0x0b, 0x52, 0x0f, 0x16, 0xec, 0xef, 0x04, 0x0f, 0x34, 0x08, + 0xfa, 0x20, 0xc4, 0x01, 0x41, 0x18, 0xdf, 0xd0, 0xd0, 0x07, 0xf0, 0xf0, 0x11, + 0xf6, 0xc8, 0xee, 0x28, 0x14, 0xc6, 0xbf, 0xf6, 0xf4, 0x0f, 0x29, 0xf5, 0x1b, + 0x09, 0x09, 0x01, 0xe1, 0xf4, 0xc0, 0xe2, 0xe2, 0x13, 0x1a, 0xf8, 0x07, 0x07, + 0x08, 0xf2, 0xd0, 0xea, 0x0d, 0x4c, 0x01, 0xa6, 0x48, 0x04, 0x0a, 0x14, 0x90, + 0xfe, 0x0f, 0x2b, 0xa6, 0x7f, 0x84, 0x2d, 0x37, 0x07, 0xb2, 0xeb, 0x63, 0x0b, + 0xc9, 0xa5, 0xef, 0x35, 0x0c, 0xe3, 0x13, 0xf6, 0x20, 0xe5, 0xec, 0x09, 0x21, + 0x6b, 0xe2, 0x02, 0xc2, 0xd3, 0xe5, 0x13, 0xe6, 0x4a, 0x19, 0x9c, 0x24, 0x3b, + 0xba, 0xcb, 0xda, 0x00, 0x55, 0xee, 0x35, 0xad, 0xf2, 0x9a, 0x75, 0xe8, 0xf0, + 0x03, 0x0b, 0x17, 0xed, 0xd5, 0x18, 0xc9, 0xfe, 0xe0, 0xf6, 0xbd, 0xe8, 0xb8, + 0x53, 0xd8, 0xe8, 0x1f, 0x16, 0xd2, 0xdd, 0x1f, 0x50, 0x37, 0xf7, 0x54, 0x23, + 0x17, 0xd4, 0xd7, 0xd7, 0xf7, 0xd3, 0xd9, 0x08, 0x37, 0x21, 0xcf, 0xf5, 0x17, + 0xe3, 0xd9, 0xb6, 0xe5, 0x25, 0xd0, 0xee, 0x27, 0xd3, 0x46, 0x8b, 0x12, 0x21, + 0x26, 0x74, 0xaa, 0x10, 0x02, 0xff, 0x46, 0x31, 0x16, 0x30, 0xb2, 0x0b, 0x3e, + 0xc4, 0x30, 0x61, 0xfe, 0xf8, 0x4c, 0xb8, 0xfc, 0xee, 0x19, 0xf0, 0xcd, 0x1b, + 0x26, 0x35, 0x38, 0x0c, 0xe7, 0xf0, 0xfd, 0xec, 0xe5, 0x3d, 0xf0, 0x08, 0xd1, + 0x16, 0x16, 0x14, 0xce, 0x08, 0xfa, 0x25, 0xfb, 0xe6, 0x26, 0xd2, 0xfa, 0xff, + 0x04, 0xf4, 0x19, 0x0b, 0x01, 0x07, 0x17, 0xf4, 0x08, 0xdc, 0xc5, 0x08, 0xe0, + 0x4f, 0x24, 0xe6, 0xd5, 0x16, 0x19, 0xf9, 0xe8, 0xc6, 0xc9, 0xeb, 0x21, 0x06, + 0x2d, 0x15, 0xf2, 0x1a, 0xfa, 0xff, 0x0a, 0xf2, 0xfa, 0xeb, 0xa8, 0x03, 0xbe, + 0xd8, 0xf4, 0xf1, 0xfa, 0x35, 0x33, 0x46, 0xc1, 0xf7, 0x2b, 0xc3, 0xcb, 0xf6, + 0xd7, 0xf5, 0xf5, 0x34, 0x06, 0xde, 0x1c, 0x2c, 0xd7, 0xbf, 0xe8, 0xca, 0x22, + 0xff, 0x58, 0x14, 0xe0, 0xd9, 0xef, 0xd4, 0x33, 0x13, 0xff, 0x08, 0x19, 0xd7, + 0x81, 0x01, 0xf8, 0xea, 0xfb, 0x2b, 0x05, 0x16, 0x1b, 0x0e, 0xd8, 0xdf, 0x0f, + 0x1a, 0xfe, 0x15, 0x03, 0x2c, 0x07, 0x1c, 0xf4, 0xe5, 0xe0, 0xd9, 0x03, 0x03, + 0xff, 0xc4, 0x2f, 0x49, 0x12, 0xde, 0xd7, 0xc9, 0xf5, 0xfb, 0xfd, 0x23, 0x1e, + 0xf1, 0x20, 0xd7, 0xd1, 0x34, 0x1e, 0x29, 0xf3, 0x16, 0xf7, 0x34, 0x21, 0xd4, + 0x0c, 0xe0, 0xf8, 0xec, 0x2c, 0x06, 0xd0, 0x2d, 0x22, 0x09, 0x33, 0x64, 0xf2, + 0x32, 0xef, 0x1f, 0xea, 0xfd, 0xaf, 0xfd, 0xf7, 0xf0, 0x02, 0x2e, 0xfa, 0xcd, + 0xf0, 0xec, 0xea, 0xf8, 0xe7, 0x07, 0xe7, 0xe1, 0xde, 0xfb, 0x04, 0xe6, 0x00, + 0x00, 0xe9, 0x2a, 0x51, 0xdd, 0x2d, 0xf9, 0xfe, 0xdf, 0xed, 0xf3, 0x12, 0xba, + 0x81, 0x1f, 0x07, 0xe2, 0xe2, 0x08, 0xff, 0x00, 0x20, 0xe3, 0x28, 0xf9, 0xee, + 0xf2, 0x01, 0xfa, 0x3c, 0x1a, 0x11, 0xec, 0xff, 0x25, 0x1e, 0x29, 0xfb, 0x17, + 0xcb, 0xcd, 0x40, 0xf2, 0x03, 0xeb, 0xdf, 0xce, 0x07, 0x0f, 0x2d, 0xec, 0xe2, + 0x03, 0x17, 0x10, 0xf8, 0x16, 0xf3, 0xf2, 0x0a, 0xd4, 0xee, 0x3f, 0xfd, 0x1e, + 0x10, 0x46, 0xe7, 0xe5, 0xd5, 0xba, 0xed, 0xff, 0xf6, 0x58, 0x13, 0xda, 0x35, + 0xba, 0xe2, 0x1b, 0x25, 0xe7, 0xf1, 0xcc, 0xb3, 0x1e, 0x44, 0xed, 0x0e, 0xcc, + 0xe7, 0xe5, 0xeb, 0x36, 0xcb, 0x57, 0x0b, 0xc7, 0x32, 0x1d, 0x3c, 0x18, 0xd1, + 0xfd, 0x06, 0xdf, 0x07, 0xcf, 0xe0, 0x02, 0x1d, 0xed, 0x2e, 0xbf, 0x0d, 0xff, + 0x07, 0xc7, 0xf5, 0xe6, 0xd0, 0xf5, 0x00, 0xf8, 0x17, 0xfe, 0xfd, 0xe8, 0x3a, + 0xe7, 0x2b, 0x18, 0x4f, 0xf8, 0x2e, 0xfb, 0x2d, 0xa1, 0x01, 0xe9, 0x81, 0xe2, + 0xbb, 0x00, 0xcf, 0xf3, 0xc8, 0xf9, 0x57, 0xc9, 0x16, 0xd2, 0x22, 0xe9, 0x06, + 0xf2, 0x14, 0x15, 0x4a, 0xe9, 0xf4, 0x09, 0xef, 0x1a, 0x97, 0x20, 0xdf, 0xde, + 0x21, 0xfc, 0x0a, 0xdb, 0xd9, 0x02, 0xe9, 0xf5, 0xf9, 0xf4, 0x0f, 0x2b, 0x25, + 0x39, 0x0a, 0x36, 0x20, 0xf0, 0xef, 0x27, 0xfd, 0xeb, 0x5d, 0x08, 0xe1, 0xfe, + 0x46, 0xea, 0x50, 0x11, 0x0f, 0x23, 0xf2, 0xd1, 0x2d, 0x0c, 0x32, 0xed, 0x0b, + 0xd6, 0x25, 0xbc, 0x7f, 0x0e, 0xe6, 0xfc, 0x17, 0x47, 0xe7, 0x13, 0x3e, 0x15, + 0x1a, 0x13, 0xde, 0x12, 0x1d, 0x31, 0xee, 0xe9, 0x36, 0xe8, 0x24, 0xe7, 0x15, + 0x03, 0x03, 0x48, 0x24, 0xe3, 0xeb, 0x08, 0x09, 0xf9, 0x20, 0x17, 0xe5, 0xf7, + 0xec, 0xf7, 0x3b, 0x17, 0xaf, 0xfd, 0x02, 0x77, 0x22, 0x14, 0xe2, 0xe8, 0x1b, + 0xf0, 0xe4, 0x21, 0xb1, 0xcc, 0xfe, 0xec, 0xac, 0xc4, 0xc7, 0xc9, 0x03, 0xf8, + 0xde, 0xd9, 0xf3, 0xc3, 0xea, 0xed, 0xfb, 0x0c, 0x35, 0x22, 0x00, 0x64, 0x3b, + 0x09, 0x0b, 0x4e, 0x16, 0x22, 0x06, 0xf7, 0x6d, 0x09, 0xab, 0xed, 0xf6, 0x00, + 0x11, 0xb4, 0x0c, 0xf6, 0xf1, 0x26, 0xb2, 0x2b, 0x05, 0x04, 0x01, 0xa3, 0xd6, + 0x0c, 0x57, 0xe5, 0x07, 0x32, 0xf2, 0xf1, 0x00, 0xed, 0x24, 0xc1, 0xed, 0x12, + 0x45, 0xce, 0x35, 0xfd, 0xec, 0x2f, 0xd0, 0xed, 0xe8, 0xe5, 0x21, 0x0e, 0x0d, + 0x6c, 0x68, 0xcb, 0xdd, 0x20, 0x23, 0x30, 0xea, 0x20, 0x18, 0x1a, 0xee, 0xf1, + 0xaf, 0xef, 0xfb, 0xe2, 0xa3, 0xc0, 0xee, 0xf2, 0x7f, 0x82, 0x28, 0x36, 0x2e, + 0xf7, 0x12, 0x07, 0xc3, 0xee, 0xe2, 0x16, 0xea, 0x2f, 0x0a, 0xfc, 0x0b, 0xef, + 0x11, 0xb6, 0xcb, 0x18, 0xdc, 0x0c, 0x30, 0x3c, 0x0b, 0x39, 0x41, 0xe3, 0xe3, + 0x08, 0xff, 0x4c, 0xbb, 0xaf, 0x09, 0x6a, 0x0a, 0xd0, 0xe6, 0x1a, 0x1b, 0xea, + 0x29, 0x27, 0xdc, 0xe2, 0xc0, 0x1e, 0xff, 0xcf, 0x2c, 0x37, 0x3b, 0x05, 0xe8, + 0xb9, 0x33, 0xd0, 0x00, 0xdb, 0x20, 0xc7, 0x41, 0xc3, 0x0a, 0xf0, 0x20, 0x54, + 0x01, 0x0b, 0xd6, 0xef, 0x07, 0x18, 0x42, 0xcf, 0x26, 0x5b, 0xce, 0xf2, 0xea, + 0xfb, 0x0a, 0x2d, 0xf8, 0x02, 0xe2, 0xcd, 0xd2, 0x36, 0x02, 0x10, 0x27, 0x1b, + 0xca, 0x33, 0x34, 0xdb, 0xf5, 0x33, 0xdd, 0x1a, 0x0e, 0x3c, 0xd5, 0xd9, 0x16, + 0x15, 0x15, 0x0c, 0xe4, 0x15, 0x1d, 0x21, 0x20, 0x02, 0xf0, 0xe2, 0x3f, 0xd2, + 0x28, 0x16, 0xf7, 0x3d, 0xca, 0xca, 0x1e, 0xc9, 0xdf, 0x2d, 0xe4, 0x21, 0xe8, + 0xbe, 0x21, 0x2d, 0x06, 0xe5, 0xfc, 0x11, 0xf9, 0xfb, 0x2c, 0xeb, 0x39, 0x33, + 0x07, 0x06, 0x08, 0xc0, 0xee, 0xe9, 0xe5, 0x81, 0xf7, 0x04, 0x1c, 0x39, 0xff, + 0xf2, 0x13, 0x13, 0xf7, 0xc6, 0x46, 0xdc, 0xad, 0x04, 0xf7, 0x0b, 0x09, 0x04, + 0xde, 0x20, 0xdc, 0x00, 0xe3, 0x16, 0xd4, 0xde, 0xbf, 0xba, 0xe5, 0x62, 0xe7, + 0xf6, 0xde, 0xde, 0xd9, 0x30, 0xee, 0xf8, 0x00, 0x01, 0xdf, 0x05, 0xdf, 0xef, + 0x31, 0xec, 0xda, 0x1c, 0xf0, 0x00, 0x1b, 0xbf, 0xdc, 0xc1, 0x19, 0xe4, 0x2e, + 0xef, 0x15, 0x03, 0xd8, 0x1d, 0xdd, 0x02, 0x2b, 0x2b, 0xf1, 0xf8, 0x3d, 0x1d, + 0xfe, 0x1f, 0xce, 0x37, 0x35, 0xd6, 0x0f, 0xfb, 0x20, 0xb3, 0xe3, 0x33, 0xf7, + 0xc9, 0xd3, 0x0e, 0xe8, 0x07, 0x1a, 0xea, 0x04, 0xf4, 0xf7, 0x0c, 0x13, 0x4c, + 0x04, 0xe2, 0xd5, 0x0e, 0xbb, 0x1f, 0xde, 0xfb, 0x9e, 0x99, 0x12, 0x8c, 0xeb, + 0x43, 0xe3, 0xf8, 0x09, 0xe0, 0x1a, 0xe1, 0xdc, 0x16, 0x0d, 0x15, 0x09, 0x0b, + 0xbc, 0xf5, 0xfe, 0x23, 0x2f, 0xe6, 0x27, 0xed, 0xe1, 0x21, 0xd5, 0x44, 0xf1, + 0xe3, 0xed, 0xff, 0xb1, 0xeb, 0xf6, 0xe0, 0x13, 0xfe, 0x41, 0x08, 0xf9, 0x12, + 0xfb, 0x1a, 0xf7, 0x3c, 0x01, 0xdf, 0x7f, 0x12, 0xe2, 0x76, 0x24, 0x19, 0xf0, + 0xd3, 0x5e, 0xe8, 0xeb, 0x13, 0xda, 0x07, 0x17, 0xe6, 0x0a, 0x05, 0xf6, 0x17, + 0xd5, 0xcf, 0xe5, 0x0e, 0xc6, 0x3e, 0xd9, 0x00, 0xb1, 0x16, 0xec, 0xce, 0x23, + 0x6e, 0xdd, 0xdc, 0x3c, 0xd9, 0xd8, 0x13, 0xde, 0xf8, 0x19, 0xf8, 0x63, 0xca, + 0x11, 0xa3, 0xf3, 0x86, 0x0c, 0x31, 0x12, 0x16, 0x9f, 0xe1, 0xf0, 0xb9, 0x04, + 0xa3, 0xea, 0x01, 0x12, 0x19, 0x38, 0xd1, 0x2e, 0x44, 0x01, 0xfa, 0xb8, 0xcd, + 0xf1, 0x02, 0xd8, 0x66, 0xeb, 0x45, 0xea, 0xca, 0xf1, 0xb7, 0xe9, 0xf2, 0xe4, + 0xc5, 0x08, 0x02, 0xf9, 0x14, 0xfe, 0x11, 0x33, 0x2e, 0xe1, 0x21, 0x34, 0x13, + 0x2a, 0xf0, 0x24, 0xcc, 0xb9, 0x36, 0xd1, 0xbf, 0xbf, 0xcf, 0x59, 0xc7, 0x81, + 0x13, 0xa2, 0xfb, 0x0d, 0xf3, 0xdc, 0x0d, 0xc7, 0xf5, 0xd8, 0xbe, 0x05, 0xd5, + 0xe6, 0x23, 0x76, 0xda, 0xf3, 0x19, 0x26, 0xfb, 0x34, 0xd9, 0x13, 0x40, 0x0d, + 0x9f, 0x41, 0x7b, 0xfb, 0x04, 0x1b, 0xcc, 0x32, 0x21, 0x1c, 0x15, 0x1b, 0xee, + 0x4e, 0xe5, 0x0c, 0x04, 0x46, 0xe4, 0xfd, 0xd8, 0xf1, 0xf3, 0xe8, 0x14, 0x21, + 0xed, 0xfc, 0x0f, 0x2e, 0xf3, 0xf1, 0xcc, 0xd5, 0xfa, 0xeb, 0xe6, 0x25, 0x7f, + 0x0f, 0x15, 0xf5, 0x1a, 0x24, 0x53, 0x1a, 0x5b, 0xee, 0xde, 0x00, 0x55, 0xf4, + 0xf9, 0xe1, 0xd9, 0x05, 0x27, 0xd3, 0x46, 0x22, 0x0a, 0x05, 0x39, 0xe0, 0x0c, + 0x2f, 0xdb, 0xfd, 0xfe, 0x13, 0xcf, 0xb3, 0xc1, 0x0c, 0xe3, 0x08, 0xde, 0xe5, + 0x24, 0xe7, 0xd3, 0x34, 0xfa, 0x0b, 0x10, 0x33, 0xe3, 0xd9, 0x01, 0x09, 0x14, + 0xed, 0x21, 0xdc, 0xf4, 0xc0, 0x1f, 0x54, 0xcc, 0x2b, 0x15, 0xf3, 0xf4, 0xc1, + 0x12, 0x14, 0xfd, 0xe0, 0xee, 0x08, 0x0c, 0xdc, 0xdf, 0xe0, 0x03, 0x04, 0x0e, + 0xe9, 0xd7, 0xfd, 0xfc, 0xee, 0x00, 0xf3, 0xfc, 0xfb, 0xf6, 0x07, 0xee, 0x16, + 0xf4, 0xfa, 0xfc, 0xff, 0xf2, 0xda, 0x03, 0x03, 0x05, 0xdf, 0xfa, 0xef, 0x66, + 0x26, 0xb2, 0x14, 0x0a, 0x13, 0x05, 0xff, 0x0b, 0x3e, 0x19, 0x1a, 0x13, 0x0f, + 0x4a, 0x18, 0x0d, 0x33, 0x0e, 0x04, 0x01, 0x42, 0x3b, 0x35, 0x1d, 0xeb, 0x18, + 0x16, 0x1f, 0x0d, 0x0b, 0x36, 0x16, 0x21, 0x15, 0x19, 0xcd, 0x13, 0x23, 0xf8, + 0x14, 0x02, 0x19, 0x3e, 0x1e, 0x10, 0x2a, 0x0d, 0x41, 0xfa, 0x0c, 0x00, 0x07, + 0x21, 0x19, 0x2f, 0x18, 0x04, 0x24, 0xf4, 0x06, 0x11, 0x1e, 0x02, 0x25, 0x3b, + 0x16, 0x08, 0x0c, 0xfc, 0xd6, 0x07, 0xe8, 0x1e, 0xea, 0x08, 0x10, 0xf6, 0x10, + 0x7f, 0x1a, 0x01, 0x1b, 0x2f, 0xf9, 0x26, 0xf6, 0x13, 0xe7, 0xe6, 0xef, 0x33, + 0xfa, 0x22, 0xe3, 0x19, 0xf9, 0x14, 0x20, 0x11, 0x24, 0xee, 0xf9, 0xfa, 0xeb, + 0xec, 0xf6, 0xf8, 0x23, 0xdc, 0x05, 0x15, 0x0c, 0xf3, 0xfd, 0xde, 0x3c, 0xfb, + 0xe0, 0xf3, 0x2c, 0x1e, 0x08, 0xf7, 0x0e, 0xe9, 0xeb, 0x06, 0x3c, 0x11, 0xf3, + 0x39, 0xf7, 0xf2, 0x16, 0xe8, 0xdc, 0xe5, 0x18, 0x3b, 0xbc, 0x07, 0x24, 0x06, + 0xed, 0xe6, 0xcb, 0x12, 0x06, 0xef, 0x25, 0x1e, 0x0b, 0x1f, 0xb3, 0x08, 0x50, + 0x1b, 0x14, 0x02, 0x1e, 0x11, 0x8b, 0x13, 0xf2, 0x18, 0xbe, 0xba, 0xda, 0x20, + 0x3f, 0xdc, 0x38, 0xe7, 0xea, 0x2a, 0x69, 0xd3, 0x26, 0x07, 0x11, 0x04, 0xd2, + 0x10, 0xdd, 0xe8, 0x3c, 0x0c, 0x0c, 0xec, 0xe7, 0x19, 0x02, 0xbe, 0xbc, 0xf8, + 0xed, 0xe7, 0xfd, 0xf4, 0xdb, 0x33, 0x18, 0x00, 0xda, 0xd6, 0x7f, 0x3c, 0x17, + 0xb1, 0xcb, 0x67, 0x2f, 0xc0, 0x28, 0x48, 0xaf, 0xe2, 0x1e, 0xf7, 0xe7, 0xdd, + 0x1f, 0xdf, 0x27, 0x09, 0x09, 0xf8, 0xd0, 0x3e, 0x19, 0x32, 0x13, 0xd5, 0xe7, + 0xdb, 0x1b, 0x28, 0x95, 0x17, 0xf1, 0xcf, 0xb5, 0x20, 0x00, 0xf5, 0xf6, 0xd3, + 0x3f, 0xdc, 0xe1, 0x0d, 0xfb, 0x32, 0xe0, 0x09, 0x1e, 0xe2, 0x31, 0xdd, 0x02, + 0x1c, 0xc7, 0x0b, 0xf2, 0xdb, 0x48, 0xf4, 0x20, 0xf0, 0x14, 0x3a, 0x1b, 0xcd, + 0xd4, 0xf5, 0xf0, 0xc1, 0x81, 0xef, 0xf1, 0xd8, 0xf3, 0xac, 0xce, 0x01, 0xa9, + 0x39, 0x24, 0xea, 0xe0, 0x13, 0xf1, 0x3d, 0xc0, 0xe2, 0xd8, 0xce, 0x2d, 0x21, + 0xe9, 0xde, 0xc0, 0x70, 0xd3, 0xd8, 0x03, 0xf6, 0xc2, 0x24, 0x04, 0xd1, 0x07, + 0x1b, 0x06, 0xfb, 0x06, 0xfb, 0x15, 0xb9, 0x1d, 0xd4, 0xd3, 0xce, 0x0a, 0x0e, + 0x0b, 0x35, 0xc5, 0x1a, 0x11, 0xd7, 0xf4, 0xfd, 0xfe, 0xe1, 0xec, 0x2b, 0x26, + 0xac, 0x76, 0x25, 0x40, 0xe4, 0x03, 0xa9, 0xb6, 0xf6, 0xf1, 0x07, 0x2e, 0x1f, + 0xf2, 0xf7, 0x28, 0x07, 0xf2, 0x37, 0xd6, 0xef, 0xf2, 0x21, 0xe8, 0xe9, 0xed, + 0x3e, 0xfb, 0x2b, 0x01, 0xf2, 0x06, 0xe3, 0xb2, 0xed, 0x08, 0xe1, 0xee, 0xd8, + 0x0d, 0xe8, 0xd9, 0x17, 0x3c, 0xfd, 0xd4, 0xb2, 0x24, 0x27, 0x18, 0x18, 0xf6, + 0xdf, 0xf4, 0xd9, 0xf7, 0xfa, 0x18, 0x66, 0x13, 0x22, 0xf9, 0xd8, 0xcc, 0x3b, + 0x22, 0xc8, 0x03, 0xe1, 0x71, 0x4a, 0x09, 0xf5, 0x12, 0x03, 0x0d, 0x26, 0x0d, + 0xea, 0xf5, 0xcc, 0xe4, 0xf4, 0x22, 0xab, 0x08, 0x1b, 0x5d, 0xbf, 0x6b, 0xe4, + 0xfb, 0x21, 0xde, 0xe2, 0x53, 0x24, 0x33, 0x06, 0x11, 0xc8, 0x0c, 0x0f, 0x12, + 0x05, 0xfd, 0xe3, 0xf5, 0x1e, 0xdd, 0x41, 0x07, 0xd0, 0xe1, 0xcd, 0xbf, 0x17, + 0x24, 0x2e, 0xe8, 0x20, 0x08, 0x01, 0xb9, 0x4b, 0xd1, 0x2e, 0xf8, 0xf5, 0x2a, + 0xf6, 0xfd, 0x1d, 0x10, 0xc0, 0xd9, 0xda, 0x1d, 0x2d, 0x18, 0x28, 0xfb, 0x5d, + 0x32, 0xbc, 0xf7, 0x41, 0x03, 0xe6, 0xdc, 0x3a, 0x1d, 0x14, 0xb2, 0x04, 0x7f, + 0xec, 0xf1, 0x26, 0xea, 0x2b, 0xe4, 0xed, 0x13, 0x0e, 0xe0, 0x04, 0x08, 0x0a, + 0x1a, 0xf7, 0xf4, 0x2c, 0xcc, 0x27, 0x3c, 0xe8, 0x37, 0xbb, 0x2f, 0x35, 0x18, + 0x32, 0x11, 0x41, 0xa4, 0xe4, 0xff, 0xeb, 0xea, 0xfc, 0xde, 0x00, 0xda, 0xc1, + 0x4a, 0xd4, 0xd7, 0xc4, 0x33, 0xcf, 0x27, 0x20, 0xcb, 0x34, 0x06, 0x08, 0xca, + 0xcb, 0x47, 0xdc, 0xea, 0x28, 0xd0, 0xdd, 0xe1, 0x24, 0xd6, 0x04, 0xbf, 0x0a, + 0x30, 0x23, 0x00, 0xdb, 0x14, 0xf9, 0xf3, 0xf3, 0x52, 0xdd, 0xd5, 0xc7, 0xa9, + 0x19, 0xc8, 0xff, 0x19, 0x20, 0xdc, 0x43, 0xf4, 0xd2, 0x0b, 0xcf, 0x20, 0xd0, + 0x22, 0x3b, 0x17, 0x31, 0xa6, 0x7f, 0xe0, 0x57, 0x08, 0x61, 0x1a, 0x25, 0xe7, + 0x27, 0x27, 0x20, 0x0d, 0xc0, 0x0e, 0xe2, 0x2e, 0xf0, 0x06, 0xf1, 0x0f, 0xe5, + 0x09, 0x11, 0xd9, 0xdd, 0x25, 0x96, 0x27, 0xde, 0x03, 0x1f, 0xff, 0x1d, 0xfa, + 0xe6, 0x02, 0x35, 0xf9, 0xfa, 0x43, 0x29, 0x33, 0xf8, 0xf1, 0xc1, 0x3e, 0xe6, + 0x26, 0x2a, 0x1b, 0xd4, 0x1c, 0x2d, 0x00, 0x8f, 0xe5, 0xdb, 0x14, 0xfc, 0x96, + 0x41, 0xf7, 0x04, 0x16, 0x1a, 0xc3, 0xfb, 0xec, 0x4b, 0x01, 0xa3, 0x07, 0xe3, + 0xca, 0x15, 0xa4, 0x2f, 0x01, 0x25, 0x7f, 0xee, 0xe6, 0x21, 0x53, 0xde, 0x35, + 0x01, 0x08, 0x13, 0x05, 0xd2, 0x3f, 0xd5, 0xf8, 0x2b, 0x18, 0xaf, 0xe5, 0xd0, + 0xfc, 0x66, 0xf2, 0xd8, 0xfc, 0x14, 0xbf, 0x0c, 0xe6, 0x53, 0x17, 0x26, 0x24, + 0x46, 0x2b, 0xe5, 0x14, 0xf5, 0xde, 0x1a, 0xdf, 0xe2, 0xf9, 0x46, 0x22, 0x02, + 0xf2, 0xc7, 0xa6, 0xcb, 0xbc, 0xf9, 0xe9, 0x4c, 0xc6, 0x33, 0xe7, 0xab, 0xd8, + 0x07, 0x09, 0x4f, 0x0c, 0x1e, 0xe6, 0xd2, 0x2c, 0xca, 0xf1, 0x41, 0xca, 0xf8, + 0x17, 0xf6, 0x31, 0x34, 0x01, 0xdd, 0x2a, 0xed, 0xf1, 0xb9, 0xe1, 0xfe, 0x26, + 0x42, 0x2d, 0x1b, 0x3f, 0xf7, 0x14, 0xec, 0x08, 0xf1, 0xea, 0x12, 0xcc, 0xd3, + 0x24, 0xf9, 0xc0, 0xe0, 0xea, 0xfb, 0x26, 0xfb, 0x1c, 0x20, 0x1b, 0xc4, 0x37, + 0xfc, 0x1e, 0x15, 0xfb, 0x09, 0x2d, 0x14, 0x0d, 0x3d, 0x1e, 0x03, 0xf2, 0xf2, + 0xd4, 0xf4, 0x35, 0xf7, 0x0f, 0xf2, 0xe7, 0x35, 0x21, 0xf2, 0xc6, 0x0a, 0x31, + 0xee, 0xf4, 0x2d, 0x0a, 0x14, 0x15, 0x0a, 0x1d, 0x01, 0x14, 0xf6, 0xfb, 0x2a, + 0x2e, 0x3d, 0x30, 0x03, 0x0c, 0x2a, 0x2d, 0x04, 0xf0, 0x1e, 0x0f, 0xee, 0x05, + 0x3e, 0xe5, 0x4d, 0xfe, 0xe1, 0xea, 0x2c, 0x47, 0xe8, 0x4d, 0x7f, 0xd4, 0x2d, + 0xae, 0xe6, 0x00, 0x0a, 0x28, 0xf2, 0xe9, 0x34, 0x0b, 0xd8, 0x59, 0x2b, 0xfe, + 0x23, 0x14, 0x3c, 0x01, 0x28, 0xe2, 0xfd, 0x0c, 0x21, 0xef, 0x21, 0xc3, 0x35, + 0x2e, 0x32, 0xe5, 0x0d, 0xf7, 0xf2, 0x3c, 0xfd, 0x68, 0xc8, 0x23, 0x19, 0x73, + 0x06, 0xe2, 0x23, 0x24, 0x2f, 0xf2, 0xff, 0x1d, 0x0b, 0x24, 0x31, 0x1b, 0x1a, + 0x14, 0x07, 0xe8, 0xeb, 0x34, 0x00, 0xf7, 0x2b, 0xea, 0x12, 0x35, 0x58, 0xc8, + 0xfe, 0xf5, 0x24, 0xfa, 0x23, 0x15, 0x0d, 0xde, 0xfe, 0x52, 0xf5, 0xfd, 0x21, + 0x32, 0x11, 0x18, 0xd2, 0x0b, 0x0d, 0x3a, 0xd2, 0xba, 0xb1, 0x04, 0xe7, 0x02, + 0x29, 0x64, 0xa5, 0x2d, 0x4e, 0x0f, 0x99, 0xfe, 0x0f, 0xc2, 0x00, 0xdd, 0xec, + 0xf6, 0xab, 0x15, 0x0a, 0xd1, 0xe3, 0x4d, 0xe5, 0xda, 0x16, 0x0c, 0x12, 0xe9, + 0x93, 0x29, 0xe4, 0xf1, 0x09, 0x55, 0xfb, 0xe3, 0x07, 0x10, 0xea, 0xcf, 0x28, + 0xde, 0x00, 0x41, 0xeb, 0x26, 0xd4, 0xcb, 0xfc, 0x35, 0xe7, 0xb8, 0xce, 0xeb, + 0xd0, 0xf8, 0x01, 0x00, 0x07, 0xfe, 0xc4, 0xea, 0x39, 0x07, 0x21, 0x28, 0x24, + 0x0d, 0xe9, 0xb9, 0xfc, 0x23, 0x0e, 0xe2, 0x5f, 0x11, 0x21, 0xc7, 0xee, 0xcd, + 0x36, 0x03, 0xf9, 0xe7, 0xf5, 0xee, 0xec, 0xf9, 0x7f, 0xcf, 0xfc, 0xed, 0xff, + 0xea, 0x0a, 0xd9, 0x01, 0x28, 0xda, 0xff, 0x0a, 0xff, 0xdc, 0xcf, 0x2e, 0x03, + 0x40, 0x01, 0x1c, 0x16, 0xdb, 0xd8, 0xe1, 0x1a, 0x23, 0x1d, 0xf0, 0xf3, 0xe3, + 0x7f, 0x33, 0xea, 0xed, 0xfd, 0x05, 0x2f, 0xe7, 0x09, 0x09, 0xf1, 0xe0, 0x1c, + 0xf7, 0x27, 0xf3, 0xb3, 0x70, 0xd2, 0xee, 0x1c, 0x4b, 0xdd, 0x3d, 0x05, 0xd0, + 0xf1, 0xe6, 0xe2, 0x0c, 0x03, 0xd3, 0xe7, 0x09, 0x17, 0xfd, 0x0f, 0x22, 0x07, + 0x22, 0xbf, 0x40, 0x0d, 0xe7, 0x3b, 0x39, 0x1d, 0xf8, 0xc5, 0xcd, 0xb0, 0xf6, + 0x30, 0xc2, 0x12, 0x2d, 0xf7, 0xd8, 0xf9, 0xd8, 0xdc, 0x01, 0xee, 0xd4, 0xd7, + 0xdc, 0xff, 0xe8, 0x05, 0xf2, 0xe1, 0x0a, 0xf4, 0x64, 0x1f, 0xf1, 0xf3, 0xd4, + 0x2a, 0xda, 0x29, 0xde, 0x04, 0x40, 0x15, 0x0b, 0x2a, 0xf8, 0xea, 0x02, 0x9a, + 0xf6, 0x22, 0x01, 0x12, 0xc4, 0x1d, 0x2d, 0x41, 0x1c, 0xcd, 0x77, 0xaf, 0xeb, + 0xee, 0xf0, 0x04, 0xf5, 0x20, 0x35, 0x12, 0xe8, 0x7f, 0xf6, 0x1e, 0xc4, 0xca, + 0x1e, 0x15, 0x4c, 0xd1, 0xf2, 0xea, 0x73, 0x00, 0xe7, 0xfd, 0x07, 0x1b, 0xea, + 0xb2, 0xdf, 0xf9, 0x0d, 0xd6, 0x3e, 0xa3, 0xc8, 0x0b, 0x20, 0xe7, 0xfa, 0xf7, + 0x0a, 0x22, 0x69, 0xc4, 0xc7, 0xd2, 0x22, 0xc0, 0xcc, 0x29, 0xad, 0xef, 0xe7, + 0x35, 0x27, 0x3b, 0x1a, 0x07, 0xd2, 0x0d, 0xd3, 0xc9, 0x1d, 0x31, 0x02, 0x0d, + 0x22, 0x31, 0x06, 0xfd, 0x14, 0x2c, 0x0c, 0x20, 0x93, 0xf0, 0xaa, 0xe8, 0xfb, + 0x01, 0x07, 0x2a, 0x1c, 0x1a, 0x06, 0xec, 0xff, 0xe5, 0x4a, 0x14, 0xba, 0x08, + 0xbd, 0x79, 0xd2, 0xf9, 0x0a, 0x24, 0x14, 0x12, 0xe1, 0xa9, 0x24, 0xc9, 0xdc, + 0xe3, 0x27, 0x28, 0x20, 0x18, 0x34, 0x25, 0x27, 0xb7, 0x93, 0x12, 0xf7, 0x06, + 0x15, 0xf0, 0x20, 0x30, 0x00, 0xf2, 0x6c, 0xd9, 0xfd, 0x14, 0x3c, 0x03, 0xf6, + 0x09, 0xe3, 0xfc, 0xe5, 0xd3, 0x02, 0xde, 0xc4, 0xe3, 0xe2, 0x2b, 0x27, 0x38, + 0xe1, 0xe8, 0x16, 0x26, 0xd8, 0xd0, 0xdf, 0xcd, 0xc9, 0x1e, 0xc4, 0x33, 0xf8, + 0x58, 0xd4, 0x2e, 0x2e, 0xfd, 0xd2, 0x02, 0x41, 0xd6, 0x09, 0xf0, 0x0c, 0x5e, + 0xf0, 0xf4, 0xed, 0xea, 0xf8, 0x41, 0x09, 0xe6, 0xd0, 0xfe, 0xf4, 0xda, 0x32, + 0xda, 0x3d, 0xe6, 0xfc, 0x36, 0x37, 0xea, 0x12, 0xf7, 0x0b, 0x33, 0x08, 0x1b, + 0x01, 0x2a, 0xe1, 0xda, 0xf5, 0x1d, 0x11, 0x11, 0xfe, 0xff, 0xef, 0xcf, 0x3d, + 0x7f, 0xe3, 0xf1, 0xdc, 0x06, 0xe0, 0x1d, 0xe2, 0x09, 0x23, 0x18, 0xf0, 0x2e, + 0x0e, 0xfb, 0xfd, 0x0b, 0x29, 0xf1, 0xf2, 0x18, 0xf2, 0x09, 0xf3, 0x09, 0x20, + 0x3f, 0xd2, 0xce, 0x29, 0x54, 0xe3, 0x31, 0xd2, 0x1a, 0x1d, 0x0b, 0x17, 0x0e, + 0xd2, 0xe9, 0x08, 0x39, 0x16, 0xde, 0x09, 0x1d, 0x22, 0x0c, 0xd0, 0x17, 0xf1, + 0xea, 0x19, 0x3d, 0x60, 0x16, 0x45, 0x23, 0x0b, 0xc9, 0xce, 0xdc, 0xce, 0xf7, + 0x1b, 0xe4, 0x15, 0xf3, 0x02, 0x11, 0x04, 0x5b, 0x2a, 0x0d, 0x52, 0x55, 0xf4, + 0xc4, 0x26, 0x07, 0xef, 0x2d, 0x7a, 0x0b, 0x31, 0x6f, 0x15, 0xf3, 0xf0, 0x38, + 0x28, 0xfa, 0x26, 0xd3, 0x08, 0xf0, 0xe1, 0x02, 0xe5, 0x23, 0x0e, 0xfc, 0xdf, + 0xfa, 0x23, 0xff, 0x7e, 0x04, 0x2c, 0x08, 0xe8, 0xe9, 0x11, 0x51, 0x61, 0x1e, + 0x24, 0x21, 0x57, 0xcf, 0x29, 0xfc, 0x1c, 0xdb, 0x23, 0x3f, 0x25, 0xf5, 0x07, + 0xfd, 0xf7, 0xeb, 0x0e, 0xf8, 0x0e, 0x20, 0xe9, 0xf6, 0x04, 0x25, 0xe5, 0x1a, + 0xe8, 0x23, 0x60, 0xe6, 0x32, 0xf0, 0xec, 0xf8, 0xec, 0x7f, 0x00, 0x20, 0x6b, + 0xd7, 0xf6, 0x6f, 0x10, 0x05, 0x3d, 0xec, 0xf0, 0x24, 0x21, 0xdb, 0xe0, 0xcd, + 0x38, 0x15, 0x31, 0x46, 0xd3, 0xf4, 0x0f, 0x12, 0x00, 0x1e, 0x12, 0x17, 0xdd, + 0xfa, 0x10, 0xf0, 0xfb, 0x28, 0xda, 0x1b, 0xfb, 0x27, 0x01, 0x04, 0xe4, 0xcc, + 0xec, 0x0b, 0x18, 0x26, 0xe0, 0x48, 0xe5, 0xcd, 0x16, 0x12, 0x0c, 0x24, 0xea, + 0x1a, 0xee, 0x25, 0x38, 0x1a, 0x0e, 0x29, 0x0c, 0x26, 0x02, 0x28, 0xf4, 0x06, + 0x3a, 0x11, 0xf4, 0xfb, 0x00, 0x08, 0x02, 0x15, 0xe4, 0xf0, 0xf9, 0x0b, 0xfc, + 0x36, 0x33, 0x0f, 0x04, 0xf9, 0x20, 0x19, 0x01, 0x5a, 0x10, 0x25, 0x43, 0x11, + 0x08, 0xe3, 0x22, 0x2e, 0xf2, 0x26, 0xfc, 0xd6, 0x34, 0x16, 0x00, 0x2e, 0x19, + 0xdb, 0x01, 0x21, 0xf1, 0xdf, 0x1d, 0x16, 0xfa, 0x26, 0xce, 0xe9, 0xe3, 0xd6, + 0x22, 0x35, 0x06, 0xf4, 0x1d, 0x06, 0x2c, 0xfd, 0x1e, 0x52, 0x0e, 0x0f, 0x19, + 0x7f, 0xfc, 0xe5, 0x07, 0x20, 0xe3, 0x22, 0x01, 0x03, 0x1c, 0x0a, 0x2a, 0x0d, + 0x32, 0x26, 0x01, 0xdd, 0xf1, 0xb2, 0xfb, 0x05, 0xc6, 0xf4, 0xc9, 0x03, 0x0c, + 0xf5, 0xf0, 0xdc, 0xf2, 0xf6, 0xef, 0x0d, 0xb7, 0xf0, 0x11, 0xc2, 0x36, 0xd2, + 0x15, 0xd9, 0xd2, 0x7f, 0xdf, 0xd2, 0x1d, 0xec, 0x18, 0x01, 0xc3, 0x0a, 0xfe, + 0xfc, 0xda, 0x17, 0x37, 0xeb, 0x56, 0xd7, 0x0f, 0xa8, 0xfb, 0xb4, 0x35, 0xde, + 0x38, 0x2a, 0xa3, 0xf1, 0xd7, 0xe5, 0x2b, 0x0b, 0x02, 0xcd, 0x2a, 0x42, 0xd5, + 0xf0, 0xed, 0xfc, 0x10, 0x2c, 0x0f, 0x0a, 0x18, 0xe0, 0x45, 0x27, 0xde, 0xfd, + 0xe6, 0xdf, 0xf1, 0xfd, 0xea, 0xaf, 0x26, 0xfe, 0x0f, 0x09, 0x4c, 0xbc, 0x33, + 0x0f, 0xf6, 0x13, 0xec, 0x2e, 0xf3, 0xf8, 0xe7, 0xf9, 0xea, 0x04, 0x42, 0x10, + 0x09, 0xdf, 0xdf, 0xfe, 0xfb, 0xac, 0xe9, 0xb3, 0xc9, 0x18, 0xe9, 0x07, 0xf4, + 0xdd, 0xeb, 0x0a, 0xf3, 0x1f, 0xde, 0xad, 0xf5, 0x19, 0x60, 0x1a, 0xdc, 0xb6, + 0xe1, 0x14, 0xf2, 0xba, 0x3c, 0x0c, 0x20, 0x0f, 0x38, 0xe5, 0xe5, 0xe9, 0x34, + 0xfa, 0xbf, 0x48, 0xa3, 0xc3, 0x0a, 0x28, 0x13, 0xfe, 0x17, 0xf6, 0x3a, 0x59, + 0x34, 0xf1, 0x0a, 0x1e, 0xe8, 0x9d, 0xf8, 0x1c, 0xdb, 0xdb, 0x50, 0xc6, 0xdd, + 0x31, 0xcc, 0xc4, 0x0d, 0xb1, 0xb3, 0x48, 0x1b, 0x35, 0xca, 0x30, 0xce, 0xd1, + 0x81, 0x64, 0x95, 0x4f, 0x31, 0xd1, 0xe5, 0xe1, 0xf2, 0x05, 0xda, 0xc1, 0x20, + 0xf6, 0xa4, 0x02, 0x12, 0xe5, 0xa1, 0xd0, 0xf6, 0x2f, 0x23, 0xdc, 0x28, 0x35, + 0x4c, 0x28, 0xe0, 0x05, 0x07, 0xc7, 0x18, 0xc3, 0x01, 0xc4, 0xf3, 0xdc, 0xec, + 0x2d, 0x02, 0x12, 0x0e, 0x18, 0xe0, 0x08, 0xe1, 0x0b, 0xcf, 0x0d, 0xe1, 0xb5, + 0x34, 0xbb, 0xf3, 0x07, 0x2f, 0x11, 0xfc, 0xfc, 0x42, 0xf2, 0x15, 0x3a, 0x55, + 0xf2, 0xf2, 0xd9, 0xfb, 0xcc, 0xdc, 0x35, 0x13, 0x11, 0x0a, 0x03, 0xe9, 0xf7, + 0xf9, 0x5c, 0xe3, 0xee, 0xd4, 0x19, 0x34, 0xec, 0x49, 0x16, 0x29, 0x0e, 0xd7, + 0xe0, 0xcf, 0xef, 0x21, 0xfc, 0xf2, 0x11, 0x0c, 0xf5, 0x14, 0x1b, 0x17, 0xbd, + 0x08, 0x2c, 0xfa, 0xf3, 0x41, 0xc2, 0x00, 0xef, 0xd7, 0x25, 0xf6, 0x03, 0x00, + 0xd6, 0x10, 0xfc, 0x59, 0x08, 0xeb, 0x32, 0xbf, 0x1a, 0xb9, 0x22, 0x40, 0x2f, + 0x6a, 0x1f, 0xff, 0x11, 0xf8, 0xe9, 0xf0, 0xd9, 0xcd, 0x00, 0xdd, 0xe1, 0xcd, + 0x58, 0x06, 0xd2, 0xf2, 0xa8, 0xf3, 0x06, 0x21, 0x18, 0x1a, 0x06, 0x14, 0xe0, + 0xf5, 0x2c, 0x1f, 0x24, 0x0f, 0xc5, 0xf9, 0x05, 0x28, 0xcd, 0x06, 0xe0, 0xc3, + 0x22, 0x16, 0x16, 0x0f, 0x32, 0x2d, 0xfe, 0x1a, 0xf8, 0xf7, 0x29, 0x28, 0xd7, + 0x19, 0xeb, 0x4b, 0xe6, 0x07, 0x19, 0xd9, 0xf6, 0x05, 0x03, 0x08, 0xc3, 0xea, + 0xfb, 0x2d, 0xb6, 0xe8, 0x02, 0x31, 0xcd, 0xdf, 0x7f, 0xf3, 0xfc, 0x17, 0x04, + 0x12, 0x3c, 0xf3, 0x6b, 0x05, 0x02, 0xeb, 0x4a, 0xf8, 0x33, 0xe8, 0x23, 0x3b, + 0x07, 0x35, 0x4a, 0xf3, 0x81, 0xf7, 0x21, 0x0e, 0x49, 0x1b, 0x05, 0x30, 0xb7, + 0x37, 0x21, 0xf1, 0xee, 0x16, 0x2b, 0x10, 0x0c, 0x0c, 0xdc, 0x30, 0x02, 0xe9, + 0x29, 0xcc, 0x2d, 0xea, 0xfd, 0x21, 0x02, 0x15, 0x2a, 0x10, 0xff, 0xf4, 0x0b, + 0x10, 0xf8, 0x21, 0x35, 0xfc, 0x0c, 0xef, 0xed, 0x18, 0xfb, 0x02, 0x22, 0x02, + 0x2e, 0xda, 0x35, 0x00, 0x11, 0xe1, 0x26, 0x09, 0x4b, 0x12, 0x00, 0x03, 0x13, + 0x1d, 0x2c, 0x25, 0x36, 0xf5, 0x0f, 0xf6, 0xfe, 0x05, 0x0e, 0x31, 0x06, 0xe4, + 0x0f, 0xe9, 0x2a, 0x1e, 0x09, 0x35, 0x07, 0xfb, 0xd1, 0xd3, 0x04, 0x2a, 0xfc, + 0xfc, 0x28, 0xfd, 0x20, 0x34, 0x27, 0x03, 0xef, 0x1e, 0x2b, 0x0c, 0xfc, 0x13, + 0x2f, 0xdc, 0xfc, 0x0a, 0xe0, 0x1b, 0x6d, 0x08, 0xfe, 0x35, 0xd3, 0xec, 0xd8, + 0xf2, 0xd7, 0x07, 0x1e, 0xd5, 0x06, 0xf4, 0xe8, 0xec, 0x0e, 0xf9, 0xdc, 0xec, + 0x0c, 0xf8, 0xfc, 0x64, 0x2c, 0xd0, 0xf8, 0x1a, 0x2b, 0xcf, 0xaf, 0x1d, 0x3c, + 0x04, 0x22, 0x0b, 0x2a, 0xe4, 0x3d, 0x09, 0xf8, 0xcf, 0xde, 0xf9, 0xb8, 0xae, + 0xc9, 0xea, 0xd7, 0xd4, 0x1a, 0xec, 0x40, 0x20, 0xe4, 0xdc, 0x22, 0xda, 0x0a, + 0xe4, 0x5b, 0xaf, 0xd6, 0xf2, 0x1f, 0x1a, 0x1a, 0x04, 0xf0, 0xf2, 0x0f, 0x1f, + 0xfe, 0x22, 0x4d, 0xea, 0xcb, 0xec, 0xfe, 0xef, 0x3a, 0xf2, 0x2c, 0x26, 0xd5, + 0xfc, 0x7f, 0x79, 0xd4, 0xb3, 0xf9, 0x0b, 0x05, 0x32, 0xdf, 0xd5, 0xce, 0xbe, + 0x12, 0xe1, 0xfc, 0xfe, 0xf2, 0xe8, 0x2f, 0x24, 0xfa, 0xf3, 0xfd, 0x1a, 0xc8, + 0xfe, 0xea, 0x18, 0x09, 0x12, 0xca, 0xe7, 0x62, 0xf8, 0xe6, 0xfc, 0xf6, 0xce, + 0xe6, 0x16, 0xf4, 0x7b, 0x20, 0x08, 0xf4, 0xf3, 0xf3, 0xdf, 0xfa, 0xfa, 0x22, + 0x01, 0x30, 0x42, 0x2d, 0x0f, 0x3c, 0xe7, 0xdf, 0x1b, 0xfb, 0xe7, 0x05, 0x2b, + 0xd2, 0xe2, 0x07, 0xd2, 0x0b, 0x0d, 0x16, 0x3f, 0x9a, 0x14, 0x0b, 0xf6, 0xd4, + 0xfa, 0xfc, 0xc8, 0x47, 0x1f, 0xe1, 0x7f, 0x3e, 0xd5, 0x02, 0xec, 0x19, 0xf6, + 0x23, 0x13, 0x1c, 0xf7, 0xea, 0xe9, 0x19, 0x1b, 0x57, 0xe0, 0xe8, 0x16, 0x2e, + 0x10, 0x0a, 0x1e, 0x24, 0x1d, 0x1f, 0x23, 0xe4, 0x26, 0x20, 0x2f, 0xf9, 0x3f, + 0xe2, 0xe2, 0xca, 0x2e, 0xfe, 0xfe, 0xfe, 0x07, 0xbb, 0x07, 0x0f, 0x01, 0xf9, + 0x62, 0xf0, 0x09, 0x19, 0xfd, 0xee, 0x16, 0xfa, 0x26, 0x28, 0x01, 0x24, 0x05, + 0x10, 0x4a, 0xeb, 0xf2, 0xf1, 0x02, 0x17, 0xfc, 0xf8, 0xfe, 0x05, 0xe7, 0xff, + 0x31, 0x32, 0x03, 0xfc, 0x01, 0xfb, 0xfb, 0x19, 0x15, 0x21, 0x03, 0x11, 0x57, + 0x22, 0xf5, 0xde, 0xe3, 0xc1, 0x35, 0x06, 0x25, 0x37, 0x27, 0xe9, 0x81, 0x19, + 0xfc, 0xed, 0x16, 0xee, 0xe4, 0xd2, 0x5b, 0x36, 0xbc, 0xe1, 0xf3, 0x42, 0x0d, + 0x10, 0xf5, 0xf3, 0xf6, 0x06, 0x3a, 0xfc, 0xe1, 0x0e, 0xc4, 0xfc, 0xf9, 0x49, + 0xc0, 0x24, 0x09, 0x0a, 0x35, 0xfb, 0xb7, 0x2d, 0x20, 0xd0, 0xc6, 0xe0, 0xfd, + 0xc2, 0x28, 0x04, 0x07, 0xc3, 0xd8, 0xfa, 0x07, 0x32, 0x25, 0xbd, 0x26, 0xda, + 0x13, 0x2c, 0x1f, 0x06, 0x2d, 0x12, 0x07, 0x2d, 0xea, 0x04, 0xef, 0xc5, 0xb2, + 0xed, 0x03, 0xaa, 0xd7, 0x14, 0xf0, 0xf5, 0x0f, 0xde, 0x00, 0x19, 0x3a, 0xf1, + 0x1b, 0x20, 0x16, 0xf5, 0xc4, 0xe5, 0xb3, 0xd3, 0xb0, 0xf3, 0xec, 0x10, 0x0f, + 0xd4, 0x14, 0x13, 0xea, 0x19, 0xe6, 0x0d, 0xef, 0xe5, 0xf1, 0x14, 0xfd, 0x31, + 0xeb, 0xce, 0xaa, 0xb7, 0x0e, 0x1f, 0x02, 0xfc, 0x21, 0xbd, 0xf6, 0xf3, 0x0a, + 0xfb, 0x1d, 0xdb, 0xb8, 0xef, 0xd2, 0x28, 0xee, 0x0f, 0x29, 0xf1, 0x14, 0x23, + 0x0e, 0xf7, 0x4b, 0x2b, 0xfa, 0x1f, 0x0b, 0x21, 0x01, 0x11, 0xfc, 0x14, 0x3a, + 0x60, 0x16, 0xe5, 0xf4, 0x19, 0x06, 0x14, 0x55, 0x5d, 0xd5, 0xf7, 0xfe, 0x11, + 0x6a, 0xe9, 0x2a, 0xe8, 0x36, 0x67, 0x04, 0x24, 0xef, 0x13, 0x39, 0xe7, 0xf7, + 0xf6, 0xea, 0xf3, 0xfc, 0xfd, 0xe6, 0xf9, 0xe0, 0x53, 0x1d, 0xf2, 0x13, 0x25, + 0x69, 0xf0, 0x3c, 0x10, 0x3a, 0xf2, 0xff, 0x40, 0x1c, 0x17, 0x08, 0x28, 0x3a, + 0x18, 0x00, 0x27, 0xd6, 0xbf, 0xff, 0xb3, 0x23, 0xd0, 0xd3, 0xdb, 0x12, 0xff, + 0xf0, 0xe8, 0x21, 0xe7, 0xcd, 0x33, 0xff, 0x20, 0x06, 0x03, 0xef, 0x25, 0x52, + 0x01, 0xcb, 0x4a, 0x05, 0x0f, 0xd4, 0x09, 0xec, 0xfc, 0x36, 0x33, 0x05, 0xfc, + 0xcc, 0x2e, 0xe4, 0xe3, 0xc5, 0x39, 0xd1, 0x40, 0x7f, 0x23, 0xd3, 0xc5, 0xdd, + 0x12, 0x3e, 0x2b, 0xe3, 0xef, 0x56, 0xaa, 0xc7, 0x24, 0x06, 0xe6, 0xc3, 0xed, + 0xb1, 0xb2, 0x4a, 0x50, 0xf1, 0x2c, 0xd1, 0xdf, 0xc9, 0xf0, 0xdf, 0xe6, 0x02, + 0x03, 0x08, 0xe3, 0xd0, 0x40, 0xf0, 0xd6, 0x2d, 0x0c, 0xcc, 0xde, 0x49, 0x4a, + 0xd7, 0x1d, 0x81, 0x39, 0xdd, 0xb3, 0x33, 0xdd, 0xde, 0xc8, 0xd6, 0xda, 0xfe, + 0xfd, 0xcd, 0x1b, 0x12, 0x34, 0xfa, 0xf6, 0x17, 0x13, 0x0c, 0xfe, 0xba, 0xe4, + 0x08, 0x47, 0xee, 0xf7, 0xf1, 0xe0, 0x16, 0x9e, 0x13, 0x68, 0x39, 0xb1, 0x07, + 0xb5, 0x0e, 0xda, 0xc7, 0xcb, 0x0e, 0x11, 0xfa, 0x6b, 0x10, 0xf5, 0xd9, 0xfc, + 0xcf, 0xea, 0x08, 0xf7, 0xe6, 0xf7, 0x4f, 0xde, 0x1f, 0x19, 0x0c, 0xb9, 0x2a, + 0xf9, 0x1e, 0xe4, 0xf6, 0xc1, 0xb8, 0xea, 0x32, 0xd1, 0xff, 0x14, 0xd4, 0x67, + 0x10, 0x06, 0xe3, 0xd8, 0x5c, 0x1b, 0xd5, 0x0b, 0x65, 0xf6, 0x3b, 0x24, 0xd8, + 0x1b, 0xfc, 0x0b, 0xed, 0xde, 0x71, 0xb2, 0x3b, 0x46, 0x1e, 0xfa, 0xe3, 0x10, + 0x15, 0xf0, 0x3e, 0xfb, 0xb8, 0xf4, 0x07, 0xcd, 0x4e, 0x5c, 0xed, 0xc7, 0x38, + 0x02, 0x55, 0xfd, 0xe5, 0xae, 0xcb, 0xd6, 0xfb, 0xac, 0x6f, 0xf7, 0xcd, 0x14, + 0xea, 0x16, 0x03, 0x25, 0x15, 0x3e, 0xe0, 0x20, 0x17, 0xa8, 0xe9, 0xf1, 0x26, + 0xe3, 0x0d, 0x27, 0x02, 0xb8, 0x3d, 0x4b, 0xd6, 0xdc, 0x02, 0xe0, 0xd4, 0xfb, + 0xd2, 0x3b, 0x51, 0xd5, 0x28, 0xdd, 0x1e, 0xc5, 0xb6, 0x72, 0xed, 0x0b, 0x3a, + 0xba, 0x0c, 0xd1, 0x02, 0xdf, 0xf1, 0x02, 0xe1, 0xe4, 0xe4, 0xe4, 0xf3, 0x26, + 0xf7, 0x40, 0x09, 0x05, 0xe4, 0x23, 0x19, 0xc1, 0xf3, 0xc4, 0x0f, 0xc6, 0x21, + 0x0f, 0x39, 0x4b, 0x17, 0xce, 0x5f, 0xfd, 0x12, 0x0d, 0xd2, 0x7f, 0xf6, 0xfd, + 0x2a, 0xe2, 0x17, 0xc2, 0x41, 0x0d, 0x29, 0xed, 0x10, 0x38, 0xf0, 0xf8, 0xd2, + 0x15, 0x1c, 0x39, 0x4e, 0xed, 0x0d, 0xaa, 0xd5, 0xe2, 0x17, 0x7f, 0xa5, 0x14, + 0xde, 0x3b, 0x69, 0x06, 0x0a, 0xfc, 0xff, 0x2e, 0x12, 0x39, 0x05, 0xee, 0x6f, + 0xee, 0x26, 0x06, 0xbb, 0x01, 0xf5, 0xaa, 0x3c, 0xe7, 0xb9, 0x1b, 0xe7, 0x90, + 0xd2, 0x41, 0x37, 0x0e, 0x38, 0xf2, 0x2e, 0x16, 0xdb, 0x0f, 0x03, 0xc2, 0x05, + 0x12, 0xe1, 0xe0, 0x25, 0x23, 0xd7, 0xd6, 0xef, 0xf8, 0xf7, 0xf9, 0xb6, 0x0a, + 0x2a, 0x0c, 0x05, 0xe9, 0xd9, 0xdf, 0x25, 0x08, 0x2a, 0x24, 0x30, 0xdb, 0x2e, + 0xf4, 0x2a, 0x0a, 0xd0, 0xc5, 0x32, 0xd8, 0xf3, 0xef, 0x11, 0xf1, 0x25, 0xc8, + 0x2d, 0x02, 0x1f, 0xca, 0x12, 0x1f, 0x14, 0xe9, 0x26, 0xec, 0x0e, 0x09, 0x06, + 0x07, 0xf3, 0x18, 0x24, 0x1d, 0xfc, 0x1c, 0xf8, 0xe5, 0xd1, 0xde, 0xea, 0xa5, + 0x14, 0x34, 0xd1, 0x6a, 0x1a, 0xbf, 0xfe, 0xdf, 0xe7, 0xda, 0xf4, 0xe9, 0x03, + 0x04, 0x81, 0x1f, 0xdd, 0xdb, 0xf5, 0x19, 0xbe, 0xdd, 0x0a, 0x1b, 0xfa, 0xee, + 0xde, 0xef, 0x04, 0x16, 0x1e, 0xe6, 0xf2, 0xc9, 0xaf, 0xf6, 0xe7, 0x43, 0xe7, + 0xfe, 0x3b, 0x1b, 0x0a, 0x10, 0xce, 0x00, 0xf8, 0xf8, 0xc6, 0x24, 0x21, 0xce, + 0xe0, 0x02, 0xb6, 0xd2, 0xe0, 0xe6, 0xe8, 0xfd, 0x24, 0x21, 0x14, 0xe5, 0xf4, + 0x07, 0xfb, 0xd6, 0xda, 0x10, 0xe9, 0x0e, 0x4c, 0x0a, 0xee, 0x19, 0x0d, 0x03, + 0xcf, 0xe9, 0x0b, 0x0d, 0xd4, 0xd9, 0x06, 0xc6, 0xd1, 0x08, 0xef, 0xc2, 0xe6, + 0x24, 0xf0, 0x4a, 0xfa, 0x0d, 0x0c, 0xf4, 0x13, 0x38, 0xf0, 0x27, 0x28, 0xfb, + 0xdb, 0x34, 0xf2, 0xc5, 0x14, 0x0e, 0xfd, 0x44, 0xef, 0x17, 0xfd, 0xf6, 0x0b, + 0xc8, 0xe2, 0x09, 0xf9, 0x22, 0xde, 0xd4, 0x10, 0x27, 0xdc, 0x05, 0xea, 0xc8, + 0x08, 0x01, 0xfc, 0xfa, 0xef, 0x23, 0x71, 0xd6, 0xda, 0x15, 0x08, 0xeb, 0x22, + 0xcb, 0xf3, 0xea, 0x4f, 0xff, 0xf5, 0x5d, 0xc5, 0xfa, 0x15, 0x5b, 0x0b, 0x03, + 0xbe, 0xfe, 0x38, 0xeb, 0x04, 0xb7, 0x2a, 0xe9, 0x7f, 0xe5, 0x1d, 0xda, 0xb0, + 0x0a, 0x20, 0xb8, 0x51, 0x00, 0xd7, 0xce, 0x3a, 0xe0, 0xab, 0xe7, 0xd5, 0xed, + 0xd6, 0xf4, 0xef, 0xda, 0xbe, 0xe6, 0xde, 0xb9, 0xe8, 0x6b, 0x21, 0xd1, 0x12, + 0x2f, 0x0e, 0xd1, 0xc1, 0x19, 0x15, 0xe1, 0xc9, 0xea, 0x40, 0xdc, 0xcd, 0x09, + 0x0a, 0x7f, 0xfb, 0xed, 0xa5, 0x00, 0xe2, 0xe2, 0xe5, 0x8a, 0xb3, 0xf8, 0x3c, + 0x17, 0xfc, 0x25, 0xe1, 0x10, 0x05, 0x14, 0xf5, 0xa2, 0x31, 0xed, 0xff, 0x06, + 0xd0, 0x10, 0x0f, 0xc3, 0x20, 0x07, 0x1c, 0x1d, 0x36, 0x00, 0xaf, 0x18, 0x4e, + 0xdd, 0xd3, 0x51, 0x1a, 0x09, 0x06, 0x12, 0xf1, 0xa5, 0xc9, 0xf6, 0xdf, 0xfa, + 0xfc, 0xe7, 0x11, 0x2c, 0x03, 0xe4, 0x1f, 0x05, 0x27, 0x28, 0xf6, 0x27, 0x35, + 0xf4, 0x3d, 0x2a, 0x1b, 0xea, 0x25, 0x49, 0xe5, 0xa6, 0x0c, 0xc2, 0xd6, 0xe1, + 0x22, 0x0f, 0x38, 0x59, 0xfb, 0xda, 0xdf, 0x28, 0xde, 0xec, 0xf6, 0xd0, 0x25, + 0x1d, 0x47, 0xf9, 0xed, 0x5f, 0xb0, 0x5c, 0xc0, 0xeb, 0x18, 0x2c, 0x10, 0x39, + 0x1f, 0x5a, 0xe8, 0xbf, 0x10, 0xf3, 0xf1, 0xf9, 0x02, 0x1c, 0x17, 0xf9, 0xfa, + 0xf8, 0x37, 0xe5, 0xfb, 0xfd, 0xcb, 0x77, 0xfd, 0x52, 0x41, 0x62, 0xac, 0xbb, + 0x2c, 0x21, 0x3d, 0xea, 0xd4, 0xb8, 0x12, 0x05, 0x03, 0xcc, 0xf9, 0x0a, 0xfc, + 0xc7, 0x1e, 0xea, 0x6b, 0xf5, 0x0c, 0xf9, 0xcc, 0x0e, 0xbf, 0xea, 0x2a, 0x31, + 0x26, 0xe8, 0xf9, 0x52, 0xee, 0x0c, 0xf0, 0x7f, 0x28, 0x4f, 0x14, 0x67, 0x07, + 0xb4, 0x52, 0x05, 0xda, 0x22, 0xf0, 0x05, 0x0c, 0x2b, 0x6c, 0x19, 0x07, 0x23, + 0x2c, 0xde, 0xed, 0x26, 0xdc, 0x40, 0x42, 0xbf, 0xc2, 0x05, 0x53, 0xe1, 0xf5, + 0x18, 0xb0, 0xaf, 0x30, 0x0b, 0xf9, 0xbe, 0x03, 0xeb, 0xf6, 0x01, 0xf9, 0x09, + 0x2a, 0x11, 0xd6, 0xae, 0x27, 0x47, 0x12, 0xdc, 0x40, 0xdd, 0x04, 0x2d, 0xe5, + 0xcb, 0xca, 0x73, 0xa3, 0x3a, 0x06, 0xd7, 0xde, 0x3b, 0xeb, 0xed, 0x0e, 0x40, + 0xf8, 0xdf, 0x09, 0x19, 0xd9, 0x52, 0xd9, 0x25, 0xfa, 0xd9, 0x00, 0x29, 0xfa, + 0x0f, 0x24, 0xdf, 0xee, 0x7f, 0xd2, 0x2e, 0x34, 0x1f, 0xf1, 0xea, 0xb6, 0xe7, + 0xd4, 0x1e, 0xd6, 0xd3, 0xd4, 0xb9, 0xa8, 0xea, 0xba, 0xd6, 0xa2, 0x31, 0x3f, + 0x10, 0xf2, 0x23, 0x13, 0x31, 0xda, 0x23, 0x0b, 0x16, 0x4c, 0xe6, 0x04, 0x03, + 0x22, 0xf2, 0x2f, 0x25, 0xbb, 0xe8, 0x15, 0xef, 0xed, 0x07, 0x2b, 0xb4, 0xfa, + 0xe4, 0x23, 0x18, 0x25, 0x03, 0x3b, 0xb3, 0x68, 0xf3, 0x4e, 0xe9, 0xed, 0xf0, + 0x4a, 0xfb, 0x10, 0x0a, 0x1d, 0x20, 0xef, 0x1f, 0x06, 0xfa, 0xe8, 0xf7, 0x1e, + 0xb6, 0xd3, 0x0e, 0x02, 0xf9, 0x19, 0x2c, 0x2b, 0x1e, 0x10, 0x62, 0xc8, 0xc7, + 0xe8, 0xd8, 0xb9, 0x0a, 0xf3, 0x10, 0x16, 0x07, 0x1a, 0x15, 0xf0, 0x15, 0x24, + 0x37, 0xdb, 0xfc, 0x1c, 0x30, 0x07, 0x14, 0xec, 0x26, 0xee, 0xd4, 0xea, 0xd8, + 0xf9, 0x0d, 0x2c, 0x04, 0x12, 0x33, 0xda, 0xe0, 0xff, 0x3f, 0x42, 0xec, 0xe3, + 0x25, 0xd9, 0xf1, 0x22, 0xc9, 0xe8, 0xf1, 0x27, 0x7f, 0x34, 0xa1, 0x0d, 0x25, + 0xfd, 0xd8, 0xce, 0xfe, 0xcd, 0x9e, 0xc8, 0x36, 0xa6, 0xc7, 0xf3, 0xd5, 0xc5, + 0x20, 0x36, 0xea, 0xa7, 0x2e, 0x27, 0x3a, 0x33, 0xdd, 0xa0, 0xd4, 0xf3, 0xff, + 0xfd, 0x16, 0x0a, 0xf8, 0xb2, 0x06, 0xf5, 0xcb, 0x2d, 0x20, 0x03, 0x31, 0x0a, + 0xe9, 0xde, 0x4c, 0x17, 0xf7, 0xe0, 0xe8, 0xe3, 0xb9, 0xf2, 0xe9, 0xd5, 0xf0, + 0xe5, 0xdc, 0x0c, 0xd6, 0xb2, 0xbc, 0x7f, 0x44, 0x79, 0xca, 0xc9, 0xa6, 0x2a, + 0x36, 0xd0, 0xc0, 0x19, 0x4d, 0xf0, 0xf9, 0x04, 0x43, 0xf9, 0xf2, 0xd8, 0x49, + 0x55, 0xd2, 0xeb, 0xb5, 0xf6, 0xda, 0x10, 0xd7, 0xfc, 0x41, 0xbf, 0x1f, 0x34, + 0xf7, 0xf3, 0x1e, 0xfb, 0xf8, 0xf7, 0xf0, 0x0c, 0xde, 0xe7, 0x6b, 0xe8, 0xf4, + 0xee, 0xf0, 0xd5, 0xfd, 0x0d, 0x44, 0xe5, 0xd8, 0xf1, 0xfe, 0x07, 0xd1, 0xd7, + 0x15, 0x01, 0xf1, 0x50, 0xfc, 0x27, 0xe5, 0x51, 0xcc, 0x4c, 0xd9, 0xf1, 0x0b, + 0xcf, 0x14, 0xf9, 0xd7, 0xf7, 0xe2, 0xe7, 0x15, 0x22, 0xf3, 0xd2, 0xed, 0xe1, + 0x0b, 0x1c, 0xc9, 0x07, 0x23, 0x0e, 0xce, 0xf1, 0x26, 0x0d, 0xc8, 0x09, 0x27, + 0xef, 0x06, 0x1c, 0xee, 0xc4, 0xe4, 0x4c, 0xf2, 0x2d, 0xf9, 0xdc, 0x23, 0x34, + 0x06, 0xf6, 0xf1, 0x3e, 0x0e, 0xea, 0xeb, 0x54, 0x00, 0x18, 0x12, 0x0c, 0xe9, + 0x14, 0x0f, 0xef, 0x09, 0x02, 0x37, 0xd2, 0xf3, 0xe1, 0x2e, 0x15, 0x08, 0xa6, + 0x0e, 0x23, 0xe3, 0xf7, 0x13, 0xf7, 0xf0, 0x21, 0x45, 0xd2, 0xf7, 0x03, 0x17, + 0x1a, 0x3d, 0xe6, 0x24, 0x42, 0xd4, 0x09, 0x2f, 0xfe, 0x2a, 0xd2, 0x11, 0x2a, + 0x2f, 0xdb, 0xe0, 0xbc, 0x12, 0xe1, 0xd7, 0x57, 0x04, 0x11, 0x07, 0x2d, 0x2a, + 0x37, 0xce, 0xd8, 0x3a, 0xf1, 0xb9, 0x1b, 0x13, 0xe8, 0xba, 0xe7, 0x7f, 0x01, + 0xe9, 0xf6, 0xd3, 0xb8, 0x3b, 0xbf, 0x12, 0x0c, 0xdb, 0x2f, 0xf2, 0xdf, 0xa3, + 0x0a, 0x5a, 0x7c, 0x21, 0xdf, 0x0d, 0xca, 0x4d, 0xdf, 0x13, 0xd9, 0xd0, 0x14, + 0xf8, 0x14, 0x0c, 0xe5, 0x24, 0xfb, 0xaa, 0xee, 0x8f, 0x0e, 0xe4, 0x06, 0x05, + 0xbf, 0x25, 0x65, 0x33, 0xd8, 0xf1, 0xfd, 0x65, 0x0e, 0xdf, 0x26, 0xd5, 0xf4, + 0xdd, 0x05, 0xd4, 0x15, 0x0e, 0x25, 0xf3, 0xed, 0xce, 0xdf, 0x19, 0x20, 0x38, + 0x13, 0xda, 0x05, 0x1a, 0x00, 0xdb, 0x21, 0x14, 0xff, 0xf9, 0x16, 0x1c, 0x04, + 0xec, 0x07, 0xe9, 0xe5, 0x1d, 0x14, 0xf6, 0xff, 0x35, 0x3b, 0x24, 0x25, 0xea, + 0xee, 0xee, 0x2b, 0xd1, 0x35, 0xff, 0x15, 0x1e, 0x0b, 0xef, 0xfe, 0x34, 0xf8, + 0xf6, 0xe9, 0x0c, 0x19, 0xe9, 0x11, 0x20, 0xdb, 0xaa, 0xda, 0xee, 0x05, 0xba, + 0x19, 0xe8, 0x22, 0xe4, 0xd4, 0xfa, 0x02, 0xe8, 0xf2, 0x5d, 0xe8, 0xd3, 0x12, + 0xf3, 0x0d, 0x0a, 0x2e, 0xe8, 0xd3, 0xc6, 0x64, 0xd2, 0xd8, 0xb5, 0xf1, 0x07, + 0xf3, 0xd8, 0xe7, 0xf5, 0x08, 0x12, 0x04, 0xe0, 0xee, 0xf6, 0x0c, 0xe5, 0xea, + 0x19, 0x21, 0xbe, 0x7f, 0x00, 0xef, 0xbf, 0x09, 0xcd, 0xdf, 0x16, 0x00, 0xd6, + 0x0d, 0xe8, 0x2e, 0xf1, 0xdc, 0x17, 0x18, 0xe4, 0xf4, 0xf5, 0xf3, 0x2e, 0x2f, + 0x16, 0xe2, 0xdd, 0x4d, 0x27, 0xf3, 0xba, 0xfe, 0x2d, 0x31, 0x03, 0xfb, 0xc6, + 0x3c, 0x19, 0x4b, 0xe3, 0xbc, 0x08, 0xeb, 0x26, 0xd1, 0x03, 0x3a, 0x01, 0xf1, + 0xe6, 0xb6, 0x37, 0x26, 0x14, 0x3c, 0x2a, 0x4a, 0xe1, 0xe2, 0x2a, 0xf1, 0xff, + 0x34, 0xb8, 0xf9, 0xe6, 0xba, 0x2a, 0xf9, 0x0a, 0xe4, 0x6f, 0xf0, 0x4b, 0xcc, + 0x1f, 0xd2, 0xd1, 0xc6, 0x5e, 0xba, 0xe9, 0xd6, 0xc3, 0xf7, 0xf1, 0xf4, 0x0c, + 0xe7, 0xc8, 0xce, 0xe7, 0x2b, 0xdc, 0xfa, 0xe9, 0xd3, 0xf2, 0x02, 0x2f, 0x11, + 0x2a, 0x51, 0xba, 0x2b, 0xec, 0x49, 0x06, 0xfb, 0xbf, 0xf4, 0xe4, 0xa0, 0xdf, + 0xab, 0x81, 0xe9, 0x22, 0x0b, 0x1a, 0x78, 0x24, 0xf2, 0x0d, 0x0f, 0xe4, 0xe4, + 0xea, 0xdd, 0x1c, 0x13, 0xd2, 0xe2, 0x04, 0x10, 0x22, 0x14, 0xc6, 0xc3, 0xe3, + 0x2c, 0xef, 0x64, 0xbe, 0x03, 0x02, 0x0f, 0x01, 0x25, 0x3e, 0xf3, 0xf9, 0xdd, + 0x32, 0x1e, 0x3d, 0x1c, 0x1e, 0x10, 0x02, 0x3e, 0x1d, 0x3f, 0xa6, 0x28, 0x68, + 0x08, 0xeb, 0xfb, 0x56, 0xe6, 0xdf, 0x25, 0x46, 0xcf, 0xa5, 0xf4, 0xf6, 0x15, + 0x2f, 0x1b, 0xdc, 0x4a, 0x10, 0x28, 0xd9, 0xfd, 0xd7, 0xdb, 0x0f, 0xe7, 0xed, + 0xff, 0xdb, 0x14, 0x2b, 0xe8, 0xa2, 0x92, 0x35, 0x46, 0xda, 0xb7, 0x0e, 0xf2, + 0x16, 0x51, 0x16, 0xf2, 0xff, 0x06, 0x1f, 0x04, 0xf0, 0x0c, 0xd4, 0xfa, 0x08, + 0xbb, 0xed, 0x06, 0xfc, 0xd8, 0xfc, 0x26, 0xd9, 0x09, 0xf6, 0xe2, 0x7f, 0x11, + 0x73, 0xd9, 0x09, 0x43, 0xa9, 0xe2, 0xb6, 0xf4, 0xeb, 0x5a, 0x1a, 0xf3, 0x12, + 0xfe, 0xf8, 0x0f, 0x14, 0x14, 0xe9, 0x2e, 0xee, 0x2c, 0xe8, 0xff, 0x0c, 0xb0, + 0xe0, 0x18, 0xba, 0x1d, 0xe9, 0x12, 0xec, 0xeb, 0xe2, 0xe2, 0xe4, 0x27, 0x1b, + 0xd1, 0xc5, 0xe3, 0xeb, 0x1a, 0xf1, 0x06, 0xe2, 0xf6, 0xe2, 0x30, 0xf2, 0xdd, + 0x0b, 0xb5, 0x6e, 0x07, 0xdf, 0xbc, 0x5f, 0x0c, 0x4f, 0xc7, 0xbd, 0xf1, 0xe1, + 0x18, 0xdd, 0x67, 0x29, 0x3a, 0xf9, 0xce, 0x39, 0x06, 0xba, 0xf6, 0xdb, 0xf7, + 0x21, 0xa4, 0xf9, 0xd6, 0x25, 0xdb, 0x1c, 0xe6, 0x03, 0xd4, 0x00, 0x2b, 0x02, + 0x2d, 0x02, 0xd5, 0x43, 0xb0, 0x8f, 0x12, 0xf7, 0x18, 0x15, 0x2f, 0x25, 0x19, + 0xfe, 0x1a, 0x27, 0xf6, 0x04, 0x0d, 0xd7, 0xe1, 0xf7, 0x3d, 0x02, 0xde, 0x27, + 0xf6, 0x27, 0x25, 0x1a, 0x48, 0xf4, 0xfb, 0xe7, 0x52, 0xf2, 0x24, 0x4c, 0xea, + 0x10, 0x02, 0x48, 0x6d, 0xea, 0xda, 0x6c, 0xb6, 0xb7, 0x7f, 0x12, 0xef, 0x38, + 0xc6, 0xf7, 0xf4, 0xc6, 0x1b, 0x0b, 0x0c, 0x05, 0x12, 0xf1, 0xe5, 0x18, 0x2e, + 0x96, 0xec, 0x0f, 0xea, 0x3a, 0x33, 0xf6, 0xd9, 0x77, 0xd9, 0xf4, 0xd2, 0x03, + 0xf6, 0x5d, 0x05, 0xb2, 0x25, 0x18, 0xf4, 0xfc, 0xdb, 0x61, 0x12, 0x0d, 0xd7, + 0xcd, 0xe9, 0xdb, 0x19, 0xf7, 0x36, 0x02, 0x90, 0xdc, 0xfe, 0x21, 0x3e, 0xfb, + 0xf2, 0x35, 0xf4, 0xf9, 0xf0, 0x50, 0xe9, 0xd2, 0xee, 0x3c, 0xfd, 0x4d, 0x31, + 0x59, 0x02, 0x23, 0x45, 0x10, 0x02, 0xc1, 0x2b, 0xd4, 0xfd, 0x2d, 0x18, 0xc9, + 0x00, 0x38, 0xda, 0xd6, 0x02, 0x61, 0x0e, 0xe1, 0x1b, 0xde, 0xcc, 0xf7, 0xf6, + 0x82, 0x0b, 0x34, 0x03, 0xdf, 0xfd, 0xbc, 0xd4, 0xc7, 0xe6, 0xd0, 0xf5, 0x1c, + 0xfa, 0xf3, 0x1e, 0xda, 0x30, 0x17, 0x24, 0xa3, 0xe6, 0xe6, 0x4c, 0xd3, 0xa8, + 0x7f, 0x02, 0xf5, 0xc9, 0x33, 0xc6, 0x26, 0x82, 0x0c, 0x20, 0xf0, 0xdb, 0x40, + 0xe9, 0x18, 0x96, 0xb5, 0xcb, 0x3f, 0xfd, 0x00, 0x67, 0xea, 0x26, 0x53, 0xcf, + 0x0f, 0x1f, 0x11, 0x07, 0x08, 0xff, 0xc7, 0xfe, 0xec, 0x85, 0x45, 0xe8, 0x0f, + 0xe9, 0xf6, 0xf6, 0x42, 0x2b, 0x2a, 0x55, 0xde, 0x00, 0xf5, 0x4f, 0x00, 0x40, + 0x0b, 0x10, 0xf6, 0x97, 0x14, 0xc0, 0xe8, 0xcc, 0xf7, 0xf6, 0x11, 0x27, 0x07, + 0xda, 0xf0, 0x0f, 0xe9, 0xf9, 0x58, 0xc4, 0x1a, 0xde, 0x37, 0xa8, 0x03, 0x13, + 0xe9, 0xcd, 0x01, 0xd3, 0x12, 0xff, 0x0d, 0xc8, 0xf1, 0x7f, 0xf2, 0xf4, 0x0c, + 0x31, 0x17, 0xc9, 0xbb, 0x1c, 0x9f, 0xf8, 0x10, 0x23, 0xe5, 0xce, 0x00, 0xf6, + 0xf1, 0xff, 0x00, 0x00, 0xc4, 0x22, 0x1e, 0x0d, 0x37, 0xf8, 0x12, 0xfd, 0x1f, + 0xc0, 0x0b, 0xd6, 0xd9, 0xf7, 0x1d, 0x33, 0xcf, 0xfd, 0x37, 0x10, 0x10, 0x1e, + 0xd7, 0xeb, 0x10, 0x6a, 0x1e, 0x46, 0xf0, 0xfe, 0xc5, 0xe8, 0x4a, 0xf9, 0xe2, + 0xc4, 0xe9, 0x08, 0xf1, 0x35, 0xf2, 0xec, 0xd9, 0xfe, 0x10, 0xf3, 0x22, 0x13, + 0xec, 0xd1, 0xf1, 0x21, 0x18, 0xe0, 0x2d, 0xee, 0x06, 0x1b, 0x27, 0xec, 0x00, + 0xf4, 0xf2, 0xdb, 0xd2, 0x03, 0xc4, 0xf0, 0xe6, 0xc0, 0x74, 0xd5, 0x0b, 0x1e, + 0x31, 0x21, 0x04, 0x15, 0x18, 0x30, 0xc3, 0xe4, 0xbc, 0xcd, 0x39, 0x38, 0x2e, + 0xba, 0x0b, 0x2b, 0x11, 0x1a, 0x30, 0x54, 0x0b, 0x44, 0xd2, 0xf3, 0xfd, 0x43, + 0x48, 0xfd, 0x02, 0xc8, 0xd9, 0xc6, 0xda, 0xfb, 0x19, 0xd1, 0xd4, 0x0b, 0xee, + 0xd1, 0x22, 0x2c, 0x6f, 0x2f, 0xde, 0x34, 0xdc, 0x3f, 0xf5, 0x2a, 0xf5, 0xed, + 0xff, 0xd8, 0xa9, 0x08, 0xc8, 0x1b, 0xde, 0xca, 0xdd, 0xfc, 0xae, 0x78, 0x59, + 0xf7, 0xd0, 0xf4, 0xe9, 0x2c, 0x81, 0x05, 0xed, 0x1d, 0x14, 0xdc, 0x03, 0x5f, + 0x53, 0x04, 0x17, 0x09, 0x12, 0x34, 0xce, 0xe7, 0x26, 0x32, 0x1d, 0x10, 0xd2, + 0xd3, 0x0d, 0x2f, 0xec, 0xfe, 0x38, 0x1f, 0x1e, 0xfd, 0x69, 0x14, 0x45, 0xf9, + 0xef, 0xe4, 0x14, 0xfe, 0x09, 0xa8, 0x27, 0xdf, 0xce, 0xed, 0xe6, 0x09, 0xea, + 0xb8, 0xb4, 0xef, 0x6c, 0x49, 0x02, 0x17, 0x4f, 0xb0, 0xd7, 0x0a, 0x2c, 0x13, + 0xeb, 0x40, 0x77, 0x15, 0xf4, 0x9e, 0xad, 0xff, 0x31, 0x1a, 0x5f, 0xed, 0xee, + 0x34, 0xe0, 0xfc, 0xf2, 0x34, 0xa0, 0x27, 0xef, 0x07, 0x08, 0x18, 0x0c, 0x3f, + 0xa5, 0xe0, 0xda, 0xfd, 0x13, 0xd2, 0xf3, 0xc4, 0x25, 0xe2, 0x0d, 0x09, 0x15, + 0xa1, 0xef, 0xdf, 0xf4, 0x40, 0xde, 0x1d, 0x5f, 0xfe, 0x16, 0x31, 0xf6, 0x0f, + 0x64, 0xd8, 0xd4, 0xda, 0xd7, 0xce, 0x4b, 0xd2, 0xd5, 0xe0, 0xdd, 0x03, 0xd0, + 0x1f, 0x20, 0x3d, 0x04, 0x06, 0xeb, 0x7f, 0x39, 0xfe, 0x46, 0x7a, 0x03, 0x33, + 0x01, 0x12, 0xc2, 0xbe, 0xd3, 0xe2, 0xcf, 0xef, 0x13, 0x25, 0xf1, 0x04, 0xd2, + 0xe9, 0xc5, 0xd0, 0x00, 0x33, 0x00, 0x4e, 0x0d, 0x59, 0xbc, 0x07, 0xf3, 0xea, + 0xe0, 0x56, 0x40, 0xf9, 0x3f, 0x14, 0x28, 0x4a, 0xd2, 0x15, 0x15, 0x0c, 0x36, + 0x0c, 0x22, 0xe4, 0x2d, 0xff, 0x09, 0xdd, 0x20, 0xfd, 0x3d, 0x7f, 0xc0, 0x07, + 0x47, 0x1f, 0x40, 0x0e, 0x33, 0x0f, 0xe9, 0x2f, 0x01, 0xdd, 0xdd, 0xfb, 0xe0, + 0x47, 0xea, 0xf7, 0xc8, 0x1e, 0x0d, 0x27, 0xe8, 0xe0, 0x0d, 0x0a, 0x10, 0x66, + 0x08, 0x2d, 0x2e, 0x02, 0xee, 0x09, 0xee, 0x14, 0x52, 0x0e, 0xef, 0xfd, 0xd9, + 0xf2, 0x21, 0xea, 0xf0, 0xe7, 0x10, 0xeb, 0xc8, 0x05, 0xed, 0xfb, 0x16, 0xbd, + 0xfa, 0xdf, 0xe0, 0xe2, 0xf2, 0xa6, 0xfe, 0x23, 0xfb, 0xff, 0xd2, 0xd8, 0x07, + 0x73, 0x32, 0xc2, 0x1e, 0x30, 0x11, 0x0b, 0xa1, 0x0e, 0x04, 0x1a, 0x27, 0x1a, + 0xd6, 0xf5, 0x00, 0xf7, 0xf6, 0xed, 0x04, 0xf3, 0x1c, 0x3d, 0x14, 0xe4, 0xcd, + 0x0f, 0x9a, 0x0e, 0x0d, 0x15, 0xd9, 0x06, 0xe8, 0x07, 0xdf, 0x0c, 0xf4, 0x17, + 0x12, 0xe6, 0x18, 0x1e, 0xf0, 0xf4, 0x2c, 0x2f, 0xc3, 0xed, 0x1c, 0xef, 0x0f, + 0xca, 0x13, 0xfd, 0x0b, 0xfc, 0x12, 0x2f, 0x0a, 0x55, 0x09, 0x25, 0x36, 0xf9, + 0xf0, 0x02, 0xad, 0xd4, 0x17, 0x04, 0xda, 0x22, 0x7f, 0x11, 0xd7, 0x12, 0x1d, + 0xf8, 0xfa, 0xf5, 0x6a, 0x3c, 0xf7, 0xec, 0xe5, 0x0a, 0xd8, 0x0d, 0xd7, 0xea, + 0x04, 0x06, 0x19, 0x0f, 0x40, 0x28, 0x16, 0x07, 0xf7, 0xde, 0xf5, 0x1a, 0xc7, + 0xd9, 0x23, 0xfe, 0xc0, 0x22, 0xf5, 0xf8, 0xe8, 0x12, 0xdc, 0xdc, 0xf9, 0xf9, + 0x1d, 0xc8, 0x1a, 0x11, 0x07, 0xf4, 0x08, 0xf6, 0xf9, 0x10, 0xf2, 0x12, 0x00, + 0x41, 0xf9, 0x2e, 0xf1, 0xd2, 0xc3, 0xc5, 0xf6, 0xdc, 0x06, 0x09, 0x16, 0xf1, + 0x22, 0x22, 0x14, 0x11, 0xff, 0x01, 0x02, 0x16, 0x14, 0x12, 0xf1, 0xdd, 0x2e, + 0xf6, 0x1d, 0xf0, 0xef, 0x07, 0xe7, 0x48, 0x0b, 0x20, 0x1d, 0x11, 0x3a, 0x01, + 0xd4, 0xcb, 0xd3, 0xf0, 0x0b, 0x03, 0x2e, 0xd5, 0x42, 0x0c, 0xeb, 0x17, 0x09, + 0x0e, 0x07, 0xc7, 0x01, 0x2d, 0x02, 0x43, 0x9e, 0xeb, 0x1d, 0xf5, 0xca, 0xa5, + 0x7f, 0xbc, 0x2d, 0xf3, 0x35, 0xe5, 0x33, 0x08, 0xf8, 0xf9, 0x42, 0xcc, 0x10, + 0x35, 0xce, 0x54, 0x00, 0x30, 0xef, 0x9e, 0xf4, 0xfd, 0xe8, 0x49, 0xef, 0xa3, + 0x3a, 0x2d, 0xd4, 0xe3, 0x13, 0xdb, 0xe0, 0xcf, 0x15, 0xe7, 0xf3, 0xd7, 0x28, + 0xe1, 0xfb, 0x15, 0x03, 0xf6, 0xde, 0x3c, 0xe5, 0xd9, 0xbb, 0xf4, 0xec, 0xda, + 0x0f, 0x04, 0x3a, 0x16, 0xf0, 0x33, 0x07, 0xd7, 0x09, 0xde, 0x25, 0xf0, 0xdd, + 0x11, 0x94, 0x1b, 0xcf, 0xda, 0x31, 0xa7, 0x0a, 0xde, 0x09, 0x21, 0x17, 0x0a, + 0x0c, 0x19, 0xf3, 0x2a, 0xdb, 0xdb, 0xec, 0x0b, 0x2b, 0xf2, 0xd4, 0x2c, 0xa8, + 0xed, 0xeb, 0x38, 0xec, 0xd8, 0x3a, 0x5f, 0xcd, 0xec, 0x1b, 0xe6, 0x38, 0xeb, + 0x18, 0x1e, 0x83, 0xe6, 0xcd, 0x00, 0x63, 0x0b, 0x95, 0xcc, 0xf6, 0xd1, 0x2d, + 0xd5, 0x35, 0xea, 0x17, 0xf5, 0x01, 0xe5, 0x1c, 0x13, 0xef, 0xe2, 0x1d, 0x3a, + 0x0a, 0x06, 0x08, 0xd8, 0xf2, 0x44, 0xf7, 0x1e, 0x15, 0x42, 0x16, 0xe6, 0xe5, + 0xfc, 0xd5, 0xe6, 0x34, 0x10, 0x02, 0x1f, 0x19, 0xeb, 0xff, 0xc4, 0xe9, 0x01, + 0xe3, 0xda, 0xcb, 0xea, 0x04, 0xf7, 0xc7, 0x24, 0xf6, 0x19, 0x1f, 0x55, 0xdd, + 0x3e, 0x0d, 0x1b, 0xf7, 0xf1, 0xfc, 0xe7, 0x3a, 0x17, 0xff, 0xeb, 0xf3, 0x00, + 0xed, 0x0a, 0xd0, 0xd6, 0x0d, 0xb2, 0xdf, 0xf2, 0xe2, 0x11, 0x24, 0xd4, 0x23, + 0x08, 0x1d, 0xb9, 0x32, 0x2b, 0xde, 0x29, 0x1e, 0xff, 0x08, 0xf5, 0x1b, 0x00, + 0x36, 0x28, 0xe8, 0xd5, 0xfd, 0xce, 0x7f, 0xe7, 0x23, 0xf8, 0x59, 0x23, 0x3c, + 0xea, 0xcf, 0x2e, 0x03, 0x95, 0xdf, 0x16, 0xf3, 0xb2, 0xda, 0xda, 0x1e, 0x3b, + 0x4b, 0x08, 0xe5, 0xea, 0xbe, 0xe9, 0xe5, 0x0e, 0x25, 0x60, 0xf5, 0xab, 0xbc, + 0x0f, 0x22, 0x59, 0x0f, 0x0b, 0x02, 0xed, 0xdd, 0x01, 0x57, 0x09, 0x0d, 0xff, + 0x26, 0x1b, 0x35, 0xd8, 0x17, 0xfb, 0xd2, 0x1b, 0xc9, 0xff, 0x0b, 0x7f, 0xaf, + 0x07, 0x31, 0xd9, 0xef, 0x35, 0xbf, 0x05, 0x29, 0xea, 0xb6, 0xde, 0xac, 0xe4, + 0x05, 0xe5, 0x08, 0xfd, 0xe8, 0xf2, 0xb7, 0xad, 0xb4, 0xc7, 0xe8, 0xea, 0x1b, + 0x02, 0x31, 0xd8, 0x33, 0xbb, 0xe1, 0xbd, 0xfd, 0x8f, 0xd4, 0xeb, 0x46, 0x30, + 0xd0, 0x05, 0xbc, 0xfb, 0x0c, 0xf5, 0x58, 0xba, 0xd1, 0x53, 0x24, 0xf0, 0xca, + 0xc8, 0xe9, 0x46, 0x1d, 0xf2, 0x02, 0x0a, 0xeb, 0xd3, 0x19, 0x44, 0xfa, 0x07, + 0xef, 0xe1, 0x13, 0x33, 0xb5, 0x0b, 0xdc, 0x3f, 0x2d, 0xd0, 0x1c, 0xfd, 0x1c, + 0xcd, 0x15, 0x3d, 0xd7, 0xf9, 0x5e, 0x12, 0x15, 0xf8, 0xfc, 0x0a, 0xfc, 0x19, + 0xe0, 0xce, 0x28, 0xfc, 0xe7, 0xee, 0xec, 0xc7, 0xf5, 0xf0, 0x49, 0x23, 0xd8, + 0x03, 0x52, 0x66, 0x3a, 0xe9, 0x25, 0x3c, 0xf9, 0x14, 0xcb, 0xe8, 0x20, 0xe9, + 0x8f, 0xeb, 0xe1, 0x3a, 0xf1, 0xdb, 0x14, 0x15, 0x8c, 0x14, 0x58, 0x3e, 0x90, + 0x20, 0x22, 0xed, 0xef, 0x21, 0xce, 0x25, 0x29, 0xd2, 0x0c, 0xe8, 0x9a, 0xc8, + 0x39, 0x06, 0x2e, 0xf9, 0xea, 0xa3, 0xca, 0xdc, 0xd5, 0xfa, 0x20, 0x44, 0x27, + 0x02, 0x45, 0xdf, 0x1d, 0x15, 0x32, 0x1c, 0xe5, 0x2c, 0x3a, 0x55, 0xe6, 0x39, + 0xfe, 0x25, 0xf3, 0x26, 0x08, 0xec, 0xec, 0x00, 0xef, 0xfe, 0xee, 0xed, 0x26, + 0x36, 0xef, 0xb0, 0xf5, 0x1d, 0x18, 0x1b, 0x1c, 0xed, 0xf3, 0x1c, 0xe8, 0x01, + 0x21, 0x68, 0xd5, 0x45, 0xc7, 0xd7, 0x10, 0x3d, 0xcf, 0x09, 0x10, 0xee, 0x4b, + 0xfd, 0x45, 0xda, 0x19, 0xd1, 0x78, 0x08, 0xe9, 0xe0, 0x2a, 0xeb, 0xc8, 0x7f, + 0x36, 0x22, 0x27, 0xc2, 0xe9, 0xf7, 0x01, 0x0e, 0xec, 0x37, 0xfb, 0xd6, 0x5b, + 0x38, 0xec, 0x1c, 0xf8, 0x2b, 0xce, 0x29, 0x07, 0x32, 0xeb, 0x0c, 0xc4, 0xff, + 0xe4, 0xfe, 0xce, 0xf7, 0xf1, 0x01, 0xe0, 0x11, 0xdd, 0x1e, 0xde, 0x20, 0x1e, + 0xe6, 0x10, 0x11, 0x0e, 0x7f, 0x2f, 0xc3, 0x5d, 0x02, 0x13, 0xf5, 0x1e, 0x4e, + 0x45, 0xfe, 0x20, 0x26, 0xe3, 0x1d, 0x02, 0xfa, 0x1f, 0x14, 0x3d, 0xc6, 0xef, + 0x42, 0xf6, 0x20, 0x10, 0x18, 0x27, 0x0c, 0x15, 0x3b, 0x1c, 0x34, 0x46, 0x11, + 0xa3, 0x2c, 0x29, 0x06, 0x13, 0x0e, 0xdb, 0x16, 0x4c, 0x28, 0x4c, 0xd1, 0xe3, + 0x4e, 0x1a, 0xf1, 0xf7, 0x10, 0xf1, 0xf0, 0x14, 0xf4, 0x02, 0x1f, 0xec, 0x41, + 0x2e, 0x26, 0xf6, 0xea, 0x35, 0x15, 0xf2, 0xf2, 0xe3, 0xc3, 0xfc, 0x03, 0x21, + 0xe9, 0xf4, 0xda, 0x2e, 0xf2, 0x11, 0xd0, 0x33, 0x12, 0xd7, 0x41, 0x01, 0x14, + 0x15, 0xf0, 0x10, 0xeb, 0x1c, 0x05, 0x15, 0x03, 0xf6, 0xe2, 0xef, 0x62, 0x26, + 0x0b, 0xeb, 0x08, 0xff, 0x1b, 0xed, 0xcf, 0x15, 0xd0, 0xd2, 0xfa, 0xf8, 0xe6, + 0xff, 0x19, 0x1d, 0x01, 0xd3, 0x18, 0xfd, 0xfd, 0xcd, 0x04, 0xdb, 0xdd, 0x14, + 0x12, 0xe4, 0x6d, 0x7f, 0xc8, 0xfc, 0x1b, 0xe5, 0x0d, 0x18, 0x10, 0x34, 0x38, + 0xfb, 0x02, 0x12, 0x11, 0x12, 0x01, 0x33, 0x0d, 0xc3, 0x07, 0x18, 0x0b, 0xce, + 0x0a, 0x1f, 0x00, 0xfa, 0x3d, 0x40, 0x27, 0x30, 0x19, 0xed, 0xef, 0xfe, 0xfc, + 0xe7, 0xde, 0xe7, 0xff, 0xf9, 0xcf, 0xe2, 0xfa, 0x28, 0x35, 0xd5, 0x17, 0x17, + 0x17, 0x1b, 0x1c, 0x11, 0x07, 0x17, 0xf2, 0xf1, 0xfc, 0x0f, 0x16, 0xdb, 0x05, + 0xf4, 0xec, 0xe6, 0xdf, 0x47, 0xd7, 0xe8, 0x10, 0xd1, 0x4c, 0x40, 0x0b, 0xe4, + 0xe0, 0xd9, 0xe7, 0xff, 0x14, 0xfa, 0xe9, 0xdc, 0x1a, 0xdf, 0x17, 0x33, 0x0c, + 0x29, 0xa9, 0x53, 0x1c, 0xd6, 0xc4, 0x13, 0x74, 0xf8, 0xf8, 0x1d, 0xfd, 0x2f, + 0x09, 0xb0, 0x2d, 0x15, 0x1a, 0xcc, 0xcd, 0x2c, 0xdd, 0x19, 0x4d, 0xeb, 0x04, + 0x89, 0xe1, 0x28, 0xff, 0xf6, 0xf8, 0x1e, 0xd9, 0x00, 0x1f, 0xf3, 0xfb, 0xe3, + 0x56, 0x06, 0xfd, 0xe3, 0xfb, 0x0d, 0x1e, 0xc5, 0xdc, 0xe6, 0x09, 0x39, 0xdf, + 0x2f, 0x1e, 0xb8, 0x09, 0x36, 0xfb, 0x43, 0x41, 0xa4, 0xfa, 0xd9, 0xd7, 0x1c, + 0xda, 0x24, 0xcf, 0x14, 0x1a, 0xc3, 0xce, 0xb3, 0xc5, 0x9a, 0x8a, 0x04, 0xc5, + 0xdf, 0x6c, 0xef, 0x16, 0xe7, 0xe9, 0xfe, 0xd1, 0xee, 0xd4, 0x25, 0xf1, 0x0b, + 0xf3, 0xe5, 0xc2, 0xa7, 0xdd, 0xef, 0x44, 0x0d, 0x0d, 0xf5, 0xe0, 0x11, 0x20, + 0xc8, 0xbe, 0xf8, 0x1a, 0xe7, 0x49, 0x13, 0xd0, 0xe6, 0x03, 0x32, 0x4c, 0x81, + 0x06, 0xea, 0xcf, 0x17, 0x01, 0x44, 0xd8, 0x39, 0xf5, 0xcd, 0x52, 0x11, 0xfe, + 0x03, 0xd3, 0x0a, 0xe8, 0x18, 0xe2, 0x08, 0x18, 0xf8, 0x54, 0x26, 0xea, 0xc1, + 0xf8, 0xf5, 0xd4, 0xe1, 0x37, 0x66, 0x0c, 0x1c, 0xf4, 0x32, 0x0d, 0x6c, 0x12, + 0xf8, 0xe5, 0x11, 0xd7, 0x02, 0x5b, 0x0a, 0xe3, 0x23, 0x41, 0xa5, 0x57, 0x1b, + 0x47, 0xf3, 0xf9, 0x58, 0xe3, 0x3d, 0x24, 0x15, 0x1d, 0xfd, 0xb3, 0xc4, 0xfd, + 0xf4, 0xdf, 0x16, 0xf0, 0x38, 0xf7, 0x18, 0x19, 0x19, 0x63, 0x0e, 0x36, 0x40, + 0x2d, 0x17, 0xed, 0x30, 0x4c, 0x04, 0xf0, 0xb5, 0x42, 0x16, 0x04, 0x07, 0xfe, + 0x37, 0x70, 0x24, 0xe6, 0xfe, 0x7f, 0x03, 0xd4, 0x29, 0x41, 0x09, 0xe0, 0x0b, + 0x31, 0xda, 0x35, 0x02, 0xe9, 0xee, 0x0b, 0x02, 0xfb, 0x01, 0xfc, 0x12, 0x08, + 0xec, 0xdd, 0x40, 0xea, 0xea, 0xd4, 0x4a, 0xf7, 0xde, 0xf4, 0xe6, 0x23, 0x57, + 0x0a, 0x31, 0xe2, 0x09, 0x07, 0x2f, 0xe2, 0xca, 0x50, 0x12, 0x37, 0x19, 0x28, + 0xe2, 0x04, 0x7f, 0x4d, 0x3c, 0xad, 0x28, 0xf0, 0xea, 0xe0, 0xac, 0x01, 0x06, + 0x37, 0x5c, 0x08, 0xb8, 0xe9, 0x09, 0xd1, 0x35, 0x16, 0xdf, 0x22, 0xf9, 0x10, + 0x18, 0x22, 0x1b, 0xec, 0x00, 0xf6, 0xd4, 0x41, 0x16, 0x1f, 0xf9, 0xf9, 0x19, + 0x40, 0x45, 0x52, 0xf9, 0x1c, 0x17, 0xed, 0xd9, 0x2f, 0x1f, 0x71, 0x61, 0xca, + 0x0c, 0xfc, 0xf6, 0xf8, 0x29, 0x02, 0xd8, 0x16, 0xfa, 0xc5, 0x18, 0x28, 0x14, + 0x26, 0x03, 0xcd, 0xc0, 0x2e, 0x1b, 0x15, 0x31, 0xec, 0xf5, 0xda, 0x30, 0x0c, + 0x54, 0x5e, 0x18, 0x30, 0x1e, 0xeb, 0xe4, 0x08, 0x17, 0x29, 0x15, 0xfc, 0xdd, + 0xd8, 0x1b, 0x3e, 0xc8, 0x28, 0x31, 0x0e, 0xe6, 0x11, 0x06, 0x3a, 0xa8, 0xe6, + 0x1c, 0xe7, 0xd9, 0x66, 0x3d, 0x0b, 0xda, 0x30, 0x37, 0x0e, 0xc6, 0x22, 0xe6, + 0x1e, 0x28, 0xeb, 0xe9, 0x9a, 0x29, 0x37, 0x19, 0xec, 0xd4, 0xfd, 0xe5, 0xed, + 0xfb, 0x59, 0xde, 0x29, 0xce, 0x25, 0xfd, 0xe2, 0xea, 0x13, 0xde, 0xcd, 0xee, + 0x3d, 0x38, 0xef, 0x1f, 0x1b, 0x7f, 0xee, 0xef, 0x37, 0xca, 0x29, 0x0a, 0xff, + 0xe5, 0xec, 0x0c, 0xf7, 0xdb, 0x2a, 0x12, 0xd2, 0x29, 0x16, 0xbc, 0xef, 0x19, + 0xf9, 0x34, 0xee, 0x07, 0xec, 0xe4, 0xee, 0x42, 0xd6, 0xfa, 0x17, 0xd6, 0xdd, + 0xc7, 0x02, 0xdc, 0xe8, 0xcc, 0xd8, 0xe3, 0xd8, 0x0a, 0x0a, 0x20, 0x08, 0xeb, + 0x2d, 0xfe, 0x1f, 0xee, 0x05, 0xe2, 0x3a, 0xe7, 0xe9, 0xe4, 0xe2, 0xfd, 0xc3, + 0xbe, 0xec, 0xd6, 0xdc, 0xe1, 0xee, 0xee, 0x17, 0x16, 0x3e, 0xee, 0x32, 0xf4, + 0x02, 0xf8, 0x25, 0xdc, 0x05, 0xf5, 0x1b, 0xf0, 0xfe, 0xe7, 0x00, 0x15, 0xd9, + 0x0d, 0x05, 0xe6, 0xd7, 0x1f, 0x1d, 0x02, 0xe5, 0xcb, 0xeb, 0xd8, 0x13, 0xee, + 0x46, 0xe6, 0x10, 0xc1, 0xee, 0x11, 0xef, 0xec, 0xfe, 0x1a, 0xd6, 0x27, 0xf9, + 0xf9, 0x07, 0x06, 0xee, 0x30, 0x0c, 0x3a, 0x1b, 0x1a, 0x31, 0x0b, 0xf1, 0x20, + 0x10, 0x25, 0x2b, 0x15, 0xd3, 0xf7, 0x1e, 0x38, 0xe8, 0x7f, 0x04, 0x29, 0x18, + 0x0b, 0xe9, 0xf7, 0xea, 0x16, 0xe8, 0xe9, 0x06, 0xfa, 0xe1, 0x0b, 0xdd, 0xdb, + 0x02, 0x0e, 0xfc, 0x01, 0x50, 0xe6, 0x01, 0xca, 0xea, 0x08, 0x05, 0x38, 0x05, + 0xe0, 0x0e, 0x13, 0x1d, 0xd2, 0x02, 0xe8, 0x00, 0xf8, 0xe9, 0x13, 0x07, 0x0e, + 0x2e, 0x10, 0x4a, 0x0c, 0x07, 0x41, 0x18, 0x07, 0x34, 0x03, 0xf1, 0x27, 0xde, + 0xff, 0xc5, 0x16, 0xe7, 0xd8, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x21, 0x15, 0xf3, + 0xed, 0xf5, 0xf6, 0x2d, 0xe5, 0x4a, 0xc9, 0xe0, 0x0f, 0x20, 0xf2, 0x1a, 0x28, + 0x3c, 0x1a, 0xf6, 0xfa, 0x3a, 0xe4, 0x3f, 0x0d, 0x05, 0xde, 0xe9, 0x1e, 0x17, + 0x3a, 0x21, 0xbf, 0xbb, 0x0b, 0xed, 0xfc, 0x15, 0xe8, 0xfe, 0x81, 0x2b, 0xd8, + 0x2e, 0x14, 0x2f, 0xd9, 0xeb, 0x22, 0x0f, 0x0a, 0xf4, 0xf1, 0x01, 0x17, 0x0a, + 0x20, 0xe9, 0x29, 0xf7, 0xea, 0xfb, 0xf9, 0xfb, 0xd0, 0x48, 0xef, 0x05, 0xce, + 0xf5, 0xf8, 0xc7, 0x52, 0xd5, 0x07, 0xd3, 0xfc, 0xf4, 0xa8, 0x2d, 0x14, 0xdb, + 0x3b, 0xdd, 0xd1, 0xfb, 0x1e, 0xd3, 0x09, 0xc4, 0xce, 0x12, 0xcd, 0xce, 0xe2, + 0x07, 0x43, 0xfb, 0xf2, 0xd7, 0x1a, 0xe8, 0x1c, 0xf4, 0x16, 0x1a, 0xb7, 0xe8, + 0xec, 0xe7, 0xe6, 0x04, 0xfc, 0x3c, 0x3c, 0xf7, 0xc3, 0xec, 0x58, 0xe0, 0x24, + 0xdf, 0x1a, 0x40, 0x41, 0xfa, 0x25, 0xf5, 0x00, 0xc5, 0x3f, 0xfc, 0xd5, 0x24, + 0x1a, 0xfc, 0xf6, 0xd6, 0xb2, 0x10, 0x0c, 0xeb, 0x02, 0x01, 0x33, 0xd7, 0x06, + 0xe2, 0x13, 0xff, 0x11, 0x38, 0xc9, 0xd7, 0xd7, 0xeb, 0xf4, 0x15, 0xfa, 0xda, + 0x32, 0x3d, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xb5, + 0x79, 0x9c, 0x67, 0xe0, 0x3a, 0x57, 0xa7, 0x81, 0x58, 0x81, 0x7f, 0x5f, 0xe6, + 0xfe, 0xb2, 0xc5, 0xdb, 0x8a, 0x3c, 0xec, 0xc7, 0xaf, 0xa8, 0xf2, 0x09, 0x08, + 0x2f, 0xdd, 0x81, 0x7b, 0xb7, 0x0a, 0x0e, 0x24, 0x6b, 0x7f, 0xa3, 0x01, 0xdd, + 0x10, 0x04, 0x8c, 0x26, 0xe6, 0x4e, 0x81, 0x81, 0x39, 0x81, 0x04, 0x4f, 0xf1, + 0x46, 0x28, 0xc0, 0x6a, 0x9c, 0x3e, 0xb7, 0x2e, 0x77, 0x06, 0xfa, 0x46, 0x1d, + 0x63, 0x4c, 0xf2, 0xec, 0xd1, 0x91, 0x5c, 0x95, 0xfc, 0xff, 0x60, 0x95, 0xfc, + 0xff, 0x64, 0x95, 0xfc, 0xff, 0x68, 0x95, 0xfc, 0xff, 0x96, 0x3d, 0xfd, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0xf9, 0xf0, 0x0f, 0x05, + 0x06, 0x81, 0x04, 0xff, 0x74, 0xef, 0xfe, 0xf9, 0x81, 0x18, 0x16, 0x7f, 0xeb, + 0xf7, 0x04, 0x00, 0x12, 0xf5, 0xf7, 0x20, 0xec, 0x06, 0xf4, 0x7f, 0x5a, 0x7a, + 0xf7, 0x07, 0xfa, 0x2a, 0xef, 0x60, 0x0a, 0x7f, 0xee, 0x81, 0x55, 0x0a, 0xfa, + 0xfc, 0xbb, 0x0b, 0xfe, 0xdf, 0x19, 0xec, 0xfb, 0x1f, 0x04, 0x81, 0xef, 0x7f, + 0x3e, 0xea, 0xf8, 0xce, 0x31, 0x4d, 0x11, 0xfc, 0x81, 0x0b, 0x00, 0xfd, 0x15, + 0xf9, 0xf8, 0x01, 0x0d, 0x0f, 0x01, 0x03, 0xe6, 0x81, 0x03, 0x81, 0xdb, 0x0c, + 0xfa, 0x0a, 0x0d, 0xc9, 0xf8, 0x49, 0x5a, 0x15, 0xf1, 0xfd, 0x60, 0x81, 0xfd, + 0x04, 0xf1, 0x01, 0x07, 0xa2, 0x0b, 0x81, 0xf9, 0xb4, 0xc8, 0x07, 0x02, 0xaa, + 0x17, 0x7f, 0x02, 0x05, 0xd9, 0xd7, 0xf0, 0x7f, 0x23, 0xd8, 0x1d, 0x0d, 0x0a, + 0x09, 0xf1, 0xf5, 0xea, 0x7f, 0x00, 0x22, 0x3e, 0xfd, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xe2, 0xff, 0xff, 0xff, 0x2f, 0x00, 0x00, + 0xaf, 0xee, 0xff, 0xff, 0xdb, 0x16, 0x00, 0x00, 0x44, 0xff, 0xff, 0xff, 0x16, + 0x54, 0x00, 0x00, 0x34, 0x17, 0x00, 0x00, 0xd5, 0x0c, 0x00, 0x00, 0xf6, 0x22, + 0x00, 0x00, 0xcd, 0x20, 0x00, 0x00, 0xdf, 0x8f, 0x00, 0x00, 0x64, 0x25, 0x00, + 0x00, 0x83, 0x1d, 0x00, 0x00, 0x53, 0x42, 0x00, 0x00, 0xe6, 0x19, 0x00, 0x00, + 0x9f, 0x0d, 0x00, 0x00, 0x03, 0xde, 0xff, 0xff, 0x52, 0x23, 0x00, 0x00, 0x71, + 0x3f, 0x00, 0x00, 0x92, 0x19, 0x00, 0x00, 0xb0, 0xd9, 0xff, 0xff, 0xa0, 0x23, + 0x00, 0x00, 0xaf, 0x03, 0x00, 0x00, 0x30, 0xf9, 0xff, 0xff, 0x2b, 0x28, 0x00, + 0x00, 0xfc, 0x97, 0x00, 0x00, 0xcc, 0x09, 0x00, 0x00, 0xb9, 0x24, 0x00, 0x00, + 0x6b, 0xb9, 0xff, 0xff, 0x68, 0x56, 0x00, 0x00, 0x43, 0x2c, 0x00, 0x00, 0xce, + 0xef, 0xff, 0xff, 0xae, 0x3e, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x03, 0x34, 0xee, 0xd9, 0x38, 0x14, 0x0d, 0xc6, 0xdc, 0x0d, 0x1d, + 0xf3, 0x7f, 0x3a, 0x01, 0x13, 0x0f, 0x3c, 0xfd, 0x0d, 0xe3, 0xd9, 0xc3, 0xaf, + 0xad, 0xfc, 0x1a, 0xff, 0xf2, 0x7f, 0xe4, 0xdc, 0x0d, 0x74, 0x0d, 0x0a, 0xdb, + 0xdb, 0xd6, 0xac, 0xe4, 0x1f, 0xfc, 0x43, 0xff, 0x7f, 0xf9, 0x04, 0xf8, 0x48, + 0xf0, 0x85, 0x56, 0x81, 0xbc, 0xc9, 0xd4, 0x04, 0x31, 0xf8, 0x64, 0xe4, 0x16, + 0xec, 0x40, 0xed, 0xbe, 0xf2, 0x0c, 0x0b, 0x19, 0x0c, 0x38, 0x07, 0xc8, 0xe4, + 0x2d, 0x81, 0xe4, 0x77, 0xab, 0xf6, 0x2a, 0xe2, 0x27, 0xe8, 0x0a, 0xa3, 0x49, + 0xad, 0x7f, 0x1c, 0xf4, 0x39, 0x17, 0xa1, 0xa7, 0x1b, 0x0b, 0xef, 0x17, 0xd9, + 0xff, 0xf1, 0x02, 0x49, 0x2b, 0xe3, 0xcf, 0x2f, 0x7f, 0xa2, 0xff, 0xe4, 0x0f, + 0xe8, 0xe4, 0x01, 0x7f, 0xa3, 0xfa, 0xdd, 0xff, 0xce, 0x0d, 0xf6, 0xea, 0x0d, + 0xaa, 0xf6, 0xc2, 0x32, 0x02, 0xeb, 0x29, 0x1b, 0x7f, 0xe6, 0xee, 0x0c, 0xf3, + 0xc2, 0x25, 0x35, 0xde, 0xfc, 0xdc, 0xc9, 0x7f, 0x2b, 0xd7, 0x17, 0x20, 0x22, + 0x2b, 0x09, 0x59, 0xba, 0x38, 0x35, 0x16, 0x5d, 0x4d, 0x3c, 0xad, 0x95, 0x09, + 0xbd, 0x81, 0xe2, 0x22, 0xc8, 0x9f, 0x33, 0xec, 0xab, 0x70, 0x16, 0xeb, 0x24, + 0x20, 0xce, 0x2f, 0xc2, 0xb8, 0xe5, 0xf7, 0x14, 0x1e, 0x22, 0x81, 0x2f, 0xda, + 0x7f, 0xc3, 0xce, 0x5a, 0xcc, 0x70, 0xfa, 0x4d, 0x06, 0xa7, 0x8e, 0x06, 0xbc, + 0x1d, 0x35, 0x15, 0x0b, 0xd6, 0xed, 0x1f, 0xef, 0xc2, 0xca, 0xd1, 0xe1, 0xf7, + 0x23, 0xff, 0x81, 0xd2, 0x39, 0xe3, 0xee, 0x15, 0x06, 0xe2, 0xf6, 0x48, 0xc0, + 0x13, 0xeb, 0x81, 0xbd, 0x13, 0x37, 0xf5, 0x38, 0x29, 0xfc, 0x7f, 0xf4, 0xee, + 0x0a, 0x08, 0x1e, 0xac, 0x1f, 0xd0, 0x43, 0xe4, 0xd3, 0xf1, 0xfd, 0x2e, 0xe6, + 0xd4, 0x2f, 0x2b, 0x3e, 0x0a, 0x5a, 0x7f, 0x08, 0xd4, 0xe3, 0x18, 0x24, 0xb1, + 0x00, 0x11, 0x85, 0xed, 0xfc, 0x22, 0x3c, 0x0e, 0x19, 0xc7, 0x78, 0xfa, 0xbc, + 0x27, 0xfb, 0x2f, 0x81, 0x5f, 0x35, 0x0c, 0x1a, 0xe8, 0x96, 0xbd, 0x7f, 0x95, + 0x0e, 0x32, 0x62, 0xe7, 0xf6, 0xcf, 0xb3, 0xb3, 0xef, 0x55, 0xf5, 0xf2, 0xf2, + 0x24, 0xbf, 0x55, 0x79, 0xfe, 0xcc, 0xf4, 0x61, 0x58, 0x81, 0x69, 0x81, 0x11, + 0xb0, 0x4d, 0xee, 0x2d, 0x7f, 0x39, 0xdc, 0xde, 0xf7, 0x76, 0x52, 0xb6, 0xdf, + 0x7f, 0x0e, 0x68, 0x18, 0x1d, 0xe3, 0xc7, 0xb9, 0x25, 0xb6, 0x48, 0x15, 0x2b, + 0xe8, 0xc5, 0x0b, 0x11, 0x03, 0xe4, 0xc9, 0xf5, 0x19, 0xe1, 0x7f, 0x05, 0x25, + 0xd7, 0x3f, 0x08, 0x0b, 0x00, 0xba, 0x29, 0x7f, 0x1f, 0xe7, 0x18, 0xf3, 0x04, + 0x26, 0xf1, 0x1a, 0xe6, 0x11, 0x19, 0xe7, 0xfa, 0xf0, 0xa7, 0x0c, 0xf6, 0x7f, + 0xc3, 0x09, 0xec, 0xe0, 0x14, 0xe2, 0x23, 0xf0, 0x97, 0x04, 0x38, 0x10, 0x7f, + 0xd3, 0x08, 0x5d, 0xb5, 0x25, 0x20, 0x46, 0x95, 0x30, 0xa6, 0x09, 0xde, 0x64, + 0xcc, 0xf6, 0xa8, 0x03, 0xfe, 0x01, 0x10, 0xf1, 0x38, 0xfb, 0xeb, 0xfc, 0x7f, + 0x06, 0x00, 0x06, 0xf1, 0x1a, 0x3d, 0xf4, 0xf1, 0xec, 0xef, 0x7f, 0xdf, 0x2d, + 0x99, 0x12, 0xa9, 0x40, 0xef, 0x94, 0xf3, 0x0f, 0x7f, 0xe8, 0x29, 0x07, 0xf8, + 0xd9, 0xca, 0x23, 0x71, 0x36, 0x06, 0x0b, 0x2c, 0x1a, 0xdb, 0xf4, 0xec, 0x7f, + 0xe4, 0xdf, 0x03, 0xa3, 0xde, 0xb6, 0xa8, 0x08, 0x0f, 0xda, 0xfe, 0xc5, 0x1a, + 0xd2, 0xe4, 0x3a, 0xca, 0xf3, 0xfa, 0x81, 0xd0, 0xd3, 0xf2, 0x08, 0x10, 0xda, + 0x17, 0x02, 0x1a, 0x11, 0x81, 0x81, 0x76, 0xf9, 0xd7, 0xe3, 0xda, 0xbc, 0x51, + 0x3e, 0x65, 0xbe, 0x37, 0x71, 0x43, 0xca, 0xba, 0x40, 0xfd, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x14, 0xfd, 0x8d, 0x2e, 0x0c, 0x0c, 0xff, + 0x1a, 0x0e, 0x00, 0x85, 0xbe, 0xff, 0x00, 0xf9, 0xf0, 0x11, 0xf9, 0x81, 0x90, + 0xf7, 0x01, 0x00, 0x01, 0xe0, 0xf0, 0xf2, 0x9f, 0xe1, 0xe9, 0x00, 0x22, 0x81, + 0x1b, 0x0c, 0x18, 0xfe, 0xcb, 0x13, 0x5e, 0xd9, 0xeb, 0x42, 0x3e, 0x0a, 0xec, + 0x00, 0x7f, 0x24, 0xf9, 0xdf, 0xcc, 0x81, 0xbc, 0x01, 0x66, 0xb4, 0x7f, 0xfe, + 0x81, 0x1c, 0x81, 0x7f, 0x63, 0x25, 0x3b, 0xc3, 0xa5, 0x78, 0x8f, 0x01, 0x03, + 0x0e, 0x41, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x7a, + 0xed, 0xff, 0xff, 0xc0, 0xef, 0xff, 0xff, 0x49, 0x1b, 0x00, 0x00, 0xc7, 0x21, + 0x00, 0x00, 0x4d, 0x74, 0x00, 0x00, 0x26, 0x7a, 0x00, 0x00, 0x85, 0xc4, 0xff, + 0xff, 0x41, 0x95, 0xff, 0xff, 0x1b, 0xf2, 0xff, 0xff, 0x05, 0x33, 0x00, 0x00, + 0xcb, 0xf5, 0xff, 0xff, 0x4d, 0x6c, 0x00, 0x00, 0xb1, 0x08, 0x00, 0x00, 0x01, + 0xd2, 0xff, 0xff, 0x47, 0x05, 0x00, 0x00, 0x59, 0x3e, 0x00, 0x00, 0x13, 0xd9, + 0xff, 0xff, 0x62, 0x2f, 0x00, 0x00, 0x79, 0xcd, 0xff, 0xff, 0x86, 0xd7, 0xff, + 0xff, 0x99, 0x0a, 0x00, 0x00, 0x7f, 0x21, 0x00, 0x00, 0x27, 0xf4, 0xff, 0xff, + 0xc2, 0xec, 0xff, 0xff, 0xc1, 0xf3, 0xff, 0xff, 0x04, 0xff, 0xff, 0xff, 0x0f, + 0xf5, 0xff, 0xff, 0x51, 0xed, 0xff, 0xff, 0x3c, 0x2a, 0x00, 0x00, 0xec, 0xe8, + 0xff, 0xff, 0x24, 0xc3, 0xff, 0xff, 0x99, 0x32, 0x00, 0x00, 0x9a, 0x41, 0xfd, + 0xff, 0x04, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x4f, 0x2a, 0xde, 0x21, + 0xa6, 0xcc, 0x33, 0x25, 0x47, 0xe7, 0x16, 0xe6, 0xc7, 0x59, 0xb9, 0x94, 0x7f, + 0x3d, 0xd7, 0x5e, 0x81, 0x9f, 0x61, 0x50, 0x6a, 0xb5, 0x40, 0xa7, 0xa3, 0x7f, + 0xa2, 0xac, 0x4f, 0x1a, 0xde, 0x32, 0xbb, 0xe6, 0x3d, 0x37, 0x2e, 0xd2, 0x37, + 0x88, 0xcc, 0x3a, 0xda, 0xe7, 0x4e, 0x52, 0xbd, 0x30, 0xa1, 0x98, 0x3d, 0x7f, + 0x53, 0xdb, 0x53, 0xb1, 0xb7, 0x3b, 0xa0, 0xc6, 0x69, 0x7f, 0x81, 0x7f, 0x83, + 0x81, 0x7f, 0x7f, 0x7f, 0x81, 0x7f, 0x81, 0x81, 0x69, 0x81, 0x81, 0x38, 0x40, + 0xc8, 0x43, 0xb5, 0xe8, 0x56, 0x2f, 0x3d, 0xd3, 0x4b, 0xa6, 0xb8, 0x4f, 0xbb, + 0xc4, 0x16, 0x20, 0xd6, 0x01, 0xe1, 0xe3, 0x18, 0x63, 0x1d, 0xf3, 0x41, 0xdf, + 0xeb, 0x04, 0xe9, 0x18, 0x1d, 0x4c, 0xa4, 0x23, 0xc5, 0xd1, 0x2d, 0x58, 0x2b, + 0xeb, 0x53, 0xc8, 0xc9, 0x07, 0xe0, 0xfd, 0x13, 0x26, 0xeb, 0x24, 0xf9, 0x01, + 0x1c, 0x12, 0x12, 0x00, 0x23, 0xf0, 0xe3, 0x0e, 0xf8, 0xfc, 0x0c, 0x9a, 0xfc, + 0xff, 0x3a, 0x42, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x9c, 0x79, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x7c, + 0xf5, 0xff, 0xff, 0xf1, 0x1c, 0x00, 0x00, 0xcc, 0x3d, 0x00, 0x00, 0xdb, 0x02, + 0x00, 0x00, 0xc2, 0xff, 0xff, 0xff, 0x66, 0x42, 0xfd, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0xe7, 0xe7, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, + 0x1c, 0xf5, 0xff, 0xff, 0x54, 0x38, 0x00, 0x00, 0xdf, 0xe2, 0xff, 0xff, 0xbe, + 0x0b, 0x00, 0x00, 0xbe, 0x02, 0x00, 0x00, 0xc9, 0xed, 0xff, 0xff, 0xa7, 0x31, + 0x00, 0x00, 0x86, 0x2a, 0x00, 0x00, 0x48, 0x2b, 0x00, 0x00, 0x9d, 0xf3, 0xff, + 0xff, 0x00, 0xec, 0xff, 0xff, 0x2f, 0xe0, 0xff, 0xff, 0x94, 0x39, 0x00, 0x00, + 0x83, 0xd9, 0xff, 0xff, 0x50, 0x06, 0x00, 0x00, 0xd1, 0xfc, 0xff, 0xff, 0x1f, + 0xfd, 0xff, 0xff, 0x33, 0x2b, 0x00, 0x00, 0xa6, 0xf8, 0xff, 0xff, 0x8e, 0xde, + 0xff, 0xff, 0x78, 0x1c, 0x00, 0x00, 0xcc, 0x24, 0x00, 0x00, 0xfd, 0xed, 0xff, + 0xff, 0x55, 0x06, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xb6, 0xe8, 0xff, 0xff, + 0x06, 0xf2, 0xff, 0xff, 0x6b, 0xf5, 0xff, 0xff, 0x83, 0xfc, 0xff, 0xff, 0x6b, + 0xf6, 0xff, 0xff, 0x99, 0xf9, 0xff, 0xff, 0xdd, 0xf0, 0xff, 0xff, 0x68, 0x38, + 0x00, 0x00, 0x22, 0xf1, 0xff, 0xff, 0xe3, 0xeb, 0xff, 0xff, 0x2a, 0xf3, 0xff, + 0xff, 0xc1, 0x32, 0x00, 0x00, 0xe5, 0xe5, 0xff, 0xff, 0x26, 0x26, 0x00, 0x00, + 0xfb, 0x08, 0x00, 0x00, 0x31, 0xf9, 0xff, 0xff, 0x56, 0xe6, 0xff, 0xff, 0xd5, + 0xe0, 0xff, 0xff, 0x40, 0xe8, 0xff, 0xff, 0xdf, 0xf1, 0xff, 0xff, 0x76, 0xf5, + 0xff, 0xff, 0x2e, 0xe4, 0xff, 0xff, 0xec, 0xf1, 0xff, 0xff, 0x19, 0xf5, 0xff, + 0xff, 0x03, 0x2c, 0x00, 0x00, 0xb4, 0xec, 0xff, 0xff, 0x57, 0xe2, 0xff, 0xff, + 0x26, 0xe7, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0x2a, 0xf9, 0xff, 0xff, 0x91, + 0xf3, 0xff, 0xff, 0x2a, 0xec, 0xff, 0xff, 0xb1, 0xe3, 0xff, 0xff, 0xa0, 0xf7, + 0xff, 0xff, 0x0a, 0x28, 0x00, 0x00, 0xfb, 0xeb, 0xff, 0xff, 0xa2, 0xfb, 0xff, + 0xff, 0x62, 0x26, 0x00, 0x00, 0x82, 0xf0, 0xff, 0xff, 0x5e, 0x29, 0x00, 0x00, + 0xe7, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xf7, 0xff, 0xff, 0x40, + 0xfa, 0xff, 0xff, 0x70, 0x0a, 0x00, 0x00, 0xeb, 0xf5, 0xff, 0xff, 0x15, 0x2b, + 0x00, 0x00, 0xf0, 0xf2, 0xff, 0xff, 0x6f, 0x24, 0x00, 0x00, 0xd8, 0x11, 0x00, + 0x00, 0x79, 0x28, 0x00, 0x00, 0x1e, 0xf8, 0xff, 0xff, 0x76, 0xf9, 0xff, 0xff, + 0x12, 0xe8, 0xff, 0xff, 0xa4, 0x31, 0x00, 0x00, 0x2a, 0xfd, 0xff, 0xff, 0x89, + 0xea, 0xff, 0xff, 0xfe, 0xe3, 0xff, 0xff, 0xf5, 0x28, 0x00, 0x00, 0xf9, 0x1b, + 0x00, 0x00, 0xdd, 0xf8, 0xff, 0xff, 0xb1, 0x04, 0x00, 0x00, 0xb8, 0xf3, 0xff, + 0xff, 0x9f, 0x03, 0x00, 0x00, 0x92, 0xe7, 0xff, 0xff, 0x93, 0xfe, 0xff, 0xff, + 0xe6, 0x2d, 0x00, 0x00, 0xf7, 0x30, 0x00, 0x00, 0x6c, 0x36, 0x00, 0x00, 0x4a, + 0x0c, 0x00, 0x00, 0x4c, 0xf8, 0xff, 0xff, 0x12, 0xed, 0xff, 0xff, 0x67, 0xf8, + 0xff, 0xff, 0x29, 0x33, 0x00, 0x00, 0x08, 0xef, 0xff, 0xff, 0x72, 0x2b, 0x00, + 0x00, 0xed, 0xf4, 0xff, 0xff, 0x0b, 0x29, 0x00, 0x00, 0xf4, 0x2e, 0x00, 0x00, + 0x48, 0xfe, 0xff, 0xff, 0xd3, 0xf2, 0xff, 0xff, 0xde, 0xfd, 0xff, 0xff, 0xd9, + 0x08, 0x00, 0x00, 0x6e, 0x25, 0x00, 0x00, 0x9b, 0xf6, 0xff, 0xff, 0xf7, 0xea, + 0xff, 0xff, 0x82, 0x0a, 0x00, 0x00, 0x7d, 0x0e, 0x00, 0x00, 0x68, 0xee, 0xff, + 0xff, 0x0c, 0x27, 0x00, 0x00, 0xeb, 0x2e, 0x00, 0x00, 0xc9, 0xfe, 0xff, 0xff, + 0xda, 0x39, 0x00, 0x00, 0xd4, 0x32, 0x00, 0x00, 0x1e, 0x03, 0x00, 0x00, 0x1d, + 0xdf, 0xff, 0xff, 0xe8, 0xfb, 0xff, 0xff, 0x89, 0x07, 0x00, 0x00, 0xcd, 0x28, + 0x00, 0x00, 0x22, 0x1e, 0x00, 0x00, 0xe5, 0xf8, 0xff, 0xff, 0x48, 0x9c, 0xfc, + 0xff, 0x4c, 0x9c, 0xfc, 0xff, 0x50, 0x9c, 0xfc, 0xff, 0x54, 0x9c, 0xfc, 0xff, + 0x58, 0x9c, 0xfc, 0xff, 0x5c, 0x9c, 0xfc, 0xff, 0x8a, 0x44, 0xfd, 0xff, 0x04, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x32, 0x01, 0x00, 0x00, 0x62, 0xff, + 0xff, 0xff, 0xed, 0x4a, 0x00, 0x00, 0x94, 0xfe, 0xff, 0xff, 0x5d, 0x18, 0x00, + 0x00, 0x82, 0x2f, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, + 0x79, 0x01, 0x00, 0x00, 0x7d, 0x2c, 0x00, 0x00, 0xc2, 0x15, 0x00, 0x00, 0x74, + 0x36, 0x00, 0x00, 0x1a, 0x56, 0x00, 0x00, 0xa2, 0x11, 0x00, 0x00, 0x6c, 0x1d, + 0x00, 0x00, 0x29, 0x1e, 0x00, 0x00, 0xac, 0x9c, 0xfc, 0xff, 0xb0, 0x9c, 0xfc, + 0xff, 0xb4, 0x9c, 0xfc, 0xff, 0xb8, 0x9c, 0xfc, 0xff, 0xbc, 0x9c, 0xfc, 0xff, + 0xc0, 0x9c, 0xfc, 0xff, 0xc4, 0x9c, 0xfc, 0xff, 0xc8, 0x9c, 0xfc, 0xff, 0xcc, + 0x9c, 0xfc, 0xff, 0xd0, 0x9c, 0xfc, 0xff, 0xd4, 0x9c, 0xfc, 0xff, 0x02, 0x45, + 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x50, 0x27, 0x00, + 0x00, 0x6a, 0x04, 0x00, 0x00, 0x00, 0xcd, 0xff, 0xff, 0xb4, 0x89, 0xff, 0xff, + 0xcb, 0xa4, 0xff, 0xff, 0x2a, 0x40, 0x00, 0x00, 0x76, 0x19, 0x00, 0x00, 0xd1, + 0xbd, 0xff, 0xff, 0x57, 0x0b, 0x00, 0x00, 0x4e, 0x32, 0x00, 0x00, 0x17, 0x46, + 0x00, 0x00, 0x15, 0xed, 0xff, 0xff, 0x10, 0x4a, 0x00, 0x00, 0x2c, 0x21, 0x00, + 0x00, 0xd1, 0xd7, 0xff, 0xff, 0x07, 0xdc, 0xff, 0xff, 0x4e, 0x45, 0xfd, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x1b, 0x31, 0x3b, 0x4d, 0x2e, + 0xfe, 0xe7, 0xae, 0xcf, 0x14, 0x7f, 0xfc, 0xe6, 0x08, 0x36, 0xa9, 0x01, 0x7a, + 0xdf, 0xf7, 0xf8, 0x0b, 0xed, 0x0e, 0xfe, 0xfc, 0xd3, 0x81, 0xf5, 0xbc, 0x02, + 0xf4, 0xa4, 0x81, 0x9a, 0xfa, 0xcd, 0xf0, 0x46, 0xd4, 0xd4, 0xcd, 0xa8, 0x37, + 0xb3, 0xb8, 0x2e, 0xe1, 0x51, 0x4e, 0xfa, 0x1f, 0xf2, 0xc3, 0xd9, 0x7f, 0x3c, + 0x0f, 0x4e, 0xe4, 0x7f, 0x81, 0x81, 0xb8, 0x16, 0x0a, 0x06, 0xb1, 0xbe, 0xf5, + 0x2a, 0xd4, 0x2f, 0x25, 0xd5, 0xac, 0x57, 0x29, 0xd3, 0xa5, 0xf0, 0x8d, 0x19, + 0x07, 0x81, 0x1b, 0xbe, 0x01, 0xe1, 0xea, 0xf6, 0xcc, 0xe9, 0x31, 0x2a, 0x12, + 0xf1, 0x46, 0x7f, 0x7f, 0x7f, 0xe0, 0x61, 0xbb, 0xdd, 0x0a, 0xe8, 0x04, 0xb7, + 0x11, 0x0c, 0xcd, 0x0a, 0x7f, 0xf6, 0x1e, 0xfe, 0xa6, 0xa4, 0x01, 0x64, 0xc9, + 0x4a, 0xa8, 0x43, 0xba, 0xc3, 0x7f, 0x81, 0x63, 0xbb, 0x00, 0xc6, 0x81, 0x7f, + 0x9e, 0x81, 0x81, 0xf7, 0x7f, 0x81, 0x81, 0x7f, 0x1d, 0x7f, 0xed, 0x7f, 0x81, + 0xe3, 0x7f, 0x9f, 0x3c, 0x7f, 0x81, 0x7f, 0x49, 0x61, 0x9f, 0xa2, 0x00, 0x13, + 0xa9, 0x55, 0xa7, 0xcf, 0xfa, 0x7e, 0x81, 0xf9, 0x16, 0x07, 0xac, 0xe6, 0x42, + 0xfa, 0xf0, 0x13, 0xa0, 0xbb, 0x30, 0x81, 0xf9, 0x81, 0xe7, 0xfc, 0xe6, 0xc0, + 0xc1, 0x2c, 0x78, 0xdf, 0xca, 0x0b, 0x97, 0x0f, 0x1e, 0xe8, 0x0e, 0xc8, 0xf6, + 0xf6, 0x14, 0x99, 0x09, 0xd9, 0x19, 0xd9, 0x81, 0xce, 0x24, 0x16, 0xf6, 0x42, + 0x40, 0xd6, 0xd9, 0xe4, 0x2b, 0x06, 0x9b, 0xea, 0xf5, 0x19, 0x0d, 0xfd, 0x68, + 0xc6, 0xef, 0xed, 0xee, 0xf7, 0x08, 0xe4, 0x09, 0x3b, 0x11, 0xaa, 0xe4, 0x08, + 0xff, 0x08, 0xb8, 0xde, 0x58, 0xed, 0xe2, 0x06, 0x07, 0x15, 0x62, 0x08, 0x83, + 0xe5, 0x14, 0xc7, 0x26, 0x16, 0x12, 0xc4, 0xf2, 0xf8, 0xf5, 0x03, 0x17, 0xee, + 0x0c, 0x28, 0x01, 0x1e, 0x15, 0x17, 0xd5, 0xc6, 0xb6, 0x00, 0xcf, 0xae, 0xed, + 0xdb, 0xfc, 0xe2, 0x2d, 0xf9, 0xdb, 0xe3, 0x37, 0xe7, 0x10, 0x7a, 0x46, 0xfd, + 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x81, 0x1c, 0x00, 0x00, + 0x0e, 0xfe, 0xff, 0xff, 0x07, 0x01, 0x00, 0x00, 0x49, 0xf8, 0xff, 0xff, 0xd4, + 0x08, 0x00, 0x00, 0x93, 0x25, 0x00, 0x00, 0x1f, 0xe7, 0xff, 0xff, 0xa9, 0x1c, + 0x00, 0x00, 0xc2, 0x3a, 0x00, 0x00, 0xe4, 0x1b, 0x00, 0x00, 0x9f, 0x06, 0x00, + 0x00, 0x37, 0xf8, 0xff, 0xff, 0x90, 0x5b, 0x00, 0x00, 0x57, 0x08, 0x00, 0x00, + 0x72, 0xfb, 0xff, 0xff, 0xc9, 0x7e, 0x00, 0x00, 0x19, 0x07, 0x00, 0x00, 0x67, + 0xff, 0xff, 0xff, 0x74, 0xff, 0xff, 0xff, 0x37, 0xff, 0xff, 0xff, 0x96, 0x30, + 0x00, 0x00, 0xb3, 0xfc, 0xff, 0xff, 0x52, 0x5d, 0x00, 0x00, 0x32, 0x03, 0x00, + 0x00, 0xdb, 0x04, 0x00, 0x00, 0x3f, 0x05, 0x00, 0x00, 0xa4, 0xfe, 0xff, 0xff, + 0xc1, 0x36, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x24, 0x1b, 0x00, 0x00, 0x83, + 0x32, 0x00, 0x00, 0x09, 0xfa, 0xff, 0xff, 0x06, 0x47, 0xfd, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x13, 0xe9, 0xd2, 0x14, 0x97, 0x41, 0xa4, + 0xeb, 0x07, 0x1d, 0x32, 0xfb, 0xf7, 0x0a, 0xe6, 0xfe, 0xbd, 0x6c, 0x2d, 0x1c, + 0xd1, 0x3a, 0x16, 0x2d, 0x1e, 0xf8, 0x7f, 0x13, 0x1b, 0xc3, 0x50, 0x2b, 0xf9, + 0x17, 0xfd, 0xe6, 0x16, 0xea, 0xe0, 0x98, 0xcd, 0x32, 0xeb, 0x3c, 0x10, 0xf8, + 0x1b, 0xef, 0xf1, 0x10, 0x35, 0x00, 0x0b, 0x13, 0x03, 0xb3, 0xdf, 0x05, 0x7f, + 0xdd, 0xae, 0x3d, 0x3b, 0xf7, 0x62, 0xbe, 0xf2, 0xba, 0x28, 0x10, 0xfb, 0x98, + 0xa5, 0x21, 0x31, 0x27, 0xec, 0xfd, 0xe4, 0x1c, 0x09, 0xe2, 0x44, 0x0d, 0x28, + 0x28, 0xf9, 0xd5, 0x43, 0xe8, 0xcc, 0x27, 0xbe, 0x81, 0xa7, 0xd8, 0x1d, 0xe1, + 0x00, 0xe9, 0x33, 0x5a, 0x59, 0xf8, 0x81, 0xa4, 0x12, 0x00, 0xa1, 0x01, 0x26, + 0x29, 0x37, 0x27, 0xe7, 0xfd, 0x12, 0xcc, 0xe1, 0xd7, 0x01, 0x5f, 0x1b, 0xf5, + 0x5c, 0x1c, 0xc2, 0xb4, 0xe3, 0xed, 0xee, 0x03, 0xdc, 0xbb, 0xdc, 0x71, 0xb4, + 0xb9, 0xf2, 0xf3, 0xba, 0xc9, 0x18, 0x25, 0xd3, 0xe0, 0x89, 0xdd, 0x30, 0xc3, + 0x7f, 0xfb, 0x3e, 0x58, 0xca, 0x55, 0xa7, 0xec, 0xcc, 0xf0, 0xfb, 0x01, 0xf4, + 0xb8, 0xe8, 0x09, 0x04, 0x39, 0x02, 0x81, 0xcc, 0xbe, 0xc9, 0x06, 0xd1, 0x11, + 0xbe, 0xde, 0xe4, 0xf7, 0x2f, 0xf2, 0x38, 0x04, 0xd2, 0x52, 0xf2, 0x07, 0x24, + 0xd5, 0xbf, 0x06, 0x14, 0xf7, 0x49, 0x08, 0xd8, 0xc9, 0xae, 0x1b, 0x6e, 0x40, + 0xca, 0x7f, 0x51, 0x1f, 0xf0, 0xf8, 0x2b, 0x2b, 0xff, 0xf9, 0x0a, 0xe4, 0x1e, + 0x14, 0xc6, 0xf9, 0x27, 0x42, 0x0e, 0x38, 0x14, 0x01, 0xde, 0xea, 0x3b, 0x35, + 0x60, 0xf5, 0x2d, 0xea, 0xab, 0x4e, 0x33, 0x73, 0x58, 0x6f, 0x02, 0x20, 0x7d, + 0x30, 0x1e, 0x0d, 0xd6, 0x1a, 0xe9, 0x60, 0xb7, 0x0f, 0x11, 0x8e, 0x26, 0x29, + 0x1f, 0x7f, 0x16, 0xe3, 0x23, 0x75, 0x11, 0x81, 0xf0, 0xc4, 0xef, 0x13, 0x0b, + 0x43, 0xaf, 0x20, 0x1a, 0x01, 0x49, 0xa6, 0xff, 0x0f, 0x24, 0xfe, 0x05, 0x2f, + 0x4b, 0xbb, 0xce, 0x4a, 0x12, 0x50, 0x22, 0xf4, 0xc5, 0x08, 0x0c, 0x1f, 0x2a, + 0x58, 0xfa, 0xf7, 0x30, 0x30, 0xde, 0x4a, 0xa8, 0xf3, 0x21, 0x59, 0x19, 0x1e, + 0xdb, 0x0c, 0x17, 0x03, 0xb5, 0x91, 0xdc, 0xed, 0x09, 0xbe, 0x81, 0xfb, 0xe6, + 0xcc, 0x2b, 0x76, 0x55, 0xca, 0xf0, 0xe6, 0xef, 0xee, 0x19, 0xc7, 0xba, 0xb4, + 0x28, 0x20, 0xd1, 0x7f, 0x0a, 0xf4, 0x10, 0xf9, 0xe4, 0x01, 0xfe, 0xdb, 0x1e, + 0x36, 0x28, 0xd4, 0x21, 0xef, 0xdc, 0x00, 0xe7, 0x3e, 0x52, 0x12, 0xa5, 0x29, + 0x09, 0xad, 0x87, 0x81, 0x10, 0x9f, 0x49, 0xca, 0x1c, 0xb0, 0xe4, 0x23, 0xbe, + 0xde, 0x28, 0x0e, 0x22, 0xcf, 0xe9, 0xaf, 0x10, 0xf7, 0xdf, 0x10, 0x0a, 0xf6, + 0x04, 0xe5, 0xfd, 0x00, 0xe5, 0xfe, 0x81, 0x09, 0xc6, 0x1f, 0x10, 0x15, 0xcf, + 0xe7, 0x05, 0xc2, 0xd2, 0x09, 0x04, 0x15, 0xf6, 0x37, 0x65, 0x18, 0xd5, 0x06, + 0x4a, 0xcf, 0x1d, 0xfe, 0x0b, 0xe0, 0xed, 0x02, 0x15, 0x09, 0x03, 0xd4, 0xd7, + 0xec, 0x53, 0xe0, 0x03, 0x21, 0x7f, 0xfa, 0xf9, 0xf8, 0xed, 0x1a, 0x11, 0xf6, + 0xeb, 0xfe, 0x46, 0x2a, 0x3a, 0xd3, 0x5b, 0x1b, 0x0d, 0x08, 0x3d, 0x14, 0x3a, + 0xdf, 0x14, 0x16, 0xea, 0x25, 0xf7, 0x14, 0xfa, 0x3a, 0xe7, 0x05, 0x0f, 0x0b, + 0xe1, 0xeb, 0x13, 0x1a, 0xf4, 0xe1, 0x0d, 0xe9, 0x0f, 0xde, 0x7f, 0xfd, 0xfc, + 0xe9, 0x0d, 0x0d, 0x03, 0xf9, 0xc0, 0x28, 0xdd, 0x07, 0x04, 0xe5, 0xf9, 0x0c, + 0xe8, 0x87, 0x07, 0x06, 0xe7, 0xb2, 0x10, 0x1c, 0x81, 0xf1, 0x12, 0xf9, 0x12, + 0xf6, 0x11, 0x70, 0x24, 0x2e, 0x55, 0xda, 0xe4, 0xe8, 0x9e, 0x00, 0xf1, 0x60, + 0x0f, 0x03, 0xb9, 0xa3, 0x2f, 0x29, 0x34, 0xe5, 0xf8, 0x0f, 0x22, 0xec, 0x31, + 0xec, 0xea, 0xf1, 0xf5, 0xfd, 0x05, 0x18, 0x65, 0xda, 0x2e, 0x14, 0x3d, 0xcc, + 0x4e, 0x1f, 0x1f, 0x7f, 0xba, 0xc6, 0xfb, 0x22, 0x23, 0x61, 0x48, 0x32, 0x73, + 0x81, 0xf5, 0xfc, 0x50, 0xdd, 0xd7, 0x05, 0xe4, 0x0a, 0xa0, 0xf5, 0xe7, 0xce, + 0x3b, 0xce, 0xaa, 0xc1, 0xda, 0xd1, 0x2d, 0x08, 0xcb, 0xea, 0xfd, 0x07, 0xfd, + 0x02, 0x06, 0xf4, 0xed, 0xfb, 0xcc, 0x7f, 0xf1, 0x29, 0x01, 0x2a, 0xd5, 0x2b, + 0x4b, 0x01, 0x2f, 0x01, 0xde, 0x12, 0xf7, 0xe6, 0x13, 0xea, 0x06, 0x1c, 0xe8, + 0x05, 0x0a, 0x13, 0xf7, 0xfa, 0x07, 0x0a, 0xf0, 0xf8, 0xcf, 0x0c, 0x57, 0x3d, + 0x29, 0x2c, 0x06, 0x13, 0x7f, 0xbd, 0xe2, 0xf8, 0x09, 0x19, 0xf6, 0x13, 0x44, + 0x24, 0xf5, 0xed, 0xc4, 0x3c, 0xa0, 0xff, 0x22, 0x50, 0x04, 0xf7, 0xf5, 0xf0, + 0x03, 0x07, 0xc1, 0x04, 0x12, 0x07, 0x17, 0x08, 0x09, 0xff, 0xf3, 0xfd, 0xeb, + 0xff, 0xf4, 0xf9, 0xd8, 0x7f, 0xdb, 0xed, 0xec, 0x3d, 0x32, 0xf9, 0xea, 0x0b, + 0xe4, 0xfa, 0x28, 0xb0, 0xb8, 0xeb, 0x08, 0x3d, 0xda, 0x41, 0x34, 0xcf, 0x27, + 0xf3, 0x21, 0x03, 0xba, 0x17, 0xe2, 0xc6, 0xa2, 0xe1, 0x4d, 0xdd, 0xd6, 0x81, + 0x17, 0xfd, 0xf5, 0xf0, 0x19, 0xe9, 0x58, 0xd3, 0x30, 0xfa, 0x31, 0xe1, 0xfe, + 0x35, 0x6e, 0xfd, 0x6d, 0x04, 0x9e, 0xec, 0x58, 0x2f, 0xa4, 0x1d, 0x81, 0x01, + 0x0b, 0xf1, 0x01, 0xfb, 0xff, 0x25, 0xed, 0xc6, 0xe4, 0x5c, 0xde, 0xfb, 0xd1, + 0x40, 0xea, 0x7f, 0x2a, 0xe3, 0x05, 0xd8, 0xf4, 0x07, 0xf9, 0x33, 0x60, 0xdf, + 0x16, 0x02, 0x05, 0xf0, 0xe8, 0xe0, 0x41, 0x14, 0x01, 0x06, 0xda, 0x08, 0x0c, + 0x01, 0x21, 0xef, 0xdd, 0x00, 0x20, 0xf4, 0x0a, 0xed, 0xde, 0x20, 0xf2, 0xdf, + 0xe7, 0x0b, 0xfd, 0x06, 0xf9, 0x04, 0xe5, 0xfa, 0xf6, 0x1d, 0x0b, 0xfc, 0x22, + 0x7f, 0x07, 0x71, 0x02, 0x03, 0x18, 0x02, 0xd6, 0x06, 0xe4, 0x02, 0x02, 0xfe, + 0x1f, 0xd1, 0xf9, 0x0f, 0xfe, 0xf2, 0xf2, 0x0a, 0xe0, 0xf9, 0x11, 0xfa, 0x34, + 0xf5, 0xe4, 0xbd, 0xf8, 0x0c, 0x7f, 0xeb, 0xe0, 0x2f, 0xc5, 0x14, 0xd2, 0xf9, + 0x11, 0x09, 0xd8, 0x14, 0x34, 0xf2, 0xf3, 0xfe, 0xe8, 0xff, 0xea, 0xf2, 0x3b, + 0x18, 0x0b, 0xdd, 0x0d, 0xfe, 0xd0, 0x03, 0x1c, 0xe3, 0x7f, 0x18, 0xcc, 0xd5, + 0x23, 0x25, 0x20, 0xb8, 0x0a, 0x36, 0xef, 0x2e, 0x2c, 0x03, 0xf8, 0x03, 0xff, + 0xf4, 0xd6, 0xf2, 0x1b, 0x7f, 0x39, 0x1f, 0xe1, 0x1a, 0x03, 0x17, 0x02, 0xd5, + 0xe2, 0xff, 0xdb, 0xbf, 0x1b, 0xff, 0x09, 0xdc, 0xf5, 0x65, 0xf4, 0x12, 0x02, + 0xe0, 0x3a, 0x0c, 0xee, 0xd2, 0xfe, 0xf7, 0x12, 0x1b, 0x01, 0xb8, 0xe0, 0xee, + 0xc6, 0x1c, 0x07, 0x06, 0x9d, 0xfd, 0xcc, 0x53, 0x1c, 0xff, 0x1a, 0xe4, 0x1c, + 0xf2, 0xf1, 0x48, 0x21, 0x1c, 0x7f, 0x20, 0xf0, 0xe2, 0x9c, 0x0b, 0x22, 0xda, + 0x13, 0x41, 0x3d, 0x1b, 0xfc, 0xf5, 0xf2, 0x19, 0x09, 0x7f, 0x15, 0x5a, 0xfc, + 0x20, 0x3b, 0x63, 0x1a, 0xf6, 0xe2, 0x00, 0xe8, 0xed, 0xd0, 0xf4, 0xbb, 0x03, + 0x41, 0x2c, 0x32, 0x39, 0xf8, 0x62, 0xf7, 0xfb, 0xda, 0x16, 0x21, 0xfe, 0x35, + 0x2b, 0x41, 0x13, 0xd1, 0x0f, 0x78, 0x50, 0xfe, 0x04, 0x2f, 0x1e, 0xe1, 0x09, + 0x31, 0x0d, 0xf2, 0xf5, 0x0b, 0xee, 0x08, 0xe8, 0xf8, 0x7f, 0x95, 0xb5, 0x00, + 0x29, 0x04, 0x12, 0x01, 0x20, 0x42, 0x81, 0x19, 0x09, 0xeb, 0xe6, 0xe6, 0xe1, + 0x1a, 0xca, 0xf8, 0x01, 0xf5, 0xc9, 0xec, 0xa8, 0xe7, 0xba, 0xd2, 0x27, 0x00, + 0x3f, 0x22, 0xba, 0x12, 0x4b, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x20, 0x01, + 0x00, 0x00, 0xb2, 0x3b, 0xbe, 0xc6, 0x7f, 0xe4, 0x20, 0x29, 0xa7, 0x18, 0xe5, + 0xfe, 0x3c, 0xcf, 0x64, 0x43, 0x27, 0xa0, 0xd5, 0x52, 0xbb, 0x59, 0xc8, 0x39, + 0xcc, 0x50, 0x68, 0x54, 0xaa, 0x81, 0x05, 0x15, 0xab, 0x52, 0x9e, 0x96, 0x1f, + 0xae, 0x36, 0x31, 0x81, 0xd7, 0xa7, 0xe6, 0x64, 0x81, 0x7f, 0x5a, 0x5c, 0x93, + 0xaa, 0x64, 0xb4, 0x7f, 0xb9, 0x5b, 0xac, 0x67, 0x7f, 0x52, 0x88, 0x96, 0xb5, + 0x41, 0xf3, 0x33, 0xe1, 0xbf, 0xb8, 0xc5, 0x19, 0x0e, 0xb8, 0xcc, 0xcf, 0xe2, + 0x47, 0xaf, 0x27, 0x28, 0x33, 0xc4, 0xc8, 0x2a, 0xf0, 0x36, 0xf7, 0x2b, 0xd4, + 0x35, 0x21, 0x07, 0xd1, 0xe5, 0xb1, 0x2c, 0xca, 0x70, 0xbc, 0xa3, 0x6a, 0xb9, + 0x50, 0x53, 0xaf, 0xc1, 0xad, 0xb4, 0x65, 0x23, 0x60, 0x63, 0x3d, 0x8e, 0x9e, + 0x66, 0xba, 0x58, 0xa4, 0x46, 0xa6, 0x5f, 0x73, 0x71, 0xaf, 0xcd, 0xaf, 0x43, + 0x81, 0x7f, 0x81, 0x81, 0xfe, 0x81, 0x7f, 0x7f, 0xa7, 0x81, 0x81, 0x81, 0x7f, + 0x2c, 0x7c, 0x7f, 0x7f, 0x81, 0x81, 0x7f, 0x81, 0x66, 0x81, 0x7f, 0x81, 0x7f, + 0x7d, 0x7f, 0x81, 0xa4, 0x81, 0x7f, 0xb5, 0x37, 0xba, 0xb4, 0xad, 0xb3, 0x47, + 0x4a, 0xe3, 0xb2, 0xc5, 0xaf, 0x3c, 0xfe, 0x2f, 0x2a, 0x36, 0xc8, 0xcf, 0x3a, + 0xc6, 0x0f, 0xc2, 0x41, 0xca, 0x3d, 0x1f, 0x21, 0xcc, 0xc2, 0xc1, 0x44, 0x04, + 0x45, 0xdc, 0xd5, 0x23, 0xc8, 0x38, 0x49, 0xfd, 0xc0, 0xd2, 0xa9, 0x47, 0x2e, + 0x11, 0x28, 0x23, 0xd1, 0xc6, 0x23, 0xef, 0xf9, 0xc9, 0x18, 0xd6, 0x2d, 0x1f, + 0x2f, 0xdf, 0xf8, 0xa8, 0x2e, 0xab, 0x3b, 0xbb, 0xc5, 0xdf, 0xbf, 0x59, 0x63, + 0xfc, 0xaa, 0xc6, 0x84, 0x46, 0x59, 0x10, 0x36, 0x39, 0xd8, 0xc2, 0x32, 0xcd, + 0xcc, 0xb2, 0x32, 0xcc, 0x31, 0x1b, 0x46, 0xd6, 0xd7, 0xcb, 0x46, 0xa7, 0x09, + 0xc8, 0xe3, 0xd8, 0xe8, 0x3b, 0x23, 0x0d, 0xd3, 0xe3, 0xd3, 0xfe, 0x30, 0x0b, + 0x13, 0x16, 0x03, 0x02, 0x13, 0xdd, 0xd5, 0xd6, 0x19, 0xf0, 0x0b, 0x04, 0x2d, + 0xed, 0xd0, 0x08, 0x1f, 0x3e, 0x4c, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xac, 0x6f, 0x00, 0x00, 0x6b, 0x01, 0x00, 0x00, 0xc8, 0x6b, + 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x08, 0xef, 0xff, 0xff, 0xb3, 0x6a, 0x00, + 0x00, 0x5d, 0x04, 0x00, 0x00, 0xef, 0xfb, 0xff, 0xff, 0x67, 0x65, 0x00, 0x00, + 0x6a, 0xa4, 0x00, 0x00, 0xb1, 0x56, 0x00, 0x00, 0x6b, 0x6f, 0x00, 0x00, 0xde, + 0xf9, 0xff, 0xff, 0xa9, 0xff, 0xff, 0xff, 0xb7, 0xe7, 0xff, 0xff, 0xe4, 0xff, + 0xff, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x87, 0x91, 0x00, 0x00, 0x8e, 0x43, 0x00, + 0x00, 0x32, 0xff, 0xff, 0xff, 0xd6, 0x42, 0x00, 0x00, 0xe5, 0xfd, 0xff, 0xff, + 0xf1, 0xa7, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0xcf, 0x2b, 0x00, 0x00, 0x24, + 0xff, 0xff, 0xff, 0x0e, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x74, + 0x00, 0x00, 0x5c, 0x6c, 0x00, 0x00, 0xd0, 0x3f, 0x00, 0x00, 0xdb, 0x03, 0x00, + 0x00, 0xca, 0x4c, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0xf7, 0xee, 0xf3, 0x35, 0xfa, 0xb2, 0xf7, 0x5f, 0x50, 0xfe, 0xd6, 0xfc, 0x11, + 0x20, 0xd5, 0x97, 0x20, 0x00, 0xe1, 0xf7, 0xb7, 0x33, 0xec, 0xf1, 0xd1, 0x13, + 0xfb, 0x4f, 0x7f, 0xa5, 0xfa, 0x8e, 0xe5, 0xe7, 0xfa, 0x34, 0x03, 0xf4, 0xee, + 0x21, 0x01, 0x95, 0x0f, 0x8b, 0x07, 0x03, 0xa3, 0xc8, 0xf1, 0xd3, 0x0e, 0xd7, + 0x1a, 0xeb, 0xe4, 0x0d, 0x28, 0xf5, 0xa1, 0x7f, 0x36, 0xfb, 0x10, 0x1d, 0x0e, + 0x7f, 0x0b, 0xf1, 0x39, 0x04, 0x1e, 0xdb, 0xb1, 0xf6, 0xd4, 0x13, 0xf3, 0x35, + 0xef, 0x0d, 0x2a, 0xb5, 0x0e, 0xc8, 0xf0, 0xdf, 0x25, 0x6e, 0xe2, 0xf7, 0x10, + 0x3c, 0xcf, 0x07, 0x0f, 0xe6, 0x45, 0xdd, 0x17, 0xef, 0x33, 0xcf, 0xe1, 0x34, + 0x08, 0x34, 0xf6, 0x0e, 0xfa, 0xfb, 0xfc, 0x7f, 0xf7, 0xe5, 0x1a, 0xea, 0x11, + 0x1b, 0xfb, 0x95, 0x17, 0xfe, 0xc7, 0xb3, 0xde, 0x22, 0xe7, 0xea, 0xdc, 0x53, + 0x2a, 0x12, 0xdb, 0x6c, 0x16, 0xbc, 0x01, 0x46, 0xef, 0xdc, 0x27, 0xf8, 0xbe, + 0x99, 0x43, 0xe8, 0x9a, 0xc0, 0x93, 0xc0, 0xfe, 0xf6, 0xc8, 0x7f, 0xfd, 0x07, + 0xd8, 0xe8, 0x20, 0x35, 0xe5, 0xd2, 0x71, 0xf5, 0xdf, 0xc7, 0xb0, 0x1d, 0x12, + 0xde, 0xef, 0x17, 0x01, 0x3a, 0x11, 0x6d, 0x04, 0x1b, 0x68, 0x7f, 0x1b, 0xce, + 0x1d, 0xef, 0xe8, 0xd5, 0xeb, 0x35, 0xda, 0x11, 0xb5, 0xfb, 0xf9, 0xe4, 0xe3, + 0x24, 0x17, 0x02, 0x20, 0xac, 0xf2, 0x48, 0x11, 0xe2, 0xfe, 0xbe, 0xd4, 0x81, + 0x67, 0xbd, 0x2d, 0xea, 0xe8, 0xec, 0xcf, 0xf7, 0xd9, 0x44, 0x95, 0xea, 0x01, + 0xd2, 0x08, 0xf5, 0x1a, 0xb5, 0x4d, 0xe1, 0x15, 0xe9, 0x01, 0xea, 0xaa, 0xda, + 0x1f, 0xd1, 0xf8, 0x11, 0xbd, 0x3b, 0x81, 0xdb, 0xf5, 0xfb, 0xe0, 0xf8, 0xe5, + 0x1e, 0xf7, 0xf7, 0x6d, 0x0d, 0xf3, 0xeb, 0x00, 0x7d, 0x2e, 0xf5, 0x20, 0xe6, + 0xcb, 0xf3, 0x09, 0x09, 0x13, 0x1f, 0xeb, 0xfb, 0xc0, 0x02, 0x27, 0x7f, 0xff, + 0x2b, 0x26, 0x27, 0xea, 0x30, 0x73, 0xbd, 0xfa, 0xc7, 0x16, 0xb0, 0x2c, 0xfd, + 0x20, 0xf0, 0xce, 0x1c, 0x16, 0xe7, 0xf2, 0xd9, 0x00, 0xf9, 0x19, 0xe4, 0xe5, + 0xf1, 0x11, 0x3b, 0xbd, 0xf0, 0x2e, 0x0c, 0x2c, 0xe3, 0xd5, 0x01, 0xf3, 0xfc, + 0xef, 0x7f, 0x08, 0x10, 0xf3, 0xff, 0xff, 0xf9, 0x20, 0xff, 0x09, 0x81, 0x51, + 0x0d, 0xc6, 0x32, 0xf5, 0x07, 0x12, 0xc4, 0xe4, 0xf4, 0x24, 0x22, 0x06, 0x1d, + 0xe8, 0x0b, 0xf3, 0xf5, 0x61, 0x00, 0x1b, 0x4f, 0x13, 0xd9, 0x0f, 0x16, 0x03, + 0x4f, 0xc6, 0x35, 0x5b, 0x38, 0xd7, 0x0d, 0xf9, 0xce, 0xd0, 0xad, 0x1b, 0xfb, + 0xf8, 0xd4, 0x0f, 0xf6, 0xfb, 0x13, 0x23, 0x3a, 0x52, 0x6a, 0x09, 0x81, 0xfe, + 0x36, 0x0d, 0xf8, 0x29, 0xc6, 0xec, 0xf8, 0xf6, 0x54, 0x31, 0x02, 0x09, 0x5d, + 0x7f, 0x1d, 0xed, 0xed, 0xcf, 0xe5, 0xb1, 0xe4, 0x40, 0x17, 0x90, 0xab, 0xa0, + 0xc9, 0x13, 0xd2, 0x3b, 0x13, 0x0a, 0x18, 0x55, 0xfc, 0x6b, 0x95, 0x2a, 0xfb, + 0xa0, 0x16, 0x0b, 0xa7, 0x01, 0x09, 0x1e, 0x0f, 0x22, 0x61, 0x24, 0x51, 0xdc, + 0x27, 0x38, 0xdc, 0xd8, 0xdf, 0xce, 0x56, 0xe3, 0xf1, 0x7f, 0x66, 0xbb, 0x31, + 0xf8, 0xba, 0xe9, 0x02, 0xbb, 0x45, 0x0c, 0x23, 0x32, 0xef, 0x0e, 0x1a, 0xd6, + 0x00, 0xf0, 0xd7, 0xb9, 0xe0, 0xd7, 0x07, 0xd6, 0xf9, 0x25, 0xee, 0xe8, 0x43, + 0x35, 0xe0, 0x7f, 0x4f, 0xde, 0xf0, 0xe3, 0xda, 0x32, 0xfe, 0xa4, 0x23, 0x0c, + 0xf7, 0xd2, 0x04, 0xf4, 0x0d, 0xe3, 0x10, 0xef, 0xd9, 0xe9, 0xc3, 0xf8, 0xe2, + 0xf5, 0xd1, 0xf9, 0xe7, 0x00, 0xdb, 0x09, 0xbd, 0x2d, 0x16, 0x0f, 0x05, 0xf4, + 0x7f, 0x04, 0xe4, 0x09, 0xf5, 0xf8, 0xda, 0x0f, 0xd9, 0xef, 0x10, 0x0c, 0x12, + 0xc4, 0xec, 0xa7, 0x16, 0xb6, 0x00, 0x3f, 0x6c, 0xf2, 0x11, 0xab, 0x81, 0x14, + 0xc3, 0x52, 0xa4, 0x09, 0x93, 0x36, 0x0b, 0xc8, 0xa9, 0xf4, 0xf0, 0xe3, 0xf4, + 0x00, 0x20, 0x11, 0xec, 0x71, 0x15, 0x0b, 0x28, 0x13, 0xfd, 0xc4, 0x11, 0x7f, + 0x0d, 0x14, 0xad, 0x98, 0xf5, 0xdc, 0x43, 0x0b, 0xb6, 0xf4, 0xe1, 0xe9, 0xb8, + 0xdf, 0x82, 0xb4, 0x17, 0xd9, 0xd6, 0x06, 0x28, 0xfa, 0x1d, 0x46, 0x98, 0x28, + 0x7f, 0x34, 0x47, 0x34, 0x06, 0x53, 0xfb, 0xeb, 0x25, 0x23, 0x51, 0xea, 0x16, + 0xc8, 0xf9, 0xfc, 0x14, 0xf5, 0x57, 0x1c, 0x46, 0x60, 0xda, 0x0f, 0x39, 0xc2, + 0x9a, 0xc3, 0xa9, 0x1d, 0xda, 0x68, 0xe6, 0xdc, 0xec, 0x08, 0xc6, 0x9a, 0x3d, + 0x07, 0x1c, 0xd7, 0xf0, 0xfc, 0x7f, 0x43, 0x54, 0x31, 0x09, 0x6e, 0x1d, 0xd3, + 0x5e, 0x22, 0xb7, 0xda, 0x46, 0x1a, 0x55, 0x14, 0xf4, 0x0a, 0x3f, 0xdf, 0xf6, + 0x24, 0xd7, 0x00, 0x01, 0x0a, 0x4a, 0xed, 0x81, 0x36, 0x27, 0x06, 0x5f, 0xf2, + 0x01, 0xf2, 0x0d, 0xac, 0xf0, 0xf2, 0x12, 0xe2, 0xeb, 0xcd, 0xb4, 0xdf, 0x36, + 0xc6, 0xd1, 0x47, 0xe2, 0xe3, 0xe7, 0xf6, 0x7f, 0x04, 0x0d, 0xef, 0x51, 0xe0, + 0x0c, 0xdf, 0x14, 0xf8, 0xad, 0xfc, 0x17, 0xf8, 0xbd, 0xe1, 0x49, 0xf1, 0x2a, + 0x07, 0xe4, 0xf7, 0xf3, 0x05, 0x07, 0xe7, 0x4c, 0x55, 0xef, 0x10, 0x21, 0x05, + 0x1f, 0xdf, 0xfa, 0x72, 0xf8, 0xd8, 0x33, 0xf3, 0xc4, 0x08, 0x19, 0x59, 0xe3, + 0xfb, 0x14, 0x33, 0xff, 0x7f, 0xe5, 0x1a, 0x08, 0xd3, 0xca, 0x3b, 0xdd, 0x0f, + 0x22, 0xd1, 0x28, 0x0f, 0x06, 0xf3, 0xd6, 0x14, 0x12, 0x3b, 0x24, 0x7f, 0xab, + 0xd6, 0xf2, 0xef, 0xd2, 0xb9, 0x41, 0x16, 0xfc, 0xd8, 0xfe, 0xfa, 0xe0, 0x11, + 0x30, 0x4c, 0x34, 0xff, 0xf8, 0x1d, 0x47, 0x7f, 0xe0, 0xee, 0xd6, 0x20, 0xe0, + 0xbb, 0xee, 0x3c, 0x15, 0xd8, 0xcd, 0x04, 0x17, 0x1b, 0xbd, 0x4c, 0x39, 0x47, + 0x50, 0xcb, 0xe2, 0xfa, 0xd0, 0x28, 0xf3, 0xb9, 0xcb, 0xd4, 0x1c, 0xe8, 0x7e, + 0x60, 0xcb, 0xc7, 0xd3, 0xdf, 0x3c, 0x06, 0xff, 0xaf, 0xcc, 0x02, 0x4a, 0xe4, + 0x1e, 0xd9, 0xe2, 0x81, 0x2e, 0xdf, 0x24, 0xeb, 0x50, 0xd3, 0x00, 0xb3, 0xd1, + 0xc5, 0x20, 0xda, 0x18, 0x13, 0x37, 0x7f, 0x1e, 0x12, 0x12, 0x14, 0xdf, 0x03, + 0xed, 0x31, 0xc1, 0xd4, 0x29, 0xc1, 0xdf, 0xeb, 0xd1, 0xea, 0x1b, 0x1a, 0x01, + 0xf4, 0x08, 0x03, 0xed, 0xf7, 0x23, 0xea, 0x16, 0xf8, 0xf8, 0xfb, 0x08, 0xc9, + 0xc7, 0xf8, 0x12, 0x25, 0x0b, 0x0f, 0xf5, 0x7f, 0x19, 0x1f, 0xd8, 0xaf, 0x19, + 0x06, 0x12, 0xff, 0x21, 0xe3, 0xfd, 0xee, 0xf8, 0xed, 0x00, 0xea, 0x30, 0x11, + 0xfb, 0x41, 0x41, 0x04, 0xf5, 0xad, 0xe3, 0xe4, 0x11, 0x33, 0x05, 0xd5, 0xfe, + 0x5a, 0x59, 0x1a, 0x0a, 0xdd, 0x72, 0x20, 0xbc, 0x07, 0xe3, 0xf5, 0xf6, 0xd7, + 0x2e, 0x7f, 0x0c, 0xba, 0xe6, 0xb0, 0x15, 0x32, 0x12, 0x8e, 0xee, 0xc4, 0x16, + 0x29, 0xf5, 0xc7, 0x3a, 0xd3, 0x7f, 0xfd, 0xea, 0x74, 0xbd, 0xbf, 0xe8, 0xcf, + 0x00, 0x1c, 0xff, 0xf9, 0xde, 0x7d, 0xfe, 0xfe, 0xfa, 0xdd, 0xee, 0xd4, 0xa6, + 0x24, 0xc6, 0xe9, 0x99, 0x81, 0xfa, 0x4d, 0xa9, 0x4e, 0x4f, 0xd7, 0x30, 0xe8, + 0xe4, 0x19, 0x00, 0x0f, 0x2a, 0x1e, 0x08, 0xa3, 0x05, 0xb9, 0x10, 0x59, 0x54, + 0xf2, 0xdc, 0xaf, 0xe0, 0x17, 0x7f, 0xba, 0xfd, 0x13, 0xe6, 0x2e, 0xdd, 0xce, + 0x13, 0xed, 0xd4, 0xef, 0x1a, 0xe8, 0xf4, 0x17, 0x3a, 0x01, 0x4c, 0xe8, 0xf7, + 0x77, 0xc0, 0x15, 0xbb, 0x04, 0x51, 0x06, 0xe6, 0xf1, 0xee, 0xfa, 0x18, 0x3e, + 0x24, 0xd3, 0x07, 0xcd, 0xd0, 0xf1, 0xf3, 0x21, 0xd9, 0x0f, 0xdf, 0x9e, 0x16, + 0xea, 0xde, 0x31, 0x32, 0xed, 0xf4, 0x03, 0x1a, 0xd2, 0x7f, 0xdc, 0x0b, 0xee, + 0x1c, 0x0c, 0x0d, 0x22, 0xdd, 0xbc, 0x96, 0x46, 0xde, 0xc5, 0x4c, 0x22, 0xbc, + 0x0e, 0x57, 0x1c, 0x23, 0x74, 0xf8, 0x81, 0x87, 0x22, 0x2a, 0x28, 0x31, 0xc8, + 0xdb, 0x12, 0x47, 0x13, 0xf1, 0x35, 0x37, 0xb7, 0xd6, 0xb7, 0x15, 0x01, 0xf2, + 0x0d, 0x60, 0xdf, 0x04, 0x06, 0x27, 0x77, 0x04, 0x5f, 0xf5, 0xcd, 0xea, 0xf3, + 0xb1, 0x56, 0xae, 0x81, 0xef, 0xeb, 0x12, 0x1a, 0x74, 0x4a, 0x25, 0x14, 0x8e, + 0x46, 0x22, 0x13, 0xfc, 0x23, 0xee, 0xf1, 0x0c, 0xd2, 0xf0, 0xfb, 0xf3, 0xeb, + 0xf4, 0x09, 0xdf, 0xcc, 0xdf, 0xf9, 0x2e, 0x03, 0x7f, 0x21, 0xf0, 0x1f, 0xfc, + 0x9a, 0x2f, 0xd9, 0x03, 0xfa, 0x0a, 0xbf, 0x56, 0x1b, 0x0e, 0xfd, 0xda, 0xf8, + 0x19, 0xb6, 0x36, 0xdc, 0xa4, 0xda, 0xe2, 0xf1, 0x33, 0xe8, 0xa1, 0x29, 0xe9, + 0xf8, 0xcd, 0x1e, 0x6a, 0x7f, 0x0a, 0xfe, 0xee, 0x35, 0xed, 0x51, 0x0a, 0xec, + 0xf2, 0xed, 0xfc, 0xf9, 0xe4, 0xff, 0x19, 0x1f, 0x12, 0xb0, 0x24, 0xfb, 0xe6, + 0xe4, 0x03, 0x24, 0xbc, 0x01, 0xf3, 0xdd, 0xea, 0x03, 0xd5, 0x1a, 0x0c, 0x10, + 0xd4, 0x4c, 0x02, 0x7f, 0xc3, 0x05, 0x21, 0xdd, 0x00, 0x1d, 0xc9, 0x01, 0x02, + 0x14, 0xfa, 0x21, 0x4c, 0xeb, 0xa4, 0xe0, 0x20, 0x81, 0x12, 0x45, 0x8f, 0x11, + 0xc2, 0xf0, 0xe9, 0x23, 0xb2, 0x01, 0x12, 0x45, 0xf6, 0x09, 0x82, 0x2b, 0xec, + 0x2e, 0x27, 0x8d, 0x2f, 0x93, 0xb8, 0x3c, 0xa5, 0x45, 0x41, 0xdc, 0x5f, 0x1a, + 0x1f, 0xd3, 0x7f, 0x66, 0xdd, 0xfe, 0xfa, 0x37, 0x3e, 0xdb, 0x04, 0xd7, 0xfa, + 0xdf, 0xc2, 0x99, 0x17, 0x0a, 0xba, 0x55, 0xdd, 0xe2, 0x6e, 0xc0, 0xce, 0xd5, + 0xbf, 0x13, 0xc3, 0xbb, 0x4f, 0xb3, 0xfb, 0xb8, 0xbc, 0x0b, 0x42, 0x2d, 0x53, + 0x23, 0x92, 0x0a, 0xc3, 0xe6, 0xb7, 0xaf, 0xf1, 0x25, 0x32, 0x0e, 0x81, 0x38, + 0xf1, 0x0c, 0xff, 0xd0, 0x46, 0x33, 0xc4, 0xf7, 0xb8, 0xb2, 0xfb, 0x0e, 0x0f, + 0xf2, 0xd7, 0x5e, 0xcc, 0x11, 0xc0, 0x1c, 0xeb, 0x09, 0x7f, 0xf8, 0xf6, 0xf3, + 0xff, 0x2c, 0x0d, 0xc7, 0xf3, 0x27, 0xd0, 0x11, 0x2e, 0x47, 0x4b, 0xba, 0xd7, + 0x05, 0xe5, 0xfd, 0x59, 0xe5, 0x1d, 0xdc, 0x19, 0xd0, 0x2d, 0xb9, 0xa4, 0xe1, + 0xc4, 0x97, 0x28, 0xee, 0x0f, 0xf1, 0x7f, 0xdb, 0x07, 0xf3, 0xdf, 0xc4, 0xcd, + 0x34, 0xfa, 0xce, 0xb3, 0xd8, 0x13, 0xe4, 0xad, 0xef, 0x7f, 0xe6, 0x1c, 0x44, + 0xea, 0xe2, 0x19, 0x71, 0x93, 0xd5, 0x5a, 0xe2, 0x82, 0xb5, 0xac, 0x8d, 0x09, + 0xef, 0xbf, 0xdd, 0xef, 0xfd, 0xd9, 0xe3, 0xcf, 0xfc, 0xe0, 0xf1, 0x42, 0xfa, + 0x4a, 0xe9, 0x0c, 0xf3, 0x14, 0x02, 0x7f, 0x07, 0xc0, 0xf6, 0x06, 0xdc, 0xd8, + 0x23, 0xef, 0xfb, 0x15, 0xd6, 0xe0, 0xd6, 0xf6, 0xdf, 0x24, 0xed, 0xe6, 0xd6, + 0x2a, 0x08, 0x2e, 0xed, 0xf9, 0x61, 0xbd, 0xf3, 0x03, 0x23, 0xf6, 0x0e, 0xb2, + 0xea, 0x81, 0xfb, 0xcc, 0xe1, 0xe8, 0x9c, 0xe4, 0xf5, 0xfc, 0xe3, 0xf7, 0x20, + 0xd8, 0xe2, 0x01, 0xa7, 0x2f, 0x8a, 0x15, 0xd4, 0x3f, 0x4c, 0x81, 0x8c, 0x97, + 0xd7, 0xdb, 0x3f, 0x52, 0x84, 0xee, 0xfa, 0xd4, 0x04, 0x14, 0x07, 0xca, 0xc7, + 0xec, 0xe9, 0xce, 0xd8, 0x3b, 0x04, 0xee, 0x92, 0xe9, 0x04, 0xd2, 0x40, 0x66, + 0xcd, 0xc8, 0xff, 0xe5, 0xf3, 0xad, 0xbf, 0x46, 0xc4, 0xf4, 0x47, 0xf6, 0x00, + 0x58, 0x7f, 0xd9, 0xe8, 0x25, 0xf2, 0x04, 0xe4, 0xc1, 0xc3, 0xff, 0x10, 0xe8, + 0x55, 0x07, 0x2b, 0xf6, 0x13, 0x3b, 0xf9, 0xe9, 0xfd, 0x21, 0xd4, 0x1d, 0xf8, + 0x04, 0xcd, 0xff, 0x7f, 0x1d, 0x14, 0x01, 0x14, 0x1f, 0x0c, 0x5d, 0x17, 0xa9, + 0x49, 0x08, 0xfa, 0x16, 0x03, 0x50, 0x19, 0x04, 0xdb, 0xde, 0x31, 0x2c, 0xe3, + 0xfd, 0x1c, 0x18, 0x00, 0xf2, 0x13, 0x2f, 0xf5, 0xef, 0xb4, 0xde, 0xdb, 0x81, + 0x14, 0xe9, 0xdf, 0xeb, 0xf2, 0xf7, 0xe4, 0xfe, 0xfc, 0xec, 0xf7, 0x04, 0xf5, + 0x27, 0xd2, 0x7f, 0x0d, 0x1c, 0x2e, 0x0d, 0xee, 0xda, 0xfc, 0xec, 0x12, 0xfc, + 0x22, 0xf2, 0xf1, 0xe1, 0xde, 0xdf, 0x0c, 0xe9, 0xce, 0xf5, 0xe6, 0xfe, 0xe8, + 0xc2, 0x0c, 0x15, 0xeb, 0x07, 0x09, 0xf5, 0xc2, 0x1d, 0x07, 0x21, 0x10, 0xee, + 0x29, 0xc1, 0x00, 0x62, 0xf3, 0xe5, 0xd1, 0x06, 0xf3, 0x13, 0x7f, 0x2a, 0x12, + 0x01, 0xe5, 0x00, 0xf0, 0xf5, 0x06, 0x09, 0xc3, 0xb9, 0xd5, 0x03, 0x0e, 0xf9, + 0x01, 0x39, 0x0d, 0x10, 0x05, 0x46, 0x7f, 0xc6, 0xee, 0x25, 0xe3, 0x4d, 0xeb, + 0xfd, 0xf4, 0x09, 0x28, 0xb0, 0xea, 0xb0, 0xdf, 0xd4, 0x03, 0x04, 0xed, 0xdf, + 0xe0, 0x01, 0x18, 0xdd, 0x08, 0xfa, 0x14, 0x08, 0xf4, 0xff, 0x1e, 0xc8, 0x7f, + 0x1c, 0xdc, 0x02, 0x1b, 0xbd, 0x46, 0xea, 0x10, 0x1a, 0x2d, 0x0b, 0x21, 0x08, + 0x1d, 0x10, 0xaf, 0xc3, 0x2c, 0xd8, 0xc2, 0x1d, 0x03, 0xcf, 0xe8, 0x17, 0x20, + 0x09, 0xe5, 0x26, 0x3d, 0x1a, 0xdc, 0xf4, 0xfd, 0xcc, 0xdc, 0xb1, 0xc9, 0x02, + 0xff, 0x12, 0xda, 0x36, 0xd2, 0xcc, 0x01, 0xfe, 0x20, 0x7f, 0x11, 0x21, 0x0a, + 0x6c, 0xef, 0x1b, 0xd9, 0x20, 0x19, 0x18, 0x05, 0x23, 0x0d, 0xbe, 0x3c, 0xf6, + 0xcc, 0xec, 0xc4, 0xd6, 0xd5, 0xd0, 0x81, 0xd2, 0xd4, 0x37, 0xca, 0x1d, 0xc3, + 0xd4, 0x0e, 0x23, 0xee, 0x4f, 0xd4, 0x09, 0xe1, 0x92, 0xfc, 0xf4, 0x0f, 0x18, + 0xfc, 0xf4, 0x07, 0x28, 0x3a, 0xfd, 0xee, 0xd9, 0xc8, 0x02, 0xb7, 0x05, 0x1a, + 0xd7, 0x2c, 0xb8, 0xd5, 0x52, 0x1c, 0xc7, 0x1a, 0xe0, 0x01, 0x81, 0xe1, 0xd9, + 0x3c, 0xdb, 0xde, 0x10, 0x2d, 0xd2, 0xed, 0x00, 0xfe, 0xf9, 0xec, 0xec, 0xf6, + 0xa6, 0x01, 0x1f, 0x11, 0x03, 0x81, 0xde, 0x4d, 0xe3, 0x18, 0x34, 0xe0, 0xe9, + 0x14, 0x0c, 0xfa, 0xdb, 0x0e, 0xe1, 0x0a, 0xf6, 0xe2, 0xb9, 0xb2, 0x45, 0x5b, + 0xa8, 0x98, 0x2a, 0x43, 0x81, 0x54, 0x84, 0xd9, 0x06, 0xdf, 0x05, 0xec, 0xc9, + 0xc6, 0xd8, 0xd0, 0x3f, 0x24, 0x5e, 0xeb, 0xf9, 0x01, 0x0c, 0xa4, 0xa1, 0x12, + 0xd3, 0xd6, 0x3f, 0x3b, 0x01, 0x03, 0xdd, 0xf6, 0xc7, 0xc0, 0xdf, 0x01, 0xf1, + 0xfe, 0xeb, 0x28, 0x1d, 0xf1, 0x07, 0x3c, 0xc6, 0x16, 0x5c, 0x7f, 0xe3, 0x1f, + 0x26, 0xf8, 0xd6, 0x33, 0xe7, 0x6f, 0xe7, 0x9a, 0xbb, 0xe8, 0xf6, 0x01, 0xcc, + 0xf8, 0x03, 0xcd, 0x1c, 0x16, 0xda, 0xe1, 0xed, 0x17, 0x27, 0xc3, 0x2b, 0x26, + 0xf8, 0x18, 0xf6, 0x02, 0xf5, 0xe6, 0xfa, 0x09, 0xf5, 0xeb, 0x26, 0x81, 0x27, + 0xf2, 0xe2, 0x00, 0x0f, 0xe6, 0xce, 0xef, 0xf0, 0xfb, 0x25, 0x18, 0xe0, 0xee, + 0xf1, 0x7f, 0x1e, 0x11, 0xd9, 0xd8, 0xfa, 0x15, 0xd3, 0x02, 0xee, 0xfc, 0xe8, + 0x2d, 0x06, 0x0f, 0x4f, 0x02, 0xe9, 0xf6, 0x04, 0x0d, 0xdd, 0xed, 0x05, 0xe3, + 0xe7, 0xca, 0x02, 0xfa, 0xe8, 0x22, 0x1b, 0x55, 0xf0, 0xc9, 0xe2, 0x0f, 0x0e, + 0xf1, 0xa2, 0xc1, 0xbd, 0xcf, 0x16, 0xc9, 0x7f, 0x24, 0xfc, 0xf1, 0xda, 0x18, + 0x10, 0x18, 0xfa, 0x11, 0x33, 0x03, 0xdc, 0xe6, 0xe1, 0x1b, 0xa2, 0xd5, 0x23, + 0xdb, 0xf6, 0xdf, 0xcf, 0x24, 0xff, 0xdf, 0x7f, 0x16, 0xd3, 0xf7, 0xf5, 0xd0, + 0xb0, 0x05, 0x0d, 0x0b, 0x15, 0xb2, 0xed, 0xd6, 0x54, 0xfd, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x2f, 0xe7, 0xff, 0xff, 0x82, 0x23, 0x00, + 0x00, 0xe2, 0xff, 0xff, 0xff, 0x05, 0xfc, 0xff, 0xff, 0x10, 0xfe, 0xff, 0xff, + 0xcb, 0x05, 0x00, 0x00, 0x3c, 0x2d, 0x00, 0x00, 0x97, 0x48, 0x00, 0x00, 0xb1, + 0xfb, 0xff, 0xff, 0x0d, 0xfc, 0xff, 0xff, 0xc7, 0xfe, 0xff, 0xff, 0x9c, 0xfa, + 0xff, 0xff, 0x73, 0xff, 0xff, 0xff, 0x5d, 0xf4, 0xff, 0xff, 0xe8, 0xfb, 0xff, + 0xff, 0xe8, 0xfc, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x68, 0x30, 0x00, 0x00, + 0x88, 0xfc, 0xff, 0xff, 0x88, 0x3f, 0x00, 0x00, 0x2f, 0x35, 0x00, 0x00, 0x29, + 0x2b, 0x00, 0x00, 0x37, 0xff, 0xff, 0xff, 0xf2, 0x27, 0x00, 0x00, 0xae, 0xf3, + 0xff, 0xff, 0x8c, 0xfd, 0xff, 0xff, 0xdf, 0x16, 0x00, 0x00, 0x5d, 0x42, 0x00, + 0x00, 0x87, 0xec, 0xff, 0xff, 0xb2, 0x29, 0x00, 0x00, 0x7d, 0x23, 0x00, 0x00, + 0x5e, 0xfb, 0xff, 0xff, 0x31, 0xfb, 0xff, 0xff, 0x11, 0x3d, 0x00, 0x00, 0x69, + 0x05, 0x00, 0x00, 0xd5, 0x41, 0x00, 0x00, 0x35, 0xff, 0xff, 0xff, 0xca, 0x0c, + 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x19, 0xe9, 0xff, + 0xff, 0xc0, 0xf7, 0xff, 0xff, 0x11, 0x07, 0x00, 0x00, 0x05, 0xfe, 0xff, 0xff, + 0x3c, 0x34, 0x00, 0x00, 0x48, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x58, + 0x4a, 0x00, 0x00, 0xe3, 0xf2, 0xff, 0xff, 0x61, 0xf7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0xf4, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xff, 0x66, 0xef, 0xff, + 0xff, 0x7b, 0x3c, 0x00, 0x00, 0xa2, 0x2e, 0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, + 0x59, 0x1f, 0x00, 0x00, 0x3f, 0x33, 0x00, 0x00, 0x3c, 0xfe, 0xff, 0xff, 0x1c, + 0x15, 0x00, 0x00, 0x14, 0x34, 0x00, 0x00, 0x09, 0x26, 0x00, 0x00, 0x64, 0x20, + 0x00, 0x00, 0xe2, 0x55, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0xf3, 0x32, 0x0b, 0x24, 0xff, 0x39, 0x14, 0xfe, 0x1c, 0x2f, 0xe1, 0x1e, + 0x0b, 0xd4, 0xb6, 0xcf, 0x31, 0xf6, 0x7f, 0xec, 0x48, 0xd7, 0x4a, 0xdd, 0x34, + 0x48, 0xe2, 0xcb, 0x26, 0x1f, 0x01, 0xbb, 0xe2, 0x1a, 0x1e, 0xd3, 0xfd, 0xc7, + 0xa4, 0xe3, 0x10, 0x12, 0xdf, 0x45, 0xf6, 0xe0, 0x29, 0xe0, 0x71, 0xa6, 0x03, + 0x18, 0xb5, 0x21, 0xac, 0xf5, 0x12, 0x1e, 0x0e, 0x00, 0xf1, 0x0b, 0x0d, 0x25, + 0x7f, 0xe0, 0x2d, 0x0b, 0xc3, 0xf7, 0xd3, 0x48, 0x06, 0x07, 0xda, 0x09, 0xf3, + 0xc9, 0xba, 0x10, 0xcf, 0x00, 0xfc, 0x1c, 0x13, 0x1e, 0x08, 0x47, 0xe2, 0xd3, + 0xee, 0x11, 0x3a, 0xbd, 0x10, 0x43, 0xd7, 0x5d, 0x11, 0x15, 0xe7, 0x0d, 0x17, + 0xf9, 0x17, 0x23, 0x18, 0xf1, 0x1e, 0xfd, 0xe2, 0xcc, 0xf6, 0xf6, 0x1c, 0x01, + 0x26, 0xec, 0xf0, 0xec, 0xeb, 0xe2, 0x56, 0xf5, 0x21, 0x00, 0xf6, 0xc5, 0xf3, + 0x03, 0xf2, 0x19, 0xf4, 0x01, 0x0f, 0x31, 0xdc, 0xf4, 0x01, 0xdb, 0x3a, 0x81, + 0xd6, 0x17, 0x79, 0xec, 0xee, 0xfd, 0xe7, 0xe8, 0xfa, 0xf5, 0x06, 0xf7, 0x16, + 0x37, 0x04, 0xed, 0x1f, 0x21, 0xbd, 0x24, 0xf3, 0x44, 0xe6, 0x0d, 0x09, 0x24, + 0x01, 0xdc, 0x1a, 0x2a, 0xe3, 0xef, 0xee, 0x38, 0x10, 0x25, 0xed, 0x02, 0xe7, + 0x11, 0x08, 0xfd, 0xf1, 0x18, 0xf5, 0xe3, 0x26, 0x14, 0x2d, 0xf0, 0xe8, 0xfb, + 0x21, 0xff, 0x02, 0xf0, 0xf0, 0xfc, 0xe4, 0x07, 0x02, 0x1f, 0x17, 0xfd, 0x15, + 0x29, 0xd9, 0x1a, 0x16, 0x09, 0x09, 0x1f, 0x24, 0x19, 0xe8, 0x81, 0xed, 0xcd, + 0x29, 0x34, 0x12, 0xfb, 0x40, 0xd8, 0x11, 0x07, 0xd6, 0xf3, 0xfa, 0x06, 0xfe, + 0x3d, 0x2c, 0xdc, 0x1f, 0xee, 0xdc, 0x12, 0x38, 0x2f, 0x2a, 0xee, 0x02, 0xf5, + 0x05, 0x2e, 0x0d, 0x20, 0xf6, 0x0c, 0xe2, 0x20, 0x14, 0x00, 0xce, 0x12, 0xf3, + 0x1f, 0xd8, 0xc5, 0xce, 0x34, 0xfb, 0xe7, 0x0d, 0x1d, 0xa0, 0xe5, 0x4b, 0xf0, + 0x0c, 0x3c, 0xdf, 0x39, 0xfd, 0x28, 0x04, 0x0a, 0xff, 0x0b, 0x43, 0xf7, 0x40, + 0xe2, 0x17, 0x24, 0x48, 0xc6, 0x2f, 0xbd, 0x01, 0xdf, 0xe5, 0xee, 0x12, 0x52, + 0xc7, 0xab, 0x0b, 0x0d, 0x2b, 0x1a, 0xf2, 0x03, 0xd8, 0xe7, 0xfe, 0x27, 0xf4, + 0x2d, 0xfa, 0xc7, 0x25, 0x7f, 0xe7, 0x01, 0x2b, 0x9a, 0xfb, 0x5d, 0x32, 0xed, + 0xf9, 0xff, 0x7f, 0xf9, 0xf0, 0x2d, 0xd4, 0x07, 0xe5, 0x06, 0x15, 0x69, 0xf5, + 0xe1, 0xfe, 0x98, 0x95, 0x85, 0x75, 0xfc, 0xe9, 0x29, 0x7c, 0xe6, 0x0b, 0xd5, + 0x14, 0xfa, 0xd4, 0x12, 0x61, 0x39, 0xe9, 0x10, 0x24, 0x19, 0xcc, 0x1c, 0xf3, + 0xee, 0xa7, 0x59, 0xf1, 0x49, 0xe8, 0x15, 0xe5, 0x0a, 0x12, 0xca, 0x9f, 0x0a, + 0x0f, 0x23, 0x16, 0x24, 0xc3, 0x00, 0x17, 0xe4, 0xd0, 0xc4, 0x0f, 0x16, 0xf7, + 0xda, 0x13, 0xdf, 0x2e, 0xf4, 0x1e, 0xe7, 0xf3, 0x12, 0xe0, 0x27, 0xf4, 0xe8, + 0xff, 0x1c, 0x06, 0xf0, 0x04, 0x03, 0xf8, 0x7f, 0xe7, 0x51, 0xe3, 0xee, 0x08, + 0x20, 0xca, 0x05, 0xd1, 0xfd, 0xf0, 0xfa, 0xdb, 0xae, 0xca, 0x2a, 0x28, 0x0f, + 0x00, 0x92, 0x35, 0x2c, 0xe2, 0xfe, 0x02, 0xb0, 0x0d, 0x05, 0xce, 0xe7, 0xdb, + 0x02, 0xcf, 0xd9, 0xf1, 0xf9, 0x07, 0xf4, 0xe5, 0x1b, 0x40, 0xed, 0xd9, 0x21, + 0xce, 0xa6, 0xd3, 0x22, 0xf0, 0xf2, 0x1a, 0x40, 0xf7, 0x49, 0xdf, 0x17, 0xe3, + 0x28, 0x0a, 0x0f, 0xfa, 0xc6, 0xd0, 0x97, 0x12, 0x1d, 0xae, 0xd4, 0x37, 0x5e, + 0xa2, 0x03, 0x53, 0xc6, 0xdf, 0x9f, 0x3e, 0xe8, 0xb5, 0xf4, 0x14, 0x49, 0xf7, + 0x01, 0xe6, 0xec, 0xc4, 0x7f, 0x02, 0xee, 0x44, 0x4c, 0x2c, 0x25, 0xe5, 0xd2, + 0x20, 0x16, 0xeb, 0xee, 0xe1, 0xc3, 0x42, 0xde, 0x09, 0x27, 0xec, 0xf4, 0xf2, + 0xf0, 0x22, 0x13, 0x03, 0xfb, 0xd5, 0xca, 0x27, 0x28, 0xc9, 0x29, 0xf4, 0x06, + 0xf0, 0x11, 0xe4, 0xed, 0x01, 0x21, 0x06, 0xfe, 0xe4, 0xfa, 0x0c, 0x1f, 0xb6, + 0xf5, 0xda, 0x03, 0x02, 0x00, 0x05, 0xfc, 0xf4, 0x7f, 0x1e, 0xff, 0x0b, 0xfd, + 0xe4, 0xb8, 0xde, 0xbc, 0xe0, 0x4a, 0x2e, 0x01, 0xbf, 0x15, 0x20, 0x10, 0x20, + 0x11, 0x20, 0x1b, 0x28, 0xb9, 0x0b, 0xe9, 0xf1, 0xcf, 0x2c, 0x00, 0xdc, 0x4a, + 0x3e, 0x33, 0x0b, 0xdf, 0xa4, 0xe6, 0x14, 0xf4, 0xc4, 0xd1, 0xd4, 0x17, 0xec, + 0x16, 0x06, 0xda, 0xca, 0x7f, 0x15, 0xf9, 0xc8, 0xba, 0x33, 0xee, 0xae, 0xfc, + 0xe8, 0xbb, 0xfc, 0xe6, 0x24, 0x12, 0xe6, 0x05, 0xf5, 0xfb, 0x05, 0x0e, 0xc5, + 0x32, 0xe8, 0x04, 0xd1, 0x0a, 0xf2, 0xbc, 0x1b, 0x14, 0x15, 0xc5, 0xf9, 0xce, + 0xfd, 0x38, 0xfd, 0xeb, 0xe6, 0x7f, 0x23, 0x45, 0x08, 0xeb, 0xee, 0x3e, 0x26, + 0xf6, 0xd9, 0xbb, 0x0a, 0xa6, 0x1e, 0xd3, 0xea, 0x08, 0xf6, 0xcc, 0x0c, 0xe9, + 0x39, 0xea, 0x08, 0xe4, 0x04, 0x13, 0xfc, 0xf5, 0xe8, 0xe4, 0x05, 0xeb, 0x91, + 0xea, 0x19, 0x3c, 0xd0, 0xdd, 0xe0, 0x13, 0xfb, 0xf0, 0xe6, 0xc8, 0x3e, 0xef, + 0xeb, 0x13, 0x42, 0xc2, 0xf0, 0xdf, 0xe1, 0xe0, 0x0f, 0xf8, 0xfa, 0xc8, 0xc5, + 0xfb, 0x2a, 0x14, 0xee, 0x36, 0xdd, 0x0d, 0x01, 0xd2, 0xe5, 0xb1, 0x11, 0x09, + 0x59, 0x03, 0x16, 0xeb, 0x81, 0x24, 0xb4, 0xd6, 0x27, 0x02, 0x1d, 0x29, 0x66, + 0x0f, 0xa9, 0x35, 0x36, 0x99, 0x2a, 0x33, 0xfa, 0xce, 0xd7, 0xe1, 0xff, 0x06, + 0xfa, 0x2b, 0x05, 0xe9, 0xc4, 0xdf, 0x19, 0xee, 0xd1, 0xca, 0x0a, 0x44, 0x9e, + 0x09, 0xd4, 0x5d, 0x26, 0x26, 0xec, 0x6a, 0x32, 0x00, 0xf7, 0x59, 0xf9, 0x37, + 0xfb, 0xc9, 0x93, 0xe0, 0xf6, 0x03, 0xdd, 0x3f, 0x17, 0xf6, 0x10, 0xed, 0x00, + 0xcd, 0xf6, 0x90, 0xcb, 0x12, 0xe3, 0x3f, 0x01, 0x7f, 0x20, 0xfa, 0xfc, 0x15, + 0x02, 0x7d, 0xce, 0xe4, 0x04, 0x12, 0x04, 0x13, 0xcf, 0x1a, 0x21, 0xdf, 0x70, + 0xef, 0xf4, 0x12, 0xe1, 0x01, 0x29, 0x04, 0x37, 0xf1, 0x42, 0xf1, 0x9a, 0x0d, + 0x1e, 0x14, 0x05, 0x1d, 0x18, 0xde, 0x03, 0x06, 0xef, 0xed, 0xb3, 0xdf, 0x0d, + 0xec, 0x08, 0xb4, 0x01, 0x12, 0x0a, 0x48, 0xec, 0xd7, 0x7f, 0x04, 0x37, 0xde, + 0x4f, 0xd7, 0xd9, 0x21, 0xa5, 0x19, 0x0f, 0x0d, 0x16, 0xde, 0xe3, 0x3f, 0xcd, + 0x36, 0x2f, 0x34, 0x05, 0x4a, 0xb7, 0x22, 0x47, 0xf0, 0xeb, 0x07, 0x0a, 0x25, + 0xcc, 0x8d, 0xd5, 0xed, 0xc6, 0xce, 0xf1, 0xf9, 0x37, 0xbc, 0xed, 0x32, 0x08, + 0xbf, 0xe9, 0x0e, 0x9a, 0xe3, 0x0e, 0xe5, 0xe0, 0xd4, 0xca, 0xc8, 0xd5, 0xb2, + 0x3c, 0xd6, 0xe0, 0x0f, 0x19, 0x01, 0x02, 0xf1, 0xfc, 0xef, 0x22, 0xff, 0x1f, + 0xdf, 0x05, 0x23, 0x2a, 0xf2, 0x00, 0x48, 0xf9, 0x00, 0xf4, 0x69, 0x27, 0xef, + 0x00, 0x7f, 0x04, 0x2e, 0x2a, 0x2b, 0x0d, 0x35, 0xfa, 0xf1, 0x0b, 0xdd, 0x14, + 0x24, 0x17, 0x03, 0xfe, 0x27, 0x1f, 0x07, 0xe9, 0x13, 0xea, 0x5e, 0x05, 0xd5, + 0x04, 0xf1, 0x16, 0xf0, 0xf9, 0xd6, 0xe8, 0xe0, 0x00, 0x53, 0xec, 0xf7, 0x22, + 0xeb, 0xfd, 0x0a, 0xd3, 0x05, 0xf2, 0x43, 0x9c, 0xdf, 0xcc, 0x01, 0x00, 0x14, + 0xe4, 0xfa, 0xe3, 0x40, 0x0b, 0xa5, 0x05, 0xdb, 0x11, 0x26, 0x8b, 0x8f, 0x1d, + 0x6d, 0x01, 0xc9, 0xdb, 0xc0, 0x44, 0x19, 0x81, 0x14, 0xd1, 0x44, 0xfe, 0xcf, + 0x36, 0xed, 0xde, 0x19, 0xeb, 0xeb, 0xf8, 0x05, 0x3d, 0xf7, 0xd4, 0xcd, 0x3e, + 0x1b, 0x65, 0x72, 0x13, 0xd1, 0x59, 0x1a, 0x11, 0x28, 0x00, 0xd9, 0xd3, 0x12, + 0x08, 0x20, 0xd4, 0xf2, 0x17, 0x02, 0xf8, 0xf1, 0x06, 0x03, 0x36, 0xe4, 0xc5, + 0x16, 0x7d, 0xaf, 0x35, 0x2e, 0x19, 0xf2, 0x7f, 0x0e, 0x0e, 0xe4, 0xf8, 0xd9, + 0xf9, 0xf2, 0x0f, 0xfe, 0xc4, 0x41, 0x08, 0x07, 0xde, 0x42, 0xfe, 0xdd, 0x00, + 0x04, 0xfd, 0xe5, 0xda, 0x04, 0xea, 0x0b, 0x0f, 0x48, 0xf9, 0x07, 0x1c, 0x0e, + 0x16, 0xfc, 0xfb, 0x25, 0xf0, 0xcd, 0xfa, 0x03, 0x22, 0xec, 0x1b, 0xee, 0x20, + 0x13, 0xea, 0x00, 0xfc, 0xf8, 0x1d, 0x08, 0x1c, 0x7f, 0x37, 0x2f, 0x11, 0x03, + 0x36, 0xc8, 0xe2, 0xe8, 0x1b, 0x66, 0x12, 0x0c, 0x26, 0x91, 0x20, 0xe6, 0xff, + 0x2b, 0x5c, 0x02, 0xcb, 0x06, 0x28, 0x21, 0xfc, 0xee, 0x17, 0x18, 0xfd, 0xf6, + 0xde, 0x17, 0x44, 0x61, 0xfb, 0xf8, 0x20, 0xc2, 0x07, 0x1a, 0xfe, 0xe5, 0xd4, + 0x0b, 0x16, 0x29, 0x04, 0xec, 0x6b, 0x42, 0x1a, 0x22, 0x7f, 0x90, 0x00, 0xca, + 0x33, 0xd1, 0xa4, 0x09, 0xe9, 0x59, 0xbe, 0x01, 0x1b, 0xf3, 0x7d, 0x1a, 0xd2, + 0x2b, 0x0c, 0x04, 0x38, 0xca, 0x26, 0x38, 0x30, 0xc9, 0x2a, 0x7c, 0x12, 0xe5, + 0x02, 0x1e, 0x03, 0xe2, 0x07, 0xfd, 0xca, 0xf4, 0xd3, 0xc2, 0x4c, 0xeb, 0xca, + 0x47, 0x64, 0xe7, 0x0e, 0xfa, 0xc2, 0xf0, 0xfd, 0x9f, 0x3f, 0xca, 0x0c, 0xa7, + 0x47, 0x05, 0xee, 0x17, 0x0a, 0x0f, 0xf7, 0xcb, 0xfc, 0x3c, 0x58, 0x07, 0x18, + 0x36, 0xf6, 0x24, 0xeb, 0xf7, 0x17, 0xfc, 0xf4, 0xe9, 0xfb, 0x7f, 0x13, 0xf2, + 0xf9, 0xee, 0x06, 0xe6, 0xf9, 0xe9, 0xdb, 0xdb, 0x3a, 0xda, 0xd8, 0x0e, 0x0e, + 0x44, 0xd9, 0x10, 0x02, 0xfc, 0xfd, 0x2e, 0x15, 0xc2, 0x0e, 0x00, 0xf1, 0xdb, + 0xfe, 0x15, 0xfd, 0x0a, 0x00, 0xe7, 0x2d, 0x04, 0x19, 0xeb, 0xd1, 0xee, 0x28, + 0x22, 0xe3, 0xd9, 0xbc, 0xe1, 0x27, 0x05, 0xf4, 0x25, 0x2c, 0x0f, 0x31, 0x45, + 0x0d, 0x00, 0x13, 0xe6, 0x05, 0x0c, 0xe9, 0x16, 0xe3, 0xde, 0xaa, 0xfe, 0x76, + 0x1c, 0x26, 0xdb, 0x12, 0xf9, 0x18, 0xa3, 0x1d, 0x14, 0xdb, 0x0d, 0x03, 0xed, + 0x0c, 0x0a, 0x4c, 0x18, 0x2a, 0x38, 0x52, 0x33, 0xd3, 0xfe, 0xff, 0xd8, 0xfa, + 0xf2, 0x0f, 0x06, 0xee, 0x22, 0xee, 0x5b, 0x22, 0x07, 0xf8, 0x02, 0x63, 0x08, + 0xe0, 0x4e, 0xf6, 0xd7, 0x81, 0x59, 0xde, 0x08, 0x40, 0x0d, 0xd9, 0xf2, 0xf0, + 0x26, 0x81, 0x4c, 0x24, 0x34, 0xd1, 0x10, 0xd9, 0x13, 0x96, 0xda, 0xdb, 0x2e, + 0x07, 0xd4, 0xfd, 0x36, 0xcf, 0xcd, 0xd1, 0xd9, 0x06, 0xb7, 0xf1, 0x00, 0xeb, + 0x18, 0xd5, 0xdf, 0xf0, 0xd9, 0x3d, 0xd3, 0xaa, 0x10, 0x47, 0xf5, 0xfb, 0xde, + 0x59, 0xd3, 0x0c, 0x42, 0x1a, 0xf1, 0x28, 0xf7, 0x1e, 0xb8, 0xfc, 0xc0, 0xf0, + 0xea, 0xe2, 0x1e, 0xf4, 0xd4, 0xf2, 0x1b, 0xd6, 0xf5, 0xdd, 0xcf, 0x35, 0xd2, + 0xf8, 0x17, 0xf3, 0xd8, 0x3b, 0x25, 0x11, 0x0c, 0xb2, 0x2f, 0x07, 0xad, 0xff, + 0x28, 0xd2, 0x40, 0xf2, 0x99, 0xfe, 0xef, 0x22, 0xd5, 0x93, 0xca, 0x05, 0xe8, + 0xf9, 0x0d, 0x21, 0x0b, 0x0a, 0xdf, 0xde, 0xcc, 0x04, 0x81, 0x46, 0x25, 0x18, + 0x34, 0x0b, 0xfe, 0xe9, 0xec, 0xdd, 0xef, 0xe0, 0x3e, 0xf8, 0xcb, 0x1c, 0xe8, + 0xd0, 0xab, 0xcf, 0x29, 0xdd, 0x00, 0x12, 0x53, 0x03, 0x02, 0x1e, 0x14, 0x08, + 0x0a, 0x09, 0x75, 0x01, 0x21, 0x21, 0x34, 0x05, 0xce, 0x1e, 0xf8, 0xcf, 0x44, + 0x4c, 0x14, 0xed, 0xe0, 0x25, 0x26, 0x13, 0xfb, 0xd9, 0xf5, 0x0e, 0xf7, 0x47, + 0x3d, 0x27, 0x24, 0x3e, 0x07, 0x15, 0x27, 0x52, 0xfe, 0xfc, 0x0d, 0xee, 0xd1, + 0xea, 0xca, 0xc4, 0x4b, 0xee, 0xfb, 0x0f, 0x3a, 0x37, 0xa9, 0x0a, 0x55, 0x57, + 0xee, 0xec, 0x7f, 0x1e, 0x19, 0x32, 0x97, 0xdb, 0x1f, 0xb2, 0x3b, 0xe4, 0x7f, + 0x03, 0xe7, 0xec, 0xc4, 0xf6, 0xfc, 0x27, 0x51, 0x43, 0x02, 0xd0, 0xbb, 0x0b, + 0x2b, 0x9a, 0xf5, 0x44, 0xfe, 0xb5, 0x23, 0x35, 0xd2, 0x47, 0xca, 0x7b, 0xda, + 0xee, 0x0a, 0x35, 0x65, 0xb9, 0xb6, 0xdc, 0x41, 0xef, 0x1c, 0xed, 0x13, 0x50, + 0x03, 0xe8, 0x18, 0xef, 0xfe, 0x04, 0x16, 0xfc, 0x1f, 0x00, 0xf1, 0xbb, 0xf8, + 0x0f, 0x59, 0xc8, 0x09, 0xf0, 0x5a, 0x10, 0xbe, 0xf5, 0x16, 0x2c, 0xc7, 0x4d, + 0x15, 0x2b, 0xd6, 0xf2, 0x28, 0x38, 0xc9, 0x09, 0x27, 0xff, 0x26, 0xfa, 0xde, + 0x3c, 0x22, 0xf2, 0x07, 0xec, 0x0c, 0x43, 0x1a, 0x02, 0x1e, 0x3c, 0x03, 0xca, + 0xe3, 0xf2, 0xbe, 0xdc, 0x29, 0x0d, 0x81, 0x27, 0x02, 0x5b, 0x3d, 0xd6, 0xff, + 0x46, 0x47, 0xe8, 0x2b, 0xc3, 0xd7, 0xfd, 0xee, 0x5c, 0xe9, 0x3a, 0x12, 0x04, + 0xfb, 0xf1, 0x1b, 0x39, 0xf2, 0x20, 0xfe, 0xd7, 0xef, 0x0d, 0xf9, 0x13, 0xed, + 0x06, 0xf0, 0x31, 0xef, 0x0e, 0x0d, 0xdc, 0xe8, 0x12, 0x31, 0x02, 0xc5, 0xe7, + 0xda, 0x14, 0x10, 0xc5, 0xcb, 0xf3, 0xfb, 0xe3, 0x26, 0xf1, 0x03, 0xfe, 0x14, + 0xd0, 0xef, 0xe7, 0x7f, 0x0e, 0x03, 0x10, 0xd5, 0x01, 0xf6, 0xef, 0x02, 0x00, + 0x04, 0x36, 0xef, 0xd4, 0x0c, 0x16, 0x1f, 0xfe, 0xe7, 0xf2, 0xef, 0x0b, 0x07, + 0xef, 0xfa, 0xd9, 0x49, 0x11, 0x4c, 0xf3, 0x4e, 0x7f, 0xe9, 0xb6, 0xcc, 0xf8, + 0xe1, 0x19, 0xc1, 0x15, 0xbf, 0xc4, 0x14, 0xc0, 0x07, 0xcb, 0xbe, 0x70, 0xc2, + 0x3c, 0x12, 0xdd, 0x4f, 0x04, 0x06, 0xe1, 0xd2, 0x23, 0xdb, 0x22, 0xf9, 0xb4, + 0x00, 0x12, 0xd1, 0xae, 0x57, 0xf8, 0xf4, 0x37, 0x32, 0xea, 0xcd, 0xd6, 0xdd, + 0xd8, 0x1b, 0x0b, 0xbd, 0x41, 0x42, 0x35, 0xda, 0xd6, 0x10, 0x26, 0x22, 0xf5, + 0x0c, 0xe7, 0x02, 0x0a, 0xfc, 0xea, 0xfe, 0x56, 0xf8, 0x3b, 0xe6, 0x16, 0xbc, + 0x0c, 0x12, 0x08, 0x4a, 0xf7, 0x2e, 0xd5, 0x4c, 0x1c, 0xdc, 0xeb, 0x7f, 0xe7, + 0x1a, 0x05, 0x0b, 0xff, 0x0c, 0xf8, 0xab, 0x1b, 0xee, 0xcd, 0x00, 0x06, 0xd7, + 0x21, 0x1e, 0x50, 0xf0, 0x0f, 0x0b, 0xb7, 0x21, 0x12, 0xec, 0x0e, 0x19, 0x2e, + 0xf4, 0xd4, 0xe0, 0x4c, 0xfc, 0x26, 0xeb, 0xf0, 0x44, 0xb0, 0x43, 0xe3, 0xfc, + 0xf2, 0xf9, 0x19, 0xb7, 0xc9, 0x39, 0xd5, 0x1e, 0x06, 0x07, 0xeb, 0x02, 0xf3, + 0x1f, 0x81, 0x05, 0xb9, 0x30, 0xe4, 0xf2, 0xd3, 0x02, 0xdf, 0x10, 0x0e, 0xf9, + 0xf1, 0xd6, 0x05, 0x24, 0xe3, 0x03, 0xfa, 0xc7, 0x0f, 0xed, 0xff, 0xd0, 0xc3, + 0x05, 0x2b, 0xfa, 0x0b, 0xd4, 0x19, 0x4a, 0xe6, 0x4c, 0x16, 0xee, 0x14, 0xe9, + 0x0c, 0xae, 0xe9, 0xd8, 0xd1, 0xdc, 0xd4, 0x1a, 0xdf, 0xf5, 0xd5, 0x0e, 0xde, + 0xf6, 0xf7, 0xea, 0x05, 0x18, 0xef, 0xd5, 0x03, 0xce, 0xf3, 0x1b, 0xdb, 0x2d, + 0x10, 0x21, 0x3f, 0xf9, 0xdd, 0xd8, 0xe6, 0x0e, 0x12, 0x09, 0x07, 0xed, 0x0f, + 0x2c, 0x1b, 0x12, 0xee, 0x00, 0x05, 0x7f, 0xd6, 0x39, 0xd5, 0x4d, 0x38, 0x05, + 0xfe, 0x39, 0x21, 0x05, 0xfc, 0x48, 0x27, 0x04, 0xfc, 0xec, 0xf4, 0x0c, 0xce, + 0x26, 0xf6, 0xf8, 0xf7, 0x2b, 0x49, 0x18, 0x25, 0x1e, 0xff, 0xda, 0x2f, 0x56, + 0x0f, 0x2a, 0x4a, 0x24, 0xf0, 0xe4, 0x37, 0xe8, 0x0a, 0xa0, 0x21, 0xe5, 0x93, + 0xaa, 0x08, 0x0b, 0xa5, 0xff, 0xf1, 0x0f, 0xd4, 0x64, 0xe0, 0xd2, 0xbd, 0xf9, + 0x44, 0x43, 0xeb, 0xe5, 0x0e, 0x08, 0xdd, 0xe1, 0x2c, 0xee, 0x81, 0x45, 0xe6, + 0xdf, 0xd1, 0xa5, 0x65, 0xe1, 0x03, 0xeb, 0xfc, 0xf8, 0xe6, 0x0a, 0xed, 0xb5, + 0x20, 0xd5, 0xca, 0x3a, 0x2d, 0xf3, 0x1a, 0xf1, 0x3b, 0xd9, 0x9e, 0x0d, 0x4a, + 0xe3, 0xa9, 0xc8, 0x0c, 0x85, 0x25, 0xf0, 0x2b, 0xb5, 0xb7, 0xf3, 0xad, 0x2c, + 0x45, 0x57, 0xf8, 0x4a, 0xa0, 0xe3, 0x32, 0x22, 0xfc, 0x10, 0x03, 0x40, 0xe2, + 0xd4, 0xea, 0x05, 0xf2, 0x2f, 0x34, 0x81, 0xba, 0xbf, 0xef, 0xe8, 0x2b, 0x0e, + 0x3e, 0xb0, 0x44, 0x04, 0xa7, 0x2f, 0x20, 0x33, 0xfe, 0x3c, 0x41, 0x21, 0xbe, + 0xdc, 0xf9, 0x10, 0x15, 0xd8, 0x19, 0x47, 0xad, 0x2c, 0x0d, 0x2b, 0xf4, 0xfc, + 0x35, 0xbd, 0x2d, 0x0d, 0x36, 0x58, 0x22, 0x07, 0xee, 0x05, 0x7f, 0x15, 0xc5, + 0x17, 0x0c, 0xfd, 0xf6, 0xe3, 0x1d, 0x2f, 0xcc, 0x9a, 0x5a, 0x0d, 0x31, 0xc9, + 0x65, 0x0c, 0xdc, 0x2c, 0x3b, 0xe4, 0xfd, 0xe1, 0xa4, 0xf4, 0xfc, 0xeb, 0xc4, + 0xcc, 0xf3, 0x0c, 0x32, 0x33, 0x12, 0xf0, 0x27, 0xaf, 0xfa, 0xd6, 0xdd, 0x1b, + 0xcc, 0xcf, 0x41, 0x32, 0xef, 0xde, 0x18, 0x08, 0xe9, 0xc2, 0xaa, 0xbc, 0xf3, + 0xaa, 0x03, 0x2f, 0xf3, 0xc9, 0x81, 0xbb, 0x91, 0x19, 0x26, 0xfe, 0x07, 0xfc, + 0x17, 0xcb, 0xb3, 0x0d, 0xd6, 0x15, 0xa5, 0xf0, 0xc2, 0xbd, 0x34, 0x1e, 0xcf, + 0xf8, 0xdf, 0x19, 0xdc, 0xb4, 0xe8, 0xde, 0x8c, 0x10, 0xfa, 0x05, 0x3a, 0xe5, + 0xe5, 0x04, 0xce, 0x0e, 0xf2, 0xf5, 0x2d, 0x12, 0xf3, 0x00, 0x8a, 0x37, 0x15, + 0xd8, 0xa3, 0x35, 0x0a, 0x81, 0xbe, 0xfd, 0xfe, 0x2c, 0x35, 0xdd, 0xed, 0x32, + 0xb5, 0xed, 0x0d, 0x14, 0xe8, 0xd9, 0x3c, 0x31, 0x18, 0x09, 0xfe, 0x3a, 0x0b, + 0x1b, 0xfa, 0xe5, 0x22, 0x07, 0xcd, 0x38, 0xc6, 0xeb, 0x08, 0x7f, 0x0c, 0x5c, + 0xf5, 0x1a, 0xe5, 0xd2, 0xcf, 0xdb, 0x04, 0x5a, 0x0e, 0xe9, 0x35, 0x1b, 0xd1, + 0x23, 0xe6, 0xf8, 0xfc, 0xeb, 0x34, 0xdd, 0x49, 0xd6, 0x00, 0x47, 0xd4, 0x11, + 0x0b, 0xfa, 0x1d, 0x37, 0x18, 0xe8, 0x28, 0xeb, 0x47, 0xb3, 0xe4, 0x4c, 0x28, + 0xf9, 0x28, 0x3c, 0xea, 0xf9, 0xf2, 0xda, 0x1e, 0xc4, 0xfd, 0xc1, 0xd8, 0xf8, + 0xfd, 0x7f, 0xf1, 0x2d, 0xaf, 0xe2, 0x08, 0xe1, 0x33, 0x34, 0xe8, 0x1a, 0x3b, + 0xd5, 0xf7, 0xbd, 0x3b, 0x0e, 0x31, 0x03, 0x01, 0xbf, 0xe1, 0x51, 0x07, 0x08, + 0x49, 0xf8, 0x4b, 0xa5, 0x4b, 0x25, 0x27, 0xfe, 0xee, 0x07, 0xd7, 0xb5, 0xf3, + 0xd4, 0x51, 0xc3, 0x34, 0xd8, 0x29, 0xe4, 0x1a, 0xca, 0xbe, 0x1d, 0x14, 0x55, + 0x0f, 0xa0, 0xd0, 0xd7, 0x14, 0xa1, 0xc4, 0x61, 0xb4, 0xf0, 0xbd, 0xf3, 0xd6, + 0xf0, 0x81, 0x43, 0x2b, 0x20, 0xdf, 0xfc, 0x52, 0x2d, 0x35, 0xec, 0xd5, 0xe2, + 0x51, 0x4b, 0x29, 0xfc, 0x1c, 0xd7, 0x36, 0x12, 0xcc, 0x04, 0xee, 0xd5, 0xac, + 0x30, 0xd5, 0xe8, 0xfb, 0x18, 0xf1, 0xf2, 0x1a, 0xc2, 0x2b, 0x18, 0xae, 0xe0, + 0x9f, 0xcd, 0xbb, 0xec, 0x4d, 0x18, 0xc3, 0x7a, 0x3e, 0xba, 0x20, 0xf8, 0xe7, + 0xde, 0xd9, 0xbd, 0xe1, 0xc6, 0x73, 0x5b, 0x7e, 0xd5, 0x1e, 0xe9, 0xcd, 0xcd, + 0xd4, 0xc7, 0x00, 0x0e, 0x6a, 0xf7, 0x3d, 0xff, 0x11, 0x7f, 0x0e, 0x18, 0xcd, + 0x0b, 0x31, 0x3a, 0x49, 0x0a, 0xed, 0xdd, 0xf5, 0x1d, 0xbd, 0x3f, 0x29, 0x0b, + 0x0c, 0x07, 0xf6, 0x46, 0x15, 0xb6, 0xd2, 0x40, 0x4b, 0xc9, 0xee, 0x67, 0x40, + 0x44, 0x56, 0x4d, 0x0e, 0xda, 0xfc, 0xf3, 0xea, 0xf6, 0xfd, 0xff, 0x17, 0xf9, + 0xf9, 0x05, 0xd8, 0xf9, 0x05, 0x07, 0xee, 0xe0, 0x13, 0xf3, 0xc8, 0xf0, 0xab, + 0x0a, 0x41, 0x3d, 0xda, 0x9f, 0xf5, 0x04, 0x81, 0x14, 0x07, 0x09, 0xff, 0x24, + 0x0b, 0x0d, 0xee, 0xce, 0xf3, 0x0b, 0xfb, 0x02, 0x2d, 0xf0, 0x18, 0x1e, 0xf8, + 0xfb, 0xf4, 0xf5, 0x3c, 0x06, 0x15, 0xfd, 0xfb, 0xbe, 0x12, 0x01, 0x06, 0x10, + 0x0c, 0x29, 0xea, 0xf2, 0xf6, 0xfd, 0x1e, 0x2a, 0x15, 0xf7, 0xed, 0xbd, 0xd6, + 0x34, 0xe9, 0xfe, 0xc4, 0x43, 0x3a, 0xb2, 0x4f, 0xe7, 0xeb, 0x3d, 0xbc, 0x7f, + 0xe0, 0x33, 0x0e, 0x28, 0x27, 0xe5, 0xf0, 0x35, 0x19, 0xca, 0x10, 0xdc, 0xdc, + 0xb3, 0xf2, 0x06, 0x0a, 0xdf, 0x45, 0x31, 0x15, 0xf4, 0xb7, 0xf7, 0x10, 0xff, + 0xff, 0xd9, 0xe1, 0xe1, 0xd0, 0x0f, 0x03, 0x03, 0xfc, 0xfe, 0x0e, 0xc9, 0x17, + 0x21, 0xc9, 0xe4, 0xf8, 0x98, 0x08, 0xfe, 0x20, 0x5a, 0x1c, 0x3b, 0xfd, 0x00, + 0xe5, 0x27, 0x13, 0xc0, 0x45, 0x1f, 0xeb, 0xfb, 0xe2, 0x23, 0x0d, 0xd4, 0xeb, + 0xf4, 0x1a, 0x1b, 0x06, 0xe4, 0x1a, 0x2e, 0x4c, 0x1d, 0xea, 0x1e, 0xd8, 0x8f, + 0xfa, 0x3b, 0xdd, 0xe4, 0x2a, 0x0d, 0xf9, 0x02, 0xce, 0x07, 0x11, 0x18, 0xeb, + 0x1b, 0x21, 0xfd, 0x81, 0x09, 0x02, 0xf3, 0x0e, 0x19, 0xf0, 0x3d, 0xd0, 0xc9, + 0xfb, 0x72, 0x36, 0x24, 0x32, 0x15, 0x04, 0x12, 0x7f, 0x3a, 0x0d, 0x1a, 0x1d, + 0xe4, 0xf0, 0x07, 0x09, 0x0a, 0xff, 0x59, 0x18, 0xbf, 0xe9, 0x2b, 0xf2, 0xf0, + 0x29, 0x1e, 0xf1, 0x31, 0xc8, 0xe2, 0x4c, 0xf7, 0x6c, 0xf6, 0x51, 0x1c, 0xec, + 0x1b, 0x3a, 0x17, 0x08, 0xf7, 0x43, 0xec, 0xc4, 0xeb, 0x20, 0x2f, 0xe4, 0x26, + 0xf1, 0xfe, 0xd1, 0xfe, 0xe4, 0x69, 0xfb, 0x03, 0xd4, 0xf3, 0xbf, 0x44, 0xed, + 0x4c, 0xec, 0x10, 0x52, 0x0f, 0xc6, 0xf5, 0x24, 0x1c, 0xe7, 0xf3, 0xbc, 0x19, + 0x7f, 0xe4, 0x4c, 0x0d, 0x11, 0xf4, 0xeb, 0x14, 0xbb, 0x45, 0xe9, 0xce, 0x0d, + 0x0f, 0xc7, 0x1c, 0x12, 0xf0, 0x18, 0x06, 0x0f, 0xc2, 0xd6, 0xd0, 0xb9, 0x03, + 0x15, 0xe2, 0x18, 0x4f, 0x4d, 0x3b, 0x02, 0xd4, 0xe2, 0xfb, 0x2c, 0xe0, 0x1d, + 0x18, 0xc8, 0xf6, 0x29, 0x1c, 0xf1, 0xea, 0x20, 0x24, 0x8c, 0x1e, 0x05, 0x22, + 0x2a, 0x00, 0x11, 0xe4, 0x00, 0x17, 0x1d, 0xc5, 0x0e, 0x7f, 0xe6, 0xd0, 0xd4, + 0xee, 0x45, 0xd5, 0x26, 0xd7, 0xe4, 0xeb, 0x47, 0xf1, 0x6a, 0x1c, 0x26, 0x45, + 0x42, 0xeb, 0x06, 0x2e, 0xfc, 0xd5, 0xfa, 0xcb, 0x01, 0xf4, 0xc2, 0xe3, 0x0b, + 0x0a, 0xcd, 0x49, 0x01, 0x28, 0x19, 0xde, 0x86, 0xd8, 0x11, 0xfd, 0x1c, 0x25, + 0x2a, 0x1a, 0x05, 0x1c, 0xf5, 0x78, 0x34, 0x1e, 0xe7, 0x06, 0x1d, 0xe7, 0xcc, + 0xde, 0xfb, 0x02, 0xf2, 0x7f, 0x26, 0x08, 0xb7, 0xd6, 0xaa, 0x0c, 0xe8, 0x23, + 0x28, 0xfb, 0xef, 0x04, 0x0b, 0xd8, 0x02, 0xc1, 0xf0, 0x31, 0x2b, 0xe6, 0x1b, + 0xfe, 0x0c, 0x1a, 0xbe, 0xf9, 0x14, 0xef, 0xe2, 0xc8, 0xe0, 0xf2, 0x2a, 0x6d, + 0x0d, 0x15, 0xc3, 0xfe, 0x43, 0x2c, 0x12, 0xf4, 0x6a, 0x10, 0x1c, 0x28, 0xdf, + 0xf5, 0x15, 0xb1, 0xd7, 0x03, 0xea, 0xf3, 0x42, 0x9a, 0xec, 0xcb, 0x3e, 0xf3, + 0xc6, 0x69, 0x10, 0xf0, 0x14, 0xea, 0x17, 0x00, 0x6f, 0xe7, 0x81, 0xe9, 0x8b, + 0x0a, 0xd5, 0x62, 0x4c, 0x38, 0x57, 0x92, 0xb6, 0xeb, 0xe9, 0xe4, 0x63, 0xb3, + 0xfd, 0x00, 0x2e, 0x3f, 0x11, 0xee, 0xf3, 0x05, 0xdc, 0x88, 0x0c, 0x2c, 0x4c, + 0xd6, 0xf2, 0x06, 0x1c, 0xdc, 0x55, 0xeb, 0xfe, 0xb5, 0x0d, 0xa3, 0x07, 0x22, + 0xae, 0x3a, 0xd2, 0x79, 0x26, 0xf8, 0x3f, 0x26, 0x31, 0x2c, 0x29, 0x45, 0xfb, + 0x34, 0xfa, 0x6a, 0x38, 0xbc, 0xe0, 0x55, 0xfe, 0xf8, 0x21, 0xfb, 0xe9, 0xec, + 0x0b, 0xca, 0xd7, 0xbb, 0xff, 0x7f, 0xfc, 0x1b, 0xcf, 0xd5, 0x33, 0x54, 0xfc, + 0x0e, 0xd3, 0x25, 0xfc, 0x31, 0xc0, 0x4d, 0xe9, 0x09, 0x39, 0xc9, 0xe5, 0xf3, + 0xe3, 0x22, 0xf9, 0xf1, 0xb5, 0xff, 0x7f, 0xec, 0x46, 0x09, 0xfb, 0xdf, 0xc8, + 0xcf, 0x37, 0x35, 0x56, 0x17, 0xf2, 0xf9, 0xee, 0xe1, 0x04, 0xf6, 0xf9, 0xf0, + 0xc6, 0x1e, 0x04, 0xd9, 0x04, 0x31, 0x1d, 0xc3, 0x75, 0x58, 0x8a, 0x31, 0x2d, + 0x10, 0xa5, 0xd6, 0xee, 0x29, 0x8b, 0x39, 0xef, 0x24, 0x39, 0x01, 0x02, 0x44, + 0x21, 0xfa, 0xb2, 0x8a, 0x95, 0xe4, 0xde, 0xdd, 0xf4, 0xc8, 0xf1, 0x28, 0x23, + 0x64, 0xff, 0x3f, 0xcf, 0x81, 0x32, 0x01, 0x0f, 0xc6, 0xef, 0xc4, 0x0e, 0x01, + 0x3a, 0x29, 0xb0, 0xf4, 0xf9, 0x22, 0x16, 0xb9, 0x00, 0xd0, 0xf3, 0x1e, 0x57, + 0x03, 0x10, 0xea, 0x56, 0x22, 0xf1, 0x3d, 0x0a, 0x06, 0xd2, 0x9a, 0x67, 0x14, + 0xd6, 0x3e, 0xd7, 0xbf, 0xea, 0xf0, 0xd5, 0x32, 0xbe, 0x24, 0x01, 0x9e, 0x11, + 0xd0, 0x1e, 0x8e, 0xaa, 0xd1, 0xfa, 0xe8, 0xf4, 0x1d, 0x3b, 0x7f, 0x14, 0xe8, + 0xe0, 0xba, 0x06, 0xc1, 0xf7, 0x14, 0x98, 0x18, 0xa5, 0x0e, 0x48, 0x2f, 0xf5, + 0xc3, 0xca, 0xce, 0xf9, 0x3f, 0x28, 0xd5, 0x27, 0x2e, 0x19, 0xdd, 0x68, 0x1e, + 0x44, 0x03, 0x07, 0xe4, 0xe0, 0xf5, 0x40, 0xf7, 0x5f, 0xfc, 0xbf, 0x41, 0xf7, + 0x0a, 0x9e, 0x18, 0xda, 0xc8, 0x19, 0xdf, 0xfa, 0x2f, 0xe8, 0x07, 0xfa, 0xf0, + 0xee, 0xfa, 0xb9, 0x29, 0x06, 0xb1, 0xae, 0x08, 0x2f, 0xec, 0xf9, 0xfc, 0xdf, + 0xbe, 0x7f, 0xc3, 0x1b, 0x0f, 0x11, 0xd8, 0x32, 0xfd, 0xe8, 0xed, 0x0d, 0xbf, + 0xef, 0xee, 0x48, 0xf7, 0x02, 0xf8, 0xd9, 0xef, 0xf2, 0x2e, 0xee, 0x11, 0xea, + 0xfe, 0xd8, 0xf6, 0xc0, 0x30, 0xb4, 0x20, 0x12, 0x09, 0xf9, 0xcf, 0xe9, 0x09, + 0xca, 0xd6, 0x4e, 0x30, 0xf8, 0xea, 0xeb, 0x03, 0x81, 0xee, 0x34, 0xf6, 0xf8, + 0xf5, 0xda, 0x30, 0x05, 0x04, 0xf6, 0x11, 0x40, 0xee, 0xfc, 0x0a, 0xda, 0xea, + 0x13, 0x0d, 0x1e, 0x3e, 0x11, 0x2a, 0x0e, 0x09, 0x18, 0x31, 0xd9, 0xd1, 0x0a, + 0xe5, 0xd1, 0x53, 0x3a, 0xd5, 0xd5, 0x4c, 0x6d, 0x03, 0xde, 0x3a, 0xd3, 0x21, + 0x11, 0x81, 0x15, 0x40, 0x5b, 0xfc, 0x15, 0xb3, 0x14, 0x8e, 0x47, 0x3e, 0x8a, + 0xb0, 0x2a, 0x57, 0x40, 0xee, 0xc1, 0xf4, 0x2a, 0x0c, 0xef, 0xc0, 0xb6, 0x2e, + 0x74, 0x73, 0x1e, 0xf8, 0xe7, 0x1d, 0x8c, 0x6d, 0xf6, 0xec, 0x35, 0xc6, 0xf2, + 0xde, 0x0a, 0xc9, 0xcb, 0x07, 0x15, 0xe1, 0x1b, 0x47, 0x0f, 0xf0, 0xf1, 0xf9, + 0x0d, 0x1a, 0x41, 0x08, 0x58, 0x29, 0xf7, 0x0e, 0x1f, 0x50, 0xeb, 0xe7, 0x19, + 0x47, 0xf3, 0x3d, 0x0c, 0x21, 0xfd, 0x08, 0x09, 0xde, 0x7f, 0x15, 0xfd, 0xe5, + 0x29, 0x0c, 0x15, 0x02, 0xfa, 0xdd, 0xeb, 0x07, 0x26, 0x01, 0x16, 0x3e, 0x3d, + 0xda, 0xe0, 0xda, 0x1c, 0xde, 0xe1, 0x2b, 0xe7, 0xf8, 0x04, 0xc3, 0x21, 0xf7, + 0x6f, 0xd2, 0xf7, 0xd2, 0x55, 0xb7, 0xe6, 0x20, 0xf6, 0xf8, 0xd4, 0x3e, 0xe7, + 0x2e, 0x3b, 0xd7, 0xd8, 0xb3, 0x9e, 0xc1, 0xde, 0x37, 0x2f, 0xcb, 0xb9, 0x25, + 0xb1, 0xb7, 0xc9, 0x0a, 0xa2, 0x5f, 0x17, 0x82, 0xb1, 0xce, 0x19, 0x36, 0x26, + 0xba, 0x0c, 0x09, 0xea, 0xf1, 0xea, 0xda, 0x04, 0xf9, 0x18, 0xee, 0xb5, 0x9f, + 0xb4, 0xfc, 0xc9, 0x7f, 0x15, 0xe8, 0x05, 0xe4, 0x24, 0x22, 0xf0, 0xd7, 0xda, + 0x14, 0xde, 0x2b, 0x0e, 0x08, 0x9c, 0x4a, 0x03, 0xec, 0xea, 0xe4, 0xd1, 0x2f, + 0xc6, 0x4b, 0xd1, 0x7f, 0xf9, 0x0e, 0xe6, 0xd8, 0x2f, 0xe2, 0x7a, 0xb0, 0x2c, + 0xdf, 0xd2, 0xd2, 0xe3, 0x17, 0x21, 0xd4, 0x35, 0x1b, 0xf9, 0x26, 0xfb, 0x13, + 0x4e, 0xff, 0x01, 0x42, 0x07, 0xea, 0xc9, 0xe5, 0x34, 0x30, 0x20, 0xf6, 0xd2, + 0x13, 0x2c, 0xcb, 0x3d, 0xf8, 0x42, 0xcc, 0x1a, 0xf3, 0xeb, 0xe9, 0x37, 0x1c, + 0x17, 0x41, 0x03, 0xa7, 0x1a, 0x31, 0x35, 0xd2, 0xf7, 0xdb, 0xa2, 0x2b, 0x09, + 0xcd, 0xdc, 0x20, 0xfa, 0x0f, 0xed, 0x39, 0x11, 0x27, 0x12, 0xeb, 0x1b, 0x20, + 0xad, 0x19, 0xa5, 0x0c, 0xff, 0x64, 0xd3, 0xc7, 0xef, 0x1f, 0xe5, 0x44, 0xc1, + 0xdc, 0x10, 0x2e, 0xa8, 0x2e, 0xdf, 0xc7, 0xd2, 0xfb, 0x26, 0xc0, 0xe2, 0xf2, + 0x52, 0x28, 0xea, 0xfc, 0x8b, 0x3c, 0x29, 0x4b, 0x38, 0xaa, 0x7f, 0x0a, 0x3f, + 0x4b, 0xf3, 0xe0, 0xc9, 0xe4, 0x06, 0x16, 0xdf, 0xaa, 0xd1, 0xec, 0xf2, 0x28, + 0x23, 0x00, 0x1a, 0xeb, 0xe3, 0xb3, 0x3d, 0x49, 0x2a, 0xac, 0x1e, 0xea, 0x29, + 0xcb, 0xbe, 0x52, 0xe2, 0x07, 0xd8, 0xf1, 0x20, 0x32, 0xc4, 0x39, 0x12, 0x02, + 0xd5, 0xd2, 0xf3, 0xeb, 0xe9, 0x13, 0x3d, 0xec, 0x6c, 0x13, 0xf9, 0x10, 0x73, + 0xe0, 0xd9, 0xe0, 0xf7, 0x19, 0xec, 0xfd, 0xe7, 0x08, 0xca, 0x37, 0xe9, 0xfd, + 0xf5, 0x03, 0x23, 0x05, 0x7f, 0xd2, 0xf1, 0x02, 0xdd, 0xf8, 0xc4, 0xce, 0xd6, + 0xeb, 0xb1, 0x1e, 0x21, 0xfe, 0x1a, 0xfd, 0xd9, 0x0d, 0x0f, 0x7f, 0xcc, 0x51, + 0x0a, 0xfb, 0xf3, 0x21, 0xdf, 0x41, 0xf8, 0x04, 0x18, 0x08, 0x03, 0x05, 0x31, + 0x39, 0x1c, 0x74, 0xf5, 0x1a, 0x03, 0xe6, 0x35, 0x5c, 0x03, 0xee, 0x55, 0xbf, + 0xff, 0x3c, 0xe1, 0x1f, 0x0e, 0xf7, 0x2c, 0xec, 0x51, 0xbe, 0xc2, 0xee, 0xf3, + 0x15, 0x11, 0xeb, 0xf1, 0x37, 0x1d, 0x21, 0x7f, 0x01, 0x69, 0xe8, 0x0f, 0x20, + 0x1e, 0x57, 0x10, 0x54, 0xbf, 0xf8, 0xe4, 0x27, 0x22, 0x0e, 0xe2, 0xc7, 0x42, + 0x09, 0x07, 0xe7, 0x01, 0xbe, 0x10, 0x41, 0xdb, 0xdf, 0x39, 0xc9, 0x11, 0xde, + 0xd7, 0xf7, 0x0c, 0x1b, 0xd9, 0x1b, 0xe7, 0xde, 0xf9, 0xf6, 0xe8, 0x22, 0x3d, + 0xf8, 0x15, 0xfb, 0x79, 0xf3, 0x1c, 0xfc, 0x06, 0xcb, 0x09, 0x52, 0xfe, 0x2d, + 0x16, 0xf7, 0x09, 0xe5, 0x43, 0xe0, 0x48, 0xce, 0xed, 0x0e, 0xc1, 0xea, 0x32, + 0xc0, 0xe0, 0xd7, 0xf2, 0x77, 0x0d, 0x76, 0x18, 0xd6, 0xb5, 0x2a, 0xca, 0x61, + 0xe4, 0xe0, 0x01, 0xd9, 0xd1, 0xec, 0x19, 0xc4, 0x0d, 0x22, 0x00, 0xac, 0x25, + 0xb8, 0xe0, 0xea, 0x37, 0xc5, 0x07, 0xc5, 0xe0, 0xe1, 0x19, 0x7f, 0xaf, 0x23, + 0xf5, 0xed, 0xb7, 0x69, 0x26, 0xf1, 0x07, 0x32, 0xe8, 0x2d, 0xf1, 0x3e, 0x0b, + 0xdc, 0xf3, 0xff, 0x1b, 0x10, 0xee, 0x2f, 0x16, 0x2b, 0xc9, 0x37, 0xff, 0xec, + 0xcc, 0xcb, 0xf2, 0x23, 0xeb, 0x06, 0x1c, 0xc9, 0xf1, 0x33, 0xf2, 0x0a, 0x06, + 0xaf, 0xf6, 0x27, 0x09, 0x98, 0x06, 0xeb, 0xfa, 0x11, 0x02, 0xf6, 0x03, 0x24, + 0x66, 0xe1, 0x43, 0xcf, 0xdd, 0xf9, 0xd2, 0x1d, 0x49, 0xdc, 0xf9, 0x05, 0x7f, + 0xe6, 0x22, 0x0e, 0xe5, 0x10, 0xfa, 0xcc, 0x16, 0xda, 0x03, 0xcd, 0x05, 0x0a, + 0xdc, 0x0d, 0x1e, 0x0b, 0x00, 0x15, 0x08, 0x24, 0xf8, 0xfb, 0x2e, 0xac, 0x08, + 0xed, 0xd5, 0x4e, 0x2b, 0xd2, 0x20, 0x38, 0x31, 0x2b, 0xb9, 0xc9, 0xf1, 0x56, + 0xd2, 0xa7, 0xfd, 0x95, 0x55, 0x4d, 0xef, 0xe4, 0xce, 0xb3, 0xd6, 0xd2, 0x2b, + 0x19, 0xd2, 0xe8, 0x29, 0x1c, 0x05, 0xad, 0xd8, 0x81, 0x34, 0x2a, 0x39, 0x6e, + 0x7a, 0x30, 0x04, 0x05, 0xd5, 0x2c, 0xac, 0x0d, 0x1b, 0xb2, 0x06, 0x11, 0x06, + 0xc8, 0xe5, 0x3c, 0x29, 0x2c, 0xc9, 0xfb, 0x2d, 0x97, 0x2f, 0xc6, 0x40, 0x25, + 0x16, 0x2c, 0x1b, 0x1e, 0xd1, 0x1d, 0xdf, 0xf8, 0x6c, 0xd9, 0x16, 0x4a, 0x1c, + 0x1a, 0xea, 0xd5, 0xcb, 0xdd, 0x00, 0x04, 0xf0, 0xc0, 0x02, 0xfe, 0xf4, 0x2e, + 0x02, 0x46, 0xe0, 0xdf, 0xb2, 0x29, 0x17, 0xd4, 0xd7, 0x44, 0xdf, 0xfc, 0x07, + 0xee, 0x23, 0xff, 0x14, 0x1f, 0xdb, 0xb9, 0xa1, 0x04, 0xf1, 0x93, 0x01, 0xd9, + 0x82, 0x7f, 0xee, 0x65, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, + 0x00, 0xd8, 0x31, 0x7a, 0xbf, 0x55, 0x3c, 0x49, 0x68, 0xb3, 0xbd, 0x56, 0xe8, + 0xa8, 0xeb, 0x48, 0x81, 0xac, 0xd2, 0xdd, 0xbe, 0x4c, 0x93, 0x67, 0x4d, 0x48, + 0x95, 0x3b, 0x17, 0x3d, 0x7f, 0xe3, 0x22, 0x48, 0xe3, 0xbd, 0x52, 0xf6, 0x08, + 0x4e, 0xb2, 0x48, 0x36, 0xd1, 0x5b, 0x67, 0xab, 0xdd, 0xd9, 0x44, 0xdd, 0xe4, + 0x41, 0x29, 0xa9, 0x1b, 0x46, 0x81, 0x43, 0x60, 0x4a, 0x0f, 0x50, 0x61, 0x7f, + 0xcf, 0x5b, 0x7f, 0xb6, 0x74, 0x5b, 0x5e, 0x7f, 0x9b, 0x8e, 0x46, 0xb3, 0x91, + 0xe5, 0x7f, 0xca, 0xb0, 0x81, 0xc4, 0xbb, 0x73, 0xe7, 0x7f, 0x69, 0x6e, 0x81, + 0x5b, 0x32, 0x6f, 0x7e, 0xa6, 0x7f, 0x68, 0x97, 0xac, 0x61, 0xc6, 0xd1, 0x65, + 0xae, 0x66, 0xe8, 0x96, 0x7f, 0x72, 0x91, 0xb5, 0xd9, 0x4e, 0xb4, 0x43, 0x4c, + 0x7f, 0xd2, 0xe1, 0x5d, 0x12, 0x7f, 0x6b, 0x65, 0x27, 0x68, 0x74, 0xfa, 0xf6, + 0x35, 0x1f, 0xd8, 0x41, 0x13, 0x2c, 0x37, 0xf4, 0xb7, 0x0e, 0xc6, 0xd9, 0x1a, + 0x4b, 0x1a, 0xe9, 0xaf, 0xea, 0xd4, 0x3b, 0x52, 0x1b, 0x2c, 0x2b, 0xbd, 0x1c, + 0x2f, 0x2e, 0x18, 0xc1, 0x6d, 0x3a, 0xa3, 0xe3, 0x27, 0xc7, 0xca, 0x32, 0xd3, + 0x25, 0xdc, 0xad, 0x20, 0x17, 0xc9, 0xd4, 0xf8, 0x19, 0xea, 0x6b, 0x18, 0x40, + 0x0a, 0xd4, 0x23, 0x59, 0x51, 0x22, 0x2c, 0x20, 0x20, 0x29, 0x85, 0xaa, 0x60, + 0x73, 0x9e, 0x4d, 0x72, 0x5f, 0x6a, 0x86, 0xbe, 0x70, 0xc0, 0xb4, 0xa3, 0x5c, + 0xa7, 0x81, 0x25, 0x95, 0x81, 0x51, 0x99, 0x26, 0x5e, 0x7f, 0xb7, 0x48, 0x53, + 0x46, 0x6e, 0xbf, 0x35, 0x6c, 0xba, 0xa7, 0x7d, 0xbf, 0xc4, 0x51, 0x8d, 0x5e, + 0x7f, 0x97, 0x12, 0x6e, 0x87, 0xa1, 0x43, 0x59, 0xa7, 0x25, 0x59, 0xbe, 0x9a, + 0x60, 0x63, 0xb9, 0x0a, 0x5d, 0x4e, 0x46, 0x51, 0x69, 0x2e, 0x81, 0x7f, 0x7d, + 0x81, 0x7f, 0x7f, 0x7f, 0x64, 0x81, 0x81, 0x7f, 0x81, 0x81, 0x81, 0x69, 0x14, + 0x81, 0x27, 0x81, 0x91, 0x7f, 0x78, 0x1e, 0x7f, 0x5e, 0x91, 0x7f, 0x7f, 0x7f, + 0x58, 0x81, 0x77, 0x7f, 0x81, 0x81, 0x7f, 0x81, 0x9a, 0x7f, 0x81, 0x7f, 0x41, + 0x81, 0x63, 0x7f, 0x81, 0x81, 0x6a, 0x7f, 0x81, 0x78, 0x7f, 0x22, 0x81, 0x5b, + 0x7f, 0x48, 0x4c, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xd3, 0xcd, 0x40, 0x3d, 0xc6, + 0x4c, 0x1c, 0x3e, 0x20, 0xbe, 0xb5, 0x1a, 0xad, 0xb5, 0xda, 0x37, 0x4d, 0xda, + 0x07, 0xc3, 0xdd, 0x44, 0x7f, 0x0a, 0x3e, 0x19, 0xb3, 0x44, 0x45, 0x3c, 0xff, + 0xab, 0x4f, 0x3b, 0x91, 0xb1, 0x32, 0xba, 0xbc, 0x35, 0xc8, 0x2e, 0xab, 0xc9, + 0x46, 0x26, 0xbb, 0xcb, 0x3e, 0x39, 0xd5, 0x7f, 0x2c, 0xf4, 0xd5, 0x10, 0x2f, + 0x4f, 0x43, 0x3e, 0x43, 0x51, 0x33, 0x1f, 0xd4, 0xc5, 0x59, 0x16, 0xd0, 0x20, + 0x48, 0x18, 0x1b, 0xc6, 0xd8, 0x3c, 0xc2, 0xf8, 0xc6, 0x41, 0xfd, 0xc6, 0x2b, + 0xb9, 0xc5, 0x13, 0x95, 0xe2, 0x22, 0x32, 0x10, 0x1c, 0x3f, 0x1c, 0x09, 0xc3, + 0x12, 0x36, 0xf2, 0xcc, 0x4d, 0xaa, 0x81, 0x23, 0xbb, 0x28, 0x51, 0xc2, 0xbd, + 0xfe, 0xb7, 0xa6, 0x5c, 0x28, 0xcd, 0x3c, 0x24, 0xa7, 0xdd, 0x57, 0x25, 0xe8, + 0xbf, 0x23, 0x1c, 0x53, 0x18, 0x11, 0xc7, 0xaf, 0x57, 0x25, 0xb5, 0x2a, 0x35, + 0x2e, 0x02, 0xa9, 0xb4, 0x56, 0xaa, 0xaf, 0xa6, 0x2d, 0x2e, 0xb6, 0x43, 0xa7, + 0xd8, 0x1f, 0x65, 0xd6, 0x39, 0xf5, 0xf6, 0x36, 0x58, 0x25, 0xe9, 0xb1, 0x07, + 0x44, 0xb8, 0xae, 0x4c, 0xaa, 0xbe, 0x3e, 0xb4, 0x33, 0x40, 0xdd, 0xdb, 0xf1, + 0xc6, 0xb0, 0x7f, 0x39, 0xbf, 0x59, 0x40, 0xb8, 0x9e, 0x7f, 0x3e, 0x2d, 0xe4, + 0x3e, 0x4b, 0x61, 0x29, 0x19, 0xc7, 0xe3, 0x22, 0x0b, 0xeb, 0x12, 0x06, 0x1a, + 0x06, 0xca, 0xec, 0x1e, 0xea, 0xca, 0xc7, 0xf9, 0x30, 0xe7, 0x20, 0xc9, 0xfa, + 0x15, 0x28, 0x08, 0x20, 0xcc, 0x03, 0x23, 0x2e, 0x13, 0xfc, 0xe0, 0x06, 0x16, + 0xe1, 0xce, 0x2a, 0xe1, 0xdf, 0x2b, 0xf1, 0x14, 0xc8, 0x06, 0xf6, 0xf2, 0xe7, + 0xde, 0x44, 0x2b, 0xec, 0x38, 0x15, 0xcc, 0xda, 0x28, 0x1d, 0x0a, 0x07, 0x2e, + 0x26, 0x29, 0x14, 0x05, 0x22, 0x3a, 0x68, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0xd5, 0x4f, 0x00, 0x00, 0x93, 0xfe, 0xff, 0xff, 0x2a, + 0xf6, 0xff, 0xff, 0x5b, 0x51, 0x00, 0x00, 0x78, 0xfc, 0xff, 0xff, 0x1e, 0x01, + 0x00, 0x00, 0x43, 0xfe, 0xff, 0xff, 0xd9, 0xff, 0xff, 0xff, 0x2b, 0x3c, 0x00, + 0x00, 0xac, 0x31, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x43, 0x57, 0x00, 0x00, + 0xdf, 0x40, 0x00, 0x00, 0xe9, 0x56, 0x00, 0x00, 0x52, 0xe8, 0xff, 0xff, 0x43, + 0x14, 0x00, 0x00, 0xc8, 0x57, 0x00, 0x00, 0x09, 0x07, 0x00, 0x00, 0x2f, 0x59, + 0x00, 0x00, 0xd4, 0x3f, 0x00, 0x00, 0x9f, 0xfe, 0xff, 0xff, 0x3c, 0xf5, 0xff, + 0xff, 0x2b, 0xf0, 0xff, 0xff, 0xac, 0xfb, 0xff, 0xff, 0x72, 0xea, 0xff, 0xff, + 0xeb, 0x65, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xc3, 0xff, 0xff, 0xff, 0x2a, + 0x01, 0x00, 0x00, 0x2b, 0x0f, 0x00, 0x00, 0x7f, 0x53, 0x00, 0x00, 0x43, 0x01, + 0x00, 0x00, 0x4f, 0xee, 0xff, 0xff, 0x26, 0x46, 0x00, 0x00, 0x18, 0x26, 0x00, + 0x00, 0x11, 0x02, 0x00, 0x00, 0xb7, 0x3c, 0x00, 0x00, 0xea, 0x34, 0x00, 0x00, + 0xcb, 0xfe, 0xff, 0xff, 0x20, 0x6c, 0x00, 0x00, 0x7a, 0xff, 0xff, 0xff, 0xdb, + 0xf7, 0xff, 0xff, 0xc3, 0x57, 0x00, 0x00, 0xde, 0xff, 0xff, 0xff, 0x46, 0xfd, + 0xff, 0xff, 0xd4, 0x40, 0x00, 0x00, 0xbf, 0x58, 0x00, 0x00, 0x62, 0x00, 0x00, + 0x00, 0x55, 0xf7, 0xff, 0xff, 0xe7, 0x65, 0x00, 0x00, 0x0b, 0xe4, 0xff, 0xff, + 0x36, 0x00, 0x00, 0x00, 0x95, 0x08, 0x00, 0x00, 0x4d, 0x56, 0x00, 0x00, 0x0c, + 0xf5, 0xff, 0xff, 0xac, 0xff, 0xff, 0xff, 0x58, 0xfb, 0xff, 0xff, 0xec, 0xf8, + 0xff, 0xff, 0x83, 0xf0, 0xff, 0xff, 0xa1, 0xe1, 0xff, 0xff, 0x43, 0xf8, 0xff, + 0xff, 0xfa, 0xff, 0xff, 0xff, 0x14, 0x02, 0x00, 0x00, 0x9f, 0x11, 0x00, 0x00, + 0x46, 0x69, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x35, + 0x0c, 0xc2, 0x04, 0x56, 0x1a, 0x14, 0x2f, 0x49, 0xe0, 0x11, 0x00, 0x14, 0xdf, + 0xfb, 0x14, 0x07, 0xed, 0x61, 0x4f, 0x08, 0x00, 0x29, 0xf1, 0xd7, 0x0d, 0x9d, + 0xb3, 0x0a, 0x36, 0x00, 0x81, 0x95, 0x0e, 0x01, 0x08, 0x18, 0xda, 0xeb, 0x46, + 0x21, 0x46, 0xc0, 0xe6, 0x35, 0x28, 0x2c, 0x00, 0x1d, 0xe5, 0xc1, 0xfa, 0x3f, + 0xd3, 0x0a, 0x12, 0x04, 0xf0, 0xd8, 0xe6, 0xce, 0x42, 0xfa, 0x0f, 0xe3, 0x04, + 0x7f, 0x1c, 0xea, 0xda, 0xbb, 0xde, 0xdb, 0xe1, 0x41, 0x33, 0xfd, 0x27, 0x42, + 0xd1, 0xc6, 0xe0, 0xe1, 0xed, 0x25, 0x0e, 0xf0, 0xfb, 0x13, 0x0c, 0x41, 0x15, + 0x4b, 0x20, 0x16, 0xae, 0x1a, 0xe9, 0xee, 0xf8, 0x17, 0xfc, 0x24, 0xb2, 0x0d, + 0xfd, 0x2a, 0x12, 0xbf, 0xf4, 0xe6, 0x41, 0xba, 0xe8, 0x4d, 0x0c, 0x61, 0xdd, + 0xff, 0xb4, 0xe5, 0xc5, 0x1f, 0xeb, 0xf8, 0xe1, 0xaf, 0x01, 0xf7, 0x15, 0xee, + 0xeb, 0xec, 0x08, 0xf5, 0xe4, 0xfe, 0xe1, 0xe8, 0xf2, 0x06, 0xd9, 0x11, 0xfa, + 0x17, 0x03, 0xea, 0x14, 0xef, 0x1b, 0xeb, 0x0b, 0xdb, 0xd0, 0x1b, 0x0d, 0x7f, + 0x13, 0x16, 0xf7, 0xcb, 0xe0, 0x16, 0x0d, 0xcb, 0xd6, 0x04, 0xdf, 0x31, 0x24, + 0xf8, 0x16, 0x51, 0xd1, 0xf5, 0x13, 0x09, 0xd7, 0xea, 0xf4, 0x10, 0x09, 0x12, + 0x21, 0x0d, 0xf7, 0xcd, 0xe8, 0xd6, 0x23, 0x1d, 0x2b, 0xd9, 0x01, 0x1d, 0x11, + 0xf3, 0x7f, 0x08, 0xf4, 0x06, 0x0d, 0x02, 0x09, 0xd8, 0xf1, 0x1b, 0x02, 0xe7, + 0x26, 0x14, 0xe3, 0xe3, 0xfd, 0x03, 0xf1, 0xf0, 0x1a, 0x25, 0xec, 0x07, 0xe7, + 0x1f, 0xf4, 0xd1, 0xb1, 0xea, 0x12, 0x06, 0x19, 0x30, 0xd5, 0x1e, 0xf5, 0xef, + 0x22, 0x09, 0xea, 0x1f, 0xff, 0xf4, 0xf7, 0x01, 0xf2, 0x1b, 0x0c, 0x16, 0x17, + 0x0e, 0xf7, 0xe2, 0xd4, 0x0e, 0xda, 0xd4, 0x1c, 0x01, 0x30, 0xe8, 0x14, 0xfb, + 0x1f, 0xc0, 0x2f, 0x2b, 0xf7, 0xd4, 0x4e, 0x81, 0x3d, 0x9f, 0x3d, 0x0f, 0x5c, + 0x0a, 0xdb, 0x28, 0xf6, 0xd3, 0x10, 0xd5, 0x03, 0x07, 0x8f, 0xba, 0x4b, 0x12, + 0xd6, 0xed, 0xdb, 0xfa, 0xe6, 0xea, 0xbf, 0x17, 0xd0, 0xde, 0x2a, 0x03, 0x10, + 0xeb, 0xea, 0x35, 0xeb, 0x1b, 0x08, 0x0a, 0x26, 0x23, 0xb9, 0x3c, 0x21, 0x0c, + 0xee, 0x00, 0x39, 0x09, 0x22, 0x92, 0xc8, 0xe7, 0xfe, 0x3d, 0xf7, 0x13, 0xf5, + 0xf1, 0x19, 0xfd, 0x16, 0xeb, 0x07, 0x0e, 0xdc, 0x24, 0x0f, 0xa6, 0x1d, 0xeb, + 0xd2, 0x39, 0x03, 0xd4, 0xf2, 0xdb, 0xdf, 0x1f, 0xd6, 0xf6, 0xf8, 0x0c, 0xb0, + 0xee, 0xfc, 0xee, 0xb3, 0xf3, 0xd4, 0xd4, 0xe5, 0xeb, 0x23, 0x19, 0xf4, 0x02, + 0xc4, 0x64, 0xee, 0x7f, 0x20, 0x0e, 0xf6, 0xfc, 0x0d, 0xde, 0x54, 0x13, 0x1c, + 0xf5, 0x05, 0x07, 0xe1, 0xf9, 0xfe, 0x1d, 0xeb, 0xb1, 0x31, 0xd3, 0x12, 0xbc, + 0x72, 0xe3, 0xd9, 0xbc, 0x2b, 0x04, 0x03, 0x69, 0x23, 0x38, 0xf5, 0xb1, 0x40, + 0x1b, 0x0c, 0xa8, 0xf9, 0xe6, 0xc6, 0xe6, 0x08, 0xe4, 0x74, 0x42, 0x1b, 0xcb, + 0xf0, 0x26, 0xf4, 0xed, 0x19, 0xf8, 0x0c, 0x12, 0x1d, 0xbf, 0xfa, 0x12, 0x50, + 0xeb, 0x22, 0x2e, 0x1e, 0x02, 0xeb, 0x7f, 0x91, 0xd6, 0xe6, 0xff, 0x15, 0x08, + 0xe2, 0xf7, 0x0a, 0x09, 0xfa, 0x12, 0x19, 0x02, 0xd3, 0xb4, 0xd9, 0xeb, 0xba, + 0x22, 0xe0, 0x05, 0x25, 0xec, 0xd9, 0xc4, 0xe7, 0xce, 0xea, 0xf0, 0x03, 0x42, + 0x58, 0x3a, 0xfb, 0xf9, 0x12, 0x2c, 0xdd, 0x4d, 0x5c, 0x2d, 0x32, 0xde, 0xe8, + 0x01, 0xfb, 0xcf, 0x14, 0xd1, 0xec, 0xe4, 0xf7, 0x23, 0xbc, 0xb4, 0xd6, 0xe7, + 0xef, 0x7f, 0xef, 0xa2, 0xc0, 0x2c, 0xe4, 0x07, 0xf7, 0x3e, 0xc0, 0x42, 0x3f, + 0x7b, 0xc6, 0xd4, 0x43, 0x15, 0x06, 0x30, 0xf4, 0x58, 0x16, 0x14, 0xd0, 0x28, + 0x16, 0xd1, 0x22, 0x0a, 0x1a, 0xfa, 0x08, 0xf0, 0x2c, 0x18, 0xee, 0xc7, 0xf5, + 0xe1, 0xfa, 0xfa, 0xfb, 0xfa, 0xbe, 0xe9, 0x0d, 0x15, 0xe7, 0xc6, 0xfc, 0xfd, + 0x09, 0xee, 0xe3, 0xf7, 0x2a, 0x1a, 0x03, 0x23, 0x19, 0x00, 0xea, 0x13, 0xec, + 0x3f, 0x10, 0xf6, 0x1f, 0x48, 0x7f, 0x10, 0x11, 0xf4, 0x21, 0x04, 0x0d, 0x13, + 0x04, 0xd8, 0xf5, 0x21, 0x2c, 0xb6, 0x28, 0x3a, 0xe9, 0xeb, 0x57, 0x2a, 0x59, + 0x28, 0x19, 0x29, 0xb5, 0x4c, 0xd1, 0xf8, 0xd5, 0xfa, 0x01, 0xff, 0xeb, 0x18, + 0x81, 0xfc, 0xe2, 0xfd, 0xea, 0xde, 0x16, 0x1c, 0xed, 0x5e, 0x27, 0x07, 0xd2, + 0x2e, 0xe4, 0x0e, 0x24, 0xf9, 0xc5, 0x3b, 0xde, 0xfc, 0x13, 0x37, 0x9f, 0xfc, + 0xe1, 0xee, 0x12, 0x0f, 0x07, 0x1a, 0xe1, 0xe7, 0xf8, 0x33, 0xda, 0x23, 0xb6, + 0xcd, 0xde, 0xdf, 0x01, 0x65, 0xab, 0x15, 0xf5, 0x26, 0xff, 0xe5, 0xbd, 0x1d, + 0x39, 0x23, 0x11, 0xd5, 0xb3, 0x27, 0xed, 0x17, 0x21, 0xd9, 0x22, 0xd5, 0x01, + 0x3c, 0xf8, 0xf7, 0x2a, 0x7f, 0xf7, 0xdd, 0xeb, 0x23, 0x0f, 0x0e, 0x45, 0xd2, + 0x25, 0x75, 0xe2, 0xb0, 0xe7, 0x04, 0x14, 0x1a, 0xe0, 0x95, 0xec, 0xef, 0xad, + 0xde, 0x4c, 0x03, 0x05, 0x3a, 0xce, 0x21, 0xdc, 0xbc, 0x4c, 0x9b, 0xf2, 0x23, + 0x02, 0x15, 0x17, 0xfd, 0xea, 0x0e, 0x0e, 0xc0, 0x54, 0xfb, 0x05, 0x02, 0xd2, + 0xdc, 0xf3, 0x25, 0xe1, 0x1e, 0x22, 0xf3, 0x04, 0x9d, 0xe7, 0xfd, 0x19, 0x05, + 0x37, 0x05, 0xd4, 0xc2, 0xc3, 0x1a, 0x40, 0xee, 0xe0, 0xfb, 0xdb, 0xe3, 0x11, + 0x4e, 0x2c, 0x26, 0x10, 0xdc, 0x2e, 0xfb, 0xed, 0x06, 0x17, 0xeb, 0xda, 0x11, + 0xd1, 0xef, 0x37, 0x10, 0x7f, 0x01, 0x12, 0x09, 0xde, 0xe0, 0x14, 0x04, 0x0d, + 0x21, 0xea, 0x2e, 0xb7, 0x1b, 0x00, 0xeb, 0xf0, 0xe7, 0x2c, 0x24, 0x79, 0x1f, + 0xf0, 0xe0, 0xdc, 0x18, 0xd3, 0xdd, 0x03, 0x1c, 0x05, 0xd7, 0xe9, 0x21, 0xd4, + 0xe0, 0x43, 0x2e, 0x0a, 0xf3, 0x09, 0x1a, 0x30, 0x65, 0xe8, 0x3c, 0x20, 0x1d, + 0x0f, 0xf2, 0xb7, 0xfc, 0xd5, 0x7f, 0xbb, 0xff, 0xa9, 0xe9, 0xd4, 0x3b, 0x36, + 0x18, 0x30, 0xd7, 0xe2, 0xfd, 0x01, 0x9d, 0x39, 0x08, 0xfb, 0xa9, 0x32, 0xb6, + 0xff, 0xe8, 0x2f, 0xb9, 0x58, 0x5c, 0x15, 0xd3, 0xb9, 0x02, 0x19, 0x81, 0xe9, + 0xc3, 0x18, 0x4e, 0xeb, 0x57, 0xbf, 0xb5, 0x2a, 0xdc, 0xc6, 0xe6, 0xff, 0xe6, + 0xed, 0x67, 0x30, 0xa6, 0x5f, 0xad, 0x09, 0xce, 0xd8, 0x17, 0xc7, 0x0e, 0x06, + 0xc2, 0xff, 0x0f, 0x1e, 0x01, 0xb0, 0x37, 0xff, 0xdd, 0x29, 0xec, 0xf2, 0x06, + 0xd4, 0x0c, 0xe1, 0xfb, 0xda, 0x24, 0xfd, 0x08, 0x5a, 0xfd, 0x14, 0xff, 0x0c, + 0xf4, 0xe7, 0xa4, 0xe4, 0x07, 0xed, 0xed, 0xbe, 0x2d, 0x2f, 0xad, 0xeb, 0x11, + 0xde, 0x0d, 0x2d, 0x58, 0x0d, 0xa2, 0x01, 0xf9, 0x06, 0xb7, 0xd6, 0xcf, 0x99, + 0xfd, 0x62, 0xfb, 0x38, 0xbe, 0x88, 0x35, 0x39, 0xf5, 0xf6, 0xec, 0xff, 0xfa, + 0xfb, 0xbd, 0x36, 0xba, 0x0d, 0x30, 0x50, 0x12, 0x28, 0x22, 0x81, 0x00, 0xd7, + 0xff, 0xfd, 0xf1, 0xb6, 0xf1, 0xb1, 0xf3, 0x38, 0xdb, 0x30, 0x48, 0x1b, 0x1a, + 0xd4, 0xd8, 0x22, 0xfb, 0x13, 0xdd, 0xec, 0xe6, 0xf0, 0xf6, 0x56, 0x08, 0xc8, + 0x0a, 0x1e, 0x4e, 0x1e, 0xac, 0x07, 0x02, 0x52, 0xf6, 0xd6, 0x59, 0xb5, 0x01, + 0xf0, 0x18, 0xcf, 0xfa, 0x1f, 0x22, 0x7f, 0x1b, 0xee, 0x79, 0x00, 0x00, 0x03, + 0xe8, 0xca, 0x14, 0xf7, 0xf4, 0xc5, 0xf7, 0x2e, 0x31, 0xd8, 0x03, 0xe9, 0x0c, + 0xf9, 0x1a, 0x32, 0x7c, 0xc5, 0xd7, 0x1c, 0xf7, 0x1c, 0xa8, 0x19, 0xbc, 0x0f, + 0x08, 0x3b, 0x0a, 0xa6, 0x2a, 0x0a, 0x0d, 0xd0, 0xb0, 0xf6, 0xfc, 0x14, 0xa7, + 0xe4, 0x1b, 0x34, 0x1d, 0x00, 0x06, 0x5f, 0xb6, 0x13, 0x38, 0xfc, 0x16, 0xed, + 0xff, 0xb3, 0x81, 0xf4, 0x2e, 0x2f, 0xc1, 0xeb, 0x03, 0x36, 0x2c, 0xd6, 0xf4, + 0x64, 0x5c, 0xe2, 0x48, 0xb6, 0xe3, 0x2d, 0xf9, 0xce, 0xe0, 0x11, 0x1f, 0x1f, + 0xaf, 0xe9, 0x1b, 0x43, 0xe3, 0x35, 0x4c, 0xf9, 0x68, 0xda, 0x24, 0xfa, 0x0b, + 0x50, 0xf9, 0xca, 0x16, 0xdd, 0x28, 0x0b, 0xf6, 0x49, 0x10, 0x0d, 0xdb, 0x0e, + 0x0c, 0x0c, 0xec, 0xfb, 0xfc, 0x0c, 0x1e, 0xef, 0xd7, 0xca, 0xb8, 0xea, 0x0b, + 0x0e, 0xc1, 0xed, 0xf5, 0xc6, 0xeb, 0x04, 0x7f, 0x01, 0xcb, 0x17, 0xff, 0xe1, + 0x7e, 0xfd, 0xed, 0x19, 0x0e, 0x17, 0x1c, 0x09, 0x2a, 0xe7, 0xe9, 0x10, 0xe5, + 0xe6, 0x25, 0xc7, 0xe6, 0xeb, 0xd0, 0xe4, 0xec, 0xdb, 0xd7, 0xf4, 0xfb, 0xd2, + 0x08, 0xfa, 0xf0, 0xe9, 0xf6, 0xd9, 0xf0, 0x12, 0xea, 0x1a, 0x11, 0x04, 0xef, + 0xed, 0x08, 0xfe, 0x00, 0xca, 0xe5, 0xd5, 0x1f, 0xef, 0x18, 0x7f, 0x2e, 0x13, + 0x10, 0x13, 0xf8, 0xf5, 0xed, 0x0c, 0xf6, 0xd8, 0xe7, 0x02, 0xd0, 0x12, 0xdd, + 0xf1, 0xda, 0xfc, 0xe8, 0xfa, 0xd4, 0xeb, 0xe8, 0xd8, 0xe3, 0xe2, 0x16, 0xed, + 0x2f, 0x07, 0x22, 0xfd, 0xfa, 0xf3, 0xee, 0xfb, 0xfe, 0xed, 0x47, 0xac, 0xe7, + 0xc6, 0x05, 0x01, 0xcc, 0x1e, 0x03, 0x09, 0x1a, 0x4a, 0xea, 0xef, 0xe5, 0xf4, + 0xe6, 0x19, 0x2c, 0x36, 0x07, 0x81, 0x34, 0xde, 0x1e, 0xfa, 0x2f, 0xe7, 0xfb, + 0xeb, 0x0d, 0x18, 0x1c, 0xee, 0xcf, 0xec, 0xe6, 0x20, 0xca, 0x12, 0xf3, 0xea, + 0x22, 0xe7, 0xee, 0xdb, 0x0e, 0xec, 0xfb, 0x0a, 0xf1, 0x0a, 0xdd, 0x3b, 0xe9, + 0xf2, 0x15, 0xf3, 0x29, 0xfd, 0xe7, 0x14, 0xf8, 0xfe, 0xe9, 0xd7, 0x1c, 0x7f, + 0xe6, 0xe1, 0xfa, 0xf3, 0x17, 0xff, 0xf5, 0xda, 0xe6, 0x21, 0xe9, 0x22, 0xd3, + 0xb4, 0x0f, 0xff, 0x04, 0x07, 0xff, 0xf0, 0xe3, 0xf1, 0x26, 0x45, 0xf0, 0xf9, + 0xf8, 0xe6, 0x0c, 0x26, 0xc4, 0xcb, 0xd5, 0xfe, 0xf3, 0x0b, 0xcd, 0xf7, 0xea, + 0xf2, 0x04, 0x15, 0xde, 0xf1, 0x1b, 0xfb, 0x26, 0x18, 0x12, 0xff, 0xfa, 0x10, + 0x38, 0x14, 0xf4, 0x0b, 0xc0, 0xe8, 0xf8, 0x30, 0xbd, 0x28, 0xc0, 0x3f, 0xde, + 0xe2, 0xec, 0x13, 0xde, 0x32, 0xd7, 0xf4, 0x1c, 0xd7, 0xf2, 0xf7, 0xf2, 0xdc, + 0xd5, 0xc1, 0xef, 0xaa, 0x3f, 0x0b, 0x13, 0x1b, 0xbb, 0x19, 0xd1, 0x04, 0xf5, + 0x7f, 0xd3, 0x03, 0x03, 0x3c, 0x1b, 0x12, 0x1e, 0x14, 0xcd, 0x0a, 0xd9, 0x31, + 0x3e, 0x47, 0xf1, 0xfe, 0x04, 0x04, 0xe2, 0x23, 0x00, 0xe8, 0x41, 0x08, 0xbf, + 0xa7, 0xf1, 0xe7, 0x12, 0xc9, 0x33, 0xe3, 0x0e, 0xeb, 0x98, 0xaa, 0xec, 0xf5, + 0x7f, 0x01, 0x01, 0xdc, 0xed, 0xee, 0x36, 0x20, 0xfd, 0xe4, 0xf6, 0x05, 0xed, + 0x14, 0xe2, 0xec, 0xe9, 0xec, 0xf4, 0x3b, 0xee, 0x22, 0x00, 0x1f, 0xe5, 0xed, + 0xe2, 0x03, 0x08, 0xdd, 0x00, 0x56, 0x28, 0xdc, 0x09, 0xc0, 0xef, 0xdd, 0xec, + 0xf8, 0xe2, 0xdb, 0x10, 0xf6, 0x05, 0xfe, 0x18, 0xdd, 0x1a, 0x02, 0xf8, 0x93, + 0xbc, 0x0e, 0x3e, 0x0d, 0xe4, 0xaa, 0x03, 0xdd, 0xe3, 0x44, 0xe4, 0x39, 0x07, + 0xdd, 0xe8, 0xfc, 0x33, 0x12, 0xfd, 0xf4, 0x2c, 0xda, 0xf7, 0x02, 0xe9, 0x1c, + 0x0c, 0x31, 0x22, 0x1d, 0x15, 0x30, 0xf1, 0xc6, 0xfc, 0xe7, 0x7f, 0xf3, 0x02, + 0xef, 0x1d, 0x31, 0xf9, 0xe2, 0xc3, 0xf9, 0x1f, 0x0f, 0x22, 0x12, 0xf5, 0x3a, + 0xe4, 0x07, 0x0b, 0xea, 0xdf, 0xe3, 0x1b, 0xe2, 0x24, 0x04, 0x74, 0x22, 0xb9, + 0x34, 0x18, 0xe2, 0xcd, 0xf4, 0x46, 0xd4, 0xf2, 0x1d, 0xf7, 0xe6, 0xea, 0x1a, + 0xfd, 0x17, 0xfb, 0x28, 0xee, 0xf7, 0x03, 0xfa, 0xea, 0x0b, 0xde, 0xef, 0xf1, + 0xdf, 0xf7, 0x0e, 0xff, 0x00, 0x0e, 0x1f, 0x02, 0x36, 0x1b, 0x7f, 0x14, 0xf3, + 0x1e, 0xf7, 0xd7, 0x26, 0xe5, 0xfc, 0xfb, 0xea, 0xce, 0xd8, 0xe9, 0x00, 0xc5, + 0x2e, 0xea, 0x30, 0xe3, 0xfc, 0xf9, 0xfc, 0xa2, 0xfa, 0xcb, 0x3f, 0xfa, 0x0f, + 0x08, 0xa1, 0x20, 0x05, 0x21, 0x81, 0x2d, 0xd4, 0x04, 0x82, 0xc1, 0xa9, 0xa6, + 0xbd, 0xfe, 0xcb, 0xf9, 0x01, 0x18, 0x2b, 0x17, 0x0a, 0xc1, 0xf2, 0x37, 0xdc, + 0xb3, 0xf0, 0xd2, 0x4a, 0x37, 0xfe, 0xa4, 0xc1, 0xe1, 0xc6, 0x36, 0xed, 0x04, + 0xdf, 0x18, 0x01, 0xc4, 0x13, 0xfd, 0x39, 0x1f, 0xb5, 0xe0, 0x44, 0x07, 0x9f, + 0xe2, 0x81, 0x60, 0xbe, 0xd5, 0x15, 0xd6, 0xb5, 0xf0, 0x3b, 0xbb, 0x00, 0x06, + 0x03, 0x57, 0x08, 0x13, 0x10, 0x1f, 0x2d, 0x09, 0x13, 0x17, 0xd8, 0xac, 0xd4, + 0x0f, 0xf8, 0x0a, 0xdf, 0xc0, 0x14, 0xc3, 0xf6, 0xcd, 0xfb, 0x25, 0xf2, 0x0f, + 0xf4, 0x03, 0xf2, 0xc0, 0xf0, 0xeb, 0x24, 0xf6, 0xf8, 0x2c, 0xdb, 0x16, 0xf9, + 0x23, 0x15, 0x36, 0x05, 0xbf, 0x06, 0x58, 0xb3, 0x05, 0x65, 0x28, 0x7f, 0xfa, + 0xe0, 0x1b, 0xe2, 0xf8, 0x35, 0x1d, 0x62, 0x29, 0xc8, 0x0f, 0x06, 0x06, 0xfa, + 0x22, 0x07, 0xb3, 0xe0, 0x1b, 0xcc, 0x14, 0xe3, 0xdd, 0xfa, 0xf6, 0x0a, 0xe8, + 0xe5, 0xec, 0xfa, 0x2a, 0x17, 0xd2, 0x47, 0x11, 0xf2, 0x13, 0xe8, 0x1d, 0x3c, + 0x7c, 0xc6, 0xbc, 0x0f, 0xfb, 0xec, 0xfd, 0x18, 0x81, 0xc9, 0xe9, 0x0e, 0xee, + 0x06, 0xf3, 0x1f, 0x25, 0xfc, 0x11, 0x74, 0x06, 0xe4, 0xd7, 0x04, 0x0b, 0x1e, + 0x0a, 0xfc, 0x55, 0xc9, 0xdc, 0x12, 0xe1, 0xfe, 0x19, 0xd2, 0xda, 0xd2, 0xa2, + 0xea, 0x34, 0x20, 0x0d, 0x42, 0x05, 0x0a, 0xc1, 0xb1, 0xce, 0x11, 0xb6, 0x02, + 0x01, 0x29, 0x1f, 0xd8, 0x40, 0xe3, 0x62, 0xc7, 0x14, 0x09, 0xd1, 0xef, 0x11, + 0x3d, 0xed, 0xc0, 0xc1, 0xe9, 0xe9, 0x13, 0x3f, 0x23, 0x81, 0x16, 0xd3, 0x0c, + 0xde, 0x40, 0xf2, 0x1e, 0x3e, 0x13, 0xfe, 0xd2, 0xeb, 0xdf, 0x10, 0xda, 0xdb, + 0x13, 0x03, 0x11, 0xad, 0xdf, 0xf6, 0x06, 0x56, 0x10, 0x10, 0xd7, 0xfa, 0xbe, + 0xf9, 0x12, 0xfb, 0x31, 0xe0, 0x0b, 0x30, 0xd9, 0xe9, 0x08, 0xea, 0x0d, 0xce, + 0x0f, 0x23, 0xf1, 0x03, 0xf8, 0xe8, 0xfe, 0xdf, 0xce, 0x29, 0xfb, 0xec, 0xcc, + 0x2c, 0xc0, 0xcd, 0xec, 0x13, 0x7f, 0xf4, 0x18, 0xd1, 0x0a, 0xc1, 0xfb, 0xfe, + 0x05, 0xe6, 0x0f, 0x0c, 0xfb, 0x0f, 0x30, 0x13, 0xe1, 0xd4, 0xf2, 0xea, 0xde, + 0xfe, 0x2c, 0xf9, 0xde, 0x18, 0x16, 0xf9, 0xea, 0xe1, 0x2e, 0x1e, 0xdc, 0xed, + 0x3c, 0x07, 0xfa, 0x06, 0x13, 0xfd, 0xcf, 0x04, 0xf3, 0x15, 0x0d, 0x81, 0xe5, + 0x08, 0xb8, 0xc8, 0xf6, 0xea, 0x14, 0xf7, 0xef, 0xea, 0x43, 0x19, 0xeb, 0x3d, + 0xf9, 0x1b, 0xb7, 0x0b, 0x14, 0x0e, 0xed, 0xd5, 0xf9, 0xb7, 0x10, 0xe5, 0x4b, + 0xee, 0xd2, 0x17, 0xf2, 0x14, 0x25, 0xfa, 0xd8, 0x05, 0x06, 0xd1, 0x17, 0xf8, + 0xf7, 0xc6, 0xc9, 0xbc, 0xfd, 0xe5, 0xf9, 0xd3, 0xd2, 0xcb, 0xd4, 0xce, 0x0a, + 0xc9, 0xd3, 0xfe, 0xb3, 0x5e, 0x0d, 0xf5, 0x0c, 0xcd, 0x1c, 0x7f, 0xe8, 0x9a, + 0x15, 0x63, 0x30, 0x08, 0x3b, 0x0a, 0x26, 0x9e, 0x26, 0x5c, 0x6e, 0xe5, 0x6a, + 0xcd, 0xdc, 0x04, 0xf0, 0xe9, 0xeb, 0xf8, 0x20, 0xbe, 0x2e, 0xdc, 0x11, 0x01, + 0xb0, 0xce, 0x2f, 0x1f, 0xe0, 0xf6, 0xa3, 0xf2, 0xb4, 0xe2, 0x1a, 0x32, 0x16, + 0xdf, 0x42, 0xe7, 0x07, 0xd6, 0x38, 0xda, 0xc7, 0xcd, 0xeb, 0xf5, 0xdc, 0xff, + 0xed, 0x2d, 0x15, 0x17, 0x17, 0x27, 0x02, 0x03, 0x2e, 0x04, 0xea, 0x2e, 0xf4, + 0x7f, 0xdd, 0x04, 0x1c, 0x5d, 0xce, 0xd0, 0x00, 0x1f, 0xf5, 0xf2, 0x16, 0x72, + 0x07, 0xe0, 0x11, 0x30, 0x1d, 0xd6, 0x0e, 0x2d, 0x22, 0x7d, 0x0e, 0x00, 0xf0, + 0xff, 0xcc, 0x5a, 0xcb, 0x19, 0xfc, 0xd2, 0x9d, 0xe3, 0xce, 0x14, 0xfb, 0x4b, + 0x0e, 0xd4, 0xd9, 0xde, 0x1b, 0xa2, 0x00, 0xbc, 0xcf, 0xbf, 0x0a, 0xfc, 0xef, + 0x3f, 0x46, 0x40, 0x41, 0x10, 0x1e, 0xfe, 0x46, 0xe7, 0xce, 0xf8, 0xc3, 0x54, + 0x12, 0x60, 0xd2, 0xf3, 0xeb, 0xc2, 0xfb, 0x32, 0x63, 0x42, 0xd4, 0x41, 0xbf, + 0x41, 0x38, 0xe5, 0x38, 0xea, 0xdf, 0xf8, 0x07, 0x84, 0xb9, 0xf3, 0xe3, 0xcf, + 0xef, 0xcd, 0xc6, 0x34, 0xbd, 0x2c, 0x97, 0xc9, 0x81, 0x07, 0xd0, 0x2e, 0x10, + 0x13, 0xc3, 0xb0, 0x07, 0x05, 0xcb, 0xf0, 0xf8, 0x17, 0x19, 0x15, 0xe9, 0xfe, + 0xe2, 0x29, 0xfa, 0x3d, 0xb8, 0x01, 0xcd, 0x2f, 0xee, 0x04, 0xd8, 0xf6, 0xf8, + 0x5f, 0x98, 0xff, 0xd8, 0xd4, 0x54, 0x6a, 0xe9, 0x2c, 0x39, 0xee, 0x10, 0x19, + 0x19, 0xf8, 0xe8, 0xce, 0xf7, 0xfc, 0xb8, 0x14, 0xd8, 0x6c, 0x19, 0x30, 0x2c, + 0xf5, 0xbe, 0x24, 0xf2, 0xfb, 0xf2, 0xfc, 0xe3, 0xe2, 0xc3, 0xc1, 0xba, 0xaa, + 0x7f, 0x53, 0x08, 0x47, 0xf5, 0x2f, 0xfe, 0x54, 0x14, 0xba, 0x17, 0xea, 0x1c, + 0xff, 0xb6, 0x0e, 0xec, 0x1c, 0xf8, 0x32, 0xd8, 0xce, 0x24, 0x51, 0xe7, 0x1b, + 0x62, 0x60, 0x00, 0xc4, 0xd1, 0xc5, 0xcb, 0xca, 0xba, 0xc0, 0x00, 0x02, 0xfc, + 0x25, 0x9e, 0xff, 0x3f, 0xf6, 0x11, 0x41, 0xf0, 0xf4, 0x26, 0x10, 0x0b, 0xd2, + 0xfc, 0x00, 0x7f, 0x5b, 0x1d, 0xc3, 0x36, 0xc5, 0x3d, 0xfe, 0x10, 0x49, 0x48, + 0xdb, 0xc0, 0x0f, 0xa4, 0x42, 0x96, 0x31, 0xbc, 0xd2, 0x2d, 0x2e, 0x59, 0x24, + 0xe4, 0x0c, 0x22, 0x4d, 0x0b, 0xae, 0xf6, 0xeb, 0xc8, 0x09, 0x02, 0xde, 0x30, + 0x08, 0xbb, 0x3f, 0x3e, 0xbe, 0x0f, 0x09, 0x1b, 0xe8, 0x01, 0x3a, 0x73, 0xe9, + 0x2b, 0xe4, 0x25, 0xec, 0x05, 0x1a, 0x20, 0x13, 0xe9, 0xf8, 0xca, 0xfb, 0x0e, + 0xe7, 0x30, 0xe7, 0x22, 0x1b, 0xd6, 0xe7, 0x5d, 0x7f, 0xce, 0xc2, 0xcf, 0xc8, + 0xfd, 0xe9, 0x6e, 0x00, 0xe9, 0x4b, 0x2b, 0x91, 0xd6, 0xf4, 0xf4, 0x21, 0xbd, + 0xa6, 0x2c, 0xe6, 0xf3, 0xea, 0x1c, 0x0e, 0x07, 0x69, 0xee, 0xd7, 0xf4, 0xf3, + 0xed, 0x14, 0xc5, 0xf0, 0xea, 0xf5, 0xed, 0x0b, 0x35, 0x22, 0xd6, 0x0b, 0xd6, + 0xcc, 0x1c, 0x21, 0x37, 0x05, 0x1c, 0xdd, 0xd0, 0x18, 0xe8, 0x9d, 0x6b, 0x12, + 0x1c, 0x13, 0x4c, 0xdb, 0x3a, 0xee, 0xcb, 0x7f, 0x07, 0xf6, 0xe0, 0x98, 0x01, + 0x0d, 0x31, 0xdb, 0x1c, 0xb9, 0x0c, 0xe0, 0x14, 0xd0, 0x00, 0xe4, 0xda, 0xe8, + 0x3b, 0xcc, 0x04, 0xe3, 0x0d, 0x38, 0xf3, 0xfe, 0xf5, 0xe5, 0x3f, 0xc6, 0xcc, + 0x1c, 0x35, 0xe2, 0xf9, 0x14, 0x1e, 0xb7, 0x03, 0xd5, 0x7f, 0x0a, 0x25, 0x21, + 0x41, 0x32, 0x1d, 0xed, 0x24, 0xfc, 0x22, 0x3a, 0x19, 0xef, 0x11, 0xf5, 0xf7, + 0x0e, 0x30, 0xf6, 0xed, 0x25, 0x1d, 0x77, 0x00, 0xf0, 0xe2, 0x08, 0xf5, 0x28, + 0x7f, 0x16, 0x3d, 0xc9, 0x1b, 0xf3, 0xf0, 0xf1, 0x16, 0x82, 0x10, 0xcb, 0xf2, + 0x2f, 0xef, 0xd9, 0xdd, 0x02, 0xfd, 0xeb, 0x08, 0xf7, 0x21, 0xfd, 0xf6, 0xf1, + 0x0f, 0xd2, 0xd8, 0x10, 0xf0, 0xe1, 0xe5, 0xd3, 0xf1, 0x0a, 0xfd, 0x19, 0x58, + 0xf5, 0x27, 0xf5, 0x32, 0xd2, 0xe5, 0x34, 0xeb, 0x23, 0x5a, 0xf8, 0x23, 0x03, + 0xda, 0x00, 0x15, 0x15, 0x27, 0x33, 0xf7, 0x04, 0xe7, 0xe5, 0x10, 0xf1, 0x2f, + 0x06, 0x0e, 0xcc, 0xd9, 0x09, 0x0d, 0xb7, 0x26, 0x20, 0xfb, 0x0e, 0xc6, 0x01, + 0xf2, 0xe2, 0xee, 0xc6, 0x2b, 0x9f, 0xd2, 0x20, 0x02, 0xed, 0xda, 0x2f, 0xe0, + 0xf1, 0xf8, 0x11, 0x4e, 0xb8, 0x1d, 0xea, 0xf2, 0xee, 0xf8, 0x05, 0x23, 0xf8, + 0xdc, 0xa0, 0x59, 0x24, 0xe1, 0xe9, 0xd9, 0x0e, 0xf8, 0xe7, 0xe4, 0x4e, 0x35, + 0x0c, 0x7f, 0xdd, 0xba, 0xe0, 0xc6, 0xb6, 0x44, 0x16, 0xe1, 0x13, 0xe3, 0x38, + 0xf8, 0xe7, 0x16, 0xae, 0xdc, 0xdf, 0xcd, 0x45, 0xde, 0xfb, 0x3f, 0xd3, 0x06, + 0x22, 0xeb, 0x16, 0x06, 0xe3, 0xf6, 0xd0, 0x08, 0x08, 0xf0, 0x08, 0x1d, 0xda, + 0xba, 0xdd, 0xf7, 0x08, 0xf5, 0xf4, 0x17, 0xec, 0xef, 0x81, 0x37, 0xbd, 0x06, + 0x2a, 0x1f, 0xca, 0xfc, 0xf8, 0xef, 0x12, 0x69, 0x09, 0xfe, 0x06, 0x04, 0xde, + 0x0c, 0xe4, 0x12, 0xe4, 0x0d, 0xec, 0xdb, 0x88, 0xf4, 0xf0, 0x28, 0xeb, 0xe0, + 0x3a, 0xa3, 0xf1, 0xa5, 0x15, 0x0e, 0xea, 0xf9, 0x0a, 0x16, 0x15, 0x19, 0x10, + 0xad, 0x06, 0xf1, 0x06, 0xae, 0x08, 0x24, 0x35, 0xe1, 0xc4, 0x9f, 0xd7, 0xa2, + 0xda, 0xdd, 0x45, 0x19, 0x39, 0x14, 0xf3, 0x3c, 0xf1, 0xdb, 0x34, 0xf2, 0x07, + 0x27, 0xc1, 0x11, 0xdf, 0xd9, 0xb0, 0x1d, 0x5c, 0xfe, 0xe4, 0x0b, 0xe7, 0xf4, + 0x32, 0x1c, 0x7f, 0x35, 0x05, 0xef, 0xf5, 0x03, 0xeb, 0xa3, 0xdd, 0x20, 0x07, + 0x11, 0x2a, 0x13, 0xd8, 0xd9, 0xd3, 0xc0, 0xe3, 0xcc, 0xed, 0xcd, 0xfc, 0xcd, + 0xde, 0x31, 0xda, 0x07, 0xe9, 0xe9, 0xf9, 0x25, 0x42, 0xcb, 0x1b, 0x43, 0xec, + 0x39, 0xd7, 0x32, 0x17, 0xdb, 0xf3, 0x10, 0xf1, 0x3c, 0xc0, 0x07, 0xd6, 0x1d, + 0x81, 0xfa, 0xc3, 0x0d, 0xfc, 0x1c, 0xff, 0xc8, 0x05, 0xf0, 0xc9, 0x1c, 0x18, + 0xe5, 0x3b, 0xf3, 0xe9, 0xf6, 0xc8, 0xdd, 0x3b, 0xd4, 0x46, 0xe5, 0x0c, 0x10, + 0x03, 0x0b, 0x1b, 0x07, 0x44, 0x31, 0x34, 0x03, 0xe9, 0x44, 0xcf, 0x22, 0xe5, + 0xb5, 0x0e, 0x21, 0x66, 0xd7, 0x0c, 0xbd, 0xae, 0xf5, 0xe0, 0x63, 0xef, 0x7f, + 0xec, 0xf1, 0x21, 0xd1, 0xbd, 0x00, 0x32, 0xdf, 0xe6, 0xe0, 0xd3, 0xfc, 0xfa, + 0x2e, 0xe7, 0xf4, 0xf0, 0xaa, 0xde, 0xf5, 0x3a, 0xf8, 0xd8, 0x19, 0xfd, 0xe6, + 0xd1, 0xee, 0xe9, 0xf4, 0xe5, 0xf4, 0x42, 0x20, 0xc3, 0x4f, 0xd5, 0x49, 0x3b, + 0x5c, 0xe2, 0x0d, 0x69, 0x2b, 0x10, 0xea, 0x44, 0x06, 0x7f, 0x17, 0xe7, 0xcc, + 0xcb, 0x21, 0x4a, 0x45, 0xdf, 0x6e, 0x2c, 0xe2, 0x18, 0xc2, 0xd7, 0x3b, 0xa5, + 0x5b, 0x1f, 0x00, 0xfc, 0x1c, 0xa9, 0x9c, 0x9a, 0xee, 0xe3, 0xc1, 0xdd, 0xe3, + 0x4c, 0x45, 0x92, 0xba, 0xfe, 0x08, 0x32, 0xb5, 0x16, 0xf2, 0x0c, 0x2a, 0xce, + 0xad, 0xda, 0xa0, 0x60, 0x12, 0xc0, 0xec, 0x12, 0x06, 0x1e, 0x7f, 0x1c, 0xf3, + 0x10, 0xdc, 0xed, 0xcb, 0xec, 0x0e, 0xff, 0x08, 0xde, 0x0f, 0xf6, 0xf6, 0x0b, + 0xe9, 0x11, 0x0b, 0xf2, 0xf7, 0xce, 0x09, 0x06, 0xe8, 0xe3, 0xf1, 0x22, 0xd7, + 0xff, 0x0b, 0x04, 0x32, 0xe7, 0xe8, 0xed, 0xcf, 0x0a, 0x3b, 0xf5, 0xe9, 0x28, + 0x00, 0x08, 0xda, 0x05, 0x1c, 0xee, 0x01, 0x0b, 0x07, 0xf4, 0xfd, 0xb6, 0x14, + 0x2b, 0xd6, 0xb2, 0x08, 0xe8, 0x2e, 0xff, 0x17, 0x5a, 0x3b, 0x09, 0x24, 0xe0, + 0xdd, 0x55, 0x3b, 0xde, 0x05, 0x11, 0xbe, 0x12, 0x02, 0xe6, 0xde, 0x81, 0x0b, + 0x03, 0xf2, 0xf2, 0x5b, 0x08, 0xce, 0xef, 0x3b, 0xdb, 0x73, 0x08, 0x2c, 0x04, + 0x34, 0x0c, 0x29, 0xf7, 0xea, 0xf9, 0x02, 0xe8, 0x52, 0x02, 0x03, 0xf0, 0x40, + 0xec, 0xe6, 0xf8, 0xb6, 0x48, 0xf1, 0x22, 0x35, 0x12, 0xd7, 0x09, 0x0e, 0xc0, + 0xfd, 0x3c, 0x1b, 0x35, 0x46, 0x6c, 0xdc, 0x22, 0x8d, 0x39, 0xc0, 0x15, 0x2b, + 0x84, 0x29, 0x38, 0x69, 0x07, 0x08, 0x20, 0xff, 0x2f, 0xf4, 0x12, 0xe4, 0xfe, + 0x33, 0xed, 0xe9, 0xe3, 0x04, 0xd9, 0xe0, 0xa1, 0xae, 0x7f, 0x10, 0x12, 0x38, + 0xf0, 0xb3, 0xcd, 0x4d, 0xd5, 0x04, 0xdc, 0x18, 0x23, 0x16, 0x1d, 0x93, 0x0e, + 0xcf, 0x07, 0x1c, 0xa7, 0x61, 0x02, 0x29, 0x14, 0xdd, 0xdc, 0x31, 0xe8, 0xf8, + 0x0e, 0xbc, 0xf2, 0x3f, 0xa7, 0xa2, 0xe2, 0x81, 0x0e, 0xce, 0xf8, 0xfb, 0x08, + 0xe3, 0x1e, 0x13, 0xdf, 0xde, 0xef, 0xe5, 0xd0, 0x1a, 0xee, 0xf8, 0xee, 0x17, + 0xee, 0xe5, 0x3e, 0xf3, 0xde, 0x03, 0x19, 0x2b, 0x54, 0xcb, 0x22, 0x05, 0xf1, + 0x42, 0x22, 0x32, 0x40, 0x39, 0xe2, 0xe4, 0xb9, 0x30, 0xcb, 0x16, 0x2d, 0x19, + 0xf8, 0x89, 0x14, 0x0f, 0x14, 0xe8, 0xe0, 0x0e, 0xc7, 0x50, 0x1e, 0x1e, 0xaa, + 0xf0, 0x1a, 0x0b, 0xc5, 0x17, 0x91, 0xe6, 0x4d, 0xf5, 0xbf, 0xd0, 0xe7, 0xf7, + 0xe9, 0x09, 0x19, 0xef, 0xc6, 0x05, 0x2d, 0xec, 0xab, 0x16, 0x13, 0x01, 0xfd, + 0x10, 0xfd, 0x2c, 0xed, 0x48, 0x12, 0x12, 0x9e, 0x09, 0xf1, 0xfe, 0xd9, 0x1e, + 0xb2, 0xe4, 0x7f, 0x03, 0x0f, 0x2f, 0xd8, 0x3e, 0x19, 0x0e, 0xa6, 0x11, 0x00, + 0x02, 0x1d, 0xfb, 0xc3, 0xb2, 0x0b, 0xf5, 0xfa, 0x30, 0xdd, 0xe4, 0x51, 0xe3, + 0xe4, 0xe4, 0x2a, 0x14, 0xd8, 0x81, 0x60, 0x03, 0x17, 0xa9, 0xef, 0x08, 0x03, + 0xc9, 0xeb, 0xb6, 0xe2, 0xa8, 0x0d, 0x26, 0xcc, 0x0f, 0xf8, 0x77, 0xf8, 0x20, + 0x0b, 0xf9, 0x1d, 0x3b, 0xcd, 0x13, 0xc3, 0x00, 0xa9, 0x36, 0x94, 0x07, 0x24, + 0x1e, 0x1b, 0x11, 0x07, 0x0f, 0xf5, 0xba, 0xfb, 0xf7, 0x7d, 0xf0, 0x0b, 0xc2, + 0x4f, 0x10, 0x23, 0xfc, 0x1c, 0x1e, 0x05, 0xdf, 0xea, 0x10, 0xef, 0x2f, 0xf5, + 0xdd, 0xd2, 0x23, 0x00, 0x40, 0x0f, 0xd6, 0xec, 0x1e, 0x07, 0x05, 0xf9, 0xe6, + 0xd4, 0xeb, 0xfb, 0x14, 0x48, 0x00, 0x32, 0xf3, 0xe4, 0xdc, 0x12, 0xfd, 0xcc, + 0xf4, 0x43, 0x3f, 0x14, 0x1b, 0xeb, 0xd8, 0x0d, 0x02, 0xed, 0xe4, 0xfb, 0x24, + 0x33, 0x1f, 0xf1, 0xf6, 0x3a, 0xf9, 0x09, 0x7f, 0xf9, 0x2c, 0x17, 0xe2, 0x21, + 0xf8, 0xea, 0x03, 0x09, 0xc7, 0x38, 0x3b, 0xef, 0x08, 0xfa, 0x07, 0xa3, 0xd2, + 0xc9, 0xa0, 0x28, 0x57, 0xf1, 0x16, 0x06, 0xd7, 0x34, 0xe5, 0xec, 0xe7, 0x37, + 0x0d, 0xf5, 0x56, 0x2c, 0xcc, 0x2b, 0xf3, 0xf5, 0x0e, 0xc7, 0xde, 0x4d, 0x0a, + 0xe0, 0x47, 0x14, 0x17, 0x11, 0x0f, 0x15, 0xf6, 0x11, 0x0f, 0x27, 0xf9, 0x7f, + 0xe6, 0x22, 0x29, 0x4a, 0xfa, 0xe8, 0xd8, 0x0b, 0x31, 0x02, 0xd0, 0x0a, 0xfb, + 0x29, 0x17, 0x09, 0xd4, 0x3c, 0x51, 0x51, 0x0e, 0xcd, 0xff, 0x0d, 0x19, 0xf8, + 0xd4, 0x7f, 0x0d, 0xb9, 0xca, 0xff, 0xe4, 0xff, 0x28, 0xfd, 0xd2, 0xf7, 0x02, + 0x0f, 0xd9, 0xde, 0xf3, 0x2a, 0x29, 0xd5, 0x05, 0x3b, 0xf1, 0x0a, 0xd5, 0x46, + 0x20, 0xdc, 0x48, 0xd8, 0xe4, 0xf5, 0x42, 0xd2, 0x18, 0xfd, 0x51, 0x32, 0x39, + 0xde, 0xd7, 0x08, 0xe1, 0xb9, 0xe9, 0x4d, 0xeb, 0xf3, 0xde, 0xf7, 0xed, 0xc9, + 0x4b, 0x25, 0xe5, 0xf5, 0x13, 0xe3, 0x0e, 0x0f, 0xd6, 0xe7, 0x37, 0xd2, 0x26, + 0xf9, 0xed, 0xf6, 0x0c, 0x06, 0xf8, 0xed, 0x41, 0x11, 0xe6, 0x33, 0xcb, 0x01, + 0xf6, 0xea, 0x12, 0xeb, 0x08, 0xcd, 0xb1, 0x00, 0x22, 0x4d, 0x7e, 0x10, 0x4d, + 0x45, 0x26, 0xf4, 0x29, 0x43, 0xe3, 0xf1, 0x24, 0x81, 0xd0, 0xa5, 0xe4, 0xed, + 0xf2, 0x1d, 0xcc, 0xdf, 0xfe, 0xe5, 0x09, 0xd8, 0xec, 0x0d, 0x27, 0xf2, 0xd4, + 0x0c, 0xfe, 0x13, 0xd4, 0x51, 0xc4, 0xa3, 0xf5, 0x48, 0xc8, 0x32, 0xa3, 0x8f, + 0x30, 0x0b, 0x15, 0xd4, 0xc1, 0x02, 0xca, 0x02, 0x2f, 0xce, 0xbe, 0x71, 0x0e, + 0x1b, 0xb1, 0xf9, 0x13, 0x4b, 0x1a, 0x29, 0xc6, 0xe9, 0x40, 0xcb, 0xfa, 0xa8, + 0x67, 0xc8, 0xd0, 0x81, 0xf5, 0xf8, 0x29, 0xd7, 0x1c, 0xe1, 0x3b, 0x02, 0xfc, + 0x50, 0x16, 0xc8, 0x09, 0x95, 0x0f, 0x9f, 0x64, 0xf4, 0xf0, 0xdf, 0xfc, 0xf8, + 0x38, 0xa6, 0xfe, 0x1b, 0x0f, 0x67, 0x21, 0x5c, 0x19, 0xda, 0x29, 0xea, 0x05, + 0xec, 0x32, 0x04, 0xd7, 0x81, 0x00, 0xd2, 0x03, 0xe6, 0xef, 0x0a, 0xbe, 0x2d, + 0x24, 0xec, 0x55, 0xf0, 0x4a, 0x1c, 0xd4, 0x09, 0x06, 0x5d, 0x37, 0x2a, 0x31, + 0xc8, 0xf3, 0xbc, 0x1b, 0x05, 0xe8, 0x05, 0x04, 0xd1, 0xe4, 0xd2, 0x13, 0xf5, + 0x93, 0x0f, 0xc5, 0x16, 0x56, 0xfa, 0x14, 0x0d, 0xff, 0x10, 0x10, 0x39, 0xf8, + 0xdf, 0xd1, 0xbe, 0x1c, 0xcd, 0x32, 0x16, 0x28, 0xc8, 0x55, 0x0b, 0xfe, 0x25, + 0x2a, 0xef, 0xdc, 0x9a, 0xd4, 0xf7, 0x05, 0x17, 0xe0, 0xc1, 0x1c, 0x0d, 0x23, + 0x13, 0x07, 0x28, 0xf5, 0x06, 0xc8, 0xc2, 0xbd, 0xf4, 0xc7, 0xfa, 0x2b, 0x7f, + 0x14, 0x24, 0x4e, 0x09, 0x5f, 0x26, 0x08, 0x36, 0x46, 0x24, 0xd7, 0xc2, 0x1f, + 0xf8, 0x11, 0x23, 0x07, 0xbb, 0xdb, 0x11, 0xda, 0xc5, 0x45, 0xde, 0x32, 0x09, + 0x32, 0xbe, 0xc2, 0xf2, 0xd2, 0x5a, 0xb6, 0xfe, 0xe4, 0x47, 0xa0, 0xef, 0xf4, + 0x16, 0x33, 0xf2, 0x23, 0x3d, 0xea, 0xde, 0xe2, 0x52, 0x07, 0xb4, 0x18, 0x31, + 0xe5, 0xff, 0x50, 0x05, 0xe7, 0xf8, 0xf3, 0xe7, 0xd4, 0x41, 0xd0, 0x4e, 0x44, + 0x27, 0xff, 0x2a, 0xd4, 0x41, 0xf3, 0xe1, 0xc8, 0xeb, 0xd7, 0x31, 0x2e, 0x20, + 0xb9, 0xe5, 0x05, 0xf2, 0x36, 0xe3, 0x10, 0xb5, 0xda, 0xff, 0x1c, 0xb1, 0xf0, + 0x27, 0x02, 0x7f, 0xe1, 0xb9, 0x3b, 0xab, 0x25, 0x37, 0x75, 0xa6, 0x46, 0xe8, + 0xcf, 0xb7, 0xf8, 0x1c, 0x48, 0xec, 0x06, 0x2c, 0xf2, 0x9b, 0x18, 0x48, 0xcd, + 0xde, 0x0f, 0xf2, 0xe1, 0x5c, 0xfa, 0xdf, 0xf7, 0xe9, 0x29, 0xd0, 0x13, 0xe5, + 0xe2, 0xe6, 0x0e, 0xd4, 0xf4, 0xf8, 0x1f, 0xc6, 0xe3, 0x40, 0x26, 0xed, 0x33, + 0xfa, 0xce, 0x24, 0x7f, 0xe4, 0xcf, 0x0a, 0xef, 0xe7, 0x02, 0x28, 0x4f, 0xd2, + 0x00, 0x2f, 0x13, 0xfb, 0xe7, 0x22, 0x1b, 0x9f, 0x65, 0xc4, 0x0f, 0xe8, 0x04, + 0x1c, 0x2a, 0x36, 0xe9, 0x6a, 0xbc, 0x27, 0xc4, 0xb6, 0xd3, 0x85, 0xe9, 0xc3, + 0x29, 0xe3, 0x35, 0x00, 0x79, 0x0f, 0x06, 0xb8, 0x0b, 0x2b, 0x25, 0xe4, 0xc7, + 0x1c, 0x02, 0x47, 0xe1, 0x5e, 0xf9, 0x0f, 0xd3, 0x29, 0xdf, 0xcb, 0x20, 0x1d, + 0xaf, 0x2d, 0x7f, 0x1a, 0x18, 0x3f, 0xf9, 0xe8, 0x7c, 0x04, 0x08, 0xfc, 0xd0, + 0xb1, 0x49, 0xf5, 0xc5, 0x09, 0x0f, 0x6b, 0x18, 0xda, 0xef, 0x2c, 0x97, 0xc2, + 0xc6, 0xea, 0xdf, 0xb7, 0xc6, 0x44, 0x23, 0xd2, 0xf6, 0x99, 0x2f, 0x4e, 0x8e, + 0x1f, 0xde, 0x3b, 0x47, 0x33, 0xbb, 0x16, 0x65, 0xca, 0xac, 0x0d, 0xf0, 0xee, + 0xe5, 0x1b, 0xe4, 0xfb, 0x81, 0xa3, 0x05, 0x03, 0xe1, 0x11, 0x0d, 0xfb, 0xa6, + 0x10, 0xf0, 0xd1, 0x2e, 0x0d, 0x2e, 0xe5, 0x2b, 0xd6, 0xd3, 0xf9, 0xee, 0x68, + 0xe9, 0x0a, 0xc8, 0x6c, 0xe3, 0xfa, 0x00, 0x04, 0xfc, 0x0c, 0x01, 0xe1, 0xff, + 0xe5, 0xf3, 0x14, 0xfb, 0xdf, 0x2d, 0x28, 0xde, 0x12, 0xcd, 0xa8, 0xe1, 0xff, + 0x1a, 0xff, 0x4d, 0xc8, 0xf3, 0x0a, 0x05, 0x0c, 0x4e, 0xf2, 0x0b, 0xea, 0xec, + 0x0c, 0xdd, 0x4f, 0xcd, 0x5a, 0x0d, 0x1f, 0x36, 0x37, 0xea, 0xf3, 0x7f, 0x2e, + 0x46, 0xfa, 0xda, 0xd4, 0xc6, 0xf7, 0xd9, 0xf9, 0xf3, 0xd5, 0xca, 0xf4, 0x05, + 0x81, 0x25, 0xd3, 0xf1, 0x78, 0xcc, 0xc8, 0xd4, 0x04, 0x00, 0x35, 0xd0, 0xdc, + 0xbd, 0x17, 0xf0, 0x16, 0x19, 0xa5, 0xee, 0xf3, 0xdd, 0xf4, 0x0b, 0xdd, 0x0c, + 0x01, 0x03, 0xeb, 0x16, 0x27, 0xf7, 0xd6, 0x0b, 0x0e, 0x40, 0x15, 0x20, 0xf7, + 0x14, 0x60, 0x01, 0x09, 0x0d, 0xed, 0x15, 0x1c, 0xbf, 0xe3, 0x13, 0x0f, 0xef, + 0x16, 0xfb, 0x10, 0x12, 0xf4, 0xef, 0x21, 0x1d, 0xf7, 0x17, 0xc4, 0x01, 0xf2, + 0xdc, 0xcf, 0xe6, 0x2d, 0xd0, 0xda, 0x14, 0x32, 0xe9, 0xd1, 0xed, 0x1c, 0x39, + 0x81, 0x0f, 0xd8, 0xef, 0x24, 0xda, 0x18, 0x1c, 0x11, 0xfc, 0x02, 0x9f, 0xed, + 0x2b, 0xfe, 0x12, 0xfa, 0xf6, 0x3b, 0x15, 0x04, 0xf0, 0x0e, 0x1a, 0xc3, 0x09, + 0xc2, 0x0b, 0xcc, 0x4f, 0x04, 0xeb, 0x16, 0xe6, 0x0c, 0xc6, 0xe3, 0x54, 0xfc, + 0xfa, 0xf3, 0x3a, 0xe1, 0x2e, 0xcf, 0x48, 0x36, 0xf4, 0xed, 0x10, 0xd0, 0xc1, + 0xff, 0x09, 0x04, 0x38, 0xfa, 0xef, 0x0c, 0x03, 0xd2, 0xe0, 0x13, 0xf3, 0xf1, + 0xda, 0xd6, 0xec, 0xf9, 0xe7, 0x02, 0xfb, 0x43, 0x49, 0x00, 0x2f, 0x09, 0xf5, + 0xf7, 0x81, 0xcd, 0x98, 0x2f, 0xff, 0xfc, 0x08, 0xd6, 0x05, 0x81, 0xb4, 0x03, + 0xf1, 0x22, 0x26, 0x3c, 0xef, 0x0b, 0x13, 0xf5, 0xde, 0xf9, 0x76, 0xf6, 0xe6, + 0xf2, 0x3b, 0xfd, 0xe4, 0xd5, 0xd6, 0xc2, 0x15, 0x60, 0xe1, 0x02, 0xc3, 0x04, + 0x3b, 0xa8, 0xd6, 0x04, 0x2c, 0x1b, 0x03, 0xf0, 0x24, 0x98, 0xd6, 0xf9, 0x07, + 0x18, 0x29, 0x0e, 0x17, 0x0c, 0x0a, 0x05, 0xec, 0xfb, 0x0a, 0xfd, 0xfe, 0x00, + 0x26, 0x2e, 0x04, 0x11, 0xe8, 0x13, 0xf8, 0x39, 0xf5, 0xfa, 0xcf, 0xe6, 0xdf, + 0xae, 0x08, 0x36, 0xfe, 0x0d, 0xfb, 0xf1, 0x07, 0x3e, 0x18, 0xeb, 0xfa, 0x13, + 0xf5, 0x03, 0x0f, 0x0d, 0xd9, 0x06, 0x7f, 0xe8, 0x17, 0xf4, 0x14, 0x89, 0xd0, + 0xa2, 0xe1, 0xac, 0xfc, 0xff, 0x6b, 0x17, 0x99, 0xfb, 0xdb, 0xf9, 0xe8, 0xca, + 0xe3, 0x14, 0xf5, 0x3b, 0x10, 0x63, 0x57, 0xc5, 0x0f, 0xf1, 0xcd, 0x1c, 0x0e, + 0x0c, 0xd9, 0x0a, 0x04, 0xfb, 0xfb, 0x4e, 0x24, 0xed, 0x0d, 0x12, 0x3e, 0xd5, + 0x1e, 0xd6, 0x81, 0x3f, 0x08, 0xac, 0x13, 0x3c, 0xec, 0x35, 0xb7, 0xe0, 0x1d, + 0x37, 0xdc, 0x10, 0x62, 0x1c, 0xb2, 0xef, 0x41, 0x2a, 0x3c, 0x17, 0x10, 0xe8, + 0xb9, 0x3c, 0x72, 0xdd, 0xdf, 0x2c, 0xe3, 0x1a, 0x0b, 0x6f, 0xc6, 0xd6, 0xef, + 0xde, 0x3f, 0xe8, 0xe6, 0xb6, 0x19, 0xd9, 0xd4, 0xef, 0x15, 0xcc, 0x0a, 0x55, + 0xdd, 0xfa, 0x24, 0xe8, 0xce, 0x08, 0x2e, 0xf1, 0xbb, 0x4e, 0xfb, 0x1d, 0xfd, + 0xfd, 0x06, 0xe8, 0x18, 0x10, 0x7f, 0xd6, 0x31, 0xf8, 0xc6, 0xe9, 0xc7, 0xf2, + 0x47, 0xe7, 0xfd, 0xe3, 0xc1, 0xdd, 0x0f, 0x3a, 0xb7, 0xba, 0x28, 0xe7, 0x16, + 0x8b, 0xf9, 0x1f, 0x9d, 0xfa, 0x0a, 0x28, 0xe5, 0xca, 0xec, 0x3d, 0x29, 0xb6, + 0x16, 0x0a, 0xfb, 0x17, 0xbf, 0x02, 0x24, 0xce, 0xde, 0x36, 0x7f, 0x13, 0xf0, + 0x83, 0x35, 0x25, 0xe6, 0xfb, 0xf1, 0xd0, 0x05, 0x39, 0x26, 0x02, 0xc8, 0xd6, + 0x5f, 0xde, 0xb9, 0x3c, 0x13, 0xbc, 0x2a, 0x10, 0xd5, 0xad, 0xf2, 0xef, 0x0a, + 0xf6, 0x35, 0xd2, 0xad, 0xd5, 0x0a, 0xf6, 0x0c, 0xb6, 0x7f, 0xd4, 0x24, 0x5a, + 0x93, 0xa6, 0xf7, 0x11, 0x00, 0xf1, 0x35, 0x57, 0x17, 0xc7, 0x3b, 0xc9, 0xdb, + 0x1f, 0xbd, 0xc7, 0x81, 0xf9, 0xb1, 0xd2, 0x2c, 0xec, 0x5b, 0xf0, 0xed, 0x83, + 0x27, 0x26, 0x7d, 0xd5, 0x12, 0xab, 0xd5, 0x36, 0xdf, 0x60, 0x44, 0x3a, 0x47, + 0xdc, 0x25, 0x1b, 0x48, 0xc1, 0xec, 0x02, 0xdd, 0x30, 0x06, 0xfd, 0xf4, 0x1f, + 0x2c, 0xc1, 0xe9, 0xfe, 0xf8, 0x15, 0x12, 0x16, 0x44, 0x11, 0xa5, 0x39, 0xb3, + 0x23, 0x0f, 0xde, 0x1f, 0x25, 0xeb, 0x05, 0xfb, 0x15, 0xe1, 0x71, 0x3b, 0xdc, + 0xf0, 0x32, 0xc9, 0xf4, 0xe1, 0xb3, 0x02, 0x46, 0x36, 0x07, 0x40, 0x6b, 0x1b, + 0xd0, 0x36, 0x1a, 0xe3, 0xa8, 0xc9, 0x77, 0x03, 0xd0, 0xe5, 0x2a, 0x36, 0x31, + 0xc5, 0x0e, 0xe5, 0xf1, 0xc7, 0xfa, 0x7f, 0x2e, 0xe6, 0x0a, 0x16, 0x32, 0xd7, + 0x17, 0x2d, 0xd4, 0xf3, 0xee, 0xe1, 0xc3, 0x29, 0x3e, 0x04, 0xc7, 0xe8, 0xe8, + 0xf8, 0xee, 0xfa, 0xf5, 0xd0, 0xfd, 0xfa, 0xf7, 0xe1, 0x93, 0x16, 0x7f, 0xd8, + 0xcf, 0x06, 0x1a, 0x06, 0xdf, 0xfc, 0x08, 0xfe, 0x22, 0x0a, 0xdd, 0xdf, 0xfe, + 0x19, 0xf5, 0x14, 0x13, 0x5c, 0x08, 0x2c, 0xd3, 0x02, 0xe2, 0x0e, 0xec, 0x23, + 0x0a, 0x19, 0xed, 0xcc, 0x33, 0xe0, 0xff, 0x50, 0xeb, 0x3d, 0x06, 0xe1, 0x06, + 0xad, 0xd5, 0x10, 0x12, 0xec, 0xcf, 0x06, 0x12, 0x5e, 0x1c, 0xd5, 0x1d, 0x0d, + 0x07, 0x12, 0xa6, 0xb9, 0xf4, 0xf8, 0xf6, 0x3f, 0xfd, 0xdd, 0x3a, 0x1a, 0x12, + 0xbc, 0x1b, 0xe6, 0xd7, 0x0f, 0xfb, 0x1f, 0x27, 0x1f, 0xd6, 0xee, 0x27, 0xbb, + 0x42, 0xec, 0x3a, 0x0b, 0xc0, 0xfd, 0x04, 0xe0, 0xe4, 0x22, 0x27, 0xe8, 0x06, + 0x39, 0xdf, 0xfb, 0x17, 0xda, 0xfb, 0xed, 0xea, 0xf6, 0xcb, 0xce, 0x7f, 0x21, + 0xdb, 0x10, 0xf6, 0x47, 0xba, 0xbf, 0x08, 0xc6, 0xdc, 0x2c, 0xeb, 0xdd, 0x03, + 0xdb, 0x27, 0x22, 0x1a, 0xe4, 0x49, 0x23, 0xe8, 0xf5, 0xeb, 0x12, 0xfd, 0x21, + 0xf3, 0xf4, 0xe8, 0xdd, 0xdb, 0x3c, 0xf2, 0x26, 0x30, 0xfd, 0xd5, 0xcc, 0x00, + 0x2b, 0xb9, 0xf0, 0x25, 0x0f, 0xeb, 0xe6, 0xc9, 0x01, 0xf4, 0x07, 0xa1, 0x0e, + 0xfb, 0xe7, 0x11, 0xef, 0x0e, 0xdf, 0x19, 0xec, 0x26, 0x3d, 0x18, 0xd5, 0x81, + 0x28, 0xae, 0x29, 0xa8, 0xf9, 0x4d, 0x0e, 0x0f, 0x21, 0x0b, 0x12, 0xdd, 0xb1, + 0xf1, 0x0e, 0x1e, 0x0e, 0x81, 0xd7, 0xbc, 0x10, 0x0a, 0xf6, 0xe9, 0x05, 0xdd, + 0xe9, 0xe6, 0xf1, 0xfb, 0x55, 0x04, 0xd0, 0xfd, 0xd3, 0xe2, 0x21, 0xc2, 0x19, + 0x13, 0xe1, 0x56, 0xe1, 0x27, 0x0e, 0xf0, 0x09, 0xf8, 0x13, 0x23, 0x58, 0xf7, + 0x1d, 0x08, 0xde, 0x08, 0xfa, 0xfd, 0xbf, 0x1e, 0x51, 0x0a, 0x10, 0xa6, 0xfe, + 0x7f, 0x2d, 0x4c, 0x1c, 0xe6, 0xa3, 0xcf, 0xa5, 0x30, 0xe9, 0xc8, 0xf5, 0x30, + 0xfd, 0x3f, 0xad, 0xcc, 0x12, 0xdb, 0x33, 0xfd, 0xe5, 0xfc, 0x4a, 0x1f, 0x12, + 0x9b, 0xe8, 0xcc, 0xcd, 0x06, 0xd6, 0x0a, 0x42, 0x2e, 0x24, 0xe4, 0xcb, 0x58, + 0xb7, 0x15, 0x2f, 0x01, 0x29, 0xf9, 0xe0, 0x0a, 0x08, 0xeb, 0x1c, 0xa5, 0xf7, + 0xee, 0x9e, 0xd5, 0x43, 0x17, 0x78, 0xfe, 0xf1, 0xa8, 0xd8, 0xdd, 0xed, 0x47, + 0xca, 0xb2, 0xd9, 0x02, 0x7f, 0x08, 0x36, 0xd5, 0xe5, 0x45, 0x13, 0xcf, 0x12, + 0x07, 0xe1, 0x5e, 0x35, 0x48, 0xb5, 0xf8, 0x06, 0xed, 0x63, 0x36, 0x6d, 0x27, + 0xd1, 0xb8, 0x21, 0xde, 0xbd, 0xcd, 0xc9, 0x00, 0xd5, 0x12, 0xf6, 0x17, 0x2e, + 0x8f, 0x21, 0xad, 0x0f, 0xa8, 0xef, 0x20, 0x2f, 0xe2, 0x5d, 0x16, 0x31, 0x51, + 0xcb, 0x19, 0xdd, 0x0b, 0x52, 0xf9, 0xe8, 0xae, 0xdf, 0x4e, 0xd7, 0xe5, 0xd5, + 0x71, 0x68, 0x07, 0x64, 0xd0, 0xfc, 0x27, 0xbe, 0x6a, 0xce, 0x1a, 0xef, 0xe0, + 0x04, 0x15, 0xb1, 0x1e, 0x48, 0x1f, 0xfe, 0xd2, 0x3f, 0x22, 0xb0, 0xb5, 0xd8, + 0x35, 0x2d, 0x81, 0x07, 0xa6, 0xfd, 0x0d, 0x1a, 0xbb, 0xd2, 0x17, 0xec, 0xd7, + 0xf5, 0x12, 0x33, 0x50, 0x58, 0xfe, 0xc7, 0x2b, 0x41, 0xb3, 0x39, 0x27, 0x05, + 0xd3, 0x27, 0xe7, 0x30, 0xb6, 0xb6, 0xe8, 0xb3, 0xe9, 0xd9, 0x22, 0xfb, 0xdb, + 0x05, 0x9c, 0xe0, 0xfd, 0x24, 0x16, 0x1f, 0x05, 0xfe, 0x02, 0x11, 0xe7, 0x09, + 0x09, 0x13, 0x19, 0xfe, 0x7f, 0x11, 0x32, 0xf4, 0xc2, 0x3f, 0x15, 0xff, 0xfb, + 0x3e, 0x0c, 0x13, 0xff, 0x0d, 0xfe, 0xbc, 0x17, 0xe2, 0x05, 0xc2, 0xe7, 0x57, + 0x16, 0xed, 0x19, 0xdd, 0xe6, 0xfb, 0xfb, 0x06, 0x2c, 0xc3, 0x3a, 0xc1, 0xf4, + 0xc8, 0xf4, 0xbe, 0x11, 0xdd, 0x1a, 0xff, 0x02, 0xff, 0x77, 0xb5, 0x1e, 0xef, + 0xfd, 0xa1, 0x4f, 0x5e, 0x23, 0x08, 0xb4, 0xf8, 0xef, 0xbd, 0x01, 0xc9, 0xe8, + 0xe2, 0xfd, 0x4a, 0x1c, 0xfe, 0x1b, 0x06, 0x00, 0xfb, 0x07, 0x0f, 0x00, 0x2d, + 0x46, 0xd3, 0xe9, 0xda, 0xf6, 0xea, 0x30, 0xf4, 0x13, 0x15, 0xce, 0xe2, 0xd5, + 0xba, 0xfb, 0x27, 0xf6, 0xe8, 0x05, 0x7f, 0x0f, 0xd7, 0x03, 0xed, 0xe3, 0xa9, + 0xec, 0xea, 0xc8, 0xce, 0x30, 0x56, 0xc4, 0x0a, 0x35, 0xde, 0xd5, 0x04, 0xd2, + 0x23, 0xee, 0x3d, 0x27, 0xeb, 0xb2, 0x15, 0xf7, 0xf8, 0x91, 0x02, 0xfd, 0x16, + 0x14, 0xd6, 0x22, 0x14, 0xf6, 0xe0, 0xf6, 0xb4, 0x20, 0x0e, 0x0f, 0x38, 0x15, + 0x2e, 0xc3, 0x24, 0xf9, 0xba, 0x21, 0x13, 0x29, 0xe4, 0x1e, 0xf0, 0xd8, 0x23, + 0xe8, 0x23, 0x43, 0xf5, 0xe3, 0x19, 0xc9, 0x45, 0xe1, 0xe4, 0xeb, 0xfa, 0xd8, + 0xfd, 0xae, 0xfd, 0x1d, 0xf5, 0x7f, 0xed, 0x00, 0xd6, 0xd9, 0x3d, 0xc4, 0xb9, + 0x1c, 0x56, 0xe8, 0xbb, 0x40, 0xde, 0xf5, 0x50, 0xfa, 0xf5, 0x04, 0xe4, 0xfe, + 0xfb, 0xfe, 0x3b, 0x20, 0xe0, 0xca, 0x1f, 0xb5, 0xf3, 0xcf, 0xfb, 0xe2, 0x0e, + 0xba, 0xd9, 0x81, 0xbe, 0xf9, 0xcf, 0xc7, 0xb5, 0x4a, 0x19, 0xf9, 0x14, 0xf3, + 0x02, 0x17, 0xf8, 0xfd, 0x34, 0x07, 0xdd, 0xff, 0xf1, 0x0f, 0xfa, 0x01, 0x01, + 0x24, 0x25, 0xc3, 0xf5, 0xd3, 0x06, 0xd5, 0x73, 0x07, 0xb8, 0x23, 0x0b, 0x0f, + 0x1d, 0xc5, 0xef, 0x64, 0x24, 0xde, 0xcc, 0x36, 0xd2, 0x7f, 0x1c, 0x09, 0x9a, + 0xe1, 0xf8, 0xbe, 0xb7, 0xe0, 0x8e, 0x70, 0xde, 0x2c, 0xf8, 0x27, 0xc3, 0xe4, + 0x27, 0xf6, 0x7b, 0x10, 0x02, 0x01, 0x23, 0x52, 0xe8, 0xfc, 0xf5, 0x02, 0x25, + 0x0f, 0xc4, 0xba, 0xd3, 0x3d, 0x15, 0xe0, 0xd6, 0xf8, 0x93, 0x14, 0x0c, 0x4d, + 0x40, 0xf2, 0x2b, 0x19, 0xcd, 0x47, 0x08, 0x08, 0x18, 0x7f, 0x0c, 0xbb, 0x3f, + 0xfa, 0xdf, 0xbc, 0x18, 0x05, 0x3f, 0x1c, 0xc0, 0xea, 0x0d, 0x01, 0xcf, 0xd7, + 0x29, 0xf6, 0x12, 0x13, 0xec, 0x24, 0xc9, 0xc5, 0xf9, 0x15, 0x1e, 0x12, 0xe9, + 0x21, 0x2d, 0xfc, 0x02, 0xfd, 0xf7, 0x07, 0x12, 0xb1, 0xe9, 0xc6, 0x34, 0x2b, + 0x01, 0x0c, 0xb2, 0xf6, 0xfc, 0x0a, 0x11, 0xc6, 0xfc, 0xf3, 0xfd, 0xf5, 0xc6, + 0xe6, 0x39, 0x1c, 0xe3, 0x81, 0xc8, 0xd1, 0x0a, 0xb2, 0xf0, 0xd4, 0xdd, 0x01, + 0xd9, 0x0c, 0xd8, 0xb1, 0x13, 0x0c, 0xcc, 0x29, 0x41, 0x2d, 0x18, 0x09, 0x1c, + 0xfa, 0xdd, 0x15, 0x65, 0xff, 0xf5, 0x0c, 0x4d, 0xa9, 0x32, 0x54, 0x6d, 0x0f, + 0xdd, 0xf9, 0xd4, 0xe0, 0xe5, 0x06, 0xca, 0x0f, 0x38, 0xec, 0xb8, 0x4c, 0x6d, + 0xa4, 0x72, 0x27, 0x5f, 0xfb, 0x2c, 0x28, 0x4d, 0xfa, 0x0d, 0xc2, 0x16, 0xf3, + 0xf6, 0xc8, 0x1b, 0x11, 0xde, 0x18, 0xee, 0x91, 0x98, 0x1e, 0xda, 0x0f, 0x7f, + 0xf6, 0xd3, 0x0d, 0xbd, 0xd8, 0x12, 0xaf, 0x0c, 0x05, 0xf9, 0x3a, 0x30, 0x45, + 0x08, 0xd9, 0xcf, 0xee, 0x1f, 0x7e, 0xe2, 0x18, 0xbd, 0x26, 0xde, 0xf6, 0xfb, + 0x24, 0x1a, 0xdd, 0x0d, 0xe9, 0x08, 0xe5, 0xee, 0x08, 0xd7, 0xd0, 0xc6, 0x14, + 0xf6, 0x19, 0xfc, 0xf4, 0xed, 0x12, 0xfc, 0x0b, 0x02, 0x12, 0xce, 0x1a, 0xca, + 0xd4, 0xe4, 0xcc, 0xdc, 0xb7, 0xfa, 0xa1, 0xb0, 0xca, 0x22, 0x26, 0x3e, 0xe8, + 0xd7, 0x14, 0xe9, 0xeb, 0x16, 0xb0, 0xf9, 0x1e, 0x34, 0xf8, 0xe1, 0x0c, 0x08, + 0xd5, 0x01, 0xf6, 0x47, 0xda, 0x1d, 0x9b, 0xf4, 0x37, 0xe0, 0xf8, 0xbd, 0x0f, + 0x30, 0x44, 0x18, 0x3f, 0x13, 0xfd, 0x0e, 0x1e, 0x09, 0x2e, 0x1b, 0x5d, 0x2b, + 0x04, 0x95, 0xc9, 0x43, 0xfd, 0x34, 0xfa, 0xf8, 0xfe, 0x7f, 0xfa, 0xef, 0xaa, + 0x19, 0xeb, 0xe6, 0xc4, 0xfd, 0xdf, 0xde, 0x2f, 0x43, 0xce, 0x3f, 0xfc, 0xf0, + 0xe0, 0xe2, 0xcd, 0x27, 0xfd, 0xfb, 0x40, 0xe5, 0x04, 0xf0, 0xee, 0xe0, 0x17, + 0x89, 0x0c, 0x2f, 0x19, 0x17, 0xc8, 0x26, 0x0b, 0xfa, 0xfd, 0x7f, 0x06, 0x0b, + 0xe4, 0x47, 0x4c, 0x00, 0x8e, 0xf9, 0xe9, 0x0a, 0x39, 0x1a, 0xe5, 0xea, 0x20, + 0xf2, 0x23, 0x4c, 0x01, 0x0c, 0x09, 0x27, 0xe2, 0xfc, 0x08, 0x15, 0x19, 0x16, + 0x1e, 0xe5, 0xf0, 0xd0, 0xa7, 0xf5, 0xdd, 0x3e, 0x04, 0xf5, 0x3d, 0x24, 0x15, + 0x1b, 0xbf, 0xf4, 0x32, 0x02, 0xed, 0xf3, 0xd5, 0x32, 0xfc, 0x59, 0x81, 0xaa, + 0x3e, 0xf6, 0x21, 0x23, 0xf3, 0x24, 0xcf, 0x33, 0x97, 0xe9, 0x0e, 0xf5, 0xd4, + 0x03, 0xca, 0x49, 0xf9, 0x46, 0xc3, 0xcb, 0xed, 0xef, 0x19, 0xc2, 0x00, 0xff, + 0x01, 0xb3, 0x10, 0x20, 0x17, 0x03, 0xf6, 0xd0, 0xcc, 0x12, 0xf7, 0x26, 0x2f, + 0xd4, 0x66, 0xea, 0x01, 0xba, 0xd7, 0x5f, 0x0d, 0xff, 0x31, 0xe9, 0x20, 0xf6, + 0x7f, 0xe5, 0x15, 0x26, 0xf2, 0xef, 0x05, 0x0f, 0xf8, 0xd9, 0xf7, 0x5e, 0x34, + 0xcb, 0xae, 0x92, 0x5d, 0xe1, 0x0c, 0x16, 0x3b, 0xa1, 0x0f, 0x04, 0xce, 0xb8, + 0x28, 0xd8, 0x54, 0xe1, 0x49, 0x01, 0xed, 0x09, 0xe0, 0x1e, 0xf7, 0xe2, 0x0b, + 0xf3, 0xf3, 0xe1, 0x27, 0xb9, 0x39, 0x17, 0x3e, 0xf1, 0x02, 0x1d, 0x0e, 0x67, + 0x19, 0xbc, 0x17, 0xb3, 0x0d, 0xb4, 0xe0, 0x36, 0xc9, 0x1f, 0x11, 0xe3, 0x2f, + 0xd3, 0xdb, 0xf4, 0x26, 0x0b, 0x13, 0xf1, 0x01, 0xd5, 0x04, 0xd0, 0xdf, 0x26, + 0xc4, 0xb2, 0x2b, 0x33, 0x38, 0xde, 0x41, 0xc2, 0xb6, 0xf4, 0x7f, 0x4f, 0xf0, + 0x00, 0x04, 0xfc, 0x00, 0xbd, 0xed, 0xfc, 0xdb, 0x3b, 0xf9, 0x16, 0xf3, 0xff, + 0x02, 0xfb, 0xf0, 0x1d, 0x2f, 0x10, 0xdf, 0x5f, 0xd9, 0x01, 0xfb, 0xe5, 0x29, + 0x38, 0xde, 0x05, 0xd9, 0xc1, 0xf8, 0xe9, 0x1e, 0xa7, 0x13, 0x01, 0xb8, 0xeb, + 0xb5, 0x2b, 0x29, 0xa7, 0xad, 0xf2, 0xdd, 0xe5, 0x0c, 0x1b, 0xee, 0x58, 0xae, + 0x05, 0x62, 0xd9, 0x12, 0xf2, 0x0f, 0x03, 0x27, 0x00, 0x39, 0xac, 0xb8, 0xef, + 0xcd, 0x02, 0x5f, 0x11, 0x1f, 0xfe, 0xa6, 0x02, 0x13, 0xde, 0x35, 0x18, 0x04, + 0xd0, 0xeb, 0x14, 0xdf, 0x81, 0xed, 0xfb, 0x8c, 0x14, 0xfa, 0xe9, 0x1f, 0x01, + 0x12, 0xe7, 0xc2, 0xd2, 0xea, 0xf0, 0xde, 0xf1, 0xfd, 0x01, 0x14, 0xd7, 0x0d, + 0x08, 0x16, 0x1e, 0xab, 0x3a, 0x0e, 0xe0, 0xf6, 0xf5, 0x1c, 0x50, 0x7f, 0xea, + 0x20, 0x0c, 0xdd, 0xc9, 0xfc, 0xe3, 0x0d, 0xee, 0x15, 0xc7, 0xde, 0x0a, 0x0c, + 0xf9, 0x20, 0xe8, 0xff, 0xda, 0xf9, 0xf0, 0x6a, 0xf2, 0xf7, 0x1d, 0xf6, 0xee, + 0xf0, 0x23, 0xe5, 0x0c, 0xde, 0xd6, 0x4c, 0xe8, 0x0e, 0x91, 0xdf, 0xc9, 0x7f, + 0x3c, 0xa9, 0x3b, 0xcb, 0x38, 0xe2, 0x38, 0x5a, 0xea, 0x16, 0xec, 0x2a, 0x5a, + 0xe1, 0x04, 0x00, 0x13, 0xf8, 0xce, 0x15, 0x38, 0x1a, 0xc8, 0x10, 0x4c, 0x2d, + 0x0c, 0xfa, 0xdb, 0x59, 0x2a, 0xee, 0x0c, 0x9d, 0x47, 0x13, 0x22, 0xa1, 0x5c, + 0xdf, 0xff, 0x97, 0xcb, 0x3d, 0xcc, 0x85, 0xd0, 0x76, 0xf2, 0x9f, 0xe7, 0x04, + 0xd4, 0x32, 0x14, 0x1c, 0x0a, 0x14, 0xe9, 0x2b, 0x9d, 0x66, 0xc4, 0xd5, 0xf0, + 0xda, 0x40, 0x4d, 0x0a, 0xb1, 0x51, 0xf9, 0x29, 0x19, 0x03, 0xb1, 0x1b, 0x4f, + 0xcd, 0x0c, 0xe1, 0x1d, 0x3c, 0x0b, 0x96, 0x43, 0xf6, 0xe4, 0xe3, 0x57, 0xa0, + 0xf8, 0xdd, 0x2d, 0x00, 0xa9, 0x35, 0xdb, 0x5a, 0x56, 0xe2, 0xfb, 0x0a, 0xd6, + 0x23, 0x3b, 0xc5, 0x06, 0xf9, 0xe8, 0x03, 0x01, 0x21, 0xee, 0xe7, 0x0b, 0x7f, + 0xf5, 0x2f, 0x11, 0xf7, 0x7d, 0x0c, 0x53, 0xb4, 0xd4, 0xcd, 0xe6, 0x11, 0x2a, + 0x0d, 0xdc, 0xc6, 0x7f, 0x2a, 0x1a, 0xd6, 0xe8, 0xba, 0xe5, 0x03, 0x14, 0xfc, + 0x00, 0x17, 0x0e, 0x16, 0xed, 0x47, 0x6e, 0xbd, 0xd4, 0xfd, 0x10, 0xfe, 0xcb, + 0xd6, 0x09, 0xeb, 0xe8, 0xea, 0xd9, 0xdb, 0x25, 0x20, 0xcf, 0x15, 0x2e, 0x32, + 0xbf, 0x03, 0xe2, 0xf2, 0xe9, 0xdb, 0x2c, 0xd3, 0xe1, 0xe1, 0xf4, 0xd9, 0xee, + 0x12, 0x18, 0xdf, 0xd8, 0xd8, 0x38, 0xf0, 0x13, 0x59, 0xc6, 0x1a, 0xc6, 0x0f, + 0x0a, 0xe6, 0x04, 0x0b, 0xc4, 0x89, 0xb0, 0xcb, 0x45, 0x1a, 0xf6, 0xfa, 0xd7, + 0x12, 0x19, 0x27, 0xad, 0x33, 0xb0, 0x25, 0x41, 0x33, 0xfc, 0x09, 0x0f, 0x3b, + 0xc1, 0xf2, 0x58, 0xd3, 0xfa, 0xcc, 0xf8, 0x7f, 0x0b, 0xd1, 0xe6, 0x94, 0x12, + 0x1d, 0x78, 0xfe, 0xb6, 0x3c, 0x45, 0xe5, 0x5a, 0x22, 0x2d, 0x05, 0x32, 0xd8, + 0xdc, 0xc5, 0x18, 0x65, 0x0f, 0xc7, 0xdb, 0xf3, 0xa0, 0xdd, 0xf9, 0x31, 0xfe, + 0xe9, 0x08, 0xd0, 0x25, 0xdc, 0x07, 0x1d, 0x1d, 0x00, 0x24, 0x26, 0x7f, 0xf6, + 0x10, 0xdf, 0x3c, 0xf9, 0x0f, 0x13, 0x2e, 0xe4, 0x12, 0xf3, 0xfe, 0x19, 0x00, + 0xf1, 0x43, 0xea, 0x02, 0xd8, 0x1a, 0x08, 0x0f, 0xdd, 0x1c, 0xe1, 0x14, 0xe0, + 0xe2, 0x0f, 0x06, 0xea, 0x05, 0xd7, 0xce, 0xbd, 0xe8, 0x3b, 0xea, 0x22, 0xcc, + 0xf0, 0x18, 0x1a, 0xfd, 0xed, 0xfd, 0xee, 0x81, 0xbe, 0xf7, 0x13, 0xfa, 0xfb, + 0xf5, 0xe8, 0x02, 0xf8, 0x1c, 0x0f, 0x01, 0xf2, 0x13, 0x18, 0x42, 0x08, 0x13, + 0x22, 0x3a, 0xc7, 0xef, 0x07, 0x20, 0xdb, 0xea, 0x0a, 0x19, 0xf9, 0x09, 0x01, + 0x13, 0xfd, 0xe9, 0xdb, 0xf2, 0xfc, 0x0a, 0xf6, 0x04, 0xfd, 0xdf, 0x19, 0xca, + 0xee, 0x1c, 0x05, 0xf2, 0xbb, 0xe8, 0xc1, 0xef, 0x18, 0x16, 0xfe, 0xef, 0x01, + 0xe1, 0xff, 0x19, 0xe4, 0x3e, 0x34, 0xe6, 0x1a, 0xe9, 0x29, 0xe5, 0xdf, 0x1c, + 0x2c, 0xf5, 0x0b, 0x13, 0x20, 0x0a, 0x2c, 0xd9, 0xc7, 0xbb, 0x0b, 0xd6, 0x03, + 0x01, 0xc5, 0xea, 0x57, 0xcd, 0xe7, 0x6b, 0x27, 0xf6, 0x3c, 0x29, 0xf4, 0x30, + 0xf1, 0xd8, 0xc1, 0x02, 0xf7, 0x35, 0xde, 0x7f, 0xec, 0x1f, 0xd0, 0xf5, 0x15, + 0xca, 0x05, 0xdb, 0xd0, 0xf7, 0x16, 0xf1, 0x0a, 0x06, 0x25, 0x07, 0x08, 0xff, + 0x35, 0xce, 0xd1, 0x2c, 0xf5, 0x0c, 0x13, 0xf1, 0x97, 0xe2, 0x13, 0xd9, 0x1b, + 0xf0, 0xf8, 0x18, 0xe6, 0xac, 0x24, 0xf0, 0xa1, 0x37, 0x0c, 0x09, 0x02, 0x31, + 0x40, 0xf5, 0xf9, 0xfa, 0x0e, 0xcd, 0x13, 0xc8, 0x09, 0xeb, 0xd9, 0xe5, 0xe0, + 0x34, 0xf9, 0x81, 0xed, 0xd9, 0xf3, 0xf4, 0x1c, 0x47, 0xf6, 0x08, 0xda, 0xff, + 0x00, 0x19, 0xb9, 0xf7, 0x30, 0xe8, 0xc6, 0xd8, 0xda, 0x01, 0xf5, 0x2b, 0xb1, + 0x57, 0x09, 0xce, 0x09, 0x3f, 0xdb, 0xad, 0xf5, 0xf6, 0xf9, 0x02, 0xdd, 0x21, + 0x3a, 0x81, 0xdf, 0x0d, 0x06, 0x2f, 0xd4, 0x34, 0xdd, 0xf5, 0x45, 0x02, 0xd6, + 0xf5, 0xd8, 0xfa, 0xe1, 0x10, 0xcd, 0x10, 0x2b, 0x09, 0x02, 0xff, 0x07, 0x00, + 0xd7, 0x0d, 0x22, 0xe9, 0x1c, 0xfb, 0x1a, 0xf3, 0x0b, 0xed, 0xa2, 0x1d, 0xd9, + 0xea, 0xfb, 0x33, 0x1d, 0xe3, 0x12, 0x66, 0x98, 0xee, 0x1e, 0x97, 0x10, 0xfb, + 0xc2, 0xef, 0x21, 0x03, 0x57, 0xbc, 0x06, 0x1d, 0x15, 0xee, 0xec, 0xf1, 0xe0, + 0xef, 0xe7, 0x08, 0x10, 0xf8, 0xe7, 0x2c, 0xfa, 0xff, 0x03, 0x37, 0x43, 0x14, + 0x22, 0x09, 0x01, 0xe9, 0x18, 0xd9, 0xf4, 0x0a, 0x1e, 0x13, 0xdf, 0x08, 0x2e, + 0xfa, 0x1e, 0x12, 0x1d, 0xe4, 0xc5, 0x2a, 0x5d, 0xed, 0xff, 0x22, 0xe7, 0x3b, + 0x0b, 0x3b, 0xf8, 0x12, 0x21, 0xf5, 0x0f, 0x31, 0xf0, 0x81, 0xfd, 0xbf, 0x0a, + 0x07, 0x3e, 0x03, 0x25, 0x35, 0xdf, 0xe4, 0xd8, 0xf0, 0xda, 0xa5, 0xc2, 0xc5, + 0xe8, 0xe5, 0x15, 0x2b, 0x0c, 0xf1, 0x0a, 0x22, 0xe6, 0xe2, 0xe5, 0x31, 0xef, + 0x17, 0x40, 0xfa, 0x3b, 0xf6, 0x3e, 0xc1, 0xd1, 0xdf, 0x00, 0x6e, 0x04, 0x7f, + 0xde, 0x13, 0xf7, 0x0e, 0x11, 0x37, 0xed, 0xa8, 0x23, 0x3e, 0x13, 0xe2, 0xec, + 0xfb, 0xf1, 0xef, 0xee, 0x0e, 0x0a, 0xfd, 0x02, 0xfd, 0x1b, 0x8d, 0x81, 0xf8, + 0x42, 0xf8, 0x30, 0x0a, 0xc8, 0xe0, 0x35, 0xe3, 0x20, 0x91, 0xc1, 0x03, 0x16, + 0x12, 0xec, 0xf5, 0xdd, 0x10, 0x04, 0xf4, 0x03, 0xf6, 0x2e, 0x29, 0xfc, 0x0f, + 0x15, 0x3d, 0x27, 0xe5, 0xd1, 0xd8, 0xdc, 0x70, 0xde, 0x12, 0x2e, 0x23, 0x05, + 0x09, 0xe2, 0xb8, 0x1b, 0x62, 0x18, 0x4f, 0x14, 0xfb, 0xd4, 0x12, 0x0c, 0x03, + 0xf3, 0xce, 0x43, 0xef, 0xed, 0x50, 0x3d, 0xb5, 0x1b, 0x09, 0x05, 0x00, 0x81, + 0xfd, 0x13, 0x42, 0xdc, 0xc5, 0x34, 0x1f, 0xf5, 0xe5, 0xc0, 0x47, 0x3f, 0xb7, + 0x29, 0x25, 0xb3, 0xed, 0x1c, 0x34, 0xc2, 0xdf, 0x97, 0xfd, 0xcd, 0xea, 0x2c, + 0x22, 0x1d, 0xc2, 0xd7, 0x95, 0x88, 0x26, 0xe0, 0xe3, 0x31, 0x32, 0x17, 0xe1, + 0x72, 0xcc, 0xfc, 0x93, 0xa9, 0xbf, 0xca, 0xc3, 0xcb, 0xf6, 0x29, 0x85, 0xfe, + 0x36, 0x15, 0x24, 0xac, 0x10, 0x28, 0xdf, 0x01, 0x10, 0x05, 0x0b, 0x0c, 0x74, + 0x2b, 0x09, 0x5d, 0xe9, 0xc6, 0xb5, 0xe7, 0x0f, 0xd5, 0xd9, 0x06, 0x01, 0xfd, + 0xc5, 0x1f, 0xc1, 0x03, 0xc4, 0x0b, 0xb4, 0x59, 0x3a, 0xe2, 0x09, 0xdf, 0xb6, + 0xe7, 0x81, 0xff, 0xdb, 0xcb, 0x4c, 0xdf, 0x0b, 0x28, 0x18, 0xfb, 0xf8, 0x13, + 0xdc, 0x02, 0xfe, 0xee, 0xde, 0xfe, 0xea, 0x19, 0x36, 0xe8, 0xe8, 0x02, 0x0d, + 0xa4, 0xa9, 0x27, 0x0f, 0x01, 0xe3, 0xd9, 0x1f, 0x26, 0xee, 0x17, 0xaa, 0xf9, + 0xff, 0x47, 0xf7, 0x23, 0xde, 0xbe, 0xfb, 0x11, 0xeb, 0xc8, 0x15, 0xce, 0xd5, + 0x0d, 0xe6, 0xe8, 0x15, 0x1b, 0xe7, 0x29, 0x59, 0xbb, 0xc0, 0xef, 0x3c, 0xfb, + 0x28, 0x15, 0x03, 0x27, 0x05, 0x7f, 0xf6, 0xb5, 0xcb, 0x05, 0xae, 0xe4, 0xb7, + 0x0f, 0x0b, 0x5f, 0x4c, 0xcd, 0xd6, 0x36, 0x27, 0x00, 0xc5, 0xfe, 0x13, 0xeb, + 0x07, 0x36, 0x4a, 0xb0, 0xdf, 0xfb, 0xef, 0xff, 0x03, 0x38, 0xb3, 0xaf, 0x0b, + 0x20, 0x0f, 0x01, 0x02, 0xea, 0xe9, 0x2d, 0xc7, 0x17, 0xd7, 0xe3, 0xfe, 0xe8, + 0xc2, 0x06, 0xfc, 0x3f, 0xf9, 0xc2, 0xf4, 0x1a, 0x12, 0x17, 0xf3, 0xe2, 0x32, + 0x07, 0xf5, 0x2d, 0xe3, 0xe5, 0xdc, 0x0a, 0x81, 0x03, 0xf7, 0x17, 0x09, 0xb9, + 0x08, 0x39, 0x6d, 0x2d, 0xe9, 0xef, 0x22, 0xec, 0x2f, 0x52, 0x28, 0xf8, 0xb8, + 0xfe, 0xe2, 0xfc, 0xf7, 0x07, 0x05, 0xff, 0x08, 0x41, 0x30, 0x0f, 0xc8, 0x2e, + 0x05, 0xcf, 0xdb, 0xf2, 0x06, 0xaf, 0xd4, 0xb2, 0x56, 0x30, 0xcd, 0xf5, 0x75, + 0xc5, 0xbc, 0x2a, 0x3f, 0xf9, 0xf9, 0xf4, 0x00, 0x6e, 0x16, 0xec, 0xea, 0x12, + 0xfd, 0x02, 0xf9, 0x93, 0x16, 0xd3, 0xf1, 0xbc, 0x9b, 0xe8, 0xdb, 0x29, 0xea, + 0x2b, 0x13, 0x07, 0xdb, 0x4f, 0xd4, 0x83, 0x0e, 0xdf, 0xfd, 0x7f, 0xd8, 0x1d, + 0xab, 0x08, 0xee, 0xc8, 0xe3, 0x28, 0xc3, 0x25, 0x0a, 0x48, 0x81, 0xf1, 0x02, + 0xcd, 0xea, 0xba, 0xd3, 0xde, 0x02, 0xe2, 0x0d, 0xe8, 0x3e, 0x03, 0x1a, 0xec, + 0x37, 0xcd, 0x03, 0x0f, 0xe8, 0xc5, 0x16, 0x34, 0xc8, 0xf8, 0xf9, 0x1b, 0x92, + 0x1b, 0xfa, 0xca, 0xe6, 0xda, 0x52, 0x08, 0x23, 0x3d, 0x03, 0x30, 0x2b, 0xfd, + 0xe8, 0x5c, 0xe5, 0x22, 0x0d, 0x18, 0xdb, 0x0e, 0x15, 0xb8, 0x1b, 0xe0, 0xd5, + 0xf1, 0xda, 0x15, 0xf4, 0xd2, 0x25, 0xe1, 0xde, 0xbd, 0xcd, 0xd1, 0x0f, 0x1a, + 0x5d, 0x40, 0xd7, 0xf2, 0xe8, 0x45, 0x2a, 0xe8, 0x21, 0x97, 0xe5, 0x22, 0x32, + 0xcd, 0x16, 0xce, 0xb9, 0x2d, 0x12, 0x23, 0x2c, 0x30, 0xc7, 0x4b, 0x33, 0x10, + 0xc1, 0xe5, 0x02, 0xeb, 0xdf, 0xf3, 0xff, 0xf1, 0x2c, 0xff, 0xe6, 0x09, 0x3e, + 0xc6, 0x2c, 0x06, 0xf7, 0x12, 0xdb, 0xe1, 0x04, 0xe0, 0xda, 0xc2, 0xd6, 0xfc, + 0x7f, 0x30, 0xf1, 0x34, 0x05, 0xec, 0x25, 0xdc, 0x2c, 0xf3, 0x2a, 0xf1, 0xf4, + 0xe6, 0xf5, 0x1f, 0xeb, 0x07, 0xd3, 0xf5, 0x11, 0x19, 0x17, 0xef, 0xc3, 0x7f, + 0xf8, 0xd6, 0xf5, 0xf0, 0xd0, 0xe4, 0x19, 0xb8, 0xe6, 0xbb, 0x1b, 0x34, 0xff, + 0xf5, 0xc6, 0xf8, 0x35, 0x46, 0x89, 0x52, 0xe6, 0xf5, 0x08, 0x05, 0x0a, 0x41, + 0x3a, 0xe2, 0xd8, 0xb5, 0xdc, 0xf2, 0xf6, 0x44, 0xc8, 0xca, 0x4e, 0x13, 0xa8, + 0x2f, 0x14, 0x26, 0xef, 0xf1, 0x14, 0x3a, 0xc4, 0x19, 0xef, 0x03, 0x01, 0x2f, + 0x03, 0x13, 0xcf, 0xd1, 0xbb, 0x22, 0xe2, 0xfc, 0x56, 0xee, 0x3d, 0xe9, 0x03, + 0x37, 0x4c, 0xb5, 0xc8, 0x22, 0x22, 0x00, 0xe0, 0xf7, 0x07, 0xcd, 0xcf, 0x14, + 0x01, 0x13, 0xcf, 0x15, 0x1e, 0xd4, 0xf8, 0xdd, 0xfc, 0x27, 0x32, 0x2a, 0xf0, + 0xcb, 0x2b, 0xcc, 0xdd, 0x13, 0x29, 0x09, 0x7f, 0x0f, 0x5d, 0xd7, 0xd5, 0x38, + 0xe0, 0x08, 0xfb, 0x24, 0x88, 0x81, 0xfd, 0xdf, 0x01, 0x00, 0x2e, 0xd8, 0xde, + 0xe9, 0xfa, 0x38, 0xd4, 0x9a, 0x4a, 0x32, 0xfc, 0xf7, 0xe1, 0x10, 0xab, 0xdd, + 0xdb, 0xd8, 0x5f, 0x33, 0xd9, 0x03, 0x1f, 0x1f, 0x25, 0x35, 0xd7, 0xcd, 0xea, + 0x39, 0xf1, 0xd5, 0xc3, 0x2a, 0xa6, 0xf7, 0x38, 0x06, 0xda, 0x19, 0xfc, 0xda, + 0x1b, 0xe1, 0x0b, 0x9b, 0x0b, 0x16, 0x26, 0xa1, 0xb2, 0x0f, 0x02, 0x04, 0x08, + 0x0d, 0x2a, 0x1d, 0xbc, 0x7f, 0xea, 0x14, 0x01, 0x19, 0x0b, 0x2e, 0xd5, 0xf7, + 0xe5, 0x1d, 0xc8, 0x3b, 0x25, 0xfa, 0x5d, 0x17, 0xf2, 0x2e, 0xfe, 0x12, 0xeb, + 0xca, 0xdb, 0xe2, 0x03, 0x2e, 0xcd, 0xfd, 0xfb, 0x11, 0x1a, 0xf2, 0x5b, 0xff, + 0x06, 0xfe, 0xd1, 0x36, 0xe4, 0xf6, 0x14, 0xe8, 0x22, 0x2c, 0x47, 0x21, 0x1f, + 0xd4, 0x26, 0xda, 0x09, 0xf4, 0x58, 0xf3, 0xd5, 0xf4, 0xdb, 0x2a, 0x36, 0x3b, + 0xe5, 0x0a, 0xdf, 0xd5, 0xe8, 0xed, 0x2e, 0x06, 0xc6, 0xd8, 0xf2, 0xfb, 0xfa, + 0xf0, 0xbb, 0x03, 0xf2, 0x02, 0xf7, 0xe3, 0xaa, 0x9f, 0x01, 0x17, 0xf4, 0xb7, + 0xbb, 0x55, 0xe1, 0xba, 0xc4, 0xf7, 0x07, 0xb7, 0x09, 0x08, 0xc7, 0xf6, 0x56, + 0xde, 0x7f, 0x09, 0xd3, 0x5f, 0x48, 0x1d, 0x59, 0x4b, 0xc4, 0x11, 0x03, 0xe7, + 0xb1, 0xab, 0xed, 0xed, 0x48, 0xe1, 0x05, 0xb6, 0x9f, 0xde, 0x1a, 0xac, 0xc9, + 0xeb, 0x04, 0xb4, 0xbd, 0xeb, 0x03, 0xe5, 0xc0, 0x20, 0x1c, 0xe9, 0x46, 0xf6, + 0x37, 0x60, 0xb2, 0x09, 0xc9, 0x2d, 0x1d, 0x79, 0x1a, 0xe4, 0x5d, 0xae, 0x30, + 0x41, 0x26, 0xe9, 0x09, 0xd5, 0x34, 0xe7, 0x15, 0xf3, 0x81, 0xbf, 0x26, 0xb5, + 0x93, 0x5b, 0xdb, 0x1d, 0x0c, 0xd9, 0xf8, 0xac, 0xeb, 0xa9, 0x45, 0x91, 0xa3, + 0x63, 0x01, 0x36, 0xb0, 0xc9, 0x33, 0x15, 0x4e, 0xfd, 0x21, 0xd0, 0x9e, 0xca, + 0xea, 0x44, 0xd9, 0x0b, 0x41, 0xe8, 0x1d, 0xe9, 0xdc, 0x28, 0x1b, 0xe2, 0xc5, + 0x10, 0x33, 0xc9, 0x08, 0x1b, 0x1f, 0x81, 0xed, 0xd8, 0x69, 0xd6, 0x08, 0xbd, + 0x3b, 0x07, 0x98, 0xf8, 0xd6, 0x63, 0x00, 0x1f, 0x0a, 0xbd, 0xf1, 0xf7, 0x00, + 0x21, 0x36, 0x10, 0xc1, 0x21, 0x22, 0x10, 0x5c, 0xd0, 0xf8, 0xbf, 0xd9, 0xf2, + 0x07, 0xe3, 0xf6, 0xca, 0xd6, 0x04, 0x05, 0xe3, 0xdd, 0x4e, 0xf8, 0xb4, 0xef, + 0x9d, 0xfc, 0x31, 0xd1, 0xdc, 0xe7, 0xd0, 0xc9, 0x7f, 0xea, 0xde, 0x21, 0x28, + 0x32, 0x10, 0xff, 0xe8, 0xc1, 0x1c, 0x1a, 0x0f, 0x51, 0xae, 0xcf, 0x0d, 0xbe, + 0x0a, 0xf2, 0x28, 0x02, 0xfe, 0xfb, 0xca, 0xb8, 0xdb, 0x9c, 0x0a, 0xcc, 0xdc, + 0x9a, 0xfb, 0x8d, 0x8c, 0xef, 0x0b, 0x1f, 0x48, 0xc8, 0x27, 0x10, 0xaf, 0x26, + 0x1a, 0x31, 0x88, 0xae, 0x1f, 0x1a, 0x07, 0x09, 0xbb, 0xc0, 0xd5, 0x7f, 0x02, + 0xdd, 0xac, 0x6b, 0x10, 0xfc, 0x2a, 0x2a, 0xf2, 0x21, 0xe2, 0xc7, 0x9c, 0x1d, + 0x15, 0xfd, 0xf1, 0x37, 0xa4, 0x41, 0xe6, 0x1e, 0xf5, 0x42, 0x03, 0xf9, 0x14, + 0xee, 0xb9, 0x44, 0x7c, 0xfa, 0x16, 0xf8, 0x78, 0xff, 0x10, 0xa1, 0xd1, 0x40, + 0x11, 0xc6, 0xd2, 0x08, 0x10, 0xe3, 0xef, 0x16, 0x26, 0xe1, 0x1e, 0x1c, 0x46, + 0x31, 0x0b, 0x3a, 0x10, 0x93, 0x0a, 0xe6, 0x33, 0x26, 0x10, 0xef, 0x07, 0xf5, + 0xf1, 0x03, 0x12, 0xc1, 0xcc, 0x25, 0x0a, 0x1f, 0xe8, 0x1b, 0xce, 0x17, 0x28, + 0x0f, 0x0a, 0x33, 0xd0, 0x06, 0x2f, 0xf2, 0x01, 0xf2, 0xe8, 0xdd, 0xd8, 0xff, + 0x02, 0xfe, 0xd2, 0x09, 0xf3, 0x81, 0xe5, 0xf8, 0xf8, 0x1e, 0x35, 0xd4, 0xf5, + 0xf0, 0x42, 0xed, 0xc3, 0x04, 0x00, 0x17, 0xef, 0x2d, 0x1d, 0xdf, 0xc6, 0xfe, + 0xf4, 0xf7, 0x46, 0x08, 0xe2, 0xee, 0xf1, 0xd2, 0x04, 0xf7, 0x24, 0xd5, 0xdf, + 0xf6, 0xd8, 0xeb, 0xd6, 0x08, 0xec, 0x0e, 0xc8, 0x1e, 0xe8, 0x09, 0x05, 0xb3, + 0xf9, 0xfe, 0xe8, 0xe8, 0xe5, 0xe5, 0x39, 0x7f, 0xa4, 0x34, 0x45, 0xc3, 0xcc, + 0xfc, 0xec, 0xe5, 0xf0, 0xf7, 0xf2, 0x05, 0x00, 0x29, 0x0a, 0x09, 0x01, 0x38, + 0x02, 0xdd, 0xdc, 0x32, 0xe1, 0xd3, 0xe7, 0xf5, 0xbc, 0xf3, 0xf9, 0xe5, 0x2e, + 0xeb, 0xeb, 0xee, 0xe9, 0x34, 0xd5, 0x01, 0xda, 0xe3, 0xc3, 0xae, 0x38, 0xbf, + 0xde, 0xeb, 0x0a, 0x6c, 0x23, 0x72, 0x01, 0xfd, 0xc5, 0x41, 0x35, 0x18, 0x01, + 0x7f, 0x15, 0xe5, 0xbb, 0x3d, 0xd6, 0xe9, 0xd2, 0x26, 0xc1, 0xef, 0xf9, 0x37, + 0xbc, 0xb8, 0x31, 0x4d, 0x0e, 0x42, 0xef, 0x46, 0x0d, 0x3f, 0x23, 0xfd, 0xc0, + 0xd6, 0xeb, 0x24, 0xf3, 0x45, 0x63, 0x15, 0xdc, 0xe5, 0x1a, 0xe4, 0x17, 0xfe, + 0x15, 0x0f, 0x03, 0xf1, 0xee, 0xfd, 0xec, 0x1b, 0x3a, 0xbc, 0xb4, 0xfd, 0x23, + 0x25, 0x01, 0xe5, 0x81, 0x10, 0xf0, 0xe9, 0x32, 0xf4, 0x15, 0x0e, 0xd9, 0x23, + 0xbb, 0xfd, 0x3d, 0x06, 0x0e, 0x12, 0xa4, 0x0f, 0xcb, 0xfd, 0x0c, 0x0a, 0x0c, + 0xee, 0x06, 0xa3, 0x00, 0x08, 0x20, 0x2e, 0x4f, 0xee, 0x0f, 0x41, 0x38, 0xe6, + 0xcc, 0x16, 0x42, 0xc0, 0xcc, 0x20, 0x1c, 0x0b, 0x00, 0x1b, 0xde, 0x47, 0xd8, + 0x08, 0xe3, 0x37, 0xfb, 0xfd, 0xdb, 0xc9, 0x08, 0xe9, 0x06, 0xc4, 0x10, 0xf2, + 0xe9, 0xe0, 0xcd, 0xda, 0x04, 0x01, 0x1e, 0x11, 0xd1, 0xb9, 0xff, 0x1c, 0xde, + 0x14, 0xdd, 0xe7, 0x4e, 0x01, 0xeb, 0xb2, 0x61, 0x2c, 0x4b, 0x02, 0xd9, 0x09, + 0xde, 0xc8, 0x06, 0x22, 0x0e, 0x03, 0xe2, 0xf7, 0x18, 0xf0, 0xfe, 0xd2, 0xf7, + 0xe2, 0x2c, 0x1b, 0x2e, 0xf9, 0xf1, 0xdc, 0x18, 0x02, 0x81, 0xe9, 0x06, 0xc5, + 0x22, 0x52, 0x89, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x78, 0xd8, 0xff, 0xff, 0x28, 0x26, 0x00, 0x00, 0xc4, 0x0d, 0x00, 0x00, 0xd4, + 0x0e, 0x00, 0x00, 0xf0, 0x1a, 0x00, 0x00, 0x24, 0x27, 0x00, 0x00, 0x00, 0xd6, + 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0xbd, 0xd6, 0xff, 0xff, 0x0c, 0xf2, 0xff, + 0xff, 0xbd, 0x01, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x00, 0xce, 0xe2, 0xff, 0xff, + 0x78, 0x5d, 0x00, 0x00, 0x93, 0x50, 0x00, 0x00, 0xb4, 0xd4, 0xff, 0xff, 0x18, + 0xfb, 0xff, 0xff, 0x2c, 0x06, 0x00, 0x00, 0xa4, 0x4b, 0x00, 0x00, 0x3e, 0x59, + 0x00, 0x00, 0x9f, 0x3f, 0x00, 0x00, 0x71, 0x21, 0x00, 0x00, 0xc5, 0x3e, 0x00, + 0x00, 0xc6, 0xc0, 0xff, 0xff, 0x21, 0x18, 0x00, 0x00, 0xd1, 0x7a, 0x00, 0x00, + 0xe1, 0xe7, 0xff, 0xff, 0x83, 0x29, 0x00, 0x00, 0xb5, 0x26, 0x00, 0x00, 0xf0, + 0x33, 0x00, 0x00, 0x96, 0x5a, 0x00, 0x00, 0x15, 0x1d, 0x00, 0x00, 0x21, 0xf2, + 0xff, 0xff, 0xd9, 0x3e, 0x00, 0x00, 0xec, 0x04, 0x00, 0x00, 0x8c, 0xe4, 0xff, + 0xff, 0xa8, 0xf6, 0xff, 0xff, 0x16, 0x43, 0x00, 0x00, 0xdf, 0xd2, 0xff, 0xff, + 0xf7, 0x06, 0x00, 0x00, 0x3a, 0x2d, 0x00, 0x00, 0x3f, 0x34, 0x00, 0x00, 0x1d, + 0x27, 0x00, 0x00, 0x16, 0x4e, 0x00, 0x00, 0x28, 0x11, 0x00, 0x00, 0x8c, 0x03, + 0x00, 0x00, 0x1f, 0x43, 0x00, 0x00, 0x1c, 0xd5, 0xff, 0xff, 0x3a, 0x11, 0x00, + 0x00, 0x4b, 0x3e, 0x00, 0x00, 0x43, 0x1d, 0x00, 0x00, 0xcf, 0x27, 0x00, 0x00, + 0x60, 0xc6, 0xff, 0xff, 0xc1, 0xcd, 0xff, 0xff, 0x97, 0x18, 0x00, 0x00, 0x57, + 0x22, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x85, 0x15, 0x00, 0x00, 0x16, 0x10, + 0x00, 0x00, 0x50, 0xd2, 0xff, 0xff, 0x04, 0xff, 0xff, 0xff, 0x9f, 0xf9, 0xff, + 0xff, 0x9a, 0x58, 0x00, 0x00, 0x1c, 0xed, 0xff, 0xff, 0x8d, 0x21, 0x00, 0x00, + 0xd1, 0x34, 0x00, 0x00, 0x54, 0x5c, 0x00, 0x00, 0x29, 0xf5, 0xff, 0xff, 0x91, + 0x2b, 0x00, 0x00, 0x27, 0x0d, 0x00, 0x00, 0x72, 0x15, 0x00, 0x00, 0xc2, 0x15, + 0x00, 0x00, 0xcf, 0xce, 0xff, 0xff, 0x34, 0x20, 0x00, 0x00, 0xb3, 0x07, 0x00, + 0x00, 0x02, 0x6c, 0x00, 0x00, 0x86, 0x41, 0x00, 0x00, 0xf2, 0x2e, 0x00, 0x00, + 0x32, 0xc9, 0xff, 0xff, 0x1d, 0xf4, 0xff, 0xff, 0x1d, 0xfc, 0xff, 0xff, 0xf9, + 0x1c, 0x00, 0x00, 0x40, 0xfa, 0xff, 0xff, 0x1d, 0x59, 0x00, 0x00, 0x26, 0x0e, + 0x00, 0x00, 0x5b, 0x0e, 0x00, 0x00, 0x68, 0x08, 0x00, 0x00, 0xed, 0x54, 0x00, + 0x00, 0x83, 0x07, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00, 0x1b, 0x32, 0x00, 0x00, + 0xd0, 0xf1, 0xff, 0xff, 0x33, 0x0f, 0x00, 0x00, 0x37, 0x54, 0x00, 0x00, 0x66, + 0x15, 0x00, 0x00, 0x0d, 0xea, 0xff, 0xff, 0x82, 0xdc, 0xff, 0xff, 0xd7, 0x34, + 0x00, 0x00, 0x98, 0xf7, 0xff, 0xff, 0x6c, 0x13, 0x00, 0x00, 0xfd, 0x46, 0x00, + 0x00, 0x82, 0xe1, 0xff, 0xff, 0xca, 0x54, 0x00, 0x00, 0xaf, 0x29, 0x00, 0x00, + 0x22, 0xf5, 0xff, 0xff, 0x89, 0x13, 0x00, 0x00, 0x9c, 0xf1, 0xff, 0xff, 0xcd, + 0x8d, 0x00, 0x00, 0x2a, 0x41, 0x00, 0x00, 0x86, 0x0d, 0x00, 0x00, 0x44, 0x2a, + 0x00, 0x00, 0x7d, 0x3f, 0x00, 0x00, 0x6c, 0x25, 0x00, 0x00, 0x7f, 0x0e, 0x00, + 0x00, 0xbd, 0x2b, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, 0xf2, 0x4b, 0x00, 0x00, + 0x11, 0xee, 0xff, 0xff, 0x0c, 0x3c, 0x00, 0x00, 0x42, 0x45, 0x00, 0x00, 0x10, + 0x45, 0x00, 0x00, 0xa7, 0x7f, 0x00, 0x00, 0x3b, 0xf5, 0xff, 0xff, 0x19, 0x2e, + 0x00, 0x00, 0xbd, 0x41, 0x00, 0x00, 0xd7, 0xd8, 0xff, 0xff, 0xbd, 0x30, 0x00, + 0x00, 0x77, 0x55, 0x00, 0x00, 0x5e, 0x8b, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x00, 0x00, 0xa6, 0xde, 0xf3, 0xa5, 0xde, 0xdb, 0xc4, 0xf3, 0x2a, + 0xd5, 0xdf, 0x81, 0x02, 0xe1, 0xd8, 0x0c, 0xc8, 0x19, 0xca, 0x11, 0xc6, 0xd7, + 0x37, 0x7f, 0x23, 0xd5, 0x0a, 0x10, 0x81, 0x15, 0xab, 0x9c, 0xef, 0x9b, 0x94, + 0xe8, 0xb2, 0x3f, 0x51, 0xe5, 0x0c, 0x23, 0xed, 0x32, 0xb7, 0x81, 0x85, 0x17, + 0x03, 0x0c, 0xb9, 0xba, 0x81, 0xfb, 0x0d, 0xeb, 0x10, 0x7f, 0x35, 0xee, 0x00, + 0xbb, 0x08, 0xe8, 0xe6, 0xe3, 0xe4, 0xd9, 0x32, 0x7f, 0x36, 0xe2, 0x28, 0x48, + 0xdc, 0xe6, 0x8c, 0xc4, 0x49, 0xae, 0xc9, 0xf4, 0xf2, 0xe8, 0xee, 0x7f, 0xf3, + 0xa1, 0xa6, 0xec, 0x07, 0x56, 0x7f, 0xf8, 0x39, 0xb6, 0xdf, 0x05, 0x64, 0xdd, + 0x63, 0x18, 0xea, 0xba, 0xea, 0x73, 0x32, 0x99, 0x41, 0x02, 0x09, 0xee, 0xe2, + 0x05, 0xeb, 0xde, 0xed, 0xfe, 0x04, 0xcd, 0xf8, 0x99, 0x5a, 0xe1, 0xcb, 0x32, + 0x33, 0xae, 0x3b, 0x41, 0x03, 0x3a, 0x84, 0x42, 0x81, 0xb6, 0x57, 0x0e, 0xa6, + 0x4a, 0x0d, 0xcd, 0x34, 0x8e, 0x7f, 0x7f, 0x57, 0xe8, 0x16, 0xcb, 0x7f, 0x35, + 0xd5, 0xb4, 0x27, 0x5d, 0xad, 0x8f, 0xe4, 0xb9, 0x35, 0xcd, 0xc9, 0xfb, 0x9f, + 0x7f, 0x7f, 0xb4, 0x69, 0xd2, 0x62, 0x7f, 0xb1, 0xd6, 0xd4, 0xd0, 0x7f, 0x29, + 0xed, 0xd9, 0x70, 0x03, 0xad, 0xc7, 0x17, 0x5a, 0x2e, 0xe1, 0x01, 0x24, 0xb8, + 0x17, 0xd1, 0xf4, 0xe5, 0x61, 0x59, 0xed, 0xf0, 0x11, 0x7f, 0xe5, 0x1d, 0xb7, + 0xf9, 0x91, 0x43, 0xf8, 0xe9, 0xac, 0xf4, 0x9c, 0xab, 0x65, 0x23, 0x53, 0xd4, + 0xfb, 0x4c, 0xdc, 0x65, 0xa5, 0x49, 0xd6, 0x22, 0x7f, 0x7f, 0xd0, 0xbb, 0xd4, + 0x0f, 0x81, 0x81, 0x7f, 0xe2, 0x81, 0x26, 0xcc, 0x7f, 0x10, 0xc4, 0xf9, 0x8c, + 0xff, 0xd2, 0xd8, 0x7f, 0xcf, 0xd3, 0x81, 0x7f, 0x81, 0xcb, 0x7f, 0x7f, 0x81, + 0x0a, 0x18, 0xe2, 0x17, 0x81, 0x14, 0xb5, 0x44, 0xe3, 0xc4, 0xdd, 0x4b, 0xf0, + 0xe7, 0xd3, 0x83, 0x39, 0x20, 0x20, 0xf1, 0x04, 0xf3, 0x11, 0x2d, 0xe8, 0x81, + 0xd5, 0xf4, 0xa0, 0x04, 0xb1, 0x0a, 0x10, 0xc4, 0x9d, 0xfe, 0xbc, 0x24, 0x65, + 0xe8, 0x8a, 0x15, 0xc9, 0xa4, 0xbc, 0x81, 0x81, 0xe7, 0xcc, 0xe1, 0xda, 0xc3, + 0x56, 0x0c, 0x9b, 0xd8, 0xfa, 0xc3, 0x03, 0xe7, 0x07, 0x28, 0xff, 0xf1, 0xfd, + 0xc1, 0xf0, 0x3a, 0xae, 0x7c, 0xff, 0xe0, 0x0f, 0xd8, 0x08, 0xdc, 0x6e, 0xd4, + 0x26, 0xe0, 0x7f, 0xf7, 0x00, 0x2e, 0xdf, 0x00, 0xf8, 0x48, 0xa4, 0xf8, 0xea, + 0xbd, 0x2b, 0xd6, 0x11, 0xe0, 0xe1, 0x1a, 0x03, 0x0d, 0xba, 0x23, 0xe7, 0xc3, + 0xe9, 0x5a, 0xd0, 0xa2, 0x2b, 0xff, 0xe8, 0xee, 0xdb, 0x01, 0xe1, 0xc1, 0xe9, + 0x13, 0xfd, 0x53, 0x67, 0xb2, 0xe2, 0xe3, 0x38, 0x5b, 0x04, 0xb9, 0xbb, 0x17, + 0x17, 0x81, 0xce, 0x32, 0xe6, 0x48, 0x19, 0x3b, 0x35, 0xb7, 0x0b, 0x00, 0xa9, + 0xb2, 0xe5, 0xcb, 0xec, 0x7f, 0xe1, 0xd6, 0xd3, 0x37, 0xe1, 0xc0, 0xa5, 0xbd, + 0xc6, 0x0b, 0xbd, 0xaa, 0x6a, 0x7f, 0x35, 0xe2, 0xaf, 0xf1, 0xea, 0xb1, 0xf9, + 0x7f, 0x7f, 0x4d, 0xbc, 0xa7, 0x29, 0x7f, 0xd4, 0xff, 0x20, 0x32, 0x8b, 0x78, + 0xa7, 0xc6, 0x17, 0xe8, 0xa8, 0xcf, 0xbf, 0xbb, 0x7f, 0x7f, 0xc3, 0xaa, 0x35, + 0xf2, 0x54, 0xda, 0x7f, 0xfb, 0x15, 0xdc, 0xaf, 0xff, 0x91, 0xb2, 0x08, 0xf1, + 0xf1, 0x1f, 0xe3, 0xa2, 0xbc, 0xdc, 0x01, 0xec, 0x07, 0xf1, 0x33, 0x7a, 0x28, + 0xeb, 0x7f, 0x32, 0x0b, 0xe4, 0xe3, 0x7f, 0x98, 0xc8, 0xda, 0x90, 0xce, 0xde, + 0x3d, 0x92, 0x85, 0xf8, 0xe6, 0x0d, 0xcd, 0xcb, 0xb7, 0xeb, 0xb8, 0x7f, 0x24, + 0xe8, 0xfb, 0x92, 0x11, 0x96, 0x47, 0xca, 0xe0, 0xac, 0x7f, 0x7f, 0x4e, 0x11, + 0xdc, 0x7f, 0xa4, 0x81, 0x7f, 0x7f, 0xf2, 0x3f, 0x7f, 0x7f, 0x81, 0x01, 0xdd, + 0xe3, 0x7f, 0xd5, 0x7f, 0xca, 0xed, 0x4c, 0x07, 0xaa, 0x06, 0x7f, 0xd2, 0x7f, + 0x81, 0x81, 0x7f, 0x30, 0x7f, 0xaf, 0xca, 0xc9, 0xfd, 0x81, 0x7f, 0x2c, 0x1d, + 0x7e, 0x81, 0x95, 0x48, 0xe3, 0x1f, 0x58, 0x7f, 0x7f, 0x24, 0x7f, 0x81, 0x81, + 0x7f, 0xdd, 0xf1, 0x93, 0xef, 0x8e, 0xb0, 0xfb, 0x81, 0x81, 0x7f, 0x7f, 0x7f, + 0xe9, 0x1d, 0x7f, 0x36, 0x81, 0x7f, 0x7f, 0xa6, 0x81, 0x7f, 0x81, 0xa2, 0x7f, + 0x22, 0x81, 0x81, 0xa3, 0x7f, 0x7f, 0x6e, 0x7f, 0x7f, 0xe4, 0x04, 0x81, 0xfb, + 0xff, 0x7f, 0x02, 0x72, 0xdb, 0x16, 0xc2, 0xed, 0xdf, 0x9d, 0xb4, 0x34, 0xaa, + 0x81, 0x7f, 0xea, 0x7f, 0x81, 0xcc, 0x81, 0x7f, 0x81, 0xfd, 0x5c, 0xd2, 0x7f, + 0x15, 0x55, 0xbc, 0x04, 0xf4, 0xe7, 0xb3, 0x67, 0x1e, 0x1e, 0x6f, 0x4c, 0x39, + 0xe6, 0x56, 0x39, 0x1c, 0x51, 0xf4, 0x09, 0xe8, 0xa8, 0x53, 0x29, 0xc6, 0xfa, + 0x13, 0xe3, 0xf6, 0xbd, 0xf6, 0x75, 0xa9, 0x81, 0xc9, 0xbf, 0xf3, 0xc1, 0x17, + 0xd3, 0x1c, 0x2a, 0x03, 0xd2, 0x1c, 0xc8, 0xd2, 0x0f, 0x6c, 0xa7, 0xea, 0x33, + 0xab, 0x3a, 0xe6, 0xe3, 0xe4, 0xf9, 0x26, 0x65, 0x19, 0xb2, 0xd0, 0x23, 0xfe, + 0x1c, 0x11, 0xe2, 0xee, 0xf4, 0xcb, 0xb0, 0xd2, 0x0f, 0x23, 0xc3, 0xfd, 0x63, + 0x0e, 0x04, 0xb7, 0x35, 0xfe, 0x7f, 0x84, 0x4d, 0x05, 0x64, 0xe2, 0xf0, 0x26, + 0xa9, 0xbc, 0x2f, 0xf6, 0xe8, 0xef, 0x1c, 0xcd, 0xc6, 0xc0, 0xab, 0x8f, 0x16, + 0xec, 0xe6, 0xe3, 0x7f, 0x40, 0xe9, 0x9d, 0xb6, 0xdb, 0xaa, 0xad, 0x83, 0xf8, + 0x08, 0xf3, 0xd9, 0x7f, 0xd4, 0xc4, 0x19, 0x8c, 0x0f, 0x7f, 0xb9, 0x92, 0x10, + 0x97, 0x7f, 0xce, 0xd6, 0x9d, 0x06, 0x0c, 0xfb, 0xd9, 0xf2, 0x1b, 0xe2, 0xf0, + 0xcc, 0x34, 0x7f, 0xd6, 0xe1, 0x03, 0xf2, 0xb1, 0xf0, 0xdf, 0x09, 0x21, 0xf7, + 0x4e, 0xff, 0x24, 0xfa, 0xe1, 0xcb, 0xf5, 0xcc, 0xdc, 0xc4, 0xf7, 0xf5, 0x4b, + 0xfb, 0x3f, 0xef, 0xab, 0xe4, 0xf8, 0x08, 0xea, 0x64, 0xfc, 0x2d, 0x17, 0x0c, + 0x19, 0xdd, 0xa7, 0x35, 0x08, 0xa6, 0x09, 0xfa, 0xfc, 0x02, 0xef, 0xb2, 0x72, + 0x31, 0xc9, 0xff, 0x1c, 0xde, 0xa8, 0x05, 0xfe, 0xb5, 0xc9, 0x0a, 0xdd, 0xfd, + 0x17, 0x2d, 0xfd, 0xe4, 0xe0, 0xe9, 0x06, 0xf2, 0xf8, 0x10, 0xc2, 0xed, 0xde, + 0xc7, 0x0d, 0x4c, 0xf1, 0xf3, 0x7f, 0xd2, 0x08, 0x23, 0x1e, 0xdc, 0xf6, 0xfb, + 0x5c, 0x95, 0x2a, 0x16, 0xe4, 0xc9, 0xdb, 0x7f, 0xed, 0x55, 0xff, 0x06, 0xdb, + 0xe3, 0xe6, 0xda, 0xe9, 0xb2, 0x3d, 0xc9, 0xef, 0x43, 0x9d, 0xf5, 0xdc, 0x12, + 0x06, 0xd8, 0xc7, 0x5f, 0xf4, 0x7f, 0x29, 0x43, 0x4e, 0xd3, 0x12, 0x4a, 0x5a, + 0x06, 0xe9, 0x31, 0xf3, 0x90, 0x7f, 0xac, 0xf8, 0xd1, 0xce, 0xf4, 0x7f, 0xe1, + 0x34, 0x7f, 0xdf, 0xa9, 0xfc, 0x01, 0x39, 0xc5, 0xff, 0x52, 0x06, 0x57, 0x7f, + 0x81, 0xb5, 0x92, 0xae, 0xed, 0x0a, 0x03, 0xeb, 0xb7, 0xbb, 0x63, 0x0f, 0x52, + 0x7f, 0x46, 0x46, 0xe1, 0xd7, 0x5f, 0xb4, 0x10, 0xee, 0x81, 0x52, 0x7f, 0x81, + 0xeb, 0xc3, 0xa3, 0xc2, 0xfd, 0xfc, 0x9d, 0x00, 0x5a, 0x0f, 0x20, 0xae, 0xae, + 0xfa, 0xdb, 0x2e, 0xd2, 0xa4, 0x0c, 0x1d, 0x7f, 0xb3, 0xd5, 0xc3, 0x0c, 0xef, + 0x7f, 0xf2, 0xf4, 0xd1, 0xbb, 0xab, 0x23, 0x7f, 0x43, 0x0d, 0xf8, 0xec, 0x40, + 0x7f, 0x7f, 0xdf, 0xf0, 0xf3, 0x1b, 0xd9, 0xe3, 0x59, 0xbc, 0xe5, 0xc4, 0xed, + 0x0b, 0x08, 0xc4, 0x02, 0xf3, 0xe3, 0x3f, 0xbd, 0xc8, 0xf1, 0xbf, 0xc5, 0xdb, + 0xdf, 0x4d, 0xd9, 0x05, 0xf1, 0x29, 0x3e, 0xe3, 0xf7, 0xfe, 0x19, 0x15, 0x0c, + 0xe2, 0x02, 0x00, 0x63, 0xda, 0xd6, 0xf9, 0xe7, 0x01, 0x2a, 0x0d, 0xe7, 0x77, + 0xee, 0xae, 0xeb, 0xcb, 0xf3, 0xe0, 0xfc, 0x2d, 0xfb, 0xfe, 0x04, 0x1a, 0xc5, + 0xbd, 0xf0, 0x46, 0xfa, 0x93, 0x02, 0x1d, 0xfd, 0xfe, 0xf4, 0xd2, 0x0c, 0x23, + 0x01, 0x0b, 0xc9, 0x20, 0xf0, 0xfe, 0xff, 0x99, 0x7f, 0xfb, 0xeb, 0xea, 0xef, + 0xfe, 0xb6, 0xf9, 0x11, 0xca, 0xa1, 0xd9, 0xe6, 0xf2, 0xc4, 0xd9, 0xf8, 0x12, + 0xa3, 0xfc, 0x1c, 0x03, 0xdf, 0x1e, 0xc5, 0xe3, 0xce, 0xd6, 0xf8, 0x23, 0xe9, + 0x02, 0x91, 0xd2, 0xee, 0xee, 0x3c, 0x0b, 0xec, 0xde, 0xd5, 0x4d, 0x13, 0x25, + 0xf7, 0xa1, 0xd1, 0xca, 0xfb, 0xd1, 0xf6, 0x07, 0xea, 0xd6, 0x28, 0xf0, 0xd6, + 0x0b, 0xca, 0xc3, 0xfd, 0xb4, 0xb1, 0xf7, 0xc8, 0xda, 0x05, 0xf6, 0xd0, 0xea, + 0x8f, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xab, 0xe6, + 0xff, 0xff, 0x26, 0x01, 0x00, 0x00, 0xae, 0x02, 0x00, 0x00, 0x85, 0xe8, 0xff, + 0xff, 0xb4, 0xeb, 0xff, 0xff, 0xd0, 0xf5, 0xff, 0xff, 0x1e, 0x0f, 0x00, 0x00, + 0x6b, 0xeb, 0xff, 0xff, 0x4b, 0xe6, 0xff, 0xff, 0xe5, 0xe6, 0xff, 0xff, 0x2e, + 0xf1, 0xff, 0xff, 0x46, 0x01, 0x00, 0x00, 0xa6, 0x15, 0x00, 0x00, 0x32, 0xfe, + 0xff, 0xff, 0x8a, 0x09, 0x00, 0x00, 0xf4, 0xeb, 0xff, 0xff, 0xa7, 0xf8, 0xff, + 0xff, 0xeb, 0xfa, 0xff, 0xff, 0xd0, 0x1f, 0x00, 0x00, 0x0c, 0x24, 0x00, 0x00, + 0x9b, 0xfc, 0xff, 0xff, 0x0c, 0xff, 0xff, 0xff, 0x77, 0xe0, 0xff, 0xff, 0x9a, + 0xef, 0xff, 0xff, 0x19, 0x08, 0x00, 0x00, 0x67, 0x22, 0x00, 0x00, 0xe0, 0x17, + 0x00, 0x00, 0xb6, 0xe9, 0xff, 0xff, 0xbc, 0xef, 0xff, 0xff, 0x33, 0xff, 0xff, + 0xff, 0x8b, 0xf9, 0xff, 0xff, 0x52, 0xdb, 0xff, 0xff, 0x91, 0x0c, 0x00, 0x00, + 0x14, 0xff, 0xff, 0xff, 0x1e, 0xf4, 0xff, 0xff, 0xbf, 0xfd, 0xff, 0xff, 0xf3, + 0xe5, 0xff, 0xff, 0x29, 0xf1, 0xff, 0xff, 0x15, 0x14, 0x00, 0x00, 0x10, 0x23, + 0x00, 0x00, 0xd7, 0x17, 0x00, 0x00, 0xfc, 0x29, 0x00, 0x00, 0x12, 0x15, 0x00, + 0x00, 0x92, 0xf9, 0xff, 0xff, 0xbb, 0x13, 0x00, 0x00, 0x45, 0xe5, 0xff, 0xff, + 0x26, 0xf6, 0xff, 0xff, 0x32, 0xf9, 0xff, 0xff, 0x46, 0x0c, 0x00, 0x00, 0x0e, + 0x2a, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x78, 0xf5, 0xff, 0xff, 0xaa, 0xf0, + 0xff, 0xff, 0x22, 0xec, 0xff, 0xff, 0xbe, 0x21, 0x00, 0x00, 0x5d, 0xf9, 0xff, + 0xff, 0xea, 0xe7, 0xff, 0xff, 0xb7, 0x2f, 0x00, 0x00, 0xce, 0xf8, 0xff, 0xff, + 0x90, 0x2e, 0x00, 0x00, 0xe5, 0x26, 0x00, 0x00, 0xe1, 0xf2, 0xff, 0xff, 0x33, + 0xf9, 0xff, 0xff, 0x9f, 0x14, 0x00, 0x00, 0x99, 0x1e, 0x00, 0x00, 0x9d, 0xf9, + 0xff, 0xff, 0xef, 0xdb, 0xff, 0xff, 0x45, 0xf0, 0xff, 0xff, 0x08, 0xf4, 0xff, + 0xff, 0x3f, 0xf2, 0xff, 0xff, 0x12, 0xf1, 0xff, 0xff, 0x69, 0xf0, 0xff, 0xff, + 0xd7, 0xeb, 0xff, 0xff, 0xac, 0xcf, 0xff, 0xff, 0xca, 0xe7, 0xff, 0xff, 0x89, + 0xf2, 0xff, 0xff, 0xe6, 0x26, 0x00, 0x00, 0x6d, 0xf1, 0xff, 0xff, 0xee, 0xd4, + 0xff, 0xff, 0xca, 0xfa, 0xff, 0xff, 0x42, 0xec, 0xff, 0xff, 0x20, 0x22, 0x00, + 0x00, 0x71, 0x03, 0x00, 0x00, 0xcd, 0xeb, 0xff, 0xff, 0x15, 0x2a, 0x00, 0x00, + 0xe0, 0xec, 0xff, 0xff, 0x3f, 0xf9, 0xff, 0xff, 0x2c, 0xff, 0xff, 0xff, 0x06, + 0xfa, 0xff, 0xff, 0x72, 0xfe, 0xff, 0xff, 0xf7, 0xfd, 0xff, 0xff, 0xe9, 0xfd, + 0xff, 0xff, 0xcb, 0xf1, 0xff, 0xff, 0xe7, 0xe4, 0xff, 0xff, 0xef, 0xfd, 0xff, + 0xff, 0x80, 0xf6, 0xff, 0xff, 0x1e, 0x06, 0x00, 0x00, 0xdb, 0xfa, 0xff, 0xff, + 0x1c, 0xe5, 0xff, 0xff, 0x24, 0xf5, 0xff, 0xff, 0xfb, 0x1a, 0x00, 0x00, 0xb4, + 0x1c, 0x00, 0x00, 0x18, 0x3a, 0x00, 0x00, 0x02, 0xef, 0xff, 0xff, 0x71, 0x22, + 0x00, 0x00, 0xe1, 0xf2, 0xff, 0xff, 0x7f, 0xef, 0xff, 0xff, 0xd6, 0x02, 0x00, + 0x00, 0x16, 0xf8, 0xff, 0xff, 0x87, 0xf5, 0xff, 0xff, 0x33, 0xff, 0xff, 0xff, + 0x62, 0xfb, 0xff, 0xff, 0x1d, 0x22, 0x00, 0x00, 0x5d, 0xf4, 0xff, 0xff, 0x09, + 0x0b, 0x00, 0x00, 0xd5, 0xd6, 0xff, 0xff, 0x5a, 0xf3, 0xff, 0xff, 0x6c, 0xfe, + 0xff, 0xff, 0x7c, 0xff, 0xff, 0xff, 0x6b, 0x25, 0x00, 0x00, 0x0a, 0xda, 0xff, + 0xff, 0x7d, 0xf8, 0xff, 0xff, 0xac, 0xf3, 0xff, 0xff, 0x71, 0xf9, 0xff, 0xff, + 0x39, 0xf3, 0xff, 0xff, 0x2d, 0xd4, 0xff, 0xff, 0x33, 0xfc, 0xff, 0xff, 0xff, + 0xf2, 0xff, 0xff, 0xf6, 0x91, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0xba, 0xcf, 0x85, 0xce, 0x0c, 0x9f, 0xff, 0xeb, 0x0c, 0xa5, 0xda, + 0xeb, 0x12, 0xda, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x9f, 0xe6, 0x09, 0xef, 0xed, + 0x02, 0xf9, 0x4f, 0xe9, 0x44, 0xae, 0x5c, 0x4d, 0xf2, 0xe7, 0xd9, 0x31, 0xf8, + 0xd0, 0xd3, 0x2d, 0x03, 0xdc, 0x00, 0x36, 0x0e, 0xff, 0xfb, 0x1a, 0x5d, 0x7c, + 0xbe, 0xf5, 0xd1, 0x1e, 0x32, 0x50, 0x2b, 0x1c, 0x02, 0xdf, 0x49, 0x3c, 0x21, + 0x1a, 0xf7, 0xfc, 0x48, 0x03, 0xda, 0xfd, 0x01, 0xf7, 0x58, 0x19, 0x22, 0x2e, + 0x0f, 0xd8, 0xb0, 0x3f, 0x25, 0x06, 0x81, 0xf7, 0xcf, 0x22, 0x28, 0x34, 0xc8, + 0xf4, 0xe5, 0xff, 0xc1, 0x32, 0xfa, 0x0c, 0x62, 0x20, 0x0a, 0xf5, 0x4c, 0xcc, + 0xcc, 0xd5, 0xe9, 0x05, 0x45, 0x41, 0x17, 0x3c, 0xe1, 0xfe, 0x1a, 0x25, 0x2c, + 0x03, 0xfa, 0x21, 0xdb, 0xdc, 0x02, 0xec, 0xf9, 0x14, 0x09, 0x0d, 0x23, 0xbe, + 0xe5, 0x00, 0x23, 0x2b, 0x02, 0x0c, 0xf6, 0x1c, 0xc5, 0xec, 0x36, 0x5e, 0x1e, + 0x09, 0x00, 0xff, 0xb3, 0x43, 0xa2, 0x04, 0x3b, 0xf5, 0xd3, 0xd4, 0x39, 0x0a, + 0xdd, 0x00, 0xf1, 0xfe, 0x0d, 0xd2, 0xf5, 0xf1, 0x24, 0xcd, 0xe7, 0x62, 0x03, + 0x07, 0xec, 0x04, 0xcf, 0x16, 0xf0, 0xbd, 0x37, 0xf4, 0xf5, 0xdf, 0x81, 0x15, + 0xf7, 0xf8, 0xbe, 0xda, 0xd2, 0xdd, 0xd6, 0xd5, 0xe2, 0xfa, 0xf6, 0x10, 0x21, + 0xe0, 0x30, 0xd1, 0x18, 0xfd, 0x0b, 0xd7, 0xde, 0xd9, 0xde, 0xc3, 0x2e, 0xf8, + 0xdd, 0xcd, 0x13, 0x12, 0x0b, 0x0f, 0xed, 0x0e, 0xe6, 0xe4, 0xd3, 0x32, 0x02, + 0x29, 0x1e, 0xd8, 0xe6, 0xca, 0xf4, 0x07, 0x2b, 0x1e, 0x11, 0x0a, 0xf9, 0xce, + 0x4c, 0xd1, 0x1c, 0x24, 0xea, 0x11, 0xf1, 0x0f, 0xc4, 0x12, 0xf8, 0x49, 0x06, + 0x41, 0x01, 0x1c, 0xec, 0xe5, 0xe5, 0x1d, 0xfd, 0x2c, 0xde, 0xdb, 0x2f, 0x10, + 0x78, 0x68, 0x04, 0x45, 0xd0, 0xf3, 0xfb, 0x1e, 0x2e, 0xf5, 0xad, 0xd1, 0xf3, + 0xf8, 0x05, 0x0b, 0x19, 0xee, 0xf7, 0xec, 0x14, 0xee, 0xf0, 0x17, 0x2f, 0x16, + 0xa7, 0xe1, 0xb8, 0x11, 0x32, 0xf5, 0x26, 0x1d, 0x26, 0x18, 0xd9, 0x03, 0xfc, + 0x05, 0x45, 0x24, 0xe0, 0xff, 0x0d, 0xfe, 0xf6, 0x19, 0xe5, 0x07, 0x05, 0x10, + 0x0f, 0x2b, 0x29, 0x2b, 0x0c, 0x12, 0xdf, 0x56, 0x00, 0x38, 0x14, 0xe4, 0x0f, + 0xdc, 0x16, 0x58, 0x09, 0x14, 0x01, 0xf9, 0x0f, 0xd2, 0x25, 0x02, 0x13, 0xfc, + 0xe7, 0x1d, 0x27, 0xf8, 0x0c, 0xee, 0xae, 0xe0, 0x07, 0x10, 0xc3, 0x16, 0x04, + 0xd0, 0x11, 0x13, 0xcf, 0x7f, 0xe4, 0x0b, 0xda, 0x05, 0x0f, 0xe6, 0xdc, 0xba, + 0xe4, 0x0f, 0xf3, 0x16, 0xdc, 0x0f, 0xb2, 0x3c, 0xee, 0xf2, 0x21, 0x1c, 0xf1, + 0x1a, 0x39, 0xd6, 0xfc, 0xfe, 0x11, 0xf2, 0x2c, 0x36, 0xfc, 0x9c, 0xfd, 0x3a, + 0x01, 0x90, 0x36, 0xef, 0xf4, 0xc5, 0xfd, 0xfd, 0xa5, 0x35, 0x0f, 0x36, 0x0f, + 0xba, 0xd1, 0x17, 0xe0, 0x4d, 0xb6, 0xbd, 0x1a, 0x15, 0xf5, 0x20, 0xd0, 0x23, + 0x1f, 0xff, 0xe5, 0xfd, 0xae, 0x7f, 0x12, 0xa0, 0xef, 0xf6, 0xed, 0xf2, 0x20, + 0xe4, 0x25, 0xab, 0x23, 0xee, 0x15, 0xe2, 0xbf, 0x03, 0xf2, 0xbd, 0x1a, 0xfe, + 0xed, 0xd3, 0x24, 0x26, 0x22, 0xd6, 0x11, 0xfc, 0x19, 0x10, 0x11, 0xfb, 0xff, + 0xdf, 0xe6, 0x2e, 0xee, 0xf4, 0x1b, 0xf2, 0xf2, 0xf5, 0x4d, 0xbf, 0xfc, 0xf2, + 0xe7, 0xd1, 0x41, 0xe8, 0x45, 0xf2, 0x07, 0x0c, 0x19, 0x01, 0xf3, 0xe2, 0xe9, + 0xfa, 0xe3, 0xfd, 0xfb, 0x3b, 0x42, 0xc7, 0xaa, 0xef, 0x01, 0x27, 0xdf, 0xec, + 0xf6, 0x1b, 0xf7, 0x1c, 0xd9, 0x22, 0x0a, 0x0a, 0xe6, 0x4d, 0xb6, 0x24, 0x03, + 0xd6, 0x08, 0xb6, 0xeb, 0xf6, 0x48, 0x9e, 0xbb, 0x9a, 0x26, 0xd4, 0x2b, 0x9d, + 0xd0, 0xc1, 0xe7, 0xfc, 0x17, 0x06, 0xab, 0x1a, 0x5e, 0x2e, 0x53, 0xc5, 0x08, + 0x3e, 0x20, 0x24, 0xe3, 0xb6, 0xcf, 0x2b, 0x1a, 0x08, 0xe9, 0xc6, 0x19, 0x16, + 0xd4, 0xc7, 0x51, 0x0c, 0x01, 0xf3, 0x4f, 0x2d, 0x07, 0xa5, 0x1c, 0x26, 0x13, + 0xd4, 0xc1, 0xe3, 0xe0, 0xd7, 0x06, 0xb7, 0xef, 0xc1, 0xfe, 0x11, 0xfc, 0x00, + 0x0b, 0x21, 0x62, 0x02, 0x0a, 0x06, 0xf6, 0x15, 0xea, 0xe0, 0x22, 0xcb, 0xe4, + 0x43, 0xf9, 0xf0, 0x11, 0x45, 0xfc, 0xb8, 0x9e, 0x1d, 0xd6, 0x0b, 0x45, 0x15, + 0x35, 0xe2, 0x4c, 0xd7, 0xdd, 0x14, 0x01, 0xe0, 0x2b, 0x49, 0xf4, 0xe0, 0xbb, + 0x18, 0x10, 0xfc, 0x72, 0x30, 0x62, 0xcc, 0xe9, 0x09, 0xd3, 0xe1, 0x30, 0x53, + 0xe7, 0x54, 0xd1, 0x23, 0x1b, 0xd6, 0x09, 0x0f, 0xd9, 0x29, 0xef, 0xd8, 0xaf, + 0xeb, 0xec, 0x11, 0x68, 0x81, 0x3f, 0xef, 0x29, 0x2d, 0x35, 0xc3, 0x69, 0xd0, + 0x05, 0x05, 0x23, 0xe7, 0x0b, 0x2a, 0xf7, 0x34, 0xcc, 0x2a, 0x0c, 0xd7, 0xdb, + 0xdf, 0x35, 0x12, 0xf8, 0xd9, 0x1a, 0x2f, 0xa5, 0xc2, 0x29, 0x10, 0xe6, 0x17, + 0xf2, 0x31, 0x36, 0x23, 0xfa, 0x2c, 0xcd, 0xdc, 0xa6, 0xa6, 0x12, 0x49, 0xff, + 0x16, 0xc6, 0xd8, 0xc3, 0x0f, 0xf4, 0xd8, 0xfe, 0xe3, 0xf0, 0xdd, 0x4c, 0xd9, + 0xe2, 0xe0, 0x0e, 0xfd, 0xfa, 0xe7, 0x3d, 0xdf, 0xb6, 0xf2, 0xf5, 0x83, 0xdb, + 0xff, 0x1c, 0x3d, 0x21, 0x20, 0x96, 0xc6, 0xc8, 0x42, 0x3a, 0x1b, 0x3c, 0x27, + 0xcf, 0x57, 0x0f, 0x1c, 0xc4, 0x3c, 0xc7, 0xe2, 0xda, 0xe8, 0xc5, 0xfb, 0xf7, + 0xd7, 0x03, 0x08, 0xd0, 0xfe, 0xf4, 0xfa, 0x11, 0xaa, 0xe5, 0xdd, 0xa4, 0xdc, + 0x81, 0x19, 0x44, 0x0e, 0xea, 0xfc, 0xf5, 0xd4, 0xe3, 0x13, 0x2c, 0x9c, 0xef, + 0x04, 0x10, 0xa1, 0x51, 0x41, 0xd4, 0xec, 0x23, 0x67, 0x22, 0x0d, 0x0d, 0x34, + 0xca, 0xd2, 0xb6, 0xca, 0x3a, 0xf9, 0xc0, 0x16, 0xa6, 0x22, 0xeb, 0xc3, 0x10, + 0xd4, 0xa1, 0x35, 0xc4, 0x23, 0x52, 0xe6, 0x30, 0x30, 0xe2, 0xc8, 0x26, 0x21, + 0x20, 0x00, 0x66, 0x46, 0xfe, 0x00, 0xdd, 0xaf, 0x4f, 0x4a, 0xdf, 0x16, 0x05, + 0x02, 0xe2, 0x0b, 0xf5, 0xf5, 0x0c, 0xe6, 0x45, 0xeb, 0x46, 0x0a, 0x3d, 0x81, + 0x2a, 0xf6, 0xdb, 0x38, 0xb8, 0xe9, 0x06, 0x1a, 0x27, 0xf3, 0x1d, 0x13, 0xda, + 0x25, 0x07, 0x37, 0xa4, 0x23, 0x0d, 0x1f, 0xd4, 0xf1, 0xdc, 0x43, 0x28, 0x4f, + 0x36, 0xa6, 0x0b, 0x13, 0xf4, 0xf3, 0xe4, 0xe8, 0xe3, 0x01, 0x35, 0x98, 0x2b, + 0x00, 0xc9, 0x26, 0x20, 0xd4, 0x5a, 0x3b, 0x0d, 0xfb, 0x03, 0x28, 0xe6, 0xfe, + 0x12, 0xe1, 0x0c, 0xef, 0x72, 0x1c, 0xd6, 0xa1, 0x51, 0xcf, 0x1e, 0x0c, 0xed, + 0x5c, 0xe2, 0xd1, 0x13, 0xf7, 0xe4, 0xff, 0xf2, 0xe5, 0xf2, 0x10, 0xf9, 0xd2, + 0xdf, 0x1f, 0xff, 0xee, 0x1d, 0x51, 0x02, 0xcc, 0xf0, 0xe3, 0x0f, 0xc4, 0x45, + 0x02, 0x2e, 0x3e, 0x13, 0x34, 0x00, 0xf4, 0xdc, 0x3b, 0x13, 0x0f, 0xe0, 0x4e, + 0x02, 0x55, 0x17, 0xfa, 0xf7, 0x07, 0xcd, 0x04, 0xf6, 0x9f, 0x03, 0xf4, 0xf0, + 0xe4, 0xdf, 0xce, 0x1c, 0x0e, 0x14, 0x03, 0x0c, 0xf8, 0x0d, 0xe4, 0xe1, 0xea, + 0x2f, 0xd8, 0xdf, 0x15, 0xf1, 0xcf, 0xfc, 0x16, 0x3e, 0x08, 0x0c, 0x00, 0xfc, + 0xf0, 0xc6, 0xd6, 0xf1, 0x20, 0x7f, 0x07, 0x43, 0xce, 0x00, 0x06, 0x12, 0x18, + 0x11, 0x11, 0x1b, 0xdb, 0x13, 0x1e, 0xb5, 0x49, 0xdf, 0xee, 0xd4, 0x39, 0xd7, + 0x0e, 0xfe, 0x25, 0xe8, 0x18, 0xc4, 0xf2, 0xd8, 0x07, 0x4d, 0xe6, 0xf6, 0xf9, + 0xf7, 0x05, 0x31, 0xda, 0xea, 0xfe, 0xfd, 0x15, 0xfc, 0x10, 0xea, 0x0f, 0xc8, + 0x35, 0xcb, 0xc9, 0x27, 0xd5, 0x33, 0x24, 0xf9, 0x12, 0x1b, 0xc6, 0x81, 0x1c, + 0xfa, 0x35, 0xee, 0xb0, 0x01, 0xd9, 0x06, 0x20, 0x06, 0x0b, 0x14, 0xb8, 0xf6, + 0x1e, 0x17, 0xf3, 0xf3, 0x1c, 0xbb, 0xcb, 0xa7, 0xc0, 0x35, 0x04, 0xfa, 0x11, + 0x21, 0x7a, 0xaa, 0xe1, 0x12, 0x14, 0x12, 0xd5, 0x0c, 0x11, 0xc2, 0x2c, 0xfb, + 0xb6, 0x2e, 0x3a, 0xfb, 0xd3, 0xed, 0xf4, 0xd0, 0x1d, 0x1c, 0x04, 0xd1, 0x1d, + 0xb7, 0xdd, 0xd6, 0xf1, 0xf4, 0xf0, 0x09, 0x0e, 0xee, 0x39, 0x0a, 0x16, 0xe3, + 0xcb, 0x27, 0x1f, 0xc8, 0xf0, 0x21, 0x49, 0x27, 0x48, 0xfb, 0xe5, 0xee, 0xff, + 0x14, 0xe6, 0xf4, 0xc9, 0xdb, 0x56, 0xff, 0xda, 0xe9, 0xee, 0x1f, 0x1b, 0x0b, + 0xb5, 0xe5, 0x99, 0xdc, 0xdf, 0xdb, 0xdf, 0xc1, 0x07, 0x52, 0x18, 0xd8, 0xfc, + 0x00, 0x0b, 0xcd, 0xe4, 0x0f, 0x38, 0xf0, 0xe5, 0x28, 0x93, 0x26, 0x10, 0x49, + 0x16, 0xf9, 0x18, 0x37, 0xc8, 0x9e, 0x25, 0xf0, 0x16, 0xb2, 0xf5, 0xed, 0xdc, + 0xe4, 0x20, 0xf7, 0x35, 0x1b, 0x40, 0x22, 0xd0, 0xa4, 0xdf, 0x03, 0xd0, 0x39, + 0xd3, 0x5e, 0x10, 0xb8, 0xd8, 0x47, 0x41, 0x1e, 0xf3, 0xe9, 0x29, 0xcd, 0xee, + 0x0a, 0xab, 0x05, 0xd3, 0xe3, 0x07, 0xc9, 0xd2, 0x11, 0xf2, 0x36, 0xef, 0x62, + 0x10, 0xd1, 0xf2, 0xea, 0xb6, 0x14, 0xc8, 0x24, 0x03, 0x1a, 0xce, 0x7f, 0x43, + 0x39, 0x0c, 0xd3, 0xb0, 0x2e, 0x1a, 0x00, 0xf9, 0xed, 0x00, 0xf4, 0xd7, 0xad, + 0x03, 0x01, 0xaf, 0x5a, 0x16, 0x10, 0x30, 0x16, 0x04, 0x3c, 0x19, 0x17, 0x10, + 0xe8, 0xdb, 0xc9, 0xe5, 0x3e, 0xf4, 0x06, 0xe2, 0x16, 0xe5, 0x36, 0x06, 0xdb, + 0x2f, 0xe0, 0xf2, 0x01, 0xee, 0xdf, 0x08, 0x15, 0x5e, 0x0d, 0x5b, 0x25, 0x1a, + 0x41, 0x09, 0xac, 0xe7, 0x02, 0x01, 0xc2, 0xed, 0xf9, 0x1b, 0x7f, 0xd5, 0xfe, + 0x28, 0x12, 0xed, 0xf8, 0x2c, 0x12, 0x04, 0x1b, 0xf8, 0x13, 0xd2, 0x0b, 0xe0, + 0x04, 0xf0, 0x02, 0xc9, 0xc7, 0xdb, 0xd5, 0xfe, 0xe0, 0xfa, 0x13, 0xdd, 0xfa, + 0x12, 0x1c, 0xe2, 0xfa, 0xfd, 0xf2, 0x22, 0xe5, 0x0b, 0x2a, 0x4f, 0xe2, 0xfc, + 0xf3, 0xdd, 0x1d, 0x2c, 0x23, 0xe1, 0x2c, 0xd5, 0x10, 0x05, 0xf5, 0x15, 0x07, + 0x0f, 0x0c, 0x1e, 0x1e, 0xfa, 0x17, 0xf0, 0xfa, 0x03, 0x22, 0x1f, 0x11, 0x03, + 0xe8, 0xf9, 0x14, 0x15, 0x1d, 0xfe, 0x16, 0xe8, 0xd3, 0x0d, 0x19, 0xdd, 0x26, + 0xfa, 0xc7, 0x2e, 0x1e, 0x15, 0xdc, 0xeb, 0xf8, 0x14, 0xfd, 0x15, 0x18, 0xf5, + 0x2e, 0x0b, 0x20, 0xf1, 0x1a, 0x1a, 0x07, 0x0e, 0x18, 0x2f, 0x13, 0xfe, 0xf2, + 0xc7, 0xd1, 0xfe, 0x00, 0xfd, 0x0f, 0x1e, 0x1c, 0x04, 0x28, 0x12, 0xec, 0x0c, + 0xe4, 0xe1, 0xf6, 0xfd, 0xd5, 0x2e, 0x0f, 0x13, 0x19, 0xf6, 0x0a, 0xd9, 0xfa, + 0x01, 0xeb, 0xdc, 0xef, 0x22, 0xfc, 0x24, 0x08, 0x0b, 0xbe, 0xe6, 0xcc, 0x2c, + 0x2a, 0xec, 0x0c, 0x3a, 0xf5, 0xd5, 0xf1, 0xf1, 0x07, 0xec, 0x0c, 0x2b, 0xdf, + 0xdd, 0x01, 0x0e, 0x1e, 0x21, 0x0c, 0xf6, 0xb8, 0x05, 0x20, 0xea, 0x53, 0x1b, + 0xfb, 0xf1, 0x16, 0xe8, 0x06, 0x2d, 0x0f, 0xdc, 0x01, 0xba, 0x0b, 0xc8, 0x05, + 0x15, 0x0f, 0xf2, 0x07, 0xdb, 0x24, 0xd2, 0x3e, 0x30, 0x22, 0xfd, 0xc5, 0x02, + 0xca, 0x18, 0xf1, 0xea, 0x11, 0x1a, 0xef, 0x1e, 0xdd, 0x7f, 0xdf, 0x08, 0x11, + 0xe1, 0xe0, 0xd7, 0xed, 0xcd, 0xcf, 0xf4, 0x0a, 0x1b, 0xd8, 0xdd, 0xfe, 0xef, + 0x3f, 0xf7, 0x34, 0xef, 0x05, 0xdf, 0xe7, 0xe7, 0x21, 0x38, 0xef, 0xfd, 0xec, + 0xe8, 0x12, 0xd9, 0xe0, 0xf3, 0x2c, 0xc3, 0xe0, 0xeb, 0xe6, 0x1e, 0x1f, 0x1b, + 0xf2, 0xbb, 0xfb, 0xf1, 0x44, 0xe4, 0x0e, 0x08, 0x08, 0xd9, 0x3d, 0x39, 0x16, + 0x09, 0x30, 0xd1, 0x4f, 0x33, 0x15, 0xdf, 0x07, 0xf6, 0xf0, 0x20, 0x14, 0x39, + 0x0d, 0xc2, 0xef, 0x81, 0xf4, 0x13, 0x1b, 0xee, 0xc3, 0xba, 0xd7, 0xe6, 0x55, + 0xfa, 0xeb, 0xe0, 0x3a, 0x43, 0x03, 0x01, 0xcc, 0x11, 0xa8, 0x4d, 0x33, 0xe1, + 0x00, 0x00, 0x4a, 0x58, 0xd6, 0xc1, 0xdf, 0x42, 0xf2, 0xb9, 0x33, 0xb7, 0xd0, + 0x20, 0x41, 0xd8, 0x3d, 0xe2, 0x5e, 0x17, 0xcd, 0xe1, 0xd6, 0x14, 0xee, 0x1b, + 0xff, 0xf0, 0xd9, 0xfc, 0xb2, 0xdb, 0xcf, 0xf8, 0xba, 0x3b, 0xfd, 0x1c, 0xc7, + 0xd6, 0x34, 0x29, 0xe2, 0xe1, 0xf8, 0xab, 0xdc, 0x62, 0x4f, 0x17, 0xdf, 0xc7, + 0xef, 0xda, 0x44, 0xfe, 0xd3, 0x4f, 0x45, 0xe1, 0x3c, 0x08, 0xec, 0xdb, 0x3d, + 0xfc, 0x1f, 0xc8, 0xec, 0xb2, 0x2b, 0x20, 0x22, 0x1a, 0xf7, 0xcc, 0xfb, 0x03, + 0x15, 0x58, 0x20, 0xf3, 0xe4, 0x19, 0xf1, 0xce, 0x11, 0xbd, 0x1c, 0x05, 0xcd, + 0x1b, 0xc0, 0xfe, 0x20, 0xf4, 0xf1, 0x18, 0x58, 0xd5, 0x28, 0xec, 0x29, 0x0d, + 0x2b, 0x1f, 0xb3, 0xf1, 0x23, 0xfe, 0x7f, 0x6a, 0x47, 0x2d, 0xdf, 0x04, 0xf2, + 0xc3, 0x01, 0x1e, 0x22, 0x8e, 0x08, 0xfb, 0x44, 0x0f, 0x5b, 0xf7, 0xe0, 0x0c, + 0xf6, 0xb6, 0x34, 0x0b, 0x3e, 0x0d, 0xdd, 0x41, 0xf5, 0xd7, 0xf4, 0x2b, 0x14, + 0xec, 0x0c, 0xca, 0x37, 0x14, 0x2f, 0xda, 0x3d, 0x12, 0x04, 0x12, 0x08, 0xef, + 0xfc, 0x71, 0x21, 0x4d, 0xf6, 0xe0, 0xec, 0xf3, 0xcb, 0x2c, 0x23, 0x11, 0x91, + 0x06, 0xf7, 0x01, 0xd7, 0x2c, 0x16, 0xfe, 0x1b, 0xc8, 0x1b, 0x15, 0xd6, 0x04, + 0x2d, 0x82, 0x44, 0x0e, 0x08, 0xff, 0x3d, 0x06, 0x62, 0x17, 0xb2, 0xee, 0x4b, + 0x19, 0x26, 0x07, 0x86, 0xc7, 0xff, 0xf0, 0x55, 0xd6, 0x04, 0x4a, 0xef, 0xe6, + 0x33, 0x15, 0xe4, 0x03, 0x10, 0xc1, 0xc0, 0xf5, 0xed, 0x1f, 0x09, 0x1d, 0x21, + 0xaf, 0xf9, 0xd5, 0x02, 0x59, 0x06, 0xcc, 0xfd, 0xab, 0xec, 0x27, 0x49, 0xf1, + 0x10, 0xe8, 0xd1, 0x1a, 0xae, 0xf7, 0x14, 0x2a, 0x12, 0x1f, 0xfc, 0xc3, 0x3f, + 0xf3, 0x08, 0xe2, 0xea, 0xb3, 0xef, 0x10, 0xed, 0x04, 0xf8, 0x2b, 0xce, 0xeb, + 0xf4, 0xf9, 0x16, 0xf0, 0xf5, 0x29, 0x2c, 0xcf, 0xf3, 0x15, 0xf6, 0x22, 0xea, + 0x0d, 0xf7, 0xcd, 0xf7, 0x6e, 0x0e, 0xb9, 0xea, 0xd9, 0xf0, 0x1b, 0x01, 0xc9, + 0x0e, 0xd5, 0xf1, 0x1a, 0x00, 0x1e, 0xfb, 0x0e, 0xe4, 0x05, 0x4d, 0xea, 0x81, + 0xee, 0x0e, 0xcc, 0x01, 0x19, 0xc6, 0xfb, 0xe3, 0x14, 0x34, 0xec, 0xe5, 0x39, + 0x13, 0x09, 0x2c, 0xc6, 0xfe, 0xa7, 0xe5, 0x20, 0xd1, 0x0c, 0x0a, 0x0c, 0x43, + 0xe9, 0xb0, 0xf7, 0xf3, 0x02, 0x60, 0x29, 0x1c, 0xd9, 0x28, 0x3f, 0x0d, 0x35, + 0xc2, 0x37, 0x1b, 0x0b, 0x2d, 0xe4, 0xf4, 0xa7, 0xde, 0xf0, 0xbd, 0x1d, 0x22, + 0x21, 0xc5, 0x1f, 0xe7, 0x4e, 0x28, 0xcf, 0xc2, 0xf9, 0xc3, 0xb8, 0xc9, 0xec, + 0xe2, 0xf0, 0x0a, 0x11, 0xd0, 0xc0, 0xb0, 0x25, 0x0d, 0xca, 0xbe, 0x2a, 0xf8, + 0xd7, 0x0f, 0xe5, 0xf7, 0xfa, 0xde, 0xe5, 0xe8, 0xf6, 0x42, 0x2f, 0xe3, 0xdd, + 0x2e, 0xb1, 0xb8, 0xcf, 0xf6, 0x08, 0xc6, 0x2d, 0xd4, 0xe0, 0xee, 0x34, 0xd7, + 0x21, 0x12, 0xb3, 0x48, 0x3c, 0x12, 0xd5, 0x04, 0xcf, 0xdc, 0x25, 0x05, 0x03, + 0xcf, 0x0b, 0x30, 0x9d, 0x1c, 0x30, 0x23, 0x5b, 0x36, 0x27, 0x3d, 0xdf, 0xe0, + 0xfd, 0xde, 0xdb, 0xfd, 0x41, 0x0c, 0xdb, 0xe5, 0x08, 0x1b, 0xef, 0x5c, 0x81, + 0x1d, 0x2a, 0xcb, 0x0e, 0x0b, 0x35, 0x2a, 0xcc, 0x24, 0xe8, 0x2c, 0x2e, 0x18, + 0x18, 0xe8, 0x52, 0xb7, 0x32, 0x16, 0xd7, 0xf6, 0x51, 0xdb, 0xaf, 0x39, 0xfe, + 0xec, 0xf0, 0x8c, 0xee, 0xd5, 0xc5, 0x32, 0x0e, 0xc6, 0xc9, 0xab, 0x06, 0x35, + 0xdb, 0x4d, 0x33, 0x02, 0x1d, 0x05, 0xe9, 0x27, 0xcd, 0x13, 0x00, 0xcb, 0x48, + 0x0b, 0xe1, 0x0d, 0xb3, 0xfc, 0xd9, 0x10, 0x24, 0x07, 0xf9, 0xf3, 0x1c, 0xb3, + 0xba, 0xf4, 0xdf, 0xf7, 0xf3, 0xc9, 0x2e, 0xd2, 0xf6, 0xfa, 0x2a, 0xca, 0xec, + 0xb1, 0xfd, 0xf8, 0xca, 0xc8, 0xea, 0x04, 0x38, 0x25, 0x09, 0xb3, 0xce, 0x27, + 0x1a, 0x4f, 0x11, 0x1a, 0xe3, 0x22, 0x27, 0xfd, 0x03, 0x41, 0xd7, 0x05, 0xe5, + 0x9e, 0x04, 0x0c, 0x04, 0xf5, 0xe3, 0xdf, 0x55, 0xed, 0xea, 0xd0, 0x2b, 0x16, + 0xe2, 0xf3, 0x29, 0xf4, 0x44, 0x27, 0x65, 0xda, 0x45, 0x16, 0xd5, 0xed, 0x04, + 0xf3, 0x13, 0xb9, 0xc8, 0xe6, 0xf8, 0xbc, 0x7f, 0xdc, 0xea, 0xfd, 0xed, 0x10, + 0x10, 0x29, 0x3e, 0xea, 0xf8, 0x9e, 0x11, 0xd2, 0x0d, 0x28, 0x44, 0x30, 0x2a, + 0x49, 0x2b, 0xba, 0xd4, 0x18, 0x07, 0x48, 0x12, 0x21, 0x59, 0x36, 0xea, 0x13, + 0x58, 0xe4, 0xc3, 0x37, 0xdb, 0xcb, 0x19, 0xdf, 0x21, 0x17, 0x50, 0x0d, 0xcd, + 0xbf, 0x2b, 0x0e, 0xd2, 0x06, 0xb9, 0xfe, 0x3b, 0x1d, 0xe9, 0xd8, 0x0d, 0x41, + 0xdd, 0xfe, 0xeb, 0xd5, 0x37, 0xad, 0xf3, 0x00, 0x21, 0x0f, 0xcc, 0xf0, 0xd6, + 0x5e, 0x0b, 0xf2, 0x09, 0x2b, 0x39, 0xd3, 0x1b, 0xe3, 0xb7, 0xed, 0xfb, 0xe3, + 0xd7, 0x40, 0xe3, 0x09, 0x44, 0x0f, 0x26, 0xf5, 0xf9, 0x4b, 0x98, 0xf1, 0x09, + 0x81, 0xe8, 0xcd, 0x34, 0xdc, 0x19, 0x2a, 0x5b, 0xe8, 0xf5, 0xfd, 0x2c, 0xc2, + 0xd4, 0xe1, 0x0c, 0xda, 0xe7, 0xfe, 0xcd, 0x1d, 0xf8, 0x00, 0x08, 0xe5, 0xf1, + 0x51, 0x10, 0x11, 0xa9, 0xc9, 0x28, 0x10, 0xfd, 0x4e, 0x0c, 0x1e, 0x21, 0x28, + 0x0b, 0x0e, 0xe8, 0xcd, 0xff, 0xe3, 0x20, 0xbd, 0xe6, 0x05, 0xef, 0x31, 0xf6, + 0xe4, 0x25, 0x0d, 0xf0, 0xf0, 0x1f, 0x14, 0xe0, 0xf5, 0x15, 0x19, 0xeb, 0x0a, + 0x02, 0xe9, 0xbd, 0x24, 0x0c, 0x0d, 0x44, 0xe9, 0xf7, 0xdf, 0x42, 0xce, 0xf6, + 0x16, 0x12, 0x02, 0xca, 0x28, 0x0f, 0x1c, 0x1c, 0xf5, 0x32, 0xfd, 0x24, 0x43, + 0xdf, 0xe6, 0xea, 0x1c, 0x0a, 0x11, 0xfe, 0xfd, 0x12, 0x19, 0xf5, 0xd2, 0x47, + 0xc4, 0x1f, 0x0c, 0xfe, 0x07, 0xf4, 0x0c, 0xd3, 0xe6, 0xd8, 0x81, 0x6d, 0xff, + 0xf6, 0x05, 0x29, 0xe1, 0x04, 0xd9, 0xf7, 0xf7, 0xea, 0xec, 0xf5, 0xbd, 0x10, + 0x08, 0xf5, 0xd1, 0x47, 0x17, 0x36, 0xe0, 0xf5, 0xf2, 0xe2, 0xd9, 0x10, 0xd9, + 0xdb, 0xe8, 0x47, 0xfd, 0x30, 0x41, 0xfc, 0xdf, 0x10, 0xf4, 0x27, 0x05, 0xea, + 0xed, 0xdb, 0x1b, 0x12, 0x0f, 0xd3, 0x09, 0xfe, 0xf4, 0x08, 0xea, 0xf4, 0x0e, + 0x4e, 0x0f, 0xf3, 0x53, 0x35, 0xc1, 0xd3, 0x06, 0x39, 0xed, 0xc4, 0xe4, 0xd1, + 0xfb, 0xcc, 0x28, 0xeb, 0xb9, 0xfe, 0xd2, 0xfb, 0xf0, 0xc5, 0xf6, 0x48, 0xdf, + 0xb8, 0x16, 0xf4, 0x20, 0x04, 0x32, 0x3e, 0xc8, 0xe0, 0xe5, 0x0e, 0x18, 0x1c, + 0x30, 0x1d, 0xf7, 0x1f, 0x22, 0x0f, 0xb9, 0x3a, 0xa8, 0x2c, 0x55, 0x01, 0x0c, + 0xfb, 0xb5, 0xf1, 0xf5, 0xe6, 0xe5, 0x3a, 0x7f, 0xe0, 0xba, 0xcc, 0xf4, 0xfd, + 0xee, 0xde, 0x61, 0xcd, 0xf8, 0xb7, 0xd6, 0xb1, 0x10, 0x03, 0x10, 0xe6, 0xe4, + 0xf2, 0xe0, 0x2d, 0x96, 0x01, 0x0e, 0xde, 0xc2, 0x0d, 0x22, 0x06, 0xd0, 0x39, + 0xe3, 0xfc, 0x2b, 0xb5, 0xeb, 0xc6, 0xc7, 0xac, 0xe6, 0x1f, 0xf6, 0xf9, 0xbb, + 0x37, 0xec, 0xe9, 0x2d, 0xdf, 0xb9, 0x1a, 0xe4, 0xd5, 0xdb, 0xc3, 0x07, 0x19, + 0xef, 0xf5, 0xd2, 0x1d, 0x03, 0xda, 0x0e, 0x33, 0x42, 0x30, 0x19, 0x09, 0x3c, + 0xb6, 0x03, 0xea, 0x1f, 0xe7, 0xf1, 0xd4, 0x0f, 0xe5, 0xe4, 0x16, 0x05, 0xf5, + 0x05, 0x7f, 0xf3, 0xd2, 0x16, 0xe7, 0x23, 0xda, 0xd7, 0xd0, 0xfe, 0xeb, 0x2d, + 0xf4, 0x47, 0x05, 0x0c, 0xed, 0x08, 0x00, 0x11, 0x0d, 0xe6, 0xb4, 0x24, 0x13, + 0x10, 0x17, 0xf4, 0x17, 0xf5, 0x23, 0xd7, 0x3d, 0x0f, 0xef, 0xee, 0xdf, 0xf2, + 0xde, 0x1b, 0xfb, 0xe3, 0x11, 0x11, 0x1a, 0x21, 0x5a, 0xb5, 0x21, 0x05, 0xd8, + 0xed, 0x36, 0xde, 0xfb, 0xe8, 0xe4, 0xe8, 0x39, 0xd1, 0x08, 0x56, 0xc6, 0xf3, + 0x02, 0x26, 0xde, 0x14, 0xff, 0x38, 0x0a, 0xea, 0x0a, 0xc1, 0xfa, 0xf2, 0xd7, + 0xc8, 0x22, 0xcf, 0xb8, 0x28, 0x10, 0xc6, 0xf0, 0xec, 0xff, 0xdb, 0x2e, 0xf9, + 0x0d, 0x39, 0x02, 0xf0, 0xf9, 0xf9, 0x15, 0x4a, 0x02, 0xd3, 0x11, 0xfe, 0x15, + 0xdd, 0xc7, 0x19, 0xe5, 0x13, 0x08, 0x15, 0x3c, 0x05, 0xcd, 0x1a, 0xf4, 0x10, + 0x07, 0xff, 0xee, 0xed, 0x0f, 0xfc, 0x1b, 0x0a, 0xba, 0xe0, 0xf5, 0xe2, 0xb3, + 0x0c, 0x9f, 0x4d, 0xfd, 0xcd, 0x1a, 0xd8, 0xf9, 0xe3, 0x34, 0xef, 0xf3, 0xfd, + 0x40, 0x47, 0x0e, 0x20, 0x14, 0xec, 0x11, 0xe8, 0x38, 0xfb, 0x45, 0xbf, 0xed, + 0x6a, 0xcf, 0xd4, 0x3c, 0x0e, 0x40, 0x0b, 0x2d, 0x3d, 0x30, 0xd8, 0x32, 0x03, + 0xe5, 0xc5, 0x07, 0x0f, 0x03, 0xfb, 0x92, 0xe6, 0xe3, 0x3c, 0xfd, 0x39, 0xfd, + 0x12, 0x99, 0xdb, 0x0e, 0x3b, 0x31, 0x06, 0xc0, 0xc5, 0x02, 0x49, 0xe3, 0x3a, + 0xcc, 0x38, 0xef, 0xa1, 0x1e, 0x09, 0x01, 0xc4, 0x3b, 0x28, 0x41, 0xb9, 0x12, + 0xeb, 0x10, 0x43, 0xdf, 0x1e, 0xb0, 0xc8, 0x7f, 0x18, 0x05, 0x0e, 0x0e, 0xfe, + 0xde, 0x34, 0xe5, 0x29, 0xe9, 0x06, 0x00, 0x0b, 0x10, 0xd6, 0xeb, 0x1e, 0x14, + 0xe2, 0xd9, 0xba, 0x1e, 0xec, 0x26, 0x09, 0xd0, 0xc0, 0xf7, 0x8e, 0x09, 0xb6, + 0x44, 0x22, 0x29, 0xf6, 0x05, 0xc7, 0x91, 0x09, 0xd2, 0x81, 0x50, 0xdd, 0x10, + 0xf2, 0x05, 0x6b, 0x10, 0x0b, 0x26, 0xe1, 0x79, 0xd5, 0x33, 0xdc, 0x1d, 0xc8, + 0xed, 0xc3, 0x41, 0x8f, 0xca, 0xde, 0x10, 0xec, 0x01, 0xe0, 0xe5, 0xe7, 0x18, + 0x97, 0xe0, 0x09, 0xfd, 0x1b, 0x09, 0xfa, 0x05, 0x0f, 0xf2, 0xbd, 0xeb, 0x39, + 0xf5, 0xe0, 0xd9, 0xe7, 0xda, 0x22, 0x21, 0x2b, 0xf9, 0xdb, 0xf8, 0x19, 0x34, + 0xf2, 0x38, 0xdd, 0xf0, 0xfb, 0xe5, 0x04, 0xf5, 0xbd, 0x59, 0x01, 0x0f, 0x79, + 0x1c, 0xda, 0xcd, 0x1e, 0x30, 0x27, 0x0d, 0x11, 0x0a, 0x0b, 0xf0, 0x4d, 0xb3, + 0x5e, 0xf5, 0x23, 0xf6, 0xfc, 0x2f, 0xd7, 0x5b, 0xc2, 0x5f, 0x21, 0xfd, 0xdf, + 0x06, 0x3e, 0xef, 0x78, 0x5b, 0x9a, 0x3e, 0x18, 0xf0, 0xf2, 0xc4, 0xf4, 0xec, + 0xff, 0x09, 0xe7, 0x23, 0x07, 0x22, 0x1b, 0xe9, 0xdf, 0x3c, 0xe7, 0x0b, 0x01, + 0xc1, 0x07, 0xec, 0xa0, 0x0b, 0xce, 0xf9, 0x02, 0x0a, 0x57, 0x5d, 0xbc, 0x18, + 0xdb, 0x24, 0x08, 0x07, 0x37, 0xfc, 0xd2, 0x3d, 0xe0, 0x12, 0x14, 0x32, 0xe7, + 0x31, 0xf9, 0xe1, 0x5d, 0xf5, 0xc7, 0x25, 0xf8, 0xe5, 0x0a, 0x12, 0x0b, 0x29, + 0xfe, 0xd5, 0x3c, 0x32, 0xf8, 0x02, 0xed, 0x1a, 0x38, 0xdb, 0xee, 0x12, 0xdc, + 0x05, 0x1c, 0xa6, 0xff, 0xde, 0xf3, 0x07, 0x06, 0x1d, 0xb2, 0xd9, 0x03, 0x2b, + 0xa0, 0x10, 0x29, 0xee, 0x27, 0x3d, 0x2b, 0xb4, 0xdb, 0x2a, 0xca, 0xf6, 0xd4, + 0x10, 0x81, 0xff, 0xe7, 0x20, 0xb3, 0x04, 0xbb, 0xe5, 0x0c, 0xd7, 0xbe, 0xde, + 0xa9, 0xed, 0xe0, 0x02, 0xed, 0x19, 0x01, 0x0e, 0xc9, 0xee, 0x3f, 0x4a, 0x63, + 0xfa, 0xfc, 0xf8, 0x12, 0xdf, 0xbf, 0x12, 0x1f, 0x26, 0xd7, 0xfd, 0x08, 0x2d, + 0xc6, 0x38, 0xa5, 0xba, 0x42, 0xed, 0xe2, 0x04, 0x02, 0x22, 0xd2, 0x34, 0x25, + 0x29, 0xfd, 0x05, 0xe4, 0xfe, 0x9f, 0x12, 0x36, 0xb6, 0xf1, 0x3e, 0x02, 0xcf, + 0x54, 0xa5, 0x19, 0xe6, 0x59, 0xfa, 0xf9, 0x1c, 0x15, 0x02, 0xfb, 0x3c, 0x11, + 0x38, 0xed, 0x14, 0xf1, 0x0a, 0x1a, 0x14, 0x03, 0xd0, 0x4c, 0xcc, 0x1a, 0x1c, + 0x1e, 0xe8, 0xd6, 0x2e, 0xd7, 0xef, 0x60, 0xd3, 0x23, 0xfb, 0x0d, 0xe8, 0x35, + 0x7f, 0xf8, 0xde, 0xf7, 0x1b, 0xf2, 0xc9, 0x1a, 0xda, 0xe1, 0xc6, 0x33, 0xc9, + 0x37, 0xce, 0x02, 0x43, 0x05, 0x07, 0xeb, 0x12, 0xf9, 0x32, 0xea, 0xf5, 0x18, + 0x0f, 0x51, 0xd9, 0xd1, 0xdd, 0xd1, 0x02, 0x18, 0xef, 0xc1, 0x29, 0x51, 0xed, + 0xc2, 0x37, 0xee, 0x45, 0x02, 0xdc, 0xff, 0x35, 0xc4, 0x03, 0x0d, 0xc8, 0xdd, + 0x27, 0xeb, 0xb8, 0xd4, 0xdd, 0x2d, 0x2e, 0xe7, 0x26, 0xf2, 0xce, 0xe7, 0x04, + 0x1d, 0x2d, 0x05, 0x0f, 0x06, 0xfd, 0xc0, 0xff, 0xf5, 0x09, 0x21, 0xec, 0xf5, + 0xfe, 0xee, 0xf2, 0x0e, 0xea, 0x16, 0xec, 0x01, 0x14, 0x2c, 0x13, 0xfd, 0xdf, + 0x04, 0xe0, 0x0a, 0xe2, 0x9d, 0xe4, 0x54, 0xd9, 0x06, 0x0b, 0xda, 0x0b, 0xc3, + 0x0e, 0x14, 0xca, 0x13, 0xc7, 0x46, 0xfd, 0x28, 0xea, 0x2d, 0x14, 0x16, 0xd5, + 0x07, 0x0c, 0x27, 0x27, 0x07, 0x10, 0xde, 0x46, 0x02, 0x0c, 0x06, 0x1f, 0xd0, + 0x32, 0xec, 0xf9, 0xb0, 0xfe, 0xcd, 0xea, 0x18, 0x1b, 0x09, 0xcf, 0x3d, 0x01, + 0xee, 0x07, 0xeb, 0xe9, 0xe7, 0xf5, 0x00, 0x2c, 0x48, 0xf8, 0xe5, 0x25, 0xf3, + 0x0e, 0x7f, 0x0b, 0x05, 0xd5, 0xcd, 0x21, 0x0a, 0xdd, 0xc6, 0xef, 0xf0, 0xf1, + 0xfc, 0xc9, 0x29, 0xf2, 0xf9, 0x04, 0xee, 0xe6, 0x19, 0xf7, 0x1f, 0x48, 0x01, + 0xfb, 0xc3, 0xea, 0xb0, 0x0a, 0x23, 0xe5, 0xfa, 0xbc, 0x12, 0xfe, 0xec, 0x0a, + 0xdb, 0x01, 0xc1, 0xed, 0xdd, 0xfe, 0x08, 0xee, 0x8a, 0x01, 0xa4, 0x11, 0xf1, + 0x22, 0xbc, 0x00, 0x08, 0x16, 0x23, 0x02, 0x7c, 0x37, 0xf8, 0xff, 0xfb, 0xe9, + 0xcd, 0xee, 0x55, 0x15, 0x38, 0x42, 0x14, 0xac, 0xb2, 0x5d, 0x21, 0xe5, 0xfc, + 0x1a, 0xd9, 0xf9, 0xc9, 0xd3, 0xd0, 0x0d, 0xe0, 0x29, 0x4f, 0xfd, 0xd1, 0x4f, + 0xca, 0xc8, 0x05, 0xed, 0xe0, 0xfa, 0xf5, 0x36, 0x17, 0x19, 0xd6, 0x4b, 0xd5, + 0x14, 0xda, 0x51, 0xe5, 0xd6, 0xfa, 0x0f, 0xd1, 0x09, 0xe8, 0x93, 0x24, 0x75, + 0x19, 0x2a, 0x11, 0x2e, 0x30, 0x0f, 0x4d, 0xfa, 0xb9, 0xda, 0x94, 0xbe, 0xa0, + 0xf4, 0xee, 0x28, 0xe8, 0x2c, 0x44, 0xdd, 0xb4, 0x7f, 0x9e, 0xee, 0xee, 0xfd, + 0xf0, 0x12, 0xde, 0x28, 0x17, 0xc4, 0x1c, 0x27, 0x95, 0x0f, 0x18, 0x09, 0x33, + 0x3b, 0x0d, 0xe4, 0xd4, 0x14, 0x37, 0x39, 0xc3, 0x4f, 0xc6, 0x0f, 0xe8, 0x03, + 0xdb, 0x01, 0xf9, 0xf2, 0xe6, 0xe3, 0xb6, 0x07, 0xe9, 0x8a, 0x2b, 0x57, 0x10, + 0x2b, 0x21, 0x0a, 0xec, 0x06, 0xad, 0x65, 0xcc, 0x22, 0x1f, 0x35, 0x01, 0x8e, + 0x13, 0x1e, 0x19, 0xc7, 0xfd, 0xfa, 0x32, 0xc9, 0xe2, 0x4b, 0x5f, 0x36, 0xde, + 0xb5, 0xea, 0x4b, 0x1d, 0xdf, 0xf5, 0x13, 0xe4, 0xe1, 0xf7, 0x98, 0xd9, 0xef, + 0xfb, 0x13, 0x08, 0x2b, 0x08, 0xd3, 0xdf, 0xfe, 0x2d, 0x01, 0xbf, 0xef, 0x4d, + 0xe3, 0x11, 0x34, 0xf4, 0x2f, 0xcf, 0x09, 0xbc, 0xfa, 0x63, 0xdb, 0x0f, 0x3e, + 0x0f, 0xc9, 0xdb, 0x12, 0x0b, 0xf3, 0x2b, 0xf2, 0xf8, 0xf0, 0xbb, 0xd2, 0xb5, + 0xe8, 0x49, 0xef, 0x91, 0xdf, 0x07, 0x13, 0x48, 0xdd, 0x46, 0xfc, 0xf5, 0xfa, + 0xdb, 0xdf, 0x23, 0x7f, 0xe5, 0x03, 0xf2, 0x2e, 0x0e, 0xb2, 0xd8, 0x10, 0x48, + 0x03, 0x03, 0xd9, 0xe4, 0x2b, 0xc0, 0x17, 0xfe, 0xa2, 0xfb, 0xde, 0xf7, 0x05, + 0x26, 0x5b, 0xf7, 0x51, 0x0e, 0xe2, 0xcf, 0xcc, 0x58, 0xc1, 0x46, 0x41, 0xfe, + 0xf6, 0x43, 0xc8, 0x48, 0xf6, 0x0c, 0x1c, 0xb3, 0xf4, 0x45, 0xde, 0x3b, 0x38, + 0x2a, 0x5f, 0x90, 0x3e, 0xb5, 0x24, 0x73, 0x1d, 0x17, 0x1c, 0x0b, 0xe7, 0x0e, + 0xdd, 0xfa, 0x22, 0x29, 0x3f, 0x02, 0xf9, 0xe2, 0xf8, 0x59, 0xc9, 0xe7, 0xe8, + 0x14, 0x11, 0x7f, 0x10, 0xf0, 0x4c, 0xc2, 0x39, 0x67, 0x1e, 0x3b, 0x29, 0xa2, + 0x14, 0xc1, 0x45, 0xc4, 0x5a, 0x97, 0x3c, 0x61, 0x13, 0x2e, 0xb4, 0xe8, 0x2b, + 0x26, 0x19, 0xe9, 0xc2, 0xcf, 0xf7, 0xdb, 0xee, 0xfe, 0x61, 0xd7, 0x34, 0xed, + 0xcc, 0xdf, 0x4b, 0x54, 0x02, 0x23, 0x55, 0xff, 0xfd, 0xc2, 0x50, 0x28, 0x31, + 0x03, 0xac, 0x0c, 0x44, 0xe0, 0xdb, 0x20, 0x16, 0x23, 0x10, 0xd5, 0x41, 0x0a, + 0x2c, 0x0b, 0xe5, 0xe7, 0x65, 0xfe, 0xea, 0xe9, 0x4d, 0xad, 0x70, 0xee, 0x19, + 0xab, 0xcb, 0x22, 0x20, 0xc7, 0xf7, 0xe1, 0x2a, 0xa5, 0xf3, 0x20, 0xf8, 0x19, + 0x1c, 0x0b, 0x33, 0x50, 0x1e, 0x3d, 0xf3, 0xce, 0xf3, 0x16, 0x36, 0x19, 0xdb, + 0xf8, 0xdf, 0x1f, 0xe4, 0xe0, 0x19, 0x30, 0x0a, 0xa1, 0xeb, 0xba, 0x0e, 0xf8, + 0xa4, 0xf6, 0x22, 0xdd, 0xb3, 0xf8, 0xeb, 0xbc, 0x22, 0xfa, 0xff, 0xe5, 0x51, + 0xef, 0xf7, 0x08, 0xe3, 0x7f, 0x0a, 0x0a, 0xd5, 0x29, 0xf0, 0x02, 0xc9, 0x28, + 0x30, 0xc3, 0x19, 0xd2, 0x23, 0x0f, 0x6a, 0xd3, 0xb4, 0xf1, 0x12, 0xd5, 0xf3, + 0x19, 0xc8, 0xc6, 0xcd, 0xcd, 0xf5, 0xf9, 0x10, 0x36, 0xf6, 0x26, 0x2b, 0x50, + 0xe4, 0x9b, 0x47, 0x43, 0xee, 0x2f, 0x0a, 0x19, 0xf6, 0x15, 0xff, 0x0b, 0x14, + 0x13, 0x37, 0x27, 0x18, 0x23, 0xfc, 0x13, 0x36, 0x3a, 0xf3, 0xf5, 0xfe, 0xff, + 0x1f, 0xdb, 0x01, 0x15, 0xf2, 0x5f, 0x0e, 0x12, 0xd4, 0xe9, 0x07, 0xdf, 0x32, + 0xc5, 0xcf, 0xf5, 0x28, 0xf8, 0x2e, 0x2d, 0xf0, 0x7f, 0xf1, 0xf0, 0xd9, 0x04, + 0xd2, 0x39, 0x2d, 0xb6, 0xcf, 0xd9, 0x0d, 0x08, 0x6f, 0xfd, 0x2d, 0xfb, 0xd3, + 0xf8, 0x0b, 0x02, 0xdf, 0xf0, 0xc7, 0x52, 0x34, 0xf6, 0x1f, 0xf1, 0xcf, 0xec, + 0x48, 0x1e, 0xfd, 0xed, 0xe2, 0xb4, 0x20, 0x3e, 0xe2, 0xfc, 0xb4, 0xfa, 0xea, + 0x16, 0xf4, 0xd1, 0x04, 0xea, 0x17, 0x51, 0x18, 0x6e, 0x23, 0xec, 0x06, 0xec, + 0x62, 0x04, 0x5f, 0xe4, 0xbd, 0x20, 0x1a, 0xa6, 0xea, 0x19, 0xdf, 0xf1, 0xbf, + 0xf9, 0xfe, 0x8f, 0x05, 0xf7, 0xe9, 0xdd, 0xfb, 0x07, 0xec, 0x12, 0x00, 0x1b, + 0x49, 0x14, 0x2f, 0xd4, 0x06, 0x15, 0x12, 0x19, 0xeb, 0x12, 0xdf, 0xea, 0x44, + 0x07, 0xe1, 0x47, 0xfe, 0x46, 0xe0, 0x39, 0xe5, 0xe2, 0xcd, 0xee, 0x24, 0xde, + 0xe9, 0xfd, 0xb6, 0x2c, 0xc1, 0xed, 0xde, 0xc9, 0x28, 0xef, 0xdf, 0x06, 0x01, + 0xc7, 0xf4, 0xf3, 0x22, 0xde, 0x14, 0x0e, 0x00, 0x0f, 0x0f, 0xf2, 0xcf, 0x55, + 0xe2, 0xf4, 0xe5, 0x0a, 0x05, 0xeb, 0xd2, 0x28, 0xdf, 0x14, 0xc8, 0xcd, 0xda, + 0xfb, 0xf8, 0xed, 0xf3, 0x05, 0xd9, 0x7f, 0xfd, 0x2c, 0x20, 0xf0, 0x10, 0x0f, + 0xc8, 0xd8, 0x23, 0xba, 0xdb, 0xfb, 0x0f, 0x04, 0xca, 0xe8, 0x30, 0xff, 0xea, + 0x03, 0x4f, 0x03, 0xd3, 0xda, 0x20, 0xf0, 0xbe, 0xfd, 0x26, 0xca, 0x03, 0xc9, + 0xdf, 0x03, 0x48, 0xf9, 0x37, 0xf6, 0x13, 0x01, 0x21, 0xf3, 0x21, 0xc7, 0xd8, + 0xff, 0xaa, 0x36, 0x39, 0xef, 0x36, 0x03, 0x00, 0xe5, 0x3b, 0xe4, 0xf8, 0x32, + 0x3d, 0x17, 0x10, 0xe7, 0x28, 0x32, 0xbb, 0x10, 0xd0, 0xc3, 0x1b, 0x0a, 0xed, + 0xed, 0x11, 0x2d, 0x01, 0xd0, 0xf4, 0xf7, 0x03, 0x01, 0x12, 0xb5, 0x0a, 0xf5, + 0x04, 0x02, 0xf6, 0x17, 0x15, 0xf6, 0xaa, 0xea, 0xb3, 0x3a, 0x0d, 0x19, 0x43, + 0xdf, 0xf3, 0xdb, 0xcd, 0x4c, 0xd0, 0xf8, 0x0a, 0xeb, 0x36, 0xd6, 0x8e, 0x65, + 0x3c, 0xc1, 0x0e, 0x04, 0x1d, 0x40, 0xdb, 0x04, 0x27, 0x27, 0xbb, 0x2b, 0xc2, + 0xca, 0x0f, 0xf8, 0x1b, 0x27, 0xe2, 0x12, 0x8f, 0x15, 0xfe, 0xbc, 0xea, 0x4b, + 0xef, 0xe7, 0xfe, 0xbb, 0xc2, 0xe6, 0x08, 0xe3, 0xcc, 0x38, 0x36, 0xdb, 0x10, + 0x1a, 0x11, 0xe1, 0x10, 0xd3, 0xe5, 0xc1, 0xec, 0xd6, 0xe8, 0x30, 0xce, 0x2e, + 0x3b, 0xe7, 0xb9, 0xce, 0x01, 0x39, 0x3a, 0x04, 0x0c, 0x3b, 0xbe, 0xec, 0x2d, + 0xff, 0x07, 0x02, 0xf4, 0x61, 0x81, 0xf0, 0x39, 0x0c, 0xf3, 0xe4, 0xca, 0xc5, + 0xea, 0x21, 0xe5, 0x12, 0xef, 0xe2, 0xef, 0xeb, 0x13, 0xde, 0x21, 0x18, 0xf5, + 0xee, 0x02, 0x04, 0x43, 0xf4, 0xd7, 0xe9, 0x25, 0xd6, 0x4b, 0xff, 0x4e, 0xe1, + 0xe8, 0xd4, 0xfd, 0xe5, 0xfd, 0xf0, 0xde, 0xe7, 0x0e, 0xe9, 0xd3, 0xd0, 0x2f, + 0x25, 0xe1, 0x06, 0xfc, 0x21, 0xd7, 0xdf, 0x25, 0x7f, 0x1b, 0xee, 0x01, 0xed, + 0xf4, 0x29, 0xf3, 0x3e, 0x09, 0x22, 0xd8, 0xd9, 0x0e, 0xc5, 0x2e, 0xe5, 0x16, + 0x15, 0x3d, 0xb9, 0x0d, 0xff, 0xc5, 0xe0, 0xff, 0xfe, 0x33, 0xe3, 0x19, 0x61, + 0xe4, 0xfb, 0xfc, 0x32, 0xbf, 0xea, 0x00, 0x38, 0x45, 0x2b, 0xc5, 0x25, 0xec, + 0xd7, 0x0c, 0xf0, 0x30, 0xd0, 0xc1, 0x02, 0x20, 0xd9, 0xf4, 0x23, 0x5e, 0x21, + 0x45, 0x0f, 0x28, 0xe6, 0x4d, 0x02, 0x39, 0x08, 0xf1, 0xe4, 0xbd, 0x16, 0xff, + 0x02, 0xfe, 0xee, 0xe2, 0xd3, 0xcb, 0x35, 0x6c, 0x65, 0xfe, 0x03, 0x00, 0xf3, + 0xf0, 0xb9, 0x51, 0x0a, 0x4d, 0x01, 0x48, 0xd7, 0x12, 0x17, 0x1a, 0x0a, 0xf2, + 0x2f, 0x07, 0xf8, 0x02, 0xf5, 0x47, 0xca, 0x17, 0x09, 0xd3, 0x57, 0xfd, 0xe1, + 0xec, 0x05, 0xf9, 0x03, 0xfa, 0xdd, 0xf4, 0x3f, 0xb6, 0x00, 0x1c, 0xd9, 0x4a, + 0xea, 0x23, 0x03, 0xf8, 0xf5, 0x11, 0xfc, 0x13, 0x2f, 0x09, 0xb3, 0x0b, 0xeb, + 0x0d, 0x19, 0xf3, 0x27, 0xff, 0x03, 0xcb, 0x18, 0x56, 0xd9, 0x1d, 0xec, 0xbb, + 0xe5, 0x22, 0xf9, 0xf6, 0x14, 0x13, 0x7f, 0x0c, 0x1b, 0xb0, 0x0e, 0x19, 0x2c, + 0x2e, 0x03, 0x31, 0x0c, 0xff, 0x31, 0x11, 0x18, 0x03, 0x28, 0xde, 0x1b, 0xe4, + 0x1e, 0x1b, 0xfb, 0x10, 0xed, 0x0f, 0xff, 0x18, 0xd9, 0x1a, 0xde, 0xfa, 0xe7, + 0xb4, 0x30, 0xbe, 0x4f, 0x01, 0x20, 0x1a, 0x02, 0xfe, 0x61, 0x0e, 0x22, 0x1d, + 0x0e, 0x30, 0x38, 0xc0, 0xdd, 0x2c, 0xf5, 0xd1, 0x03, 0x2f, 0x51, 0x3f, 0xdd, + 0xdb, 0xfc, 0x13, 0x23, 0xc5, 0x07, 0x02, 0xa5, 0x20, 0x35, 0xf9, 0x0b, 0xdd, + 0xf9, 0x1a, 0xfc, 0x0e, 0xfb, 0x23, 0x20, 0x3f, 0x12, 0x1c, 0xe2, 0xff, 0xec, + 0xdf, 0xe5, 0xdb, 0x0a, 0x03, 0x16, 0xc1, 0x0e, 0xe0, 0xf3, 0x09, 0xfc, 0x0a, + 0xd9, 0x03, 0x7f, 0x06, 0x26, 0xfe, 0xfb, 0x06, 0xcd, 0xe9, 0x0f, 0x1e, 0xfa, + 0xe8, 0x18, 0xd5, 0xdf, 0x1b, 0x12, 0xe0, 0x1c, 0xe7, 0x16, 0x15, 0xb4, 0x03, + 0xf5, 0xca, 0xd4, 0x33, 0x0a, 0xf7, 0xfc, 0x31, 0xb2, 0xef, 0xf2, 0xf1, 0xf2, + 0xfe, 0xf3, 0xf9, 0xfd, 0xf6, 0xd4, 0x05, 0x10, 0x60, 0x48, 0x11, 0xd8, 0xf4, + 0x23, 0x08, 0xf4, 0xee, 0xe4, 0xc6, 0x22, 0x14, 0xdc, 0xfc, 0x06, 0xff, 0x18, + 0x0f, 0x1c, 0xf2, 0xdd, 0x30, 0x35, 0x53, 0x01, 0xd0, 0xfa, 0xdd, 0x1a, 0x0d, + 0x54, 0x09, 0xcf, 0x1e, 0xf4, 0x0d, 0xef, 0x02, 0x1a, 0xf0, 0x10, 0xef, 0x18, + 0xfc, 0x0a, 0x1a, 0xfc, 0x0a, 0xec, 0x0f, 0x2e, 0x01, 0xfa, 0x27, 0x19, 0xfd, + 0xef, 0x0f, 0xef, 0x3f, 0xf3, 0x04, 0xf7, 0x0b, 0x3d, 0x2e, 0xef, 0x02, 0xea, + 0xf8, 0xf1, 0xb5, 0x02, 0x3d, 0xb7, 0x0c, 0xc2, 0xf2, 0x24, 0x02, 0xc8, 0x4d, + 0xd7, 0x16, 0xee, 0x2c, 0x22, 0xa4, 0x21, 0x00, 0x0d, 0xe4, 0xc1, 0xff, 0x3b, + 0xf2, 0x18, 0x10, 0x7f, 0x27, 0xd9, 0xfd, 0x0b, 0x11, 0xfa, 0xac, 0xd7, 0x0e, + 0xd2, 0xc8, 0xbd, 0xf9, 0xd4, 0x1c, 0x4f, 0x48, 0xe4, 0xf1, 0x02, 0x2c, 0xab, + 0x3c, 0x0d, 0x97, 0xc9, 0xc2, 0xdb, 0xeb, 0xf6, 0x17, 0x36, 0xb7, 0x09, 0xfb, + 0xea, 0xfa, 0xad, 0xcf, 0xf9, 0xee, 0x2c, 0x38, 0x64, 0xb2, 0xb7, 0xe7, 0xf7, + 0xe4, 0xf6, 0x1b, 0x0f, 0xfb, 0x0a, 0xf4, 0x11, 0xc6, 0x0c, 0xfa, 0xa0, 0xec, + 0xf7, 0xe6, 0xc3, 0x21, 0xd7, 0xe1, 0xfe, 0x9e, 0xc9, 0x01, 0xef, 0x05, 0xbc, + 0xb4, 0x2a, 0x46, 0x42, 0xbc, 0xd7, 0xe9, 0xec, 0x17, 0xfc, 0x24, 0xff, 0x47, + 0x8f, 0x4f, 0xfc, 0xeb, 0xcd, 0xdc, 0xea, 0xec, 0x91, 0xe6, 0xee, 0x26, 0x9f, + 0xf3, 0x0e, 0xe2, 0x1e, 0x18, 0xa9, 0x56, 0xe2, 0x96, 0x3a, 0x02, 0xf9, 0xa0, + 0x21, 0x47, 0x51, 0x28, 0xd2, 0x0f, 0xa6, 0x86, 0x16, 0xf7, 0xec, 0xea, 0xa5, + 0xcf, 0x4b, 0x24, 0x4f, 0xfb, 0xc4, 0x43, 0x47, 0xf2, 0xd5, 0x31, 0xa4, 0x48, + 0xc0, 0xe5, 0xc5, 0xe9, 0x97, 0xa3, 0xbf, 0xe6, 0xed, 0x66, 0xf1, 0xff, 0x0e, + 0x6c, 0x42, 0x5c, 0xef, 0xe3, 0x25, 0x4e, 0xd3, 0xac, 0xc3, 0xf7, 0x25, 0x09, + 0xd3, 0x13, 0x02, 0xea, 0xd6, 0x29, 0x4e, 0xd5, 0x23, 0x35, 0xd0, 0xd8, 0xe8, + 0xc5, 0x3c, 0x81, 0xad, 0x38, 0x02, 0xa9, 0x98, 0xe8, 0xcd, 0x2e, 0xd7, 0xd5, + 0xb7, 0x0e, 0x48, 0x2b, 0x5a, 0x41, 0x57, 0x14, 0xc4, 0x10, 0xeb, 0x61, 0x16, + 0x1b, 0xa3, 0xfc, 0x33, 0xf7, 0xeb, 0x96, 0x24, 0xe9, 0xdf, 0x26, 0x05, 0x19, + 0xe3, 0xf2, 0x08, 0x4a, 0xdb, 0xbc, 0x08, 0x13, 0x0b, 0x81, 0x09, 0xf1, 0x04, + 0x05, 0x09, 0x1c, 0x56, 0xe2, 0x11, 0x0a, 0x0f, 0xc6, 0x54, 0xfd, 0x15, 0xcc, + 0x20, 0xfc, 0x18, 0xfb, 0x0a, 0xee, 0x39, 0x21, 0x35, 0xd4, 0xeb, 0x2b, 0xe1, + 0x2b, 0x11, 0x2e, 0xd9, 0x26, 0xdd, 0xc0, 0x11, 0xf3, 0x31, 0xe2, 0xeb, 0xf0, + 0xf1, 0xf9, 0xe7, 0xfa, 0x14, 0xd2, 0xe7, 0xf3, 0x1f, 0x28, 0x46, 0xf5, 0x36, + 0xcf, 0x14, 0xea, 0x01, 0x10, 0xb8, 0xcb, 0x0b, 0x17, 0xc6, 0xf2, 0xf0, 0xe2, + 0xf4, 0x31, 0xdf, 0x2d, 0x23, 0xf2, 0x02, 0x12, 0x0f, 0x44, 0x1f, 0xfa, 0x2f, + 0x08, 0x39, 0x22, 0xc6, 0xe3, 0xc5, 0x0b, 0x13, 0x02, 0xcf, 0xd8, 0x09, 0x12, + 0xc9, 0xd3, 0xec, 0x0c, 0xe3, 0xe7, 0x17, 0x39, 0x10, 0x27, 0x05, 0x1b, 0x1b, + 0x1c, 0xe8, 0x12, 0x13, 0x2a, 0xde, 0xec, 0xfb, 0xe5, 0xfd, 0x37, 0xe3, 0xcb, + 0x20, 0xe1, 0x2f, 0xc5, 0x20, 0xc2, 0x06, 0x29, 0x0e, 0xdf, 0x5b, 0xf6, 0xfc, + 0xcf, 0x55, 0xf3, 0x7e, 0xca, 0x0d, 0xfd, 0xd3, 0xbd, 0xd0, 0x04, 0x09, 0x99, + 0x30, 0xd9, 0x24, 0xc0, 0xf1, 0xe7, 0x4a, 0xfc, 0x6c, 0xf3, 0x01, 0xd4, 0xfa, + 0x1c, 0x5e, 0x20, 0xea, 0xc3, 0x06, 0xc9, 0x0a, 0x8a, 0x32, 0xe2, 0x2f, 0xf3, + 0x1f, 0x12, 0x39, 0x12, 0x12, 0xaa, 0x02, 0x3f, 0x51, 0xb5, 0x59, 0x1f, 0x32, + 0x13, 0x1a, 0x22, 0xc9, 0xf0, 0xff, 0xef, 0xb1, 0xd9, 0xc6, 0xdd, 0xf2, 0xfa, + 0x2e, 0x3a, 0x4f, 0xd4, 0x02, 0xc7, 0xcf, 0xf7, 0xcb, 0x12, 0x8f, 0x0a, 0x14, + 0xe5, 0x85, 0x0d, 0xbe, 0xd1, 0xa3, 0x22, 0x50, 0xa7, 0x4d, 0xec, 0xe0, 0x0b, + 0x24, 0xb0, 0x31, 0x4c, 0x17, 0xf7, 0x00, 0x8c, 0xe0, 0x7f, 0x1b, 0xe6, 0xdd, + 0xf5, 0x36, 0x04, 0xf7, 0x93, 0xef, 0x38, 0x4c, 0x03, 0x1b, 0x5f, 0xe9, 0x26, + 0x20, 0x14, 0xfb, 0xf1, 0x0a, 0xcf, 0xfe, 0x09, 0x05, 0xaa, 0x34, 0x21, 0xc4, + 0xcb, 0x09, 0xf3, 0xdc, 0xff, 0x7f, 0x0f, 0xda, 0x0e, 0x22, 0x23, 0x2f, 0xf7, + 0x11, 0xf9, 0x13, 0x18, 0x2d, 0xe0, 0x34, 0x34, 0x19, 0xe4, 0x0c, 0x27, 0xbd, + 0x08, 0xe0, 0xe8, 0xeb, 0x19, 0xff, 0x1e, 0x0c, 0xe9, 0xfc, 0x49, 0x07, 0x0c, + 0x10, 0x15, 0xdb, 0x20, 0x02, 0x26, 0x07, 0x1c, 0x25, 0x23, 0xd0, 0x10, 0x12, + 0x46, 0xe4, 0xc8, 0x02, 0xdf, 0x0e, 0x14, 0xfb, 0xe9, 0xf7, 0x1a, 0x0b, 0x0b, + 0x22, 0x02, 0xf9, 0x0f, 0xf9, 0x24, 0x0a, 0x27, 0x10, 0x0f, 0x23, 0x1a, 0x87, + 0x01, 0xf4, 0xde, 0x10, 0x06, 0x04, 0x1b, 0xe9, 0xdd, 0xe2, 0x0c, 0x19, 0xc5, + 0x0a, 0x0b, 0x19, 0xe6, 0x20, 0x35, 0xf3, 0x22, 0xf7, 0xff, 0x39, 0x1a, 0x06, + 0xed, 0x21, 0xf7, 0xd3, 0x09, 0x22, 0x05, 0xe5, 0xf0, 0x0a, 0xf6, 0xfe, 0x0a, + 0x13, 0x05, 0x51, 0x19, 0x10, 0x34, 0xfd, 0x44, 0xf4, 0xe3, 0xf8, 0xf2, 0xf4, + 0x30, 0xe9, 0xf8, 0x19, 0xfa, 0x0a, 0xdb, 0x0e, 0x0a, 0xc9, 0xff, 0xe7, 0xdd, + 0x28, 0xf3, 0x05, 0x42, 0xe6, 0xf3, 0x18, 0xf9, 0xe9, 0xf4, 0x08, 0x20, 0x1d, + 0x20, 0x39, 0xe8, 0x11, 0x07, 0xf7, 0xd1, 0x3a, 0xee, 0xdc, 0xfa, 0x35, 0xf3, + 0x0d, 0x17, 0x12, 0xf9, 0x1c, 0xfa, 0x09, 0x06, 0x05, 0x17, 0x27, 0x00, 0x21, + 0xcb, 0x0c, 0xff, 0x20, 0xc7, 0x03, 0xf4, 0x0a, 0x20, 0x15, 0xe1, 0x26, 0x02, + 0xd9, 0x12, 0x0e, 0x41, 0xfc, 0x24, 0x01, 0xe9, 0x24, 0xeb, 0x05, 0x19, 0x1b, + 0x11, 0xd4, 0x27, 0xe1, 0x08, 0x07, 0xfb, 0xe3, 0xe1, 0x20, 0x1e, 0xfd, 0xe6, + 0xc1, 0x1d, 0xda, 0xe9, 0xd8, 0x03, 0x08, 0xc1, 0x19, 0x0f, 0x33, 0xde, 0xf3, + 0x17, 0xe9, 0x0b, 0x0d, 0x04, 0x7f, 0x1d, 0xfd, 0x05, 0x36, 0xb6, 0xd1, 0x22, + 0x07, 0x5e, 0x1e, 0xeb, 0xfc, 0x3c, 0xd1, 0x15, 0x0a, 0x1b, 0x11, 0xd7, 0x29, + 0x19, 0x3d, 0xa9, 0x20, 0xda, 0xc0, 0xeb, 0xa3, 0x20, 0xdf, 0xe0, 0x8f, 0xee, + 0x0e, 0xf8, 0xf0, 0xfb, 0x16, 0xed, 0x43, 0x0b, 0xb0, 0x1c, 0x06, 0x85, 0x26, + 0xe8, 0x23, 0xc4, 0x65, 0x11, 0x26, 0xf4, 0x2d, 0xfa, 0x11, 0xd1, 0xc9, 0x42, + 0xdd, 0x1f, 0xbe, 0xae, 0x0b, 0x03, 0x52, 0x07, 0xc1, 0xd7, 0x25, 0x23, 0x07, + 0x2c, 0xd5, 0x0b, 0x1a, 0x14, 0x3b, 0xd8, 0x13, 0x31, 0x37, 0x0d, 0x1d, 0x25, + 0xda, 0xe8, 0x03, 0x17, 0xf9, 0x7f, 0x03, 0x01, 0x30, 0x29, 0x53, 0x56, 0xf6, + 0x18, 0x9b, 0xde, 0xe9, 0xc3, 0xed, 0xe6, 0x1a, 0x9e, 0x37, 0xda, 0x0f, 0xcb, + 0x2c, 0x21, 0xd8, 0x42, 0x16, 0x00, 0x22, 0x36, 0x45, 0x18, 0xbf, 0xff, 0x0d, + 0x25, 0xff, 0xaf, 0xf8, 0xef, 0xdc, 0x1c, 0x9f, 0x05, 0xeb, 0x26, 0xe2, 0xdd, + 0x3c, 0x02, 0x06, 0xfa, 0xe9, 0xf7, 0xa9, 0x15, 0x07, 0xf8, 0xf7, 0x0c, 0xfe, + 0xe1, 0xff, 0x24, 0x9e, 0xd7, 0xbe, 0xdf, 0x0a, 0xf6, 0xca, 0x05, 0xf6, 0x15, + 0xe7, 0xf2, 0x3b, 0x0f, 0xdb, 0x2c, 0x27, 0x98, 0x13, 0x74, 0xff, 0xf7, 0x11, + 0xde, 0x40, 0x2d, 0xeb, 0x02, 0xe2, 0xe7, 0xea, 0xdf, 0x00, 0x32, 0xea, 0xd9, + 0xfc, 0xc6, 0xfc, 0xf5, 0xdd, 0x02, 0xd7, 0xd7, 0xe1, 0x23, 0xe5, 0xbf, 0xcd, + 0x64, 0x4a, 0xe4, 0xf3, 0x7f, 0x1d, 0x05, 0x96, 0x53, 0x22, 0xe8, 0xb6, 0xc2, + 0x18, 0x23, 0x1a, 0x64, 0xec, 0x03, 0xe5, 0xcc, 0x4e, 0x6d, 0xf5, 0x5f, 0xf0, + 0x86, 0x00, 0xc0, 0xdd, 0x28, 0x15, 0x47, 0x1a, 0x21, 0x00, 0xdf, 0x0c, 0xd2, + 0xf5, 0x0b, 0xd8, 0xd5, 0x37, 0x2c, 0xf6, 0x1a, 0x15, 0xce, 0xe4, 0xef, 0xf9, + 0x1f, 0x08, 0xd1, 0x41, 0x0f, 0xd1, 0x44, 0xe5, 0x25, 0x36, 0x0e, 0x0c, 0xf6, + 0xf6, 0xf2, 0x2c, 0x22, 0xb1, 0x1d, 0x15, 0x21, 0x5b, 0x25, 0x11, 0x75, 0xba, + 0xd9, 0x10, 0x1e, 0xf7, 0x01, 0xdd, 0xf6, 0x7f, 0xb7, 0xfc, 0x12, 0x1e, 0x02, + 0xcb, 0xeb, 0xf0, 0x00, 0xea, 0xbd, 0x35, 0xbc, 0x1f, 0x10, 0x14, 0xd2, 0x07, + 0xdc, 0xce, 0xc6, 0x02, 0x01, 0x21, 0x50, 0xc8, 0xb7, 0xf2, 0x23, 0xcd, 0xce, + 0x02, 0xb8, 0x4c, 0x01, 0xbf, 0x2e, 0xea, 0x1e, 0x52, 0x3e, 0xc5, 0xfd, 0x37, + 0x07, 0x2b, 0x0f, 0x14, 0xaf, 0xfd, 0x26, 0xdc, 0xe4, 0xf8, 0x1a, 0x0b, 0xff, + 0x65, 0x02, 0x00, 0x35, 0xaf, 0x33, 0xd5, 0x30, 0x62, 0x11, 0x04, 0xe2, 0xe3, + 0xda, 0x39, 0x3b, 0x2e, 0x1f, 0x47, 0x55, 0x39, 0x0c, 0xf8, 0x22, 0x1e, 0x2d, + 0xce, 0x75, 0x07, 0x02, 0x0a, 0xfa, 0x43, 0x58, 0x15, 0xcb, 0xf9, 0x3f, 0xcb, + 0xdc, 0xe0, 0xf0, 0x04, 0x46, 0xbc, 0xca, 0x0f, 0xf9, 0x04, 0xe7, 0x25, 0x15, + 0xb8, 0xe1, 0xd8, 0x14, 0x24, 0x49, 0x0e, 0x2c, 0xe1, 0x98, 0x1c, 0xdb, 0xfe, + 0x34, 0xe8, 0xe7, 0xea, 0x16, 0x0f, 0x00, 0x49, 0x7f, 0x34, 0x41, 0xe3, 0x0b, + 0x0e, 0x49, 0x63, 0x45, 0xf3, 0xe8, 0xe1, 0xcc, 0xcc, 0xbd, 0x49, 0x07, 0xcc, + 0xee, 0xf4, 0x53, 0x02, 0x5e, 0x23, 0x31, 0xe0, 0xf8, 0xfb, 0xf5, 0xe1, 0xeb, + 0xd7, 0xe8, 0x02, 0x2c, 0x30, 0xcd, 0x27, 0x31, 0xcb, 0xf0, 0xe6, 0x03, 0xf9, + 0x67, 0xee, 0xd8, 0x36, 0xb9, 0x02, 0x4c, 0xdf, 0xae, 0xd0, 0xfc, 0xf8, 0xc5, + 0x50, 0xde, 0x46, 0x00, 0xf9, 0xdd, 0xc5, 0x68, 0x12, 0xfc, 0xe2, 0xff, 0xee, + 0xe4, 0xf2, 0xec, 0xf9, 0x77, 0xc7, 0x7f, 0x2a, 0x1e, 0xf2, 0xd0, 0x45, 0x9b, + 0x61, 0xff, 0x33, 0xdd, 0x20, 0xaf, 0xed, 0x6a, 0x03, 0x1a, 0xe2, 0x5a, 0x08, + 0x07, 0x50, 0xc6, 0xd8, 0x1f, 0x02, 0xc5, 0xe6, 0xe4, 0xb3, 0xfe, 0x0f, 0x1f, + 0xe0, 0x02, 0xf5, 0xd1, 0x1e, 0xfb, 0xa4, 0x07, 0x1a, 0xcb, 0x34, 0xcf, 0xf6, + 0x16, 0x38, 0x1b, 0x19, 0x2e, 0x2d, 0xe7, 0xc5, 0xca, 0xe3, 0x19, 0x10, 0x03, + 0xdc, 0xd1, 0xfd, 0x35, 0x0e, 0x0c, 0xb0, 0xe2, 0x5a, 0xdd, 0xf3, 0x81, 0xee, + 0xe0, 0x18, 0xea, 0xe5, 0x42, 0x6f, 0x07, 0xf9, 0xa2, 0x6e, 0xd4, 0x36, 0x14, + 0x49, 0xd0, 0x4f, 0x0b, 0xe6, 0xd6, 0xbf, 0x0b, 0xea, 0x13, 0x1a, 0xc6, 0x08, + 0x1c, 0x1d, 0xb3, 0xfe, 0x0a, 0xe7, 0x23, 0xe6, 0xd0, 0xc7, 0xc9, 0xe7, 0xf3, + 0x43, 0x1b, 0x02, 0x66, 0xee, 0x02, 0x5b, 0xf3, 0x31, 0x0a, 0x5b, 0xc6, 0xef, + 0xdb, 0xd5, 0x35, 0xec, 0xf8, 0x3a, 0xb5, 0xf9, 0x25, 0xfc, 0x40, 0xa3, 0x24, + 0x0f, 0xfb, 0xd4, 0x13, 0xf6, 0xee, 0xb2, 0x2f, 0xef, 0x8b, 0xf5, 0x28, 0x69, + 0xef, 0xc4, 0xdb, 0x03, 0xfe, 0xe8, 0x00, 0x01, 0x3e, 0x1b, 0x2a, 0x3f, 0x2a, + 0x11, 0x0b, 0x03, 0xfa, 0xdc, 0xef, 0x1d, 0x47, 0xd1, 0xfe, 0x23, 0x14, 0x0b, + 0x0e, 0x2c, 0xd5, 0x4d, 0x0e, 0xcc, 0xd0, 0xed, 0x2e, 0x1d, 0x0e, 0x11, 0xfa, + 0xfb, 0xc4, 0xea, 0x33, 0x02, 0x36, 0x1e, 0xd4, 0xc5, 0x0c, 0xdf, 0xd8, 0x25, + 0xc3, 0xfa, 0xcc, 0x2c, 0x39, 0xc0, 0xea, 0xee, 0x06, 0xda, 0x27, 0x31, 0x1e, + 0x19, 0xff, 0x00, 0x0c, 0xf5, 0x12, 0xbe, 0x06, 0xd1, 0x5d, 0x13, 0xe6, 0xcc, + 0xc9, 0xf9, 0x6c, 0xf7, 0xe7, 0x57, 0xcc, 0x03, 0xd8, 0x3a, 0xb4, 0x7f, 0x1b, + 0xf7, 0xd3, 0x1f, 0xfe, 0xcc, 0xeb, 0xf6, 0x34, 0x12, 0xd0, 0xcd, 0x4b, 0xd8, + 0xeb, 0x11, 0x0d, 0xfd, 0x21, 0xf9, 0xd2, 0x90, 0x25, 0x03, 0xe8, 0x01, 0x1a, + 0x0c, 0x22, 0x29, 0x5e, 0xdd, 0xf0, 0xc4, 0x3e, 0xe1, 0xaf, 0x09, 0x1c, 0x03, + 0x4a, 0x1e, 0x27, 0x17, 0xe9, 0x35, 0xe4, 0xfb, 0xe9, 0x11, 0xc6, 0xcf, 0x02, + 0xb8, 0x35, 0x4d, 0x5f, 0xe2, 0xd9, 0x13, 0xff, 0x5a, 0x14, 0x15, 0x0f, 0xd3, + 0xca, 0xdc, 0xf9, 0x21, 0x1d, 0x48, 0xe4, 0x40, 0x20, 0xda, 0xce, 0xf0, 0x38, + 0xfe, 0xc9, 0x08, 0xdf, 0x13, 0x16, 0x27, 0xfe, 0xb1, 0xf0, 0xde, 0xa1, 0x1c, + 0xd9, 0x04, 0xf2, 0xe0, 0xf7, 0xe9, 0xd9, 0x30, 0x1b, 0x01, 0xde, 0xc4, 0xf8, + 0xe2, 0xd2, 0x13, 0xf5, 0x47, 0x07, 0xec, 0x57, 0xe7, 0xd2, 0xf6, 0xe3, 0xb5, + 0xfc, 0xbc, 0x00, 0x36, 0xef, 0x7f, 0x27, 0x43, 0xc8, 0xb1, 0x3a, 0xed, 0xd8, + 0xf0, 0x1b, 0x2e, 0xe4, 0x34, 0x4c, 0xfd, 0xf0, 0x0e, 0x48, 0xd9, 0x18, 0x26, + 0x2d, 0x04, 0xbd, 0xad, 0xd7, 0xbf, 0x08, 0xe4, 0x1e, 0x0c, 0xff, 0x6b, 0x39, + 0xe9, 0x25, 0x25, 0xf6, 0xf2, 0xe2, 0x00, 0x1f, 0xce, 0x53, 0xf6, 0x02, 0xf5, + 0xd2, 0x0b, 0xf9, 0x19, 0xfb, 0x10, 0xfa, 0xdc, 0xd7, 0xfa, 0xf9, 0x0e, 0xf8, + 0xdc, 0x05, 0x0a, 0x20, 0x12, 0x12, 0xf8, 0x1b, 0x39, 0x36, 0x0b, 0xc5, 0xf9, + 0x12, 0x01, 0xb0, 0xa3, 0xd3, 0xcc, 0x03, 0xef, 0x3e, 0x10, 0x28, 0x35, 0x14, + 0x34, 0x17, 0x10, 0xe5, 0x59, 0x2b, 0xfb, 0xcb, 0xe8, 0x06, 0xe6, 0xf9, 0xd8, + 0xd2, 0xf9, 0xa0, 0xe6, 0x99, 0x16, 0xf5, 0x59, 0x47, 0xbd, 0x3c, 0xd6, 0xda, + 0x02, 0xf9, 0x7f, 0xe0, 0xc6, 0xfe, 0xe4, 0x11, 0xc8, 0x0b, 0x19, 0xeb, 0x27, + 0x0a, 0x1e, 0xdd, 0x1a, 0x06, 0x0c, 0x0a, 0x10, 0xfa, 0x36, 0x1e, 0xbe, 0xb8, + 0x9b, 0x16, 0x0f, 0xcc, 0x0c, 0x00, 0x41, 0x1d, 0x44, 0x1a, 0x10, 0xf4, 0xff, + 0x51, 0xfc, 0x23, 0x37, 0xfd, 0xe0, 0x20, 0x2a, 0xe5, 0x2b, 0x4e, 0xf6, 0x09, + 0x3f, 0x1f, 0xeb, 0x0b, 0xe5, 0xe3, 0xcd, 0xd5, 0xb3, 0x15, 0x39, 0x22, 0x95, + 0xd7, 0x32, 0xb2, 0xcc, 0x19, 0xe2, 0x28, 0xd2, 0x55, 0xd7, 0x41, 0x81, 0x44, + 0x0c, 0xfa, 0x22, 0xf5, 0xd9, 0xdd, 0xe9, 0xd9, 0x1b, 0x17, 0x79, 0x96, 0x24, + 0x04, 0x16, 0x19, 0x19, 0xd2, 0x0b, 0xde, 0xce, 0xbb, 0xc9, 0xc2, 0x05, 0x20, + 0x20, 0x0b, 0xce, 0xe6, 0xe4, 0x0c, 0xdd, 0x06, 0xd1, 0x18, 0x0b, 0xfe, 0xf3, + 0xe6, 0x08, 0xf6, 0xeb, 0x92, 0x09, 0xd4, 0x01, 0x14, 0x54, 0x4c, 0x4b, 0x0f, + 0x27, 0x21, 0x32, 0xea, 0xb4, 0xc3, 0x11, 0xcc, 0xc9, 0xf9, 0x19, 0xd3, 0x6a, + 0x09, 0x2b, 0xe2, 0xf7, 0x0f, 0x09, 0x84, 0xc8, 0x64, 0xb1, 0xdb, 0xf7, 0x51, + 0x1e, 0xe5, 0x6a, 0xdf, 0x1e, 0xf4, 0xad, 0x0f, 0xb6, 0x00, 0xea, 0xde, 0x12, + 0x7b, 0xab, 0xdd, 0x39, 0x19, 0xf2, 0x90, 0x30, 0x1b, 0xe4, 0x3d, 0x39, 0x3b, + 0x3b, 0x08, 0x0a, 0xe6, 0xd0, 0x47, 0x01, 0xcf, 0xf7, 0x04, 0xd7, 0x22, 0x9f, + 0xb9, 0x34, 0xdd, 0x81, 0x33, 0x16, 0xda, 0x18, 0x2e, 0x2d, 0xec, 0x1b, 0xf3, + 0xf2, 0xfe, 0xd4, 0x00, 0xf9, 0xc1, 0x4f, 0xd7, 0xff, 0xfe, 0xa4, 0x1a, 0x05, + 0x19, 0xfb, 0xfc, 0x04, 0x15, 0xff, 0xf9, 0xe9, 0x12, 0xfe, 0x02, 0x0e, 0x0f, + 0x06, 0x2f, 0xc1, 0xe7, 0xbb, 0xbe, 0xbf, 0xd7, 0xfa, 0xff, 0xd9, 0xd9, 0xf9, + 0xfa, 0xfd, 0xf9, 0xcd, 0x09, 0xe4, 0xfc, 0xf2, 0x2a, 0x23, 0x20, 0xf6, 0xf2, + 0xb2, 0x55, 0xe5, 0xeb, 0x29, 0xf3, 0xef, 0x17, 0x08, 0xf9, 0x0a, 0x20, 0xfe, + 0x05, 0x3a, 0x43, 0x1b, 0xe0, 0x2b, 0x23, 0x00, 0x16, 0xf4, 0x2d, 0x31, 0x00, + 0x0e, 0xf7, 0x31, 0x39, 0x39, 0x39, 0xef, 0x14, 0x08, 0x32, 0x2e, 0x37, 0xf6, + 0xf9, 0xe3, 0xcb, 0xef, 0xa9, 0xcf, 0x0f, 0xd8, 0xea, 0x97, 0xfa, 0xf4, 0x14, + 0x1d, 0xd5, 0xd9, 0xef, 0xda, 0x38, 0xed, 0x0d, 0xf9, 0x2d, 0xd7, 0xf5, 0xd8, + 0x2b, 0xd4, 0x08, 0xe2, 0x32, 0xfa, 0x4a, 0x7f, 0x2a, 0x3f, 0xe1, 0x19, 0xd9, + 0xef, 0xc0, 0x02, 0x3a, 0x25, 0x2b, 0xe8, 0xc1, 0xa6, 0x30, 0x06, 0xc7, 0x22, + 0xf4, 0x07, 0xea, 0x19, 0x1c, 0x0c, 0x16, 0xe1, 0x30, 0x43, 0x1e, 0xf2, 0xfb, + 0xe2, 0xed, 0x4d, 0x49, 0xb9, 0xb9, 0x9d, 0xd2, 0x27, 0xf7, 0xfb, 0x20, 0xba, + 0x19, 0xdb, 0x22, 0xe6, 0x1f, 0x2b, 0xf2, 0x35, 0x2f, 0xd2, 0x05, 0xd3, 0x27, + 0xef, 0x12, 0xe5, 0x1b, 0xdd, 0x0e, 0xdf, 0xd6, 0xd0, 0xf6, 0xf8, 0xe4, 0xc6, + 0xd0, 0x62, 0x16, 0xd7, 0xc9, 0x1e, 0x17, 0xc9, 0x04, 0x30, 0xd7, 0x04, 0x0e, + 0x02, 0xf1, 0x06, 0x09, 0x01, 0x0d, 0x3c, 0xed, 0x05, 0x0b, 0xaf, 0xca, 0x04, + 0x09, 0xe1, 0x19, 0x06, 0x36, 0x19, 0xe0, 0xe8, 0x06, 0xcb, 0xc4, 0xf2, 0x40, + 0x08, 0xba, 0x4e, 0xfa, 0x93, 0xd6, 0x9d, 0x05, 0x24, 0xa4, 0x04, 0x50, 0x1c, + 0xe0, 0x54, 0x23, 0xd6, 0xbc, 0x66, 0xc7, 0x57, 0x71, 0xfb, 0x59, 0x1e, 0x59, + 0x0d, 0xec, 0xd3, 0xe6, 0x0a, 0x01, 0x57, 0xb5, 0x30, 0xe4, 0xd8, 0x40, 0x1a, + 0x39, 0xd8, 0x50, 0xf3, 0xe6, 0x12, 0x20, 0xea, 0x4b, 0xf9, 0x2a, 0x0a, 0xfc, + 0x29, 0xe1, 0xa1, 0x4d, 0x2b, 0x6e, 0x19, 0x22, 0x46, 0x1a, 0xc4, 0xe5, 0xf6, + 0xce, 0x43, 0xed, 0x2e, 0xe1, 0xe0, 0x2a, 0x41, 0xd4, 0xb4, 0xef, 0xe1, 0x13, + 0x2c, 0x36, 0xd4, 0xef, 0xdc, 0x46, 0x30, 0x4a, 0x03, 0xec, 0x2a, 0xdc, 0xaa, + 0xc6, 0x64, 0x4d, 0xf9, 0xa1, 0x15, 0xbb, 0x1f, 0x93, 0x01, 0x17, 0x07, 0xf7, + 0xab, 0x81, 0x65, 0x23, 0xf6, 0x58, 0x0b, 0x3e, 0x28, 0xc7, 0x92, 0x18, 0x32, + 0x4e, 0xec, 0xf1, 0x20, 0xe5, 0xb8, 0xae, 0xff, 0x5d, 0xd4, 0x57, 0x59, 0x46, + 0xca, 0x15, 0x42, 0xe5, 0x6f, 0x02, 0x40, 0xc2, 0xd1, 0xe1, 0xc7, 0xdc, 0x00, + 0x00, 0xed, 0xaf, 0xea, 0x2f, 0xc7, 0xdb, 0x37, 0xcd, 0x1a, 0x05, 0xd1, 0xe9, + 0xf5, 0x0a, 0xd1, 0x11, 0x6a, 0x2a, 0x30, 0x1e, 0xc8, 0x5c, 0xab, 0x1e, 0x6c, + 0xd1, 0x7a, 0x22, 0xfb, 0xea, 0x58, 0x08, 0x1c, 0x7f, 0x11, 0xe8, 0xdc, 0xc6, + 0xb8, 0x22, 0x98, 0x17, 0xc0, 0xd9, 0xb3, 0x07, 0x02, 0x57, 0xe0, 0xf4, 0x1b, + 0xa9, 0xfa, 0x39, 0xf4, 0xef, 0x23, 0xa9, 0x2d, 0x4e, 0x20, 0xb9, 0x0b, 0xda, + 0x38, 0xbb, 0x99, 0xf7, 0x18, 0xd7, 0xd4, 0x6a, 0x1d, 0x53, 0x89, 0x2c, 0xa7, + 0xcb, 0xf1, 0x04, 0xd9, 0x65, 0xfb, 0x64, 0x18, 0x08, 0xfc, 0xb5, 0x1e, 0x1b, + 0xda, 0x15, 0xb7, 0xe2, 0x18, 0x2f, 0x01, 0x22, 0xc8, 0x20, 0x3e, 0x5c, 0x8e, + 0x1f, 0xea, 0xcd, 0x4a, 0x3b, 0xe3, 0x74, 0x7b, 0x04, 0x93, 0xe1, 0x20, 0xf1, + 0x3a, 0xe5, 0xe8, 0xf5, 0xa6, 0x16, 0x60, 0xde, 0x27, 0xe5, 0xed, 0xf9, 0xbb, + 0x19, 0x20, 0xc6, 0x0f, 0x7c, 0x23, 0xd2, 0xe5, 0x0f, 0x03, 0xd9, 0xda, 0xf2, + 0xdc, 0xde, 0xcc, 0x26, 0x0b, 0x27, 0xdf, 0x19, 0x05, 0xff, 0x49, 0xc9, 0x10, + 0x28, 0x0b, 0xdd, 0xdd, 0x02, 0x01, 0xff, 0xbe, 0xd4, 0x34, 0x09, 0x0a, 0xd8, + 0xe3, 0x00, 0xc6, 0xf6, 0x0a, 0x1f, 0xee, 0xd9, 0xe5, 0x2c, 0x43, 0xe5, 0x14, + 0xec, 0x05, 0x9c, 0x0a, 0xd3, 0xfc, 0x0a, 0xd7, 0x26, 0x3e, 0x24, 0xda, 0xd0, + 0xe2, 0x4f, 0x0c, 0xd8, 0xb7, 0x60, 0x9e, 0xf8, 0xf9, 0xe5, 0x4a, 0xd0, 0xd1, + 0x69, 0x00, 0x9d, 0xb9, 0xb9, 0x28, 0xec, 0xd9, 0x1c, 0x19, 0xda, 0x71, 0xab, + 0x33, 0x7e, 0x41, 0x05, 0xeb, 0x03, 0x0c, 0x5c, 0xf7, 0x14, 0xa1, 0xd5, 0x7f, + 0xe6, 0xd2, 0x2b, 0x5f, 0xfe, 0xc0, 0xc7, 0xf6, 0xe9, 0xdc, 0xf8, 0x18, 0xd6, + 0x62, 0xe2, 0xd6, 0x2d, 0xcc, 0xd7, 0xc3, 0x7f, 0xf5, 0xd1, 0x0c, 0xee, 0x57, + 0xde, 0xbd, 0x09, 0xff, 0xcc, 0xb0, 0xc6, 0xfd, 0xad, 0xf8, 0x4a, 0xf8, 0xf4, + 0xe2, 0xd4, 0x73, 0x39, 0x45, 0xf4, 0x17, 0x11, 0xf4, 0x03, 0xfd, 0x3b, 0x02, + 0xf9, 0x15, 0xde, 0x9b, 0xeb, 0xe6, 0xeb, 0xdd, 0xe1, 0x4a, 0x17, 0xd7, 0x0b, + 0x2b, 0xe3, 0x08, 0xfc, 0x04, 0x36, 0xfe, 0x55, 0xa9, 0x16, 0x0f, 0x18, 0xfb, + 0x0a, 0xf6, 0x07, 0x3d, 0xec, 0x1b, 0x19, 0xfa, 0xbe, 0xf3, 0x2d, 0x36, 0x01, + 0x9a, 0x09, 0x33, 0xc2, 0xe8, 0xc6, 0x28, 0xec, 0x32, 0xac, 0xde, 0x1c, 0xbe, + 0x29, 0xcd, 0xde, 0x2d, 0x2a, 0x43, 0xe2, 0x3f, 0xe7, 0xc9, 0xf1, 0xf1, 0xcf, + 0x32, 0x00, 0x0b, 0xea, 0x39, 0x27, 0xeb, 0xd8, 0xef, 0x06, 0x32, 0xd6, 0xcc, + 0x08, 0xe6, 0xe1, 0xe8, 0xc4, 0x11, 0xe7, 0x0c, 0x0d, 0x1d, 0xe0, 0x0b, 0xe0, + 0x1f, 0x12, 0xf3, 0x47, 0xf5, 0xc2, 0x22, 0xd0, 0xea, 0x0f, 0xbd, 0x76, 0xdf, + 0x31, 0x1e, 0x00, 0xca, 0x26, 0x5c, 0xc1, 0x1f, 0x1b, 0x34, 0x08, 0x22, 0x15, + 0x00, 0x41, 0x2b, 0xb8, 0xf6, 0x42, 0xf9, 0x2b, 0xee, 0xcb, 0x03, 0x6f, 0x1d, + 0xc2, 0xd5, 0x0c, 0xe0, 0x28, 0xc1, 0x26, 0xc1, 0x2a, 0x4a, 0xc9, 0x35, 0xfe, + 0x09, 0xe2, 0xdf, 0xff, 0xe6, 0x2a, 0x08, 0xde, 0x42, 0xf1, 0x1b, 0x2b, 0x2a, + 0x19, 0xc0, 0x23, 0x08, 0x10, 0xbd, 0xe1, 0x88, 0x16, 0xee, 0xfa, 0x21, 0xce, + 0x40, 0xd0, 0xc3, 0xf2, 0x46, 0xd5, 0x05, 0x13, 0xed, 0x0b, 0x00, 0x67, 0x76, + 0xa6, 0x67, 0xfc, 0x64, 0x10, 0x23, 0xdf, 0xf7, 0x11, 0x36, 0x11, 0x0c, 0x2e, + 0xf5, 0xd7, 0x3c, 0xf6, 0x49, 0xdd, 0x58, 0x6b, 0x11, 0x7f, 0x29, 0x7c, 0xbf, + 0xe3, 0x3d, 0x27, 0xff, 0xbb, 0x1f, 0x00, 0xbb, 0xff, 0xdd, 0xdf, 0x0b, 0x7f, + 0x0c, 0x0d, 0x44, 0xfe, 0x67, 0x39, 0xec, 0xb7, 0x53, 0x54, 0xee, 0xcc, 0xde, + 0x39, 0xe9, 0x14, 0xfe, 0x69, 0x3c, 0xc0, 0xc0, 0x33, 0x26, 0xf6, 0x17, 0x11, + 0xcc, 0xcd, 0x66, 0xdd, 0xdf, 0x3f, 0x15, 0xf3, 0x02, 0x44, 0x29, 0x1d, 0x2c, + 0xa1, 0xd0, 0xc6, 0x03, 0x00, 0x0e, 0x66, 0x39, 0x13, 0x32, 0x68, 0xe5, 0x30, + 0x01, 0xfd, 0x56, 0xce, 0xfd, 0x08, 0x01, 0x18, 0x1b, 0x20, 0x08, 0x11, 0x4c, + 0xb2, 0x32, 0x01, 0xda, 0x0a, 0x00, 0x07, 0xbd, 0x2c, 0xdf, 0xe6, 0x35, 0xc7, + 0x22, 0xbd, 0xe7, 0x1c, 0xec, 0xc7, 0xe3, 0x56, 0x18, 0xd5, 0xfc, 0xe4, 0xe4, + 0xde, 0x45, 0x1f, 0x42, 0x00, 0x22, 0xf5, 0xf8, 0x9a, 0x64, 0x5c, 0x16, 0xf2, + 0xe2, 0xe4, 0x22, 0xf1, 0x23, 0x0a, 0x00, 0x31, 0x45, 0x21, 0xb8, 0x95, 0x1b, + 0xdb, 0x42, 0xf3, 0x4c, 0xa7, 0xc8, 0x16, 0xe2, 0xf6, 0xfc, 0xfa, 0xe6, 0xf7, + 0xd2, 0xe8, 0x0f, 0xcd, 0xe8, 0xff, 0x02, 0x09, 0xec, 0xe7, 0xf3, 0xe7, 0xc1, + 0xbd, 0xf6, 0xf7, 0xe0, 0xbd, 0x33, 0xf1, 0xfa, 0xc4, 0x16, 0x3e, 0x38, 0x1c, + 0x06, 0x11, 0xef, 0xd5, 0x37, 0xd5, 0x0a, 0x29, 0xd2, 0x06, 0x22, 0x3d, 0x0d, + 0x08, 0x44, 0x1e, 0x10, 0x14, 0x0f, 0xd4, 0x0e, 0x28, 0xec, 0x41, 0x0f, 0xdc, + 0xf0, 0xec, 0x0d, 0x08, 0xe8, 0xb0, 0x62, 0x0e, 0x25, 0x00, 0x1a, 0x00, 0x24, + 0xcc, 0xd7, 0xfb, 0xe6, 0x22, 0xfe, 0xd0, 0x1c, 0xde, 0xf3, 0xf5, 0xf6, 0x14, + 0xda, 0xe3, 0xfb, 0x06, 0xe4, 0x0b, 0x1d, 0x21, 0x21, 0x22, 0x3d, 0xe4, 0x15, + 0xf5, 0x34, 0x29, 0xca, 0x1a, 0xeb, 0x0b, 0xe2, 0x1b, 0xeb, 0x21, 0xd9, 0x0a, + 0x1c, 0xf7, 0x12, 0xfd, 0xe8, 0xcb, 0x15, 0xe1, 0xd3, 0x81, 0x02, 0x56, 0xe8, + 0xd4, 0x06, 0xd3, 0xf1, 0xf7, 0x09, 0xf2, 0xd6, 0xb8, 0x12, 0x43, 0x9b, 0x0d, + 0xf3, 0x04, 0x16, 0xca, 0xaf, 0xf8, 0x44, 0x23, 0x35, 0xf8, 0xe8, 0xea, 0x3d, + 0x00, 0x07, 0xf7, 0xe5, 0xed, 0xd4, 0xf7, 0xf8, 0x13, 0x0f, 0x2f, 0x0e, 0xd8, + 0x14, 0xe7, 0x0d, 0xd6, 0x2f, 0x3d, 0x37, 0xe8, 0xec, 0xe8, 0xb2, 0x0e, 0xf5, + 0x24, 0xe0, 0x07, 0x08, 0xe8, 0x18, 0x01, 0x10, 0x51, 0x23, 0xde, 0xe8, 0xf9, + 0x02, 0x12, 0x69, 0x05, 0x96, 0xdd, 0xda, 0xdf, 0xe2, 0x1e, 0xc4, 0xd3, 0xf1, + 0xe0, 0xd9, 0x7f, 0x23, 0x07, 0xf2, 0x14, 0x16, 0x28, 0x3d, 0x28, 0xff, 0x01, + 0x19, 0xef, 0x32, 0xf2, 0xd8, 0xde, 0x30, 0xd3, 0x08, 0x2f, 0xf2, 0xd6, 0x2f, + 0xdc, 0xfa, 0xef, 0x05, 0x18, 0xcc, 0xf1, 0x09, 0x43, 0x0f, 0x38, 0xfe, 0xe3, + 0xd5, 0xec, 0x07, 0x11, 0x0b, 0x1c, 0xed, 0x07, 0x1d, 0xdf, 0x07, 0x4d, 0xc9, + 0x21, 0xf7, 0xad, 0x4f, 0x05, 0x20, 0x0f, 0x25, 0xe5, 0xee, 0xf4, 0x1b, 0xe4, + 0x27, 0x5a, 0xd0, 0x09, 0xe0, 0xe5, 0xfd, 0xb3, 0xf8, 0x02, 0x47, 0xad, 0xf7, + 0xd2, 0x55, 0x28, 0x26, 0xd5, 0x3a, 0x12, 0xd7, 0xd0, 0x02, 0x00, 0x51, 0x81, + 0xec, 0xe5, 0xc4, 0xe4, 0xf8, 0x2f, 0x3c, 0xc9, 0xf7, 0x2b, 0xf9, 0xed, 0x30, + 0xf1, 0x6b, 0x06, 0x47, 0xee, 0xbc, 0x27, 0xc5, 0x0e, 0x1e, 0xf9, 0x6c, 0x14, + 0xf6, 0xee, 0x00, 0xd1, 0xde, 0x27, 0xf7, 0x17, 0xec, 0xee, 0x17, 0xfc, 0xe8, + 0xdf, 0xd0, 0xf6, 0xe6, 0x17, 0x0d, 0x09, 0xf5, 0xc5, 0xce, 0xe5, 0xd6, 0xc5, + 0xf3, 0x53, 0xff, 0xd4, 0x13, 0xb4, 0x0b, 0xd4, 0xec, 0xd4, 0x5d, 0x11, 0xe6, + 0xd8, 0x1b, 0xe8, 0xda, 0xab, 0xa3, 0xbb, 0x51, 0x1d, 0xf8, 0x1e, 0xd2, 0x13, + 0xca, 0x01, 0xea, 0xcc, 0xfc, 0xe8, 0x0d, 0xed, 0xa6, 0x16, 0x03, 0x2a, 0xf2, + 0xe1, 0x19, 0x15, 0xe9, 0x0a, 0x0d, 0xe7, 0x1e, 0x20, 0x22, 0xf7, 0xd2, 0x5f, + 0x17, 0x41, 0x07, 0x57, 0xdc, 0xf0, 0xe9, 0xfe, 0xbb, 0xef, 0x0e, 0x26, 0x81, + 0x25, 0x94, 0x95, 0xff, 0x0f, 0xe5, 0xfe, 0xe2, 0xef, 0xf6, 0x02, 0xb2, 0x10, + 0xc8, 0x4e, 0x6f, 0xe0, 0xec, 0xf9, 0x5c, 0x47, 0xe7, 0xa6, 0x45, 0xd7, 0xfb, + 0xfb, 0xc9, 0xf7, 0x1a, 0xd3, 0x17, 0x06, 0xfd, 0xcd, 0xf9, 0x02, 0xf6, 0xed, + 0xa7, 0x15, 0xea, 0xf2, 0x2c, 0xf1, 0xf4, 0x0c, 0x20, 0xf7, 0x38, 0xae, 0x09, + 0xf8, 0x0c, 0x30, 0xe7, 0x45, 0x38, 0x09, 0x16, 0xf2, 0x15, 0x24, 0xa3, 0x0c, + 0x13, 0x42, 0x0a, 0xeb, 0xfd, 0xf1, 0x0f, 0xdd, 0xdf, 0xc7, 0xe2, 0xb4, 0x08, + 0x46, 0x6e, 0xd8, 0x0a, 0xeb, 0xf5, 0x1e, 0xf5, 0x38, 0x04, 0x20, 0x19, 0xdd, + 0xf6, 0xd5, 0xfb, 0x8a, 0xc8, 0x1d, 0xd9, 0xa5, 0xdf, 0xf3, 0xf5, 0xcc, 0xc5, + 0x11, 0xba, 0xa1, 0x10, 0x36, 0xe4, 0xf1, 0xe1, 0xd2, 0x1b, 0x28, 0x93, 0xd2, + 0x50, 0x15, 0x6c, 0x10, 0x2e, 0x5a, 0x12, 0xc4, 0xe9, 0x2c, 0xf6, 0xff, 0xc4, + 0x3f, 0x10, 0xc6, 0xd1, 0x07, 0x0a, 0x15, 0xf7, 0x15, 0xf9, 0x07, 0xb6, 0x16, + 0xd8, 0x02, 0xe9, 0x45, 0xd0, 0x30, 0xbf, 0x1f, 0x39, 0x9f, 0xda, 0xf2, 0x14, + 0xe9, 0xe9, 0x1b, 0xf8, 0x60, 0xc7, 0xce, 0xe9, 0xce, 0x3d, 0x14, 0xc0, 0xad, + 0xd2, 0xa3, 0x2c, 0x4d, 0xd6, 0xf6, 0xcc, 0xf8, 0x11, 0x2d, 0x28, 0x26, 0x01, + 0xdd, 0xcd, 0x7f, 0xc9, 0xfe, 0xf0, 0xf6, 0xff, 0x0d, 0x4a, 0xd5, 0x1d, 0x2a, + 0x14, 0xe4, 0xda, 0xa3, 0xdc, 0xe0, 0xf8, 0xe7, 0xd1, 0xee, 0x2d, 0x3a, 0x09, + 0xbe, 0x52, 0x1b, 0xfa, 0x45, 0xfb, 0x2a, 0xae, 0x1f, 0x35, 0x1d, 0xf7, 0x41, + 0x08, 0xe7, 0x1d, 0x08, 0xd9, 0x04, 0xe0, 0xe3, 0x1f, 0xfb, 0xe8, 0x22, 0xfa, + 0x03, 0xc4, 0x28, 0xa5, 0xee, 0x26, 0x4c, 0x21, 0x36, 0xea, 0x2c, 0x28, 0xee, + 0x1a, 0x0a, 0xd4, 0xea, 0xdc, 0x36, 0x1d, 0xfe, 0xe8, 0xf7, 0xcd, 0xf5, 0xbf, + 0x0b, 0xba, 0xe6, 0xcb, 0xd7, 0x13, 0xee, 0xff, 0xe8, 0xef, 0xf3, 0x0e, 0x0d, + 0xfd, 0xf8, 0xd5, 0x1a, 0x2a, 0x05, 0xf6, 0x1f, 0xa4, 0xde, 0x02, 0x36, 0xfb, + 0xbe, 0x04, 0x23, 0xe7, 0x24, 0xca, 0x11, 0x50, 0x11, 0x18, 0x65, 0x11, 0xdb, + 0xdb, 0x5c, 0xf6, 0xe0, 0xd3, 0xd3, 0x07, 0x0d, 0x04, 0x01, 0x31, 0x10, 0x06, + 0xf8, 0xfa, 0xef, 0xbd, 0x29, 0x05, 0xea, 0xe0, 0xef, 0x20, 0x10, 0x51, 0xd4, + 0x43, 0x05, 0x48, 0x2a, 0xfd, 0x81, 0xfa, 0x2f, 0x23, 0xfb, 0x0f, 0xd0, 0x04, + 0xee, 0xbf, 0x0a, 0xf0, 0x16, 0xf5, 0x18, 0xf3, 0xee, 0xc8, 0xdc, 0x20, 0x12, + 0x40, 0xba, 0x1a, 0xf3, 0xfe, 0x3d, 0xe2, 0xdc, 0xdf, 0xec, 0x00, 0xfc, 0x08, + 0x0e, 0x0e, 0xc4, 0x24, 0xc4, 0x03, 0x24, 0x3f, 0x11, 0x60, 0xcd, 0xd0, 0xbf, + 0xfa, 0xda, 0xac, 0xe9, 0x08, 0xed, 0x0d, 0x19, 0xd8, 0x3b, 0xe1, 0xfe, 0x36, + 0x32, 0x16, 0xf3, 0x26, 0xd7, 0x2f, 0x12, 0x08, 0xd9, 0xf8, 0xf6, 0x0a, 0x11, + 0xbe, 0xfd, 0xfd, 0xdd, 0xf8, 0xc9, 0x9b, 0x6e, 0xfa, 0xe8, 0x04, 0x14, 0x36, + 0x0f, 0xcf, 0xf7, 0xf3, 0x42, 0x07, 0x13, 0xcb, 0xf8, 0xdb, 0x1d, 0x16, 0x1b, + 0xc7, 0xf7, 0xbe, 0x2b, 0xef, 0x25, 0x03, 0xf4, 0xcf, 0xd7, 0xf9, 0x06, 0x2c, + 0x22, 0x08, 0x0a, 0x14, 0x16, 0x1c, 0x47, 0xbf, 0xaf, 0x3c, 0x26, 0x3b, 0xe6, + 0xde, 0xfc, 0x12, 0x1f, 0x11, 0x01, 0xc6, 0x1c, 0x35, 0x51, 0x1b, 0x22, 0xfd, + 0xfc, 0x1a, 0xf9, 0xf8, 0x18, 0xc9, 0xfb, 0x81, 0x08, 0xd1, 0xf2, 0xc7, 0x2c, + 0x2b, 0x1f, 0xc7, 0x15, 0x0e, 0x26, 0xf1, 0xfc, 0xf5, 0xe1, 0x0e, 0xf3, 0xfe, + 0x53, 0x01, 0x13, 0x02, 0xdb, 0x26, 0xf1, 0x03, 0xfa, 0x06, 0xf1, 0xd3, 0x03, + 0xde, 0xe6, 0x28, 0xb6, 0x1d, 0xed, 0xfa, 0xf6, 0xfa, 0xcc, 0xea, 0x13, 0xe6, + 0xe5, 0x0c, 0x2e, 0xfb, 0xf3, 0x0e, 0x25, 0x49, 0x08, 0x08, 0x08, 0x2d, 0xc9, + 0xe8, 0x19, 0x0b, 0xe4, 0x27, 0xec, 0xdd, 0x14, 0x15, 0x1c, 0x2a, 0xed, 0xe0, + 0x26, 0x00, 0x45, 0x15, 0x2a, 0x30, 0xeb, 0x31, 0xf0, 0x01, 0x16, 0xcf, 0x1d, + 0xe1, 0x16, 0x0e, 0x1d, 0xfb, 0xf1, 0x3f, 0x07, 0x1f, 0x26, 0x13, 0xf9, 0x81, + 0xfe, 0xef, 0xf5, 0x1b, 0x08, 0x02, 0xd8, 0x42, 0xe7, 0xbd, 0x0f, 0x25, 0x5a, + 0x18, 0x0d, 0x00, 0x03, 0x14, 0xd7, 0x3b, 0x36, 0xe3, 0x42, 0x17, 0xfe, 0x11, + 0xd5, 0x02, 0x11, 0xb5, 0x1e, 0x14, 0x19, 0xf8, 0x07, 0x34, 0xc2, 0xd7, 0xd7, + 0xe3, 0x27, 0x12, 0xcc, 0xd1, 0xef, 0x13, 0xdb, 0xf7, 0x06, 0xf9, 0x17, 0x0c, + 0xeb, 0x5d, 0x3c, 0x1b, 0x0b, 0x3e, 0x28, 0x01, 0x1e, 0x20, 0xcd, 0xf7, 0xcf, + 0xd0, 0x39, 0xd3, 0xd7, 0x00, 0xea, 0xda, 0xe8, 0x2c, 0xf1, 0xf8, 0x81, 0xf8, + 0xc4, 0x1c, 0xeb, 0x2a, 0xbf, 0xd9, 0xc0, 0xed, 0xe1, 0x01, 0x04, 0xab, 0xdd, + 0xf3, 0x1a, 0xe4, 0x3b, 0xdd, 0x05, 0x3c, 0xf5, 0xf9, 0x19, 0x13, 0xae, 0xcc, + 0xcf, 0x45, 0xd4, 0x21, 0x0c, 0xa7, 0xa9, 0x46, 0xe1, 0xcf, 0x60, 0x28, 0xe6, + 0xf7, 0xe9, 0x45, 0xec, 0x10, 0xc5, 0x43, 0xea, 0x10, 0x08, 0x44, 0xd9, 0xe8, + 0xe4, 0xff, 0x34, 0x04, 0xcb, 0xc7, 0x05, 0x1c, 0x1c, 0xd5, 0x0e, 0x0a, 0xf3, + 0x06, 0xd4, 0xe4, 0x50, 0x0e, 0x2c, 0xfe, 0x4b, 0x91, 0x2e, 0xe8, 0x34, 0xf9, + 0x16, 0xe4, 0xf2, 0xfa, 0x4c, 0x00, 0xbf, 0x09, 0x08, 0xe9, 0x04, 0xf5, 0xb0, + 0x45, 0x1b, 0x1a, 0xef, 0x9e, 0x49, 0x38, 0xf2, 0x02, 0xb6, 0x01, 0xb5, 0xe2, + 0xe1, 0x0b, 0xab, 0x33, 0x7f, 0x0a, 0xec, 0x04, 0xf8, 0x01, 0x0e, 0x35, 0x4a, + 0xd5, 0x4f, 0xcb, 0xd9, 0xbe, 0xea, 0xec, 0x0f, 0x14, 0xb3, 0xfb, 0x0b, 0xfc, + 0x32, 0x1c, 0x0b, 0xf1, 0xe9, 0x05, 0x05, 0xcb, 0xe7, 0x15, 0xd5, 0x15, 0x0b, + 0x11, 0xf0, 0xd6, 0xec, 0x02, 0x0f, 0x3f, 0xf0, 0x29, 0x19, 0xd2, 0xcb, 0xb9, + 0x0b, 0x4e, 0x34, 0x2a, 0x18, 0x0c, 0xca, 0xe4, 0x00, 0x23, 0xec, 0xfe, 0x2e, + 0xc1, 0x48, 0x03, 0xfd, 0xe3, 0xef, 0x12, 0x37, 0xff, 0xf5, 0xdd, 0x2a, 0x03, + 0x12, 0xec, 0xed, 0xe4, 0x20, 0x06, 0x33, 0xb5, 0x49, 0x21, 0xf7, 0xf8, 0xe8, + 0x1a, 0x68, 0xe9, 0xd3, 0x5c, 0x27, 0xc4, 0x37, 0xf2, 0xc7, 0xff, 0xd1, 0x21, + 0x2c, 0x04, 0x55, 0xf0, 0x03, 0xc7, 0x24, 0xe3, 0xd3, 0xc3, 0xcf, 0x2f, 0x0c, + 0xe7, 0xc1, 0xc7, 0x0b, 0x81, 0x39, 0x1f, 0xfd, 0x28, 0xf0, 0xe0, 0x15, 0x0c, + 0xf2, 0xfb, 0x03, 0x3d, 0x0b, 0xc7, 0xea, 0xfc, 0xe1, 0xee, 0x3d, 0x14, 0x30, + 0xba, 0xfc, 0x28, 0xfd, 0x30, 0x2c, 0xfb, 0x16, 0xe9, 0x3e, 0xd1, 0xd1, 0x05, + 0xe6, 0xc2, 0xde, 0x09, 0xdb, 0xee, 0xac, 0xe7, 0xec, 0x5f, 0x21, 0xe1, 0x12, + 0x12, 0xf4, 0x24, 0x14, 0x09, 0x13, 0x03, 0xfa, 0xf5, 0xe1, 0xff, 0x2d, 0xc0, + 0x09, 0x5a, 0xcf, 0xd2, 0x04, 0xfc, 0x42, 0xbd, 0xe2, 0x09, 0xf3, 0x02, 0xd6, + 0x2b, 0x17, 0x21, 0xf4, 0xa0, 0xc9, 0xc4, 0xf2, 0x35, 0x01, 0xc8, 0x5b, 0xb5, + 0xe2, 0x47, 0x0b, 0x16, 0xc4, 0xa6, 0xfe, 0xe1, 0x05, 0xfa, 0xce, 0xd0, 0xf3, + 0x33, 0x23, 0x03, 0xc9, 0xea, 0xd2, 0x1a, 0x04, 0x16, 0xd6, 0xbe, 0x41, 0xd8, + 0xe1, 0x18, 0xae, 0xc7, 0xed, 0x03, 0xe7, 0xd7, 0x0b, 0x17, 0x0b, 0xf2, 0x1b, + 0xb8, 0x10, 0x19, 0xd8, 0xb0, 0x30, 0xcb, 0xfa, 0xfc, 0xef, 0xbf, 0xfa, 0x39, + 0x30, 0x27, 0x1e, 0x24, 0xd9, 0x2b, 0xf4, 0xfe, 0x07, 0x14, 0x1c, 0x08, 0xec, + 0xd1, 0xdd, 0x0f, 0xd5, 0x10, 0xf2, 0xec, 0x3b, 0xc0, 0x41, 0x0c, 0x3b, 0xd9, + 0x9e, 0xd4, 0x16, 0xe4, 0x0f, 0x25, 0x31, 0x10, 0xe1, 0xcd, 0xe2, 0xf1, 0xdf, + 0xe2, 0x67, 0xe3, 0xbb, 0x31, 0xea, 0x03, 0x0d, 0x1f, 0xd5, 0xbd, 0xea, 0xf3, + 0xca, 0x13, 0x03, 0x07, 0x0d, 0x09, 0x27, 0xd0, 0x7f, 0xf9, 0x5b, 0x33, 0x00, + 0xf3, 0xff, 0xfc, 0xf7, 0xb8, 0x24, 0x0f, 0xe3, 0xde, 0xfb, 0xf0, 0x0e, 0x02, + 0x10, 0xf1, 0xef, 0x18, 0xde, 0xea, 0xff, 0xd1, 0xe7, 0x0b, 0x4c, 0xaf, 0xf6, + 0xe3, 0x11, 0x36, 0x33, 0x42, 0x03, 0xfa, 0xfe, 0x41, 0x0e, 0x4f, 0x29, 0x1f, + 0xfa, 0x15, 0xd6, 0x2b, 0xd0, 0xf8, 0x03, 0xf0, 0xdb, 0xc6, 0xd7, 0xf8, 0x0f, + 0xf5, 0x39, 0xfc, 0x07, 0x0c, 0xec, 0xf4, 0xf0, 0xfc, 0xb3, 0x05, 0xf9, 0xd8, + 0xe1, 0x29, 0xdb, 0x31, 0x03, 0xf0, 0x00, 0x03, 0xdb, 0x22, 0xe0, 0xfe, 0xed, + 0xfc, 0xe6, 0xe9, 0xfc, 0x0c, 0xdf, 0x1a, 0x2d, 0x2f, 0x07, 0xe3, 0xd4, 0x06, + 0x10, 0xfe, 0xee, 0x2a, 0x21, 0xcc, 0xf6, 0xf5, 0xd4, 0xe0, 0xf1, 0x01, 0x02, + 0xf1, 0x25, 0xeb, 0xd3, 0xf6, 0x32, 0xe8, 0xe8, 0xf4, 0x13, 0x1c, 0xa7, 0xf3, + 0x1b, 0x21, 0xfd, 0xe4, 0x09, 0xdd, 0x04, 0xe9, 0x27, 0xf2, 0xed, 0xee, 0xea, + 0xef, 0x11, 0xda, 0xf7, 0xf3, 0x26, 0x81, 0xf2, 0xe2, 0x0d, 0x0c, 0xde, 0x0e, + 0x10, 0x00, 0xd3, 0xf1, 0xe4, 0xe7, 0x0c, 0x23, 0x00, 0xfa, 0x27, 0xff, 0x33, + 0xfa, 0x17, 0x11, 0x12, 0xf7, 0x37, 0x3a, 0xd6, 0xc2, 0x0f, 0xd5, 0x0d, 0x0f, + 0x06, 0x28, 0xd4, 0xfc, 0x2a, 0x64, 0xc5, 0xf8, 0xf1, 0xc8, 0xe5, 0x2f, 0x18, + 0x05, 0x46, 0xbe, 0x12, 0xc1, 0x2a, 0xbc, 0xf8, 0x26, 0x61, 0x2c, 0xeb, 0x0b, + 0xf3, 0x29, 0x38, 0x4f, 0xfd, 0x17, 0xd8, 0xc2, 0x0f, 0xff, 0xfd, 0xe1, 0x03, + 0xed, 0xf1, 0x20, 0xfa, 0xdf, 0xd7, 0xe6, 0xca, 0x13, 0xcf, 0xd4, 0x09, 0x17, + 0xf6, 0xea, 0xe3, 0x02, 0x21, 0x27, 0x08, 0xca, 0xe7, 0xe9, 0x29, 0x13, 0xe6, + 0x47, 0xdf, 0xfe, 0xf9, 0x16, 0x5c, 0xd6, 0x33, 0xce, 0x0e, 0x3d, 0x2e, 0xd4, + 0x01, 0x11, 0xc9, 0xbe, 0xe6, 0xf2, 0xd1, 0xe0, 0xfd, 0x2e, 0xe0, 0xfc, 0x60, + 0x3e, 0x33, 0x02, 0x52, 0x0f, 0x0c, 0xe9, 0x2b, 0x7f, 0x25, 0xff, 0x0d, 0xf0, + 0xf2, 0xc0, 0xf2, 0xdc, 0xd7, 0xf1, 0xf0, 0xf1, 0xc1, 0xd9, 0x0d, 0x38, 0x1e, + 0x16, 0xf0, 0x0c, 0x02, 0x0a, 0x5a, 0xea, 0xab, 0xfb, 0x1e, 0x0f, 0xec, 0xf3, + 0xba, 0x1d, 0xed, 0xf3, 0xe4, 0xf3, 0xf0, 0x1e, 0xcb, 0x38, 0x00, 0xae, 0xf4, + 0x56, 0x56, 0x37, 0x08, 0xab, 0xfe, 0x1d, 0xef, 0x25, 0x06, 0xdc, 0x14, 0xef, + 0x0b, 0xc9, 0xf8, 0xf2, 0x02, 0xef, 0x0a, 0x35, 0x34, 0xe8, 0x93, 0xe8, 0xf7, + 0xf7, 0x69, 0xf7, 0x05, 0x5b, 0x0b, 0x43, 0xf0, 0xe4, 0x7f, 0x16, 0xeb, 0x15, + 0xdf, 0xa5, 0x09, 0x4d, 0x31, 0xea, 0xf1, 0x13, 0xe0, 0xe7, 0x0f, 0xdc, 0x2c, + 0xa2, 0xfc, 0x0a, 0x57, 0x4b, 0x1e, 0x61, 0x25, 0xd2, 0x39, 0x0a, 0x0e, 0xac, + 0xe5, 0x09, 0xfe, 0x76, 0xe4, 0xc8, 0xd8, 0x4d, 0xa7, 0xfb, 0xf6, 0xdc, 0x04, + 0xfa, 0x19, 0x05, 0x94, 0xc8, 0x28, 0x1f, 0xcc, 0xfb, 0xad, 0x0b, 0x22, 0xf5, + 0xdb, 0x26, 0x13, 0x0d, 0x0a, 0xf4, 0x09, 0xe1, 0x0b, 0x17, 0x11, 0x48, 0x1c, + 0xd1, 0xbb, 0xe3, 0xdc, 0x73, 0xe7, 0xe0, 0xed, 0x35, 0xe0, 0x09, 0x14, 0xdb, + 0x0d, 0xfb, 0xb4, 0xea, 0x09, 0xe1, 0xf1, 0x20, 0x00, 0x2d, 0xd5, 0xf9, 0xd8, + 0xe3, 0xf6, 0xc7, 0xa3, 0x40, 0xcc, 0xdf, 0x0c, 0x13, 0x02, 0xcf, 0xe3, 0x27, + 0x19, 0x00, 0x2c, 0xd3, 0x31, 0x15, 0x00, 0xdf, 0xc6, 0x26, 0xde, 0x79, 0xd6, + 0x0e, 0xff, 0x1e, 0xf3, 0xdc, 0x44, 0xf2, 0x13, 0xf2, 0x16, 0xf8, 0x17, 0xb7, + 0xbe, 0xeb, 0xd6, 0x1d, 0xaf, 0xe2, 0xc5, 0xa2, 0x39, 0x24, 0xf3, 0xf2, 0x5b, + 0xe4, 0x00, 0x9c, 0xd5, 0xe9, 0x1d, 0x04, 0xf6, 0x2a, 0x0d, 0x06, 0xf7, 0x33, + 0xdd, 0x1a, 0x16, 0xfa, 0xae, 0xe2, 0xf4, 0x23, 0x7f, 0x0b, 0x40, 0xe7, 0x1d, + 0x0c, 0xee, 0xf7, 0xe5, 0xd3, 0xfc, 0xe0, 0xff, 0xda, 0xd2, 0x07, 0xf9, 0x0b, + 0x0f, 0xde, 0xce, 0x20, 0x0c, 0x0a, 0x3a, 0xfe, 0x0d, 0x2b, 0x62, 0xda, 0x1a, + 0xda, 0x0b, 0x21, 0xff, 0xe8, 0xfe, 0xeb, 0xf4, 0x19, 0x20, 0x2b, 0x0d, 0x0a, + 0x20, 0xca, 0x0f, 0x3b, 0xfc, 0x0d, 0x1b, 0x7f, 0xe6, 0x1c, 0xdd, 0xb4, 0x00, + 0x18, 0x48, 0xe5, 0x0f, 0x1e, 0xfa, 0x1d, 0xec, 0xfa, 0x1a, 0x03, 0xea, 0x10, + 0xe4, 0xdc, 0xd5, 0xe2, 0xec, 0x1f, 0xea, 0xeb, 0xfa, 0xf0, 0xff, 0xe4, 0xc6, + 0x10, 0x21, 0x06, 0xf5, 0x1f, 0xe2, 0x01, 0x23, 0x11, 0x0a, 0x0e, 0xfe, 0xf4, + 0x0a, 0xee, 0xd8, 0xfb, 0x0b, 0x11, 0xf6, 0xfc, 0xe2, 0xd0, 0xb0, 0xcf, 0x1d, + 0xd8, 0xc2, 0x10, 0xdd, 0xb9, 0xca, 0xef, 0x16, 0x08, 0xe3, 0x27, 0xfa, 0x44, + 0x28, 0x00, 0xe8, 0x20, 0x2b, 0x49, 0xed, 0x20, 0xf5, 0xf1, 0xd8, 0x50, 0xdd, + 0xf8, 0x15, 0xed, 0x07, 0x21, 0xdb, 0xfb, 0xf2, 0xff, 0x00, 0xf5, 0xf3, 0xf2, + 0x0f, 0xe4, 0xd8, 0x03, 0xd8, 0x04, 0xe4, 0x05, 0xc9, 0x2d, 0xd7, 0x04, 0x1e, + 0x22, 0xea, 0x13, 0x0f, 0xef, 0xd2, 0xf0, 0xfd, 0xe1, 0xda, 0xd6, 0x06, 0x22, + 0xf6, 0xe9, 0x2d, 0xd8, 0x01, 0xf2, 0x1f, 0x3c, 0xe6, 0xf0, 0xf0, 0x14, 0xce, + 0x0e, 0xe0, 0x14, 0xf0, 0xf3, 0x2c, 0x01, 0xe7, 0x23, 0xd1, 0x22, 0xde, 0x7f, + 0xcb, 0xed, 0xfc, 0x16, 0xda, 0xca, 0x03, 0x00, 0xf1, 0xd9, 0xe0, 0xf7, 0xca, + 0xd8, 0xf6, 0xf9, 0x01, 0x21, 0x1d, 0xae, 0xdd, 0x03, 0xee, 0xfd, 0x03, 0x09, + 0x03, 0x09, 0xd7, 0xe0, 0x27, 0xdf, 0x10, 0x5a, 0x10, 0x26, 0xe1, 0xf7, 0xf6, + 0x2b, 0x0d, 0xfe, 0x20, 0xd1, 0x01, 0x16, 0x2e, 0xc7, 0x0e, 0xfc, 0x10, 0x29, + 0x18, 0xdf, 0xfc, 0x1a, 0xf4, 0xe1, 0xf4, 0xd6, 0x24, 0xc8, 0xcc, 0x16, 0x3a, + 0xec, 0x14, 0x04, 0x55, 0xfe, 0xf1, 0x1a, 0xf9, 0x10, 0xf8, 0x0d, 0x14, 0xf5, + 0x2b, 0x15, 0x04, 0x17, 0xfc, 0x1d, 0xe3, 0xe9, 0xe0, 0xe6, 0xf8, 0xfe, 0xf6, + 0xc0, 0x20, 0x09, 0x21, 0x1e, 0xe2, 0x0d, 0x2a, 0x21, 0x96, 0xcc, 0xfc, 0xb5, + 0xf3, 0x46, 0xc7, 0xee, 0xe0, 0x4a, 0xf9, 0x2e, 0x1f, 0x2b, 0x07, 0x07, 0xb9, + 0xab, 0xe0, 0x08, 0xf7, 0x1b, 0x08, 0x8f, 0x20, 0x2c, 0x1f, 0xb3, 0xf3, 0x18, + 0xde, 0xe5, 0x0b, 0x19, 0xfe, 0xe5, 0xe7, 0x2f, 0xcb, 0xec, 0xac, 0xe1, 0x18, + 0x21, 0xd4, 0x0b, 0xa1, 0xce, 0xcb, 0xfd, 0x14, 0x2e, 0x29, 0x14, 0x4a, 0xd9, + 0x59, 0x22, 0x05, 0x02, 0xd8, 0x19, 0xf0, 0xbf, 0xf6, 0xcd, 0xf0, 0xe1, 0x15, + 0x26, 0xe7, 0xf6, 0xa2, 0x3b, 0xdc, 0x12, 0x58, 0x21, 0xee, 0xf8, 0xe2, 0xe5, + 0x09, 0xf2, 0x1f, 0x0a, 0xda, 0xd6, 0x32, 0xde, 0x28, 0x23, 0xfb, 0xac, 0x6f, + 0x13, 0xe5, 0xe6, 0xf7, 0x38, 0x27, 0xd7, 0x02, 0xdd, 0x17, 0xaf, 0x2f, 0xa8, + 0xfd, 0xed, 0x29, 0xe9, 0x3c, 0x7f, 0xef, 0xfb, 0x8f, 0xda, 0xe5, 0x01, 0xef, + 0xfd, 0x12, 0xed, 0xc4, 0x13, 0xa5, 0x45, 0xbb, 0xf7, 0x0f, 0xb6, 0xfe, 0xdd, + 0x04, 0xd2, 0x03, 0x19, 0x1b, 0xf6, 0x07, 0x2c, 0x14, 0x0a, 0x3b, 0xf3, 0xca, + 0x79, 0x12, 0x18, 0x56, 0xe9, 0x3a, 0xe2, 0x39, 0xed, 0xff, 0x6f, 0x1b, 0x13, + 0x37, 0x3a, 0x13, 0xd6, 0xb0, 0xf9, 0x31, 0x5d, 0xec, 0x21, 0xf8, 0xcf, 0xbe, + 0xf5, 0x31, 0xe9, 0xf6, 0xc0, 0xf0, 0x25, 0xe9, 0x4c, 0xcf, 0x0b, 0xf3, 0x22, + 0x1c, 0x0b, 0x05, 0x7f, 0xf1, 0x0c, 0x23, 0x22, 0x64, 0xf7, 0xc9, 0x16, 0x14, + 0x1c, 0x1b, 0xf6, 0xe2, 0x0a, 0xe2, 0xeb, 0x3f, 0x21, 0x22, 0x04, 0x21, 0xf2, + 0x71, 0x10, 0xf5, 0xef, 0x0b, 0xd8, 0xf0, 0xd5, 0xe4, 0x1f, 0x38, 0x4f, 0x07, + 0x0a, 0x1e, 0x2a, 0x3c, 0xe6, 0x1d, 0xf2, 0x20, 0x17, 0x09, 0xf2, 0x27, 0x07, + 0xe0, 0x1e, 0x8f, 0x3e, 0x1f, 0x22, 0x03, 0x1a, 0x2d, 0xe9, 0xf4, 0xe6, 0xe3, + 0xe6, 0xf3, 0xf9, 0xc3, 0x00, 0xfa, 0x26, 0xd6, 0xff, 0x03, 0x2a, 0xca, 0xd5, + 0x7f, 0xe1, 0x01, 0x1c, 0x10, 0xa3, 0xdf, 0x1e, 0x3f, 0x24, 0xfe, 0x0c, 0x38, + 0x21, 0x71, 0x0b, 0xb0, 0x08, 0xc6, 0xb5, 0xeb, 0x43, 0xc0, 0xe8, 0x1c, 0x15, + 0x0c, 0xda, 0x2d, 0x0a, 0xf3, 0xf3, 0x51, 0xb8, 0xea, 0xf7, 0xf8, 0x3a, 0x6f, + 0xe8, 0x01, 0xdc, 0xf2, 0xea, 0xc3, 0x1c, 0xbc, 0xee, 0xf7, 0xf3, 0x34, 0x4c, + 0x21, 0x3a, 0x01, 0xd3, 0x05, 0xd2, 0xd1, 0xfe, 0xf6, 0xe7, 0x24, 0xd1, 0x07, + 0x44, 0x37, 0xf7, 0x0c, 0xf5, 0xa8, 0x2c, 0x22, 0x19, 0xf4, 0xcc, 0xdb, 0x4b, + 0x02, 0x24, 0xee, 0xa9, 0xbc, 0xad, 0xf4, 0x6e, 0xfe, 0xe8, 0xd7, 0xd3, 0xf3, + 0xc2, 0x30, 0xe3, 0x1c, 0x15, 0xe5, 0x08, 0xdb, 0xf5, 0xd8, 0x4e, 0x0d, 0xe2, + 0xb8, 0x0d, 0xc5, 0xe6, 0x19, 0x08, 0xd0, 0x28, 0x27, 0x34, 0x31, 0xe5, 0x26, + 0xfe, 0x1d, 0x3f, 0xdb, 0xb0, 0x19, 0xe0, 0xfe, 0x22, 0xd7, 0xdf, 0x2b, 0x0a, + 0x07, 0x09, 0x32, 0xe6, 0xe6, 0xee, 0x1d, 0xea, 0xda, 0x4e, 0x7f, 0x59, 0x2a, + 0xd8, 0xee, 0x06, 0x0e, 0xed, 0x1c, 0x30, 0xfe, 0x2c, 0x25, 0xf7, 0xc5, 0xfb, + 0x48, 0xe5, 0xd0, 0xe4, 0xd0, 0xe1, 0x27, 0xfc, 0x12, 0x14, 0xd2, 0x0d, 0xb9, + 0x00, 0xc0, 0xfb, 0x1b, 0xd5, 0x06, 0xfb, 0x16, 0xd3, 0xe4, 0x28, 0x1a, 0x2e, + 0xd4, 0x19, 0x0e, 0xf2, 0x10, 0xe2, 0xfa, 0x08, 0x23, 0xf4, 0xfd, 0x14, 0xd3, + 0xe1, 0xbe, 0x1d, 0x16, 0x39, 0x16, 0x1c, 0x09, 0xfb, 0xe4, 0xe9, 0xe3, 0xf3, + 0x1a, 0x16, 0x05, 0xe6, 0xd8, 0xcb, 0x2e, 0xd2, 0x0c, 0xf7, 0x44, 0xc5, 0xe7, + 0xe7, 0x28, 0xe4, 0x27, 0xe7, 0x23, 0xe5, 0xf9, 0xfe, 0x25, 0x1a, 0x13, 0xc8, + 0xe2, 0x3b, 0xf3, 0x37, 0xe7, 0xf6, 0xdf, 0x4c, 0x26, 0x36, 0xf0, 0x17, 0x25, + 0x27, 0x08, 0x50, 0xfc, 0x02, 0xdc, 0x12, 0x16, 0xf9, 0x24, 0x81, 0x00, 0x26, + 0x14, 0xd1, 0xef, 0x06, 0xe1, 0xeb, 0x09, 0x0a, 0xd5, 0x2b, 0x1e, 0xd5, 0x0c, + 0xdf, 0xfe, 0x0d, 0x0d, 0x30, 0xdc, 0xfd, 0xd8, 0xde, 0x2f, 0x1e, 0x12, 0x22, + 0xee, 0xf2, 0xef, 0x47, 0xd4, 0xd8, 0x35, 0x70, 0xf9, 0x1e, 0x44, 0x10, 0xe8, + 0x42, 0xfc, 0xeb, 0xee, 0xb5, 0x29, 0xf7, 0xfb, 0xe4, 0x28, 0x0b, 0x2e, 0x27, + 0xda, 0x23, 0x29, 0xed, 0x2a, 0x19, 0xd7, 0x37, 0xeb, 0xf9, 0x09, 0xfc, 0x58, + 0xef, 0xd1, 0xfa, 0xe9, 0xe2, 0xf9, 0x01, 0x14, 0xfe, 0x1c, 0x1d, 0x21, 0x35, + 0x28, 0x9d, 0x4b, 0xff, 0x43, 0xfe, 0xe9, 0xdf, 0x2e, 0x29, 0x54, 0x1a, 0xd7, + 0xbe, 0x2f, 0xbb, 0xbb, 0xeb, 0x31, 0x1c, 0x3e, 0xf5, 0xee, 0x16, 0x0e, 0xef, + 0xe1, 0xac, 0xc7, 0x0a, 0xfc, 0x1e, 0x37, 0xf5, 0xca, 0x02, 0x54, 0x2e, 0xed, + 0xd1, 0xfb, 0xcc, 0x4f, 0x0e, 0xee, 0xa3, 0xe8, 0xdf, 0x01, 0x14, 0xf0, 0x00, + 0x2c, 0xfe, 0x0a, 0x8c, 0x38, 0x2a, 0xa7, 0xfc, 0xf3, 0xdc, 0xe4, 0x4e, 0xc7, + 0x31, 0x3a, 0xe4, 0xdd, 0x0c, 0xd4, 0xdd, 0x59, 0xea, 0x06, 0x06, 0x49, 0xe7, + 0x20, 0xf3, 0x15, 0xe1, 0xe9, 0xb6, 0xf8, 0xf1, 0x35, 0xda, 0xea, 0x12, 0x7f, + 0x20, 0xec, 0x91, 0x2c, 0xda, 0xf1, 0xfb, 0x52, 0xf2, 0x16, 0xe4, 0x30, 0x3e, + 0x0f, 0x0b, 0x40, 0xfc, 0x10, 0xf1, 0x13, 0xd1, 0x39, 0xf0, 0x11, 0x22, 0x3a, + 0xf9, 0x3c, 0xd7, 0xd9, 0x24, 0x00, 0x19, 0x0a, 0xdf, 0x3a, 0x0b, 0xb4, 0x2d, + 0x07, 0xbc, 0xe0, 0x12, 0xee, 0xe5, 0x17, 0x32, 0xf6, 0x16, 0x35, 0x23, 0xcf, + 0x6d, 0x1f, 0x0b, 0xd5, 0x00, 0x35, 0x05, 0x38, 0xc7, 0x38, 0x0a, 0x1c, 0x03, + 0x18, 0x11, 0x00, 0xef, 0x36, 0xd6, 0x9b, 0xd5, 0x08, 0x06, 0xf2, 0xdb, 0xf8, + 0xf1, 0x81, 0x56, 0xf0, 0xec, 0xe0, 0xf1, 0xe9, 0xcf, 0xf3, 0x6f, 0xff, 0x0f, + 0x0a, 0x01, 0x4a, 0xe4, 0x22, 0xee, 0xf3, 0xe1, 0x2e, 0x05, 0xeb, 0xd6, 0xf9, + 0xcb, 0xe3, 0x2e, 0xc4, 0xc9, 0xfe, 0x03, 0x13, 0xd7, 0x1d, 0xd4, 0x34, 0x1e, + 0x13, 0xc9, 0xf4, 0x07, 0xd5, 0x56, 0x2f, 0x28, 0x07, 0xf1, 0x16, 0x11, 0xcf, + 0x20, 0xeb, 0x13, 0x27, 0xe7, 0x04, 0xe3, 0xdf, 0x25, 0xf1, 0xf6, 0xd6, 0xd4, + 0xb2, 0x50, 0x11, 0xdb, 0x04, 0xf4, 0x0e, 0x3f, 0x6f, 0x56, 0x03, 0x3e, 0x0c, + 0x11, 0x3f, 0x12, 0x24, 0x39, 0xec, 0x0d, 0x16, 0x0f, 0x4a, 0x34, 0x36, 0xe0, + 0xd5, 0x02, 0xe2, 0x23, 0x47, 0x0a, 0x43, 0x0c, 0xd3, 0x0d, 0xcb, 0x24, 0x1f, + 0xe5, 0xfd, 0x15, 0x2f, 0x02, 0xf7, 0xcc, 0xfc, 0xe1, 0x0e, 0x26, 0x2c, 0xf7, + 0xd4, 0x0b, 0x10, 0x14, 0x36, 0x3b, 0x30, 0x04, 0x4b, 0x2a, 0xe7, 0xc7, 0xda, + 0xd4, 0x38, 0xc8, 0xe2, 0xae, 0xde, 0x0f, 0x53, 0xbb, 0xe3, 0xd7, 0xd7, 0xf1, + 0x15, 0x1f, 0x21, 0x4e, 0xdc, 0x04, 0xe2, 0x81, 0x06, 0x2c, 0xd1, 0xd1, 0x1b, + 0xff, 0x3a, 0xc1, 0xd9, 0x03, 0xbf, 0xfd, 0xdb, 0x4a, 0x10, 0x5d, 0xd4, 0xf5, + 0xf1, 0xbc, 0x13, 0x14, 0x6e, 0xdd, 0x19, 0xc0, 0xf2, 0xde, 0xfd, 0xf3, 0x0c, + 0x20, 0xe1, 0xc5, 0xe4, 0x3a, 0x22, 0x1c, 0x09, 0xd4, 0x0b, 0xdb, 0xcf, 0xd4, + 0xfc, 0xda, 0x19, 0xc4, 0xa7, 0x14, 0xd0, 0xbd, 0xd6, 0xe4, 0x03, 0xd4, 0x19, + 0xf3, 0x21, 0xe1, 0x29, 0xcd, 0xfc, 0xf9, 0xf4, 0xe3, 0xe9, 0x35, 0x03, 0xe1, + 0xb1, 0x1a, 0xf1, 0xf6, 0xe3, 0x13, 0xbc, 0x19, 0xde, 0xe2, 0xfa, 0xa5, 0x0e, + 0xef, 0x2a, 0x1c, 0x18, 0xe4, 0xdf, 0xeb, 0xe8, 0x12, 0x02, 0xea, 0xbf, 0xfb, + 0x32, 0xf4, 0x12, 0x11, 0x2c, 0x17, 0x1c, 0xf0, 0xf5, 0xeb, 0xe1, 0x31, 0x25, + 0xf2, 0x05, 0x12, 0x46, 0xdf, 0xbc, 0x00, 0xf5, 0xee, 0x10, 0xe9, 0x09, 0xf9, + 0x15, 0xeb, 0x00, 0x1a, 0x23, 0x07, 0xef, 0x0b, 0x0b, 0x08, 0xfc, 0xfa, 0xc7, + 0x0f, 0xf7, 0x0b, 0x28, 0x25, 0x15, 0x02, 0x2b, 0xe3, 0xf8, 0x1a, 0x33, 0x1e, + 0x27, 0x26, 0x34, 0xdc, 0x24, 0xe7, 0xc1, 0x37, 0x21, 0xe9, 0x11, 0x18, 0x20, + 0xd6, 0x0e, 0xde, 0xd8, 0x0e, 0xf3, 0xfe, 0x24, 0xd0, 0xf5, 0x4c, 0xcd, 0xd4, + 0xfc, 0x1d, 0x15, 0xee, 0xf5, 0x1e, 0x23, 0xe0, 0x41, 0xb8, 0xd8, 0xd9, 0x1c, + 0x14, 0x01, 0xcc, 0x35, 0xca, 0x18, 0xf1, 0x31, 0xf8, 0xf1, 0x13, 0x04, 0xec, + 0x18, 0x0b, 0x1e, 0x59, 0x01, 0xff, 0xd3, 0xcf, 0x29, 0x41, 0xd7, 0xf2, 0x2b, + 0x3a, 0x0c, 0x18, 0xff, 0x27, 0x53, 0x24, 0x14, 0x24, 0xe5, 0x10, 0x7f, 0x03, + 0x4b, 0x0b, 0xc4, 0x07, 0x4f, 0xe7, 0x29, 0x46, 0x3d, 0x5d, 0x0b, 0x06, 0x0c, + 0xb1, 0xa9, 0x23, 0xf0, 0x1d, 0x85, 0x09, 0x18, 0xcd, 0x1b, 0xc8, 0xc3, 0xc5, + 0x51, 0x30, 0x9c, 0xda, 0x48, 0xed, 0xe3, 0x20, 0x12, 0xfa, 0x0d, 0x15, 0xbc, + 0x02, 0xe0, 0xc7, 0xea, 0x28, 0x2a, 0x7f, 0xab, 0xed, 0xaa, 0x50, 0x52, 0x4e, + 0xa8, 0x3d, 0x3d, 0x03, 0xe5, 0xf0, 0x02, 0x01, 0xd9, 0xa9, 0x42, 0x13, 0xf1, + 0xc8, 0x4e, 0xfd, 0x43, 0x0f, 0x20, 0xa7, 0xa7, 0xbd, 0x3c, 0xd1, 0xe7, 0x1b, + 0xb8, 0x01, 0xda, 0xc8, 0xca, 0xce, 0x5f, 0x4a, 0xf9, 0xdc, 0x16, 0xc7, 0x4e, + 0xda, 0xd8, 0x32, 0xd7, 0xd1, 0xd7, 0x06, 0xb6, 0x04, 0x07, 0xdf, 0xe9, 0x00, + 0x21, 0xae, 0xcd, 0x1f, 0x54, 0x3a, 0xfb, 0xc0, 0x01, 0xd5, 0xc2, 0x06, 0x1a, + 0x0d, 0x67, 0xbc, 0xf6, 0x09, 0x17, 0x34, 0xd1, 0x09, 0xdf, 0x27, 0xb2, 0x87, + 0x29, 0x1c, 0xd3, 0xe1, 0xbc, 0xc4, 0xa5, 0x48, 0x24, 0xf5, 0xfd, 0xd5, 0x56, + 0xfa, 0x03, 0xbf, 0x46, 0x3b, 0x13, 0xc7, 0x0d, 0xbc, 0xfd, 0xdf, 0x00, 0x36, + 0x6e, 0x86, 0x77, 0xe7, 0xf8, 0xb8, 0xbe, 0x00, 0x44, 0x00, 0x15, 0xdb, 0xda, + 0x19, 0xcd, 0x07, 0xae, 0xb3, 0xc6, 0x1a, 0x3a, 0x36, 0x97, 0xcf, 0xde, 0x6c, + 0xd7, 0xc8, 0x20, 0xe3, 0x08, 0xef, 0xd6, 0x1a, 0x25, 0x34, 0xd2, 0x41, 0x29, + 0x23, 0xf1, 0xea, 0xd3, 0xcf, 0xfa, 0x54, 0xd1, 0x26, 0xc6, 0x33, 0x45, 0xdb, + 0x18, 0x38, 0x52, 0x4f, 0xcf, 0xdc, 0xe9, 0xc5, 0x3b, 0x0f, 0x17, 0x0f, 0xe5, + 0xf1, 0x41, 0x43, 0xf3, 0x25, 0x3a, 0xf4, 0x28, 0x1a, 0xfe, 0x12, 0xad, 0x25, + 0x42, 0xe4, 0x2a, 0x22, 0x1c, 0x7f, 0x39, 0x83, 0x11, 0x23, 0x0e, 0xab, 0x08, + 0x16, 0x2a, 0xe5, 0xf4, 0xf3, 0x01, 0xbc, 0x45, 0x50, 0xb0, 0xd7, 0xb3, 0xdb, + 0x12, 0xd6, 0xf6, 0xe3, 0xec, 0xd1, 0x08, 0xdd, 0xce, 0xe8, 0x11, 0x09, 0xe3, + 0x7f, 0xf9, 0x0d, 0xff, 0xc8, 0xc4, 0xf8, 0xf1, 0x08, 0xd9, 0xc8, 0x53, 0x1f, + 0xc2, 0x31, 0x6c, 0x35, 0xf2, 0xe9, 0x08, 0x4a, 0x1d, 0x8f, 0x26, 0x43, 0xc1, + 0xe0, 0x13, 0x36, 0xe5, 0x03, 0x01, 0xe4, 0x0b, 0xc9, 0xfd, 0xe5, 0xf2, 0xd5, + 0xfa, 0x2a, 0x03, 0x29, 0xe1, 0xb9, 0x48, 0xbd, 0xf2, 0xc9, 0x48, 0x0f, 0x30, + 0xf6, 0xef, 0x41, 0xf9, 0xd6, 0xe1, 0xfe, 0x43, 0x06, 0x03, 0xbc, 0x04, 0x1a, + 0x85, 0xe2, 0x2b, 0xbf, 0x9f, 0x1c, 0x24, 0xf8, 0xf8, 0x0f, 0x30, 0x1a, 0xe4, + 0x26, 0xb6, 0xaf, 0x32, 0x16, 0x0d, 0xc6, 0xce, 0xf3, 0x05, 0x59, 0xd6, 0xdd, + 0xc1, 0x08, 0xf3, 0x40, 0x63, 0xd9, 0x2b, 0x2d, 0x15, 0xe2, 0x50, 0xc6, 0xf4, + 0x3c, 0xfa, 0xd8, 0xe6, 0xf8, 0x1a, 0x48, 0x52, 0x02, 0xee, 0x29, 0x20, 0x21, + 0x26, 0xfb, 0xe1, 0xf1, 0x0a, 0x29, 0x14, 0xfa, 0xa0, 0xed, 0x4c, 0xde, 0xe2, + 0xf0, 0x65, 0xeb, 0xc7, 0xca, 0x0d, 0x05, 0xa9, 0x11, 0xf1, 0x02, 0x11, 0xe0, + 0x01, 0x43, 0x16, 0xf4, 0x45, 0x08, 0x69, 0x01, 0xfa, 0xdb, 0x2a, 0xb2, 0x07, + 0x15, 0x42, 0xd2, 0xe9, 0xb5, 0x53, 0x1b, 0xf1, 0xda, 0x18, 0x0d, 0xea, 0xf2, + 0x42, 0xec, 0x0b, 0x5f, 0xf0, 0xce, 0x0d, 0xb4, 0x55, 0x0c, 0xf7, 0xc2, 0x43, + 0xe9, 0x52, 0xb2, 0xdc, 0xe3, 0x04, 0x81, 0xf4, 0x24, 0xe4, 0x11, 0x1a, 0xff, + 0x08, 0xe6, 0x10, 0xf4, 0x75, 0xd0, 0x56, 0x2c, 0xf4, 0xe9, 0xfb, 0xfc, 0x1a, + 0xcc, 0xd7, 0x11, 0x5e, 0x06, 0x13, 0x5c, 0x29, 0x04, 0xea, 0x0e, 0x0a, 0x02, + 0xef, 0x21, 0x02, 0x0c, 0xe4, 0x07, 0x81, 0xd1, 0xe0, 0x1a, 0x44, 0xd3, 0xd6, + 0x24, 0x30, 0xd1, 0xe2, 0xff, 0xa7, 0x30, 0xb7, 0x28, 0xd2, 0x2a, 0xc3, 0x24, + 0x11, 0x03, 0x2f, 0xe9, 0x4b, 0xe5, 0xee, 0x32, 0xb8, 0xb0, 0xe4, 0xa0, 0xfd, + 0x34, 0xaa, 0x3c, 0xd2, 0x32, 0x01, 0x08, 0xd2, 0xd1, 0xf7, 0xd1, 0xed, 0x36, + 0x00, 0x1b, 0xf5, 0xd7, 0xb1, 0x47, 0x1b, 0x0a, 0x0b, 0x39, 0x3c, 0x31, 0x25, + 0x03, 0xe7, 0x0b, 0xec, 0xf3, 0x8b, 0xed, 0xcc, 0x62, 0xcd, 0x05, 0xf9, 0xd7, + 0xa8, 0x17, 0xc1, 0xd8, 0xa4, 0x37, 0x5f, 0x34, 0xe7, 0xc5, 0xed, 0x4d, 0xce, + 0xf8, 0xd6, 0x1a, 0xff, 0xab, 0xd3, 0x0c, 0x3d, 0xda, 0xe6, 0x23, 0xcc, 0x1b, + 0x36, 0xc2, 0xf3, 0xf4, 0xf2, 0x5c, 0x26, 0xeb, 0xc8, 0x28, 0xdf, 0x5b, 0xc7, + 0x59, 0x1c, 0x7f, 0xfd, 0x07, 0x8a, 0x09, 0xd2, 0xf3, 0x2b, 0xe3, 0x47, 0xe2, + 0x61, 0xd5, 0x33, 0x37, 0xd9, 0xf4, 0x5d, 0xda, 0xf7, 0x10, 0xfd, 0xde, 0xef, + 0xb6, 0xcc, 0xfb, 0xec, 0x1a, 0x11, 0xf1, 0xc3, 0xe9, 0xcf, 0xca, 0xc7, 0xee, + 0xf1, 0xd1, 0xf2, 0x0b, 0xca, 0xdc, 0xdb, 0x0a, 0xc7, 0x28, 0xe5, 0x03, 0xfc, + 0x0b, 0x07, 0x74, 0xf1, 0xbe, 0x1a, 0xe5, 0x22, 0xd7, 0xf2, 0x1a, 0x00, 0x12, + 0x16, 0x1b, 0x27, 0xcd, 0xdd, 0xe4, 0xc6, 0x0c, 0x26, 0x2e, 0x02, 0x05, 0x12, + 0x49, 0x04, 0xe6, 0x31, 0x34, 0xce, 0x51, 0xfe, 0xec, 0xfe, 0xda, 0x1f, 0x10, + 0xf6, 0xf6, 0x42, 0x00, 0xe7, 0x10, 0x16, 0x07, 0x7f, 0xb4, 0x05, 0xd1, 0x33, + 0xfc, 0x09, 0xe4, 0x16, 0x1b, 0x0a, 0xbb, 0xa4, 0x3d, 0x36, 0x26, 0xde, 0x29, + 0x09, 0xce, 0xe5, 0xfb, 0xed, 0xfe, 0xe4, 0xbb, 0x0c, 0x15, 0xe4, 0x06, 0x40, + 0xcb, 0xf5, 0x33, 0x10, 0xee, 0x24, 0x1f, 0x62, 0xef, 0xcb, 0x08, 0xfa, 0x1d, + 0xf4, 0x37, 0xc2, 0x4d, 0xe4, 0xea, 0x2a, 0x05, 0xf2, 0x11, 0xda, 0x23, 0x2d, + 0xf8, 0xea, 0x16, 0xf0, 0x2d, 0x99, 0xb7, 0xe7, 0x22, 0x04, 0xb8, 0xe7, 0x46, + 0x29, 0x7f, 0x28, 0x37, 0xff, 0x0b, 0xab, 0xe3, 0xe8, 0xf9, 0x10, 0x20, 0x11, + 0xe2, 0xef, 0x45, 0xf8, 0x5c, 0x08, 0x51, 0x0d, 0xb2, 0xf3, 0x12, 0xd7, 0xfe, + 0xca, 0xe1, 0x1d, 0x04, 0xcc, 0x37, 0x52, 0xe7, 0xe4, 0xa8, 0xaf, 0xdd, 0xd1, + 0xd9, 0x06, 0xff, 0xd2, 0x04, 0x16, 0xe9, 0xac, 0x0f, 0x1c, 0x05, 0xec, 0xef, + 0x45, 0x00, 0xfe, 0xbf, 0x1a, 0xc6, 0xca, 0xc9, 0xe7, 0x10, 0x26, 0x0f, 0x31, + 0xda, 0xe9, 0xdd, 0xf2, 0x2f, 0x09, 0xe7, 0xf7, 0x1d, 0xd0, 0xcb, 0xc8, 0xd9, + 0xd6, 0xb7, 0xef, 0xcc, 0x1d, 0x86, 0xb0, 0xa8, 0x1f, 0xcc, 0xc6, 0xdf, 0xf4, + 0x1f, 0xd2, 0xfc, 0xfc, 0x0f, 0xe1, 0x29, 0xf9, 0xa8, 0x14, 0x0b, 0x28, 0x49, + 0x08, 0xfa, 0xef, 0x19, 0xe8, 0xe8, 0x37, 0xc2, 0x09, 0xed, 0xe2, 0x0b, 0x0f, + 0x18, 0x40, 0xff, 0xd2, 0x6c, 0x3a, 0xd8, 0x8a, 0x5d, 0xf5, 0x5f, 0xc4, 0xb7, + 0xf4, 0x1c, 0xf5, 0xde, 0x23, 0x21, 0x0c, 0xb7, 0x27, 0xcc, 0x81, 0xe1, 0xd0, + 0x19, 0x6b, 0xc8, 0x47, 0xa8, 0xea, 0xea, 0xdb, 0xc5, 0xb0, 0xf3, 0x4e, 0xe8, + 0x27, 0x3b, 0x3b, 0x3a, 0xe7, 0x98, 0x09, 0x31, 0x14, 0x36, 0x1c, 0x35, 0x2f, + 0xfe, 0x1f, 0xf1, 0xf1, 0x4f, 0xa6, 0x25, 0x29, 0x34, 0xfa, 0xb3, 0x0d, 0x26, + 0x41, 0xf4, 0xd2, 0xe3, 0xc1, 0xd8, 0x3f, 0xdc, 0x12, 0x13, 0xbb, 0x98, 0x55, + 0x41, 0x64, 0xe0, 0xc2, 0xfe, 0x03, 0xf2, 0x5a, 0x27, 0x3b, 0x3d, 0x11, 0xfd, + 0x34, 0x40, 0x1b, 0x13, 0xe1, 0x23, 0xc5, 0x2e, 0x02, 0xe0, 0x16, 0x21, 0x27, + 0x65, 0x0a, 0x11, 0xb7, 0x26, 0x18, 0xf3, 0x45, 0xb6, 0x07, 0xed, 0x19, 0xc8, + 0xe6, 0x1d, 0xc1, 0xfd, 0x35, 0x24, 0xfd, 0xb6, 0x73, 0x08, 0xfb, 0x15, 0x1a, + 0xec, 0xf3, 0x1c, 0x00, 0xef, 0xf9, 0x0c, 0x0c, 0xd6, 0xf4, 0xc9, 0x24, 0xeb, + 0xf3, 0xea, 0x0e, 0xeb, 0xdd, 0x14, 0x03, 0x08, 0xe5, 0x10, 0x00, 0xca, 0xf3, + 0xcb, 0xfc, 0xeb, 0x13, 0xf1, 0xf5, 0x02, 0x3b, 0xec, 0xf2, 0x28, 0xb2, 0x0d, + 0xf6, 0x38, 0x39, 0x2f, 0xef, 0xd6, 0xf1, 0xda, 0x12, 0x1b, 0x1b, 0xe6, 0x16, + 0xcd, 0x14, 0x21, 0x26, 0xf0, 0x2b, 0xec, 0xe1, 0xdf, 0xef, 0xc7, 0x23, 0x22, + 0xd1, 0xaa, 0x1c, 0xfd, 0xeb, 0xff, 0x22, 0xf4, 0x21, 0xf4, 0x11, 0xea, 0x1c, + 0x41, 0x0a, 0x0e, 0xc7, 0x05, 0xcb, 0xe2, 0x09, 0xb3, 0xe3, 0xff, 0x01, 0x32, + 0x10, 0xfc, 0xde, 0x1d, 0xda, 0x1d, 0x00, 0x08, 0x1d, 0xd9, 0xeb, 0x19, 0x09, + 0x0d, 0x81, 0xf8, 0x07, 0xd8, 0xfc, 0xcf, 0x12, 0xc6, 0x34, 0x1e, 0xeb, 0x0b, + 0xfe, 0x02, 0xfb, 0xfb, 0xeb, 0xe7, 0x23, 0xcf, 0x08, 0x25, 0xe3, 0x2e, 0xd4, + 0xbd, 0x06, 0xe0, 0xb7, 0x1c, 0xf7, 0xcb, 0xe7, 0xde, 0xf3, 0xf1, 0xfb, 0xf2, + 0x32, 0xe9, 0x00, 0xf4, 0xd8, 0x20, 0xe2, 0x2f, 0x35, 0xe1, 0x1d, 0xd2, 0x06, + 0xdc, 0xf4, 0x11, 0x35, 0x04, 0xe0, 0xf6, 0x07, 0x14, 0xcc, 0xf7, 0xdc, 0x08, + 0x1c, 0xc1, 0xf8, 0x0c, 0x1f, 0x9a, 0x07, 0x1d, 0xf1, 0xb5, 0xc9, 0x04, 0x2f, + 0x24, 0xdc, 0xe8, 0x0c, 0x2c, 0x11, 0x01, 0x19, 0xf7, 0xcf, 0xe5, 0xeb, 0x09, + 0x72, 0x23, 0x9f, 0x28, 0xf4, 0xf8, 0x08, 0xf2, 0xeb, 0xfb, 0x09, 0x3b, 0x1e, + 0x3f, 0xc6, 0xdc, 0x21, 0x81, 0x24, 0xec, 0xe6, 0x0b, 0xea, 0x01, 0xfb, 0xd0, + 0xca, 0x06, 0x12, 0x37, 0xed, 0x52, 0x18, 0xff, 0xf7, 0xf4, 0x1e, 0x03, 0x14, + 0x16, 0x43, 0xf9, 0x3d, 0xe6, 0xe9, 0x1e, 0xe9, 0xec, 0xfe, 0xfa, 0x21, 0x64, + 0xf0, 0x0f, 0x01, 0x0c, 0x0d, 0x38, 0x15, 0x23, 0x3e, 0xf3, 0x0e, 0xdc, 0xf5, + 0xe9, 0xe7, 0x47, 0x00, 0xe3, 0xdd, 0xd6, 0xce, 0x15, 0xf2, 0x6f, 0x41, 0xeb, + 0x15, 0xe6, 0x0f, 0x3c, 0xf1, 0x47, 0x2f, 0x00, 0x0d, 0xe3, 0xb2, 0xb0, 0xd9, + 0x13, 0xc1, 0xc9, 0xe5, 0x08, 0x16, 0xd4, 0x0c, 0xd7, 0x65, 0x0e, 0x42, 0xbc, + 0xf1, 0xfb, 0x43, 0xf4, 0x26, 0xfd, 0xfb, 0x2b, 0xf6, 0xf7, 0x25, 0x81, 0x02, + 0x03, 0x52, 0x29, 0x0d, 0xea, 0xf4, 0xbd, 0x0d, 0x3d, 0x1e, 0x0e, 0x66, 0xd5, + 0xd1, 0xda, 0xc9, 0xf1, 0xfb, 0xce, 0x1e, 0xee, 0xd1, 0xe2, 0x1d, 0xf9, 0x23, + 0xec, 0x38, 0xf4, 0x7b, 0x45, 0x16, 0x4f, 0x56, 0x06, 0x16, 0x42, 0xeb, 0x24, + 0x04, 0xed, 0x10, 0xc8, 0x5a, 0x03, 0x07, 0x19, 0xbb, 0xe6, 0xf1, 0xd2, 0xcd, + 0x1b, 0x45, 0xd2, 0x0b, 0xcf, 0xf4, 0x0b, 0x05, 0xe2, 0x0f, 0x07, 0xfb, 0xb8, + 0xfe, 0x3c, 0xc0, 0xf0, 0xf2, 0xf7, 0xb5, 0xfb, 0xd4, 0xe7, 0x3a, 0xe4, 0xf6, + 0x03, 0x09, 0xc8, 0x22, 0xc6, 0xdb, 0xc8, 0x33, 0xf3, 0xf9, 0xf5, 0x0f, 0xc5, + 0x48, 0x25, 0x23, 0x27, 0x0b, 0x0a, 0x0e, 0x50, 0xee, 0x92, 0xf8, 0x08, 0xef, + 0x11, 0xd8, 0x00, 0xf4, 0x01, 0x08, 0x05, 0x3c, 0x16, 0x37, 0xf5, 0xcd, 0x28, + 0xb9, 0x01, 0xdc, 0xf9, 0x32, 0x00, 0x11, 0x03, 0x2e, 0xc9, 0xf9, 0xb8, 0x2a, + 0x23, 0xc9, 0x07, 0x24, 0xd0, 0x1a, 0xed, 0xf7, 0x0b, 0x6e, 0xe2, 0x1d, 0xca, + 0xf2, 0xb9, 0x16, 0xb6, 0xf2, 0x20, 0xda, 0x1a, 0xd9, 0xd4, 0xf6, 0x20, 0xcc, + 0xf0, 0x7e, 0x1c, 0xe7, 0xe0, 0x6c, 0xfe, 0xfd, 0xe5, 0xfc, 0xd1, 0x44, 0xed, + 0x0f, 0xf8, 0x30, 0x0c, 0x37, 0x05, 0x9d, 0x11, 0xf0, 0xee, 0xb8, 0xe7, 0x4d, + 0xea, 0x33, 0x81, 0xb4, 0x44, 0x1b, 0xfc, 0xdc, 0xe9, 0x31, 0x01, 0xd7, 0xdd, + 0xfa, 0x10, 0xdf, 0x08, 0x7f, 0xfd, 0x14, 0x1f, 0xeb, 0xf1, 0x1d, 0x00, 0x16, + 0xe7, 0xf8, 0xff, 0x03, 0x20, 0xd1, 0x1e, 0x0c, 0x0c, 0x02, 0xe2, 0x00, 0xc5, + 0x18, 0xb0, 0xf9, 0xda, 0x03, 0xd7, 0x2c, 0xea, 0xe2, 0xd7, 0x0d, 0xfd, 0xdd, + 0xe7, 0x16, 0xfb, 0xee, 0x09, 0xfa, 0xff, 0x0e, 0x0d, 0x02, 0xe2, 0xf8, 0x0a, + 0xea, 0x08, 0x04, 0xee, 0x06, 0xcb, 0xfc, 0x0e, 0xf1, 0xeb, 0x12, 0x1d, 0xf4, + 0x0c, 0x05, 0xd8, 0xc6, 0xea, 0x12, 0x2d, 0x00, 0x19, 0x21, 0xef, 0xfb, 0x31, + 0xf1, 0xc2, 0x2a, 0x06, 0x12, 0x29, 0x0a, 0xf1, 0xf7, 0xf5, 0x0f, 0x05, 0x45, + 0x32, 0x31, 0x1f, 0x06, 0x07, 0xff, 0x1c, 0x06, 0xef, 0x06, 0xe3, 0xd7, 0xf3, + 0xd0, 0x29, 0xdf, 0x14, 0xef, 0xf2, 0xde, 0x0e, 0xf9, 0xdb, 0xe4, 0xfe, 0xfa, + 0x05, 0x25, 0xfe, 0xf3, 0x13, 0xc0, 0x0a, 0xf0, 0x00, 0x1e, 0xe2, 0x0c, 0xc8, + 0x6a, 0xeb, 0x0d, 0x49, 0x1d, 0x49, 0x32, 0x20, 0x01, 0xd8, 0x0e, 0xfc, 0x64, + 0xdd, 0xd8, 0x21, 0x08, 0xf3, 0xfd, 0xfa, 0x9c, 0xaf, 0x09, 0xd6, 0x0e, 0xb8, + 0xeb, 0xd1, 0x31, 0xc8, 0x3e, 0x04, 0xed, 0xea, 0x38, 0x16, 0xd1, 0x3c, 0x42, + 0x08, 0xed, 0xe5, 0xe0, 0xea, 0x05, 0x59, 0x16, 0x03, 0xf5, 0xab, 0xd9, 0x19, + 0x49, 0x3b, 0x32, 0xcb, 0xfa, 0x44, 0xdb, 0xf1, 0x10, 0xf4, 0xee, 0x10, 0x1a, + 0xe5, 0xf0, 0xef, 0xc6, 0xee, 0x24, 0xe7, 0x1a, 0x1b, 0xf8, 0xf3, 0x17, 0xaa, + 0xd9, 0x0f, 0x0f, 0x54, 0xef, 0xd0, 0x0c, 0x7d, 0xeb, 0xba, 0xbc, 0x09, 0x03, + 0x0e, 0x81, 0xd8, 0x42, 0xc5, 0xf5, 0x85, 0xe7, 0x03, 0x2b, 0xe9, 0x34, 0xd6, + 0x32, 0x0f, 0x2c, 0xe8, 0xf9, 0xe5, 0x0a, 0xc1, 0xde, 0x0b, 0xfe, 0x22, 0xe1, + 0xbe, 0xe4, 0x15, 0x2b, 0x28, 0x00, 0x22, 0x1c, 0xe0, 0x1b, 0x09, 0x05, 0xb6, + 0x36, 0x00, 0x0a, 0x05, 0xfa, 0xb5, 0x21, 0x29, 0x1e, 0xba, 0xd2, 0x10, 0xf6, + 0xad, 0x08, 0x41, 0x17, 0x0b, 0xfd, 0x07, 0x02, 0x10, 0x88, 0x3c, 0xee, 0x8a, + 0x29, 0x2b, 0xf1, 0xe2, 0xf5, 0x04, 0xea, 0x29, 0xfa, 0xe2, 0xec, 0x00, 0x1d, + 0x11, 0xe9, 0x25, 0x19, 0x1c, 0xe1, 0xf5, 0x07, 0xef, 0x25, 0xae, 0xbc, 0xe2, + 0x50, 0xca, 0x05, 0xf4, 0xf8, 0x01, 0x43, 0x0b, 0xe9, 0xdd, 0xe2, 0x04, 0x83, + 0xfb, 0xfa, 0x17, 0xfc, 0xe0, 0xf0, 0x05, 0xeb, 0xd7, 0xe9, 0x17, 0x05, 0x17, + 0x10, 0x1e, 0xdd, 0x44, 0xee, 0xcf, 0x00, 0xcf, 0xe6, 0xe9, 0x02, 0xeb, 0x38, + 0xf4, 0xc4, 0x0e, 0x10, 0x0b, 0x04, 0x21, 0x81, 0xda, 0xbc, 0x40, 0x03, 0xc5, + 0x27, 0x0a, 0xab, 0xd8, 0x01, 0xc7, 0xeb, 0xdc, 0x1a, 0xe6, 0x22, 0xd6, 0x3c, + 0xfa, 0x0d, 0xde, 0xfb, 0xc4, 0xe6, 0x12, 0x26, 0xc3, 0x40, 0xb1, 0x59, 0x05, + 0x0f, 0x1e, 0x00, 0xcc, 0x9d, 0x20, 0x46, 0xe7, 0x38, 0xfb, 0x1e, 0x11, 0x1a, + 0x18, 0x71, 0xff, 0x33, 0x1a, 0x27, 0xe6, 0x17, 0x19, 0xec, 0xd9, 0xd2, 0xf5, + 0x16, 0xf5, 0xd0, 0x00, 0x1a, 0x35, 0xce, 0xdb, 0xad, 0xf3, 0xbb, 0x24, 0xf3, + 0x31, 0x3b, 0xf7, 0x21, 0xf9, 0xd0, 0x0b, 0xe2, 0xcd, 0x93, 0x09, 0x67, 0x56, + 0xd9, 0xdf, 0xf7, 0xee, 0xf2, 0xce, 0xe9, 0xea, 0x5c, 0x32, 0xe8, 0x54, 0xc2, + 0xce, 0x01, 0xe9, 0x67, 0x0d, 0x14, 0xc9, 0x13, 0x1d, 0xd2, 0xd8, 0xe9, 0xce, + 0x9c, 0x08, 0x00, 0xdd, 0xc6, 0xb5, 0x13, 0x42, 0xd5, 0x06, 0xaf, 0x55, 0xc6, + 0xdd, 0xf1, 0xc6, 0xd0, 0x2e, 0x45, 0xfe, 0x21, 0x55, 0xc6, 0xf9, 0xef, 0x06, + 0x05, 0xbd, 0xdc, 0x81, 0x01, 0x19, 0x2d, 0xfb, 0x23, 0xed, 0x37, 0xd6, 0xe4, + 0xfa, 0xec, 0x19, 0xcf, 0x09, 0x13, 0xe4, 0x02, 0xe8, 0xd8, 0xde, 0x0d, 0xe5, + 0xf2, 0x05, 0xf7, 0xe3, 0x44, 0xd1, 0xfd, 0x38, 0x0f, 0x36, 0x6b, 0xeb, 0x28, + 0x0d, 0x14, 0xbe, 0xf0, 0xf2, 0xf8, 0x0d, 0xff, 0xc3, 0xf8, 0xe9, 0xf8, 0x39, + 0xc7, 0x04, 0x0b, 0x09, 0x38, 0x06, 0x4a, 0xdb, 0xa0, 0x13, 0xee, 0x1d, 0xf6, + 0x32, 0xeb, 0x1e, 0xfb, 0xc8, 0xde, 0x1d, 0x2a, 0xf0, 0x05, 0xf7, 0x20, 0x08, + 0xb3, 0xfd, 0xf7, 0xfb, 0xc7, 0xac, 0x81, 0x26, 0xee, 0x45, 0xfb, 0xe0, 0xe2, + 0x4f, 0x22, 0xaf, 0x3b, 0xe5, 0x1b, 0xec, 0x31, 0x04, 0xe7, 0x06, 0xf5, 0x18, + 0xf7, 0x34, 0xf5, 0x4b, 0x14, 0xc1, 0xda, 0x0e, 0xe4, 0x23, 0xf7, 0x12, 0xf9, + 0x1c, 0x0d, 0x10, 0xd6, 0xf5, 0xdc, 0xff, 0x26, 0xe4, 0x02, 0x10, 0x36, 0x0f, + 0x12, 0x03, 0xfd, 0xbb, 0x03, 0x02, 0x0b, 0x19, 0x28, 0x04, 0xee, 0xf6, 0xaf, + 0xdf, 0x51, 0xb3, 0xc9, 0xfb, 0xdc, 0x10, 0xe5, 0xe0, 0x0a, 0x07, 0xf0, 0xe9, + 0xdc, 0x08, 0xf2, 0xce, 0xb8, 0xdd, 0xad, 0x06, 0xed, 0x07, 0xe5, 0x37, 0xfb, + 0xf3, 0xec, 0x4b, 0xdd, 0xf7, 0x39, 0xe9, 0x62, 0xf9, 0x17, 0x20, 0x1f, 0xfb, + 0xf1, 0x0a, 0x39, 0x0d, 0x16, 0xe7, 0x16, 0x09, 0xff, 0xfd, 0x39, 0xfd, 0xc8, + 0xf4, 0x1d, 0xe4, 0xd0, 0x20, 0xa4, 0xd5, 0x41, 0xdb, 0x06, 0xf7, 0xf8, 0x81, + 0x25, 0x18, 0x1a, 0x19, 0x08, 0x20, 0xff, 0x00, 0xad, 0xd5, 0x55, 0xff, 0xe1, + 0xd8, 0xe7, 0xef, 0x39, 0xf0, 0x01, 0xe4, 0xf1, 0xf7, 0xf6, 0xda, 0x09, 0x01, + 0x06, 0xff, 0x36, 0xed, 0xdf, 0xe0, 0xf1, 0xd2, 0xdc, 0x32, 0xcb, 0xff, 0x25, + 0xe3, 0xe8, 0xe6, 0x03, 0x16, 0x2d, 0xb4, 0xf0, 0x01, 0x5f, 0xd6, 0xde, 0x26, + 0xdb, 0xdf, 0x1f, 0xfd, 0xe3, 0x12, 0xca, 0xf6, 0x1b, 0x03, 0x11, 0xf5, 0xb4, + 0x13, 0x01, 0xd0, 0x07, 0xf4, 0x0a, 0xcf, 0x31, 0x46, 0x04, 0x68, 0xce, 0xf7, + 0x13, 0xe4, 0x09, 0xf1, 0x51, 0xd7, 0xce, 0x13, 0xbf, 0x51, 0xe5, 0x1c, 0xeb, + 0xfa, 0x14, 0x2f, 0xc6, 0xe3, 0x03, 0xe8, 0x1b, 0x3b, 0x4f, 0x3d, 0xe3, 0xfa, + 0x0f, 0xf0, 0x09, 0x7f, 0x46, 0x3c, 0x21, 0xdb, 0x08, 0x45, 0x73, 0x2c, 0x8e, + 0x3a, 0x29, 0x09, 0xec, 0xe1, 0xea, 0xf9, 0xd1, 0x49, 0xed, 0x2c, 0x1d, 0x25, + 0x40, 0x55, 0xf1, 0xea, 0x13, 0xe5, 0xe7, 0xfe, 0x4a, 0x46, 0x17, 0xc7, 0xf3, + 0xbc, 0x00, 0xe5, 0x4c, 0xe0, 0xff, 0x20, 0xd7, 0x18, 0x21, 0x3a, 0x1f, 0xa8, + 0x4f, 0xd9, 0x43, 0x44, 0x39, 0x08, 0x30, 0x59, 0x33, 0x15, 0xbe, 0xf1, 0x0d, + 0x11, 0xf8, 0x0b, 0xdb, 0xd5, 0xb1, 0x36, 0xe3, 0x0b, 0x2e, 0x22, 0x30, 0xe6, + 0x00, 0x3c, 0xcc, 0x04, 0xce, 0x3c, 0x10, 0x27, 0xf8, 0xff, 0x29, 0x44, 0x02, + 0xa8, 0x21, 0x23, 0x05, 0x29, 0xd1, 0xf5, 0x02, 0xe4, 0x78, 0xd4, 0xda, 0xea, + 0x12, 0x27, 0xe4, 0xf4, 0xfa, 0x21, 0xf2, 0x0e, 0x06, 0xee, 0xde, 0x05, 0xe4, + 0xfb, 0x45, 0xc2, 0xb0, 0xaa, 0x29, 0xd5, 0x07, 0x52, 0xe3, 0x25, 0xe5, 0x04, + 0x21, 0x0d, 0x91, 0xdf, 0xfc, 0xe2, 0x04, 0x36, 0x58, 0x20, 0xf7, 0x16, 0xf6, + 0x2d, 0xbd, 0x06, 0x0f, 0x16, 0xda, 0x1f, 0x01, 0xf3, 0xf9, 0x14, 0x04, 0x5f, + 0x49, 0x20, 0x15, 0xbf, 0x04, 0xf8, 0xb8, 0x1e, 0x29, 0x0b, 0x1d, 0xfb, 0xb9, + 0xd9, 0xb8, 0xfe, 0x20, 0xf4, 0xfe, 0xdc, 0x06, 0xe2, 0x35, 0x25, 0xd5, 0x81, + 0x19, 0xf3, 0xb5, 0xe0, 0x01, 0xfa, 0xe8, 0x45, 0xf7, 0xe6, 0x19, 0xef, 0x2c, + 0x45, 0xe7, 0xf6, 0x01, 0x12, 0x15, 0x09, 0xf7, 0xfa, 0xef, 0x63, 0x06, 0x22, + 0x01, 0x0f, 0xdb, 0xd4, 0xee, 0xe7, 0x10, 0xd9, 0x05, 0x28, 0xe7, 0xc4, 0xdc, + 0xd5, 0xf4, 0xe7, 0xba, 0x03, 0xf0, 0xeb, 0xc7, 0xf8, 0x24, 0xac, 0x03, 0x56, + 0x13, 0xfc, 0xff, 0xe9, 0x2c, 0x13, 0xaf, 0x13, 0x05, 0xe6, 0x19, 0x26, 0xef, + 0x13, 0x17, 0xf6, 0x21, 0xb9, 0x0e, 0x29, 0xe6, 0xcf, 0x2e, 0xea, 0x1e, 0x2c, + 0x1a, 0x1e, 0xef, 0x0c, 0xb7, 0x19, 0xe9, 0x1f, 0x2a, 0xea, 0x2c, 0x00, 0xc5, + 0x17, 0x24, 0x05, 0xe3, 0x14, 0x2b, 0x15, 0x11, 0xf2, 0x05, 0xf3, 0xd1, 0x36, + 0xcf, 0x16, 0x02, 0xf6, 0xf2, 0x1c, 0x3b, 0xb8, 0x02, 0xe3, 0xcc, 0xe1, 0x42, + 0x41, 0xf9, 0xfa, 0xfe, 0xe5, 0x0e, 0x38, 0x47, 0xfa, 0x12, 0xc1, 0x0d, 0x0e, + 0x60, 0x13, 0xf4, 0x7f, 0x15, 0x1c, 0x25, 0x09, 0x0c, 0xd1, 0x07, 0x26, 0x28, + 0xd5, 0x1d, 0x23, 0xd7, 0x28, 0xcb, 0x52, 0x10, 0x00, 0x21, 0x1a, 0xdd, 0xda, + 0x1a, 0xfd, 0xc9, 0xf2, 0xc1, 0xf7, 0x1c, 0x3c, 0xeb, 0xad, 0x28, 0xe1, 0xcd, + 0xe0, 0x31, 0x0b, 0x13, 0x16, 0xb2, 0xfa, 0xf5, 0xfd, 0xf8, 0x23, 0x1f, 0xfb, + 0x00, 0x1a, 0xae, 0xd2, 0xba, 0x1e, 0x1e, 0xc4, 0xca, 0x42, 0xf9, 0xdf, 0xd7, + 0xd5, 0xef, 0x45, 0x1c, 0x29, 0xf5, 0x00, 0xda, 0x16, 0x36, 0xf8, 0xf2, 0x11, + 0x7f, 0xdd, 0x3a, 0xf3, 0x2f, 0x1f, 0xe1, 0x5c, 0xf7, 0xd7, 0xea, 0x00, 0x1e, + 0xf0, 0x05, 0x11, 0xe5, 0xee, 0xf7, 0x0f, 0x6c, 0x0c, 0xcc, 0xcb, 0x23, 0xdc, + 0x05, 0x40, 0x1d, 0x03, 0x0a, 0x05, 0xfc, 0xd5, 0xb4, 0xc3, 0x0e, 0xe9, 0x37, + 0x2e, 0xe4, 0x26, 0x4f, 0xe6, 0x32, 0xb0, 0xf8, 0xda, 0x15, 0x61, 0xfa, 0xf4, + 0xe1, 0x59, 0xf1, 0x0d, 0xfe, 0x0e, 0xc9, 0x6f, 0x0f, 0x14, 0xe2, 0x0a, 0x0a, + 0xdb, 0x0a, 0xff, 0x5e, 0x97, 0x2e, 0x1e, 0x14, 0x1a, 0xe5, 0x3f, 0x0b, 0xee, + 0x0a, 0xfd, 0xe7, 0xdc, 0x15, 0x0a, 0x40, 0xcd, 0x1c, 0xcf, 0x0b, 0x25, 0xf9, + 0xdb, 0x03, 0xf7, 0xea, 0x1b, 0x0e, 0x99, 0x62, 0xe3, 0x41, 0xf3, 0xd1, 0x4f, + 0x0a, 0x05, 0x2b, 0x13, 0xc1, 0x9f, 0xc3, 0xb8, 0x2a, 0x38, 0x01, 0x11, 0xf5, + 0x1f, 0x06, 0x17, 0x32, 0xd5, 0xce, 0xba, 0x1f, 0x1b, 0x13, 0x0b, 0xfb, 0xab, + 0xcf, 0x5c, 0x26, 0xf6, 0x22, 0xd8, 0x31, 0x2b, 0x2b, 0x82, 0x2c, 0xf9, 0x2b, + 0x61, 0xff, 0x0b, 0xe9, 0xf3, 0x1c, 0xdb, 0x3e, 0xf6, 0xec, 0xe4, 0x53, 0x14, + 0x31, 0xb3, 0xf4, 0xe3, 0x00, 0xb8, 0xed, 0x98, 0xe8, 0x04, 0xd6, 0xe2, 0xcb, + 0xd7, 0x0c, 0x12, 0xf3, 0x28, 0x23, 0xc4, 0x13, 0xdf, 0xed, 0x54, 0x9a, 0xf9, + 0x0f, 0xb7, 0xc7, 0x4a, 0x3c, 0xfc, 0xaf, 0xf4, 0x0c, 0x28, 0x1e, 0xe6, 0x12, + 0x2c, 0x35, 0xa1, 0x39, 0xe0, 0x55, 0x3a, 0xf5, 0x81, 0xc8, 0x2e, 0xe7, 0x18, + 0xae, 0x1a, 0xf0, 0x45, 0xd9, 0xf2, 0x15, 0xf5, 0x0f, 0x3c, 0x07, 0xb1, 0x3f, + 0xd4, 0x97, 0x45, 0xa6, 0x19, 0x0f, 0xde, 0xca, 0xdd, 0xef, 0xda, 0xfb, 0xd5, + 0xfc, 0x39, 0xf2, 0x7f, 0xeb, 0x0a, 0x3d, 0x46, 0x41, 0xdd, 0x98, 0x0f, 0xe9, + 0xf0, 0xb6, 0xef, 0x06, 0xf1, 0x54, 0xe9, 0x1d, 0x2a, 0x48, 0xee, 0x28, 0x18, + 0x2b, 0x09, 0x2f, 0xfe, 0x69, 0x3e, 0xe8, 0xf3, 0x3d, 0xe7, 0x31, 0xdc, 0xe1, + 0x04, 0xfa, 0x28, 0x08, 0x36, 0xbf, 0x34, 0xe3, 0x2a, 0x30, 0xd1, 0x43, 0xaa, + 0x63, 0x2f, 0x1d, 0xdb, 0x35, 0xf6, 0x13, 0xfe, 0xcd, 0xbd, 0x0e, 0xe1, 0xe6, + 0xec, 0x7e, 0x33, 0x4e, 0xcc, 0x2e, 0xfa, 0xe3, 0xc1, 0x18, 0x10, 0xe1, 0xc2, + 0x4e, 0xd8, 0x01, 0x00, 0x27, 0x03, 0x26, 0xcc, 0xff, 0xee, 0xe5, 0xf5, 0x2f, + 0x2e, 0xda, 0xcf, 0x1d, 0xdd, 0xff, 0x36, 0x11, 0x2a, 0x28, 0x1d, 0x14, 0xd1, + 0x0a, 0x3e, 0xf6, 0xb0, 0x05, 0x35, 0x4d, 0xf9, 0x37, 0x5e, 0x31, 0x14, 0x5c, + 0xdb, 0xf5, 0x05, 0x9b, 0xd9, 0xf5, 0x0f, 0x11, 0xc5, 0xb7, 0xa4, 0xf0, 0xe6, + 0x1a, 0xe4, 0xde, 0x05, 0x19, 0xe6, 0xcb, 0xe7, 0x1f, 0x37, 0xfc, 0xe9, 0xdd, + 0x1c, 0xb1, 0xf0, 0x20, 0x12, 0xdd, 0x1f, 0xe4, 0x06, 0x25, 0xa7, 0x3a, 0x43, + 0x20, 0x34, 0x14, 0xe6, 0xd6, 0x25, 0x70, 0x29, 0xc9, 0x18, 0xc1, 0x2d, 0xf2, + 0xe0, 0x06, 0x56, 0x0f, 0x0e, 0x00, 0xd4, 0x85, 0xdd, 0x01, 0x16, 0x43, 0x17, + 0xe3, 0x22, 0x18, 0x19, 0xb9, 0xef, 0xe5, 0x35, 0xb9, 0x37, 0x0a, 0xdd, 0x19, + 0xd4, 0xe1, 0x0e, 0x05, 0xbb, 0x13, 0xfc, 0xff, 0x20, 0xf9, 0xb2, 0xa2, 0xf8, + 0xe1, 0xc5, 0x43, 0x2f, 0x14, 0x09, 0xbb, 0xf1, 0x1a, 0xe8, 0xa2, 0xf1, 0xf3, + 0x09, 0x02, 0x22, 0x24, 0x25, 0xf4, 0xf8, 0x35, 0xf5, 0x13, 0x1f, 0x81, 0xd3, + 0x1a, 0xfa, 0xcc, 0x24, 0xf2, 0xf5, 0xdc, 0xf5, 0x0d, 0xf7, 0x2f, 0x01, 0x12, + 0xe9, 0xde, 0xe0, 0xe2, 0xe1, 0x16, 0xca, 0x29, 0xfb, 0xe4, 0xde, 0xf8, 0x2f, + 0x22, 0x38, 0xdb, 0xed, 0xbe, 0x15, 0xd3, 0x12, 0x1d, 0x3a, 0x04, 0x1b, 0xe8, + 0xc4, 0x00, 0x13, 0xdc, 0xd9, 0xfd, 0x13, 0x0b, 0xbd, 0xe9, 0x17, 0xad, 0x2f, + 0x12, 0x09, 0xd8, 0xf3, 0xe8, 0xa8, 0x08, 0xf5, 0xd8, 0x0a, 0xe4, 0xe5, 0xc8, + 0xc6, 0x1b, 0x00, 0x2c, 0xd5, 0x14, 0x3e, 0xdc, 0x01, 0xff, 0x0a, 0xeb, 0x1e, + 0x1a, 0x02, 0x24, 0xe4, 0xf4, 0xfc, 0x3c, 0x16, 0x0d, 0xc6, 0xf5, 0xf2, 0xf3, + 0xca, 0x0b, 0xc6, 0x21, 0xe6, 0xd8, 0x3f, 0x05, 0x1a, 0xfe, 0xe9, 0xd0, 0x5d, + 0x2d, 0xf2, 0xea, 0xf9, 0xe3, 0xf9, 0xcb, 0xd5, 0xeb, 0x00, 0xe7, 0x37, 0x02, + 0xcf, 0x1b, 0xf6, 0x18, 0xf1, 0x30, 0xf8, 0x2c, 0xfc, 0xcd, 0x81, 0x08, 0x27, + 0xff, 0x2e, 0x02, 0xfb, 0xe1, 0xf9, 0x06, 0x2e, 0xe9, 0x26, 0x13, 0xde, 0x02, + 0x17, 0x04, 0x03, 0x09, 0x37, 0x7f, 0x02, 0xdf, 0x29, 0xd9, 0xf3, 0xe8, 0xe5, + 0x0f, 0x03, 0xdc, 0x1c, 0x2a, 0xd3, 0xac, 0xf0, 0x44, 0x06, 0xf4, 0xe1, 0xe0, + 0x17, 0x00, 0xfd, 0xcf, 0xfa, 0x21, 0xfe, 0xb3, 0xe1, 0xe9, 0x2e, 0x14, 0xf9, + 0xe3, 0x02, 0xf3, 0x02, 0x11, 0x23, 0x29, 0x18, 0x13, 0x02, 0xf0, 0x12, 0xe9, + 0x13, 0xf7, 0x0f, 0xce, 0xcc, 0xf5, 0x06, 0x1a, 0x07, 0x0f, 0xf2, 0x15, 0xf2, + 0xe6, 0x08, 0xf3, 0xf2, 0xeb, 0xf8, 0xd6, 0x23, 0x08, 0xe5, 0x09, 0x2f, 0xe3, + 0xe5, 0xfc, 0x37, 0x00, 0x08, 0xea, 0x05, 0x31, 0xfa, 0xe9, 0x35, 0xf6, 0x1f, + 0x02, 0xfd, 0xde, 0xcf, 0xea, 0xd0, 0x30, 0xea, 0x07, 0xf3, 0x06, 0xfe, 0x2b, + 0xc4, 0x1c, 0xe4, 0xd2, 0xe6, 0x10, 0xf9, 0xdd, 0x11, 0xcb, 0x15, 0xb1, 0xfb, + 0x48, 0xf4, 0x23, 0x02, 0x15, 0x42, 0x1c, 0xef, 0x38, 0xc0, 0xe6, 0x04, 0x17, + 0x05, 0xef, 0xe8, 0x47, 0x24, 0xf6, 0x2d, 0x1b, 0xf4, 0x55, 0x3a, 0x37, 0xb9, + 0x10, 0xda, 0x96, 0xd4, 0x34, 0xba, 0xff, 0x09, 0x02, 0xf9, 0x1f, 0xcc, 0xf1, + 0x40, 0xbc, 0xeb, 0xe0, 0x47, 0xee, 0xef, 0xfc, 0x3c, 0x11, 0x7a, 0x08, 0xd7, + 0xf5, 0xf3, 0xd6, 0xb6, 0xf5, 0xf1, 0x25, 0xe8, 0xac, 0xfb, 0xc2, 0xce, 0x81, + 0x74, 0xcd, 0xf0, 0x43, 0xb2, 0xbd, 0xc2, 0xff, 0x04, 0x2e, 0x61, 0xbf, 0xec, + 0x03, 0xf8, 0xf7, 0xf1, 0x9d, 0xee, 0x1a, 0x1f, 0xd8, 0x4a, 0xe1, 0xdb, 0x4a, + 0x3c, 0xed, 0xee, 0x23, 0x4a, 0xcb, 0xce, 0x16, 0x3c, 0x3d, 0xf1, 0x05, 0xde, + 0x50, 0x01, 0x11, 0xcc, 0x92, 0xf9, 0x14, 0xd1, 0xd6, 0x08, 0xd9, 0x8d, 0x9c, + 0xcd, 0x2e, 0xc3, 0xed, 0x04, 0x05, 0x7a, 0x2b, 0x02, 0x1d, 0xa1, 0x26, 0xd4, + 0x32, 0x26, 0x96, 0x64, 0xe8, 0xdb, 0x0b, 0x2a, 0xd5, 0x04, 0x13, 0x2c, 0x5e, + 0xf1, 0x06, 0x0e, 0x9d, 0xdd, 0xd8, 0xe8, 0x2f, 0x23, 0x2f, 0xcd, 0xc5, 0xee, + 0x30, 0xed, 0x5e, 0xdb, 0xf4, 0xe9, 0x20, 0xe3, 0x1b, 0xe1, 0xf4, 0xd4, 0xed, + 0x2e, 0xd2, 0xb7, 0x5a, 0x0f, 0xc9, 0xca, 0xce, 0x9e, 0x53, 0x2f, 0x4b, 0x18, + 0x82, 0x00, 0xda, 0xe3, 0xbc, 0x1b, 0xc6, 0xfe, 0xde, 0x4b, 0x32, 0xbc, 0xef, + 0xb3, 0xf3, 0xfc, 0x61, 0x2f, 0xfa, 0xa1, 0x86, 0x5c, 0xd0, 0xdc, 0x02, 0x4b, + 0xeb, 0x1f, 0x5a, 0x24, 0x16, 0x0f, 0xd1, 0xd1, 0xbf, 0xd9, 0x8f, 0xa8, 0x11, + 0x3b, 0xd8, 0x32, 0xda, 0xe6, 0x59, 0x7f, 0x11, 0x40, 0xe4, 0x34, 0xf0, 0x06, + 0xd4, 0xf4, 0xd5, 0xc3, 0x1e, 0x2e, 0x1b, 0xe9, 0xf6, 0x12, 0xe5, 0x0b, 0xe4, + 0x3b, 0x14, 0xd0, 0x45, 0x0c, 0xdb, 0xdb, 0xf5, 0xfa, 0x06, 0x1a, 0xc8, 0xe3, + 0xe5, 0x06, 0x14, 0x28, 0xf6, 0xbf, 0xc9, 0x09, 0xb1, 0x35, 0xd8, 0x10, 0xf5, + 0x35, 0x09, 0x0c, 0x18, 0xfd, 0xfa, 0x16, 0xfc, 0x41, 0xd5, 0x27, 0xc1, 0xa4, + 0x0e, 0xdc, 0xdc, 0x48, 0x38, 0xff, 0x0e, 0x4b, 0x0a, 0xa5, 0xee, 0x30, 0x1b, + 0x0b, 0x01, 0x0f, 0x53, 0xf7, 0xd7, 0xed, 0xec, 0xf9, 0xd1, 0x2a, 0x26, 0x2d, + 0xfa, 0x35, 0x22, 0x36, 0xed, 0xfc, 0x14, 0x8e, 0xef, 0xdd, 0x0b, 0x3b, 0x29, + 0xd6, 0xf4, 0xd0, 0x51, 0x00, 0xf5, 0xc8, 0x35, 0x09, 0xf1, 0x11, 0xd2, 0x5a, + 0xf9, 0x4f, 0xdd, 0x05, 0xc8, 0x0b, 0xe8, 0xf6, 0x2a, 0x2b, 0xfe, 0x81, 0x07, + 0x45, 0xce, 0x16, 0x1b, 0xe8, 0x46, 0xef, 0x4e, 0x0e, 0x21, 0xfa, 0x2b, 0xce, + 0x18, 0xfc, 0x2e, 0x09, 0x04, 0x5b, 0xd6, 0x27, 0x0f, 0xc9, 0x21, 0x14, 0xf3, + 0xfc, 0xe3, 0x02, 0xf4, 0xec, 0xff, 0xff, 0x2c, 0x12, 0x1c, 0x03, 0x02, 0xdd, + 0xe5, 0x19, 0x0a, 0x0e, 0x2c, 0xf5, 0x23, 0xfa, 0xd0, 0x08, 0x1f, 0xe0, 0xdb, + 0x14, 0xf9, 0xe9, 0x00, 0x1c, 0x16, 0xd5, 0xf9, 0xc5, 0xfb, 0x26, 0x15, 0xfe, + 0x05, 0x07, 0xd5, 0x25, 0x1a, 0xe4, 0xf9, 0xf9, 0xea, 0x0d, 0x0b, 0x23, 0x14, + 0xf0, 0xef, 0xdb, 0xe8, 0x1f, 0x2e, 0x0f, 0x09, 0xdd, 0x22, 0x0e, 0x05, 0xee, + 0xfd, 0x03, 0xc6, 0x0b, 0x05, 0xf1, 0xd6, 0x04, 0xdd, 0xe0, 0xfb, 0xfa, 0x01, + 0x17, 0xf0, 0xf1, 0x1e, 0x09, 0xfe, 0x00, 0x11, 0x02, 0x00, 0xc7, 0x04, 0xd2, + 0xf5, 0xdd, 0xfa, 0x09, 0xdc, 0x0f, 0xe4, 0xe1, 0xfa, 0xcb, 0x27, 0xed, 0xef, + 0xfc, 0xd4, 0xea, 0x04, 0xd3, 0xe8, 0x23, 0x02, 0x08, 0xce, 0x0a, 0x19, 0xf7, + 0xe7, 0xf9, 0x15, 0x2c, 0x03, 0xf0, 0xf5, 0x3f, 0x0b, 0x7f, 0x16, 0x18, 0x21, + 0xf6, 0x38, 0xd5, 0xfe, 0x01, 0xeb, 0x3b, 0xbe, 0xdb, 0xba, 0xa2, 0xae, 0x01, + 0x2d, 0x6a, 0x46, 0x29, 0x2b, 0x29, 0x81, 0x04, 0xff, 0x23, 0x1b, 0xfd, 0xab, + 0x26, 0x37, 0x3f, 0x21, 0x20, 0x23, 0x9d, 0xc1, 0xc6, 0xcf, 0x7a, 0x49, 0xea, + 0xf4, 0xd5, 0x2f, 0xcc, 0x48, 0xd7, 0x13, 0xfd, 0x3e, 0x0f, 0xef, 0x50, 0xe0, + 0x11, 0xd2, 0x37, 0x2e, 0x3d, 0x20, 0x55, 0xe5, 0x3a, 0xe4, 0x12, 0x2a, 0x27, + 0x04, 0x57, 0x4d, 0xf4, 0x0f, 0x29, 0x27, 0xf8, 0x2c, 0xfd, 0x69, 0x2d, 0xfe, + 0x32, 0xfd, 0xa6, 0xc8, 0xe2, 0xf6, 0x31, 0xbf, 0x52, 0xf8, 0xff, 0xe1, 0xdb, + 0x50, 0xdc, 0xea, 0xf0, 0xdb, 0x18, 0x93, 0xca, 0x65, 0x8f, 0x09, 0x10, 0x62, + 0xe5, 0x3c, 0x4c, 0x03, 0xe7, 0x0d, 0xff, 0x9c, 0x4d, 0xe3, 0xe1, 0xf9, 0xce, + 0x36, 0xe7, 0x1d, 0x9f, 0x19, 0x13, 0x2f, 0x4d, 0xf5, 0xeb, 0xe4, 0x68, 0x10, + 0x2d, 0xe5, 0x17, 0xe3, 0xd0, 0xd5, 0xec, 0x13, 0x1b, 0x10, 0xd6, 0x39, 0xd4, + 0x24, 0xe3, 0xc3, 0x14, 0xee, 0xfd, 0xee, 0x45, 0x0e, 0x23, 0xf0, 0x32, 0x03, + 0xe7, 0xdc, 0x26, 0x3e, 0xec, 0xbe, 0xd9, 0x7f, 0xda, 0x0c, 0x23, 0x19, 0x17, + 0xf2, 0x52, 0x37, 0xce, 0xfd, 0xec, 0x25, 0x19, 0xf5, 0x01, 0xf1, 0xf0, 0x02, + 0xe8, 0x1b, 0xf7, 0xe1, 0xf2, 0x01, 0xd5, 0xdf, 0xe6, 0xff, 0x0d, 0xeb, 0xdc, + 0x18, 0xdc, 0xf1, 0x1f, 0xf8, 0xe7, 0xff, 0xf1, 0xe0, 0xd6, 0x2e, 0x0e, 0x09, + 0xdc, 0x25, 0xfc, 0x05, 0xdb, 0x1c, 0xdf, 0xca, 0xf3, 0xec, 0x27, 0x1c, 0x3e, + 0xc2, 0xde, 0x26, 0x37, 0xf6, 0xfe, 0x2f, 0x1a, 0x0b, 0xd9, 0xf5, 0xca, 0xf6, + 0xca, 0x1d, 0x10, 0x01, 0xfc, 0x08, 0xfd, 0xcf, 0x03, 0x1f, 0x1e, 0x32, 0xa4, + 0xe6, 0xed, 0x00, 0xd2, 0x27, 0xd7, 0xeb, 0x10, 0xe6, 0x1d, 0xe3, 0x00, 0xcf, + 0xff, 0x16, 0xdd, 0xcb, 0x09, 0x12, 0xe0, 0xf0, 0xee, 0x08, 0xf7, 0xc6, 0x24, + 0x44, 0x04, 0xaf, 0x22, 0xd7, 0x39, 0xef, 0x2c, 0xf8, 0x2b, 0xd9, 0x2b, 0xf8, + 0x0b, 0x4d, 0xca, 0xf8, 0xcb, 0x19, 0x1e, 0xfb, 0xd7, 0xf3, 0x1a, 0xf8, 0x4c, + 0x23, 0xe7, 0xf3, 0x00, 0x1d, 0x13, 0xe7, 0xf5, 0x39, 0xb3, 0x1c, 0xe8, 0x0b, + 0x27, 0xf0, 0xe6, 0x06, 0x40, 0x14, 0xd9, 0xe4, 0xce, 0x24, 0xd8, 0xc2, 0x16, + 0xdb, 0xf7, 0x29, 0xbb, 0x38, 0xf1, 0x01, 0xf9, 0x2a, 0x05, 0x07, 0xac, 0x13, + 0x0c, 0x04, 0xe9, 0xf6, 0x02, 0x04, 0x0c, 0x51, 0x07, 0xfa, 0xe0, 0x25, 0x2d, + 0x81, 0xe7, 0x0a, 0x02, 0x0c, 0xe8, 0x59, 0xd3, 0xf3, 0xf4, 0xec, 0xeb, 0x4e, + 0xef, 0xdb, 0x04, 0xf8, 0x0c, 0x13, 0x20, 0xde, 0xd4, 0x0b, 0xe1, 0x32, 0xd6, + 0xfa, 0x08, 0x02, 0xe2, 0x20, 0x2a, 0x28, 0x3a, 0xdd, 0xb2, 0x61, 0x5c, 0x21, + 0x1e, 0xf4, 0xb4, 0x0a, 0x30, 0xf2, 0x15, 0xd9, 0xd5, 0x25, 0x06, 0xbe, 0xca, + 0x04, 0xd4, 0xd6, 0x26, 0x5f, 0x02, 0xcd, 0x37, 0x54, 0x14, 0xd1, 0x35, 0x08, + 0x0e, 0x53, 0x17, 0x20, 0x35, 0x2d, 0x16, 0x61, 0x0f, 0xdb, 0xfb, 0xcd, 0xd0, + 0xee, 0x00, 0x47, 0x1c, 0x39, 0x14, 0x08, 0xe7, 0x2d, 0xcf, 0xfb, 0x13, 0x26, + 0xf5, 0xe6, 0xc4, 0xce, 0x3c, 0xe5, 0x11, 0x07, 0x37, 0x1b, 0xf6, 0x3f, 0x16, + 0x60, 0x07, 0xdf, 0x93, 0xcf, 0xd3, 0x9d, 0xbd, 0xda, 0x2d, 0x05, 0x01, 0xa1, + 0xe7, 0xe2, 0xcd, 0x1a, 0x20, 0xc5, 0xf0, 0x08, 0xd1, 0xc3, 0xa7, 0xd2, 0xbb, + 0x34, 0xf1, 0xe3, 0x7f, 0xe4, 0xe7, 0x18, 0xec, 0xf4, 0x59, 0xd9, 0xa3, 0x1c, + 0x0f, 0x41, 0xde, 0xe0, 0x09, 0xe6, 0x4d, 0xf2, 0x2c, 0xc2, 0x6a, 0x06, 0xbe, + 0xab, 0xbe, 0x36, 0x33, 0xd1, 0x1a, 0xba, 0xe1, 0xe5, 0x29, 0x37, 0x12, 0xb4, + 0xe2, 0xea, 0xd5, 0xd5, 0xfd, 0xcf, 0xde, 0xd0, 0xd0, 0x09, 0xf8, 0x19, 0x31, + 0x26, 0xcd, 0x3d, 0xcb, 0xfa, 0x00, 0x13, 0x07, 0xf4, 0x1a, 0xeb, 0x08, 0xde, + 0x04, 0xd9, 0x05, 0x3d, 0x0a, 0x0f, 0x0f, 0x37, 0x3f, 0xfe, 0xe5, 0x29, 0x16, + 0x1b, 0x15, 0xe2, 0xee, 0xfa, 0xf7, 0xb4, 0x0a, 0x12, 0x09, 0xf1, 0xf9, 0x6f, + 0xf0, 0xe5, 0x0c, 0x13, 0xe1, 0xac, 0xd0, 0xdd, 0xc1, 0x3f, 0xe8, 0xe1, 0x17, + 0x70, 0xf8, 0xb2, 0xf2, 0xf5, 0xdd, 0x45, 0xf7, 0x1e, 0xf1, 0x1c, 0x05, 0xe4, + 0x1f, 0xcb, 0x07, 0x10, 0x3a, 0xe3, 0xf6, 0xfe, 0x14, 0xed, 0x27, 0xcb, 0xdf, + 0xd4, 0x19, 0xe3, 0xdd, 0x15, 0xe6, 0x17, 0x13, 0xfe, 0xe7, 0x09, 0x0f, 0xcc, + 0x48, 0x6b, 0xfc, 0xfd, 0x17, 0xf7, 0x02, 0x11, 0xea, 0x19, 0xe9, 0xf0, 0x81, + 0xdd, 0x06, 0xea, 0x06, 0x03, 0xd8, 0x46, 0x24, 0x18, 0xb9, 0xd7, 0x1c, 0x0e, + 0x0d, 0x0a, 0xe1, 0x20, 0x26, 0x2c, 0x12, 0x94, 0x5f, 0x2c, 0x22, 0xcd, 0xe7, + 0x09, 0x1c, 0x1b, 0xd8, 0xea, 0x1e, 0x00, 0x56, 0xcf, 0x22, 0xef, 0xe3, 0xe5, + 0x31, 0x1a, 0xbe, 0xd5, 0x28, 0x2b, 0xfe, 0x27, 0xda, 0x17, 0x25, 0xdf, 0x51, + 0x22, 0xdb, 0x4d, 0x18, 0x2a, 0x4e, 0x3e, 0xec, 0xaf, 0x2f, 0x1d, 0x46, 0xcf, + 0x1f, 0x00, 0xe8, 0xfc, 0xd9, 0x04, 0x1f, 0x57, 0x72, 0x38, 0x05, 0x2f, 0xf6, + 0xfc, 0xe1, 0xf2, 0x2a, 0x0f, 0x32, 0xc7, 0x15, 0xf0, 0x0c, 0xea, 0x19, 0x7f, + 0x37, 0x0a, 0x2e, 0x47, 0xcd, 0x17, 0xee, 0x0c, 0x24, 0xf5, 0xb3, 0xfd, 0xd3, + 0xd3, 0xba, 0x11, 0xc8, 0xf2, 0xd4, 0xdb, 0x2c, 0x2f, 0xc9, 0xd3, 0x43, 0x0b, + 0xf8, 0xf6, 0x0c, 0xe7, 0x16, 0x0a, 0x84, 0xc7, 0xfc, 0xbd, 0x04, 0xe8, 0x06, + 0xf8, 0xea, 0x16, 0xf1, 0xc5, 0x02, 0x05, 0xee, 0xbf, 0xce, 0x1a, 0xe3, 0x82, + 0x01, 0x13, 0xeb, 0x57, 0xed, 0x15, 0x1e, 0xec, 0x38, 0x4b, 0x76, 0x10, 0x26, + 0xd4, 0xee, 0xf7, 0x2b, 0xe8, 0x02, 0x1b, 0x04, 0xbf, 0xcc, 0x17, 0x0a, 0x1d, + 0x13, 0x30, 0xf6, 0x19, 0x2b, 0x0a, 0xc7, 0x04, 0x47, 0x4c, 0x04, 0xdf, 0x26, + 0xd9, 0x00, 0xf7, 0xe4, 0xf5, 0x02, 0xe6, 0xc7, 0x09, 0x10, 0x96, 0x04, 0xfe, + 0x0c, 0xf3, 0xbe, 0x15, 0xba, 0x1c, 0x03, 0x10, 0xda, 0xf2, 0x81, 0xf5, 0xff, + 0x18, 0xa7, 0x1f, 0xff, 0x26, 0xd6, 0x45, 0xf3, 0x30, 0xea, 0xe2, 0xb1, 0xfe, + 0x36, 0x2f, 0x31, 0xb0, 0xfe, 0x33, 0x69, 0x1b, 0x0c, 0xe0, 0x3b, 0xbb, 0x13, + 0xfd, 0x2d, 0x25, 0x07, 0x0b, 0xd1, 0xf0, 0xc5, 0xdf, 0x4d, 0x63, 0x1e, 0x1c, + 0xf8, 0xd6, 0x15, 0xd4, 0xf8, 0x2c, 0xf9, 0x4e, 0xb4, 0x29, 0x15, 0xd0, 0x05, + 0x38, 0x2f, 0x12, 0xfe, 0x1a, 0x05, 0xee, 0xb5, 0xf9, 0xd6, 0xbd, 0x31, 0xfd, + 0xe8, 0x13, 0xc2, 0xf4, 0xad, 0xf4, 0x09, 0x12, 0xfa, 0x34, 0xf2, 0xe5, 0x0f, + 0xe8, 0xc0, 0x01, 0xc8, 0x2b, 0x01, 0xac, 0xda, 0x10, 0x35, 0x23, 0xf6, 0xfe, + 0x32, 0xe5, 0x09, 0x02, 0x1e, 0x7f, 0xbc, 0x21, 0x4b, 0x33, 0xff, 0xf7, 0xe7, + 0xe9, 0x08, 0x10, 0xed, 0x26, 0x32, 0x9f, 0xbf, 0x06, 0xf3, 0x50, 0x21, 0x1a, + 0x1b, 0x19, 0xf4, 0xbf, 0xe6, 0xf7, 0x1c, 0x12, 0xe6, 0xc0, 0x47, 0xe3, 0x13, + 0x27, 0xea, 0x0a, 0x35, 0xf8, 0x20, 0xcd, 0x92, 0x0b, 0x2c, 0xe5, 0xde, 0x11, + 0x04, 0x03, 0x0c, 0x42, 0xe0, 0xce, 0xd4, 0x20, 0xff, 0x22, 0x1f, 0xe8, 0xd2, + 0x03, 0xbd, 0x31, 0x6d, 0xf4, 0x0f, 0x06, 0x52, 0xcd, 0xc3, 0xf1, 0xc3, 0xe2, + 0x20, 0x0d, 0x10, 0x01, 0x15, 0xd1, 0x1f, 0xdc, 0x22, 0xf3, 0x2f, 0xe7, 0xf7, + 0x00, 0x0b, 0x0b, 0x12, 0x17, 0x44, 0xf5, 0xa2, 0xe5, 0x14, 0xf4, 0x0f, 0x3b, + 0xc6, 0x31, 0xf4, 0xcf, 0x2b, 0x08, 0xdf, 0xe1, 0xa3, 0x09, 0xfd, 0xf4, 0xc3, + 0xf0, 0xf0, 0x18, 0x3c, 0xf2, 0xb8, 0xf5, 0xe5, 0xe5, 0x05, 0x3a, 0xe6, 0x28, + 0xed, 0xe5, 0x2d, 0x2b, 0x17, 0xcf, 0x0e, 0xe4, 0xbd, 0x27, 0x09, 0xf8, 0x0c, + 0x15, 0xe2, 0xe9, 0xde, 0x24, 0x02, 0x08, 0xe8, 0x02, 0x04, 0x07, 0xcd, 0xf7, + 0x9a, 0xf3, 0x01, 0xec, 0xcf, 0xe1, 0xd5, 0xf8, 0x4f, 0x06, 0x1f, 0x15, 0xf5, + 0x2a, 0x0b, 0xea, 0xfc, 0x18, 0xd4, 0xf9, 0x33, 0x16, 0xf8, 0x7f, 0x39, 0x21, + 0x00, 0x13, 0x5f, 0xe3, 0xd7, 0xd6, 0xc4, 0x30, 0xf2, 0x08, 0xfd, 0xba, 0xf7, + 0x22, 0x0d, 0x1d, 0xf3, 0x31, 0xe7, 0xed, 0xd1, 0x39, 0xf5, 0x08, 0xce, 0xfa, + 0x1b, 0x01, 0x54, 0xfa, 0xb3, 0xf0, 0xc5, 0x3d, 0xfb, 0x01, 0x39, 0xd9, 0x02, + 0x1e, 0x25, 0xd1, 0xbd, 0x0a, 0x10, 0xd7, 0x24, 0x1b, 0xdd, 0xf1, 0xf7, 0xf8, + 0xf4, 0xea, 0x81, 0x27, 0x11, 0x2d, 0xfb, 0x64, 0x2c, 0x10, 0x16, 0x11, 0xed, + 0x0a, 0x09, 0xc1, 0x1b, 0x0c, 0xf3, 0x24, 0x0d, 0x39, 0x1d, 0x05, 0x18, 0xc8, + 0xde, 0x00, 0x1d, 0xf4, 0xf7, 0xea, 0xf8, 0x11, 0xcb, 0xfe, 0x11, 0x19, 0xed, + 0xea, 0xfc, 0x0f, 0xf0, 0xe3, 0xcc, 0xe0, 0xea, 0xa4, 0x25, 0x10, 0x04, 0xef, + 0x15, 0xeb, 0xc4, 0x01, 0xfe, 0x01, 0xd1, 0x01, 0xfe, 0xf9, 0x6f, 0x09, 0x17, + 0xdc, 0xe6, 0x2d, 0x08, 0xcd, 0xbe, 0x99, 0x30, 0xe4, 0x10, 0xb2, 0xaa, 0x22, + 0xc5, 0x00, 0x00, 0x06, 0xfd, 0xe3, 0xef, 0xc8, 0xf0, 0xe8, 0xb4, 0xf0, 0xf2, + 0x05, 0xe8, 0x11, 0xf9, 0x13, 0x1f, 0xf1, 0xf7, 0xe3, 0xe1, 0xc6, 0xc8, 0x00, + 0xf8, 0xf7, 0x42, 0x15, 0x19, 0xf7, 0xf5, 0xea, 0xf0, 0xbf, 0x19, 0x05, 0x13, + 0xe0, 0xc0, 0xdd, 0xd7, 0xcb, 0x13, 0xe7, 0x1d, 0x2e, 0xec, 0x08, 0xfe, 0xfc, + 0x18, 0x18, 0xdd, 0x10, 0x0b, 0xe3, 0x27, 0xe6, 0xf9, 0x11, 0x67, 0xfc, 0x1e, + 0xd4, 0x0b, 0xee, 0xf2, 0x1f, 0xfd, 0xb2, 0x02, 0x32, 0xcd, 0xc8, 0xf9, 0x0d, + 0x0c, 0xe6, 0xfd, 0x11, 0xe2, 0x0b, 0xee, 0xcd, 0x3a, 0xf3, 0xd8, 0x11, 0x10, + 0x05, 0x10, 0xf4, 0xdc, 0x0d, 0x36, 0x0a, 0xda, 0xf2, 0x38, 0x2f, 0x0c, 0x0c, + 0x05, 0x2a, 0xe4, 0xca, 0xfb, 0xd9, 0xfc, 0x05, 0xfc, 0xe1, 0xf7, 0xed, 0xcb, + 0x52, 0xfe, 0x00, 0x7f, 0xd9, 0x39, 0x32, 0xb1, 0x0d, 0xc0, 0x08, 0xfb, 0x16, + 0xb5, 0x10, 0x0e, 0x12, 0x31, 0xdb, 0x43, 0xc8, 0xca, 0xf0, 0xd1, 0xff, 0xf6, + 0x0f, 0xfe, 0x5f, 0xc2, 0x36, 0xe7, 0x0c, 0x1d, 0x15, 0xeb, 0x10, 0xf1, 0xc7, + 0x0a, 0x2b, 0xed, 0xd6, 0x2c, 0xc2, 0x02, 0xd2, 0xfd, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0xc0, 0x32, 0xf7, 0x38, 0xec, 0xf3, 0xe0, + 0x99, 0xc8, 0x0a, 0x05, 0xb2, 0x2f, 0x1c, 0xc9, 0x08, 0xe5, 0x0b, 0x19, 0x05, + 0x12, 0x05, 0x29, 0xcc, 0x12, 0xef, 0xf6, 0x37, 0xe9, 0xc1, 0xe6, 0xf2, 0xef, + 0x28, 0xe8, 0xd4, 0xf8, 0x14, 0xc6, 0x41, 0x23, 0x06, 0x59, 0x26, 0x09, 0xf3, + 0xeb, 0xdc, 0x44, 0xfa, 0xdc, 0xca, 0xd0, 0x12, 0x31, 0x37, 0xe9, 0xf5, 0x0d, + 0x03, 0x07, 0xb4, 0xe7, 0xfe, 0xf1, 0xa4, 0x62, 0xf5, 0x3c, 0x36, 0xf1, 0x27, + 0x06, 0xc6, 0x0f, 0x2c, 0xd8, 0xdd, 0xf9, 0x03, 0x4c, 0x0b, 0xb0, 0xa9, 0x24, + 0xfd, 0x81, 0x31, 0x96, 0xce, 0x63, 0xca, 0x17, 0x58, 0x33, 0x0d, 0x12, 0xca, + 0xc6, 0x48, 0xae, 0xeb, 0x49, 0xe8, 0xe0, 0x43, 0x08, 0x40, 0xb6, 0xc8, 0x8f, + 0x3d, 0x5b, 0xcc, 0xf6, 0x56, 0x63, 0xf5, 0x0a, 0x0d, 0xd9, 0x99, 0xe4, 0x06, + 0xde, 0x24, 0xd3, 0x0d, 0x21, 0x39, 0x2f, 0x81, 0x12, 0x41, 0xaf, 0x0a, 0xf2, + 0xd3, 0xcf, 0xdb, 0x1f, 0x04, 0xf1, 0x04, 0x3c, 0x1a, 0x53, 0x31, 0x16, 0xe9, + 0x1c, 0xe3, 0x26, 0x32, 0xbb, 0xf1, 0x01, 0x01, 0x34, 0xc2, 0x08, 0x12, 0x1b, + 0x67, 0xfb, 0x40, 0xde, 0xc6, 0xdd, 0x6b, 0xc5, 0x0f, 0x01, 0xb9, 0xd6, 0xfa, + 0xf5, 0x28, 0xe4, 0x15, 0xe9, 0x08, 0x35, 0x5f, 0x29, 0xbe, 0xf6, 0x03, 0x02, + 0xaa, 0x3a, 0x06, 0x09, 0xc6, 0x2c, 0xf5, 0xc7, 0x09, 0x25, 0xdf, 0xee, 0x06, + 0x3f, 0x25, 0x08, 0x20, 0xf0, 0xe6, 0x9c, 0xfc, 0xa8, 0xdf, 0x07, 0x48, 0xdd, + 0xad, 0xed, 0xfa, 0x06, 0xe5, 0xd6, 0xb6, 0x27, 0xb8, 0x1c, 0x1f, 0x40, 0x29, + 0xf5, 0x19, 0x14, 0xe8, 0xe5, 0x33, 0x9a, 0x26, 0x0e, 0x47, 0xe2, 0xcf, 0x0c, + 0x00, 0x39, 0xe8, 0x2a, 0x2b, 0x0e, 0xe1, 0x29, 0x66, 0xf5, 0xf9, 0xc3, 0xde, + 0xcf, 0x0f, 0xde, 0xdb, 0xd8, 0x22, 0x10, 0x01, 0xf2, 0xc7, 0xca, 0x10, 0x15, + 0xcf, 0xeb, 0x08, 0xf0, 0xe5, 0x23, 0x0d, 0x20, 0x05, 0x06, 0x31, 0xe7, 0x03, + 0xdd, 0x4e, 0xd5, 0xf8, 0x4c, 0x5e, 0x17, 0x40, 0x7f, 0xca, 0x46, 0xbc, 0xb7, + 0xbe, 0x25, 0x14, 0x1b, 0xc6, 0x08, 0xea, 0x22, 0x98, 0xef, 0xe9, 0x18, 0xd0, + 0xe1, 0x1d, 0x3e, 0xd8, 0x06, 0x18, 0xd8, 0x38, 0xe8, 0xef, 0x36, 0xfa, 0x06, + 0xff, 0x14, 0xe5, 0xae, 0x33, 0x68, 0xdc, 0x00, 0x41, 0xe4, 0x2e, 0x0b, 0x26, + 0x19, 0xfb, 0xfc, 0x27, 0x53, 0xcd, 0xf9, 0x97, 0xdc, 0x21, 0x00, 0xd3, 0x32, + 0xd0, 0x13, 0x33, 0xee, 0x65, 0x48, 0x13, 0x9d, 0x00, 0x19, 0x28, 0xb1, 0x2a, + 0xdd, 0xd5, 0xfa, 0x1c, 0xd2, 0x09, 0xd6, 0x18, 0x28, 0xe4, 0xf3, 0x07, 0x0a, + 0xfa, 0x16, 0x12, 0xfd, 0xd2, 0xcc, 0x15, 0xf7, 0x1a, 0xe9, 0xed, 0xdd, 0xea, + 0x18, 0x03, 0xd8, 0x12, 0x0c, 0x15, 0xf9, 0x00, 0x6a, 0x41, 0xd8, 0xf4, 0xf8, + 0x0c, 0x1a, 0x37, 0x1e, 0x01, 0xf8, 0xd8, 0xe6, 0xf8, 0xe2, 0xdf, 0xb7, 0x09, + 0xe3, 0x3a, 0x08, 0x1b, 0xb3, 0xeb, 0xd0, 0x2b, 0xd8, 0x00, 0xf1, 0x5e, 0x31, + 0xcb, 0xc8, 0x7c, 0xf9, 0x81, 0xd4, 0x2f, 0xfe, 0x97, 0xcc, 0x1c, 0x75, 0xee, + 0xed, 0x4e, 0xf8, 0x14, 0xde, 0x49, 0x02, 0xe0, 0xe3, 0x58, 0xfd, 0xfb, 0xdf, + 0xfb, 0x14, 0x72, 0x19, 0x1f, 0xe8, 0x55, 0xd5, 0x0a, 0x4a, 0xd7, 0xbb, 0x1e, + 0x11, 0xe0, 0xcc, 0xe6, 0xf2, 0x27, 0xc8, 0x15, 0xf0, 0xf4, 0xfd, 0xdd, 0x42, + 0x1b, 0x2f, 0xcb, 0x13, 0xe5, 0xb1, 0x09, 0x1a, 0xcb, 0x23, 0x02, 0xe7, 0xe1, + 0x0b, 0xf2, 0x02, 0xcc, 0xeb, 0x12, 0x20, 0x24, 0xe3, 0xe1, 0xb9, 0xff, 0xbd, + 0x1a, 0x89, 0xfc, 0x1e, 0x38, 0xec, 0x04, 0x1b, 0x22, 0xf8, 0x0e, 0xf4, 0x41, + 0x0d, 0xf9, 0xf5, 0xfe, 0xe3, 0xf4, 0xfa, 0x10, 0x0b, 0xec, 0xc4, 0x24, 0x11, + 0x15, 0x05, 0x26, 0x10, 0xf0, 0xeb, 0x10, 0x04, 0xd4, 0x00, 0x29, 0xf8, 0x14, + 0x11, 0x18, 0xf8, 0x23, 0xe4, 0x10, 0x7f, 0x02, 0x13, 0x3e, 0xf8, 0xfb, 0x2e, + 0xd4, 0x0d, 0xfc, 0xdc, 0xfb, 0x52, 0xe2, 0x1d, 0xfb, 0x05, 0x07, 0xe7, 0xed, + 0x24, 0xff, 0xf0, 0xd9, 0xe4, 0xf8, 0x3b, 0x46, 0x05, 0xec, 0xea, 0xd7, 0x0b, + 0xec, 0x08, 0xf1, 0x3a, 0x22, 0xfa, 0xe5, 0x06, 0xfb, 0xf8, 0x12, 0x11, 0xee, + 0x0d, 0xee, 0xea, 0x0b, 0xf0, 0xed, 0x12, 0xe6, 0xe0, 0x05, 0xe2, 0xf6, 0x07, + 0xe2, 0xd9, 0x05, 0xe6, 0xf2, 0x3e, 0x02, 0xce, 0x19, 0x02, 0x31, 0xfe, 0xda, + 0xfa, 0x3b, 0x19, 0xf6, 0x04, 0x07, 0x14, 0xfc, 0x52, 0xf6, 0xf9, 0x2f, 0x16, + 0x0b, 0x15, 0x04, 0x1d, 0xf3, 0xdf, 0x29, 0xbf, 0xeb, 0xf2, 0xae, 0x12, 0xe3, + 0x2a, 0x0a, 0xe1, 0xcc, 0x13, 0x34, 0x0d, 0xf1, 0xe2, 0x2e, 0xcb, 0x00, 0x1a, + 0x24, 0x0c, 0xe0, 0x08, 0x0a, 0xeb, 0xed, 0x2a, 0x0b, 0x26, 0x07, 0x27, 0xf3, + 0xee, 0xf2, 0x09, 0xf3, 0x19, 0xc8, 0x27, 0x26, 0xef, 0xef, 0xcb, 0x08, 0x25, + 0xf2, 0xdb, 0xc4, 0x05, 0xd8, 0xf5, 0x09, 0xde, 0x07, 0xe2, 0xe3, 0x11, 0xbe, + 0xce, 0xc1, 0xa0, 0x58, 0x0b, 0x09, 0x35, 0xf1, 0x81, 0xed, 0xe2, 0x2e, 0x07, + 0x34, 0xd0, 0xe5, 0x20, 0x1a, 0x01, 0x0e, 0x41, 0xd6, 0xea, 0x26, 0x3c, 0xf8, + 0xd3, 0x12, 0x1e, 0x02, 0x4e, 0x02, 0x01, 0xe0, 0x0e, 0x05, 0xfc, 0x0c, 0x07, + 0x27, 0xd9, 0x00, 0x08, 0x11, 0xfe, 0xe1, 0x11, 0xf1, 0x16, 0xe6, 0x04, 0x05, + 0xf3, 0x51, 0x3e, 0xeb, 0xfa, 0xd5, 0x0e, 0xd7, 0x00, 0xfe, 0xfa, 0xd7, 0xe9, + 0x42, 0x03, 0xdf, 0x04, 0xe6, 0x16, 0xfa, 0xb6, 0x06, 0x06, 0xd6, 0xf8, 0xa2, + 0xce, 0x2c, 0xfb, 0xb7, 0x1c, 0xef, 0xe4, 0x1e, 0x33, 0xf7, 0xa9, 0x03, 0x60, + 0x2e, 0x5e, 0x1d, 0x08, 0x28, 0x44, 0xdd, 0xf3, 0xfd, 0xd1, 0x0b, 0xbd, 0xed, + 0xfc, 0x31, 0x26, 0x20, 0x52, 0xe7, 0x07, 0xa3, 0x12, 0xfe, 0x5c, 0x01, 0xbc, + 0xd8, 0x2f, 0xfd, 0x0e, 0xc9, 0xdc, 0x28, 0xfd, 0xf1, 0xd0, 0x10, 0xa2, 0xd0, + 0x0c, 0xda, 0x0d, 0xc9, 0xea, 0x02, 0x14, 0xc6, 0xed, 0xde, 0xde, 0xc1, 0xc9, + 0xcd, 0xe2, 0xd1, 0xf6, 0xd4, 0x38, 0x08, 0x20, 0xf3, 0xb5, 0xf8, 0xbb, 0x17, + 0xc0, 0x1d, 0xd3, 0x26, 0x3f, 0xe0, 0xfc, 0x9c, 0x15, 0xec, 0x3f, 0xdf, 0x3b, + 0xd9, 0x1b, 0x56, 0x9f, 0x35, 0xfd, 0xdc, 0x18, 0xfc, 0x9e, 0xe7, 0x29, 0x01, + 0x23, 0xb7, 0xf8, 0xf0, 0x54, 0xe4, 0x05, 0x00, 0x7f, 0xd9, 0xf7, 0x5b, 0xdf, + 0x13, 0xbf, 0xe5, 0xed, 0xe6, 0xff, 0x30, 0x16, 0x5f, 0x2f, 0xde, 0x5e, 0x08, + 0x28, 0xbd, 0x1e, 0x09, 0x53, 0xb5, 0x32, 0xf6, 0xd1, 0xe2, 0x04, 0xd7, 0x64, + 0xfb, 0xe2, 0xf9, 0xfc, 0x50, 0x1a, 0x23, 0xc1, 0x09, 0x31, 0x15, 0x50, 0x29, + 0xf9, 0x38, 0xe8, 0xbe, 0x7c, 0xbc, 0xe8, 0x3c, 0x2a, 0xdb, 0x09, 0xe2, 0xd5, + 0x3a, 0x52, 0x3d, 0xb6, 0xda, 0xdd, 0x22, 0xfc, 0xfc, 0xec, 0xed, 0x40, 0xd8, + 0x17, 0xae, 0xef, 0xf6, 0xdb, 0xe6, 0x7f, 0xfa, 0x16, 0x09, 0x11, 0x04, 0xfc, + 0x22, 0xbc, 0xde, 0x4d, 0xf9, 0x15, 0x52, 0xf9, 0x0b, 0xf4, 0x38, 0x23, 0xfb, + 0xa7, 0x29, 0xde, 0x2e, 0x34, 0x0c, 0x45, 0xff, 0x2a, 0x05, 0xb8, 0xed, 0xf9, + 0x22, 0x9d, 0x02, 0x36, 0x02, 0xd6, 0xad, 0x17, 0xe0, 0x2e, 0x38, 0x7e, 0x09, + 0x1b, 0xd4, 0x41, 0xfd, 0xe5, 0x0d, 0x2c, 0xe6, 0x0b, 0xf7, 0x00, 0xb3, 0x0e, + 0xff, 0xae, 0x21, 0xad, 0xd4, 0x28, 0xc1, 0x16, 0x48, 0x75, 0x01, 0xfe, 0xe6, + 0x49, 0xf0, 0xad, 0xcf, 0xd6, 0x02, 0xee, 0xdb, 0x16, 0xa4, 0xbc, 0x01, 0xe2, + 0x22, 0x17, 0xf1, 0x0e, 0xf2, 0xdb, 0xe1, 0xe2, 0x44, 0xe4, 0x19, 0xe6, 0x2f, + 0xe2, 0xf1, 0x2e, 0x36, 0x06, 0xa8, 0x2d, 0x22, 0xef, 0xeb, 0xd4, 0x69, 0x35, + 0xc1, 0x09, 0xd4, 0xc6, 0xc3, 0xd4, 0x7f, 0x37, 0xdf, 0xd5, 0xff, 0xf1, 0x89, + 0x22, 0x49, 0xba, 0x29, 0x28, 0x09, 0x0e, 0x48, 0x00, 0xec, 0xf1, 0x08, 0xeb, + 0x32, 0xe3, 0xf4, 0x04, 0xff, 0x24, 0xff, 0x70, 0xe0, 0xea, 0x17, 0xf2, 0x22, + 0xa5, 0x0a, 0x2b, 0x02, 0x06, 0x10, 0x18, 0x0a, 0x5d, 0xef, 0x58, 0x0a, 0xd2, + 0xe3, 0xa7, 0x24, 0x5f, 0x18, 0xd3, 0x16, 0x08, 0x36, 0xd9, 0xf5, 0x0c, 0xde, + 0xbd, 0xf5, 0x0e, 0xe0, 0xae, 0x21, 0x22, 0x6e, 0x24, 0xf9, 0xdd, 0x09, 0x29, + 0x5b, 0x0f, 0xdb, 0x1a, 0xa7, 0xd8, 0x13, 0xfa, 0xf1, 0x38, 0xef, 0x1b, 0x18, + 0x37, 0x11, 0x05, 0xf5, 0x13, 0x21, 0x30, 0x11, 0xcb, 0xe5, 0xf0, 0xdd, 0xf3, + 0x09, 0x08, 0x34, 0xfa, 0xee, 0xfe, 0x0f, 0x00, 0x7f, 0xed, 0x1b, 0x98, 0xce, + 0xcd, 0xc5, 0xec, 0x23, 0xf2, 0xe0, 0xe0, 0xdb, 0xea, 0xd0, 0xf7, 0xeb, 0x1d, + 0xd2, 0x47, 0x24, 0xfe, 0x13, 0xd1, 0xfd, 0xd3, 0x31, 0xc4, 0xd9, 0x28, 0x2d, + 0x1f, 0xe8, 0x1f, 0xfe, 0xe2, 0x06, 0xcf, 0xea, 0x1b, 0xc5, 0xed, 0xe3, 0xc0, + 0x1f, 0xe8, 0x04, 0xf5, 0xde, 0xda, 0xcc, 0x03, 0x1b, 0xf8, 0x15, 0x14, 0x09, + 0xf0, 0xcb, 0xbe, 0xfb, 0xc8, 0xef, 0x0e, 0xfa, 0x1b, 0x34, 0xe1, 0x14, 0x0d, + 0xfd, 0x0c, 0x07, 0xe9, 0x52, 0xb1, 0xec, 0xf6, 0xe7, 0xcc, 0xf1, 0xb4, 0xed, + 0xdc, 0xe7, 0xd9, 0x2a, 0x14, 0xec, 0xf5, 0x0c, 0xbf, 0xef, 0xf8, 0xd6, 0xb0, + 0x46, 0xda, 0xee, 0xd9, 0x11, 0x2b, 0x48, 0x2b, 0xd3, 0xc9, 0xcd, 0x0e, 0xa7, + 0x08, 0x05, 0xe4, 0x30, 0x14, 0xcc, 0xf0, 0x61, 0x16, 0xfb, 0x87, 0x01, 0x1e, + 0x68, 0x0b, 0x38, 0xe7, 0xad, 0x0e, 0x27, 0xe1, 0xc8, 0x37, 0xe3, 0x32, 0x46, + 0xf6, 0xdd, 0x32, 0xcd, 0xbd, 0xfd, 0xd4, 0xc7, 0x0b, 0xff, 0x19, 0xb9, 0xf6, + 0x53, 0x1b, 0xf1, 0xda, 0xfb, 0xa9, 0x17, 0xce, 0x35, 0x27, 0x2f, 0xa7, 0x33, + 0xf6, 0x0c, 0x0c, 0xec, 0xcb, 0xd3, 0x22, 0xe7, 0x81, 0x2a, 0x01, 0xd6, 0x29, + 0xf6, 0xf9, 0x0d, 0xfc, 0xf5, 0xc8, 0xf0, 0x07, 0xf9, 0xdd, 0x12, 0xd4, 0x33, + 0xfc, 0x1c, 0xfc, 0xcc, 0xcb, 0xa5, 0xfa, 0x64, 0xdd, 0x44, 0xe2, 0xfc, 0xf2, + 0xd4, 0x31, 0x66, 0x05, 0x2c, 0xe2, 0x1f, 0xd4, 0x49, 0xd8, 0xf7, 0xad, 0x4c, + 0xf2, 0xe2, 0x06, 0x1a, 0x00, 0x22, 0x21, 0x10, 0xa9, 0xec, 0xdd, 0xe4, 0x11, + 0x09, 0xf2, 0xf4, 0xf3, 0xcb, 0x26, 0x55, 0xf9, 0xdd, 0xd8, 0x23, 0x2a, 0x33, + 0x2c, 0x04, 0x17, 0xb4, 0xb8, 0x0e, 0xcc, 0xf4, 0x37, 0x2f, 0xe5, 0x40, 0x04, + 0x07, 0xe3, 0x0d, 0x18, 0x17, 0x0d, 0x18, 0x39, 0x2d, 0xd8, 0xf1, 0xb5, 0xea, + 0x1a, 0xfc, 0xd3, 0xe2, 0x00, 0x13, 0xf2, 0xc5, 0xe2, 0xe6, 0xae, 0xd6, 0x13, + 0xdf, 0xc0, 0xb2, 0xd2, 0x00, 0x39, 0x09, 0x27, 0xfb, 0x81, 0x01, 0xde, 0x2b, + 0xfe, 0x33, 0x39, 0xfb, 0xfe, 0xfe, 0xf1, 0x06, 0xc3, 0xe4, 0x00, 0xd3, 0xc6, + 0x1f, 0x4b, 0x0e, 0xaf, 0x03, 0x36, 0xe7, 0xdd, 0xe4, 0xfd, 0xc8, 0xf4, 0xcb, + 0x1a, 0xf4, 0x0f, 0x03, 0x2f, 0xe5, 0xcd, 0x30, 0xbc, 0x2a, 0x2a, 0xf0, 0xfb, + 0xd7, 0x4c, 0x30, 0xdf, 0xcc, 0xcb, 0xe8, 0xe4, 0xf9, 0x07, 0x17, 0xf2, 0x02, + 0xc6, 0xf2, 0x39, 0x37, 0xfa, 0x21, 0xe5, 0xe6, 0x1d, 0xfe, 0xfc, 0x31, 0xef, + 0xd0, 0x19, 0x28, 0x0e, 0x4e, 0x1d, 0x1b, 0x46, 0xef, 0xef, 0x40, 0xd7, 0xf9, + 0x05, 0x15, 0x16, 0xf4, 0x01, 0x15, 0xa0, 0x04, 0x06, 0xaf, 0xc8, 0xe0, 0x08, + 0x00, 0xd5, 0x0d, 0x35, 0x03, 0x15, 0xdd, 0xdc, 0xe6, 0x33, 0xa0, 0xe6, 0xdf, + 0x37, 0xc6, 0x25, 0xdb, 0xde, 0xff, 0xfe, 0xfc, 0xc1, 0x24, 0x03, 0x5e, 0xe5, + 0xd7, 0xc7, 0xb2, 0xdc, 0x9c, 0x30, 0x12, 0xe9, 0xef, 0xde, 0x30, 0x11, 0xfb, + 0xff, 0xd7, 0x26, 0xfa, 0xd2, 0x52, 0x25, 0xe4, 0x24, 0x31, 0x1c, 0xf9, 0x14, + 0xec, 0x98, 0x1c, 0xeb, 0x20, 0xc5, 0xed, 0x81, 0xed, 0x08, 0xf7, 0x85, 0x0b, + 0xee, 0xb2, 0xf6, 0x1a, 0xf1, 0x04, 0x11, 0xcf, 0xea, 0xe9, 0x02, 0xf1, 0x01, + 0x29, 0x4d, 0xc9, 0xf6, 0x57, 0xdf, 0xc6, 0x3c, 0x39, 0x1c, 0xee, 0x04, 0xbd, + 0x43, 0xe5, 0xc8, 0xec, 0x03, 0xb5, 0xd1, 0x4a, 0x01, 0x51, 0x02, 0xe1, 0xb6, + 0xfb, 0x03, 0xfa, 0xde, 0xae, 0xa2, 0xff, 0xda, 0x01, 0xf5, 0xfa, 0xf1, 0x21, + 0x55, 0x28, 0x05, 0xf1, 0xe7, 0x20, 0x06, 0x15, 0x12, 0xf3, 0xe6, 0xf7, 0x6b, + 0x22, 0xfb, 0xf1, 0xef, 0x4e, 0x64, 0x28, 0x1f, 0x81, 0xc2, 0xfe, 0xbc, 0x1c, + 0xce, 0xac, 0x14, 0x99, 0x13, 0x0f, 0xd6, 0x07, 0x08, 0x1d, 0x30, 0x2c, 0xfd, + 0x1e, 0x0e, 0xda, 0xcc, 0xdc, 0xcf, 0x0d, 0xbf, 0xf7, 0x25, 0xaf, 0x3e, 0xad, + 0xe0, 0x01, 0x26, 0x0c, 0xae, 0x1f, 0x04, 0xf3, 0xbe, 0xf4, 0xc8, 0x4e, 0x02, + 0xcb, 0xf7, 0xec, 0xbb, 0x18, 0x3a, 0x44, 0xe1, 0xea, 0x05, 0xf7, 0x6f, 0x2a, + 0xa5, 0x3c, 0xf1, 0xfd, 0x7c, 0x22, 0xfa, 0xed, 0x23, 0xce, 0x0e, 0xd8, 0xee, + 0x29, 0x0f, 0xfc, 0x2d, 0x14, 0xd4, 0xe8, 0xed, 0xe6, 0xfb, 0x0d, 0xf4, 0xf9, + 0xff, 0xfc, 0x0a, 0xef, 0x2e, 0x14, 0x19, 0xe9, 0xbe, 0x7e, 0x30, 0x25, 0x6f, + 0x22, 0xd2, 0x11, 0xee, 0x10, 0xbe, 0xec, 0xdf, 0xa4, 0x28, 0xe3, 0xd0, 0xfe, + 0xe0, 0x07, 0x1d, 0x18, 0x91, 0x20, 0xf4, 0xac, 0x06, 0x0d, 0x36, 0x3f, 0x0b, + 0x15, 0x03, 0xb7, 0xce, 0x14, 0xec, 0x0f, 0xe1, 0xe1, 0x14, 0xaa, 0xda, 0x0e, + 0xeb, 0x0b, 0x06, 0xe8, 0x2b, 0x34, 0x0d, 0x2c, 0x38, 0x27, 0xb9, 0x70, 0x1d, + 0xfe, 0x4e, 0xf8, 0x16, 0x3a, 0x07, 0x4c, 0x27, 0x10, 0x45, 0xe2, 0xd9, 0x4b, + 0xec, 0xab, 0xa2, 0x02, 0xcb, 0x5d, 0xe2, 0x4d, 0x5b, 0x94, 0xf1, 0x6c, 0x20, + 0xc9, 0x00, 0xf6, 0x03, 0xfa, 0xef, 0x3a, 0x06, 0xe9, 0x30, 0xed, 0x11, 0xdd, + 0xdb, 0x15, 0xc3, 0x08, 0x4f, 0x59, 0x8e, 0xaf, 0x30, 0x29, 0x81, 0xdf, 0xe9, + 0xe6, 0xdb, 0xf8, 0x38, 0x40, 0x99, 0x5d, 0xeb, 0xc9, 0x0a, 0x17, 0x51, 0xc8, + 0x1b, 0xfb, 0x0a, 0xc1, 0xf0, 0x28, 0xf7, 0xa2, 0xf0, 0xc9, 0x34, 0xe6, 0xc0, + 0x8a, 0xf9, 0x06, 0x3c, 0xe3, 0xb9, 0xf7, 0x09, 0xec, 0xcd, 0x39, 0xd8, 0x03, + 0xc3, 0xf6, 0x0c, 0xe1, 0x04, 0xa2, 0x12, 0xc3, 0xe9, 0xd3, 0x05, 0x7f, 0x55, + 0xd0, 0xdb, 0x5c, 0x15, 0xef, 0xfc, 0x16, 0xcf, 0xc8, 0xd5, 0x1f, 0xfe, 0x5f, + 0x02, 0x51, 0x0c, 0x22, 0xff, 0xd7, 0x2c, 0xeb, 0x34, 0x19, 0x51, 0xfc, 0xe5, + 0xed, 0x37, 0xfd, 0xc5, 0x1c, 0xde, 0xd3, 0xf0, 0xd4, 0xf1, 0x07, 0xee, 0x3c, + 0xf2, 0xdc, 0xf0, 0xe3, 0x0f, 0x06, 0x32, 0x6d, 0xef, 0xc5, 0xe4, 0xda, 0x96, + 0xfe, 0xe1, 0x56, 0x00, 0xda, 0xf0, 0x2f, 0xd4, 0xe6, 0xe2, 0x15, 0xee, 0xfc, + 0xec, 0x3c, 0x25, 0xed, 0x2e, 0xcc, 0xd5, 0xe9, 0x91, 0xf8, 0xff, 0xf1, 0x59, + 0xd8, 0x0e, 0xe4, 0x18, 0xd1, 0xb6, 0x42, 0xef, 0x06, 0x02, 0x02, 0xce, 0xe3, + 0xf9, 0xe9, 0xd7, 0xe3, 0xfb, 0xd1, 0x2d, 0xf3, 0x17, 0xd5, 0x37, 0xd5, 0x2b, + 0xf4, 0xc7, 0x00, 0x1a, 0x2e, 0xff, 0xff, 0x0e, 0xce, 0x15, 0x00, 0x19, 0x2f, + 0x12, 0xf9, 0x25, 0x4a, 0xd3, 0xd6, 0xed, 0xa9, 0xe0, 0xd6, 0xff, 0x33, 0xfb, + 0x51, 0x0b, 0xe5, 0x4f, 0xda, 0x39, 0x42, 0xb4, 0x34, 0xee, 0xd2, 0x20, 0xf9, + 0x50, 0xd9, 0xff, 0xf2, 0x77, 0x12, 0xf6, 0x66, 0x1e, 0xe0, 0xb9, 0xfb, 0xb7, + 0x2a, 0xec, 0x03, 0x24, 0xdc, 0xed, 0xfa, 0xf4, 0xd2, 0xd6, 0xd6, 0xec, 0xfb, + 0xf9, 0x27, 0x54, 0xd9, 0x43, 0x0f, 0xfb, 0xfa, 0x01, 0xcf, 0xf1, 0x03, 0x0b, + 0x3b, 0xcd, 0x56, 0x14, 0x29, 0x00, 0xb6, 0x01, 0x48, 0xf9, 0xf8, 0x02, 0xf4, + 0x44, 0x7f, 0xf1, 0x1c, 0xeb, 0xac, 0x18, 0x14, 0xd0, 0x12, 0xef, 0x22, 0xf1, + 0x04, 0x09, 0xf4, 0xfa, 0xc2, 0x54, 0xdf, 0x31, 0xe1, 0x0a, 0xf3, 0xaf, 0x18, + 0x06, 0x36, 0xd8, 0x2d, 0x14, 0xbe, 0xe9, 0xe6, 0xe4, 0xfb, 0x0f, 0x2c, 0x18, + 0x01, 0x33, 0xf8, 0xeb, 0xed, 0xb8, 0xf0, 0x05, 0x05, 0xd7, 0xe3, 0xf5, 0xf6, + 0x09, 0x13, 0x0e, 0x02, 0xfb, 0xff, 0xe4, 0x08, 0x17, 0xf9, 0x1f, 0x13, 0xe6, + 0xf3, 0x7f, 0x0c, 0xae, 0xe5, 0x07, 0xf4, 0x27, 0x25, 0x45, 0x08, 0xc0, 0xa9, + 0x0f, 0x12, 0x2b, 0xe5, 0x6f, 0x26, 0x28, 0xe0, 0x1f, 0xee, 0x39, 0xeb, 0x32, + 0x0a, 0x12, 0x28, 0x16, 0x05, 0xe9, 0xe8, 0x16, 0xe9, 0x0a, 0xfc, 0x22, 0xe9, + 0x06, 0x00, 0x3d, 0x1a, 0x2b, 0x16, 0xaa, 0x0f, 0xfe, 0x01, 0x11, 0xda, 0x2b, + 0xea, 0xf3, 0xc7, 0x37, 0xea, 0xd7, 0xef, 0x2a, 0xd1, 0x26, 0x3b, 0xfa, 0xbe, + 0x04, 0xc3, 0xd5, 0xe6, 0x65, 0x4b, 0x0c, 0xfc, 0x1e, 0x32, 0x1c, 0x47, 0xe8, + 0x19, 0x05, 0xd9, 0x0e, 0xe7, 0xfc, 0xff, 0xb6, 0xe4, 0x1f, 0x15, 0x3a, 0x0d, + 0xbf, 0x07, 0xf1, 0x74, 0xef, 0x81, 0xe6, 0x38, 0x23, 0xe5, 0x24, 0xcc, 0x11, + 0x38, 0xec, 0x3d, 0xd1, 0x02, 0xdc, 0xd2, 0x0c, 0x14, 0x17, 0xff, 0xfc, 0xe7, + 0x13, 0xe1, 0x0a, 0xed, 0x28, 0x23, 0x14, 0xe5, 0x5d, 0xdd, 0x02, 0x46, 0xe0, + 0xe2, 0x2d, 0xf6, 0xfe, 0xc9, 0x0a, 0xc4, 0xe9, 0xba, 0xb2, 0x27, 0xc7, 0xfc, + 0x45, 0xc4, 0x92, 0xd0, 0xaf, 0x0e, 0xc3, 0x1a, 0xfd, 0xfa, 0x00, 0xc8, 0xfa, + 0xb0, 0xfb, 0x10, 0xd9, 0x23, 0x2a, 0xe2, 0x2c, 0x50, 0xf9, 0x2a, 0xe1, 0xf9, + 0x1a, 0xd0, 0xe5, 0xe2, 0xfe, 0xe9, 0x3e, 0x13, 0x28, 0xee, 0xe1, 0x29, 0xff, + 0xc2, 0x0d, 0xe7, 0x21, 0x47, 0xe5, 0x51, 0x0a, 0xdb, 0x8c, 0xef, 0x0e, 0x2c, + 0xf1, 0xeb, 0x15, 0x0e, 0xf2, 0x0f, 0xfa, 0xdd, 0xaf, 0x23, 0x33, 0xf0, 0x10, + 0x3d, 0x16, 0x0b, 0xff, 0x46, 0xdb, 0xe7, 0x12, 0xa4, 0x17, 0x1e, 0xbf, 0xdc, + 0x20, 0x12, 0xea, 0x1c, 0x19, 0x5d, 0x71, 0x32, 0xe2, 0xfe, 0x01, 0x35, 0x3b, + 0xf8, 0x8e, 0xfe, 0x3e, 0x4b, 0xd2, 0xfb, 0xcc, 0xd9, 0xc9, 0xf2, 0xf5, 0x04, + 0x30, 0x22, 0xe0, 0xf2, 0xc0, 0x05, 0x05, 0xd5, 0xee, 0x40, 0xa6, 0x91, 0x40, + 0x58, 0x20, 0xce, 0xa8, 0xd6, 0x61, 0xec, 0x1b, 0xec, 0xf3, 0x42, 0xb1, 0xfd, + 0xd9, 0xc3, 0x92, 0xd6, 0xcf, 0x1f, 0xfc, 0xd8, 0x59, 0x23, 0x0b, 0xc2, 0xf1, + 0x55, 0x05, 0xf0, 0x27, 0x32, 0x49, 0x62, 0x06, 0x26, 0x0d, 0xfc, 0xe0, 0xcf, + 0x1f, 0xcd, 0x81, 0xc1, 0x05, 0xeb, 0x15, 0xce, 0x54, 0x10, 0xd3, 0x57, 0xd4, + 0xf4, 0x29, 0x10, 0xe5, 0x2c, 0x3f, 0xf4, 0xa6, 0xf5, 0xed, 0x06, 0xf5, 0x0d, + 0xcc, 0xff, 0x2b, 0x0a, 0xe5, 0xe3, 0x0c, 0xe2, 0x28, 0x50, 0x22, 0x18, 0xe0, + 0x0b, 0xbf, 0x0d, 0x0e, 0xec, 0xdf, 0xf9, 0x10, 0xf6, 0x1c, 0x0a, 0xf3, 0x17, + 0xe9, 0xd2, 0x3c, 0x1c, 0x16, 0x06, 0xe7, 0x38, 0xd0, 0xed, 0x05, 0x1c, 0xc5, + 0xf8, 0xec, 0x10, 0xf7, 0xc1, 0xda, 0x1b, 0xda, 0x0d, 0xf5, 0xe3, 0x15, 0xf8, + 0xea, 0xdb, 0xd4, 0x21, 0x07, 0x10, 0x19, 0x45, 0x66, 0xd1, 0x15, 0x09, 0x1f, + 0xec, 0x19, 0xd6, 0x18, 0x0a, 0xe3, 0xee, 0xf5, 0xf9, 0xfb, 0xdd, 0x01, 0xec, + 0x33, 0xfe, 0xed, 0xd3, 0xe0, 0xf0, 0x78, 0x07, 0xe9, 0xf8, 0xc9, 0x7f, 0x2d, + 0xbe, 0xf5, 0xf0, 0x10, 0x23, 0x20, 0x08, 0xea, 0xe9, 0xb3, 0xe7, 0x0d, 0xea, + 0x2f, 0xef, 0x1d, 0xfd, 0xff, 0x01, 0x0a, 0x1c, 0x09, 0xd7, 0x0f, 0xf9, 0x00, + 0xed, 0xd0, 0xf6, 0xd4, 0xdc, 0x1b, 0x0a, 0xe9, 0x38, 0x06, 0xed, 0x32, 0xf8, + 0xee, 0x15, 0xe1, 0x13, 0x1c, 0x13, 0x0b, 0xbb, 0x21, 0x05, 0x0b, 0xcb, 0xfe, + 0xf3, 0xdb, 0xf7, 0xf5, 0xd7, 0x25, 0xfb, 0xd1, 0x07, 0x00, 0xa8, 0x12, 0x1f, + 0x0b, 0xd3, 0x41, 0x17, 0xe7, 0xfe, 0xea, 0x14, 0xfc, 0xf3, 0x45, 0xf8, 0xcd, + 0x09, 0x5b, 0xc9, 0xdb, 0x9e, 0xfd, 0x2c, 0x10, 0x04, 0x27, 0x4c, 0x08, 0x0a, + 0xb6, 0xe8, 0xc1, 0xda, 0x03, 0xaa, 0x7f, 0xfc, 0xde, 0xc1, 0x2d, 0xd9, 0x13, + 0xe6, 0x18, 0x05, 0xe8, 0xee, 0xfc, 0x4c, 0xcf, 0xe4, 0x1d, 0xcd, 0xbd, 0xaf, + 0x04, 0xda, 0xf5, 0xcc, 0xfa, 0x1e, 0xea, 0xdf, 0xb7, 0x03, 0x43, 0xfb, 0xf7, + 0x42, 0x53, 0xac, 0x09, 0x02, 0x41, 0x42, 0x04, 0x05, 0x26, 0x82, 0x98, 0xe7, + 0x2e, 0x28, 0x16, 0x01, 0x43, 0xe0, 0xd4, 0x34, 0xf2, 0xd9, 0x20, 0x60, 0x00, + 0x15, 0x1f, 0x27, 0xa9, 0x33, 0xcb, 0x08, 0x19, 0xde, 0xaf, 0x21, 0x24, 0x06, + 0xec, 0xfc, 0x05, 0x1b, 0xcf, 0xe4, 0x3d, 0x22, 0xec, 0xfa, 0xd6, 0x0b, 0xf6, + 0x15, 0xf8, 0xf4, 0x05, 0xec, 0xe9, 0x32, 0xe3, 0x19, 0x30, 0x29, 0xf8, 0x15, + 0xf4, 0xeb, 0xae, 0x4d, 0x15, 0x32, 0xf8, 0xf9, 0xe5, 0x19, 0x08, 0x2f, 0xe1, + 0x31, 0xf9, 0x17, 0xbf, 0xee, 0x11, 0x14, 0xb6, 0x08, 0x08, 0xf2, 0xd4, 0x17, + 0xfb, 0x2e, 0x7f, 0x09, 0xea, 0xdf, 0xf9, 0xff, 0x0e, 0xef, 0xbc, 0xe3, 0xc4, + 0x37, 0xf9, 0xcf, 0xca, 0x03, 0xcf, 0x06, 0x2c, 0xc0, 0x16, 0xd6, 0xc9, 0x0e, + 0xe5, 0x3c, 0x02, 0x5e, 0x02, 0x19, 0x33, 0x1c, 0x02, 0xf0, 0xf0, 0xf4, 0x03, + 0x0a, 0x6b, 0x1f, 0xf9, 0xfa, 0x06, 0xe6, 0x11, 0x10, 0x0d, 0xde, 0x22, 0x10, + 0xb5, 0x26, 0xf7, 0xfa, 0xfd, 0x16, 0x7b, 0xc1, 0xf8, 0x1c, 0x10, 0x0e, 0xf4, + 0xfb, 0xf8, 0x0b, 0xfa, 0xf9, 0x0a, 0x45, 0xcb, 0xff, 0x14, 0x42, 0xf6, 0xec, + 0xdb, 0x54, 0x09, 0x1b, 0x35, 0xd1, 0x62, 0xdf, 0xdd, 0xb4, 0x2a, 0x0b, 0x41, + 0x19, 0x2c, 0xde, 0xf1, 0xf6, 0xd6, 0x5f, 0xc0, 0xd8, 0x49, 0xeb, 0xe6, 0x2e, + 0x0b, 0xff, 0x57, 0x26, 0x3e, 0x0f, 0xfd, 0x21, 0xe0, 0x1e, 0xc9, 0x93, 0x7f, + 0x18, 0xfd, 0xe8, 0x1c, 0x23, 0x1f, 0x51, 0x17, 0xc5, 0xf1, 0x16, 0x03, 0x24, + 0xf6, 0xfa, 0x1d, 0xf1, 0xea, 0xf7, 0x38, 0x00, 0xfc, 0xc0, 0xe7, 0xfb, 0x10, + 0x11, 0xe2, 0x01, 0xe5, 0xb7, 0xfe, 0x23, 0xc7, 0x0f, 0x35, 0x0f, 0x63, 0x05, + 0x31, 0x04, 0x0d, 0xd9, 0x06, 0xdc, 0x16, 0x09, 0x36, 0x11, 0x01, 0x00, 0x3d, + 0x15, 0x11, 0xdf, 0xef, 0xd1, 0xf1, 0xf5, 0x04, 0x28, 0xd4, 0x14, 0xe5, 0x0d, + 0xd7, 0x14, 0x47, 0xfb, 0xf8, 0xd4, 0xf7, 0x39, 0x05, 0x14, 0x26, 0x19, 0x1d, + 0xff, 0x09, 0x0e, 0x02, 0xfd, 0xf9, 0xc3, 0x6f, 0xcf, 0xf7, 0x50, 0x00, 0x3d, + 0x1e, 0xed, 0x11, 0xeb, 0x31, 0x03, 0x1e, 0xf8, 0xc3, 0xe9, 0x37, 0xa6, 0x2a, + 0x81, 0xfd, 0x11, 0x1e, 0xa5, 0xbd, 0xe6, 0x06, 0xe2, 0xb9, 0x0f, 0x24, 0xf2, + 0x13, 0xca, 0xb1, 0xc8, 0x17, 0xa2, 0xc3, 0xe1, 0x30, 0xe6, 0x1c, 0x13, 0x14, + 0xf8, 0x1e, 0x25, 0x1f, 0xd6, 0x3c, 0x02, 0x04, 0x44, 0xea, 0x22, 0x22, 0xd2, + 0xee, 0xe8, 0xfa, 0x56, 0x4f, 0x6b, 0xfb, 0xf3, 0x09, 0x9a, 0xdb, 0x23, 0x02, + 0xcb, 0xc3, 0x1d, 0xd4, 0x1c, 0x02, 0xfa, 0x0a, 0xff, 0x13, 0xe8, 0x29, 0x04, + 0x1c, 0x48, 0xe8, 0x35, 0x18, 0x28, 0xfa, 0x16, 0xed, 0xeb, 0x05, 0xa0, 0xca, + 0x11, 0x4a, 0xe1, 0x25, 0xd9, 0x04, 0x10, 0x00, 0x15, 0x3c, 0x1e, 0x14, 0xc0, + 0x3a, 0x15, 0x3e, 0x1c, 0xf4, 0x0e, 0x26, 0xbe, 0x23, 0xff, 0x07, 0x24, 0xd6, + 0xee, 0xf1, 0xdf, 0x2c, 0x07, 0xe0, 0xcd, 0xee, 0x0e, 0xec, 0x02, 0xdf, 0x28, + 0xff, 0xc2, 0x20, 0x2b, 0xcc, 0x1e, 0xdd, 0xfe, 0xf3, 0x4e, 0x07, 0x1b, 0x1a, + 0xea, 0x44, 0x16, 0xc7, 0xff, 0x3c, 0xb6, 0xf4, 0xef, 0x58, 0xe0, 0xdc, 0x36, + 0x15, 0xcb, 0xfd, 0x63, 0x08, 0x04, 0x68, 0xd9, 0x94, 0xb1, 0xee, 0x49, 0xf6, + 0xb5, 0xf1, 0x28, 0xfc, 0x37, 0x84, 0x07, 0x35, 0xdd, 0x14, 0x23, 0x06, 0xff, + 0x30, 0x22, 0x48, 0xb8, 0x41, 0x0f, 0x15, 0x18, 0xef, 0xbe, 0xa2, 0xa5, 0x7d, + 0xec, 0xb9, 0xf5, 0xdd, 0x72, 0xfc, 0x06, 0x01, 0x1b, 0xda, 0xc3, 0xdb, 0x15, + 0x0b, 0x04, 0xd1, 0x05, 0xe9, 0xe2, 0xd5, 0x4a, 0xe9, 0x56, 0x47, 0x25, 0xd3, + 0x7b, 0x15, 0xf5, 0xf2, 0x32, 0x07, 0xe9, 0x7f, 0x57, 0xd5, 0x29, 0xf7, 0x45, + 0x1a, 0x17, 0x00, 0x14, 0xae, 0xd3, 0x0c, 0x19, 0x10, 0x3d, 0xdf, 0xf7, 0x15, + 0xe2, 0x0f, 0xf5, 0x02, 0xe4, 0xb3, 0xf1, 0xe4, 0xb1, 0xd7, 0x2c, 0x09, 0x38, + 0x01, 0x15, 0xfc, 0xcb, 0x06, 0x08, 0x08, 0xee, 0x1b, 0xd9, 0xb7, 0x10, 0xfc, + 0x4f, 0xc0, 0xe1, 0x1a, 0x5f, 0xad, 0x52, 0x42, 0xe8, 0xdf, 0xd8, 0xcc, 0x7f, + 0x5a, 0x3e, 0x2e, 0x14, 0x3d, 0xfd, 0x38, 0xd1, 0xd9, 0x13, 0xfe, 0x03, 0xf8, + 0x4c, 0xea, 0x31, 0x1b, 0xef, 0x16, 0x3b, 0xfc, 0xc0, 0xcc, 0x67, 0xff, 0xde, + 0x1d, 0x41, 0x52, 0xd3, 0x26, 0x10, 0x0a, 0x46, 0x08, 0x34, 0x46, 0xf1, 0x4a, + 0x07, 0x06, 0xd8, 0xdb, 0x3d, 0xf4, 0xc8, 0x65, 0xbb, 0xee, 0xe1, 0x18, 0xe3, + 0xf3, 0x11, 0x4e, 0x33, 0x4e, 0x07, 0xfc, 0xbd, 0x0c, 0x28, 0xbd, 0xfb, 0xe2, + 0xe4, 0xc4, 0x01, 0x24, 0x0a, 0xec, 0xc7, 0x09, 0xab, 0x41, 0x06, 0x0b, 0x57, + 0xed, 0x20, 0xad, 0x70, 0xab, 0x47, 0xf1, 0xb7, 0xf8, 0xab, 0x47, 0x19, 0x37, + 0xdf, 0x01, 0x21, 0x01, 0x2e, 0x2f, 0xdb, 0x1c, 0x1d, 0xce, 0xd1, 0x19, 0x21, + 0xd2, 0xfc, 0x5c, 0x52, 0xee, 0x1f, 0xfe, 0x3e, 0x1f, 0x23, 0xd2, 0xf2, 0x03, + 0x0e, 0xcc, 0xfa, 0x16, 0x06, 0x0b, 0x07, 0x0e, 0x06, 0x08, 0x16, 0xdc, 0x17, + 0x01, 0xc6, 0x01, 0x2a, 0xb5, 0xfe, 0x25, 0xe9, 0x7f, 0xe9, 0xee, 0xde, 0xad, + 0x16, 0x0d, 0x04, 0xbd, 0xf2, 0x24, 0x1d, 0x11, 0xfe, 0xb8, 0xfa, 0xd0, 0xf2, + 0xdd, 0x20, 0xe2, 0x12, 0x12, 0x0f, 0x31, 0x2d, 0xc3, 0xd3, 0x0d, 0x23, 0x24, + 0xcb, 0x19, 0x07, 0x20, 0x21, 0xdf, 0x00, 0x01, 0x3f, 0x26, 0x1e, 0x03, 0x10, + 0xff, 0x3a, 0xf0, 0xb4, 0x32, 0x11, 0xe0, 0x01, 0x07, 0xfe, 0xde, 0xeb, 0xff, + 0xd0, 0x07, 0x0f, 0xea, 0x3a, 0x02, 0xf0, 0x22, 0x1c, 0xf8, 0x0a, 0x10, 0xea, + 0xf5, 0x3b, 0xed, 0x0a, 0x24, 0xfd, 0x01, 0xd1, 0xf5, 0x07, 0xfd, 0x16, 0xa7, + 0x21, 0xd1, 0xef, 0x0d, 0x19, 0x13, 0xd6, 0x21, 0x5e, 0x10, 0xe3, 0xed, 0x07, + 0x38, 0xcf, 0x43, 0xd8, 0x0c, 0x0a, 0x31, 0xdb, 0x52, 0xc0, 0xf9, 0xcc, 0xfc, + 0xe5, 0xcc, 0xd6, 0x06, 0xfb, 0xad, 0x24, 0x2e, 0xdc, 0x9b, 0xfb, 0x35, 0xf4, + 0xf1, 0xe6, 0x10, 0xbe, 0xe4, 0x13, 0xef, 0x95, 0xc5, 0x45, 0xdb, 0x1e, 0x5a, + 0x24, 0xf5, 0x0c, 0xfa, 0xfa, 0xdf, 0x3b, 0xfe, 0x41, 0x35, 0x00, 0xd7, 0xe8, + 0xf0, 0xf1, 0xae, 0xc8, 0xe7, 0x5c, 0x7a, 0xa8, 0x0f, 0x34, 0x57, 0x29, 0xe6, + 0x2a, 0x23, 0x47, 0x25, 0x04, 0x24, 0xc9, 0x7f, 0xee, 0x29, 0xfb, 0xcd, 0x3d, + 0x2a, 0x32, 0x2b, 0xed, 0x2f, 0xe2, 0x12, 0x30, 0x23, 0xda, 0x15, 0x13, 0xed, + 0x60, 0x2e, 0xdf, 0x0d, 0xef, 0xa9, 0x08, 0xd1, 0xe4, 0x37, 0xc1, 0xfa, 0x06, + 0x41, 0x3f, 0xe2, 0x1b, 0x59, 0xdb, 0xa1, 0x20, 0xae, 0xf2, 0xdc, 0xa3, 0xd6, + 0x0f, 0xfa, 0xfb, 0xe7, 0x33, 0xff, 0xf3, 0x56, 0x01, 0x2a, 0xd8, 0x48, 0x93, + 0xc1, 0xc7, 0x00, 0xe7, 0x37, 0x06, 0x00, 0xf3, 0xa3, 0x50, 0xc0, 0xeb, 0x23, + 0xc3, 0x1f, 0xc6, 0xf9, 0xfd, 0xb8, 0xf3, 0xe3, 0xc7, 0xdc, 0xe3, 0xea, 0xdb, + 0xd4, 0xcd, 0xb2, 0x06, 0xd5, 0x22, 0xd5, 0x28, 0xee, 0x2a, 0x7f, 0x3f, 0xdb, + 0xf1, 0xea, 0xf2, 0x2a, 0xb3, 0x10, 0x1a, 0x19, 0x4d, 0xe5, 0xe5, 0xd9, 0xb9, + 0x9e, 0x12, 0xe6, 0x3e, 0xd4, 0x1c, 0xf9, 0xd2, 0xed, 0x32, 0x2e, 0x3e, 0xdc, + 0x17, 0xd5, 0xd1, 0x08, 0x02, 0x12, 0x2a, 0xeb, 0xec, 0x0c, 0x08, 0x1f, 0x1e, + 0x03, 0xd0, 0x23, 0x17, 0x9c, 0x09, 0x1d, 0xf1, 0xd7, 0x05, 0x27, 0x1e, 0x04, + 0xd9, 0xf9, 0xde, 0xe7, 0x3a, 0x37, 0xc8, 0x09, 0x50, 0x14, 0x0a, 0x05, 0x17, + 0x09, 0xb3, 0xcc, 0x20, 0x1b, 0x26, 0x11, 0x5d, 0x15, 0xf0, 0xff, 0x0d, 0x05, + 0xc7, 0xde, 0xe5, 0x09, 0xde, 0x27, 0x23, 0x0a, 0xf3, 0xb3, 0xff, 0x00, 0x42, + 0xd0, 0xe6, 0x0a, 0xee, 0xe2, 0x42, 0xc7, 0xd7, 0x37, 0x4d, 0xca, 0x03, 0x0d, + 0x12, 0xcf, 0x0f, 0xb7, 0x15, 0xf4, 0xbf, 0xea, 0x3a, 0xf3, 0x19, 0xf0, 0x28, + 0xe7, 0x0e, 0x04, 0xd4, 0xe0, 0x05, 0x02, 0xd6, 0xf9, 0x36, 0xfc, 0xe4, 0xf4, + 0x09, 0x1d, 0xbf, 0xcb, 0x06, 0xe0, 0xca, 0x00, 0xee, 0xd6, 0xea, 0xf4, 0xce, + 0x18, 0xfb, 0x32, 0x1d, 0x02, 0xf5, 0xe3, 0xe6, 0x16, 0x41, 0xe5, 0x4f, 0x38, + 0x05, 0xe4, 0xda, 0xf8, 0x81, 0x01, 0xaf, 0xfc, 0x06, 0xb4, 0x2c, 0x0c, 0x1a, + 0xda, 0xfc, 0xaf, 0x26, 0xec, 0xe6, 0xed, 0x16, 0x02, 0xf9, 0x29, 0x13, 0xda, + 0xbb, 0xe1, 0x20, 0xcf, 0x0a, 0xfc, 0x01, 0x36, 0xcd, 0x47, 0x00, 0xdb, 0xff, + 0x08, 0xf4, 0xfc, 0x2a, 0x52, 0xfb, 0xf1, 0x03, 0xd3, 0xee, 0xd3, 0xdf, 0xe0, + 0x07, 0x2e, 0xe7, 0xda, 0xfd, 0x0a, 0x27, 0xcf, 0x09, 0xf0, 0xbd, 0xec, 0xf8, + 0xea, 0x03, 0x22, 0x3f, 0xda, 0x07, 0xe8, 0x28, 0xd7, 0x12, 0x0c, 0x03, 0x11, + 0xf3, 0x2e, 0xd2, 0xe3, 0xe1, 0x4d, 0xe6, 0x06, 0xe8, 0xde, 0xed, 0xc1, 0x36, + 0xe6, 0x17, 0xd6, 0xf4, 0xd0, 0x04, 0xfe, 0xfb, 0xea, 0x02, 0x45, 0xc8, 0xb5, + 0x54, 0xfe, 0xde, 0xf6, 0xf9, 0xec, 0x0d, 0xd7, 0xf5, 0xc4, 0x81, 0xc8, 0x29, + 0x11, 0xc4, 0x1a, 0x1c, 0x19, 0x32, 0xd1, 0xbe, 0x0f, 0xfc, 0xf6, 0x50, 0xe5, + 0x4a, 0x31, 0x03, 0x06, 0xee, 0x1d, 0x54, 0x0c, 0xf6, 0x3a, 0xc2, 0xe7, 0x25, + 0x2d, 0x18, 0xf9, 0xfe, 0x07, 0xe5, 0x0d, 0xc0, 0xac, 0x4b, 0xe7, 0xa0, 0xad, + 0x34, 0x50, 0x45, 0xdc, 0xe9, 0xe3, 0x18, 0xcc, 0xb9, 0xfe, 0xc2, 0xf2, 0xf8, + 0xe7, 0x07, 0x4c, 0xea, 0x53, 0xfe, 0x14, 0xed, 0x08, 0xd2, 0x5d, 0x31, 0x0f, + 0x15, 0x05, 0x01, 0xc7, 0x03, 0x0b, 0xc6, 0xff, 0xde, 0xf5, 0x9c, 0xc5, 0x19, + 0x41, 0xf9, 0xf0, 0x0d, 0xdd, 0xdf, 0x24, 0x0c, 0x90, 0x17, 0x4e, 0xd9, 0xce, + 0xd9, 0xc8, 0xd7, 0x0e, 0x09, 0x3c, 0x0b, 0xb7, 0xea, 0xf2, 0x3f, 0xc4, 0xa8, + 0xd5, 0x02, 0xdf, 0xda, 0xe5, 0xf9, 0xfe, 0x19, 0x0c, 0xd2, 0x07, 0x0d, 0xb7, + 0x4b, 0x1e, 0x10, 0x08, 0xf5, 0x45, 0xf3, 0x04, 0x3c, 0xdc, 0xe9, 0xde, 0xec, + 0xc1, 0x05, 0x1a, 0xd4, 0xff, 0x10, 0xbf, 0x3f, 0xf7, 0x2b, 0x17, 0xea, 0xe6, + 0xdc, 0x16, 0x24, 0x0d, 0x07, 0x0e, 0x3c, 0xf4, 0x21, 0xcc, 0x09, 0xcc, 0x42, + 0x26, 0xc8, 0xcc, 0xfd, 0x19, 0xef, 0xef, 0x07, 0xf6, 0xfe, 0x0e, 0x2f, 0x31, + 0x43, 0xfe, 0x29, 0xc1, 0xcf, 0x35, 0xc1, 0x10, 0xff, 0xce, 0x22, 0x07, 0x0d, + 0x13, 0xee, 0x7f, 0x13, 0x00, 0x02, 0xef, 0x06, 0xf0, 0xde, 0x1a, 0x1c, 0xe7, + 0xfa, 0xcd, 0x17, 0x23, 0xc3, 0xba, 0xfe, 0xba, 0xea, 0x21, 0x09, 0x20, 0x00, + 0x22, 0xf7, 0x15, 0x46, 0xbd, 0xce, 0xc2, 0xfb, 0x12, 0xf2, 0xf0, 0x52, 0xd3, + 0x0f, 0x45, 0xde, 0xe9, 0xe8, 0x1f, 0x0b, 0x02, 0x2c, 0xe1, 0xea, 0x54, 0x03, + 0x0f, 0x0d, 0xd7, 0xf3, 0x13, 0x36, 0xfc, 0xd2, 0xc2, 0xe6, 0xed, 0xa1, 0x81, + 0xdd, 0x22, 0xd0, 0x31, 0xa8, 0xd2, 0xcb, 0x39, 0x10, 0xb7, 0xea, 0x99, 0xb6, + 0xde, 0xe7, 0x1c, 0x28, 0xf7, 0x07, 0x27, 0xe2, 0xf3, 0x60, 0xe9, 0x11, 0x22, + 0xfa, 0x0f, 0xe5, 0xd8, 0xe4, 0x19, 0xeb, 0x04, 0xcd, 0x0c, 0x8e, 0x63, 0x07, + 0xf0, 0xe4, 0xc6, 0xda, 0x3e, 0x31, 0xe0, 0x30, 0xcf, 0xe2, 0x04, 0xec, 0x69, + 0x4b, 0xa9, 0x0d, 0xc2, 0xf3, 0xc9, 0x25, 0xec, 0xe4, 0x25, 0x18, 0x64, 0xf4, + 0x2c, 0xea, 0xe1, 0x18, 0x33, 0x07, 0xd9, 0x22, 0x08, 0x0c, 0x26, 0x03, 0x2c, + 0x0f, 0x15, 0x0f, 0x3b, 0xc2, 0xe2, 0xf6, 0x52, 0x12, 0xcd, 0xd3, 0xda, 0x1d, + 0x35, 0x41, 0xd9, 0x2d, 0xfe, 0xe4, 0x0b, 0x0d, 0xa8, 0x15, 0x03, 0xce, 0x14, + 0xbe, 0x2c, 0x81, 0xd7, 0xfa, 0x2e, 0xaa, 0x4f, 0xe0, 0xc9, 0x0f, 0x0f, 0xde, + 0x17, 0x2f, 0x37, 0x4b, 0xf7, 0xfc, 0x07, 0xe8, 0x0c, 0x06, 0x02, 0xeb, 0xbd, + 0xb5, 0x0c, 0x2d, 0xd3, 0xc4, 0xf0, 0xd8, 0xf4, 0xe0, 0xcf, 0x1c, 0xfc, 0x3e, + 0xc6, 0xf1, 0x43, 0x30, 0xca, 0x0e, 0x0d, 0xd2, 0xdb, 0xbe, 0x4e, 0xce, 0xfb, + 0xe1, 0xed, 0x0d, 0x71, 0xe5, 0xe7, 0x42, 0xb9, 0x0a, 0x42, 0x05, 0xef, 0x27, + 0xc9, 0xe1, 0x07, 0x24, 0xff, 0x2f, 0xe9, 0xf2, 0x0e, 0xfb, 0x2a, 0xba, 0x3e, + 0xe8, 0x1e, 0xcc, 0xfd, 0xe7, 0x0f, 0x29, 0x1c, 0xba, 0xda, 0xe0, 0xea, 0xea, + 0xd6, 0x24, 0xe2, 0x2f, 0xb6, 0x1d, 0x62, 0xe9, 0x6c, 0xea, 0x05, 0xd8, 0xd9, + 0x26, 0x12, 0x0a, 0x21, 0xd7, 0xf6, 0xe2, 0x0a, 0xee, 0x0a, 0xf7, 0x0d, 0x51, + 0xdb, 0x01, 0xcc, 0xee, 0x05, 0xf6, 0xf8, 0x2c, 0x1c, 0xea, 0xdf, 0x28, 0xc8, + 0xa6, 0xa5, 0x21, 0xf9, 0xa6, 0x49, 0x1c, 0xb8, 0x2f, 0x0a, 0x81, 0xd4, 0xeb, + 0xe3, 0x17, 0x02, 0xd4, 0x0d, 0x25, 0xb0, 0x00, 0x19, 0x56, 0x7f, 0xff, 0xf9, + 0xe4, 0x33, 0x2e, 0xf3, 0x1c, 0xe3, 0xfa, 0xf3, 0xf9, 0xed, 0xe6, 0xed, 0xfb, + 0x3b, 0x29, 0x21, 0xdf, 0x0f, 0xc8, 0x1b, 0x06, 0xd1, 0x01, 0x01, 0xbb, 0x0c, + 0x25, 0x55, 0x14, 0xe0, 0x35, 0xdb, 0xd8, 0x29, 0x09, 0xd8, 0x56, 0x08, 0xfa, + 0xdd, 0xfa, 0xeb, 0xf4, 0xe9, 0xe1, 0xab, 0x08, 0xf2, 0xfc, 0xd3, 0xf8, 0x0d, + 0xf0, 0xcf, 0xe4, 0xe3, 0xf8, 0xf4, 0xba, 0x22, 0x15, 0x00, 0xe6, 0xdf, 0xf9, + 0x1a, 0x55, 0xff, 0xef, 0x41, 0xc9, 0x79, 0x19, 0xcd, 0x29, 0xc1, 0x16, 0xf1, + 0x27, 0x23, 0xe5, 0xf8, 0xf2, 0x0b, 0x43, 0xfa, 0xe1, 0x10, 0xf9, 0xed, 0x0c, + 0x27, 0x06, 0xd9, 0xd9, 0x0c, 0xde, 0xf6, 0x24, 0x0e, 0xe7, 0x21, 0x0b, 0xe6, + 0xfe, 0x2f, 0xe9, 0x0e, 0xf9, 0x3f, 0xf7, 0x26, 0xdc, 0x21, 0xe9, 0xcc, 0xf7, + 0xda, 0xda, 0xec, 0x20, 0x21, 0xe3, 0xf0, 0x3c, 0x1e, 0xcb, 0xf7, 0xf6, 0x47, + 0x15, 0xa9, 0xb9, 0xd7, 0x1a, 0xea, 0xe0, 0xd7, 0xdc, 0x30, 0xe8, 0x22, 0x12, + 0x39, 0x0f, 0x1b, 0xff, 0xf6, 0x02, 0xc5, 0x3f, 0x27, 0xdf, 0xcd, 0xe0, 0x06, + 0x36, 0x00, 0xef, 0x0f, 0xe8, 0xe2, 0x2e, 0x18, 0x24, 0xe5, 0xc6, 0x0b, 0xdf, + 0xf6, 0x0d, 0xde, 0xd6, 0xc9, 0x3f, 0xf1, 0x26, 0x0d, 0x10, 0xf2, 0x06, 0xe9, + 0xd2, 0x10, 0xe1, 0x37, 0xd8, 0x26, 0x21, 0x03, 0x0b, 0x7f, 0xfc, 0xe6, 0x0e, + 0x20, 0x19, 0xf0, 0x0e, 0x07, 0x07, 0x1f, 0x0c, 0xcb, 0xdd, 0x03, 0xa2, 0xea, + 0x23, 0xd1, 0x21, 0x07, 0xf4, 0xd0, 0xfd, 0xff, 0x22, 0x23, 0x0c, 0x28, 0xe1, + 0x03, 0x75, 0x24, 0x41, 0xd3, 0xef, 0x34, 0xfc, 0x48, 0x2a, 0xd5, 0xd8, 0xe0, + 0xe4, 0xda, 0xdd, 0xf6, 0x27, 0xc7, 0x07, 0x13, 0x17, 0x08, 0x27, 0x22, 0x19, + 0xf5, 0xf9, 0x16, 0xf8, 0xe7, 0x20, 0xdf, 0x10, 0x18, 0xe1, 0xba, 0xc5, 0xf4, + 0xee, 0x3e, 0xe1, 0x0d, 0xd7, 0xfe, 0x17, 0x01, 0x48, 0x25, 0xd3, 0x0d, 0xd4, + 0x39, 0x07, 0x0d, 0xff, 0xf5, 0xf4, 0x37, 0xf3, 0x0f, 0x36, 0x10, 0xbc, 0xea, + 0xe5, 0x22, 0xed, 0x1a, 0x0f, 0x18, 0xfa, 0xdf, 0x30, 0x04, 0x11, 0xea, 0xba, + 0xb0, 0x7f, 0x35, 0xe2, 0xea, 0x20, 0xdc, 0x10, 0x0f, 0x01, 0xcc, 0xc6, 0x31, + 0xc3, 0x07, 0x28, 0x1d, 0xfd, 0xf0, 0x03, 0x13, 0x1b, 0xc1, 0xff, 0x3c, 0xe2, + 0x01, 0xcb, 0x25, 0x2b, 0xe0, 0xf7, 0x04, 0xcf, 0xea, 0x08, 0xfb, 0x0d, 0xf3, + 0x3a, 0xea, 0x11, 0x3b, 0xe5, 0x1d, 0x1b, 0xdd, 0x23, 0x0b, 0x11, 0xe8, 0x07, + 0x01, 0x1b, 0x87, 0xfc, 0x23, 0xd7, 0x10, 0xed, 0x31, 0x0e, 0x03, 0x01, 0x0c, + 0xfe, 0xcf, 0xeb, 0x13, 0xdc, 0x22, 0x2c, 0x09, 0xd4, 0x2c, 0x04, 0xff, 0xe3, + 0xec, 0x45, 0xfb, 0xab, 0xed, 0xfb, 0xf1, 0x06, 0xf0, 0x8e, 0x13, 0x1c, 0xb2, + 0xd6, 0x7f, 0x0d, 0x25, 0xc3, 0x07, 0x6c, 0xd3, 0x4d, 0xe4, 0xf7, 0xbf, 0x5d, + 0xfb, 0xd7, 0x14, 0xde, 0x18, 0x1c, 0xd6, 0x30, 0x45, 0xb3, 0xca, 0xde, 0x56, + 0xe9, 0x20, 0x21, 0xf0, 0xea, 0xeb, 0xe7, 0xf7, 0xf2, 0xc0, 0xe7, 0x15, 0xdf, + 0x48, 0x21, 0x1a, 0xf8, 0x2c, 0x2c, 0xf3, 0xd4, 0x3e, 0x00, 0x32, 0xdb, 0xdc, + 0xea, 0xd1, 0xf6, 0xe6, 0xed, 0xef, 0x0d, 0xde, 0x17, 0x5d, 0x20, 0x19, 0xa4, + 0x00, 0xf7, 0xa6, 0x04, 0xab, 0xf2, 0xe6, 0xf7, 0x59, 0xdc, 0x1e, 0x4e, 0x32, + 0x26, 0x38, 0x3a, 0xe8, 0xe7, 0x31, 0x3e, 0xfe, 0x36, 0x04, 0x31, 0x3a, 0xe4, + 0xd8, 0xea, 0xbf, 0x21, 0x20, 0xdb, 0x01, 0x69, 0x9d, 0x3f, 0xd1, 0x4f, 0xbe, + 0x07, 0xef, 0x20, 0xa6, 0x24, 0xf6, 0x04, 0xff, 0x07, 0x11, 0xd1, 0x0d, 0xe0, + 0xfa, 0x0c, 0xaf, 0xe7, 0x00, 0x02, 0x82, 0xe2, 0xd1, 0xf3, 0x22, 0xab, 0x00, + 0xae, 0xb6, 0x19, 0x09, 0xdc, 0xce, 0xf4, 0x40, 0x3e, 0x06, 0x02, 0xac, 0xc2, + 0x40, 0x13, 0x09, 0x1f, 0x1f, 0x54, 0xe3, 0xe3, 0x0c, 0xff, 0x0c, 0xf6, 0xb3, + 0x19, 0xd5, 0x00, 0x6a, 0xd8, 0x1e, 0xf5, 0x1b, 0xf0, 0x0d, 0xfe, 0xdf, 0x0c, + 0x20, 0x7f, 0x50, 0x41, 0x0a, 0xf8, 0xed, 0xe2, 0x1c, 0xe5, 0x0d, 0xed, 0xe4, + 0xbc, 0x11, 0x4e, 0xc4, 0xd9, 0x11, 0xfa, 0x16, 0xe4, 0x1a, 0x15, 0x45, 0x1c, + 0xdb, 0x06, 0x03, 0xc3, 0xcf, 0xf5, 0xfd, 0x7f, 0xf2, 0xfa, 0x03, 0x3a, 0xe4, + 0xd2, 0x23, 0x43, 0x37, 0x16, 0x20, 0x0b, 0x1e, 0xd3, 0x2b, 0xde, 0xce, 0xc9, + 0xe7, 0x2d, 0xe7, 0x18, 0xbb, 0x09, 0x0f, 0x18, 0x08, 0xd1, 0x3c, 0xff, 0x6c, + 0xc4, 0x17, 0xa7, 0xff, 0xb4, 0x58, 0x28, 0x00, 0xfe, 0xfc, 0xc5, 0xfa, 0x07, + 0x32, 0xb1, 0xe3, 0x0c, 0x31, 0xde, 0x4d, 0xc3, 0xf1, 0xf0, 0xe0, 0xe1, 0x21, + 0x1c, 0x02, 0x0e, 0x38, 0xe8, 0x09, 0x21, 0xf2, 0x36, 0x47, 0x06, 0xd6, 0x2d, + 0x18, 0xd2, 0x12, 0x0d, 0x35, 0x13, 0x2e, 0x05, 0xcb, 0x16, 0xfc, 0x05, 0xd7, + 0xff, 0xd3, 0xe9, 0xdd, 0x01, 0x11, 0x05, 0xff, 0x03, 0xbf, 0x10, 0x26, 0x1d, + 0x59, 0xd4, 0x03, 0xca, 0xea, 0xa5, 0x3a, 0x2b, 0x07, 0x09, 0x20, 0x08, 0xd9, + 0x0a, 0x25, 0x01, 0x00, 0x26, 0x1a, 0xf2, 0xfa, 0xea, 0x1d, 0xdc, 0xe1, 0xf0, + 0xc1, 0x26, 0x18, 0xf0, 0xe1, 0x14, 0xfd, 0xe4, 0x10, 0x35, 0x00, 0x48, 0xce, + 0xeb, 0xeb, 0xe6, 0x1f, 0xfd, 0xe2, 0xfa, 0x0b, 0xd8, 0xcd, 0x08, 0x2b, 0x14, + 0xda, 0x2c, 0xdb, 0xdd, 0x05, 0xe4, 0x40, 0xc2, 0x04, 0xf1, 0xe0, 0x2a, 0x39, + 0x20, 0xe3, 0xf2, 0x12, 0xe5, 0xf5, 0xf7, 0xc2, 0xd6, 0xb5, 0x23, 0x0f, 0x1a, + 0xef, 0x1b, 0x05, 0xf6, 0xe8, 0x07, 0xd3, 0x1b, 0x34, 0x92, 0x2c, 0xec, 0xa4, + 0x09, 0xd5, 0xcc, 0x07, 0x41, 0x06, 0x1d, 0x28, 0xd0, 0x0d, 0x65, 0x01, 0xfc, + 0xfd, 0x1b, 0x0f, 0x18, 0x81, 0x2c, 0x6a, 0xf6, 0xfb, 0x04, 0x63, 0xd7, 0x24, + 0xcd, 0xa0, 0xfc, 0xd4, 0x01, 0xdb, 0x20, 0x25, 0xc8, 0xf2, 0xea, 0xb8, 0x04, + 0xe3, 0xe7, 0x27, 0xce, 0x1e, 0x30, 0x08, 0xfe, 0x04, 0x09, 0xdf, 0x1a, 0x2b, + 0xe5, 0x01, 0xe6, 0x1d, 0x1f, 0xfd, 0x34, 0x1b, 0xdd, 0xf0, 0xb8, 0x5e, 0xe3, + 0xe7, 0xb6, 0xc8, 0xe8, 0x12, 0x14, 0xa4, 0x44, 0xf8, 0xf1, 0x2c, 0xb0, 0xf7, + 0x3e, 0x2b, 0xf7, 0xf7, 0xe9, 0x59, 0xc1, 0xda, 0xbe, 0xca, 0xb3, 0xf4, 0xdb, + 0xc8, 0x8b, 0xbb, 0xc1, 0x48, 0xe7, 0xab, 0xfd, 0x9d, 0x44, 0x34, 0xef, 0x1c, + 0x33, 0xdd, 0x2c, 0x0c, 0xdf, 0x62, 0xac, 0xe2, 0xe2, 0xc8, 0x39, 0x9f, 0x38, + 0x47, 0xf8, 0x17, 0x81, 0x26, 0x46, 0x9f, 0xd6, 0x51, 0xc6, 0x11, 0xed, 0x63, + 0xc1, 0xf3, 0xe8, 0x14, 0xf3, 0x14, 0x2e, 0x23, 0x1c, 0xec, 0x41, 0x65, 0xf3, + 0xff, 0xc5, 0x36, 0x20, 0x0c, 0xd9, 0x09, 0xe7, 0xfb, 0xfc, 0xe9, 0x39, 0x8f, + 0xe1, 0xbf, 0x40, 0x1c, 0x19, 0x07, 0x0c, 0x02, 0x0f, 0xff, 0x2f, 0xac, 0x30, + 0x45, 0x1d, 0x35, 0xb1, 0xd5, 0x0d, 0xc5, 0xe3, 0x2e, 0x01, 0x28, 0x14, 0x67, + 0x29, 0x10, 0x41, 0xee, 0x01, 0x56, 0xd0, 0xd6, 0x48, 0x1a, 0xd7, 0x1d, 0xe0, + 0x07, 0x0a, 0x16, 0xe5, 0x01, 0xf6, 0xe8, 0xee, 0xf4, 0x00, 0x20, 0x02, 0xf7, + 0x03, 0x07, 0xdb, 0x07, 0xc7, 0x2d, 0x1d, 0x03, 0xf9, 0x03, 0x09, 0xf5, 0xd7, + 0xf5, 0xd6, 0xed, 0x19, 0x21, 0xfa, 0xec, 0xe4, 0xef, 0xb0, 0xcf, 0x1c, 0xc4, + 0x09, 0x0d, 0xbb, 0x23, 0x26, 0x0f, 0x0d, 0xec, 0x2f, 0x0c, 0xf0, 0xc1, 0x14, + 0xbc, 0x13, 0x45, 0x17, 0xdc, 0xf9, 0xeb, 0x14, 0x05, 0xef, 0xfe, 0xd2, 0x45, + 0x03, 0x15, 0x09, 0xd8, 0xda, 0x29, 0xe6, 0x07, 0xef, 0x12, 0xe0, 0x01, 0x2f, + 0x7f, 0xec, 0xfd, 0xd1, 0x03, 0x2f, 0xeb, 0xff, 0xba, 0xe0, 0x08, 0x12, 0x0f, + 0x4f, 0x47, 0xed, 0xc4, 0xc4, 0xdc, 0x2f, 0x09, 0x2b, 0x08, 0x1e, 0xdd, 0x35, + 0xd8, 0x09, 0xfa, 0xe6, 0x1c, 0xd8, 0xff, 0xd0, 0x04, 0xda, 0x1a, 0x37, 0x1d, + 0x2a, 0xe6, 0xc6, 0xf7, 0x32, 0x41, 0x1d, 0xd5, 0x3a, 0xde, 0x43, 0x07, 0x3d, + 0xfb, 0x0b, 0xd4, 0x22, 0xc9, 0x2f, 0xe5, 0xd5, 0x0f, 0x24, 0x0b, 0xc8, 0xe8, + 0x1f, 0x1f, 0x57, 0x9e, 0x2f, 0x30, 0x88, 0xf9, 0x2d, 0xd7, 0xb3, 0x1c, 0x84, + 0x2c, 0xc3, 0x07, 0x32, 0x3a, 0xb6, 0xd6, 0xca, 0x13, 0x02, 0xcf, 0xe1, 0xaa, + 0xd0, 0xd9, 0xed, 0xc7, 0xfe, 0x09, 0x09, 0xd0, 0x1e, 0x6d, 0x56, 0x37, 0xef, + 0xd9, 0xed, 0x1a, 0xe7, 0xbe, 0x56, 0xf3, 0x0a, 0x48, 0xda, 0xf0, 0xd3, 0x2a, + 0xe6, 0x12, 0x7b, 0xe0, 0xbe, 0x25, 0x0f, 0x1e, 0xdb, 0x58, 0xed, 0xec, 0x12, + 0xc4, 0xf4, 0xc0, 0x29, 0xee, 0x11, 0xdc, 0xd2, 0x19, 0x37, 0x1e, 0xf1, 0x4d, + 0xdd, 0xf4, 0x88, 0xa3, 0x32, 0xd8, 0xab, 0xc1, 0x0e, 0x27, 0x6c, 0x20, 0x36, + 0x29, 0x06, 0x08, 0x31, 0x1d, 0x35, 0x7f, 0xfe, 0x24, 0x4b, 0x17, 0xcb, 0x19, + 0x03, 0x21, 0x05, 0x0c, 0x34, 0x60, 0x18, 0x02, 0xd4, 0xf6, 0x0e, 0xfe, 0xdd, + 0x4f, 0x1c, 0x83, 0xe8, 0xbe, 0xba, 0x48, 0x30, 0xfa, 0xf3, 0x0d, 0x13, 0x47, + 0x36, 0x13, 0x34, 0x1c, 0x3e, 0xb4, 0x4b, 0xa1, 0xb9, 0xf4, 0xf9, 0x0a, 0xe3, + 0x2b, 0x36, 0xa2, 0xce, 0x32, 0x29, 0x11, 0x10, 0x3a, 0xa0, 0x28, 0x6f, 0xca, + 0xfc, 0xf0, 0xb0, 0xdb, 0xe9, 0x10, 0xfb, 0xf4, 0xef, 0x53, 0xc2, 0xf6, 0x45, + 0x2d, 0x14, 0xf8, 0xdf, 0xce, 0x17, 0xa7, 0xf3, 0x12, 0x81, 0x38, 0xac, 0x10, + 0xd6, 0xf9, 0xef, 0x43, 0x0d, 0x0c, 0x1c, 0xea, 0x1d, 0x3f, 0x1f, 0xc2, 0xe2, + 0xf6, 0x00, 0x1a, 0xe9, 0x2a, 0x02, 0x1c, 0xec, 0xf5, 0x04, 0xd1, 0x18, 0x21, + 0x11, 0xe7, 0x32, 0xb1, 0x1d, 0x21, 0x1c, 0xf5, 0xdc, 0xf8, 0xe7, 0xe9, 0x38, + 0x5a, 0x08, 0xf1, 0x2d, 0xbb, 0x08, 0xe6, 0x08, 0x13, 0x2e, 0x07, 0x35, 0x34, + 0xff, 0x11, 0xfb, 0x09, 0xf3, 0x0d, 0x5b, 0xef, 0x37, 0x38, 0x0c, 0xe5, 0x2b, + 0xcd, 0x11, 0x4a, 0x03, 0xf5, 0xf6, 0x01, 0xfc, 0x22, 0xc2, 0x0a, 0xd7, 0xdb, + 0xee, 0xf9, 0xe8, 0x07, 0xfa, 0xdf, 0xf9, 0xe5, 0x36, 0x1a, 0x07, 0xd9, 0xe7, + 0xd4, 0xff, 0xde, 0x02, 0x60, 0xf8, 0xeb, 0xe8, 0xc7, 0x3d, 0xf3, 0xf8, 0x0c, + 0xc9, 0xe8, 0x28, 0x2e, 0x1e, 0x15, 0xf0, 0xec, 0x32, 0x06, 0x39, 0x4c, 0x0a, + 0x36, 0xc7, 0xd8, 0xeb, 0x52, 0xe2, 0xda, 0xaf, 0xfe, 0x23, 0x0b, 0x02, 0x43, + 0x19, 0xda, 0x09, 0xed, 0x05, 0x0f, 0x0d, 0x29, 0xeb, 0xd8, 0x40, 0x0e, 0xd5, + 0x30, 0xf8, 0x46, 0x0b, 0xfe, 0x1e, 0x03, 0xe5, 0xef, 0x38, 0xd5, 0x05, 0xbd, + 0x07, 0xb0, 0xe2, 0x4a, 0xc5, 0x06, 0xa3, 0xeb, 0x7f, 0x28, 0x02, 0xba, 0x2c, + 0x1b, 0xeb, 0xe8, 0xdd, 0xfa, 0xf8, 0x1a, 0x03, 0x69, 0xfe, 0x0b, 0xcb, 0x26, + 0xf5, 0xfb, 0x33, 0xb2, 0xd9, 0x18, 0xcc, 0xe6, 0x4d, 0xde, 0x11, 0x0f, 0x10, + 0x0d, 0x26, 0xa3, 0xfc, 0x10, 0x22, 0xd9, 0xdb, 0x11, 0xec, 0x06, 0x36, 0x42, + 0x14, 0x33, 0xe8, 0x1a, 0xe2, 0xcd, 0xeb, 0x1d, 0xbc, 0xcb, 0x37, 0xc3, 0xf7, + 0xbb, 0x1c, 0x0b, 0x0c, 0x05, 0xb7, 0xb4, 0x6c, 0xc0, 0x0f, 0xf3, 0xe7, 0xf2, + 0x05, 0xff, 0xde, 0xde, 0xc9, 0xe8, 0xd2, 0xdd, 0x1a, 0x18, 0x36, 0x25, 0x27, + 0x24, 0x08, 0x18, 0xed, 0x19, 0x05, 0xdc, 0x1f, 0x19, 0xed, 0x16, 0xe5, 0x3e, + 0x04, 0xef, 0x07, 0xfa, 0xf7, 0xcf, 0x0f, 0x04, 0x7f, 0xf9, 0x1a, 0x0d, 0x23, + 0xd7, 0x33, 0xdc, 0xdf, 0xd5, 0x06, 0x05, 0xe5, 0xb1, 0x48, 0xe9, 0xfa, 0x1a, + 0x1c, 0xbe, 0x51, 0x03, 0x15, 0xf0, 0xfe, 0xfd, 0xdf, 0xb0, 0xe5, 0x0b, 0xf8, + 0xfb, 0x44, 0xac, 0xf2, 0xe0, 0x5b, 0x07, 0x6f, 0xdb, 0xfd, 0x21, 0x06, 0x24, + 0xee, 0x42, 0xe1, 0x0f, 0xb2, 0xb8, 0xea, 0xb3, 0xf7, 0xf9, 0xf7, 0x2f, 0xd2, + 0xab, 0x0c, 0x0d, 0x09, 0x21, 0x9d, 0x59, 0xc7, 0x07, 0xdb, 0x15, 0xfd, 0x21, + 0xf2, 0x49, 0xc8, 0x12, 0xdb, 0x70, 0xdb, 0x09, 0x2f, 0x6e, 0xbe, 0xc7, 0xb1, + 0xf2, 0xfd, 0x1e, 0xef, 0x0a, 0xe8, 0xcb, 0xeb, 0x39, 0xf7, 0x06, 0x9d, 0x1b, + 0x3e, 0xb0, 0xe5, 0xed, 0xe5, 0xf7, 0x13, 0x01, 0x43, 0x7f, 0xcd, 0xfd, 0xf5, + 0x6a, 0x35, 0x08, 0xdd, 0xf8, 0xf5, 0x1b, 0xe6, 0xd9, 0xd5, 0xf5, 0xef, 0xdc, + 0x12, 0x61, 0x41, 0x4b, 0x09, 0x04, 0xcb, 0x03, 0xfd, 0xc2, 0xe0, 0x85, 0xea, + 0xba, 0xf7, 0xfd, 0x6b, 0xc0, 0x26, 0xc8, 0x0a, 0xce, 0xe2, 0xfe, 0xfe, 0xb2, + 0x59, 0x08, 0xc9, 0x31, 0x2d, 0xef, 0x57, 0x06, 0xe0, 0x48, 0x95, 0x73, 0x29, + 0x49, 0xea, 0x77, 0x31, 0x3b, 0x24, 0x55, 0x34, 0x2e, 0xc1, 0x23, 0x26, 0xe7, + 0x1d, 0x50, 0x1a, 0xb7, 0xe9, 0xbd, 0x49, 0x20, 0x29, 0xe3, 0x0f, 0x7b, 0x0f, + 0xed, 0x2c, 0x64, 0xa7, 0xda, 0xfa, 0xef, 0x21, 0xbf, 0x05, 0xff, 0x99, 0xe1, + 0x5c, 0xcc, 0xd8, 0xd6, 0xea, 0xc0, 0x34, 0x1f, 0xad, 0xe1, 0xe6, 0xc9, 0xdc, + 0xbb, 0x19, 0xec, 0x31, 0x11, 0x04, 0xd8, 0x50, 0xf1, 0xdf, 0x68, 0x06, 0xca, + 0x5d, 0x1d, 0x68, 0xd5, 0x2c, 0x2f, 0xcf, 0x91, 0xbc, 0xc4, 0x0f, 0xb4, 0x5c, + 0x68, 0xd0, 0x14, 0x46, 0x42, 0x85, 0x21, 0x12, 0xf5, 0x24, 0xf6, 0xda, 0x2b, + 0xd7, 0x69, 0xc7, 0xd9, 0x42, 0xe9, 0x1e, 0x9f, 0xfd, 0x4f, 0x05, 0x0f, 0xe8, + 0x0f, 0x4e, 0x21, 0xd2, 0xc7, 0x87, 0x6e, 0x64, 0x5d, 0x3e, 0x23, 0xd9, 0xc7, + 0x05, 0xda, 0x0f, 0xec, 0xfc, 0x88, 0xb5, 0x0c, 0xec, 0xe2, 0xb1, 0x09, 0xbf, + 0x21, 0x0f, 0xfc, 0x3d, 0xb6, 0xf9, 0x29, 0x05, 0x7f, 0x28, 0xe9, 0x03, 0xf7, + 0xf1, 0x0f, 0xfa, 0xcc, 0xec, 0x01, 0xda, 0xf1, 0xc1, 0xe0, 0x5d, 0x47, 0x05, + 0xfb, 0x16, 0xe7, 0x16, 0x20, 0x1d, 0xdd, 0xdd, 0x2b, 0x5a, 0x1b, 0x45, 0x67, + 0xfb, 0x00, 0xe7, 0xd9, 0x1b, 0xed, 0xe3, 0x17, 0x1d, 0x59, 0x1c, 0xd2, 0x56, + 0x7f, 0xeb, 0xfe, 0xcc, 0xe9, 0xfc, 0x1a, 0xcc, 0x37, 0x27, 0xec, 0x30, 0x16, + 0x41, 0xc1, 0x29, 0x8c, 0xe4, 0x01, 0x36, 0xe0, 0xfe, 0x16, 0x1b, 0x17, 0xb5, + 0xfb, 0xe6, 0x8b, 0xed, 0xf9, 0xe6, 0x11, 0xe5, 0x2a, 0xec, 0xd3, 0xf1, 0xdd, + 0x0f, 0xc9, 0x38, 0xc4, 0xdf, 0xc7, 0x0a, 0xcb, 0x12, 0x32, 0x59, 0x17, 0x4b, + 0x1f, 0xe6, 0x03, 0x1a, 0xda, 0xe6, 0x3d, 0x36, 0x11, 0x14, 0xc1, 0xa6, 0x2e, + 0xd2, 0xf8, 0x1e, 0x06, 0x37, 0x16, 0xca, 0xdd, 0x3a, 0x25, 0xee, 0x42, 0xb7, + 0xe3, 0xdf, 0xfd, 0xdf, 0x29, 0xed, 0xa3, 0x20, 0xc2, 0x37, 0x95, 0x57, 0xea, + 0x0c, 0x0e, 0x08, 0xf3, 0xf9, 0xf9, 0x9a, 0x1c, 0xb6, 0x04, 0xdd, 0x14, 0xea, + 0x06, 0x96, 0xeb, 0x60, 0x26, 0xc6, 0x7f, 0x01, 0xe2, 0xb4, 0x21, 0xb9, 0x38, + 0x41, 0x1d, 0x3b, 0x22, 0x6e, 0xe0, 0xc4, 0xa3, 0x1e, 0xd5, 0xf5, 0xa8, 0x46, + 0xb8, 0xf5, 0x1f, 0x20, 0xfa, 0x73, 0xe5, 0x9a, 0xcb, 0x68, 0x06, 0x79, 0x59, + 0xf9, 0x37, 0x2f, 0x0b, 0xa9, 0xbf, 0xb9, 0x3f, 0x0b, 0xca, 0xaa, 0x1f, 0x05, + 0x1e, 0x41, 0x05, 0x08, 0x0f, 0xfb, 0xc5, 0x32, 0xb4, 0xc8, 0xf4, 0x05, 0xf1, + 0x93, 0x0a, 0x4c, 0x46, 0xfe, 0xbd, 0x3a, 0xc2, 0xc3, 0x4e, 0xbe, 0xcb, 0xd7, + 0xa9, 0xc6, 0xe5, 0xed, 0x95, 0xdf, 0xfa, 0x32, 0xf2, 0xc6, 0xfd, 0x95, 0xe9, + 0x45, 0x0c, 0x13, 0x17, 0x01, 0xcf, 0x23, 0x23, 0xd8, 0xc9, 0x05, 0xac, 0x21, + 0xac, 0xc0, 0x2e, 0xec, 0xe7, 0x3c, 0xf9, 0xdc, 0xde, 0x0f, 0xe8, 0xf9, 0x27, + 0xbe, 0xd7, 0x06, 0xfe, 0xdb, 0xa6, 0xd4, 0xc1, 0x0e, 0x07, 0xd9, 0x2b, 0xe4, + 0x07, 0xff, 0xef, 0xe5, 0xdd, 0xb6, 0x4d, 0x81, 0x06, 0xeb, 0x48, 0xe3, 0xea, + 0xd0, 0xee, 0x5f, 0x3f, 0xb8, 0x21, 0xf1, 0xb7, 0x0b, 0x2c, 0x17, 0x07, 0xcd, + 0xe7, 0xfe, 0x34, 0x0b, 0xfd, 0xc8, 0x0e, 0x66, 0x1b, 0x4a, 0xfa, 0xb1, 0xfc, + 0xee, 0x5c, 0xd1, 0xd4, 0x1e, 0x12, 0xb0, 0xcb, 0x22, 0x15, 0x03, 0x02, 0xf3, + 0x0f, 0x91, 0x0a, 0x03, 0x2f, 0xbf, 0xd4, 0x0a, 0xc3, 0xef, 0xa3, 0x0b, 0xf9, + 0xf0, 0x46, 0x06, 0xcc, 0xfd, 0x04, 0x11, 0xec, 0xd6, 0x61, 0xee, 0xd3, 0x20, + 0x60, 0xe5, 0xff, 0xc7, 0xfc, 0xf4, 0x63, 0x29, 0xd8, 0x2f, 0xff, 0xe9, 0xfd, + 0x15, 0xff, 0x0c, 0x25, 0x1a, 0x36, 0x11, 0xd3, 0xc5, 0xf1, 0x47, 0xec, 0xf4, + 0xd8, 0x11, 0x41, 0xe5, 0xf2, 0xa8, 0xea, 0x1a, 0x0e, 0xf8, 0x2b, 0xf9, 0x1d, + 0xc6, 0x3f, 0x3b, 0xb6, 0xd5, 0x95, 0x05, 0x0e, 0xe2, 0xf2, 0xb1, 0x03, 0xf2, + 0x36, 0xb3, 0x3b, 0x24, 0x1a, 0x2c, 0xe2, 0x5c, 0x37, 0xe4, 0xcb, 0x01, 0x2d, + 0xe6, 0xee, 0xe9, 0x23, 0xe5, 0x08, 0xa6, 0xb4, 0xfe, 0x90, 0xdf, 0xf0, 0x36, + 0x21, 0xbd, 0xb6, 0x08, 0x07, 0x2d, 0xe7, 0x99, 0xff, 0x29, 0xe9, 0xd2, 0xe9, + 0xc5, 0x22, 0x18, 0x4b, 0x0a, 0x01, 0x26, 0x06, 0x20, 0xed, 0xde, 0xe5, 0x0d, + 0xfd, 0xf7, 0xb3, 0x0a, 0x12, 0x3e, 0xed, 0x00, 0x0d, 0xb6, 0x3f, 0xff, 0x1a, + 0x17, 0x1d, 0xee, 0x06, 0x01, 0x04, 0x68, 0xf2, 0xd7, 0xc4, 0xf1, 0x15, 0xe6, + 0x17, 0xf2, 0x0e, 0x2b, 0xd8, 0x39, 0xf5, 0xdf, 0x18, 0x44, 0x00, 0x23, 0xf8, + 0x35, 0x21, 0x7f, 0x86, 0x37, 0xdc, 0x13, 0xdd, 0xd1, 0x14, 0x0a, 0x25, 0x14, + 0x28, 0x19, 0xed, 0xd9, 0xfd, 0xcb, 0xe8, 0x36, 0xf6, 0x3a, 0x10, 0xda, 0xe5, + 0xc6, 0x4b, 0x94, 0x04, 0x32, 0xa1, 0x57, 0xbb, 0x14, 0x21, 0x36, 0x28, 0x0f, + 0x39, 0x93, 0xd0, 0xd7, 0xc8, 0x14, 0xdc, 0x34, 0xe9, 0x43, 0x24, 0xfe, 0xda, + 0xaf, 0x10, 0x19, 0xf5, 0x1a, 0xd9, 0xeb, 0x23, 0x05, 0xe4, 0x35, 0x0d, 0x30, + 0x13, 0xc7, 0xc1, 0x19, 0xc3, 0x32, 0x8a, 0x48, 0x2c, 0xad, 0x15, 0xf8, 0x09, + 0x52, 0x0e, 0xe2, 0x03, 0xea, 0x1b, 0xa4, 0xc4, 0xc4, 0x5d, 0xca, 0x17, 0x09, + 0xca, 0x1e, 0x33, 0xab, 0x2b, 0xe6, 0x9d, 0xa9, 0xb9, 0x0e, 0x3b, 0xfa, 0xb3, + 0x21, 0xcd, 0x29, 0x52, 0x32, 0x63, 0x0c, 0xfa, 0xd0, 0x11, 0xfd, 0x81, 0x15, + 0x2b, 0xd0, 0xec, 0x09, 0xee, 0xb3, 0x3e, 0x06, 0x25, 0x30, 0xe2, 0x0e, 0x18, + 0x1c, 0xe6, 0x01, 0xf2, 0x66, 0xef, 0x33, 0xca, 0x41, 0xf1, 0x33, 0xdd, 0xfa, + 0xf3, 0x5c, 0xc8, 0x7f, 0xe3, 0x14, 0x31, 0x3f, 0xc9, 0xff, 0xf7, 0xfc, 0x20, + 0xfc, 0x0b, 0x10, 0x20, 0xf2, 0x36, 0xea, 0xd1, 0xf7, 0x2c, 0x1b, 0xfb, 0x25, + 0x0f, 0xfb, 0xdf, 0x17, 0x4e, 0xf6, 0x5e, 0xcb, 0xe3, 0xcc, 0xe1, 0xe2, 0xb3, + 0x0b, 0xf0, 0x36, 0xc0, 0xd9, 0x12, 0xe7, 0xfd, 0xfc, 0xf6, 0xdc, 0x1a, 0x0a, + 0xf1, 0x16, 0xfb, 0x1b, 0x0e, 0xfd, 0x3f, 0xf5, 0xe3, 0xb8, 0x23, 0xec, 0x46, + 0x1f, 0x28, 0xf1, 0xe1, 0xfb, 0x10, 0xfc, 0x09, 0xf4, 0x23, 0x0c, 0xf7, 0x17, + 0x2d, 0x12, 0xc3, 0xf9, 0xf7, 0xe6, 0x0d, 0x22, 0x03, 0x3b, 0xf9, 0x0b, 0xeb, + 0xb9, 0x13, 0x15, 0x2a, 0x0f, 0xc7, 0x1a, 0x1b, 0xee, 0x40, 0xe9, 0x01, 0x06, + 0xf9, 0x45, 0x06, 0xf4, 0x1c, 0x0e, 0x33, 0xcb, 0x56, 0x0f, 0x07, 0x15, 0xf5, + 0x46, 0x22, 0xe8, 0x08, 0xd5, 0x12, 0xe4, 0xe3, 0x13, 0x2b, 0x19, 0x1b, 0x73, + 0x14, 0xff, 0xd8, 0x57, 0xe7, 0x32, 0x1b, 0x02, 0x3c, 0xc9, 0x19, 0x00, 0xc7, + 0x19, 0xff, 0x12, 0xfc, 0x38, 0xfe, 0xf3, 0x11, 0xb2, 0x30, 0xe3, 0x07, 0x30, + 0xde, 0x42, 0x07, 0xd2, 0xc5, 0xe4, 0xf4, 0xd3, 0x0d, 0x9b, 0xcd, 0xcd, 0x1e, + 0x2b, 0xf9, 0xe4, 0x2d, 0x1c, 0x26, 0xe3, 0x40, 0xd2, 0x0f, 0xa4, 0x26, 0x0b, + 0xeb, 0x2a, 0xdf, 0xf2, 0xd7, 0x36, 0xd0, 0xad, 0xbe, 0x36, 0x0e, 0x21, 0xf7, + 0x1b, 0xc0, 0x1c, 0x27, 0x01, 0xe8, 0xdc, 0x18, 0x17, 0xe0, 0xf5, 0x1a, 0xf5, + 0x02, 0x02, 0xe9, 0x20, 0x07, 0x06, 0x81, 0xec, 0x42, 0x18, 0x1d, 0xd7, 0x47, + 0xaf, 0xca, 0xea, 0xfa, 0xbe, 0x35, 0x2a, 0xc7, 0x03, 0xd5, 0xf6, 0xe6, 0x20, + 0xb9, 0xb4, 0xc1, 0xec, 0x01, 0xc6, 0xc5, 0x00, 0xd0, 0x01, 0xf3, 0xd4, 0x66, + 0x08, 0x03, 0x1f, 0xeb, 0x00, 0x19, 0xb1, 0x38, 0xca, 0x0e, 0x3c, 0x81, 0xa9, + 0xe8, 0x35, 0xbb, 0x07, 0xf3, 0x3c, 0xea, 0x2a, 0x4a, 0xd3, 0x0a, 0xc7, 0xed, + 0xe4, 0x08, 0x1e, 0xd7, 0xe1, 0x42, 0x29, 0xcc, 0xda, 0x23, 0x01, 0xbb, 0x26, + 0xbf, 0x1c, 0xc3, 0xef, 0xdd, 0xd4, 0x38, 0xff, 0x0d, 0x47, 0x37, 0x44, 0xd2, + 0xe6, 0x8d, 0x47, 0x28, 0x2a, 0xf5, 0xd6, 0x4d, 0xac, 0xca, 0xe0, 0xb9, 0x2a, + 0x2d, 0x4f, 0xe1, 0x29, 0xf2, 0xe2, 0x14, 0xf4, 0xb8, 0x43, 0x2e, 0x24, 0xeb, + 0x40, 0x2f, 0xe4, 0x21, 0xf5, 0xd4, 0x21, 0x3f, 0xd4, 0x1c, 0x29, 0x25, 0x1a, + 0x93, 0x30, 0xab, 0x55, 0xf3, 0xc0, 0x14, 0xe0, 0x7f, 0xe7, 0x1a, 0xe6, 0xd5, + 0xeb, 0xe0, 0x36, 0x0d, 0x21, 0x2c, 0x58, 0xc7, 0xfa, 0x18, 0xe4, 0x4f, 0xb6, + 0x27, 0xd3, 0xe3, 0xd6, 0xff, 0xde, 0xd2, 0xe9, 0xdf, 0x00, 0x39, 0x02, 0xe7, + 0x84, 0xbb, 0x01, 0x1b, 0xd9, 0x04, 0xfb, 0x24, 0x05, 0x1d, 0xdb, 0x20, 0x1c, + 0xea, 0x3a, 0xf9, 0x1e, 0xf3, 0xe4, 0xea, 0x35, 0x04, 0x16, 0x28, 0x26, 0x3f, + 0x1e, 0xf4, 0xf2, 0x06, 0x28, 0xfa, 0x27, 0x01, 0x45, 0x02, 0xea, 0xec, 0x0e, + 0x20, 0x1f, 0xdb, 0xed, 0xdd, 0x10, 0x24, 0xfe, 0x5a, 0x0c, 0xda, 0xf2, 0xe8, + 0xda, 0xd0, 0xf9, 0xa5, 0x15, 0xdc, 0x0a, 0xe7, 0xd3, 0x3e, 0xd7, 0xfe, 0xf5, + 0x35, 0x28, 0xe5, 0xe3, 0x1b, 0xfe, 0xcd, 0x09, 0x1c, 0xcb, 0x4a, 0x0e, 0xdf, + 0xdf, 0x08, 0x18, 0x19, 0x39, 0x28, 0x2b, 0x12, 0x02, 0x14, 0x08, 0x4a, 0xcf, + 0xb3, 0xf7, 0xf8, 0x9c, 0x3e, 0x05, 0xaf, 0x6c, 0x12, 0x03, 0xeb, 0x7f, 0x31, + 0xad, 0x04, 0x4d, 0x00, 0x39, 0x31, 0x00, 0xe6, 0xe9, 0x38, 0xd8, 0xbb, 0x25, + 0xfe, 0xce, 0xd9, 0x3b, 0xe1, 0x0b, 0xfb, 0xe6, 0x06, 0xfa, 0x2d, 0x26, 0x3f, + 0xed, 0xac, 0xd7, 0x0b, 0xcc, 0xbc, 0xf9, 0xec, 0xc6, 0x1f, 0x22, 0xd9, 0x0d, + 0xef, 0xe5, 0xf6, 0x4d, 0x17, 0x7f, 0x2d, 0xbc, 0xec, 0x01, 0xf9, 0x6f, 0xb6, + 0xfb, 0x11, 0xd5, 0x0f, 0xe5, 0xdf, 0xe9, 0xd7, 0xe5, 0x23, 0xf8, 0xdf, 0x08, + 0xfd, 0xf3, 0xdf, 0x50, 0xd6, 0x2a, 0x01, 0xe8, 0x0b, 0xca, 0xfc, 0xd4, 0xe5, + 0xdf, 0xdd, 0xfc, 0x02, 0x42, 0xf0, 0xde, 0x25, 0xf3, 0xbb, 0x01, 0xd0, 0xdb, + 0xb6, 0x59, 0xeb, 0xe5, 0xdd, 0xdf, 0x20, 0xdb, 0xb4, 0xe1, 0xc3, 0xf0, 0x1f, + 0xcf, 0x01, 0xf3, 0x2a, 0x53, 0xf3, 0xb4, 0x47, 0xf1, 0x14, 0xd3, 0x33, 0xcb, + 0x16, 0xcb, 0xfc, 0x05, 0x01, 0xfb, 0xe8, 0xb1, 0x18, 0x20, 0xcf, 0xcd, 0xde, + 0x23, 0x8f, 0x32, 0x04, 0xfc, 0xba, 0x3a, 0xf5, 0x4d, 0xef, 0xd0, 0xdb, 0xd4, + 0xe0, 0xf8, 0x18, 0x28, 0x1e, 0xd7, 0x24, 0xe8, 0xd6, 0x0b, 0x5a, 0xcd, 0x40, + 0xfe, 0xb3, 0x16, 0xcb, 0xde, 0x4b, 0xe8, 0x25, 0xe0, 0x03, 0x2c, 0x20, 0x22, + 0xaa, 0xda, 0xc8, 0xf6, 0xf2, 0xe2, 0xe7, 0x17, 0xb2, 0x13, 0x6f, 0x30, 0xd3, + 0xe1, 0x2d, 0x0d, 0x00, 0x5b, 0xb1, 0x1c, 0x03, 0xfa, 0xa0, 0x0d, 0xfd, 0xb6, + 0xbf, 0xf9, 0x55, 0x3e, 0x22, 0xe3, 0x8f, 0xdb, 0x5e, 0xb3, 0xe5, 0x13, 0x14, + 0x2c, 0x33, 0xf3, 0xb6, 0xe1, 0x8a, 0x09, 0x16, 0x04, 0x15, 0x00, 0x62, 0xf8, + 0x1c, 0x36, 0x6f, 0xd6, 0xca, 0x02, 0xcd, 0x87, 0x4c, 0x85, 0x22, 0x2f, 0xbc, + 0x0a, 0x23, 0x41, 0x10, 0x08, 0x50, 0xd8, 0xa3, 0x13, 0x0d, 0xe1, 0x1f, 0x02, + 0xee, 0x26, 0xe3, 0xf4, 0x21, 0x0f, 0xe6, 0x13, 0x04, 0xff, 0x45, 0x4f, 0x89, + 0xc4, 0x7f, 0xfd, 0x29, 0xfc, 0x5b, 0xc2, 0x30, 0xe6, 0xb2, 0xee, 0xc0, 0x30, + 0xc8, 0xfb, 0xf3, 0xd8, 0xc3, 0x74, 0x0f, 0xf2, 0x41, 0x1a, 0xfe, 0x18, 0xd2, + 0xdd, 0xbc, 0xda, 0x3f, 0xfd, 0xc6, 0xb3, 0xdf, 0x0e, 0x27, 0xe1, 0xfb, 0x27, + 0x0e, 0x43, 0xaa, 0x66, 0x16, 0x29, 0x1a, 0x0c, 0x0c, 0xe7, 0x14, 0x10, 0x22, + 0x64, 0xa9, 0x16, 0xff, 0x11, 0x14, 0xdd, 0x2a, 0x42, 0x0f, 0xf0, 0x11, 0xbb, + 0xf3, 0xe9, 0x4e, 0xe2, 0x16, 0x92, 0xe0, 0xce, 0x11, 0xf2, 0xf4, 0xc6, 0xfe, + 0x7f, 0xfc, 0xbc, 0xf8, 0xd1, 0xe9, 0xe1, 0xe6, 0xe2, 0x13, 0x45, 0x1e, 0xe7, + 0xc8, 0xf8, 0x08, 0x31, 0xae, 0x13, 0xf4, 0xc2, 0xfc, 0xf5, 0x27, 0x0c, 0x2c, + 0x63, 0x3d, 0xda, 0x3b, 0xcc, 0xe4, 0xd1, 0xf8, 0x0c, 0xe0, 0xe2, 0xa5, 0xe5, + 0xf5, 0xe5, 0xff, 0x2f, 0xe9, 0x28, 0xca, 0x0e, 0xe7, 0x24, 0xb4, 0x3f, 0xdb, + 0x05, 0xc6, 0x25, 0xf2, 0x43, 0x05, 0xc5, 0xde, 0xd9, 0x26, 0xd5, 0xfe, 0xf4, + 0x1b, 0x3c, 0x25, 0x17, 0x23, 0xf2, 0xe2, 0x00, 0xe2, 0x20, 0xba, 0xdb, 0xff, + 0xdd, 0xc0, 0x11, 0xfe, 0x14, 0x03, 0x31, 0x00, 0x0c, 0x7f, 0xf8, 0x0d, 0x1c, + 0x05, 0xfe, 0x2b, 0xbe, 0x32, 0x04, 0xfd, 0xad, 0x38, 0xe9, 0x25, 0x19, 0xca, + 0xe5, 0x19, 0xe3, 0x69, 0xf3, 0x45, 0xfb, 0x42, 0x17, 0xe1, 0xe8, 0xf4, 0xf6, + 0xe2, 0xe5, 0xb1, 0xbf, 0x14, 0xd6, 0x2b, 0x3b, 0x04, 0xf1, 0xce, 0xfb, 0xbb, + 0xcd, 0xfb, 0xec, 0xfc, 0xd5, 0xf6, 0x11, 0x5e, 0xf0, 0x34, 0xc0, 0x1f, 0xbc, + 0xdb, 0x23, 0xe9, 0x21, 0x22, 0xe1, 0x04, 0x35, 0xdf, 0x0a, 0x26, 0xed, 0x05, + 0x60, 0xe9, 0x1f, 0xdf, 0x47, 0x67, 0x03, 0xf3, 0xf7, 0x4e, 0x27, 0xee, 0x01, + 0x01, 0xe6, 0x37, 0x0d, 0x0e, 0x1e, 0xfb, 0xf1, 0xfb, 0xcc, 0xb5, 0x44, 0xf8, + 0xb5, 0xee, 0x23, 0x31, 0x09, 0xce, 0xfb, 0xdc, 0x02, 0x17, 0x01, 0x6d, 0x26, + 0xe4, 0x31, 0x33, 0xc8, 0x27, 0xea, 0xfe, 0x05, 0xfc, 0x25, 0x08, 0x47, 0xe8, + 0x2b, 0xdc, 0xfb, 0xe8, 0xf3, 0x10, 0x31, 0x08, 0x23, 0x22, 0x03, 0xcb, 0x05, + 0xf9, 0x0f, 0x0e, 0x02, 0x09, 0xc9, 0x00, 0x36, 0x12, 0x05, 0xca, 0xec, 0xbd, + 0xd8, 0xf0, 0x25, 0x1c, 0x0f, 0x21, 0xdf, 0x25, 0xdc, 0x04, 0xd8, 0x1c, 0x01, + 0xde, 0xe8, 0x42, 0x04, 0xce, 0xd0, 0xe7, 0xc8, 0xb2, 0x53, 0x07, 0xfa, 0xd5, + 0x17, 0xe0, 0xe6, 0x02, 0xf6, 0xd2, 0xfc, 0x07, 0xdf, 0x05, 0x1f, 0xfd, 0xe3, + 0xdb, 0xc7, 0x22, 0x06, 0x0a, 0xfe, 0x30, 0x3a, 0x02, 0xed, 0x29, 0x2e, 0xfb, + 0x22, 0x0d, 0xee, 0x1b, 0xf6, 0xc9, 0xe9, 0xfa, 0xc0, 0xa6, 0xac, 0x09, 0xcc, + 0xd2, 0x50, 0xea, 0xdc, 0x76, 0xf6, 0x46, 0x32, 0xef, 0xd7, 0x24, 0x07, 0x7f, + 0x22, 0xda, 0xf9, 0x15, 0x0a, 0x4b, 0xc8, 0xc2, 0xc1, 0xca, 0x1c, 0x13, 0xf5, + 0x1d, 0x45, 0x25, 0x2e, 0xf0, 0xf2, 0x30, 0x07, 0x36, 0xce, 0x28, 0xeb, 0x33, + 0xde, 0xe5, 0x0b, 0x0e, 0xe6, 0xe4, 0xdc, 0x30, 0xfa, 0x8f, 0xdf, 0xd0, 0x58, + 0xcd, 0x5c, 0xf4, 0xee, 0x25, 0xdf, 0x1a, 0x36, 0x05, 0xcc, 0x24, 0xfb, 0xea, + 0xb2, 0x00, 0x53, 0x2a, 0xde, 0xa7, 0x20, 0xe2, 0x1a, 0x4b, 0xe0, 0x56, 0x24, + 0x06, 0xc8, 0x00, 0x09, 0x05, 0xf1, 0xc3, 0xa2, 0x8e, 0xfa, 0x6d, 0x12, 0xf4, + 0x22, 0xe4, 0xeb, 0x32, 0x6b, 0x19, 0x60, 0x0f, 0xa0, 0xf2, 0x88, 0xf3, 0x99, + 0xdf, 0x0f, 0xdc, 0xdc, 0x20, 0xe7, 0x41, 0x54, 0xdb, 0xf3, 0x27, 0xde, 0xcc, + 0x45, 0xe0, 0xe5, 0x21, 0xbe, 0xcc, 0x0c, 0xe8, 0x35, 0x3e, 0x3c, 0xd2, 0x76, + 0xe7, 0xc4, 0xed, 0x31, 0x00, 0x4c, 0x7f, 0xd8, 0xb2, 0xe6, 0x1b, 0x29, 0x0b, + 0x2c, 0x0b, 0x92, 0x43, 0x1b, 0x26, 0xfe, 0xce, 0x1b, 0x17, 0xb9, 0xff, 0xf7, + 0x17, 0x16, 0x2a, 0xc1, 0x06, 0xc6, 0xde, 0xd1, 0x07, 0x08, 0x18, 0x00, 0xf7, + 0xf9, 0x3a, 0x14, 0x02, 0x0f, 0x1d, 0xc8, 0xd4, 0x48, 0xf7, 0xf4, 0xe9, 0xf6, + 0x06, 0x45, 0xf0, 0xee, 0x00, 0x1f, 0x27, 0x46, 0x17, 0x41, 0x7f, 0xfd, 0xe5, + 0x06, 0x19, 0x05, 0xea, 0xf4, 0x11, 0x01, 0x15, 0xb8, 0xe0, 0xd6, 0xdd, 0xeb, + 0x30, 0xcc, 0xe8, 0x1b, 0x01, 0x0f, 0xf1, 0xd7, 0x20, 0xef, 0x04, 0x09, 0xbf, + 0x3a, 0x21, 0x01, 0xd2, 0xe3, 0x18, 0x15, 0xbe, 0x48, 0xf3, 0x1a, 0x10, 0xe0, + 0xe2, 0xed, 0x48, 0x2b, 0xe7, 0x53, 0x64, 0xd3, 0xe6, 0xdb, 0xef, 0xf5, 0xb8, + 0xfc, 0xc2, 0x4c, 0x23, 0x0d, 0x12, 0x1b, 0x04, 0x09, 0xca, 0x2c, 0xc3, 0x91, + 0xcb, 0x12, 0xd3, 0x3d, 0xc2, 0xfc, 0xf4, 0x1b, 0x04, 0x10, 0xbe, 0xf6, 0xcb, + 0xcd, 0xd9, 0x03, 0xe9, 0xf4, 0xec, 0x34, 0x05, 0xf0, 0x0d, 0x2b, 0x06, 0x2d, + 0xe4, 0xf5, 0xb9, 0xe4, 0xc1, 0x43, 0xd6, 0xd5, 0x14, 0x13, 0xe8, 0x05, 0x2f, + 0xf6, 0x2a, 0xed, 0xb8, 0xc9, 0x05, 0x0d, 0xec, 0x4d, 0x49, 0x42, 0xef, 0xce, + 0xcf, 0x27, 0x3d, 0x71, 0x02, 0x61, 0x24, 0xe5, 0xb6, 0xf5, 0xeb, 0xd3, 0x3a, + 0xca, 0x43, 0xd8, 0x47, 0x04, 0x2d, 0x1f, 0x3f, 0xc4, 0xba, 0xb1, 0xf3, 0x36, + 0xec, 0xeb, 0xdd, 0x04, 0x1c, 0xda, 0x50, 0x34, 0x95, 0x2a, 0x96, 0xf9, 0x62, + 0xd9, 0x08, 0xa2, 0xc1, 0x03, 0x9e, 0xa9, 0xe0, 0xf8, 0xd2, 0x1c, 0xf1, 0xbd, + 0x52, 0xa0, 0xc9, 0xdf, 0xfc, 0x11, 0xdf, 0x03, 0xfd, 0xd2, 0x81, 0x04, 0x03, + 0x0a, 0x8f, 0x3b, 0x0b, 0x93, 0xd5, 0x22, 0x06, 0x25, 0xc3, 0x19, 0x5c, 0xc9, + 0xed, 0x2e, 0x24, 0xda, 0xd2, 0xf5, 0xf6, 0xfc, 0xcb, 0x1a, 0xa3, 0xdd, 0x18, + 0xa0, 0x9a, 0xce, 0xec, 0x27, 0x04, 0xfc, 0xf9, 0x04, 0x50, 0x0b, 0xcd, 0x2f, + 0xc3, 0xba, 0xe0, 0x1d, 0x28, 0x37, 0x3c, 0x6f, 0xc8, 0x11, 0xb0, 0xf5, 0xb5, + 0x12, 0x6c, 0x13, 0x35, 0x92, 0x3b, 0x06, 0xff, 0x06, 0xc2, 0xa6, 0xc1, 0xaf, + 0xfa, 0xdf, 0xdc, 0x2f, 0x00, 0xc3, 0x0b, 0xf3, 0xf4, 0xd4, 0xb5, 0xd6, 0x22, + 0x1e, 0x1d, 0xe4, 0x30, 0xe9, 0xff, 0x44, 0xb9, 0xab, 0x10, 0xff, 0xee, 0xdf, + 0x07, 0x0a, 0xe8, 0xdf, 0x15, 0xbc, 0xe1, 0x03, 0xf3, 0x2d, 0x24, 0xf6, 0x51, + 0xfc, 0x81, 0xf5, 0xf9, 0xd7, 0x23, 0x2a, 0xa1, 0xd0, 0x2c, 0x11, 0xfd, 0xfc, + 0xf4, 0xfd, 0xd6, 0x30, 0x26, 0x06, 0xe8, 0xd3, 0xca, 0x79, 0x19, 0xef, 0x37, + 0xfc, 0x3d, 0xd2, 0xc5, 0xc8, 0x10, 0xc2, 0xec, 0x4c, 0xfc, 0x37, 0x11, 0xf8, + 0x12, 0x08, 0x13, 0xb6, 0x13, 0x01, 0xb4, 0x15, 0xf7, 0xca, 0x25, 0x29, 0xc6, + 0xab, 0xc0, 0xe1, 0x9f, 0x07, 0x27, 0x3c, 0xd1, 0x3f, 0xd9, 0xb1, 0xff, 0xce, + 0xee, 0xd3, 0x0b, 0x25, 0x02, 0x07, 0x27, 0x0f, 0xfb, 0x5e, 0xf7, 0x20, 0x27, + 0x10, 0xce, 0x3c, 0xf9, 0x2c, 0xc6, 0xb6, 0xa4, 0xd6, 0x9a, 0x30, 0xe4, 0x20, + 0xbe, 0x1b, 0xa2, 0xdb, 0x0f, 0x88, 0xf7, 0x0f, 0x03, 0x43, 0xc7, 0xfe, 0xd0, + 0xd2, 0x11, 0xce, 0x31, 0x25, 0xf9, 0x2f, 0xfc, 0xd4, 0xe2, 0xab, 0xc1, 0x6d, + 0x00, 0xda, 0xb0, 0xd9, 0xe2, 0x57, 0x4b, 0xe6, 0x05, 0xfe, 0xc0, 0x07, 0x40, + 0xf9, 0x22, 0x66, 0xf7, 0xe5, 0xf7, 0x11, 0x1b, 0x9a, 0xfe, 0x1e, 0x02, 0x2c, + 0x66, 0x1e, 0xf1, 0xd0, 0x2e, 0xe1, 0x11, 0x66, 0xcd, 0xe5, 0x2d, 0xf7, 0x12, + 0xe8, 0xf4, 0xd2, 0xd6, 0x30, 0x5a, 0x20, 0xc4, 0x26, 0x46, 0x27, 0x4c, 0x0f, + 0xd3, 0xe7, 0xee, 0x10, 0x1d, 0xfc, 0x81, 0xf9, 0xce, 0x06, 0xfd, 0x08, 0xf9, + 0xc3, 0xe4, 0xc4, 0x1b, 0x01, 0x01, 0x27, 0xba, 0xea, 0x3f, 0x7f, 0x74, 0x04, + 0xe9, 0xe7, 0xe5, 0x13, 0x2a, 0x34, 0x0b, 0xf4, 0x47, 0xf1, 0xd9, 0xdc, 0x10, + 0x3f, 0x40, 0x2a, 0xff, 0xbb, 0xd8, 0x4c, 0x08, 0x16, 0xbe, 0xff, 0xfd, 0xd2, + 0xfc, 0x0e, 0xd1, 0xbd, 0xfd, 0x3f, 0xd0, 0x08, 0xdc, 0xff, 0x14, 0x0a, 0xe7, + 0x1b, 0xdb, 0x08, 0xbf, 0xf2, 0x0e, 0xc8, 0xfa, 0x7c, 0x0f, 0x13, 0xc9, 0xe7, + 0xfd, 0x6a, 0x20, 0xe9, 0x59, 0x4a, 0xfa, 0x29, 0x30, 0x11, 0x37, 0x08, 0xfd, + 0xda, 0x32, 0x05, 0x04, 0x32, 0x2e, 0x10, 0x0e, 0xf5, 0xd3, 0xf8, 0xde, 0xf1, + 0xae, 0x25, 0x1d, 0x98, 0xe6, 0x43, 0x14, 0x11, 0xba, 0xd9, 0xb6, 0x06, 0xe3, + 0xf4, 0xfa, 0xce, 0xe2, 0xe5, 0xb8, 0xaa, 0x24, 0xfc, 0x1a, 0xea, 0x6b, 0xc0, + 0x8f, 0xf5, 0xb0, 0x2d, 0xe0, 0xed, 0x5b, 0x99, 0xbe, 0x12, 0xc2, 0xeb, 0xf1, + 0x6e, 0x5a, 0x20, 0x20, 0x1d, 0xdb, 0x25, 0xec, 0x03, 0x18, 0x13, 0xe2, 0xf8, + 0xfa, 0x0d, 0x08, 0x1a, 0x26, 0x09, 0x46, 0xd7, 0xdf, 0xe9, 0xaa, 0xe4, 0x08, + 0xf7, 0x36, 0xe3, 0xe6, 0xff, 0x05, 0xfe, 0x0f, 0xcf, 0xe3, 0xe1, 0xcd, 0xf7, + 0x1a, 0x00, 0x2f, 0x10, 0xd5, 0x1c, 0x02, 0xaf, 0x21, 0xea, 0xd3, 0x00, 0xef, + 0xe7, 0xf7, 0xe2, 0xed, 0xc9, 0xf3, 0x04, 0xdd, 0x21, 0x38, 0xda, 0x00, 0x20, + 0xed, 0x3c, 0xfe, 0x3f, 0x06, 0xd2, 0xdd, 0xce, 0x4e, 0xe3, 0x05, 0x0c, 0x05, + 0xdb, 0x29, 0x08, 0xf2, 0xda, 0x16, 0x23, 0xf2, 0x18, 0x28, 0xe8, 0x31, 0x0c, + 0x21, 0xd6, 0xe6, 0x04, 0xf3, 0x07, 0x25, 0xef, 0xf7, 0xfb, 0x03, 0x28, 0xf7, + 0xe0, 0xef, 0x05, 0xe5, 0xf6, 0x03, 0xf9, 0x04, 0xe6, 0xfd, 0xf8, 0xe9, 0x0e, + 0xe7, 0x03, 0x0b, 0xbe, 0x44, 0x21, 0xcd, 0x2a, 0x27, 0xdf, 0x14, 0x31, 0x7f, + 0x03, 0x63, 0x2a, 0x31, 0x17, 0x0b, 0xbc, 0xf6, 0x34, 0x25, 0x01, 0xd0, 0xd5, + 0x13, 0x0d, 0xf3, 0x1b, 0xf9, 0xfb, 0xbc, 0x18, 0x16, 0x07, 0xf4, 0x2c, 0x2c, + 0x01, 0xe5, 0xf2, 0x06, 0x34, 0x49, 0x27, 0xc8, 0x1d, 0xde, 0x57, 0xff, 0x12, + 0xbe, 0x10, 0x07, 0xe5, 0xf2, 0x1d, 0xc8, 0xce, 0x17, 0xb7, 0x03, 0xfb, 0x29, + 0xd2, 0xc5, 0xa4, 0x10, 0xd8, 0x24, 0xde, 0xfa, 0x0f, 0x27, 0xcb, 0xf8, 0x00, + 0x23, 0xfb, 0xfb, 0xe0, 0xdd, 0x2f, 0xeb, 0x47, 0x7f, 0x0e, 0x04, 0xc7, 0xfe, + 0x1e, 0xc9, 0xd4, 0x06, 0x01, 0x04, 0x3d, 0x2a, 0xf2, 0xf8, 0x36, 0xca, 0x16, + 0x28, 0x1a, 0x13, 0x0c, 0x3d, 0x04, 0x3a, 0x0e, 0x03, 0xd9, 0x3c, 0x2c, 0x14, + 0xd6, 0xe9, 0x05, 0xf2, 0xc5, 0x05, 0xe2, 0xd8, 0x1a, 0x0d, 0x04, 0xf5, 0x17, + 0xef, 0x01, 0x39, 0xff, 0x0e, 0x5b, 0xd1, 0xfd, 0xdc, 0x13, 0xf7, 0x0f, 0xd2, + 0x27, 0xde, 0x11, 0xe1, 0xdd, 0x10, 0x29, 0x46, 0xdb, 0x1c, 0xef, 0x02, 0x65, + 0xd8, 0xef, 0xd4, 0x34, 0xa8, 0xe7, 0x36, 0xf7, 0x11, 0x1d, 0xf5, 0x06, 0xdf, + 0xde, 0xeb, 0x07, 0x5c, 0x7f, 0x0d, 0xe6, 0x1f, 0xee, 0x05, 0x0f, 0x20, 0xd0, + 0x1d, 0x11, 0x29, 0x4f, 0x14, 0xfa, 0xfb, 0x9e, 0xa0, 0x4a, 0x08, 0xff, 0x15, + 0x20, 0x64, 0x02, 0xe5, 0xd7, 0x1b, 0xd2, 0x14, 0xe1, 0x2a, 0x50, 0x9b, 0x21, + 0x1d, 0x17, 0x1d, 0x28, 0x9f, 0xdb, 0x31, 0xd4, 0x14, 0xfc, 0xf8, 0xfc, 0xd7, + 0xd9, 0x46, 0x1c, 0x45, 0xdb, 0xe0, 0xa9, 0x2d, 0x0f, 0x43, 0x35, 0x46, 0x0d, + 0x2d, 0xdc, 0xef, 0xd6, 0x01, 0xb4, 0xf9, 0x22, 0x20, 0x35, 0x12, 0xf4, 0xf4, + 0x0f, 0xbb, 0x29, 0xe0, 0xfc, 0xc8, 0x08, 0xf6, 0x48, 0xaf, 0xf2, 0xbc, 0xe4, + 0x1f, 0xba, 0xc3, 0xb5, 0xdb, 0xde, 0xdc, 0xea, 0x02, 0x29, 0xf6, 0x0f, 0x12, + 0xfe, 0x3f, 0x36, 0xe3, 0xeb, 0xea, 0x0d, 0x1d, 0x1f, 0xdd, 0xf0, 0xfa, 0x15, + 0x0a, 0xfe, 0xd8, 0x06, 0x21, 0x0f, 0xf5, 0x24, 0xe0, 0xbb, 0xf7, 0x1a, 0xd8, + 0x02, 0x18, 0x20, 0xef, 0xe5, 0x02, 0x0e, 0x06, 0xf9, 0x12, 0xc4, 0x07, 0x44, + 0x07, 0xdb, 0xe0, 0xcf, 0x09, 0xce, 0x16, 0xec, 0xec, 0xe0, 0xf5, 0xec, 0x0b, + 0x1d, 0x08, 0x3a, 0xd8, 0x0b, 0xd8, 0xf9, 0x03, 0x03, 0xed, 0x0a, 0x19, 0xe9, + 0xe8, 0xe1, 0xd7, 0xe6, 0x0a, 0x40, 0xe1, 0xf2, 0x2b, 0x4c, 0xe6, 0x06, 0xf5, + 0x07, 0x1c, 0xda, 0xf5, 0x27, 0xde, 0xe3, 0xbb, 0xe3, 0xfe, 0xf4, 0xfb, 0x12, + 0xe6, 0x19, 0x7f, 0x4a, 0xf9, 0x1d, 0x2b, 0xf3, 0x19, 0x09, 0x00, 0x12, 0xd2, + 0x0d, 0x0d, 0xed, 0xf5, 0xe0, 0xed, 0x0e, 0x05, 0x06, 0x06, 0xe5, 0x19, 0x23, + 0x31, 0x33, 0x03, 0x20, 0xf5, 0xde, 0x06, 0xfa, 0xfc, 0xdd, 0xdf, 0xd6, 0x14, + 0x0e, 0xed, 0xff, 0x2c, 0x10, 0xef, 0x42, 0x25, 0xd0, 0x0f, 0x13, 0x05, 0xc4, + 0xf1, 0x28, 0xfd, 0x0f, 0xf2, 0xed, 0xd6, 0xc7, 0x1a, 0xf3, 0xfd, 0xdf, 0xd1, + 0xc9, 0xfd, 0x11, 0x08, 0x01, 0xee, 0x29, 0x3e, 0x05, 0xf8, 0xc0, 0x23, 0x27, + 0xce, 0x1c, 0x0b, 0x55, 0xe5, 0xa1, 0x09, 0x08, 0x70, 0xef, 0x22, 0xe6, 0x14, + 0x1f, 0xc7, 0x28, 0xd1, 0xf0, 0x10, 0xd2, 0x29, 0x16, 0x3a, 0xed, 0x0c, 0x29, + 0x08, 0xf6, 0x2a, 0xd9, 0xe8, 0xce, 0x04, 0xf3, 0xde, 0x20, 0x27, 0xfd, 0x0c, + 0x08, 0x01, 0xd9, 0xf0, 0xe1, 0x18, 0x4c, 0x0b, 0xf6, 0xd8, 0xfa, 0x36, 0x20, + 0x0c, 0xe1, 0xfe, 0x00, 0x4b, 0xfe, 0x7f, 0x2f, 0x0d, 0xf6, 0x25, 0xfb, 0x36, + 0x11, 0x12, 0x48, 0xf1, 0x1a, 0x26, 0xfb, 0x20, 0x08, 0x19, 0xe0, 0xd5, 0xf5, + 0x04, 0xd8, 0x06, 0x06, 0xe6, 0xac, 0x19, 0xed, 0xe5, 0x21, 0x23, 0xe1, 0xd5, + 0x29, 0x32, 0xf7, 0x0c, 0xc0, 0xf0, 0x40, 0x0c, 0xee, 0x25, 0x17, 0xec, 0xef, + 0x26, 0xe5, 0x16, 0xff, 0x19, 0x00, 0x34, 0x27, 0xfb, 0x05, 0x2f, 0x10, 0x7f, + 0x67, 0xf3, 0xf6, 0xcf, 0x42, 0x11, 0x10, 0xb4, 0x2d, 0xb9, 0xfb, 0x4d, 0xa4, + 0x12, 0x49, 0xef, 0xc5, 0x48, 0xf9, 0xe8, 0x18, 0xf9, 0x00, 0x23, 0xb2, 0xf6, + 0xcf, 0xd6, 0xfe, 0x1f, 0x22, 0x25, 0xf0, 0xb8, 0x34, 0x1c, 0x0f, 0xe2, 0x39, + 0xea, 0xf8, 0xd2, 0x37, 0xf7, 0xd1, 0x1d, 0xb0, 0x15, 0xed, 0x95, 0xfc, 0xd8, + 0x06, 0xdd, 0xb9, 0x07, 0x48, 0xd1, 0x2c, 0xdd, 0x27, 0x32, 0xe2, 0x31, 0x0a, + 0xdb, 0x0c, 0xde, 0xd0, 0x22, 0x1d, 0x17, 0x37, 0xd0, 0x04, 0x00, 0xe6, 0x11, + 0xae, 0x47, 0x19, 0xc6, 0xea, 0xc1, 0x0e, 0xdb, 0x18, 0xd4, 0xe1, 0x01, 0xec, + 0x53, 0x17, 0xd8, 0xdd, 0xff, 0xff, 0x1a, 0xa3, 0xdc, 0x08, 0xf2, 0xf0, 0xed, + 0x22, 0xee, 0xf2, 0xb4, 0xd7, 0x20, 0x09, 0x0a, 0xd1, 0xc6, 0xe5, 0xb3, 0xfc, + 0x15, 0x2c, 0xd0, 0x23, 0xc6, 0x10, 0xfa, 0x0e, 0xd8, 0xd4, 0x21, 0xf7, 0x7f, + 0x05, 0x06, 0xc1, 0x09, 0xbf, 0x16, 0xeb, 0x07, 0x0d, 0x04, 0xed, 0xd9, 0x2f, + 0x31, 0xec, 0xf8, 0x31, 0x24, 0x13, 0xdc, 0xf4, 0x26, 0x15, 0x0d, 0xf2, 0x1d, + 0x4f, 0x25, 0x09, 0x05, 0x39, 0xf2, 0xfb, 0xfa, 0xc8, 0x01, 0x15, 0xe8, 0x12, + 0x2a, 0xf2, 0x64, 0xbc, 0x0a, 0x2d, 0xe8, 0x37, 0x29, 0x01, 0xf0, 0x1e, 0x4e, + 0xc8, 0xe6, 0xec, 0xe9, 0x0d, 0xd1, 0x0b, 0xfd, 0x0a, 0xe8, 0x06, 0x31, 0x12, + 0x1b, 0x2d, 0xd0, 0x06, 0xf7, 0xf8, 0x18, 0xfc, 0xd9, 0xf8, 0xf9, 0x26, 0x23, + 0x0b, 0xf1, 0xf1, 0x1c, 0xbc, 0xbe, 0x31, 0xfa, 0xd7, 0x15, 0x10, 0xf1, 0xeb, + 0x09, 0xef, 0x0d, 0x2c, 0x08, 0xf1, 0xd8, 0xfa, 0xe4, 0xb4, 0x05, 0xac, 0xc6, + 0x95, 0xf0, 0x3a, 0x56, 0x06, 0x58, 0x12, 0x81, 0x13, 0xac, 0xf3, 0xb0, 0x14, + 0x26, 0xdb, 0x1d, 0x38, 0xf7, 0x1c, 0x5a, 0x02, 0x0a, 0x19, 0x0f, 0xf6, 0x30, + 0x14, 0x69, 0x42, 0xe0, 0xec, 0xcf, 0xae, 0xdd, 0xec, 0xd7, 0x3c, 0xc5, 0xd2, + 0x19, 0xdc, 0xc3, 0x09, 0x1d, 0xf2, 0x48, 0xee, 0x7c, 0xe9, 0x13, 0xe7, 0x58, + 0x43, 0x33, 0x13, 0x0e, 0xbc, 0xf3, 0xd5, 0xa0, 0x41, 0x50, 0x1f, 0xfe, 0xfd, + 0x28, 0xd7, 0xde, 0xc0, 0xe1, 0x12, 0x18, 0x40, 0xca, 0xf1, 0x10, 0xed, 0xcc, + 0xf9, 0xe2, 0x34, 0xa3, 0x0a, 0xe6, 0xfd, 0x14, 0xc6, 0x0a, 0xcd, 0x10, 0x25, + 0xf1, 0x0c, 0x03, 0xda, 0xfa, 0xa9, 0xd4, 0xfc, 0x2f, 0x34, 0x15, 0xfc, 0x13, + 0x0b, 0x05, 0xcf, 0xe2, 0xb2, 0xb0, 0xf6, 0x22, 0x00, 0xc5, 0x26, 0xeb, 0x09, + 0x02, 0x3c, 0x35, 0x0b, 0x6a, 0xe3, 0xe9, 0xf9, 0xca, 0x51, 0xe8, 0xf7, 0xe4, + 0x1b, 0x3c, 0x16, 0xcc, 0x02, 0xe1, 0x1c, 0x2c, 0x12, 0x2d, 0x1e, 0x58, 0x24, + 0xe6, 0xe7, 0xd6, 0xf5, 0x0d, 0xe7, 0xf9, 0xe7, 0xfd, 0xd5, 0xe1, 0x15, 0x0a, + 0x3e, 0x19, 0xc4, 0x11, 0x27, 0x9e, 0x12, 0x1c, 0xd6, 0xb6, 0x1a, 0xf2, 0xf1, + 0x45, 0x3f, 0x29, 0xbf, 0xc7, 0x21, 0xd3, 0xa1, 0x33, 0xf6, 0x06, 0x3c, 0x04, + 0x95, 0x10, 0x3d, 0x55, 0xee, 0x24, 0xf7, 0xe8, 0xf3, 0x17, 0xfa, 0x1b, 0xbc, + 0xf2, 0x0d, 0x30, 0x36, 0xff, 0x1e, 0xeb, 0xf8, 0x21, 0xff, 0x08, 0xc5, 0x26, + 0x00, 0xb0, 0xf3, 0xfe, 0xf6, 0xeb, 0xc5, 0xac, 0xcf, 0xf7, 0x3a, 0x42, 0x1c, + 0x27, 0x18, 0xe9, 0xf7, 0xd6, 0xf9, 0x2c, 0xec, 0x29, 0x25, 0xe3, 0xde, 0x3b, + 0xe1, 0xf3, 0x34, 0x05, 0x1e, 0x7f, 0x05, 0xf2, 0x1c, 0x12, 0xf1, 0x13, 0x16, + 0xbb, 0x32, 0x68, 0xb3, 0x2c, 0xda, 0xf6, 0x4a, 0xdf, 0x06, 0x3c, 0xca, 0xab, + 0x7c, 0xd8, 0xe0, 0x40, 0x18, 0xb8, 0xfc, 0xf2, 0x54, 0x38, 0xfe, 0x2f, 0x0a, + 0xbe, 0x41, 0xbf, 0xeb, 0x10, 0xab, 0x32, 0xbe, 0xe4, 0x00, 0x2c, 0x04, 0xf6, + 0x33, 0xcf, 0x07, 0x38, 0x18, 0x06, 0x88, 0xe1, 0x27, 0x70, 0x2f, 0x4d, 0x2a, + 0x15, 0xf1, 0x0a, 0xc6, 0xca, 0x35, 0xf4, 0xec, 0x45, 0xd2, 0x48, 0xb7, 0x25, + 0x48, 0xd4, 0x85, 0xd7, 0xe8, 0x22, 0x59, 0x13, 0xd7, 0x00, 0xc7, 0xf9, 0x12, + 0x3c, 0x51, 0x1c, 0x5b, 0xca, 0x06, 0x37, 0xed, 0xaf, 0xd7, 0x44, 0xd7, 0xb6, + 0x1e, 0xea, 0x01, 0x62, 0xe8, 0x2e, 0xd6, 0x16, 0x4d, 0x9c, 0x19, 0x48, 0xf3, + 0x18, 0xfa, 0x1d, 0x28, 0xe4, 0xb3, 0xcb, 0xed, 0x7f, 0x49, 0xfe, 0xce, 0xd8, + 0x12, 0x31, 0x25, 0x13, 0x04, 0x09, 0xac, 0x1c, 0x31, 0x0d, 0x4b, 0xfc, 0x12, + 0xc4, 0x0f, 0x60, 0xc1, 0x03, 0x04, 0x56, 0xc8, 0x40, 0x18, 0xfc, 0x14, 0xc2, + 0xeb, 0xc3, 0x98, 0xfb, 0x17, 0xf8, 0x22, 0xf8, 0xf8, 0x02, 0x27, 0x04, 0xc0, + 0x0b, 0x33, 0x4e, 0xf5, 0xef, 0x47, 0x02, 0xf7, 0xf2, 0xe1, 0x18, 0x36, 0x16, + 0x1e, 0x54, 0x3b, 0xfe, 0xd7, 0xec, 0xc1, 0x0d, 0x25, 0xd2, 0xad, 0xec, 0x2e, + 0x08, 0xfe, 0xec, 0x00, 0xd5, 0x36, 0x07, 0x39, 0x07, 0xe3, 0x04, 0xce, 0xeb, + 0x28, 0x23, 0x37, 0xee, 0x10, 0xf6, 0xf2, 0x12, 0xe8, 0x15, 0x00, 0x36, 0xd7, + 0x14, 0x10, 0x02, 0xff, 0xbc, 0xea, 0xcd, 0x1d, 0xf1, 0xf5, 0xe5, 0x37, 0xf9, + 0xf0, 0x0f, 0x32, 0x29, 0x11, 0x06, 0x06, 0x0a, 0xca, 0xea, 0x15, 0x4f, 0x16, + 0x4b, 0xff, 0xe0, 0xef, 0xe1, 0xfa, 0x32, 0xd9, 0xee, 0x7f, 0x06, 0x17, 0xe9, + 0xf0, 0xdc, 0x0b, 0xde, 0x5d, 0x0e, 0x35, 0x2c, 0x23, 0x29, 0x18, 0xe6, 0x23, + 0x1c, 0xe0, 0x2c, 0xf4, 0x06, 0xef, 0xec, 0x11, 0xdd, 0x07, 0xfc, 0x38, 0x35, + 0x40, 0x3d, 0xf1, 0xe4, 0xf1, 0x05, 0xfd, 0x18, 0x21, 0xd0, 0x05, 0x2c, 0xfc, + 0x26, 0xd6, 0xdb, 0xd5, 0x17, 0xeb, 0x43, 0x08, 0x2c, 0x21, 0xfb, 0xe4, 0xeb, + 0xea, 0xb9, 0xf4, 0xba, 0xe9, 0x4a, 0xf3, 0x30, 0x0c, 0xe8, 0x10, 0x5f, 0x1a, + 0x04, 0xec, 0x2b, 0xf5, 0x07, 0xcf, 0xfa, 0xd7, 0x81, 0x09, 0xf3, 0x06, 0xe7, + 0xfa, 0x13, 0xf3, 0x2a, 0xff, 0x33, 0xf3, 0x02, 0x1c, 0xe7, 0x05, 0x2d, 0x34, + 0xce, 0x10, 0x2c, 0xfc, 0x2b, 0x17, 0xfd, 0x3a, 0xdb, 0x22, 0xf1, 0x0a, 0xea, + 0xf2, 0x32, 0xf1, 0xec, 0xef, 0xf5, 0xf6, 0x1a, 0x14, 0x02, 0x07, 0x0b, 0x12, + 0xc1, 0x34, 0x38, 0xe0, 0x19, 0x4d, 0xf5, 0xfa, 0xec, 0xea, 0xd5, 0xf3, 0x54, + 0xe6, 0x1b, 0x08, 0x17, 0x14, 0xd6, 0x06, 0x00, 0xea, 0x1b, 0x2d, 0x27, 0xf4, + 0xf5, 0x07, 0xdd, 0x07, 0x1d, 0xe9, 0xde, 0x04, 0x61, 0xf2, 0xf3, 0xf4, 0xbe, + 0xba, 0xe6, 0x12, 0x14, 0x1e, 0x0c, 0xdf, 0xee, 0x0f, 0x0b, 0xd4, 0x14, 0x29, + 0xf1, 0xd8, 0x11, 0x39, 0xfd, 0x4c, 0x2b, 0xc6, 0x2e, 0xe1, 0xe9, 0x14, 0x27, + 0xc2, 0x04, 0xf3, 0xe0, 0xc5, 0x16, 0xec, 0xea, 0xfc, 0x1a, 0x18, 0xc7, 0xff, + 0xfc, 0xfa, 0xef, 0xd2, 0x01, 0x21, 0x33, 0x00, 0x7f, 0xe9, 0x2b, 0x08, 0x49, + 0xe0, 0x27, 0x2a, 0xf4, 0xdd, 0xfa, 0x21, 0x1c, 0x62, 0xd9, 0xf5, 0xcc, 0xf1, + 0x29, 0xe3, 0x8e, 0xe9, 0x19, 0x31, 0xb2, 0x67, 0xff, 0x37, 0x1a, 0xf6, 0x0c, + 0xe6, 0x0c, 0xcb, 0x08, 0x04, 0x10, 0xfb, 0xfc, 0x09, 0xde, 0x01, 0x03, 0xee, + 0xfd, 0xd1, 0x0d, 0x4a, 0xcd, 0xd0, 0x1d, 0x2d, 0xd4, 0x09, 0x2a, 0x30, 0x02, + 0x1a, 0x10, 0x0d, 0xf9, 0x4b, 0xdd, 0xf3, 0x24, 0x14, 0xe9, 0x01, 0xef, 0x17, + 0x4c, 0x1a, 0x26, 0xf3, 0x06, 0xee, 0xe3, 0x26, 0xd5, 0x36, 0x4a, 0x00, 0x08, + 0x02, 0xfb, 0xad, 0x24, 0x04, 0xf4, 0xdb, 0x0d, 0x2b, 0xe1, 0xf8, 0xe1, 0xc7, + 0x1a, 0xd0, 0x0d, 0xcb, 0x1b, 0xeb, 0x07, 0xdb, 0xe9, 0xd3, 0xdc, 0xb7, 0x41, + 0xf9, 0x0b, 0x1e, 0x17, 0xfc, 0x17, 0x09, 0xc7, 0x1b, 0x1d, 0xd9, 0xda, 0xf9, + 0x15, 0x04, 0xe7, 0xc8, 0x5a, 0xe3, 0xec, 0xfb, 0x4c, 0xe8, 0xf5, 0x49, 0x04, + 0xd5, 0x2c, 0xb8, 0x81, 0xde, 0xef, 0x0c, 0x30, 0xe8, 0xe7, 0x02, 0x1c, 0xfb, + 0x03, 0x20, 0x19, 0x07, 0xef, 0x07, 0xd7, 0x0a, 0x3c, 0xeb, 0x1d, 0x1b, 0x0c, + 0xf5, 0x05, 0xf0, 0x2d, 0x21, 0xce, 0xdf, 0xf9, 0xfb, 0x5a, 0x14, 0xf0, 0x2a, + 0x01, 0x4d, 0xf0, 0xeb, 0xf3, 0x14, 0xca, 0x0d, 0x34, 0xfb, 0x22, 0xfa, 0xe4, + 0x08, 0x16, 0xd3, 0xf1, 0x0b, 0x32, 0x18, 0x15, 0xf8, 0xe2, 0x33, 0xe1, 0x0c, + 0x1a, 0xfe, 0x03, 0xfb, 0xe6, 0xd4, 0x16, 0xe7, 0xca, 0x19, 0x1b, 0x16, 0x1a, + 0xfc, 0x1e, 0xfa, 0xcc, 0xc0, 0x44, 0xd8, 0x12, 0x30, 0xfe, 0xfd, 0xd6, 0xdb, + 0xfc, 0xf5, 0xf6, 0x2f, 0xfe, 0xcc, 0xd8, 0x12, 0x16, 0xcc, 0x81, 0x1c, 0x9a, + 0x29, 0x20, 0x13, 0x0e, 0x2e, 0x00, 0xfa, 0xfb, 0xca, 0x1d, 0x12, 0xfa, 0x15, + 0xdc, 0xe7, 0xd4, 0x03, 0xe5, 0xf7, 0x45, 0x00, 0xb9, 0x22, 0xf3, 0xde, 0x09, + 0x39, 0x0a, 0xdb, 0x00, 0xf8, 0xda, 0xe9, 0x0c, 0x15, 0x11, 0x12, 0xc7, 0x1a, + 0xff, 0x12, 0xdb, 0xfb, 0xef, 0xd7, 0xad, 0xfc, 0xff, 0xf6, 0xdc, 0x01, 0xf3, + 0x0b, 0x24, 0xf1, 0xed, 0xd1, 0xd6, 0x43, 0xd3, 0xff, 0xdd, 0x23, 0xf2, 0x28, + 0xc9, 0x03, 0x13, 0x0a, 0xee, 0xdf, 0x02, 0xcf, 0x02, 0xda, 0x0d, 0x29, 0xfc, + 0x21, 0xe5, 0xe8, 0x41, 0xef, 0xc7, 0xd3, 0xf4, 0xcd, 0x0a, 0x03, 0x06, 0xf9, + 0x26, 0xe3, 0x28, 0x20, 0x3f, 0xe2, 0xd6, 0x25, 0x44, 0x06, 0x45, 0x67, 0x21, + 0xdd, 0x21, 0x16, 0x0c, 0x2c, 0xf0, 0x1a, 0xcc, 0xc1, 0x10, 0x17, 0xf6, 0x05, + 0x2f, 0xe2, 0xe9, 0xec, 0xf3, 0xb5, 0xf2, 0x20, 0x0d, 0x11, 0xca, 0xa0, 0xff, + 0xe4, 0xe1, 0x97, 0x26, 0xc8, 0xc4, 0xe0, 0x43, 0x21, 0xd5, 0xc9, 0xca, 0x00, + 0x33, 0x32, 0x26, 0x0f, 0xef, 0xae, 0xda, 0x3c, 0xe0, 0x3f, 0x1c, 0xc3, 0x1a, + 0xf8, 0xd5, 0x11, 0x21, 0x58, 0xc8, 0x08, 0x2e, 0x23, 0x21, 0xd7, 0x08, 0xf2, + 0x31, 0xe6, 0xe7, 0xef, 0xe7, 0xca, 0xee, 0xdd, 0xe1, 0x47, 0x0b, 0x1a, 0x04, + 0xfe, 0xf2, 0xf2, 0xc9, 0xf5, 0x1d, 0xe7, 0x03, 0x11, 0x02, 0x32, 0x14, 0xf9, + 0xe2, 0xc5, 0xea, 0xdc, 0x0e, 0x45, 0xf2, 0x2d, 0xd6, 0xf2, 0x04, 0x2c, 0xe3, + 0x7f, 0x2f, 0x29, 0x59, 0xf8, 0x24, 0x52, 0x46, 0xef, 0x59, 0x73, 0x8d, 0x15, + 0xfc, 0xcc, 0x7e, 0xec, 0x0e, 0xc6, 0xe2, 0x4f, 0x15, 0x2c, 0xeb, 0x3c, 0xfa, + 0x04, 0x03, 0x5c, 0xda, 0x15, 0x35, 0xe4, 0xdf, 0xbc, 0x07, 0x1d, 0xfd, 0xfa, + 0x51, 0x3a, 0xf6, 0x54, 0x09, 0x91, 0x04, 0xe4, 0xec, 0x27, 0x15, 0xe1, 0xae, + 0x3c, 0x08, 0xf0, 0xea, 0x01, 0xe3, 0xf5, 0x7f, 0x35, 0x3f, 0x04, 0xc4, 0xdd, + 0x75, 0x28, 0x10, 0x50, 0xf4, 0xdc, 0xaa, 0x42, 0xd2, 0x9b, 0x09, 0xf4, 0x47, + 0x57, 0xf1, 0x3f, 0xe6, 0xdb, 0xec, 0x30, 0x72, 0x90, 0x96, 0x4f, 0xe6, 0xd2, + 0xf4, 0x01, 0x22, 0xea, 0x21, 0x0c, 0xa4, 0xfe, 0xf6, 0x3b, 0x6d, 0xc0, 0xf0, + 0xf5, 0xf0, 0xf5, 0x00, 0x5e, 0xce, 0x38, 0xb3, 0x27, 0x96, 0x97, 0xf9, 0xec, + 0xb8, 0xc5, 0x10, 0xf8, 0x12, 0xc5, 0xf3, 0x97, 0x20, 0xe7, 0xf3, 0xe5, 0xb4, + 0x23, 0xe4, 0x0d, 0x3f, 0xa8, 0x17, 0xcf, 0x0d, 0x4c, 0x18, 0xdd, 0x10, 0xf8, + 0x81, 0x28, 0x00, 0xeb, 0xd8, 0xfa, 0x36, 0x49, 0xfa, 0x2b, 0xdc, 0xea, 0x24, + 0xdb, 0xb8, 0x09, 0x20, 0x67, 0x12, 0x0f, 0x12, 0x07, 0x01, 0x9b, 0xba, 0x0d, + 0xc0, 0x6f, 0x07, 0xec, 0xc0, 0x20, 0x27, 0x11, 0xe1, 0x22, 0x1b, 0x0f, 0x2f, + 0xe9, 0x34, 0xc1, 0x11, 0xbf, 0xd6, 0xce, 0xad, 0x02, 0x1a, 0x2d, 0x1f, 0xe1, + 0x06, 0x2e, 0x06, 0xe6, 0x02, 0x34, 0xd2, 0xab, 0x1b, 0x71, 0x08, 0xec, 0xd7, + 0xd4, 0x2b, 0xe2, 0x26, 0xf7, 0x01, 0xfc, 0x30, 0x00, 0x57, 0xea, 0xc0, 0x0b, + 0x0a, 0xc0, 0x1b, 0xdd, 0x51, 0x1d, 0xda, 0x6d, 0xc6, 0x29, 0xfe, 0x04, 0x38, + 0xf4, 0x0f, 0x1b, 0xfc, 0xbb, 0x51, 0xd6, 0x2c, 0xf4, 0x2e, 0xa5, 0xc7, 0xe9, + 0x23, 0xec, 0x51, 0x12, 0xfb, 0xcc, 0x0c, 0xed, 0x75, 0xac, 0xe9, 0x31, 0x37, + 0x21, 0x5b, 0xcc, 0xcf, 0xde, 0xd0, 0x6c, 0x63, 0x0d, 0xc9, 0x2b, 0x4c, 0xe8, + 0xb8, 0x27, 0xe2, 0xa3, 0x47, 0xef, 0x1b, 0x26, 0xec, 0xc6, 0xfb, 0x64, 0x14, + 0xcd, 0xf3, 0x08, 0x30, 0x19, 0xbf, 0x28, 0xe4, 0x06, 0xd7, 0x84, 0xd4, 0x45, + 0x8b, 0x06, 0xe8, 0xab, 0xdc, 0x39, 0x17, 0x2c, 0xd2, 0xa8, 0x4e, 0x10, 0xd9, + 0xb0, 0xe4, 0x3d, 0xb7, 0x01, 0xce, 0xe3, 0xd5, 0x03, 0x10, 0xed, 0xe5, 0x32, + 0x4c, 0xbb, 0x1d, 0x2f, 0xbf, 0xba, 0x22, 0x08, 0x2e, 0x6f, 0x28, 0xa5, 0xbc, + 0xfa, 0xe8, 0xad, 0x8f, 0x92, 0xe3, 0xe4, 0x29, 0x14, 0xe4, 0xdd, 0xd2, 0xf6, + 0xd1, 0xd2, 0x29, 0x06, 0xc9, 0xe7, 0xe8, 0x0c, 0x6d, 0x5d, 0x27, 0x20, 0xc4, + 0xaf, 0x0b, 0xeb, 0x26, 0x91, 0xe2, 0xf2, 0x14, 0x0f, 0x81, 0x21, 0x04, 0xd0, + 0x17, 0x5e, 0x07, 0x1b, 0x62, 0x26, 0x15, 0x23, 0xfb, 0xe3, 0x2f, 0x00, 0xe3, + 0xe4, 0xcc, 0xf7, 0x9f, 0x18, 0x0b, 0x08, 0x2b, 0xf3, 0xd6, 0xfc, 0xf0, 0xf5, + 0xc2, 0xba, 0xd6, 0xa3, 0xb3, 0x0f, 0x10, 0xfb, 0x11, 0x26, 0xde, 0x18, 0x12, + 0xfa, 0x13, 0xfe, 0xb6, 0xf4, 0xf5, 0x30, 0xd1, 0xcf, 0xfc, 0xfe, 0x19, 0xd4, + 0xbf, 0x24, 0xc1, 0xc4, 0xdc, 0x2f, 0xec, 0x47, 0x49, 0xa8, 0xe4, 0x19, 0x11, + 0xfb, 0x9b, 0x1f, 0xe1, 0xd2, 0x38, 0xe3, 0xf1, 0x32, 0xff, 0xd8, 0x0a, 0x14, + 0xd6, 0x1c, 0xb9, 0x54, 0xdd, 0x37, 0xce, 0xd1, 0xfd, 0xde, 0x09, 0xbb, 0xe8, + 0x12, 0xfc, 0xf2, 0x10, 0x1e, 0xfb, 0xe5, 0xe5, 0x1d, 0xd0, 0x0a, 0xdb, 0x81, + 0xe3, 0xe8, 0xe8, 0x3f, 0xa6, 0xd9, 0xf3, 0xf3, 0x20, 0x2b, 0xf8, 0x3b, 0x19, + 0x40, 0xf1, 0xc0, 0x1d, 0x7d, 0x0e, 0x55, 0x46, 0xc1, 0xf5, 0xe3, 0x14, 0x62, + 0xf0, 0x13, 0xe5, 0x05, 0xe5, 0x0b, 0xca, 0x10, 0xf9, 0xe0, 0xde, 0x45, 0xd2, + 0x28, 0x2c, 0x3f, 0xef, 0x47, 0xd3, 0x1d, 0xd6, 0xe1, 0xb4, 0x10, 0xff, 0x29, + 0x36, 0x5d, 0xe8, 0x1b, 0x02, 0xe4, 0x0f, 0x04, 0x0e, 0xf5, 0xdd, 0x09, 0x28, + 0x0c, 0x1a, 0x26, 0x0e, 0xe6, 0xab, 0x81, 0xda, 0xdc, 0x38, 0xcc, 0xef, 0xc6, + 0xb3, 0x12, 0x01, 0xc4, 0xd1, 0xe8, 0xf2, 0xfa, 0x38, 0x0f, 0x53, 0x42, 0xfd, + 0xfc, 0xc4, 0xc0, 0x19, 0xd9, 0x30, 0x12, 0xf8, 0x23, 0xad, 0xfa, 0x19, 0xf0, + 0x27, 0x14, 0xf3, 0xb3, 0xdd, 0xf9, 0xbf, 0x42, 0xdc, 0x1f, 0x2c, 0x35, 0xe6, + 0xd3, 0xc3, 0xee, 0x0b, 0x03, 0xe1, 0x1b, 0xa0, 0x07, 0x09, 0x04, 0x8d, 0xfe, + 0x0c, 0xda, 0x34, 0xc0, 0xfa, 0x25, 0x0a, 0x2f, 0x1e, 0xe4, 0xf3, 0x13, 0xe6, + 0xf1, 0xbd, 0xd0, 0xf8, 0x43, 0xe2, 0x04, 0xce, 0x33, 0x00, 0x1e, 0xbb, 0xb3, + 0xe5, 0xf2, 0xe7, 0xed, 0xea, 0x11, 0x19, 0xfe, 0xfc, 0x19, 0x27, 0xd8, 0xc0, + 0x09, 0x75, 0xfe, 0xf2, 0xf9, 0xcf, 0xf8, 0xf7, 0x03, 0xeb, 0x10, 0x19, 0x3f, + 0x3d, 0xe0, 0x3d, 0x22, 0x23, 0xef, 0x02, 0x42, 0xe5, 0xd6, 0x32, 0xfa, 0x08, + 0x38, 0xe3, 0xca, 0x5f, 0x16, 0xc3, 0xc4, 0x02, 0x4c, 0xd5, 0x08, 0xa4, 0xfa, + 0x29, 0xf9, 0xe6, 0x37, 0xfe, 0xfd, 0xdc, 0xbd, 0x48, 0x12, 0x3c, 0xf4, 0xed, + 0x0d, 0x04, 0x04, 0xe5, 0x12, 0x04, 0xe2, 0xc7, 0x17, 0xdc, 0x40, 0x2c, 0xe5, + 0xe5, 0x31, 0x0b, 0xd3, 0xcb, 0x25, 0xf0, 0xfd, 0xff, 0x12, 0x25, 0xda, 0x18, + 0x1c, 0x0c, 0xf7, 0xd3, 0x11, 0x4c, 0xd9, 0x05, 0xd2, 0x08, 0xee, 0x3f, 0x19, + 0xd3, 0xf5, 0xd9, 0xe4, 0x12, 0x0f, 0x25, 0x30, 0xeb, 0x11, 0xe9, 0x22, 0x12, + 0x81, 0x04, 0xd9, 0xe1, 0x1a, 0x22, 0x07, 0x35, 0x01, 0xb6, 0xdf, 0xef, 0x06, + 0x15, 0xdb, 0x3e, 0x0b, 0xcb, 0x0b, 0x01, 0x3e, 0x0f, 0xbc, 0xe7, 0xf3, 0x2f, + 0x08, 0x27, 0x3a, 0xb6, 0xd3, 0x4d, 0xf8, 0xe7, 0x2e, 0x77, 0x8f, 0xed, 0x21, + 0x28, 0xe9, 0xfb, 0xee, 0x0c, 0xd1, 0xfc, 0xec, 0xfa, 0xfa, 0xf5, 0xf1, 0x1f, + 0x1d, 0xce, 0x04, 0x22, 0xb6, 0x1d, 0x1a, 0xd5, 0x72, 0x9f, 0x34, 0x01, 0xc9, + 0x03, 0x08, 0xe4, 0x39, 0xff, 0xcf, 0x13, 0xf6, 0xf0, 0x35, 0xfb, 0x79, 0xa8, + 0xe8, 0xf3, 0xee, 0x0b, 0xe9, 0x15, 0x3c, 0xf8, 0xc0, 0x44, 0xb8, 0xe2, 0xec, + 0x08, 0x24, 0xbf, 0x14, 0x2b, 0xe5, 0xe6, 0x22, 0xfc, 0x12, 0x0d, 0x1d, 0xc8, + 0xf6, 0x0c, 0xdb, 0x46, 0xfe, 0xc5, 0x8b, 0x83, 0x0e, 0x25, 0x32, 0x46, 0xbe, + 0x8f, 0xd8, 0xc4, 0xd9, 0xf6, 0x3d, 0x41, 0xed, 0x20, 0xf2, 0xd5, 0x42, 0xe0, + 0x2e, 0x20, 0xfe, 0x0e, 0x2e, 0xe3, 0xed, 0x0b, 0x7f, 0x24, 0x5b, 0xdf, 0xed, + 0xfa, 0xd1, 0xf2, 0x69, 0x29, 0x72, 0x13, 0xd0, 0x60, 0xee, 0xf9, 0xc3, 0x2d, + 0xff, 0xf8, 0xfd, 0x1b, 0xf8, 0x07, 0x3d, 0x1b, 0xbe, 0xe6, 0x02, 0xd6, 0x2f, + 0x29, 0x15, 0xe3, 0x26, 0xc7, 0xde, 0x30, 0x2f, 0xf6, 0xe9, 0x2a, 0x8f, 0x1c, + 0x0b, 0xd9, 0x1c, 0x01, 0xc8, 0x06, 0xf3, 0x31, 0xc0, 0x00, 0xf4, 0x33, 0x11, + 0xe9, 0x23, 0xdd, 0xf2, 0xfc, 0x11, 0xfb, 0x4f, 0x1f, 0xb7, 0x19, 0xc0, 0x19, + 0xf4, 0x22, 0x26, 0x0a, 0x1e, 0xd9, 0xfb, 0x18, 0x12, 0x12, 0xf5, 0x10, 0x08, + 0xf9, 0x12, 0x4e, 0x37, 0x38, 0xeb, 0xfd, 0xf0, 0x24, 0xdb, 0xc6, 0xfc, 0xeb, + 0x1f, 0xfd, 0xc6, 0x10, 0xf1, 0x36, 0xe9, 0x16, 0xfa, 0x4a, 0xf1, 0x0a, 0xf4, + 0xee, 0xe2, 0x81, 0x33, 0x47, 0xef, 0x0c, 0x30, 0xcb, 0xe4, 0x15, 0x2d, 0x3d, + 0xf6, 0x1e, 0x32, 0xfd, 0x23, 0x04, 0xbe, 0x22, 0xfe, 0x0e, 0x30, 0xff, 0x57, + 0x19, 0xf3, 0xf5, 0x12, 0xe7, 0x21, 0x0c, 0xd4, 0xf9, 0x32, 0x1f, 0x46, 0xe1, + 0x36, 0x06, 0x4f, 0xdc, 0x02, 0x4a, 0xe5, 0x29, 0xd1, 0x41, 0xfc, 0x2e, 0x58, + 0xdb, 0xee, 0xfd, 0x11, 0x34, 0xf3, 0x0e, 0xeb, 0x51, 0xd6, 0xb8, 0x12, 0xe5, + 0x1c, 0x17, 0x3e, 0x38, 0x0a, 0xd6, 0xf1, 0x28, 0x09, 0xf1, 0x1c, 0xee, 0xaf, + 0xb0, 0x10, 0xc1, 0xe9, 0x2c, 0xc8, 0xaa, 0xb0, 0x52, 0xf0, 0x4c, 0x37, 0xd1, + 0x21, 0xff, 0x24, 0xbf, 0x38, 0x0a, 0xf4, 0xa2, 0xdc, 0x28, 0xb7, 0xf5, 0xf6, + 0xf0, 0xbd, 0x09, 0xf5, 0xe6, 0x02, 0x08, 0xfe, 0xa2, 0xdb, 0x28, 0x26, 0x26, + 0xdd, 0x15, 0x38, 0xfd, 0xe6, 0xdd, 0x00, 0xdb, 0xea, 0xc7, 0x08, 0xa0, 0x08, + 0x30, 0x07, 0xf6, 0xb4, 0xf2, 0x1f, 0xf1, 0xcb, 0x91, 0x4b, 0xe4, 0x37, 0xf1, + 0x7f, 0x2f, 0x53, 0x03, 0xeb, 0x65, 0x05, 0xbe, 0xb3, 0xdb, 0xd3, 0x1c, 0xcb, + 0x4a, 0xf4, 0x23, 0xd8, 0x1a, 0x33, 0xc8, 0xd5, 0xfe, 0x21, 0x17, 0x35, 0x3f, + 0xfb, 0xcb, 0x06, 0xc8, 0x07, 0xf6, 0xde, 0xd3, 0xdc, 0x07, 0x02, 0x23, 0x4f, + 0x30, 0x08, 0xe5, 0xfb, 0x1c, 0xf8, 0xc6, 0xce, 0x07, 0x1d, 0x1f, 0x41, 0xea, + 0xf0, 0xce, 0x44, 0xee, 0x0c, 0xd6, 0xc6, 0x08, 0xe4, 0xd8, 0x2f, 0xf7, 0xf7, + 0xbc, 0xad, 0xe0, 0x32, 0xbf, 0xed, 0x86, 0x1b, 0xe4, 0xfc, 0xfc, 0x42, 0x16, + 0x2a, 0xc6, 0xca, 0xe8, 0xf8, 0x42, 0xf7, 0x0b, 0xf5, 0xfd, 0xf8, 0xe2, 0xe3, + 0x20, 0xfb, 0xee, 0x14, 0x25, 0x12, 0x3a, 0xe6, 0xd9, 0x16, 0xef, 0xbb, 0xed, + 0x3d, 0xe9, 0xe4, 0x1e, 0xe5, 0x17, 0x45, 0xa1, 0x32, 0xe2, 0xc0, 0x90, 0x17, + 0x29, 0x2a, 0xe5, 0x1f, 0x0a, 0x36, 0x1c, 0xd0, 0xed, 0x2f, 0x1b, 0xe9, 0x18, + 0x82, 0x0b, 0x81, 0x00, 0x15, 0x32, 0xd6, 0xe5, 0x2b, 0x24, 0xf2, 0xf1, 0xe6, + 0xc5, 0xf9, 0x0a, 0xec, 0x25, 0xd6, 0xe8, 0xdb, 0x21, 0xff, 0xc0, 0xee, 0xe7, + 0xee, 0x29, 0xe2, 0x40, 0x1b, 0x1f, 0xf9, 0x48, 0x10, 0xe1, 0x0b, 0xf9, 0xdd, + 0x20, 0xf5, 0x28, 0xdf, 0x02, 0xdf, 0xdb, 0xc5, 0x02, 0xfd, 0x45, 0x28, 0x38, + 0x1f, 0xf0, 0x40, 0xc7, 0xf0, 0xf5, 0x16, 0x18, 0xf7, 0xba, 0x36, 0xe7, 0xcf, + 0xd0, 0xf3, 0xeb, 0xc9, 0x14, 0x00, 0xee, 0xfc, 0x1c, 0xee, 0xe4, 0x0e, 0xdc, + 0x1d, 0xdb, 0x35, 0xe2, 0x05, 0x19, 0xc0, 0x4d, 0xe8, 0x16, 0xd9, 0x0c, 0xe5, + 0xe5, 0x1e, 0x03, 0xce, 0x19, 0x14, 0x81, 0x1f, 0xfb, 0x47, 0x0b, 0x03, 0x15, + 0xe8, 0x01, 0xf8, 0x13, 0xfc, 0x08, 0x02, 0x02, 0xf5, 0x0d, 0xf4, 0x28, 0x04, + 0xfd, 0xfd, 0xc2, 0x09, 0x15, 0xf9, 0xaa, 0x06, 0x0a, 0x0e, 0x00, 0x10, 0x04, + 0xb7, 0xb2, 0xc3, 0xee, 0xc9, 0x30, 0x48, 0x10, 0x5a, 0xd2, 0xe2, 0x08, 0xee, + 0xef, 0xdb, 0x00, 0x06, 0x53, 0xfe, 0x28, 0xeb, 0xf4, 0xb6, 0xfe, 0x0d, 0x25, + 0xe1, 0x17, 0x06, 0x00, 0xfc, 0x04, 0xdc, 0x3a, 0x33, 0x11, 0x41, 0x1b, 0xee, + 0x1b, 0x06, 0xd6, 0xdd, 0x2a, 0x03, 0x3e, 0xe4, 0xe7, 0x46, 0xf5, 0xec, 0x2d, + 0x1b, 0xe0, 0xe9, 0x02, 0xed, 0xfc, 0xd7, 0xfe, 0xe3, 0xf5, 0xbd, 0x27, 0xc5, + 0x2c, 0x07, 0x02, 0x38, 0x27, 0xd7, 0x37, 0xe3, 0x32, 0x81, 0xff, 0xf2, 0xd8, + 0x13, 0x52, 0xc4, 0x4e, 0x19, 0xe6, 0x30, 0xc2, 0xe5, 0xc6, 0x02, 0x9c, 0xf7, + 0xd9, 0xee, 0x02, 0x14, 0x98, 0xe2, 0x18, 0xee, 0x1a, 0xf8, 0x30, 0xdc, 0x0f, + 0x5e, 0x15, 0xe9, 0x09, 0xcf, 0xd2, 0xee, 0xe7, 0xdc, 0x2b, 0x1f, 0x62, 0x3b, + 0x00, 0x32, 0xd7, 0x1f, 0xcb, 0xe2, 0x13, 0x9b, 0x18, 0xd4, 0xde, 0x1a, 0xd7, + 0x69, 0x22, 0xeb, 0xc9, 0xaf, 0x1e, 0x1a, 0xff, 0xdb, 0xcd, 0xc7, 0xfe, 0xe7, + 0xce, 0xea, 0xb7, 0xf1, 0x16, 0xe1, 0xd8, 0xf0, 0xdf, 0x38, 0xe4, 0x4c, 0xdf, + 0x18, 0xd9, 0x3e, 0xc3, 0xca, 0x30, 0x27, 0x03, 0xf6, 0xec, 0x04, 0xc3, 0x16, + 0xb9, 0x2f, 0x16, 0x0d, 0x11, 0x31, 0xec, 0xc9, 0xf0, 0x1d, 0x02, 0xdf, 0xb5, + 0x4b, 0x3a, 0xaf, 0x22, 0xa0, 0xe2, 0x10, 0xf2, 0x52, 0x54, 0xe8, 0xb7, 0xe7, + 0x28, 0x3f, 0xcb, 0x06, 0xaa, 0x1e, 0xda, 0xd0, 0xcd, 0x1d, 0xf0, 0xc8, 0x05, + 0x03, 0x26, 0x0a, 0x11, 0xf5, 0xed, 0xf8, 0x5b, 0xed, 0x9e, 0xdd, 0xbd, 0xf7, + 0x7e, 0xba, 0xa1, 0x1b, 0x81, 0xd0, 0xe7, 0xa1, 0xfb, 0xed, 0xf6, 0xf3, 0x3c, + 0xc6, 0xc1, 0xfd, 0x2b, 0x28, 0x0d, 0xd9, 0xce, 0xf9, 0xf4, 0x44, 0xf0, 0x05, + 0x28, 0x06, 0x99, 0xba, 0x9c, 0xf4, 0x99, 0x06, 0xf0, 0x1f, 0xea, 0xe0, 0xd7, + 0xd4, 0xe6, 0x05, 0x3f, 0xab, 0x1d, 0x0c, 0xaa, 0xa2, 0xce, 0x48, 0xd1, 0xbb, + 0xc6, 0x1b, 0xe0, 0xfe, 0xd2, 0xcf, 0xc8, 0xff, 0xd5, 0xf2, 0xdd, 0x3a, 0xac, + 0x59, 0x11, 0x06, 0xb1, 0x3f, 0xfb, 0xe5, 0xbc, 0x50, 0x35, 0x20, 0x18, 0xea, + 0x6a, 0x26, 0xdd, 0x38, 0xdb, 0x36, 0xf3, 0x1c, 0xe3, 0x48, 0xf8, 0x60, 0x67, + 0x1e, 0xd9, 0xeb, 0xe0, 0xf2, 0xdd, 0xce, 0x1c, 0x3e, 0x18, 0x0e, 0xa6, 0xfe, + 0xdf, 0x0c, 0xd1, 0xcc, 0x2c, 0xdb, 0x0e, 0xec, 0xc0, 0x17, 0x2b, 0xe5, 0xfa, + 0x41, 0x21, 0xb0, 0xfb, 0xc2, 0x42, 0x24, 0x2b, 0x2f, 0xdb, 0xe4, 0xc8, 0x40, + 0x3f, 0x17, 0xb5, 0xd2, 0xf7, 0x15, 0x2e, 0x18, 0xc0, 0xa2, 0x3f, 0x6d, 0xe3, + 0xe1, 0xb8, 0xc3, 0xba, 0xfb, 0x2c, 0x0d, 0xea, 0x15, 0xc7, 0x06, 0xdf, 0xe0, + 0x55, 0xc5, 0xbf, 0x0a, 0xf1, 0xe3, 0xe3, 0xef, 0x1d, 0x7f, 0xef, 0xef, 0x4a, + 0xfd, 0x1a, 0x25, 0x04, 0xfe, 0x03, 0xd9, 0xf2, 0xef, 0x12, 0x28, 0xef, 0x36, + 0xcf, 0x21, 0x14, 0x0d, 0x21, 0xf6, 0xfa, 0xfc, 0xf3, 0xe7, 0xed, 0xd6, 0xdd, + 0xe2, 0xed, 0xb8, 0xf0, 0xe6, 0x1d, 0x17, 0xf3, 0x13, 0xf0, 0xd6, 0x00, 0xcc, + 0xe6, 0x00, 0x09, 0xff, 0xe5, 0xb7, 0xd8, 0xf8, 0x04, 0x07, 0xe2, 0xf6, 0xe3, + 0xf5, 0x06, 0xfd, 0xde, 0xfb, 0xb8, 0x18, 0xff, 0x02, 0xf1, 0x6d, 0xfe, 0x0d, + 0xfc, 0x21, 0xbb, 0x0b, 0xdf, 0xe1, 0xf8, 0xde, 0x27, 0xe6, 0xfa, 0x3c, 0xbb, + 0xfe, 0x17, 0x00, 0xdb, 0x1d, 0xf0, 0xd9, 0xbe, 0x12, 0x7f, 0xe9, 0xd1, 0xf7, + 0xe4, 0x08, 0xcc, 0xe6, 0xfb, 0xda, 0xe6, 0xf9, 0xf3, 0xeb, 0xf1, 0xec, 0xef, + 0x17, 0x11, 0xf0, 0xfc, 0x2d, 0xf7, 0xf9, 0xc6, 0xec, 0x43, 0xf6, 0x01, 0xfb, + 0xcc, 0xe4, 0xdb, 0x3c, 0x3e, 0xff, 0x0f, 0x15, 0xe4, 0xfb, 0xdd, 0xfe, 0x02, + 0xfa, 0xe3, 0x11, 0x24, 0x0f, 0x0a, 0x0f, 0xe4, 0x05, 0xcd, 0xa7, 0x0d, 0x8a, + 0x33, 0xe8, 0x2d, 0xfc, 0x49, 0x06, 0xb4, 0xe7, 0xe1, 0x1f, 0x0c, 0xf3, 0x3c, + 0xfc, 0xc4, 0xf7, 0xf8, 0x27, 0x2c, 0xe8, 0xcc, 0xe7, 0xa3, 0xb8, 0x44, 0xdc, + 0xf8, 0x2a, 0x54, 0x92, 0xd7, 0x04, 0xca, 0x81, 0xc5, 0xdd, 0xf7, 0xc9, 0x63, + 0x07, 0xfc, 0x00, 0x0a, 0x34, 0x2b, 0x43, 0xd8, 0xca, 0xe0, 0xc3, 0xb0, 0x12, + 0xfa, 0xf9, 0xa5, 0xd6, 0xc4, 0xe3, 0xff, 0xe7, 0xf9, 0x23, 0xbf, 0x4c, 0xbb, + 0xc5, 0xfe, 0x2b, 0x43, 0xf6, 0xbb, 0xfe, 0x39, 0xdc, 0x09, 0xc1, 0x99, 0x4f, + 0xf8, 0xe1, 0xe6, 0x38, 0xd8, 0x16, 0x11, 0xf7, 0x41, 0xd5, 0x1c, 0x02, 0x00, + 0xa9, 0x13, 0x02, 0xf1, 0x3f, 0x3a, 0x52, 0xba, 0xa1, 0x85, 0x8d, 0x25, 0xc9, + 0xdf, 0xdf, 0x01, 0x1f, 0x38, 0xea, 0x16, 0x26, 0x2c, 0x12, 0x26, 0xfd, 0x2c, + 0x13, 0xf6, 0x1e, 0x1f, 0x1c, 0xdd, 0xc9, 0x7f, 0x03, 0xcd, 0x04, 0x0a, 0xf3, + 0x15, 0xe2, 0x48, 0x0e, 0x38, 0xd6, 0x24, 0x11, 0x36, 0x05, 0x32, 0x17, 0x00, + 0x24, 0xf9, 0xd1, 0x24, 0x2b, 0xc2, 0xc0, 0xf9, 0xff, 0xcc, 0x0b, 0x34, 0xf0, + 0x27, 0xfb, 0xe4, 0x2c, 0x0a, 0xf7, 0xf3, 0xe1, 0xac, 0xfd, 0xe2, 0xf5, 0xdc, + 0xd8, 0x05, 0xa0, 0x0d, 0x5d, 0x04, 0xe5, 0xca, 0xfd, 0x35, 0xef, 0xd4, 0x1f, + 0x04, 0xb9, 0x0b, 0xd7, 0xed, 0xd8, 0x09, 0x05, 0xf4, 0x0e, 0xdd, 0xf2, 0xd5, + 0xf9, 0x37, 0xdf, 0x25, 0x20, 0xdb, 0xf5, 0x14, 0xf1, 0x12, 0xec, 0xcd, 0xd9, + 0xca, 0x2c, 0x2c, 0xe1, 0xfa, 0x5f, 0xb8, 0xf5, 0x01, 0x09, 0x26, 0x0f, 0xd5, + 0xf1, 0x14, 0x3c, 0xec, 0xd3, 0xdf, 0x41, 0x11, 0x3a, 0xf6, 0xce, 0x11, 0xd7, + 0x2a, 0x4d, 0x01, 0x0b, 0xec, 0xfb, 0x0a, 0x55, 0xd7, 0x01, 0xbc, 0x38, 0xe4, + 0xd3, 0xf6, 0xef, 0x34, 0xb8, 0xf2, 0x92, 0x2d, 0x91, 0xb8, 0x22, 0xf5, 0x2b, + 0xce, 0x1a, 0xbf, 0x70, 0x07, 0x36, 0xe9, 0x99, 0x1d, 0x0a, 0x08, 0x29, 0xce, + 0xee, 0xfc, 0x5d, 0xb7, 0xf2, 0xa2, 0xd3, 0x38, 0x2f, 0x6a, 0x31, 0x34, 0x41, + 0xc4, 0x0e, 0x1d, 0x20, 0x5d, 0x94, 0x1a, 0xbd, 0xb5, 0xc6, 0xd0, 0x43, 0xdb, + 0x3d, 0x44, 0xf8, 0xba, 0x0a, 0xe5, 0x2d, 0xf2, 0xd8, 0x03, 0xf7, 0x33, 0xbe, + 0x1d, 0x4b, 0x09, 0xd6, 0x09, 0x1c, 0xe9, 0x46, 0x0c, 0x17, 0xf5, 0xf0, 0xc9, + 0x34, 0x56, 0xb1, 0xba, 0x31, 0xcf, 0x0e, 0x22, 0x0b, 0x47, 0x4e, 0x1d, 0x05, + 0x38, 0x81, 0x73, 0x2a, 0xce, 0x01, 0x4f, 0xe4, 0xb0, 0x4e, 0x94, 0xf5, 0xac, + 0xd1, 0xe8, 0x16, 0x10, 0x0c, 0xf8, 0x3b, 0xb8, 0x12, 0xe3, 0xf5, 0x59, 0x64, + 0x1c, 0x38, 0xe6, 0x10, 0xd0, 0xcc, 0xc9, 0x23, 0xd6, 0xf8, 0xf9, 0xf8, 0xf1, + 0x19, 0x0b, 0x0f, 0x0f, 0x05, 0xc7, 0xe7, 0x0c, 0xdd, 0x0c, 0x0f, 0x17, 0xf8, + 0xf8, 0xf6, 0x09, 0xf9, 0xd6, 0x1b, 0x53, 0x5b, 0xf0, 0xde, 0xe9, 0x1b, 0x33, + 0x05, 0x37, 0xbd, 0x2d, 0x24, 0xde, 0x19, 0xac, 0x21, 0x4c, 0x0b, 0x1b, 0x14, + 0xd5, 0x36, 0x23, 0xe6, 0x20, 0x26, 0x22, 0xf7, 0xad, 0xe6, 0xd1, 0xdc, 0x97, + 0xca, 0x20, 0x3e, 0x12, 0xb4, 0x2d, 0x34, 0xe7, 0x35, 0x1c, 0x39, 0xc1, 0xb5, + 0x08, 0xc0, 0x21, 0x1d, 0xec, 0x31, 0x0a, 0x1d, 0x17, 0xd4, 0xe2, 0xff, 0xf4, + 0xdf, 0x3d, 0xf5, 0xdf, 0x02, 0x48, 0xe8, 0x06, 0xd7, 0x15, 0x17, 0xf7, 0xee, + 0x7f, 0x24, 0x07, 0xe2, 0x01, 0xc9, 0x18, 0x2e, 0xfc, 0xfe, 0x12, 0xda, 0xd8, + 0x07, 0x08, 0xfb, 0xea, 0xfa, 0x01, 0x07, 0xe5, 0x1b, 0x00, 0xd9, 0xcf, 0x32, + 0xf2, 0xef, 0xb4, 0xeb, 0xfd, 0xf9, 0x33, 0xd7, 0x07, 0xbb, 0xf4, 0x0f, 0xe9, + 0xf9, 0x66, 0xf7, 0x2c, 0x24, 0xa3, 0xef, 0xf8, 0x2a, 0x1c, 0x3e, 0x8e, 0xf0, + 0xaa, 0xd1, 0x05, 0x12, 0x9e, 0x14, 0xec, 0x47, 0x20, 0x27, 0x56, 0xe8, 0x36, + 0xa0, 0x81, 0xa5, 0xa2, 0xf7, 0x0b, 0x1b, 0xdc, 0xb0, 0xb6, 0xf6, 0xff, 0xf4, + 0x26, 0xe7, 0xce, 0xc3, 0x02, 0x95, 0x5e, 0x8f, 0xd4, 0xb3, 0xb9, 0xe2, 0x28, + 0xfa, 0x00, 0x0f, 0x1a, 0xee, 0x2a, 0x02, 0xcf, 0xb9, 0xea, 0xa8, 0x03, 0x3a, + 0xff, 0xcf, 0x07, 0xe5, 0x2d, 0x3f, 0x32, 0xc0, 0x0f, 0xdf, 0xd3, 0xd5, 0x0d, + 0xe6, 0x10, 0xe4, 0x11, 0xbd, 0xb0, 0x09, 0x12, 0x00, 0xd6, 0x37, 0x22, 0x36, + 0xd3, 0xf6, 0x8a, 0xeb, 0xd9, 0x20, 0xe2, 0xfb, 0xde, 0x14, 0x8c, 0xc0, 0xd0, + 0xe8, 0x21, 0xe9, 0xab, 0xd6, 0x0c, 0x1c, 0x03, 0x4e, 0xf7, 0x14, 0xbf, 0x0e, + 0xab, 0x03, 0x3f, 0x22, 0xcf, 0x52, 0xc6, 0x33, 0x7f, 0xc7, 0xd2, 0x14, 0x10, + 0x1d, 0x0d, 0x02, 0xae, 0xcd, 0xc8, 0xd8, 0xff, 0xfc, 0xd7, 0x1e, 0x13, 0xe0, + 0x2d, 0xff, 0x28, 0x1f, 0x00, 0x22, 0x21, 0x10, 0x0e, 0xf9, 0xc0, 0x1c, 0x28, + 0x26, 0x9d, 0x20, 0x1a, 0xd6, 0x21, 0x2a, 0x2d, 0x1a, 0xe4, 0xf3, 0xea, 0x14, + 0x0d, 0x0c, 0x19, 0x09, 0xcb, 0x4f, 0x51, 0xd0, 0x09, 0x2f, 0xdc, 0x8c, 0x23, + 0x12, 0xae, 0x29, 0xe2, 0xf6, 0x21, 0x29, 0x32, 0x22, 0x18, 0x23, 0xf9, 0x47, + 0xd0, 0x44, 0x23, 0x05, 0xe6, 0x17, 0x04, 0x07, 0x05, 0xf8, 0xff, 0x49, 0x0a, + 0x1f, 0x0b, 0xf0, 0x54, 0x23, 0x0a, 0x0a, 0x05, 0x0c, 0x01, 0x1b, 0xde, 0xf7, + 0xde, 0xe1, 0xd5, 0x08, 0x4f, 0x1b, 0xf1, 0x22, 0x27, 0xb5, 0x1e, 0x14, 0xdb, + 0x23, 0xc8, 0xfa, 0xd9, 0xf2, 0xf0, 0xd6, 0x17, 0xee, 0x38, 0xec, 0x29, 0xe2, + 0x26, 0xcf, 0xbc, 0xe3, 0xf9, 0x1b, 0xdd, 0xcf, 0x0b, 0xe8, 0xea, 0xea, 0x3d, + 0xea, 0x2c, 0xfa, 0xc5, 0x1c, 0xfa, 0xe4, 0xea, 0xfb, 0xd4, 0x31, 0xef, 0xe6, + 0xf9, 0xcd, 0xd3, 0xe4, 0xf0, 0xc2, 0xec, 0xe9, 0x08, 0xbb, 0x01, 0x4a, 0x19, + 0x1a, 0xfc, 0x22, 0x81, 0xee, 0x44, 0xf6, 0x2e, 0x2a, 0xf3, 0x04, 0x1a, 0xde, + 0xef, 0xf5, 0x22, 0x03, 0xe2, 0xf9, 0xf9, 0x0b, 0x0d, 0x4f, 0xf6, 0xd1, 0xe2, + 0xb6, 0x2e, 0x17, 0xf3, 0x0b, 0xd7, 0x47, 0xed, 0xb8, 0xf2, 0xfa, 0x29, 0xee, + 0x00, 0xf9, 0x19, 0xe2, 0xf0, 0xf6, 0xde, 0xe7, 0x2d, 0x29, 0x14, 0x0b, 0x18, + 0x37, 0xf8, 0x05, 0x1e, 0xeb, 0xe6, 0x22, 0xf7, 0x08, 0xfb, 0x05, 0x0a, 0x02, + 0x2f, 0xef, 0x0e, 0x00, 0xea, 0xfa, 0xe2, 0x07, 0x07, 0xee, 0xd1, 0xfc, 0xc9, + 0xf3, 0x19, 0x21, 0x28, 0xe5, 0x0c, 0xf0, 0xe1, 0x11, 0x3e, 0xe6, 0x4b, 0xd4, + 0x24, 0x1d, 0x1a, 0xc3, 0x94, 0x34, 0x3c, 0x1e, 0xfe, 0x3e, 0xb6, 0x43, 0x5b, + 0x33, 0xe1, 0xdc, 0x01, 0x2d, 0x25, 0x30, 0x38, 0xc6, 0xd3, 0xa1, 0x50, 0xcb, + 0x11, 0x0c, 0xc3, 0xe7, 0x2b, 0x44, 0x07, 0x11, 0x18, 0x14, 0x00, 0xf2, 0xc0, + 0x57, 0xb4, 0xae, 0xea, 0x06, 0xed, 0xb9, 0xf4, 0xe5, 0xe4, 0x36, 0x39, 0x0c, + 0xfa, 0xba, 0x05, 0x31, 0x2a, 0xc8, 0x50, 0x38, 0xde, 0xee, 0x2d, 0x3c, 0xfd, + 0x31, 0xd1, 0xff, 0x33, 0xa9, 0x2c, 0x21, 0x6d, 0x31, 0xdb, 0xd3, 0x04, 0x55, + 0x1f, 0xbe, 0x09, 0x28, 0x90, 0x0e, 0x79, 0xf5, 0xdb, 0x3a, 0xc0, 0xd9, 0x33, + 0xb5, 0xda, 0xd2, 0xb2, 0x17, 0x0a, 0xe8, 0xf9, 0x20, 0x24, 0x04, 0xf8, 0x11, + 0x1f, 0x12, 0xf5, 0x32, 0xa9, 0xfb, 0xe6, 0x08, 0xf2, 0xe7, 0x10, 0x12, 0x42, + 0x2a, 0xd3, 0xdb, 0x21, 0xd0, 0x7f, 0xab, 0x1b, 0x1f, 0x27, 0xd5, 0xad, 0x27, + 0x1c, 0xed, 0x0c, 0x31, 0xcd, 0x10, 0x17, 0xa7, 0x26, 0x56, 0x16, 0xee, 0x0f, + 0x68, 0x41, 0x1c, 0xdd, 0x0d, 0xdc, 0x19, 0x3c, 0xeb, 0x04, 0xae, 0x35, 0xe6, + 0x2f, 0xf8, 0x12, 0x08, 0xff, 0xc5, 0xd6, 0xac, 0xf1, 0x2f, 0xdd, 0xb5, 0xd5, + 0xfa, 0x37, 0x71, 0xeb, 0xf6, 0xa5, 0xe8, 0xfa, 0xda, 0x00, 0xd9, 0xf5, 0xc2, + 0xd0, 0x37, 0xee, 0x1c, 0xdd, 0x1a, 0xdb, 0xd9, 0x2a, 0x0b, 0xe3, 0xbe, 0x10, + 0xe6, 0xdf, 0xd2, 0x14, 0xcf, 0x7f, 0x4a, 0xde, 0xc8, 0xf9, 0xe1, 0x32, 0xf0, + 0x9f, 0xe2, 0xd8, 0xf8, 0x12, 0xc9, 0xf4, 0x04, 0x1b, 0x05, 0x27, 0x2f, 0x0d, + 0x21, 0x03, 0x20, 0x2f, 0xf9, 0xf5, 0xec, 0x29, 0x07, 0xd4, 0x2f, 0xea, 0xc7, + 0x02, 0x04, 0xa6, 0x16, 0xcc, 0xc5, 0xc5, 0xf9, 0xe5, 0xf8, 0xba, 0xfd, 0x1c, + 0x2e, 0xf6, 0x19, 0x10, 0xf1, 0x4c, 0x26, 0x09, 0xf1, 0xed, 0xc4, 0xc4, 0x75, + 0xde, 0xfe, 0xd7, 0x20, 0x50, 0xf3, 0xb1, 0xe1, 0xea, 0x28, 0x12, 0x05, 0xe7, + 0xe6, 0x1c, 0xe5, 0xd3, 0xea, 0xf0, 0xd8, 0x3f, 0xef, 0x09, 0xd5, 0xe4, 0x1a, + 0x40, 0xf2, 0x5f, 0xfc, 0x30, 0xd9, 0x82, 0xea, 0x29, 0xc5, 0x1b, 0xfa, 0xaf, + 0xd2, 0xf4, 0xd8, 0xec, 0x53, 0xdd, 0x2e, 0x37, 0xef, 0xf9, 0xe7, 0x1d, 0xff, + 0x16, 0x38, 0x18, 0x7f, 0xd8, 0xe0, 0xbc, 0xf8, 0x9a, 0xe0, 0xf5, 0x2a, 0x05, + 0x22, 0x15, 0x51, 0xef, 0xd0, 0x70, 0x22, 0x6b, 0x1a, 0xcd, 0xbb, 0x60, 0xc2, + 0xf3, 0xd8, 0x5f, 0x5f, 0xdd, 0x0c, 0xc1, 0xe0, 0xb9, 0x12, 0x0b, 0xed, 0x03, + 0x2b, 0x39, 0x1e, 0x4e, 0x2e, 0xfa, 0x3e, 0x18, 0xad, 0xca, 0x74, 0xcc, 0xe9, + 0x1b, 0x1e, 0xf6, 0x13, 0xe1, 0x14, 0x9f, 0x46, 0xcd, 0x05, 0x35, 0x47, 0x57, + 0xdf, 0xf0, 0x2c, 0x25, 0xde, 0x28, 0xc7, 0x11, 0xfe, 0x19, 0xe2, 0xfd, 0xfe, + 0xd8, 0x5d, 0xd5, 0xca, 0x97, 0x59, 0x21, 0x1e, 0x04, 0xff, 0x09, 0x4b, 0x17, + 0xc4, 0x1d, 0xc9, 0xda, 0x0a, 0xf5, 0xd0, 0x01, 0x30, 0xff, 0xb8, 0x3d, 0x20, + 0x38, 0xb9, 0x40, 0xf9, 0x2d, 0xf0, 0xe2, 0xbd, 0xcc, 0xc4, 0x07, 0xde, 0xf7, + 0xea, 0xfc, 0x46, 0xd4, 0xfb, 0x09, 0xc6, 0xf9, 0x43, 0x6b, 0xdd, 0xe2, 0xd3, + 0x18, 0xdc, 0x0b, 0x39, 0x93, 0x32, 0xfd, 0x22, 0x4c, 0x06, 0x72, 0xfd, 0xd0, + 0x18, 0x14, 0xeb, 0x43, 0x22, 0x08, 0xb6, 0x29, 0x00, 0x32, 0x7f, 0x13, 0x42, + 0xdc, 0xd5, 0x0d, 0x53, 0x10, 0x09, 0xfa, 0x5a, 0x0e, 0x13, 0xff, 0xc0, 0x18, + 0x34, 0x1f, 0x38, 0x38, 0x27, 0xc4, 0xf6, 0x19, 0x40, 0xdc, 0x30, 0xc5, 0xd7, + 0xad, 0xf2, 0xf5, 0x06, 0x07, 0xdc, 0x30, 0x01, 0x1c, 0xe8, 0x34, 0xb8, 0x3c, + 0xd1, 0xdd, 0x0c, 0xf9, 0x04, 0xc0, 0xb1, 0xf5, 0x35, 0xbb, 0x18, 0x26, 0xd4, + 0x00, 0x30, 0xf4, 0xde, 0xb9, 0xba, 0x0a, 0x13, 0xaa, 0x0c, 0xd6, 0xe7, 0x42, + 0x17, 0xe3, 0x19, 0xc8, 0x74, 0xe8, 0x13, 0xf8, 0x34, 0xd2, 0x1f, 0xee, 0xe9, + 0xef, 0xdd, 0x03, 0xc8, 0x4a, 0x48, 0x0a, 0xaf, 0xda, 0xe1, 0xee, 0xca, 0x75, + 0xaf, 0x31, 0xf6, 0x0a, 0x2a, 0x2a, 0xfc, 0xf1, 0x07, 0xc4, 0x9f, 0xf9, 0xba, + 0x1e, 0x2d, 0x15, 0x12, 0x5a, 0xfe, 0x16, 0xec, 0x0a, 0x36, 0xe7, 0xbf, 0xd0, + 0xe4, 0xc5, 0x0e, 0x18, 0xf7, 0x0e, 0xfe, 0x4b, 0x10, 0xb3, 0x35, 0xd7, 0x0d, + 0xe4, 0x01, 0xba, 0xe6, 0x22, 0xd4, 0x81, 0x05, 0x47, 0x3f, 0x05, 0xd7, 0xd7, + 0x12, 0xfe, 0x09, 0x0d, 0x1f, 0xd8, 0xff, 0xc2, 0xf5, 0x1a, 0x0f, 0xe9, 0xec, + 0x65, 0xb3, 0xc9, 0x06, 0xea, 0x3b, 0xe5, 0xf1, 0xf4, 0xe5, 0xd1, 0x57, 0xc0, + 0xc4, 0x34, 0x07, 0xb5, 0x05, 0x07, 0x12, 0x3a, 0xdf, 0xe6, 0xce, 0xc7, 0x1c, + 0x33, 0xe4, 0x95, 0xf7, 0x09, 0x20, 0x40, 0x54, 0xc0, 0xde, 0x17, 0x4c, 0xfa, + 0xff, 0xc0, 0x02, 0x24, 0x3a, 0xf5, 0xee, 0x0d, 0x91, 0x2c, 0x25, 0x53, 0xcf, + 0xdb, 0x4f, 0x4e, 0xfa, 0xd3, 0xff, 0xd2, 0x2c, 0xf0, 0x12, 0x18, 0xf1, 0x1e, + 0xcd, 0xee, 0xe6, 0x03, 0xe9, 0x01, 0xca, 0xed, 0xdb, 0x1d, 0x04, 0xb1, 0x7e, + 0xe6, 0xf9, 0xce, 0xcd, 0xf0, 0x01, 0xf0, 0x3e, 0x19, 0x05, 0x0e, 0x3d, 0x0a, + 0xe6, 0x2a, 0x20, 0xd4, 0xe0, 0x1e, 0x26, 0x1e, 0xbe, 0x42, 0x24, 0xc8, 0x31, + 0x22, 0x39, 0x23, 0xc2, 0x6a, 0xe7, 0x22, 0x11, 0x37, 0x26, 0x1e, 0x08, 0xb9, + 0x1f, 0x01, 0xef, 0x02, 0xef, 0xfa, 0x1d, 0x1b, 0x0e, 0x1c, 0x09, 0x22, 0xfc, + 0xdd, 0xba, 0x7f, 0xdb, 0x0f, 0xe3, 0x4f, 0x0b, 0xd9, 0x0d, 0xc6, 0xee, 0x29, + 0xfe, 0x9d, 0x10, 0xbc, 0x02, 0xe6, 0x17, 0x26, 0x20, 0x39, 0xe1, 0x1f, 0x07, + 0xdf, 0xe8, 0x16, 0x18, 0xdd, 0x26, 0xe1, 0xb2, 0x46, 0x1d, 0x04, 0xe3, 0xf8, + 0x0e, 0x38, 0x1e, 0xea, 0x0a, 0x30, 0x2a, 0x36, 0x31, 0x2d, 0x16, 0xd1, 0xd0, + 0xda, 0x03, 0x11, 0xb7, 0xc0, 0xf7, 0xd9, 0xd3, 0x2e, 0x02, 0xd7, 0x2b, 0xf9, + 0x94, 0xf6, 0xee, 0xfe, 0xdd, 0x3f, 0x61, 0xf5, 0x98, 0xf7, 0x02, 0xe9, 0x16, + 0xdb, 0x44, 0x2d, 0x4c, 0xf9, 0x0c, 0x09, 0x6b, 0x2e, 0x27, 0xba, 0x04, 0xf0, + 0xcb, 0x01, 0xd3, 0xe4, 0xbe, 0xe6, 0x22, 0xcc, 0x05, 0xe0, 0xec, 0x13, 0x0c, + 0xcd, 0xba, 0xe8, 0x16, 0xfd, 0x66, 0x7f, 0xfe, 0x49, 0xc3, 0x39, 0xd8, 0xce, + 0xe2, 0xfc, 0x0a, 0x12, 0xfd, 0xd2, 0x01, 0xb2, 0x11, 0xfa, 0xf0, 0xff, 0x06, + 0x3d, 0xde, 0xed, 0x9b, 0x08, 0xf8, 0xca, 0xd1, 0xca, 0xbe, 0xe8, 0x08, 0x63, + 0xc2, 0xa8, 0x1f, 0x5b, 0x4c, 0x11, 0xd0, 0x31, 0x19, 0x2d, 0xf5, 0xab, 0xe1, + 0xef, 0xe2, 0xfd, 0xf5, 0x1d, 0xe6, 0x38, 0x07, 0x2d, 0xf4, 0xcb, 0x0d, 0xc5, + 0x17, 0x02, 0x34, 0xb0, 0x55, 0xec, 0xca, 0xef, 0x1e, 0xd8, 0x17, 0x03, 0xd6, + 0xf1, 0x49, 0x06, 0xdc, 0xf8, 0x2f, 0xf6, 0x00, 0xeb, 0x81, 0x1e, 0xb7, 0xe4, + 0xe4, 0xc3, 0x22, 0x28, 0x03, 0x08, 0xbb, 0x56, 0x2e, 0xf4, 0xda, 0x00, 0xff, + 0xfc, 0x69, 0x14, 0x09, 0x06, 0xc9, 0x0f, 0x3f, 0x0f, 0xef, 0xbd, 0xe4, 0x58, + 0xe8, 0x1f, 0x5f, 0x14, 0xf5, 0xec, 0xe7, 0xfb, 0x1e, 0xa7, 0xd7, 0xfa, 0xf2, + 0x11, 0x27, 0x00, 0xe4, 0xed, 0x14, 0xf2, 0x04, 0x1d, 0xaf, 0x53, 0x04, 0x43, + 0x2c, 0xe5, 0xd9, 0x1f, 0xbe, 0x1c, 0xc8, 0xcf, 0xe4, 0x04, 0xa2, 0x1a, 0xdf, + 0xff, 0x20, 0xfe, 0xd9, 0xf9, 0x11, 0xf4, 0xeb, 0xe4, 0xc5, 0x95, 0x19, 0x2f, + 0x09, 0xcc, 0xc7, 0xda, 0x11, 0xd9, 0x36, 0x01, 0x67, 0xf3, 0xde, 0xfc, 0x2c, + 0xbe, 0x6e, 0xfa, 0xfa, 0x34, 0xb5, 0xf8, 0xb1, 0xac, 0x15, 0xdb, 0x12, 0xec, + 0x1a, 0xed, 0x2d, 0x31, 0xd2, 0xff, 0x70, 0x12, 0x0d, 0x0c, 0x08, 0xa9, 0x4d, + 0xf3, 0xf1, 0x1f, 0x45, 0x6c, 0xff, 0x5b, 0xc2, 0x8c, 0x0b, 0xff, 0x14, 0xce, + 0x45, 0x55, 0x0d, 0x66, 0x66, 0x13, 0x3d, 0x02, 0xf1, 0x0b, 0xe8, 0xe5, 0x54, + 0xf2, 0xc7, 0xd9, 0xda, 0x01, 0xda, 0xcc, 0xce, 0x29, 0xd0, 0x17, 0xdf, 0xbd, + 0xa6, 0x0c, 0x23, 0x19, 0x22, 0xf6, 0xf4, 0x1a, 0xec, 0xcb, 0x18, 0x57, 0xec, + 0x71, 0x18, 0x34, 0x1c, 0x0e, 0xf8, 0x19, 0xe2, 0x51, 0xa2, 0x3e, 0x90, 0xda, + 0x0d, 0xc8, 0x10, 0x0a, 0x28, 0xa7, 0x72, 0x81, 0xbd, 0x1f, 0x40, 0x1f, 0x9d, + 0x26, 0x0a, 0xdf, 0x0e, 0x1b, 0xde, 0xcf, 0xe1, 0xfe, 0xdb, 0xea, 0x09, 0xf9, + 0x30, 0x45, 0x1c, 0x0d, 0x05, 0xf1, 0xc5, 0xd5, 0x46, 0x04, 0x02, 0x3b, 0xe0, + 0xd5, 0x08, 0x1c, 0x3b, 0x07, 0x54, 0xec, 0x3c, 0xf1, 0xed, 0x7f, 0x15, 0x1d, + 0xf6, 0x2f, 0xd8, 0xc2, 0xfa, 0xd0, 0xd2, 0x34, 0x20, 0x3d, 0x04, 0xe6, 0xde, + 0xf4, 0xef, 0xe2, 0xee, 0x0b, 0xe7, 0xbb, 0xcd, 0x33, 0xf7, 0xca, 0xfd, 0xe9, + 0x42, 0x43, 0x25, 0x7e, 0xdb, 0x4e, 0x16, 0xde, 0xfb, 0xf3, 0x75, 0xfd, 0x8f, + 0xff, 0x13, 0x18, 0x2b, 0x17, 0xdc, 0x0d, 0xd6, 0x0f, 0x37, 0x73, 0xbe, 0x14, + 0xe0, 0x26, 0x38, 0x0f, 0x16, 0x11, 0x02, 0xe3, 0xed, 0x01, 0x23, 0x10, 0x26, + 0x0d, 0xe2, 0x20, 0xff, 0xfb, 0xe2, 0x3d, 0x00, 0x13, 0x01, 0xb4, 0xf3, 0xc0, + 0xfb, 0x4f, 0x56, 0xc7, 0x0a, 0xea, 0x22, 0xd7, 0x15, 0x71, 0xfb, 0x2a, 0x4c, + 0xd9, 0xf8, 0xd7, 0x2c, 0x1e, 0x06, 0xc7, 0xe6, 0xe5, 0xe8, 0x24, 0x20, 0xd6, + 0xbf, 0x1f, 0xf3, 0x08, 0x1e, 0xfb, 0xcd, 0xad, 0xf6, 0x16, 0x6a, 0x31, 0x3e, + 0x32, 0xa6, 0x0a, 0xe3, 0x90, 0x4b, 0xf8, 0x31, 0xcf, 0xc3, 0x10, 0xdf, 0xb8, + 0xfe, 0xb5, 0x0d, 0x9f, 0x2a, 0x1d, 0xf0, 0x0e, 0xd0, 0x5c, 0x0c, 0x0e, 0xd6, + 0x1a, 0xd6, 0x2a, 0xbc, 0xf7, 0x44, 0x22, 0xc4, 0xe2, 0xe4, 0x27, 0x9f, 0xda, + 0x13, 0x38, 0x20, 0x17, 0x44, 0x16, 0xb8, 0xcd, 0x0a, 0x0e, 0x09, 0x53, 0xf0, + 0x2e, 0x0b, 0xb6, 0x7f, 0xfc, 0x41, 0xe6, 0xe2, 0x34, 0xd0, 0x0c, 0x47, 0x19, + 0x4c, 0xa5, 0x0a, 0x04, 0xc5, 0x01, 0xb7, 0xed, 0x3d, 0x35, 0x63, 0xe5, 0x43, + 0xce, 0x22, 0xd1, 0x07, 0x20, 0x6e, 0xe7, 0x29, 0x16, 0x0f, 0x07, 0xf6, 0xd7, + 0xfd, 0x24, 0xf7, 0xd6, 0x16, 0x52, 0xe1, 0xe6, 0xa1, 0xe5, 0x13, 0xf2, 0xb7, + 0x0e, 0xe7, 0x05, 0xe4, 0xe0, 0x20, 0x0e, 0xf4, 0xd5, 0x1a, 0x0e, 0xea, 0xea, + 0xfe, 0xdc, 0x29, 0x30, 0xd6, 0xb7, 0xdd, 0x38, 0xea, 0x2e, 0x18, 0x62, 0x30, + 0xe4, 0xe6, 0xe5, 0xef, 0x1e, 0xf4, 0x03, 0x0e, 0x09, 0xdc, 0x4f, 0x4c, 0x17, + 0xe2, 0x33, 0xf4, 0xfd, 0xe6, 0xf2, 0x24, 0xff, 0x22, 0x50, 0x1d, 0xdd, 0xfd, + 0xc5, 0x21, 0x42, 0x11, 0xce, 0xdf, 0x3c, 0xc2, 0xc6, 0xcd, 0xea, 0xd7, 0x14, + 0x53, 0xc5, 0x02, 0xb8, 0x2b, 0x0b, 0xfc, 0x32, 0xe7, 0xe7, 0x28, 0xc8, 0xd3, + 0x8b, 0x13, 0x0a, 0x50, 0x70, 0xf5, 0x7d, 0x92, 0x45, 0x29, 0xea, 0xf8, 0xdb, + 0xdb, 0xee, 0x17, 0x56, 0x6b, 0x25, 0x08, 0xd8, 0xd7, 0xb5, 0xff, 0xb5, 0x05, + 0x0e, 0x25, 0x13, 0x4f, 0x6a, 0x81, 0x48, 0x24, 0x37, 0x72, 0xc2, 0x25, 0xf8, + 0x59, 0x19, 0xf8, 0x3c, 0xe8, 0x02, 0xff, 0x47, 0xef, 0x59, 0xeb, 0xf9, 0xe9, + 0xf9, 0x35, 0xe2, 0xb8, 0x10, 0xed, 0xb9, 0xfa, 0x2b, 0x1b, 0x0a, 0xf6, 0xb7, + 0xf2, 0xb0, 0x40, 0x1c, 0x15, 0x07, 0xd4, 0xe1, 0x2a, 0x08, 0xf0, 0x20, 0x39, + 0xd8, 0x13, 0x2b, 0x22, 0x2d, 0xdf, 0xe5, 0xf6, 0x13, 0x14, 0x99, 0xc4, 0xc5, + 0x17, 0x2e, 0xeb, 0x0e, 0xd1, 0x1e, 0x17, 0x14, 0xad, 0xdf, 0xbd, 0xf4, 0x24, + 0xef, 0xe8, 0xfa, 0xf6, 0x1c, 0xec, 0xe0, 0x15, 0x08, 0xdc, 0xcc, 0xf1, 0x26, + 0x07, 0xf0, 0x34, 0xdd, 0x21, 0x1f, 0x8f, 0x4c, 0xf3, 0xec, 0x4c, 0x2e, 0xc5, + 0x64, 0x27, 0x37, 0x04, 0xd8, 0xec, 0xe2, 0xeb, 0xa3, 0x21, 0xfa, 0x11, 0x07, + 0x0f, 0x1d, 0x57, 0x40, 0x06, 0xc3, 0xd8, 0x38, 0xd1, 0x08, 0x02, 0x22, 0x18, + 0x19, 0xcd, 0xe8, 0xf3, 0x44, 0xe9, 0xb5, 0xe4, 0xfc, 0x41, 0xd1, 0x1a, 0xf4, + 0x48, 0xe8, 0x0e, 0x6e, 0x2a, 0x7f, 0xec, 0xe3, 0x03, 0xe8, 0x17, 0xf1, 0xe6, + 0x12, 0x4f, 0xeb, 0xe6, 0x20, 0x2b, 0xea, 0x97, 0xfa, 0xda, 0xdd, 0x1c, 0x21, + 0x1c, 0x01, 0x11, 0x12, 0x03, 0xaf, 0x13, 0xd9, 0x2f, 0x10, 0xfc, 0xc4, 0x31, + 0x16, 0xbf, 0xfb, 0x30, 0x03, 0xb4, 0xeb, 0xd9, 0xc6, 0x0b, 0x50, 0x2c, 0x54, + 0xe5, 0xbf, 0x70, 0xba, 0x10, 0xe6, 0xe8, 0x23, 0x17, 0x24, 0x46, 0x18, 0xc9, + 0x2a, 0xb5, 0xec, 0xf4, 0x81, 0x85, 0x21, 0x8e, 0x1a, 0x79, 0xe8, 0x22, 0xf4, + 0xf1, 0xd1, 0xa8, 0xf9, 0x98, 0xba, 0xfe, 0xcc, 0xfb, 0xe7, 0x33, 0x1d, 0x3c, + 0x0a, 0xe5, 0x10, 0x05, 0x30, 0x17, 0xbd, 0x59, 0xe6, 0x49, 0xe2, 0xd0, 0xcf, + 0xb4, 0x35, 0x0d, 0x6e, 0x58, 0xe4, 0x58, 0xac, 0xbe, 0x07, 0x13, 0xd3, 0xf5, + 0xf5, 0x13, 0xfb, 0x35, 0xc0, 0x2d, 0xca, 0x36, 0xa2, 0xff, 0x40, 0x38, 0xef, + 0xf2, 0x1c, 0x1c, 0x05, 0x42, 0xaf, 0x45, 0x25, 0xca, 0x00, 0xdf, 0x3f, 0xb0, + 0xec, 0xd0, 0xe4, 0x1e, 0xec, 0x15, 0x15, 0xf0, 0x2b, 0xef, 0xbc, 0xfc, 0x14, + 0xfd, 0xe0, 0x36, 0x05, 0xad, 0xe2, 0xbd, 0xdc, 0x08, 0x0d, 0xfd, 0xdd, 0xdc, + 0x11, 0xf4, 0xcc, 0x1a, 0xef, 0xe2, 0x07, 0x25, 0x20, 0xd1, 0xe8, 0xd0, 0x45, + 0x7b, 0xdc, 0xee, 0x01, 0xfb, 0xfa, 0xf6, 0x11, 0xc9, 0xa5, 0xda, 0xde, 0x13, + 0xfc, 0xfe, 0xc7, 0x49, 0x08, 0xdb, 0x16, 0x2d, 0xd5, 0xe5, 0xdc, 0xc8, 0x0e, + 0xfd, 0xff, 0xe3, 0x31, 0x48, 0x9f, 0xde, 0x46, 0xdb, 0xf6, 0x0d, 0x3a, 0xf7, + 0xb5, 0x7f, 0x02, 0xc7, 0xa6, 0xdf, 0x04, 0xdc, 0x0c, 0xcb, 0x0b, 0xbb, 0xf7, + 0x4f, 0xf7, 0x46, 0x11, 0x2a, 0x64, 0x1e, 0x37, 0xec, 0xd5, 0x8c, 0xef, 0x3a, + 0x1f, 0x1d, 0x46, 0xdd, 0xeb, 0xcc, 0x1d, 0xe7, 0x99, 0x17, 0x10, 0x12, 0xb8, + 0x17, 0x00, 0xcb, 0x0f, 0x02, 0xcb, 0x10, 0x3e, 0x31, 0x04, 0x51, 0x26, 0x2d, + 0xf9, 0xfe, 0xe0, 0xd0, 0x18, 0xc9, 0x71, 0x32, 0x2a, 0x12, 0xd1, 0xed, 0x2b, + 0x43, 0xb1, 0xe2, 0xf8, 0x28, 0xc6, 0xf7, 0xd8, 0x04, 0x2c, 0xc5, 0x09, 0xf9, + 0x0c, 0xe6, 0x0b, 0xdc, 0x45, 0x31, 0x31, 0xe1, 0x15, 0x40, 0xef, 0x0c, 0x03, + 0xf9, 0xf5, 0xc5, 0x15, 0x1b, 0x05, 0x35, 0xe8, 0xc2, 0xf8, 0xe6, 0x24, 0xcf, + 0x40, 0x37, 0xfc, 0x7f, 0xf1, 0xdd, 0x02, 0x0a, 0xbb, 0xe1, 0x1e, 0x12, 0xd3, + 0xe3, 0x12, 0xd5, 0xec, 0x21, 0xf1, 0xd2, 0x2d, 0xc1, 0xe3, 0xec, 0xf5, 0xfa, + 0xf9, 0xd0, 0x96, 0x2e, 0xfb, 0xcd, 0x20, 0xd6, 0xd2, 0xe5, 0x05, 0x23, 0x23, + 0x2d, 0xff, 0x13, 0x53, 0xec, 0xc7, 0xdb, 0x03, 0xff, 0xf4, 0x2c, 0x04, 0xe6, + 0xea, 0xf2, 0xee, 0xed, 0x5f, 0x12, 0xe0, 0xf4, 0x27, 0xbb, 0xf9, 0xff, 0x14, + 0x0e, 0xcd, 0x00, 0x16, 0xc5, 0xc5, 0x4f, 0x0a, 0xb9, 0x15, 0xfc, 0xca, 0x0f, + 0xf8, 0x0f, 0xde, 0xdc, 0xdd, 0x23, 0x01, 0xf8, 0xf2, 0x2e, 0xe0, 0xf9, 0xf0, + 0x40, 0xe5, 0xf5, 0x2b, 0x1f, 0xc1, 0x02, 0x6b, 0xf4, 0xf2, 0xde, 0xcb, 0x41, + 0x1a, 0x01, 0x52, 0xf3, 0xe5, 0x06, 0xc4, 0x26, 0x21, 0xb3, 0x19, 0xd5, 0xed, + 0x0e, 0xe8, 0xe7, 0xf4, 0xef, 0x1e, 0xdc, 0xef, 0xe8, 0x0d, 0xf9, 0x06, 0xe8, + 0xe9, 0xd2, 0xbd, 0xff, 0x19, 0x1c, 0x14, 0x14, 0x00, 0xfd, 0xdc, 0x04, 0xe8, + 0x81, 0x35, 0x0b, 0x05, 0xcb, 0x00, 0xe7, 0x14, 0xea, 0xd6, 0x0f, 0xe2, 0x03, + 0xbb, 0x00, 0xc3, 0xf7, 0x01, 0xf9, 0x17, 0x0c, 0x1a, 0xe0, 0xe0, 0xcc, 0x63, + 0xf1, 0x22, 0x17, 0xfa, 0xea, 0x2e, 0xea, 0x1b, 0xf5, 0xde, 0x0f, 0xc8, 0xe9, + 0xcc, 0xe3, 0xe7, 0xf1, 0x18, 0x1a, 0x01, 0xe9, 0x15, 0xf9, 0xe2, 0xd2, 0x33, + 0x0d, 0xed, 0x1e, 0x25, 0xf8, 0xb0, 0x13, 0x0d, 0xf2, 0xdf, 0xf3, 0xcf, 0x2e, + 0x24, 0xa0, 0xe6, 0xd2, 0xf7, 0xf7, 0x1f, 0x24, 0x02, 0x2e, 0xde, 0x22, 0xa4, + 0x15, 0xcf, 0xec, 0x05, 0xc8, 0xf9, 0x25, 0x1d, 0x2e, 0x0f, 0xee, 0xc4, 0x64, + 0xaf, 0xcc, 0x38, 0x07, 0x26, 0xba, 0x36, 0x95, 0xfb, 0xbc, 0xfb, 0xf5, 0xb7, + 0xf2, 0xc1, 0x33, 0xc8, 0x44, 0xf9, 0x08, 0xc4, 0x0a, 0xd7, 0x05, 0xd7, 0x58, + 0x44, 0xdc, 0xeb, 0xd8, 0xca, 0xd1, 0x18, 0x18, 0xc3, 0x3a, 0x3c, 0x1c, 0x3f, + 0x0b, 0x1c, 0xec, 0x38, 0xf8, 0xa7, 0xec, 0xef, 0xc5, 0xda, 0xf9, 0xe1, 0x09, + 0x3c, 0x1c, 0x43, 0xfe, 0xc8, 0xef, 0xe1, 0xc1, 0x03, 0xaf, 0x60, 0x2a, 0x9f, + 0xf6, 0x0e, 0xeb, 0x1b, 0xaf, 0x04, 0x38, 0xe6, 0x3e, 0xc1, 0xb7, 0x2a, 0x0b, + 0x04, 0xd0, 0xce, 0x43, 0x81, 0xf7, 0xfc, 0x7c, 0x10, 0xe3, 0xf6, 0xdc, 0xfc, + 0x22, 0xf5, 0x0a, 0x15, 0xdc, 0xed, 0x06, 0xe5, 0xf7, 0x1d, 0x0f, 0x20, 0x51, + 0xe5, 0xe1, 0x0e, 0x3b, 0xef, 0xf4, 0xf0, 0x2f, 0xdc, 0xf1, 0xe7, 0xb6, 0xda, + 0x27, 0xf7, 0xfc, 0xe0, 0xfb, 0x38, 0xfe, 0xb5, 0x01, 0x37, 0x32, 0xf3, 0xfe, + 0xc9, 0xf4, 0x18, 0xd6, 0x39, 0xcd, 0x1b, 0xb1, 0x28, 0xd0, 0x07, 0xee, 0x11, + 0x7f, 0x18, 0xd8, 0xe9, 0xec, 0xd3, 0xd7, 0xd4, 0xdd, 0x05, 0x1e, 0xfd, 0xfb, + 0x54, 0x10, 0xf8, 0x49, 0xe4, 0x08, 0xc2, 0x24, 0x27, 0xb3, 0xe1, 0xdf, 0x47, + 0x0f, 0x3a, 0xd4, 0x02, 0x49, 0x17, 0x1b, 0x04, 0xc7, 0x9e, 0x0a, 0x11, 0x01, + 0x2d, 0x2d, 0x01, 0xf6, 0xfb, 0xfb, 0xff, 0xd8, 0xd6, 0x16, 0x06, 0x42, 0xde, + 0xf4, 0xf3, 0xd8, 0xda, 0x2c, 0xf7, 0xf2, 0xf4, 0x08, 0xc6, 0x1e, 0x2d, 0x30, + 0x05, 0x45, 0x13, 0xee, 0x32, 0xe0, 0x38, 0xfe, 0xd6, 0xdf, 0xd3, 0x19, 0x1b, + 0xd6, 0xfe, 0xe9, 0x06, 0x18, 0x3b, 0xf7, 0xa2, 0x1a, 0x19, 0x39, 0x3c, 0x1e, + 0xec, 0xf1, 0xfd, 0x20, 0xec, 0xd4, 0x52, 0xe8, 0xc7, 0xe9, 0x11, 0xfe, 0xd4, + 0xb2, 0x3e, 0xd5, 0xc1, 0xe3, 0xf4, 0xff, 0xfc, 0x5a, 0xd2, 0x30, 0xb9, 0x01, + 0x0b, 0x51, 0x3c, 0xd2, 0x49, 0x50, 0x11, 0xeb, 0x12, 0x2e, 0xed, 0x0d, 0x39, + 0xf9, 0xf1, 0xa4, 0x58, 0x81, 0xbd, 0x36, 0x30, 0x01, 0xe0, 0xf4, 0xdb, 0xdc, + 0x0e, 0xd4, 0x3a, 0xfc, 0x0c, 0x10, 0x1e, 0x79, 0xb4, 0xd2, 0x25, 0x33, 0x07, + 0xfd, 0xfc, 0x26, 0x2b, 0x00, 0xee, 0x12, 0xd8, 0x37, 0x0c, 0x3a, 0xa4, 0xf4, + 0xcc, 0x22, 0xf6, 0x18, 0x06, 0xde, 0xd8, 0xf7, 0x22, 0xc0, 0x24, 0x1b, 0x2d, + 0x52, 0x00, 0xb8, 0x46, 0xc7, 0xdd, 0x37, 0xbb, 0x18, 0xe8, 0x1c, 0x2b, 0xc4, + 0xde, 0xcd, 0x3f, 0xf9, 0x5e, 0xf5, 0x16, 0xcd, 0x0a, 0x0e, 0x12, 0xfe, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x37, 0x1e, 0x00, 0x00, 0x73, + 0x14, 0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0xab, 0xe6, 0xff, 0xff, 0xb5, 0x24, + 0x00, 0x00, 0xbc, 0x1e, 0x00, 0x00, 0x49, 0xf0, 0xff, 0xff, 0xd7, 0xfd, 0xff, + 0xff, 0x94, 0x13, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xf8, 0xfe, 0xff, 0xff, + 0xe0, 0x04, 0x00, 0x00, 0x45, 0xfd, 0xff, 0xff, 0x28, 0xf7, 0xff, 0xff, 0x4a, + 0x16, 0x00, 0x00, 0x13, 0xe3, 0xff, 0xff, 0x3d, 0x06, 0x00, 0x00, 0xc9, 0x1a, + 0x00, 0x00, 0x2b, 0xf5, 0xff, 0xff, 0x5c, 0x31, 0x00, 0x00, 0x3d, 0x10, 0x00, + 0x00, 0xe8, 0xef, 0xff, 0xff, 0x88, 0x2e, 0x00, 0x00, 0xe6, 0x01, 0x00, 0x00, + 0x0f, 0xfe, 0xff, 0xff, 0x9c, 0xec, 0xff, 0xff, 0x7c, 0xf9, 0xff, 0xff, 0x49, + 0x03, 0x00, 0x00, 0x96, 0xf4, 0xff, 0xff, 0x87, 0xf7, 0xff, 0xff, 0x37, 0xdb, + 0xff, 0xff, 0x52, 0x10, 0x00, 0x00, 0xd3, 0xfb, 0xff, 0xff, 0x15, 0xf7, 0xff, + 0xff, 0xfa, 0xe9, 0xff, 0xff, 0x54, 0xf6, 0xff, 0xff, 0x16, 0x22, 0x00, 0x00, + 0xb7, 0xf1, 0xff, 0xff, 0x3a, 0xfe, 0xff, 0xff, 0x67, 0xe4, 0xff, 0xff, 0x84, + 0xfd, 0xff, 0xff, 0x5c, 0x09, 0x00, 0x00, 0x5d, 0xfb, 0xff, 0xff, 0x4d, 0x1c, + 0x00, 0x00, 0x40, 0x28, 0x00, 0x00, 0x5a, 0xe0, 0xff, 0xff, 0x6f, 0xf3, 0xff, + 0xff, 0xdd, 0xf8, 0xff, 0xff, 0xc4, 0x03, 0x00, 0x00, 0x71, 0x23, 0x00, 0x00, + 0xe8, 0x21, 0x00, 0x00, 0xce, 0xf2, 0xff, 0xff, 0x42, 0xed, 0xff, 0xff, 0xe7, + 0xf1, 0xff, 0xff, 0xb6, 0xf2, 0xff, 0xff, 0x66, 0xfd, 0xff, 0xff, 0xc8, 0xf0, + 0xff, 0xff, 0xba, 0xfd, 0xff, 0xff, 0xc6, 0xff, 0xff, 0xff, 0x2e, 0xfb, 0xff, + 0xff, 0x1b, 0x1b, 0x00, 0x00, 0x41, 0xe0, 0xff, 0xff, 0xfe, 0xfd, 0xff, 0xff, + 0x61, 0xf0, 0xff, 0xff, 0x50, 0xf0, 0xff, 0xff, 0x8a, 0xea, 0xff, 0xff, 0x04, + 0xe3, 0xff, 0xff, 0x5b, 0xe1, 0xff, 0xff, 0xb5, 0xeb, 0xff, 0xff, 0x90, 0xf8, + 0xff, 0xff, 0x89, 0xe8, 0xff, 0xff, 0x83, 0xfa, 0xff, 0xff, 0x0e, 0xef, 0xff, + 0xff, 0x19, 0x22, 0x00, 0x00, 0xe8, 0xf9, 0xff, 0xff, 0xfc, 0xf4, 0xff, 0xff, + 0x2f, 0xff, 0xff, 0xff, 0x62, 0x05, 0x00, 0x00, 0x93, 0xf9, 0xff, 0xff, 0x00, + 0xfc, 0xff, 0xff, 0xcb, 0x1a, 0x00, 0x00, 0x2c, 0xea, 0xff, 0xff, 0x53, 0x17, + 0x00, 0x00, 0xbb, 0xdc, 0xff, 0xff, 0x77, 0x01, 0x00, 0x00, 0x5f, 0xf2, 0xff, + 0xff, 0x95, 0x03, 0x00, 0x00, 0x29, 0x04, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, + 0x4a, 0x25, 0x00, 0x00, 0xfc, 0xfd, 0xff, 0xff, 0xfd, 0x01, 0x00, 0x00, 0x49, + 0xf4, 0xff, 0xff, 0xba, 0xf9, 0xff, 0xff, 0xc2, 0xf8, 0xff, 0xff, 0xf9, 0x0d, + 0x00, 0x00, 0x88, 0x06, 0x00, 0x00, 0xbd, 0x0d, 0x00, 0x00, 0x79, 0xec, 0xff, + 0xff, 0x71, 0xed, 0xff, 0xff, 0x90, 0x15, 0x00, 0x00, 0x56, 0xeb, 0xff, 0xff, + 0x32, 0x2c, 0x00, 0x00, 0xda, 0xfd, 0xff, 0xff, 0x87, 0xf9, 0xff, 0xff, 0x0d, + 0x07, 0x00, 0x00, 0xe0, 0x12, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x7c, 0xfb, + 0xff, 0xff, 0xbb, 0x04, 0x00, 0x00, 0xdf, 0xdf, 0xff, 0xff, 0x98, 0xeb, 0xff, + 0xff, 0x2d, 0xf4, 0xff, 0xff, 0xfc, 0x09, 0x00, 0x00, 0xa9, 0x17, 0x00, 0x00, + 0x5a, 0x04, 0x00, 0x00, 0x98, 0xef, 0xff, 0xff, 0xb4, 0xec, 0xff, 0xff, 0x80, + 0x02, 0x00, 0x00, 0xc4, 0xfe, 0xff, 0xff, 0x04, 0x05, 0x00, 0x00, 0xb3, 0x09, + 0x00, 0x00, 0xc1, 0x1e, 0x00, 0x00, 0x19, 0x12, 0x00, 0x00, 0x75, 0xf7, 0xff, + 0xff, 0x02, 0x03, 0x00, 0x00, 0x1b, 0x0a, 0x00, 0x00, 0x94, 0x0b, 0x00, 0x00, + 0x1a, 0x14, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x9b, + 0x00, 0x00, 0x00, 0xff, 0xf3, 0xff, 0xff, 0x23, 0x01, 0x00, 0x00, 0x7a, 0xfc, + 0xff, 0xff, 0x2a, 0xd9, 0xff, 0xff, 0x8c, 0x05, 0x00, 0x00, 0xda, 0x38, 0x00, + 0x00, 0xc8, 0xdb, 0xff, 0xff, 0x19, 0xe9, 0xff, 0xff, 0xc0, 0x3e, 0x00, 0x00, + 0x17, 0x20, 0x00, 0x00, 0x22, 0x24, 0x00, 0x00, 0x66, 0x31, 0x00, 0x00, 0x73, + 0x21, 0x00, 0x00, 0x22, 0xe6, 0xff, 0xff, 0xfb, 0x3b, 0x00, 0x00, 0xfa, 0xe4, + 0xff, 0xff, 0x63, 0xf2, 0xff, 0xff, 0xef, 0x27, 0x00, 0x00, 0x55, 0xfe, 0xff, + 0xff, 0x92, 0x09, 0x00, 0x00, 0xa7, 0x24, 0x00, 0x00, 0x6f, 0xc0, 0xff, 0xff, + 0xe4, 0xad, 0xff, 0xff, 0x64, 0x13, 0x00, 0x00, 0xe8, 0xf3, 0xff, 0xff, 0x64, + 0xb3, 0xff, 0xff, 0xee, 0xea, 0xff, 0xff, 0xe8, 0xde, 0xff, 0xff, 0x59, 0x2a, + 0x00, 0x00, 0xaa, 0x3f, 0x00, 0x00, 0xf8, 0x12, 0x00, 0x00, 0x25, 0x0f, 0x00, + 0x00, 0x7b, 0x15, 0x00, 0x00, 0xfe, 0x0a, 0x00, 0x00, 0x1c, 0x24, 0x00, 0x00, + 0xa9, 0x05, 0x00, 0x00, 0xb3, 0xef, 0xff, 0xff, 0x75, 0xfc, 0xff, 0xff, 0x5f, + 0xec, 0xff, 0xff, 0x35, 0x06, 0x00, 0x00, 0xe6, 0x13, 0x00, 0x00, 0x33, 0xf6, + 0xff, 0xff, 0x46, 0xfe, 0xff, 0xff, 0x60, 0xef, 0xff, 0xff, 0x53, 0xee, 0xff, + 0xff, 0x80, 0xf4, 0xff, 0xff, 0xe9, 0xf3, 0xff, 0xff, 0xe5, 0xdf, 0xff, 0xff, + 0x68, 0xf8, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x01, 0x3e, 0x00, 0x00, 0xb2, + 0x28, 0x00, 0x00, 0x56, 0x14, 0x00, 0x00, 0x13, 0x09, 0x00, 0x00, 0x32, 0xd7, + 0xff, 0xff, 0x7c, 0x27, 0x00, 0x00, 0x61, 0x0d, 0x00, 0x00, 0x26, 0xd1, 0xff, + 0xff, 0xa2, 0x39, 0x00, 0x00, 0x69, 0xf4, 0xff, 0xff, 0x60, 0xf9, 0xff, 0xff, + 0x99, 0xe1, 0xff, 0xff, 0xd2, 0x02, 0x00, 0x00, 0x33, 0xe6, 0xff, 0xff, 0x1f, + 0x17, 0x00, 0x00, 0x71, 0x51, 0x00, 0x00, 0xed, 0x41, 0x00, 0x00, 0x9d, 0x26, + 0x00, 0x00, 0xa0, 0xf2, 0xff, 0xff, 0xe1, 0xf2, 0xff, 0xff, 0xee, 0xe8, 0xff, + 0xff, 0x0d, 0xe7, 0xff, 0xff, 0xef, 0x01, 0x00, 0x00, 0x11, 0xd0, 0xff, 0xff, + 0xee, 0x0e, 0x00, 0x00, 0xdc, 0xf4, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0x67, + 0xdf, 0xff, 0xff, 0x4a, 0xd0, 0xff, 0xff, 0xcd, 0xd2, 0xff, 0xff, 0x10, 0xdd, + 0xff, 0xff, 0xcc, 0xdd, 0xff, 0xff, 0xd7, 0xf8, 0xff, 0xff, 0x61, 0x37, 0x00, + 0x00, 0xcb, 0xed, 0xff, 0xff, 0xb4, 0xe5, 0xff, 0xff, 0xc6, 0xe4, 0xff, 0xff, + 0x32, 0x0c, 0x00, 0x00, 0x8c, 0x3d, 0x00, 0x00, 0x03, 0x3d, 0x00, 0x00, 0x69, + 0xe8, 0xff, 0xff, 0xd6, 0x20, 0x00, 0x00, 0xc0, 0xd5, 0xff, 0xff, 0x56, 0xe8, + 0xff, 0xff, 0x41, 0x2f, 0x00, 0x00, 0xbf, 0x21, 0x00, 0x00, 0xbb, 0x02, 0x00, + 0x00, 0x4a, 0x71, 0x00, 0x00, 0x73, 0x18, 0x00, 0x00, 0x7e, 0x3b, 0x00, 0x00, + 0xc2, 0x6d, 0x00, 0x00, 0x83, 0xfc, 0xff, 0xff, 0x65, 0xfe, 0xff, 0xff, 0x67, + 0xfc, 0xff, 0xff, 0xcc, 0x8d, 0x00, 0x00, 0xf9, 0xd0, 0xff, 0xff, 0x2a, 0x14, + 0x00, 0x00, 0x33, 0xe4, 0xff, 0xff, 0x1b, 0x1e, 0x00, 0x00, 0x75, 0xf8, 0xff, + 0xff, 0xb9, 0xc9, 0xff, 0xff, 0x8a, 0x34, 0x00, 0x00, 0x78, 0xe6, 0xff, 0xff, + 0xa9, 0x27, 0x00, 0x00, 0xab, 0x04, 0x00, 0x00, 0x66, 0xe5, 0xff, 0xff, 0x70, + 0xa2, 0xff, 0xff, 0x23, 0xe8, 0xff, 0xff, 0x5f, 0xe5, 0xff, 0xff, 0x48, 0xe7, + 0xff, 0xff, 0x3e, 0x08, 0x00, 0x00, 0xa6, 0x3d, 0x00, 0x00, 0x0d, 0x11, 0x00, + 0x00, 0xe5, 0x2f, 0x00, 0x00, 0x3c, 0x55, 0x00, 0x00, 0xd9, 0xf8, 0xff, 0xff, + 0xc8, 0x00, 0x00, 0x00, 0x26, 0x16, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0xf1, 0xf7, 0xff, 0xff, 0x03, 0x2a, 0x00, 0x00, 0xfb, 0xd0, + 0xff, 0xff, 0xef, 0xe6, 0xff, 0xff, 0x63, 0x08, 0x00, 0x00, 0x6c, 0xe5, 0xff, + 0xff, 0x15, 0x20, 0x00, 0x00, 0x25, 0xf0, 0xff, 0xff, 0x94, 0x2a, 0x00, 0x00, + 0x2b, 0x29, 0x00, 0x00, 0xa3, 0xee, 0xff, 0xff, 0xb1, 0x01, 0x00, 0x00, 0xa4, + 0x27, 0x00, 0x00, 0xde, 0xdd, 0xff, 0xff, 0x9b, 0xfd, 0xff, 0xff, 0x54, 0xfb, + 0xff, 0xff, 0x8b, 0xed, 0xff, 0xff, 0x4d, 0xe5, 0xff, 0xff, 0x4b, 0xe5, 0xff, + 0xff, 0x0f, 0xc8, 0xff, 0xff, 0x31, 0xf6, 0xff, 0xff, 0xdc, 0xdb, 0xff, 0xff, + 0x92, 0xf7, 0xff, 0xff, 0xdb, 0xef, 0xff, 0xff, 0x49, 0xfe, 0xff, 0xff, 0x8d, + 0xf2, 0xff, 0xff, 0x56, 0xe5, 0xff, 0xff, 0xa5, 0x00, 0x00, 0x00, 0xbb, 0xf1, + 0xff, 0xff, 0xe3, 0x05, 0x00, 0x00, 0x51, 0xf5, 0xff, 0xff, 0x0a, 0xfb, 0xff, + 0xff, 0x6e, 0xe7, 0xff, 0xff, 0x42, 0x1c, 0x00, 0x00, 0x89, 0xeb, 0xff, 0xff, + 0x71, 0xf0, 0xff, 0xff, 0x53, 0xeb, 0xff, 0xff, 0x24, 0x05, 0x00, 0x00, 0x0b, + 0x20, 0x00, 0x00, 0x28, 0xfe, 0xff, 0xff, 0xd0, 0x2d, 0x00, 0x00, 0x49, 0x07, + 0x00, 0x00, 0xef, 0x24, 0x00, 0x00, 0xf1, 0xfb, 0xff, 0xff, 0x44, 0x0e, 0x00, + 0x00, 0x9c, 0x22, 0x00, 0x00, 0x5f, 0xe6, 0xff, 0xff, 0x39, 0xe5, 0xff, 0xff, + 0xc1, 0xff, 0xff, 0xff, 0xa8, 0xfa, 0xff, 0xff, 0x90, 0xe7, 0xff, 0xff, 0xdd, + 0xf9, 0xff, 0xff, 0x81, 0xee, 0xff, 0xff, 0xa5, 0x26, 0x00, 0x00, 0xe4, 0xeb, + 0xff, 0xff, 0xb7, 0x23, 0x00, 0x00, 0xcf, 0xe4, 0xff, 0xff, 0x39, 0xf6, 0xff, + 0xff, 0x07, 0xfd, 0xff, 0xff, 0x14, 0xfe, 0xff, 0xff, 0xf5, 0x1e, 0x00, 0x00, + 0xde, 0xf7, 0xff, 0xff, 0xad, 0xef, 0xff, 0xff, 0x2a, 0xe7, 0xff, 0xff, 0x5b, + 0xec, 0xff, 0xff, 0xba, 0xfe, 0xff, 0xff, 0x63, 0xee, 0xff, 0xff, 0x92, 0xff, + 0xff, 0xff, 0xd5, 0xf8, 0xff, 0xff, 0xda, 0xdb, 0xff, 0xff, 0x79, 0x05, 0x00, + 0x00, 0xed, 0xf2, 0xff, 0xff, 0x8c, 0xe2, 0xff, 0xff, 0x5c, 0xee, 0xff, 0xff, + 0x07, 0xe5, 0xff, 0xff, 0xee, 0x01, 0x00, 0x00, 0xe2, 0xe6, 0xff, 0xff, 0xf7, + 0xed, 0xff, 0xff, 0x8f, 0x2a, 0x00, 0x00, 0x2e, 0x28, 0x00, 0x00, 0xc1, 0x26, + 0x00, 0x00, 0x9f, 0xe5, 0xff, 0xff, 0x6a, 0x03, 0x00, 0x00, 0xc1, 0xef, 0xff, + 0xff, 0x37, 0xf8, 0xff, 0xff, 0x47, 0xf0, 0xff, 0xff, 0xfa, 0x22, 0x00, 0x00, + 0xb5, 0xf5, 0xff, 0xff, 0xd0, 0xfd, 0xff, 0xff, 0x11, 0xef, 0xff, 0xff, 0x1f, + 0x2e, 0x00, 0x00, 0x65, 0xe9, 0xff, 0xff, 0x08, 0x1d, 0x00, 0x00, 0x77, 0xdb, + 0xff, 0xff, 0x36, 0xf9, 0xff, 0xff, 0xab, 0xe2, 0xff, 0xff, 0xfb, 0x16, 0x00, + 0x00, 0x53, 0xf5, 0xff, 0xff, 0x96, 0x2c, 0x00, 0x00, 0x10, 0xe1, 0xff, 0xff, + 0xb4, 0xf8, 0xff, 0xff, 0x20, 0x1a, 0x00, 0x00, 0x98, 0xe4, 0xff, 0xff, 0x9b, + 0x27, 0x00, 0x00, 0x23, 0x2c, 0x00, 0x00, 0x07, 0x2e, 0x00, 0x00, 0xd2, 0xfb, + 0xff, 0xff, 0x15, 0xec, 0xff, 0xff, 0x52, 0x20, 0x00, 0x00, 0x9a, 0xf0, 0xff, + 0xff, 0xcc, 0x2c, 0x00, 0x00, 0x58, 0xee, 0xff, 0xff, 0x79, 0x25, 0x00, 0x00, + 0xaf, 0xea, 0xff, 0xff, 0x90, 0xf4, 0xff, 0xff, 0x4c, 0x21, 0x00, 0x00, 0x3d, + 0xf0, 0xff, 0xff, 0x56, 0xf9, 0xff, 0xff, 0x36, 0xef, 0xff, 0xff, 0x77, 0xea, + 0xff, 0xff, 0x77, 0xfc, 0xff, 0xff, 0xf0, 0xd8, 0xff, 0xff, 0x18, 0x29, 0x00, + 0x00, 0x9d, 0x0c, 0x00, 0x00, 0x0f, 0x26, 0x00, 0x00, 0xa1, 0x30, 0x00, 0x00, + 0x74, 0xea, 0xff, 0xff, 0x47, 0xf1, 0xff, 0xff, 0x32, 0x18, 0xfe, 0xff, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xdb, 0x02, 0x20, 0x9a, 0x25, 0x14, + 0x19, 0x7f, 0xc5, 0x6c, 0xfe, 0xd7, 0x27, 0xd0, 0x05, 0xef, 0x21, 0xdb, 0x5c, + 0xc6, 0x0f, 0x08, 0xf8, 0x01, 0x2a, 0xff, 0xcb, 0xf5, 0xe1, 0x28, 0xa5, 0x94, + 0x45, 0xfd, 0xdd, 0xf7, 0xd6, 0xfb, 0x18, 0xda, 0x0a, 0xf8, 0xec, 0x23, 0xe2, + 0x28, 0xd7, 0x3a, 0x11, 0x15, 0x15, 0x0d, 0xe2, 0xb6, 0x0a, 0xf1, 0x9f, 0xab, + 0xf4, 0xed, 0x18, 0x0e, 0x0f, 0xef, 0xf1, 0xea, 0xeb, 0x11, 0xf5, 0xbd, 0xfd, + 0xf0, 0x52, 0x1f, 0xdd, 0xe3, 0xcd, 0xc3, 0x10, 0xc0, 0xdd, 0xe6, 0x01, 0x33, + 0xfa, 0x1b, 0x6a, 0xb7, 0x1a, 0xeb, 0x43, 0x0e, 0x32, 0x07, 0xed, 0xe0, 0xdd, + 0x2c, 0x2c, 0xe9, 0xc9, 0x17, 0xfa, 0x1e, 0x4b, 0x7f, 0x28, 0xef, 0x51, 0xed, + 0x9d, 0x57, 0x6a, 0xe6, 0xcb, 0x1d, 0xba, 0x20, 0xb6, 0x7c, 0x1c, 0x06, 0xf2, + 0xb2, 0xfb, 0x2b, 0x13, 0x1a, 0xcd, 0x03, 0xce, 0xda, 0xb9, 0x27, 0x38, 0x05, + 0xe9, 0x33, 0x2b, 0xf9, 0x4e, 0x32, 0xbb, 0xe8, 0x15, 0xae, 0x31, 0x18, 0xce, + 0x47, 0x1e, 0xf7, 0x3b, 0xe2, 0x02, 0x23, 0xcf, 0x08, 0xf4, 0xe4, 0xf7, 0x23, + 0xe9, 0x2f, 0xbb, 0xde, 0xe9, 0xe4, 0xf7, 0x1b, 0x01, 0x19, 0xf5, 0x58, 0x42, + 0x06, 0x04, 0x12, 0x08, 0x7f, 0x0d, 0x2c, 0x06, 0x0e, 0x06, 0xee, 0xe2, 0x20, + 0xb7, 0xe0, 0xf4, 0x1e, 0xf6, 0xc9, 0x1b, 0x10, 0xf6, 0x64, 0xe0, 0xcc, 0xdc, + 0x14, 0x2d, 0x30, 0xfd, 0xc3, 0x21, 0x21, 0xcd, 0xc6, 0xf3, 0x10, 0x12, 0xec, + 0x01, 0xdc, 0xe9, 0xde, 0x23, 0xe0, 0x1a, 0x23, 0xfa, 0x24, 0xe7, 0x1b, 0x0f, + 0x11, 0x0f, 0x37, 0xdc, 0xee, 0x11, 0x0a, 0x16, 0x73, 0xf1, 0xcf, 0xd4, 0x20, + 0xf6, 0x4d, 0x1d, 0x0d, 0x25, 0x09, 0x0e, 0xc4, 0xf6, 0xd0, 0xe2, 0x34, 0xe4, + 0xf1, 0xf9, 0xe1, 0x42, 0xf6, 0xef, 0x0c, 0x67, 0x35, 0xf9, 0xe8, 0xc7, 0x03, + 0x23, 0x1e, 0x20, 0x3b, 0x3e, 0xd8, 0xf5, 0x47, 0xcb, 0xb1, 0xac, 0xcf, 0xe4, + 0xfa, 0x14, 0x07, 0x07, 0x76, 0xc3, 0xeb, 0x66, 0x1f, 0x52, 0xe5, 0xbb, 0xc5, + 0x59, 0x1a, 0xd8, 0xf7, 0x02, 0xdd, 0x2c, 0x4d, 0x96, 0x44, 0x00, 0x1a, 0x2e, + 0xd8, 0x08, 0x44, 0x1b, 0xfd, 0xfb, 0x39, 0xc1, 0xf1, 0xde, 0x4c, 0xed, 0x56, + 0x19, 0x48, 0xc3, 0xeb, 0xec, 0x08, 0xb8, 0x0d, 0x16, 0xdf, 0xdd, 0xce, 0x0b, + 0x59, 0xde, 0x99, 0xe6, 0x0c, 0xac, 0xd0, 0x43, 0x1d, 0xb2, 0xd9, 0x03, 0xd9, + 0xfc, 0xde, 0xf7, 0xa9, 0xf9, 0x33, 0xf6, 0xde, 0x1d, 0xd8, 0x3a, 0xe8, 0x43, + 0xaa, 0x8f, 0xd6, 0xb5, 0x11, 0x4f, 0x24, 0x15, 0xa2, 0xb2, 0xf6, 0xce, 0xfa, + 0xc4, 0x0b, 0x1c, 0x84, 0x65, 0xf9, 0xb1, 0x15, 0x0c, 0xf7, 0xc8, 0xca, 0x81, + 0xf0, 0xe2, 0x4c, 0xba, 0x0e, 0x23, 0xc0, 0x36, 0x11, 0xe9, 0x11, 0xf9, 0xb4, + 0xe8, 0xe8, 0xf5, 0x30, 0xb6, 0x0d, 0xc1, 0x08, 0xb6, 0xb3, 0x23, 0x9e, 0xf3, + 0xe2, 0xb0, 0x00, 0x37, 0xf5, 0xf9, 0x0b, 0xb1, 0x22, 0xc0, 0xed, 0x01, 0x23, + 0xeb, 0xec, 0x24, 0xee, 0xe2, 0x1d, 0xfb, 0xe0, 0xf9, 0xc5, 0x2a, 0xf9, 0x81, + 0x19, 0xb9, 0xf7, 0x4b, 0x28, 0x10, 0xe1, 0x34, 0x02, 0x1f, 0xd2, 0x05, 0xf9, + 0xdf, 0xf6, 0x27, 0x06, 0x16, 0xfe, 0xcf, 0xf6, 0xff, 0xfc, 0xce, 0xe8, 0xe8, + 0xf4, 0xd9, 0x13, 0xb4, 0x1b, 0x08, 0x0a, 0x40, 0xf4, 0x27, 0x0a, 0x21, 0x1e, + 0xf4, 0xdc, 0x17, 0x50, 0x0f, 0xe5, 0x36, 0xf6, 0xe8, 0xe0, 0x41, 0x22, 0xe9, + 0x24, 0x2c, 0x40, 0x18, 0xe5, 0xfa, 0xf2, 0x16, 0xf6, 0x34, 0x09, 0xfa, 0x46, + 0x01, 0xf2, 0x9d, 0x2b, 0x38, 0x2e, 0x1f, 0xd4, 0x25, 0x17, 0xf8, 0x05, 0x39, + 0xb2, 0xf3, 0x2b, 0xd6, 0xfe, 0xc6, 0xb4, 0xf0, 0x0f, 0x90, 0x45, 0xc0, 0xa4, + 0x24, 0x44, 0x13, 0x08, 0x14, 0x03, 0xa6, 0xca, 0x98, 0xa5, 0x0f, 0x47, 0xd4, + 0xef, 0x36, 0x0d, 0x9a, 0x6f, 0xbb, 0xf7, 0x0a, 0x1b, 0xd6, 0xe4, 0x07, 0x00, + 0x02, 0x27, 0xb3, 0xff, 0x6c, 0x1b, 0xd9, 0x00, 0x2e, 0xa9, 0x7f, 0xdc, 0x28, + 0x9c, 0x97, 0xc2, 0xdb, 0x30, 0xeb, 0x1c, 0x2d, 0x3b, 0x09, 0x15, 0xe9, 0x39, + 0x41, 0x63, 0xe4, 0x9a, 0x3f, 0x08, 0xf0, 0x59, 0x00, 0xf8, 0x38, 0x17, 0xdc, + 0x24, 0x31, 0xb7, 0x58, 0xe9, 0x00, 0xf7, 0xf5, 0x2a, 0x28, 0x01, 0xf5, 0xf2, + 0xf4, 0x0d, 0x49, 0xfc, 0x12, 0xd4, 0x64, 0xae, 0x35, 0x34, 0xb7, 0x2d, 0xf8, + 0x03, 0xd2, 0x06, 0x23, 0xcb, 0x09, 0xd9, 0xee, 0x54, 0xb5, 0x0a, 0xc4, 0x66, + 0x14, 0xc7, 0x17, 0xd7, 0xde, 0x23, 0xd8, 0x11, 0x16, 0x22, 0xfc, 0xff, 0xce, + 0x3f, 0x10, 0xf5, 0xf9, 0x3e, 0x13, 0xf8, 0xfc, 0xdb, 0xe3, 0x55, 0x09, 0xec, + 0xdc, 0x11, 0x04, 0x15, 0x13, 0x19, 0xfc, 0x7f, 0xef, 0x02, 0x0a, 0xee, 0xed, + 0x28, 0xe4, 0x13, 0x2d, 0x08, 0x0b, 0x21, 0xfd, 0xe4, 0x09, 0xc6, 0xc1, 0x34, + 0x04, 0x04, 0x0a, 0xe5, 0xfa, 0xd1, 0x22, 0x04, 0x0f, 0x03, 0xdc, 0xf9, 0x2c, + 0xe1, 0xd1, 0xfa, 0xdc, 0xed, 0x2a, 0x65, 0x06, 0x2e, 0xf9, 0x2f, 0x02, 0x9b, + 0xeb, 0x2f, 0xe8, 0x02, 0xe3, 0x0c, 0x10, 0x10, 0xe9, 0x02, 0xfa, 0xfe, 0x13, + 0x12, 0xd4, 0xcb, 0xd4, 0xfd, 0xe8, 0xe1, 0xf2, 0x25, 0x05, 0xc8, 0xec, 0xf7, + 0xce, 0x01, 0x3c, 0xda, 0xfb, 0xcf, 0xfd, 0xf0, 0x44, 0xf9, 0x11, 0x0a, 0xf3, + 0x04, 0x26, 0xf8, 0xdf, 0xed, 0x0e, 0xdd, 0x1c, 0x02, 0xc9, 0xd8, 0xfb, 0xdb, + 0x0d, 0xf5, 0x10, 0xd5, 0xf5, 0xea, 0x3a, 0xea, 0x03, 0xfd, 0x17, 0xf5, 0x04, + 0x16, 0xff, 0xf8, 0x09, 0xe2, 0xe9, 0x4c, 0xf8, 0x4f, 0xd5, 0x27, 0xd4, 0x4a, + 0x20, 0x40, 0x7f, 0xeb, 0xcf, 0xe4, 0x26, 0xfd, 0x18, 0x08, 0xce, 0x0c, 0x13, + 0x08, 0xda, 0x12, 0x24, 0xe2, 0x25, 0x3f, 0xeb, 0x08, 0x24, 0xb4, 0x1e, 0x03, + 0xf1, 0xcc, 0x00, 0xbe, 0xb6, 0x0d, 0x21, 0x10, 0x1a, 0xf5, 0xf7, 0x05, 0xfa, + 0x03, 0x14, 0x00, 0xe7, 0x3c, 0x28, 0xe8, 0x58, 0x1e, 0xbf, 0x12, 0x62, 0xcb, + 0x7a, 0xfb, 0x1e, 0xf5, 0x1d, 0xf1, 0xe7, 0xf7, 0xd8, 0x06, 0xcc, 0xda, 0xfc, + 0x19, 0xc5, 0xf6, 0xdd, 0x10, 0xd5, 0x24, 0xfd, 0x26, 0xf1, 0xbd, 0xbf, 0x40, + 0xf6, 0x41, 0x3e, 0x1f, 0x51, 0xdc, 0xbe, 0x39, 0x19, 0x20, 0xe0, 0xbe, 0x04, + 0x1e, 0x08, 0xfb, 0xf6, 0x26, 0x0b, 0xc2, 0xc9, 0x13, 0x2c, 0x34, 0x37, 0xfe, + 0xf2, 0x1a, 0xe6, 0xe8, 0x29, 0x1a, 0x18, 0x15, 0xe7, 0x75, 0xd2, 0xdd, 0x13, + 0xde, 0x0b, 0xec, 0x24, 0xd8, 0xd9, 0xd2, 0x06, 0x2a, 0x10, 0xbe, 0xc6, 0xf9, + 0x19, 0x22, 0x57, 0xb9, 0xef, 0x1a, 0xd2, 0xe7, 0xfe, 0x07, 0x22, 0x0c, 0x2c, + 0x26, 0x81, 0xb0, 0xcb, 0xf6, 0x34, 0x15, 0x43, 0xf2, 0x0a, 0x42, 0xdf, 0xdc, + 0xc8, 0xe7, 0xd2, 0xef, 0xf9, 0x17, 0xee, 0x0e, 0xe1, 0x19, 0x0c, 0xb0, 0x36, + 0x0e, 0x24, 0xee, 0x37, 0x24, 0x09, 0xf8, 0xb4, 0x0c, 0x38, 0xfc, 0xf5, 0x4c, + 0xc0, 0x27, 0xff, 0x19, 0xf1, 0x23, 0x0a, 0xba, 0x4a, 0x54, 0x46, 0xae, 0x00, + 0xcf, 0xe4, 0xd7, 0xd6, 0xc6, 0x05, 0x13, 0xbb, 0x08, 0xed, 0xd0, 0x05, 0x5f, + 0xcd, 0xf2, 0xdf, 0xff, 0xca, 0xc1, 0xc6, 0xfc, 0x0f, 0x7c, 0xd2, 0x17, 0x40, + 0x00, 0xed, 0x98, 0xcd, 0x23, 0xbd, 0xf2, 0xce, 0xf8, 0x07, 0x35, 0x4f, 0xed, + 0x02, 0xee, 0x14, 0x46, 0x25, 0xe9, 0xe7, 0x90, 0x38, 0x24, 0xec, 0x09, 0xa8, + 0xf5, 0x59, 0x15, 0x28, 0xf7, 0x05, 0xee, 0x0e, 0x1b, 0xe5, 0x64, 0xfe, 0x36, + 0xd4, 0x2f, 0x72, 0xe8, 0x37, 0xda, 0xd7, 0x15, 0xc1, 0x92, 0x19, 0x01, 0x21, + 0xa9, 0xb1, 0xdf, 0x46, 0x1c, 0x2e, 0x08, 0xd1, 0x48, 0xe8, 0xe3, 0x37, 0x5d, + 0x0d, 0x3c, 0xf6, 0xa3, 0xeb, 0xa5, 0xce, 0x07, 0xf5, 0xae, 0x1c, 0x0f, 0x5d, + 0x5b, 0x2d, 0xa3, 0x24, 0x4e, 0x50, 0x10, 0xe1, 0x1d, 0x2a, 0x26, 0x18, 0x4b, + 0xdc, 0x32, 0xcd, 0x20, 0xf9, 0xe0, 0xfe, 0x9a, 0xe3, 0xe2, 0xb5, 0x3f, 0xfe, + 0x35, 0xe6, 0xa9, 0x37, 0xb6, 0xf0, 0x40, 0x0a, 0xc4, 0xd7, 0xf0, 0x72, 0x03, + 0xe8, 0xeb, 0x11, 0xf3, 0xf1, 0xcd, 0x1c, 0xe2, 0x29, 0x1b, 0xe1, 0x21, 0x1b, + 0xe4, 0x25, 0x09, 0xc7, 0x37, 0xbf, 0x81, 0x33, 0x86, 0x0d, 0xcc, 0xe7, 0xce, + 0x32, 0xf7, 0x11, 0x03, 0x1c, 0xed, 0xe8, 0xea, 0x42, 0x96, 0x00, 0x3f, 0x07, + 0xf2, 0xfd, 0x19, 0x2a, 0xc7, 0x0a, 0x0e, 0x62, 0xb3, 0x1a, 0xab, 0x0f, 0xb2, + 0x28, 0x19, 0xf3, 0xdb, 0x1c, 0x26, 0xf0, 0xf5, 0x2a, 0x19, 0xad, 0xcc, 0xcf, + 0x26, 0x3a, 0x34, 0xc1, 0xff, 0x07, 0x1d, 0xec, 0x21, 0xcc, 0x1a, 0xbf, 0x11, + 0xcb, 0x0c, 0x2d, 0x3a, 0x0a, 0xcd, 0x10, 0x4c, 0x12, 0xfa, 0xd0, 0xf9, 0xe6, + 0x1b, 0xb1, 0xe5, 0xd8, 0x2b, 0x13, 0xf5, 0xe4, 0x22, 0x21, 0x01, 0x45, 0xf9, + 0x1d, 0xfb, 0x25, 0xf8, 0x35, 0x4d, 0xca, 0x19, 0x30, 0xcf, 0xee, 0x02, 0xe3, + 0xf1, 0x1b, 0x0d, 0xe2, 0x23, 0x3f, 0x26, 0x34, 0x00, 0x5a, 0x0a, 0x7f, 0xed, + 0x39, 0x1b, 0x09, 0xdd, 0x0e, 0xca, 0xbf, 0xc1, 0x1b, 0x54, 0x3c, 0x38, 0xb0, + 0xf8, 0x32, 0x24, 0x24, 0x0a, 0xe7, 0x25, 0x5c, 0xca, 0x33, 0x18, 0xdc, 0x3c, + 0xc9, 0xfa, 0x06, 0x47, 0x08, 0xfc, 0x17, 0x07, 0x10, 0xfe, 0xbe, 0xe1, 0xe5, + 0x31, 0x49, 0xdb, 0xdc, 0xab, 0x2b, 0x04, 0xe2, 0xe2, 0xc6, 0x40, 0xff, 0x02, + 0xdc, 0xe2, 0xe8, 0x21, 0x07, 0xf0, 0xf7, 0xe8, 0x32, 0xf0, 0x46, 0x36, 0x0a, + 0xe6, 0xd4, 0x04, 0xd2, 0xc1, 0x52, 0xe1, 0x13, 0x17, 0x0c, 0xca, 0x2d, 0xe3, + 0x28, 0xdc, 0xc8, 0x06, 0xf0, 0xb5, 0x0c, 0xc9, 0x47, 0x43, 0xde, 0x2b, 0x3f, + 0x23, 0x37, 0xb9, 0x09, 0x1a, 0x25, 0x57, 0x74, 0xec, 0xbe, 0x09, 0xe7, 0x54, + 0xd0, 0xf1, 0x19, 0x07, 0x3e, 0x81, 0xca, 0x21, 0xe4, 0x07, 0x10, 0x1a, 0xca, + 0x2c, 0xe9, 0xc3, 0xce, 0x4c, 0xf8, 0x1b, 0x33, 0x12, 0x26, 0x12, 0x1b, 0x09, + 0xdd, 0xe3, 0xef, 0x00, 0xdc, 0xed, 0xbb, 0xef, 0x13, 0xf9, 0x07, 0xf0, 0x14, + 0xf8, 0x1a, 0xf2, 0xf0, 0x32, 0x13, 0xf1, 0x16, 0x01, 0x25, 0xef, 0x9a, 0xc3, + 0xfa, 0x02, 0x03, 0x0e, 0xe4, 0xb7, 0x11, 0x10, 0xd3, 0xec, 0x11, 0x3c, 0x30, + 0xe5, 0xe3, 0x37, 0x0a, 0xd3, 0xf0, 0xfb, 0xf8, 0x20, 0x06, 0x14, 0xfc, 0x1d, + 0x18, 0x24, 0xfa, 0x3e, 0x6c, 0x0c, 0xce, 0xe4, 0x36, 0x38, 0xb6, 0x1b, 0xe4, + 0xf8, 0x23, 0xe8, 0x00, 0xe8, 0x06, 0x0a, 0xcf, 0xeb, 0xfb, 0xde, 0xf7, 0x44, + 0xef, 0xde, 0xee, 0x98, 0x11, 0xfe, 0x35, 0xef, 0xde, 0x23, 0x07, 0xbf, 0x35, + 0x0e, 0x02, 0xfc, 0x7f, 0xd5, 0x09, 0xd7, 0x1e, 0xf6, 0x09, 0xcb, 0xef, 0x09, + 0x24, 0xf0, 0xec, 0xf3, 0xa7, 0xea, 0x22, 0x26, 0x1b, 0x39, 0x13, 0x4d, 0xf7, + 0xc4, 0xd7, 0xe7, 0xf4, 0x07, 0xf6, 0xf8, 0x08, 0xe3, 0xd6, 0x1c, 0x60, 0xb3, + 0xbc, 0x0c, 0xf5, 0xd0, 0x05, 0x31, 0xf0, 0x60, 0xbf, 0x00, 0xbc, 0xcd, 0x4b, + 0xbc, 0xdb, 0x0d, 0xf4, 0xec, 0xf2, 0x26, 0xc9, 0x1c, 0x25, 0xae, 0x5f, 0x4f, + 0xf6, 0xea, 0xd3, 0xb9, 0x96, 0xe6, 0x3a, 0x2f, 0xff, 0x05, 0x2d, 0xa4, 0x12, + 0x56, 0x5b, 0xec, 0xcb, 0xd1, 0x29, 0x9a, 0xb9, 0x27, 0x02, 0x22, 0x3c, 0x0f, + 0x1f, 0xec, 0x9f, 0xfc, 0x97, 0xf5, 0x0c, 0xfb, 0x10, 0x03, 0xf0, 0x27, 0xb6, + 0x67, 0xe9, 0xd9, 0xa3, 0xbd, 0x3a, 0xe2, 0xe1, 0xa0, 0xcb, 0x40, 0x2f, 0x3f, + 0x01, 0xf1, 0xfe, 0x81, 0xf8, 0x4e, 0x8b, 0x06, 0x09, 0x2f, 0x46, 0x12, 0xc5, + 0x15, 0xd0, 0x14, 0x8f, 0x1a, 0xea, 0x1d, 0x14, 0x3b, 0x0c, 0x74, 0x1c, 0x87, + 0x31, 0xd4, 0xd6, 0x39, 0xac, 0xc2, 0x32, 0x3d, 0x04, 0xcd, 0xd2, 0x16, 0x6d, + 0xc3, 0x3d, 0xf7, 0x02, 0xe4, 0x02, 0xd6, 0xac, 0x2a, 0x66, 0x02, 0xa3, 0xb8, + 0xec, 0xe3, 0xea, 0x4a, 0xeb, 0xec, 0x2c, 0xf8, 0x42, 0xec, 0x2b, 0xe0, 0x2f, + 0x30, 0xfb, 0x1d, 0xe3, 0xed, 0x2a, 0x5a, 0xd7, 0x5d, 0x12, 0x9f, 0x06, 0xdd, + 0x09, 0xce, 0x09, 0xc6, 0x09, 0xf1, 0xfd, 0xe5, 0x1e, 0xe4, 0xe6, 0xab, 0x17, + 0x97, 0xe4, 0xcb, 0xdc, 0x32, 0xd6, 0xc4, 0xb6, 0x0e, 0xfe, 0x38, 0x2d, 0xc1, + 0x03, 0xe1, 0x0f, 0xf8, 0xaf, 0xf2, 0x02, 0xba, 0xfc, 0x16, 0xaf, 0xc1, 0x26, + 0x0b, 0xe7, 0x3e, 0x35, 0x0a, 0x59, 0x0e, 0x7a, 0xc4, 0x55, 0xf8, 0xe2, 0xce, + 0x7c, 0xc7, 0xb9, 0xff, 0xcb, 0xf1, 0xed, 0xf5, 0x06, 0xe3, 0xa7, 0x81, 0xec, + 0xcb, 0x04, 0xc0, 0x16, 0xf6, 0x3d, 0xcc, 0x2d, 0xe6, 0xe5, 0x09, 0x12, 0x58, + 0x24, 0x21, 0x17, 0xc7, 0xeb, 0xe8, 0xcb, 0x08, 0xd8, 0x09, 0x83, 0xdc, 0xb5, + 0x16, 0xf5, 0xf2, 0xc8, 0xa6, 0x2a, 0xe1, 0xf7, 0x37, 0xf0, 0x2a, 0xe9, 0xf5, + 0x19, 0xe8, 0x19, 0xc8, 0x2c, 0x13, 0xdb, 0x57, 0x2b, 0xd1, 0x49, 0xff, 0x0d, + 0xff, 0x0e, 0x15, 0xd9, 0x14, 0x1d, 0x05, 0x24, 0xb6, 0x6d, 0xed, 0x03, 0xaf, + 0x3d, 0x2f, 0x9b, 0xfe, 0x00, 0xed, 0xf8, 0xd9, 0x3d, 0xfc, 0x2c, 0x1f, 0xdc, + 0xa4, 0xcc, 0x1e, 0xd0, 0x32, 0x10, 0xbb, 0x09, 0xff, 0xea, 0x94, 0xf3, 0x1b, + 0xf7, 0xeb, 0xea, 0xfa, 0x30, 0xc8, 0xdf, 0xdb, 0x08, 0xea, 0x18, 0xd1, 0x41, + 0x30, 0xf6, 0xf5, 0xd3, 0xdf, 0xad, 0x1b, 0xb0, 0x0b, 0x14, 0xf9, 0xf6, 0xf3, + 0x11, 0xe7, 0xed, 0xfb, 0x35, 0x1c, 0xcf, 0x1e, 0xb9, 0xfd, 0x4b, 0xe4, 0xd8, + 0x23, 0x12, 0x05, 0x0d, 0xf5, 0x43, 0x08, 0x11, 0xed, 0x03, 0xde, 0xe7, 0x34, + 0xfe, 0xc9, 0xfa, 0xdb, 0x2a, 0x16, 0x28, 0x87, 0x1f, 0x09, 0xe2, 0x25, 0x27, + 0xdd, 0x4d, 0x1a, 0xff, 0xd9, 0x4f, 0x1e, 0x36, 0xe3, 0xde, 0x81, 0x4f, 0x53, + 0x43, 0xf3, 0x3b, 0x03, 0xeb, 0xc4, 0xe7, 0x21, 0x4b, 0x02, 0x17, 0x19, 0xff, + 0x04, 0xdb, 0xbb, 0x0d, 0xf0, 0xe3, 0x74, 0xc0, 0x15, 0xef, 0x06, 0x0a, 0xfb, + 0xfd, 0x0b, 0xc9, 0xd5, 0x28, 0x09, 0xc9, 0x2d, 0x19, 0x01, 0x27, 0x2f, 0x1d, + 0x7b, 0xde, 0xe4, 0xd9, 0xfa, 0x09, 0x2d, 0xed, 0xfd, 0xe2, 0x3d, 0x02, 0xde, + 0xaf, 0x02, 0xe5, 0x2f, 0xca, 0x66, 0xc4, 0xcd, 0x0d, 0x06, 0x06, 0xa5, 0x2b, + 0xc9, 0xe6, 0x02, 0x1f, 0xbc, 0x35, 0x04, 0xf7, 0xd8, 0x2c, 0xec, 0x20, 0x1c, + 0x0f, 0x13, 0x75, 0xed, 0x1a, 0x21, 0x23, 0x38, 0x22, 0x12, 0x08, 0xed, 0xc3, + 0xe7, 0xff, 0x32, 0xa1, 0x18, 0x46, 0xf0, 0x4c, 0xe8, 0x08, 0x7a, 0xe0, 0xe2, + 0x15, 0x81, 0xa2, 0x0f, 0xdb, 0xac, 0x1f, 0xf5, 0x14, 0x4a, 0x24, 0x3c, 0x05, + 0xe6, 0x5e, 0x3f, 0x05, 0x36, 0xef, 0xb3, 0x0d, 0x2d, 0xe4, 0xb3, 0xe7, 0x02, + 0x29, 0xf4, 0xf1, 0x6b, 0xe0, 0x02, 0x3f, 0xe3, 0x3e, 0x33, 0x21, 0xef, 0x4e, + 0xfd, 0xe9, 0x4e, 0x30, 0xe1, 0x09, 0xa6, 0xf5, 0xf3, 0xc2, 0x04, 0x9c, 0xe2, + 0xd9, 0x0d, 0xdf, 0x06, 0x9c, 0xbd, 0xf7, 0xd6, 0x0b, 0xf8, 0xda, 0xf3, 0x26, + 0xf9, 0x15, 0xeb, 0x2c, 0xc1, 0xa8, 0xcf, 0xed, 0x20, 0x92, 0x21, 0xde, 0xd0, + 0xf4, 0xc5, 0x28, 0x0c, 0x0f, 0xe1, 0x3b, 0xf9, 0xd7, 0xe4, 0x04, 0xe9, 0x84, + 0x00, 0x3a, 0xeb, 0xea, 0x04, 0x0d, 0xb2, 0xd7, 0xfb, 0x2f, 0xf8, 0x06, 0xeb, + 0xf2, 0xf9, 0x06, 0xf1, 0xc2, 0x0e, 0xf7, 0x00, 0x89, 0xd3, 0x62, 0xda, 0xed, + 0x19, 0x1a, 0xf5, 0x07, 0x15, 0xe6, 0xf5, 0x7f, 0xeb, 0x36, 0xe2, 0x5b, 0x16, + 0xdc, 0x0a, 0x00, 0xcc, 0xfd, 0xf5, 0x01, 0xe9, 0x02, 0xc7, 0x25, 0x40, 0xac, + 0xd0, 0x4a, 0xf5, 0xeb, 0xf8, 0xfb, 0x8c, 0x3d, 0x1f, 0x0b, 0x11, 0x2f, 0x3d, + 0x21, 0xb2, 0xfc, 0x36, 0xfa, 0x2f, 0x20, 0x0d, 0x26, 0x1d, 0xec, 0xca, 0x12, + 0x0d, 0x3d, 0x11, 0x2c, 0x9c, 0x1c, 0x3b, 0x25, 0x15, 0x16, 0xd4, 0x3b, 0xce, + 0x63, 0x7f, 0x50, 0xe2, 0x18, 0xdc, 0xbd, 0xd5, 0xe8, 0x42, 0xdd, 0x7c, 0xd6, + 0xce, 0x0c, 0x16, 0xf6, 0x05, 0xf7, 0x19, 0xde, 0xf8, 0xff, 0xe8, 0xf4, 0xef, + 0xd7, 0xee, 0xee, 0x02, 0x6a, 0x49, 0x57, 0xd2, 0x09, 0xdc, 0xb6, 0x4d, 0x00, + 0xfd, 0x4b, 0xf5, 0x3d, 0x01, 0x35, 0xf5, 0x1e, 0x10, 0xef, 0x35, 0x05, 0x71, + 0x23, 0x1e, 0x03, 0xfe, 0xd3, 0xe2, 0x48, 0xfa, 0x1a, 0xc5, 0x48, 0xda, 0x44, + 0xe2, 0xc3, 0x08, 0xc0, 0x16, 0xd9, 0xaa, 0x36, 0xdd, 0x1b, 0xe2, 0x40, 0xf5, + 0x09, 0x3c, 0x88, 0x1c, 0x3e, 0x15, 0x1f, 0xd2, 0x04, 0xde, 0xfd, 0xc9, 0xe4, + 0x29, 0x02, 0x0d, 0xd0, 0x1f, 0x20, 0xff, 0x7a, 0xd9, 0xd2, 0x0f, 0xed, 0x05, + 0x43, 0x38, 0x18, 0xd1, 0xf6, 0x0e, 0x18, 0x0c, 0xb4, 0xef, 0xc0, 0xfd, 0xdb, + 0x41, 0x33, 0xa3, 0x2a, 0x10, 0x57, 0x52, 0x27, 0x54, 0x06, 0x0b, 0xe6, 0xf9, + 0xf6, 0xff, 0xef, 0xa6, 0x20, 0xbc, 0x34, 0xda, 0xfa, 0x20, 0xcf, 0x1a, 0x02, + 0xd0, 0xc4, 0xc3, 0xdd, 0x47, 0xe0, 0xb6, 0xbd, 0xe5, 0x48, 0x1a, 0x38, 0xa8, + 0x26, 0x14, 0x25, 0x08, 0xdc, 0xc8, 0xa5, 0xbe, 0x71, 0xc6, 0x81, 0x13, 0xb3, + 0xee, 0xcf, 0x19, 0xe4, 0x07, 0x08, 0x19, 0xae, 0xa0, 0x92, 0xab, 0x55, 0xc0, + 0xc6, 0xf3, 0xbf, 0x0d, 0xe3, 0x6b, 0xb3, 0xe4, 0xfa, 0x82, 0x58, 0x3b, 0xd9, + 0xb7, 0xef, 0xbb, 0x22, 0xdb, 0x1c, 0xc1, 0x14, 0xec, 0x08, 0xc7, 0x29, 0xca, + 0x71, 0x8c, 0xcf, 0xef, 0x69, 0xde, 0x4a, 0x68, 0xeb, 0x13, 0x07, 0xf9, 0x19, + 0x0a, 0xa4, 0x11, 0xf8, 0x1b, 0x28, 0x25, 0xea, 0x68, 0xea, 0xb8, 0xd2, 0x12, + 0xc4, 0xff, 0x27, 0xa4, 0xf1, 0xf6, 0x26, 0x4f, 0x43, 0xf8, 0xca, 0xf1, 0xf9, + 0xcf, 0xe7, 0xec, 0xe5, 0xfd, 0xc9, 0xdf, 0x41, 0x04, 0xe5, 0xef, 0xf8, 0xa7, + 0xf0, 0x00, 0xfd, 0x1c, 0xd0, 0xa7, 0xcc, 0x05, 0xc5, 0x03, 0x18, 0x15, 0xf5, + 0x03, 0xc2, 0x7f, 0xc2, 0x25, 0xf6, 0xcf, 0x1a, 0xe5, 0xf4, 0xda, 0x2b, 0x11, + 0x09, 0x21, 0xa8, 0x09, 0xde, 0x54, 0xcf, 0xc5, 0x05, 0x48, 0xf9, 0x06, 0x36, + 0xc5, 0xde, 0xdb, 0xc2, 0xd2, 0x3e, 0x17, 0x35, 0xee, 0x00, 0x17, 0xe7, 0xf8, + 0xf5, 0x1c, 0x03, 0x48, 0x2a, 0xff, 0x35, 0x32, 0x16, 0xfb, 0x1c, 0xf8, 0xea, + 0x07, 0xdf, 0x02, 0x47, 0x33, 0x16, 0x02, 0x11, 0xda, 0xef, 0x3c, 0x04, 0x1b, + 0xd0, 0xb7, 0x03, 0xf9, 0x04, 0x57, 0x45, 0xc8, 0xae, 0xf1, 0x1b, 0xfd, 0x40, + 0xf3, 0x24, 0xae, 0x11, 0xd4, 0x1a, 0x31, 0x16, 0x0f, 0x2a, 0x9d, 0xef, 0x26, + 0x0d, 0x07, 0x10, 0xfd, 0xc0, 0x4e, 0xfd, 0xe4, 0xb0, 0x28, 0xd3, 0xc0, 0xdc, + 0xf1, 0xed, 0xe9, 0x2d, 0x04, 0xd2, 0x13, 0x65, 0xfa, 0xd8, 0xe8, 0x30, 0x7f, + 0xdd, 0xf9, 0xfb, 0x63, 0x11, 0xcd, 0x1e, 0xf1, 0xc2, 0xc9, 0x3e, 0x8f, 0xf0, + 0x32, 0xd4, 0xf4, 0xaf, 0x03, 0xe7, 0x71, 0x20, 0x32, 0xe9, 0xb6, 0xfd, 0xed, + 0x42, 0x01, 0xb2, 0xef, 0xc2, 0xf8, 0xe8, 0xe4, 0xc9, 0x1a, 0xc1, 0x27, 0x6d, + 0xe9, 0x17, 0x24, 0xd0, 0x03, 0x24, 0xca, 0xd8, 0xd3, 0xf1, 0x0a, 0x09, 0xd9, + 0xfa, 0x0b, 0xe1, 0x20, 0xce, 0xe9, 0x29, 0x3a, 0xf7, 0xe9, 0xe8, 0xec, 0xfd, + 0x16, 0xf9, 0xee, 0xf1, 0xf4, 0xee, 0xd3, 0xda, 0x9f, 0xe2, 0xbb, 0xf4, 0x06, + 0x12, 0xf5, 0x04, 0xf4, 0x1a, 0xda, 0x4c, 0x25, 0x1a, 0xdd, 0x0d, 0x18, 0xc1, + 0xc4, 0x26, 0x1a, 0xdb, 0x13, 0xf9, 0x21, 0xf8, 0xf5, 0x51, 0xd3, 0x2f, 0xf2, + 0x4b, 0xb7, 0xfb, 0x2a, 0x1e, 0x1c, 0xdd, 0xea, 0x00, 0xce, 0x33, 0x2e, 0x02, + 0xde, 0x22, 0xf0, 0xe4, 0x0b, 0x2c, 0xf2, 0x7f, 0xaa, 0x20, 0x1b, 0x0a, 0x2d, + 0xe4, 0xfe, 0x36, 0xea, 0xe8, 0x1f, 0x1e, 0xe2, 0x3c, 0x0e, 0xcc, 0xf4, 0x05, + 0x2a, 0xd9, 0x11, 0x03, 0xda, 0xf9, 0xf9, 0x24, 0x00, 0x18, 0x10, 0x22, 0x2d, + 0xcf, 0x16, 0x24, 0x0f, 0x22, 0x2a, 0x02, 0xee, 0xe3, 0xd6, 0xf5, 0x5b, 0xf5, + 0x44, 0x09, 0xc3, 0xb4, 0xf0, 0x36, 0xe2, 0xb4, 0x0a, 0xea, 0x9b, 0xbf, 0xea, + 0x07, 0xd5, 0x53, 0xf4, 0x2a, 0x06, 0x1c, 0x1c, 0xe5, 0xf2, 0xdc, 0x0b, 0x0d, + 0x5d, 0x03, 0xf7, 0xcb, 0xe6, 0x16, 0xee, 0xe1, 0x17, 0x07, 0xb8, 0xe5, 0xe5, + 0x01, 0xeb, 0xe2, 0xec, 0xd8, 0x1a, 0xe7, 0x47, 0xd0, 0x11, 0x04, 0xf7, 0x29, + 0xe1, 0xfb, 0x0f, 0x45, 0xc7, 0x19, 0x36, 0xd1, 0xc3, 0xed, 0x2f, 0xd3, 0xee, + 0xbc, 0x00, 0xf0, 0xe6, 0xc6, 0x09, 0xe1, 0x17, 0x01, 0x2d, 0x10, 0xb4, 0x39, + 0x04, 0xc0, 0xda, 0x18, 0xde, 0xc9, 0xbf, 0x7f, 0x28, 0x05, 0x0e, 0x02, 0x35, + 0xfc, 0xf4, 0x39, 0xfa, 0xea, 0x22, 0x2e, 0xee, 0x29, 0xf8, 0x3e, 0x18, 0xe7, + 0x36, 0xe0, 0xf4, 0xbd, 0x0c, 0x33, 0x04, 0x0e, 0xfd, 0x39, 0x16, 0x0f, 0x13, + 0xc8, 0xc6, 0x13, 0xd6, 0x21, 0x4e, 0x0d, 0x0c, 0x0f, 0x35, 0x2d, 0x2e, 0x11, + 0x3c, 0x4c, 0x2d, 0x9a, 0x05, 0x10, 0x1f, 0xf2, 0xb7, 0xc2, 0xca, 0xe5, 0x02, + 0xc9, 0x19, 0xec, 0x34, 0x02, 0xd5, 0x4b, 0x15, 0xe9, 0x6e, 0xea, 0xda, 0xed, + 0x04, 0xd7, 0x20, 0xfa, 0xdd, 0xde, 0x17, 0x01, 0x13, 0x05, 0x18, 0x25, 0xc9, + 0x43, 0x19, 0x09, 0xbe, 0xe6, 0xfd, 0xda, 0xc4, 0xf1, 0xe8, 0xb7, 0x21, 0x5e, + 0x2b, 0x02, 0x34, 0x1c, 0x0c, 0x39, 0xb0, 0xff, 0xe3, 0x05, 0x00, 0x60, 0xf0, + 0x16, 0xf8, 0x0e, 0x2a, 0x9f, 0x31, 0x19, 0xc8, 0xcd, 0xd6, 0xd9, 0x28, 0x23, + 0xdb, 0x4d, 0x4e, 0xd8, 0xeb, 0xec, 0xc7, 0xcf, 0x37, 0xbc, 0x51, 0x64, 0x79, + 0xf5, 0x38, 0xfa, 0xeb, 0xf8, 0xd1, 0x5a, 0xc9, 0x00, 0x50, 0xe8, 0xe9, 0x0c, + 0xec, 0x30, 0x54, 0xdf, 0xfb, 0x5e, 0x17, 0xe9, 0x6d, 0x25, 0x53, 0xe2, 0xba, + 0xfb, 0xb0, 0xee, 0xda, 0xfb, 0x33, 0xaa, 0xcc, 0xe9, 0xd1, 0xeb, 0x0a, 0xbf, + 0x10, 0xd1, 0xdd, 0x08, 0x14, 0x12, 0x91, 0x3c, 0xd3, 0x14, 0xc2, 0xf4, 0x69, + 0xc9, 0xeb, 0x22, 0xfd, 0xfd, 0xe6, 0x19, 0x52, 0xfa, 0xd5, 0xe8, 0x06, 0xe2, + 0x04, 0xce, 0x81, 0x07, 0xa0, 0x37, 0x24, 0x1a, 0x03, 0xce, 0x18, 0x21, 0x44, + 0x1d, 0x37, 0xc1, 0xce, 0x3e, 0x38, 0xc7, 0xb7, 0xe6, 0xd5, 0x1e, 0xa5, 0xf1, + 0x5b, 0xdf, 0xf0, 0x50, 0x4e, 0xf6, 0x0a, 0x2d, 0x09, 0xec, 0xf6, 0x01, 0xab, + 0xde, 0xb5, 0x1f, 0xfc, 0xfc, 0x98, 0x05, 0x32, 0xcf, 0xd3, 0xd0, 0xcd, 0xc7, + 0x02, 0xc6, 0x01, 0x17, 0x05, 0x01, 0xe6, 0xd9, 0x10, 0xc5, 0x15, 0x17, 0x72, + 0x15, 0xe8, 0xdb, 0x41, 0x43, 0xff, 0xcf, 0xc9, 0xbf, 0xce, 0xf2, 0x08, 0x1c, + 0xd8, 0xf9, 0xc8, 0x2a, 0xc3, 0xf5, 0x26, 0xd1, 0x0a, 0xae, 0x55, 0x38, 0x6c, + 0xbc, 0xd6, 0xf7, 0x83, 0x0b, 0x51, 0x69, 0xed, 0x6e, 0x50, 0xb2, 0x28, 0xbf, + 0x5c, 0x1d, 0x37, 0x1c, 0x85, 0xec, 0x18, 0xf0, 0xba, 0x65, 0xdd, 0x05, 0xfd, + 0x18, 0xd8, 0x28, 0xdc, 0x26, 0xce, 0xce, 0xe6, 0x7f, 0x29, 0xbc, 0x51, 0x2d, + 0xff, 0x04, 0xbd, 0x01, 0xa9, 0xea, 0x24, 0xca, 0x0b, 0xf7, 0xe7, 0x19, 0x5b, + 0x1f, 0x12, 0x0a, 0xb5, 0xde, 0x20, 0x30, 0x39, 0xe4, 0xec, 0xb2, 0x30, 0xd3, + 0xc2, 0xc9, 0xb0, 0x03, 0xe6, 0x30, 0xe0, 0xed, 0x43, 0xd2, 0xd8, 0xfd, 0xfd, + 0xdd, 0x14, 0xfc, 0xfc, 0xf9, 0xee, 0x16, 0x15, 0x28, 0x07, 0x16, 0x1e, 0x19, + 0x40, 0x19, 0x28, 0xf9, 0x0c, 0xeb, 0x09, 0x1e, 0xf5, 0xec, 0xdd, 0x33, 0x15, + 0xf8, 0xe9, 0x0b, 0xd9, 0x16, 0x02, 0x00, 0x24, 0xdc, 0xe8, 0xda, 0x31, 0x08, + 0xe5, 0x0f, 0x1d, 0xf0, 0xf3, 0xd9, 0xe5, 0x0b, 0x0a, 0x16, 0x02, 0x0c, 0x9b, + 0xff, 0xf5, 0xf6, 0xe6, 0x31, 0x06, 0xf4, 0xf9, 0xca, 0xe0, 0x1e, 0xfc, 0xec, + 0x27, 0x3e, 0xd1, 0xd1, 0xf0, 0xda, 0x24, 0x1d, 0xd7, 0x15, 0xf5, 0xf2, 0xfe, + 0xfd, 0xdf, 0xf1, 0xdc, 0xc5, 0xec, 0xf4, 0x02, 0xe7, 0xea, 0x04, 0xda, 0x1c, + 0x14, 0x0a, 0xf9, 0x27, 0x13, 0xee, 0xf2, 0x12, 0x03, 0x12, 0x05, 0x7f, 0x0a, + 0xf4, 0xf9, 0xe0, 0x10, 0x09, 0x20, 0xf3, 0x14, 0xe5, 0x0c, 0x17, 0x15, 0xf5, + 0xd8, 0xf1, 0x38, 0x0e, 0x00, 0xf0, 0x34, 0x06, 0x15, 0x6c, 0x55, 0x16, 0xfa, + 0xeb, 0xd9, 0xb6, 0x28, 0x2b, 0xb9, 0x1b, 0x32, 0xd1, 0x50, 0x45, 0x81, 0x05, + 0x09, 0x02, 0xb6, 0xfb, 0xa8, 0x19, 0x62, 0xe4, 0xe0, 0x0f, 0xef, 0x4e, 0x37, + 0xd0, 0xeb, 0xd5, 0xb0, 0xa6, 0x54, 0xb7, 0xf8, 0xe9, 0xfd, 0x17, 0xdd, 0x3a, + 0x0c, 0x5a, 0xf2, 0x44, 0x01, 0xe6, 0xa6, 0x9d, 0x12, 0xb3, 0x20, 0xec, 0xb8, + 0xbb, 0x02, 0xdf, 0x0b, 0x16, 0x09, 0x02, 0x38, 0x3f, 0x04, 0x28, 0x49, 0x39, + 0x1c, 0x05, 0xff, 0xe1, 0x22, 0xcd, 0x1d, 0x09, 0xea, 0xca, 0xc2, 0xf2, 0xf8, + 0x1e, 0xf9, 0x93, 0x13, 0xe4, 0x46, 0x26, 0x08, 0xac, 0xe0, 0xcb, 0x96, 0x09, + 0x01, 0xff, 0xae, 0x10, 0xf8, 0x46, 0x22, 0x2b, 0xda, 0x1a, 0xd7, 0xef, 0xf2, + 0xc0, 0x33, 0xed, 0xa4, 0x20, 0xf8, 0xd9, 0x08, 0xc8, 0xec, 0x65, 0x13, 0x1c, + 0x05, 0x1c, 0xdc, 0x1b, 0xe5, 0x0b, 0x0d, 0x02, 0x0e, 0xca, 0x2d, 0xff, 0x24, + 0x00, 0x15, 0xfc, 0xea, 0x00, 0xf4, 0xfc, 0xfa, 0xe0, 0x04, 0x3c, 0xe1, 0x0c, + 0xfa, 0x42, 0xf9, 0xf5, 0x25, 0xeb, 0xb5, 0xfa, 0x0c, 0x32, 0x35, 0xcf, 0xf2, + 0xcc, 0xf5, 0x12, 0x1f, 0x0d, 0x1b, 0xc6, 0x25, 0xdb, 0xe6, 0xfb, 0xff, 0xcc, + 0xd9, 0xe3, 0xe9, 0xd4, 0xcf, 0x3e, 0xd5, 0x2c, 0x1c, 0x12, 0xfa, 0x39, 0xde, + 0xe1, 0xd3, 0x0d, 0xe9, 0x7f, 0x0b, 0xd5, 0x0e, 0xfc, 0xdf, 0xcc, 0xef, 0xf9, + 0x5a, 0xe2, 0xfc, 0xd9, 0xe2, 0xce, 0xe6, 0xf4, 0xa5, 0x12, 0x32, 0x13, 0xf4, + 0x29, 0x04, 0xec, 0xfd, 0x24, 0x1b, 0x01, 0xd8, 0x25, 0x18, 0x1e, 0xec, 0xef, + 0xa7, 0x20, 0x10, 0xe5, 0xf7, 0x02, 0xc0, 0xe0, 0x33, 0x10, 0x20, 0x2e, 0x3e, + 0xf6, 0x0d, 0xf3, 0x2f, 0xe4, 0xe3, 0x13, 0x2f, 0xcf, 0xd3, 0x29, 0xf1, 0xf6, + 0x02, 0x3b, 0xf7, 0xf5, 0xf8, 0xfa, 0xea, 0x0e, 0x46, 0x0e, 0xfe, 0xed, 0xe1, + 0x0a, 0x09, 0xea, 0x11, 0x16, 0xe3, 0xd6, 0xfc, 0x7f, 0xf6, 0xce, 0x26, 0xe7, + 0xef, 0xf4, 0xec, 0xff, 0xf0, 0xfe, 0x25, 0x28, 0x28, 0xdc, 0xd4, 0x15, 0x04, + 0xdd, 0x40, 0xce, 0x0e, 0xf8, 0x03, 0x20, 0x0a, 0xf9, 0x01, 0x15, 0x2d, 0xeb, + 0x08, 0x03, 0xd9, 0xe4, 0xc7, 0xfb, 0x24, 0x20, 0x14, 0xe4, 0x13, 0xfd, 0xd9, + 0xfb, 0xf7, 0x20, 0xd8, 0xdf, 0x11, 0xe7, 0x0e, 0xe1, 0xf6, 0xbe, 0xfd, 0xe8, + 0xef, 0x0b, 0xee, 0x02, 0x1b, 0x11, 0x06, 0x05, 0xf5, 0x14, 0x23, 0xf5, 0xf2, + 0xe9, 0x13, 0xca, 0x2c, 0x1c, 0xeb, 0xc8, 0x02, 0x04, 0xf3, 0xcd, 0x19, 0x25, + 0xbf, 0xe4, 0xed, 0x07, 0x0b, 0xea, 0x1a, 0x09, 0xec, 0xef, 0x1c, 0xd7, 0x0b, + 0x0a, 0xef, 0x22, 0x19, 0x02, 0x1c, 0xd2, 0xf6, 0xd1, 0xed, 0x4c, 0xfb, 0xf7, + 0x28, 0x20, 0x2e, 0x0b, 0xea, 0x03, 0x2b, 0x05, 0xde, 0xed, 0x00, 0x18, 0x73, + 0x26, 0xc4, 0x1e, 0x0e, 0xd5, 0xe2, 0x05, 0x15, 0xf8, 0x40, 0xd7, 0xe9, 0x45, + 0xdb, 0x01, 0xcf, 0x06, 0xfd, 0x09, 0xff, 0x0a, 0x17, 0xec, 0x81, 0xae, 0x0e, + 0xfd, 0x04, 0x20, 0xff, 0xe8, 0x7e, 0x25, 0x4d, 0xc3, 0xe9, 0x12, 0xfa, 0x16, + 0x12, 0x07, 0x0d, 0x42, 0x98, 0x00, 0x05, 0xdd, 0x00, 0x33, 0x0d, 0xe0, 0xfe, + 0xe8, 0xab, 0xa1, 0xf4, 0x10, 0x25, 0xd4, 0xf3, 0x1b, 0x03, 0x1a, 0x07, 0xff, + 0xc8, 0xf5, 0xf1, 0xf5, 0x8d, 0xea, 0xe2, 0x12, 0xc5, 0xe9, 0x5f, 0x2c, 0xd0, + 0x0c, 0xf2, 0x23, 0x2f, 0xf7, 0x0f, 0x21, 0x13, 0x1a, 0x15, 0x5b, 0x11, 0xf8, + 0xf3, 0xfa, 0xf7, 0xf8, 0x06, 0xf2, 0x36, 0xcc, 0x3e, 0x2c, 0xff, 0x12, 0x0c, + 0xf4, 0xfa, 0xf3, 0xfd, 0xf6, 0xdd, 0x06, 0x22, 0x0a, 0xa4, 0xdf, 0x1f, 0x28, + 0xf8, 0x42, 0xdf, 0xe9, 0x36, 0x19, 0xc6, 0x14, 0x27, 0xc6, 0x00, 0xeb, 0x04, + 0x0f, 0x2e, 0x41, 0xc0, 0xea, 0xab, 0xf4, 0xc9, 0x0e, 0xf5, 0xbb, 0x7d, 0xdd, + 0xdf, 0x48, 0x0e, 0x12, 0xe3, 0x2c, 0x4e, 0xe6, 0xd6, 0xfc, 0xd8, 0x44, 0xfe, + 0x17, 0x53, 0x0b, 0x0b, 0xfa, 0x2c, 0x37, 0x38, 0xea, 0x7f, 0x9d, 0x21, 0x24, + 0x13, 0x9f, 0x0b, 0xe0, 0xff, 0xc7, 0xbf, 0x21, 0xe3, 0x05, 0x1f, 0xff, 0xeb, + 0x8e, 0x2c, 0x30, 0xb6, 0xe5, 0x0c, 0xf7, 0x3f, 0x49, 0x07, 0x0d, 0xd2, 0xf1, + 0xd4, 0xfb, 0x0d, 0x0e, 0x06, 0x1b, 0xb5, 0x21, 0xcd, 0xfa, 0xe7, 0x00, 0x2a, + 0xea, 0x50, 0x40, 0x10, 0x36, 0x04, 0x40, 0xea, 0x28, 0x08, 0xf7, 0xfd, 0x08, + 0x18, 0xec, 0x07, 0xdb, 0x04, 0x2b, 0x48, 0x45, 0xd9, 0xc9, 0xf3, 0xf7, 0x03, + 0xdc, 0xc5, 0xf1, 0x1c, 0x37, 0xde, 0x02, 0x13, 0xf7, 0xa7, 0xc1, 0xfc, 0x07, + 0x20, 0xe0, 0xdb, 0x00, 0x02, 0x0b, 0xf0, 0x08, 0x3b, 0x11, 0x00, 0x03, 0x01, + 0x2d, 0x39, 0x0a, 0x3a, 0x07, 0x33, 0xfb, 0xd5, 0xca, 0xd3, 0x05, 0xfa, 0xe9, + 0x05, 0x1e, 0xea, 0xce, 0x20, 0x1a, 0xca, 0xbf, 0xed, 0xf8, 0xfb, 0xda, 0xfb, + 0x35, 0xef, 0x08, 0x22, 0xc5, 0x15, 0xe5, 0x34, 0xcf, 0x24, 0x0c, 0xe5, 0x08, + 0x8f, 0xf3, 0xec, 0xfb, 0xdb, 0x4b, 0xf3, 0xa4, 0x2b, 0xf6, 0xde, 0xfe, 0x07, + 0xcd, 0x26, 0x2d, 0x62, 0xf6, 0xd6, 0xde, 0xf7, 0x28, 0xe1, 0x7f, 0x39, 0xf1, + 0xe6, 0x08, 0x13, 0x08, 0x37, 0xf4, 0xf5, 0x06, 0x09, 0xf4, 0x4a, 0x1e, 0xed, + 0x3b, 0xd5, 0xf9, 0xec, 0x0e, 0xda, 0x17, 0xf8, 0x39, 0xf3, 0xff, 0xf7, 0xf2, + 0x38, 0x1a, 0xe2, 0x27, 0xb6, 0x03, 0x05, 0x0e, 0x2d, 0x17, 0x06, 0x28, 0x59, + 0xe1, 0xce, 0x53, 0x19, 0x1d, 0x5e, 0xc6, 0x01, 0xe4, 0x27, 0xfb, 0xf8, 0xeb, + 0xc9, 0xfc, 0xfa, 0x04, 0x02, 0xfe, 0x13, 0xef, 0x81, 0xf8, 0xed, 0x60, 0xf7, + 0x0d, 0x18, 0xb6, 0x05, 0x24, 0x1f, 0xfa, 0x19, 0xd9, 0xef, 0xcf, 0x17, 0xc8, + 0xeb, 0xd0, 0xf8, 0x03, 0x08, 0x17, 0x15, 0x17, 0xfa, 0x09, 0xdd, 0xc7, 0xc8, + 0x3d, 0x1f, 0x46, 0xda, 0xe7, 0x38, 0xdd, 0xf7, 0x0c, 0xcf, 0x02, 0xed, 0x01, + 0xc9, 0x02, 0x0a, 0x3f, 0xf2, 0xff, 0x19, 0xe2, 0x0f, 0x12, 0x09, 0xe1, 0xee, + 0x25, 0x1a, 0xae, 0xed, 0xf4, 0xe3, 0xea, 0x43, 0x06, 0xd7, 0x25, 0xe1, 0x45, + 0x23, 0x45, 0xee, 0x06, 0x02, 0x2e, 0x38, 0x24, 0xfb, 0xf8, 0x30, 0x23, 0xe3, + 0xeb, 0xf8, 0x28, 0x11, 0xe0, 0xf0, 0x07, 0xf7, 0x06, 0xf7, 0xe1, 0xf8, 0x00, + 0x52, 0x47, 0xeb, 0xf8, 0x0c, 0x0e, 0xfe, 0xd4, 0x17, 0xd4, 0xfb, 0x4b, 0xdc, + 0x1f, 0xf4, 0x05, 0x18, 0x0f, 0x9f, 0x16, 0xf2, 0xac, 0x81, 0xaf, 0x56, 0x57, + 0x11, 0xd1, 0x0b, 0x01, 0x3b, 0x0f, 0x1b, 0xe3, 0xe2, 0x16, 0x0b, 0xe0, 0xe4, + 0x0b, 0x32, 0x05, 0xd7, 0xe4, 0xdd, 0x03, 0x05, 0xf2, 0x01, 0xfd, 0xfe, 0x5a, + 0x1a, 0xd2, 0x10, 0x14, 0x25, 0x14, 0xe7, 0xce, 0xe4, 0x1f, 0x40, 0x07, 0xe0, + 0xb5, 0xd0, 0xfb, 0x0d, 0x22, 0x10, 0x42, 0x05, 0xdd, 0xaf, 0x9b, 0x3a, 0x07, + 0xff, 0xf4, 0x1a, 0xff, 0x1c, 0xc2, 0xd1, 0x83, 0x0c, 0xe5, 0x14, 0xf2, 0xb1, + 0x3a, 0x4a, 0xee, 0x0d, 0xeb, 0xd4, 0xb5, 0xcf, 0x1e, 0xd3, 0xdd, 0x0d, 0xe5, + 0xfa, 0x5c, 0x96, 0xf6, 0xe8, 0x40, 0xf1, 0x16, 0x00, 0x33, 0xd9, 0x03, 0xd6, + 0xee, 0x2b, 0x0c, 0x4d, 0x78, 0xea, 0xe0, 0xe9, 0xdc, 0x6d, 0x5c, 0xfc, 0xac, + 0xf9, 0x0b, 0x0b, 0x8f, 0x25, 0xaf, 0xdf, 0xf3, 0x3b, 0x0c, 0xd5, 0xcd, 0xfe, + 0x1f, 0xa3, 0x8d, 0xd7, 0x2c, 0x11, 0x03, 0x69, 0xd8, 0xf0, 0x03, 0x2a, 0x13, + 0x17, 0x29, 0xfb, 0xfa, 0xfc, 0xee, 0xc9, 0x12, 0xed, 0xe3, 0x1e, 0x7f, 0xf2, + 0x5d, 0xe5, 0x4f, 0xee, 0xb7, 0xce, 0x07, 0x0f, 0xea, 0x04, 0xfc, 0x08, 0x49, + 0x54, 0x06, 0x0d, 0xf4, 0x38, 0xef, 0x11, 0x1c, 0x26, 0xe8, 0x13, 0xae, 0xf6, + 0x10, 0xfa, 0x36, 0xfe, 0xbb, 0x2b, 0x26, 0xef, 0x00, 0xfb, 0xf8, 0xf8, 0x12, + 0x0b, 0x02, 0xff, 0xe3, 0x32, 0x03, 0xef, 0x45, 0xc6, 0xf5, 0xff, 0xf5, 0x0c, + 0x1c, 0xc3, 0x01, 0xdb, 0x05, 0xe4, 0xf4, 0x25, 0x13, 0x43, 0x0c, 0x03, 0x03, + 0x0c, 0xf2, 0x0d, 0x24, 0xdc, 0xcf, 0xf1, 0x14, 0x03, 0x0d, 0x18, 0x16, 0xbe, + 0x42, 0x21, 0xe9, 0x18, 0xce, 0xc8, 0x26, 0x12, 0x1e, 0xcb, 0xfe, 0xf0, 0xf4, + 0x05, 0xb8, 0x41, 0x02, 0xf7, 0xe9, 0xe1, 0xe7, 0xf8, 0xe9, 0x54, 0x0e, 0xbe, + 0x4c, 0xfe, 0xe2, 0x0b, 0xf0, 0xd9, 0xdf, 0x1d, 0x15, 0xe2, 0xfc, 0x5b, 0xf3, + 0xde, 0x35, 0x3e, 0xf9, 0x34, 0xf7, 0xee, 0xb3, 0x81, 0xc1, 0xc8, 0xef, 0x60, + 0xda, 0x34, 0xc9, 0xf5, 0xed, 0x18, 0xcf, 0xcc, 0xed, 0x0d, 0xf0, 0x2d, 0x34, + 0xbf, 0x0a, 0x00, 0x11, 0x14, 0xe4, 0x49, 0xea, 0x52, 0x23, 0xd7, 0x1d, 0xd2, + 0x03, 0x25, 0x2f, 0x2e, 0x57, 0x1f, 0xdf, 0xf7, 0x03, 0xda, 0xc4, 0xce, 0x33, + 0xe2, 0xc8, 0xf7, 0xcc, 0x1c, 0x06, 0x28, 0x22, 0x9f, 0xe4, 0xb1, 0x10, 0xea, + 0x1f, 0xef, 0x12, 0xd7, 0x05, 0xd9, 0x28, 0x52, 0x08, 0x06, 0x15, 0x42, 0x1d, + 0x12, 0x2f, 0x37, 0xee, 0xbb, 0xe1, 0xf1, 0xc0, 0x1d, 0xe6, 0xce, 0x0e, 0xb7, + 0x1d, 0x2f, 0xd4, 0x2a, 0xf5, 0xe6, 0xd9, 0xe2, 0x41, 0xd1, 0xe9, 0xa0, 0xe5, + 0xb2, 0xc8, 0x40, 0x85, 0xe5, 0x6d, 0x5d, 0x03, 0xd8, 0xf8, 0x01, 0xd7, 0x12, + 0xce, 0xdf, 0x0f, 0xbf, 0x28, 0x1d, 0xd1, 0xdd, 0x18, 0xc2, 0xcc, 0xe9, 0xaf, + 0xf4, 0x54, 0xee, 0xed, 0x10, 0x14, 0xe2, 0x2c, 0xb9, 0x03, 0xd5, 0xdb, 0xe3, + 0x70, 0xdb, 0xbc, 0x06, 0xc1, 0xe9, 0xf1, 0xf4, 0xd0, 0x21, 0x4c, 0x04, 0xed, + 0x1d, 0xe5, 0x1d, 0xda, 0xf7, 0x10, 0x14, 0xb4, 0xea, 0x51, 0xd8, 0xf4, 0x48, + 0x35, 0xdf, 0xf0, 0x04, 0x46, 0x0b, 0xff, 0x0d, 0x1d, 0x36, 0xbe, 0x19, 0xbd, + 0xfb, 0x4b, 0xed, 0x2d, 0xf4, 0x0d, 0xc1, 0xff, 0x17, 0xed, 0x2e, 0xdb, 0x3c, + 0xfe, 0x07, 0x47, 0x53, 0x2b, 0xf5, 0xc8, 0x2a, 0x1c, 0x21, 0x0c, 0x1d, 0xcd, + 0xe7, 0xdc, 0xf4, 0xf6, 0xf7, 0x2f, 0xd1, 0xd4, 0xf5, 0x1b, 0x18, 0xc4, 0x4d, + 0x17, 0xaf, 0xd5, 0xe0, 0xfc, 0xab, 0xb4, 0x17, 0x0c, 0x5a, 0x4f, 0xe7, 0x08, + 0x01, 0x7f, 0x0b, 0xcb, 0xeb, 0xff, 0xba, 0xf3, 0xe3, 0xf1, 0xed, 0xe7, 0xfe, + 0xf6, 0x10, 0x1c, 0x2c, 0x4b, 0x00, 0xab, 0xee, 0xf8, 0x07, 0xc9, 0x1c, 0x2e, + 0x0d, 0xd1, 0x18, 0x68, 0xb9, 0xca, 0xfa, 0xbb, 0xf9, 0xe7, 0x1d, 0x44, 0xd0, + 0x01, 0xf4, 0xfb, 0x01, 0xf3, 0xae, 0xb3, 0xb8, 0x04, 0x01, 0xf7, 0xfc, 0x13, + 0x0c, 0x14, 0x1c, 0x4f, 0xef, 0xd9, 0xfc, 0xdb, 0x00, 0x1a, 0xf3, 0xbc, 0xdd, + 0x09, 0x0a, 0xf5, 0x0b, 0xd8, 0xe8, 0xbf, 0xf0, 0xce, 0xda, 0x10, 0x01, 0xe6, + 0x0d, 0xe3, 0x25, 0xfd, 0x33, 0x41, 0xf2, 0xff, 0xce, 0xd8, 0x5f, 0x29, 0x25, + 0x33, 0xe3, 0xfd, 0xf0, 0xe9, 0x3f, 0xdd, 0x20, 0x31, 0x0e, 0x2f, 0x25, 0xf6, + 0xf8, 0xf1, 0xf9, 0x44, 0xc5, 0xd7, 0x22, 0xf7, 0x08, 0x81, 0xee, 0xfc, 0x30, + 0xf7, 0xdc, 0x17, 0xea, 0x21, 0x19, 0xaf, 0xf2, 0x4d, 0xbf, 0xd6, 0x40, 0xe0, + 0xd4, 0x27, 0x49, 0xc8, 0xe4, 0x5f, 0x33, 0xd1, 0x20, 0xe0, 0x09, 0xf7, 0xcd, + 0xd4, 0x1a, 0x1d, 0x30, 0x3b, 0xf1, 0x17, 0x0f, 0x4c, 0x50, 0xe5, 0xe1, 0xdd, + 0xf9, 0xd7, 0xbf, 0x35, 0xb9, 0xc0, 0x0e, 0x93, 0xfd, 0x00, 0x67, 0xd1, 0x0c, + 0x8d, 0xb9, 0x2a, 0x35, 0xd9, 0x15, 0x29, 0x3a, 0x2c, 0xeb, 0x3a, 0xf2, 0x15, + 0xee, 0x29, 0xfe, 0xd9, 0x22, 0xb0, 0xd7, 0x21, 0x16, 0x0d, 0x2a, 0xbd, 0x0a, + 0x0a, 0xfc, 0xad, 0xbd, 0xdb, 0xef, 0xc1, 0xe5, 0x22, 0xc7, 0xe1, 0x2f, 0xd2, + 0xf8, 0x2a, 0xfe, 0xdb, 0x54, 0x81, 0xc4, 0xfd, 0x00, 0x41, 0xf5, 0xe5, 0x22, + 0xdf, 0xcb, 0x09, 0xe2, 0x2b, 0xf6, 0x53, 0xe5, 0x19, 0xd8, 0x3b, 0xb2, 0x13, + 0x0f, 0xd0, 0xc8, 0x1c, 0xe0, 0x4d, 0x0d, 0xb9, 0x04, 0x06, 0x99, 0xb4, 0xe0, + 0xe8, 0xee, 0xf0, 0xe9, 0x4e, 0x79, 0x19, 0x1a, 0x02, 0x9a, 0x18, 0xfa, 0xf2, + 0xed, 0x11, 0xaa, 0xd6, 0xa9, 0xcd, 0xc8, 0xd1, 0x17, 0x37, 0x18, 0x2a, 0x18, + 0x15, 0xf9, 0xf4, 0x3f, 0xc5, 0x0d, 0x04, 0x35, 0x0e, 0xf9, 0xef, 0x04, 0x0b, + 0xd5, 0xf9, 0xf4, 0x03, 0x0a, 0xf2, 0x2a, 0xb5, 0xde, 0x2d, 0xff, 0xb5, 0xe2, + 0x4f, 0xfa, 0xdf, 0x11, 0x05, 0xda, 0xf7, 0xeb, 0xdc, 0x2d, 0xfc, 0xee, 0x00, + 0x1a, 0xfd, 0xf8, 0x0d, 0xfd, 0x07, 0x09, 0x1c, 0xad, 0x22, 0xd2, 0x12, 0xb3, + 0x02, 0x04, 0x0b, 0x0a, 0xc5, 0x16, 0x36, 0xff, 0xf1, 0x05, 0x10, 0xe3, 0xd8, + 0xab, 0xf3, 0xee, 0xf0, 0x0a, 0xf2, 0x0c, 0x23, 0x20, 0xfd, 0xbc, 0x09, 0x0e, + 0x0c, 0x43, 0x35, 0x00, 0xef, 0x19, 0xe9, 0xf4, 0xd1, 0xfb, 0xe7, 0xab, 0x1b, + 0xe8, 0x02, 0x08, 0x1d, 0xc7, 0x2e, 0x08, 0xf2, 0x12, 0xd8, 0x7f, 0xd9, 0x13, + 0xe4, 0x17, 0x03, 0xfa, 0xff, 0x47, 0xde, 0x38, 0xd6, 0x16, 0x11, 0x06, 0x0e, + 0x0c, 0x0f, 0x2e, 0x20, 0xdb, 0xeb, 0x02, 0xfa, 0xdf, 0x01, 0x29, 0x01, 0xf3, + 0x4d, 0xf0, 0xdc, 0x1c, 0xe9, 0x3e, 0xf3, 0x1e, 0xc6, 0xc1, 0xc5, 0xbf, 0xda, + 0x3b, 0xf8, 0x3f, 0x24, 0x22, 0xe7, 0xbb, 0xc5, 0x21, 0xfd, 0xf3, 0x12, 0x01, + 0xd0, 0xa4, 0x08, 0xb7, 0x1e, 0xe7, 0x0b, 0xea, 0x07, 0x05, 0xe1, 0xf0, 0xd2, + 0x12, 0xc6, 0xf4, 0xe1, 0x17, 0x2e, 0x24, 0xb0, 0x38, 0xf6, 0x4e, 0xe6, 0x03, + 0xbc, 0x17, 0x3f, 0xe0, 0xca, 0x33, 0x10, 0xf7, 0x1d, 0xf1, 0xfb, 0x0f, 0xc4, + 0x0e, 0x3a, 0xfb, 0xf0, 0xfa, 0x25, 0xfb, 0x10, 0x7f, 0xf1, 0x03, 0x41, 0xcb, + 0x29, 0xf8, 0x14, 0x35, 0x2f, 0x25, 0xfa, 0x23, 0xc8, 0xfb, 0xc3, 0x2c, 0xf3, + 0xf8, 0xdd, 0xf3, 0x1d, 0x0a, 0xfb, 0x0a, 0x09, 0xd2, 0x06, 0x18, 0x30, 0xfb, + 0x1a, 0xfe, 0xdf, 0xfa, 0xe0, 0xe4, 0x2b, 0xfb, 0xd8, 0x75, 0xfa, 0xe3, 0x1a, + 0x04, 0xb7, 0x3a, 0xde, 0xd1, 0xd9, 0xe6, 0xfd, 0xec, 0xf5, 0xc3, 0xf9, 0xe8, + 0xcb, 0x2d, 0x19, 0x47, 0x11, 0x2b, 0x2b, 0xf9, 0xf1, 0xb0, 0xa8, 0x35, 0x28, + 0x47, 0xf4, 0xf7, 0xe6, 0x11, 0xde, 0xfd, 0xf8, 0x0e, 0xed, 0xbb, 0x42, 0xf7, + 0x24, 0xd3, 0x10, 0xd2, 0x1c, 0x09, 0xe6, 0xf3, 0x0c, 0xfe, 0x1c, 0xfd, 0x11, + 0x0d, 0x3e, 0x0c, 0x2d, 0x13, 0x12, 0x05, 0x29, 0x03, 0x00, 0xbb, 0x15, 0x0c, + 0xd0, 0xce, 0xca, 0xef, 0xf8, 0x0c, 0xfd, 0xf2, 0x10, 0xcb, 0xc9, 0xfc, 0xc6, + 0x0b, 0xf3, 0x22, 0xd5, 0xd0, 0x11, 0xe4, 0x14, 0x0b, 0xc5, 0xbe, 0xdc, 0xf4, + 0x0b, 0xc6, 0xe0, 0xe9, 0x14, 0x98, 0x29, 0x0f, 0xb6, 0x05, 0xf8, 0xfe, 0xf0, + 0x0d, 0xf5, 0x25, 0xe7, 0x1e, 0xe7, 0xd9, 0xff, 0xe8, 0xe3, 0xf3, 0x05, 0x1e, + 0xe4, 0xed, 0x31, 0x08, 0xd7, 0x29, 0x24, 0xdd, 0x29, 0x25, 0x81, 0xff, 0x01, + 0xbb, 0x36, 0x30, 0x11, 0xc7, 0xfd, 0x57, 0x1a, 0x1c, 0x4b, 0x1b, 0x8a, 0xfb, + 0xfa, 0xd9, 0xef, 0x0e, 0x23, 0xe8, 0xf6, 0x58, 0x2b, 0x19, 0xa6, 0xe4, 0x1e, + 0xca, 0x3d, 0x0d, 0x47, 0xec, 0xe1, 0xcf, 0xe3, 0x29, 0xdd, 0xb5, 0xf7, 0xfe, + 0x25, 0xeb, 0x03, 0x09, 0xfa, 0xbb, 0xf2, 0xcb, 0x90, 0x2a, 0x2c, 0x63, 0x25, + 0xf7, 0xed, 0x46, 0x9b, 0xea, 0x1e, 0xfe, 0xe9, 0x00, 0x47, 0x24, 0xfc, 0x05, + 0xf0, 0xe3, 0x4b, 0xd9, 0xeb, 0xd3, 0x2b, 0xe6, 0x21, 0xf9, 0xe1, 0xec, 0xe6, + 0x8e, 0x16, 0xe2, 0x08, 0xe8, 0xf2, 0xe5, 0xef, 0x23, 0x2e, 0x90, 0x1b, 0xc7, + 0x09, 0xe5, 0x51, 0x09, 0x26, 0xd5, 0xd6, 0xf9, 0xfe, 0x81, 0x12, 0x48, 0x08, + 0xf5, 0x04, 0xda, 0xb4, 0x0f, 0xdb, 0xdb, 0x02, 0x48, 0x12, 0x06, 0x31, 0x29, + 0xdc, 0xad, 0xee, 0xf2, 0x3c, 0xa2, 0x13, 0xbb, 0xb1, 0x16, 0x94, 0x0e, 0x98, + 0xee, 0xdc, 0xca, 0xcd, 0xfb, 0x1f, 0x21, 0x35, 0xdb, 0xe1, 0x03, 0x10, 0xc5, + 0x3d, 0xdf, 0xe1, 0xee, 0xea, 0xad, 0x25, 0x10, 0xda, 0xc7, 0x37, 0xef, 0xcc, + 0xcb, 0xe9, 0x51, 0x35, 0x92, 0x9c, 0x02, 0xec, 0x55, 0x24, 0xf8, 0x1d, 0x00, + 0x03, 0x00, 0x46, 0x13, 0x20, 0x04, 0xcf, 0x1e, 0x28, 0xfe, 0x29, 0xf1, 0x3a, + 0x27, 0x18, 0x42, 0x64, 0x81, 0xf7, 0x1a, 0xd2, 0x4a, 0xbd, 0x54, 0xe5, 0xb9, + 0xbf, 0x11, 0xbb, 0xb5, 0x0b, 0xd1, 0x1b, 0x06, 0xef, 0x0e, 0x1b, 0xfd, 0x5e, + 0xe8, 0xfe, 0x06, 0x01, 0xeb, 0xa7, 0xe5, 0xc4, 0xcb, 0xf8, 0x02, 0xf6, 0xbc, + 0xfb, 0x24, 0x26, 0xc5, 0x36, 0x2f, 0xe2, 0xc0, 0xe9, 0xd3, 0xe5, 0x6c, 0x2e, + 0x02, 0xf0, 0xd1, 0xda, 0xe3, 0xdf, 0x1a, 0x1f, 0xcf, 0x15, 0x09, 0xee, 0xc8, + 0x6d, 0x09, 0xec, 0xeb, 0x26, 0xca, 0x0b, 0x18, 0xb9, 0x23, 0xea, 0x97, 0xe9, + 0x2b, 0xda, 0xf9, 0xf4, 0x89, 0xcd, 0xa5, 0xaa, 0xe4, 0xd0, 0xfd, 0x1e, 0xda, + 0xf2, 0x1a, 0xff, 0x59, 0x11, 0x16, 0xf8, 0xaf, 0x05, 0xca, 0x37, 0x32, 0xf0, + 0xe2, 0xcb, 0x0a, 0xca, 0xad, 0xbe, 0xbb, 0xb7, 0x54, 0xc2, 0x23, 0x06, 0xdc, + 0x0d, 0xed, 0x0c, 0xea, 0xbf, 0xc4, 0xb5, 0xd3, 0x8d, 0x60, 0xb6, 0x03, 0xc8, + 0x1e, 0x54, 0xcf, 0xec, 0xfd, 0x0d, 0x1e, 0x2e, 0x04, 0x18, 0xfc, 0x45, 0x02, + 0xd5, 0x55, 0xd8, 0x10, 0x46, 0x45, 0xe6, 0xc8, 0xd2, 0x21, 0x23, 0x67, 0x14, + 0x4d, 0xb8, 0xc0, 0x4e, 0x14, 0xf5, 0xd2, 0xfa, 0xfe, 0xdf, 0x19, 0x1b, 0x3f, + 0x17, 0xac, 0x0a, 0x09, 0xee, 0x0b, 0xb9, 0xea, 0xe1, 0xc8, 0x6f, 0x81, 0xda, + 0xfb, 0x42, 0xdb, 0x25, 0xd2, 0xe9, 0x31, 0x45, 0xf7, 0x15, 0x51, 0x96, 0xe8, + 0x27, 0x0b, 0x54, 0x2b, 0x9c, 0x15, 0xed, 0xc9, 0xdf, 0xc8, 0xc7, 0xe9, 0xf7, + 0xf8, 0xdd, 0x2e, 0xd4, 0xf3, 0x1d, 0x4d, 0xdf, 0xf1, 0x04, 0xf2, 0xce, 0x14, + 0x45, 0xf9, 0x1a, 0xd6, 0x01, 0xdc, 0xf3, 0xf5, 0xf9, 0xed, 0xd4, 0x02, 0x20, + 0x25, 0xe0, 0x02, 0xf4, 0x24, 0xb7, 0x3a, 0xb5, 0x38, 0xf6, 0x13, 0xfe, 0xc6, + 0x17, 0x27, 0xe7, 0xdc, 0x3d, 0xec, 0x07, 0xe1, 0xf9, 0x04, 0xca, 0xfc, 0x12, + 0xff, 0xf2, 0x05, 0x0e, 0x00, 0xdb, 0x22, 0xf0, 0x15, 0x5d, 0x1f, 0x0f, 0xeb, + 0x64, 0x1a, 0x7f, 0x1e, 0x01, 0xee, 0xb6, 0x0f, 0x09, 0x50, 0x15, 0x90, 0x1d, + 0x1d, 0xff, 0x0a, 0x03, 0xe6, 0x12, 0x58, 0xe6, 0x12, 0xdc, 0x1a, 0x4d, 0x07, + 0xe6, 0xcd, 0xce, 0x2d, 0xd5, 0xe8, 0xd9, 0x2b, 0x04, 0x1a, 0x28, 0xd5, 0x2b, + 0x95, 0xa7, 0x01, 0xd2, 0x28, 0xa2, 0x1b, 0xe7, 0x25, 0xc6, 0xe6, 0x2d, 0x09, + 0xa9, 0x20, 0x28, 0xac, 0x5e, 0xea, 0xf0, 0xe5, 0xeb, 0x09, 0xf6, 0xfe, 0x27, + 0xcc, 0x12, 0xe5, 0x05, 0x14, 0xde, 0x14, 0xe8, 0xe0, 0xf2, 0x0c, 0x20, 0x30, + 0x2e, 0xfc, 0x0a, 0xfc, 0xfb, 0xdb, 0xbd, 0xca, 0xe5, 0x0e, 0x26, 0x24, 0x1d, + 0xfb, 0xcd, 0xa2, 0x18, 0x19, 0x09, 0xf4, 0xa3, 0x14, 0xc2, 0xec, 0x9d, 0xe5, + 0x1a, 0xdb, 0x7c, 0xec, 0xe3, 0xd7, 0x00, 0xe4, 0x22, 0x0a, 0x02, 0xb1, 0x0e, + 0xd1, 0x1d, 0x10, 0x18, 0xd0, 0x51, 0x00, 0x2e, 0x02, 0x28, 0xda, 0xe0, 0xe6, + 0xc3, 0x5c, 0xb3, 0x26, 0xde, 0x0b, 0xab, 0xf5, 0x3d, 0x97, 0xf7, 0xd6, 0xeb, + 0xc2, 0xf4, 0xca, 0xd9, 0x1e, 0x17, 0x3f, 0xde, 0xb7, 0xdb, 0x46, 0x15, 0xd1, + 0x19, 0xb4, 0xe0, 0xe9, 0xf6, 0xee, 0xf8, 0xe3, 0xdc, 0xe3, 0xfc, 0x4d, 0x01, + 0x10, 0xf1, 0x17, 0x11, 0x0a, 0xc6, 0x9f, 0x23, 0x7f, 0xf7, 0x0c, 0x25, 0xfa, + 0xe6, 0x28, 0xff, 0x0c, 0xd5, 0x01, 0x5b, 0xb7, 0x0d, 0xe3, 0x19, 0x31, 0x1d, + 0x0e, 0x04, 0xd9, 0x13, 0xd7, 0xcf, 0xc0, 0x1c, 0x01, 0x06, 0xe1, 0x56, 0x03, + 0x60, 0x61, 0xa9, 0xf5, 0xec, 0x16, 0x0c, 0xe2, 0x09, 0xfe, 0x41, 0x1b, 0x3d, + 0x2c, 0xcd, 0xb6, 0x24, 0x1c, 0xcd, 0x4b, 0xdf, 0x5d, 0xe2, 0x37, 0x3a, 0xfd, + 0x25, 0xe3, 0xa2, 0xcd, 0x22, 0xff, 0x7f, 0xb5, 0xfd, 0xfb, 0x00, 0xdf, 0x30, + 0xdd, 0x4b, 0x4e, 0x26, 0xfe, 0xda, 0x23, 0xe3, 0x37, 0x19, 0xd9, 0x1e, 0xe0, + 0x05, 0xe2, 0xda, 0xee, 0xd6, 0xef, 0xf7, 0xb7, 0x07, 0x05, 0xfa, 0xc9, 0x1e, + 0x00, 0xeb, 0xf3, 0x11, 0x12, 0xe7, 0xda, 0x28, 0x83, 0xd7, 0xf5, 0x04, 0xf8, + 0xa8, 0x14, 0x4b, 0xe6, 0x09, 0xfe, 0x34, 0xb9, 0x18, 0x49, 0xd8, 0xcf, 0xf3, + 0xdf, 0x0c, 0x07, 0xef, 0x21, 0xd3, 0xd5, 0x66, 0xd9, 0x08, 0xdc, 0x0e, 0x0c, + 0x21, 0xf2, 0xd6, 0x0c, 0xc5, 0xdd, 0x13, 0xd0, 0xff, 0x57, 0xba, 0xe5, 0x24, + 0xc3, 0xd0, 0x2e, 0x07, 0xfe, 0x5d, 0x0f, 0x14, 0x5b, 0xde, 0x11, 0x4b, 0xee, + 0xf1, 0xd5, 0xd0, 0xf9, 0x14, 0x05, 0x88, 0xf9, 0x08, 0x0d, 0xbe, 0x0f, 0xf0, + 0x17, 0x1c, 0x08, 0xf4, 0x32, 0x14, 0x93, 0xd3, 0xda, 0x94, 0x0f, 0xf6, 0x38, + 0x07, 0x1e, 0x11, 0xc1, 0xdc, 0xdb, 0xd7, 0xf3, 0x31, 0xfb, 0x22, 0x06, 0xe2, + 0x01, 0xc1, 0xf6, 0x10, 0x17, 0xb9, 0x27, 0xf8, 0xfa, 0x0c, 0xdc, 0xb7, 0xe5, + 0x05, 0x28, 0x2b, 0xce, 0xeb, 0x3b, 0x2c, 0xb7, 0xfd, 0x27, 0xf8, 0xfe, 0x9e, + 0x31, 0xf2, 0x81, 0x05, 0xf3, 0xef, 0x1e, 0x05, 0x19, 0x07, 0xb3, 0xd2, 0xf9, + 0xfe, 0xa3, 0x16, 0x07, 0xdf, 0xf7, 0x62, 0xec, 0x20, 0xee, 0xe2, 0x0f, 0xf8, + 0x12, 0xe4, 0x06, 0xd3, 0xd7, 0x44, 0x17, 0x03, 0xbb, 0x0b, 0xee, 0xff, 0xf0, + 0xfb, 0x26, 0xe8, 0x39, 0xdd, 0x0e, 0x02, 0xe1, 0x07, 0x27, 0x09, 0x03, 0x28, + 0x01, 0xe3, 0xb0, 0xf8, 0xf5, 0x30, 0x0c, 0x57, 0x02, 0x01, 0xbe, 0xb8, 0x1b, + 0x25, 0x0b, 0x53, 0x17, 0x1c, 0xeb, 0x22, 0x1a, 0xaf, 0xdf, 0xd3, 0x3f, 0x07, + 0x04, 0x2c, 0xe0, 0x15, 0x29, 0x02, 0xc4, 0xf8, 0xbc, 0xaa, 0x16, 0xf7, 0xce, + 0xfa, 0x01, 0x53, 0x0a, 0x15, 0xdb, 0x27, 0xa8, 0xfc, 0x03, 0x08, 0xc5, 0x22, + 0xeb, 0xf1, 0xfe, 0x2a, 0xf5, 0xaa, 0x41, 0xcb, 0x4a, 0x22, 0xfb, 0x38, 0xc3, + 0x2c, 0xd4, 0xec, 0xfc, 0x25, 0xfe, 0xfe, 0x32, 0xe3, 0xd4, 0x12, 0x06, 0xf7, + 0xec, 0x19, 0x63, 0x3a, 0x81, 0xf5, 0x30, 0xfe, 0xe9, 0xe5, 0x04, 0xeb, 0xd2, + 0x13, 0x3a, 0x36, 0xeb, 0x13, 0x18, 0x16, 0x16, 0x0d, 0xe4, 0xfa, 0x1e, 0xe3, + 0xe9, 0x10, 0xfd, 0x22, 0x25, 0xf2, 0xe1, 0x1d, 0xf9, 0x04, 0x10, 0xc2, 0x01, + 0x0f, 0x1a, 0x15, 0xc0, 0x04, 0x81, 0xe5, 0x44, 0x02, 0xa2, 0xe6, 0x40, 0xf3, + 0x84, 0x21, 0xff, 0xb4, 0x30, 0xde, 0x4c, 0x26, 0x12, 0x1b, 0x4b, 0xe7, 0x11, + 0x6f, 0xb5, 0x6d, 0x1e, 0xe4, 0x06, 0xf3, 0x12, 0x0a, 0xf5, 0x0a, 0xd8, 0x17, + 0x5c, 0xcd, 0x7d, 0xd5, 0xc7, 0x94, 0xf4, 0x30, 0x31, 0x02, 0x28, 0xd6, 0x22, + 0xf5, 0x07, 0xc0, 0xd6, 0x29, 0xdb, 0x2b, 0x4d, 0x3b, 0xf6, 0xf7, 0x72, 0x46, + 0xe2, 0xec, 0xd8, 0xc5, 0x3f, 0xbc, 0x30, 0xfd, 0xdd, 0x22, 0xaa, 0x15, 0xf9, + 0xb3, 0xd6, 0x3f, 0xf2, 0x07, 0x44, 0xf5, 0xf7, 0x22, 0xe5, 0x28, 0xf4, 0xf9, + 0xc9, 0x93, 0x40, 0x4b, 0xf6, 0x19, 0x54, 0xc2, 0x18, 0xde, 0xe1, 0xde, 0x7e, + 0x34, 0xbe, 0x09, 0xdf, 0x11, 0x06, 0x1b, 0xbc, 0xf8, 0x2f, 0xde, 0x50, 0xd6, + 0xa9, 0x2b, 0x17, 0x03, 0xab, 0x23, 0x3d, 0x11, 0x54, 0xd5, 0xdd, 0xb7, 0x08, + 0x23, 0x23, 0x16, 0xf4, 0x13, 0xe6, 0x39, 0xd8, 0xf7, 0x0e, 0x3b, 0xf6, 0xb0, + 0xa9, 0xfc, 0x12, 0xa6, 0xf0, 0xfe, 0x3f, 0x07, 0xfd, 0xcf, 0xd5, 0xbc, 0x18, + 0xef, 0x2b, 0x43, 0x19, 0x04, 0xb3, 0xb2, 0xf9, 0x05, 0xff, 0x0f, 0x0f, 0x01, + 0xfe, 0xeb, 0xfa, 0x1b, 0xd3, 0x0b, 0x0b, 0x02, 0xe8, 0x1d, 0x29, 0xdf, 0xfb, + 0xc4, 0x25, 0xf5, 0x02, 0x14, 0xe2, 0x0f, 0x46, 0x11, 0x0c, 0x15, 0x09, 0xf7, + 0x08, 0x0c, 0x99, 0x17, 0xe9, 0xd4, 0x1a, 0x17, 0xef, 0x02, 0x37, 0x01, 0x01, + 0xd9, 0x81, 0x0c, 0x40, 0x28, 0xeb, 0x1a, 0xf6, 0xff, 0xdb, 0xf5, 0xce, 0xd2, + 0x24, 0xc9, 0x1a, 0x17, 0x08, 0x44, 0xee, 0x2e, 0x4e, 0x0d, 0x19, 0x0d, 0xb7, + 0xfa, 0xd0, 0xda, 0xe2, 0xdb, 0x12, 0x4f, 0xe1, 0x40, 0x2d, 0x33, 0x03, 0xe2, + 0xd2, 0xe1, 0xd4, 0x2b, 0xe3, 0xc1, 0x00, 0x75, 0x02, 0x30, 0x31, 0xf9, 0x07, + 0x07, 0xe6, 0x3d, 0x3a, 0xc4, 0x13, 0x0c, 0xe1, 0x0d, 0xc2, 0xf7, 0xb5, 0xf7, + 0xc1, 0xce, 0xbb, 0x15, 0xed, 0xa3, 0xf4, 0x12, 0xd9, 0x0c, 0xeb, 0x17, 0x8d, + 0xe5, 0x2a, 0x87, 0x01, 0xae, 0xe5, 0x1a, 0xf0, 0xf1, 0x05, 0xff, 0x04, 0xfd, + 0x2d, 0xee, 0x3f, 0x04, 0x4c, 0x2b, 0xc2, 0xd3, 0x03, 0xc4, 0x20, 0x7f, 0x2b, + 0xd5, 0x1f, 0x04, 0xf6, 0x02, 0x21, 0xfc, 0xd2, 0xd8, 0xf6, 0xec, 0xeb, 0x12, + 0xcd, 0xed, 0x10, 0xd7, 0xf7, 0x24, 0xf4, 0x22, 0x0b, 0xea, 0x07, 0xf5, 0x0d, + 0x1c, 0x28, 0x0b, 0xbc, 0xe0, 0xca, 0x00, 0x39, 0x1b, 0xf8, 0x32, 0x08, 0xfd, + 0x18, 0xf4, 0xeb, 0xf0, 0xfb, 0x0d, 0xfd, 0xeb, 0x11, 0x0a, 0xd4, 0xe7, 0xc8, + 0xd1, 0x47, 0x23, 0xe7, 0x1f, 0x24, 0xaf, 0xf7, 0xff, 0xe0, 0xf8, 0xef, 0x30, + 0xbe, 0xe7, 0x05, 0x03, 0x09, 0x37, 0xef, 0xe0, 0x19, 0xd3, 0x06, 0x12, 0xa2, + 0x19, 0xf4, 0xe0, 0xe4, 0x24, 0xe9, 0x4d, 0xec, 0xfb, 0xf8, 0xe0, 0x19, 0xf4, + 0x61, 0xe3, 0x65, 0x03, 0x0d, 0x82, 0x10, 0x14, 0x16, 0x7f, 0xa3, 0x08, 0x1f, + 0x29, 0x32, 0x1f, 0x13, 0xe0, 0x08, 0xf1, 0x03, 0x14, 0x20, 0xfa, 0x1f, 0xe8, + 0xca, 0x28, 0x07, 0xdd, 0x01, 0xc2, 0x16, 0xd9, 0x0b, 0xe8, 0x43, 0x10, 0x01, + 0x24, 0x21, 0x31, 0x48, 0xd3, 0x0d, 0x07, 0xd7, 0x42, 0xfe, 0xe5, 0x41, 0xd2, + 0x04, 0x02, 0x1c, 0xb4, 0xd8, 0xb2, 0xde, 0xeb, 0x51, 0x50, 0xc5, 0xcf, 0x00, + 0xd4, 0x01, 0x2f, 0xc3, 0xdf, 0xbc, 0xfc, 0xe2, 0xf3, 0x26, 0xfc, 0x40, 0x42, + 0x2d, 0xc0, 0xbb, 0xef, 0xe1, 0xeb, 0x13, 0x15, 0xa0, 0x15, 0x5a, 0xee, 0x09, + 0xfe, 0xe6, 0x38, 0x0c, 0x97, 0xe2, 0x3b, 0xca, 0xc2, 0xf6, 0x2e, 0x17, 0xf2, + 0xf6, 0x29, 0x00, 0xe7, 0x34, 0x58, 0x26, 0xe2, 0x1f, 0x21, 0x1c, 0x14, 0x0a, + 0xe6, 0x06, 0xe6, 0xd0, 0xf4, 0x05, 0x1a, 0x1a, 0xf0, 0xc8, 0x25, 0x0e, 0xf3, + 0xee, 0xb3, 0xc7, 0xee, 0xf7, 0xe2, 0xf5, 0xfe, 0xea, 0xbb, 0x39, 0x0d, 0xf4, + 0x1f, 0x09, 0x29, 0xff, 0xde, 0xd4, 0xd1, 0x06, 0xdd, 0xf7, 0x10, 0xf3, 0x3b, + 0x21, 0xd5, 0x03, 0xf2, 0xf9, 0x00, 0xe0, 0xdc, 0xec, 0x1c, 0xf4, 0x08, 0x34, + 0x7f, 0x17, 0xee, 0x0c, 0xdd, 0x2b, 0x18, 0xb1, 0x33, 0xe1, 0xc9, 0xf4, 0xe0, + 0x07, 0xef, 0xd3, 0xd5, 0x11, 0x3d, 0x15, 0x0c, 0x3c, 0x02, 0x00, 0x25, 0xf9, + 0xf1, 0xe2, 0xd6, 0xf2, 0xff, 0x50, 0x23, 0x24, 0x0d, 0xea, 0xf0, 0x3f, 0x08, + 0xf7, 0xeb, 0x38, 0xec, 0xfe, 0xe2, 0xce, 0xdf, 0xf1, 0x10, 0x14, 0x31, 0x01, + 0xea, 0xed, 0xeb, 0x07, 0xf1, 0x3f, 0x0f, 0x0b, 0x0b, 0xea, 0x26, 0x02, 0x19, + 0x0e, 0x1d, 0x27, 0xbd, 0x39, 0x03, 0x02, 0xd4, 0xc4, 0xe0, 0x2a, 0x19, 0x08, + 0x04, 0x2e, 0xde, 0x0d, 0x2c, 0x0e, 0x01, 0x33, 0xdf, 0x1e, 0xfc, 0xeb, 0xfb, + 0x09, 0xbf, 0xf0, 0xf9, 0x1a, 0xe4, 0xd8, 0x16, 0x01, 0xc1, 0x98, 0xec, 0xeb, + 0xe7, 0x37, 0x19, 0xd3, 0x15, 0x0b, 0x11, 0x23, 0x02, 0x04, 0xef, 0x1a, 0x52, + 0xfa, 0x2a, 0x34, 0xf9, 0x0b, 0x14, 0xc0, 0xf8, 0xd9, 0xfb, 0x24, 0xba, 0x2c, + 0x09, 0x2a, 0xb0, 0xef, 0x45, 0xb4, 0x1f, 0xff, 0x3c, 0x0a, 0x08, 0xfe, 0xf7, + 0x0f, 0x32, 0xcc, 0xbd, 0xc1, 0xf0, 0x0c, 0xd0, 0x08, 0x06, 0xfe, 0xf6, 0xde, + 0x3c, 0x01, 0xb9, 0x1a, 0x35, 0x0e, 0x26, 0x00, 0xdc, 0xe9, 0xcd, 0x1d, 0xe1, + 0x11, 0x81, 0x2d, 0x20, 0xcd, 0x24, 0xc5, 0xfc, 0xe5, 0x00, 0xed, 0xe1, 0x3e, + 0xf4, 0x1c, 0x0c, 0xe0, 0xe7, 0x12, 0x17, 0x1d, 0xed, 0xe9, 0x18, 0xa9, 0xe2, + 0xe8, 0xea, 0x44, 0x49, 0x13, 0x13, 0xc1, 0x12, 0xcb, 0x2b, 0xea, 0x1a, 0x22, + 0x35, 0x28, 0x27, 0xd5, 0x2d, 0xfb, 0xfd, 0x42, 0x5c, 0xee, 0x68, 0x0e, 0xeb, + 0xea, 0x2d, 0x46, 0xee, 0x3d, 0x7d, 0x07, 0x02, 0xf8, 0xe8, 0xf1, 0xe5, 0x02, + 0x0a, 0xe5, 0xf4, 0x09, 0xed, 0x6d, 0x31, 0x89, 0xf0, 0xea, 0xf2, 0xce, 0x0e, + 0x18, 0x09, 0x10, 0x41, 0xd8, 0x12, 0x0c, 0xd4, 0x08, 0x2e, 0x81, 0x33, 0x0d, + 0x54, 0xf5, 0x25, 0xb9, 0xc2, 0x12, 0xf7, 0xe1, 0x2c, 0x0f, 0x36, 0xea, 0x28, + 0x28, 0x10, 0x19, 0xfc, 0x07, 0x2a, 0xff, 0xf5, 0x0f, 0xed, 0x04, 0x1c, 0x0c, + 0xf5, 0x2d, 0xca, 0x18, 0x14, 0x19, 0x0d, 0x39, 0xaf, 0x05, 0x0f, 0xe9, 0xf7, + 0xd6, 0xef, 0xc8, 0x4a, 0xe8, 0x55, 0x03, 0xbb, 0xff, 0xe3, 0xda, 0xf8, 0xe3, + 0x28, 0x8c, 0x1a, 0x0e, 0x15, 0x7c, 0x04, 0x0f, 0xfe, 0x34, 0xe5, 0xe9, 0xf5, + 0xfc, 0xbd, 0xe3, 0x24, 0x2a, 0x44, 0xf1, 0xb5, 0xe5, 0x10, 0xde, 0x0c, 0xe6, + 0xd7, 0xe4, 0xdc, 0x83, 0xa2, 0xe5, 0xc3, 0x41, 0xeb, 0x13, 0xc3, 0xf4, 0x1e, + 0xff, 0x25, 0xb9, 0x11, 0x54, 0x53, 0xf9, 0x36, 0xd5, 0xf6, 0xf8, 0xe7, 0x1b, + 0xe0, 0x0b, 0xeb, 0xef, 0x27, 0x16, 0x40, 0x0b, 0x11, 0x4a, 0x00, 0x2a, 0xb8, + 0x02, 0x4a, 0x71, 0x05, 0xaf, 0x01, 0x30, 0x07, 0xda, 0xe8, 0xd4, 0xd9, 0xbb, + 0xff, 0x36, 0xe5, 0xe0, 0x0c, 0xcb, 0x4e, 0x2d, 0xe5, 0xd5, 0x19, 0x0e, 0x2f, + 0x28, 0xe2, 0x3a, 0xbd, 0xbd, 0xe9, 0x13, 0xed, 0x15, 0x17, 0xdf, 0x03, 0x67, + 0xfb, 0x28, 0xd3, 0x3f, 0x1e, 0xce, 0x59, 0xf0, 0x56, 0x58, 0xdc, 0x28, 0x1a, + 0xcc, 0xb4, 0xce, 0x36, 0xf3, 0x31, 0xde, 0xe5, 0xd8, 0xf3, 0x0c, 0x1f, 0x54, + 0xe3, 0xf1, 0x7f, 0x23, 0x0a, 0x62, 0x08, 0x34, 0xd0, 0xf9, 0xc2, 0x0a, 0xf4, + 0x53, 0x0a, 0x17, 0x20, 0xf7, 0x05, 0xfa, 0x78, 0xd8, 0xc1, 0xfd, 0x1b, 0xf4, + 0x81, 0xa5, 0xe4, 0x16, 0xdc, 0xec, 0xf1, 0xff, 0x02, 0xf4, 0x1e, 0xe7, 0xc8, + 0x00, 0x13, 0x0d, 0x26, 0x24, 0xf0, 0xdd, 0x22, 0xfc, 0x2f, 0x12, 0x08, 0xe9, + 0x04, 0x02, 0xee, 0xf4, 0xe2, 0x1d, 0x24, 0xdb, 0xfc, 0x2e, 0xb7, 0x15, 0xb3, + 0x1f, 0xf6, 0x5b, 0x14, 0xc7, 0xbc, 0xcb, 0x65, 0x00, 0xd4, 0x37, 0xde, 0x1b, + 0xe3, 0x07, 0x33, 0xb6, 0x25, 0x11, 0x36, 0x48, 0x0c, 0x1f, 0x11, 0xfa, 0xf9, + 0xd2, 0xdd, 0xdc, 0x14, 0x05, 0xff, 0x3a, 0x3f, 0x18, 0x4b, 0xf3, 0xed, 0xd0, + 0xb4, 0x01, 0xde, 0xdc, 0xfb, 0x07, 0x00, 0xf6, 0x27, 0xf7, 0xd1, 0x38, 0x0b, + 0xf3, 0xbb, 0x1d, 0x1c, 0x23, 0x0e, 0xf9, 0xb9, 0xa5, 0x20, 0x0c, 0x00, 0xcb, + 0x02, 0xfe, 0xf7, 0xf7, 0xfc, 0x55, 0xd6, 0xd7, 0x4d, 0xeb, 0xfc, 0xee, 0x0c, + 0x02, 0x20, 0x05, 0xcc, 0xfb, 0xfa, 0xed, 0x23, 0xd8, 0xca, 0x08, 0xfa, 0x81, + 0xfb, 0xc2, 0xf2, 0x1f, 0xa1, 0xe1, 0x3a, 0xe7, 0x0e, 0xf9, 0xfa, 0xd2, 0xec, + 0x04, 0x37, 0x40, 0x18, 0x46, 0x13, 0xd4, 0x0e, 0x24, 0xe7, 0xfc, 0x26, 0xe1, + 0x17, 0x33, 0x21, 0x0f, 0xc4, 0xef, 0xf1, 0xde, 0xda, 0xb9, 0x2f, 0x11, 0x2c, + 0xd5, 0xef, 0xec, 0x26, 0x1a, 0xf0, 0xd9, 0xe9, 0xeb, 0xf1, 0x00, 0x05, 0xd9, + 0xdd, 0xc6, 0xaa, 0xdb, 0x0b, 0x23, 0xd8, 0x22, 0x12, 0x04, 0x0e, 0x0e, 0x10, + 0xfb, 0xd6, 0xf4, 0xd3, 0x19, 0xe4, 0x31, 0xcd, 0xeb, 0xba, 0xd9, 0xfa, 0xe0, + 0xcb, 0x0e, 0x1c, 0x11, 0x0e, 0x2f, 0xf9, 0xe9, 0xed, 0xc4, 0xcb, 0xec, 0xd9, + 0x01, 0xf3, 0x3f, 0x1d, 0x11, 0xfa, 0x52, 0x14, 0x35, 0x33, 0xee, 0x29, 0xda, + 0x18, 0x14, 0xf3, 0xcc, 0xe3, 0x10, 0x81, 0xc6, 0xd0, 0x31, 0x47, 0xe0, 0xe6, + 0xf1, 0x02, 0x54, 0x02, 0x76, 0x09, 0x05, 0x29, 0x23, 0xd3, 0xd4, 0xfb, 0x1c, + 0x4f, 0xdc, 0x45, 0xd6, 0x1b, 0xf4, 0x50, 0x17, 0x63, 0x0e, 0x40, 0x44, 0xe0, + 0xe3, 0x09, 0x1c, 0xeb, 0x2b, 0x16, 0x09, 0xc6, 0xd8, 0x31, 0x11, 0x06, 0x37, + 0x34, 0x3f, 0xde, 0x27, 0x3e, 0xd8, 0xd1, 0xd1, 0xb0, 0x9d, 0x3a, 0xed, 0x0d, + 0x23, 0x10, 0xc6, 0x0e, 0xc6, 0xf9, 0x39, 0x17, 0x65, 0x02, 0xff, 0x14, 0xd5, + 0x02, 0xff, 0x28, 0x2c, 0x0a, 0x2c, 0xf9, 0xf1, 0x0c, 0x1c, 0x13, 0xe6, 0x06, + 0x00, 0x11, 0x13, 0xf7, 0x3a, 0xc9, 0xc0, 0x1b, 0xd7, 0x10, 0x18, 0xf5, 0x1d, + 0x78, 0xfe, 0x1a, 0x26, 0x19, 0xdf, 0xf3, 0xcd, 0x02, 0xe2, 0xfa, 0x26, 0x07, + 0x13, 0x07, 0x42, 0xe8, 0x0f, 0xe2, 0xf7, 0xca, 0xdd, 0x4d, 0x49, 0x40, 0x11, + 0xc6, 0x42, 0xb8, 0xe8, 0x03, 0xdd, 0x0b, 0x14, 0x2a, 0x2a, 0x3e, 0x18, 0xac, + 0xb3, 0xef, 0x1c, 0xef, 0xfc, 0xed, 0x0e, 0xfb, 0xf8, 0x14, 0x7f, 0x39, 0x8a, + 0x03, 0xe8, 0x5e, 0xdb, 0xd4, 0x5c, 0x02, 0x02, 0x39, 0xf6, 0xa4, 0xc7, 0xd4, + 0x28, 0xf3, 0xd2, 0xf9, 0xf8, 0xf9, 0x9f, 0xff, 0xb0, 0x28, 0xdb, 0x11, 0xe3, + 0xd1, 0xf6, 0xd0, 0x0f, 0x41, 0x26, 0x11, 0xe4, 0x1b, 0xed, 0xac, 0x33, 0x42, + 0x14, 0x45, 0x16, 0x0f, 0x09, 0x3b, 0xb3, 0x45, 0xeb, 0xb3, 0x3a, 0x00, 0xe9, + 0xcc, 0x37, 0xd4, 0x26, 0x10, 0xf7, 0xfd, 0xc1, 0x0d, 0x2d, 0xe4, 0x01, 0xbb, + 0x1b, 0x2e, 0x23, 0xe5, 0xf9, 0xec, 0xda, 0xc7, 0x0c, 0xee, 0xf9, 0xd6, 0xf9, + 0xd9, 0xf4, 0x4a, 0x30, 0xd6, 0xf3, 0xe7, 0x4c, 0x3b, 0x4b, 0x02, 0x05, 0x19, + 0x24, 0x0b, 0xa8, 0x02, 0x44, 0xff, 0x22, 0x25, 0xb8, 0x3b, 0x59, 0x9c, 0x1e, + 0xc4, 0x17, 0x20, 0xff, 0x0e, 0xdf, 0xd7, 0xfb, 0x0b, 0x0d, 0x05, 0xf6, 0x4e, + 0x00, 0xeb, 0x99, 0x1a, 0x3a, 0x26, 0xa6, 0x23, 0x1b, 0x0c, 0xbb, 0x13, 0x47, + 0x27, 0xdc, 0xe6, 0xfc, 0x37, 0x18, 0xbb, 0xfa, 0xb1, 0xdb, 0x65, 0xfa, 0x16, + 0xb6, 0xf7, 0x0a, 0xd8, 0x1d, 0xb0, 0xf4, 0xf4, 0xee, 0xdf, 0xf8, 0x2c, 0xd2, + 0x31, 0xe0, 0xf9, 0xdd, 0xa5, 0xbc, 0xb0, 0x1c, 0x3f, 0xdd, 0x2f, 0xf5, 0xc2, + 0xf6, 0xe1, 0xf8, 0xf2, 0xca, 0x1b, 0xbb, 0x94, 0xf6, 0x92, 0xed, 0xd9, 0xe4, + 0x3b, 0xb0, 0xda, 0xfe, 0xf2, 0x20, 0x8e, 0xf0, 0x5b, 0xd8, 0x0a, 0xf3, 0x3d, + 0xab, 0x16, 0xf7, 0xf8, 0x21, 0x00, 0xe9, 0x39, 0x09, 0xc7, 0x78, 0x3c, 0x08, + 0x1f, 0x1f, 0x1c, 0x4e, 0x53, 0x81, 0xc8, 0x13, 0x20, 0x3b, 0xdd, 0x22, 0x21, + 0x30, 0xaa, 0x05, 0xd8, 0x6f, 0xf4, 0xe5, 0xd3, 0xd7, 0x28, 0x78, 0xbc, 0xd7, + 0xea, 0xb2, 0x15, 0x1d, 0xbf, 0x91, 0xef, 0xe0, 0x2d, 0xed, 0x0f, 0x9a, 0xbf, + 0x38, 0xf1, 0xef, 0xe8, 0x17, 0xa0, 0xff, 0x81, 0x17, 0x63, 0xfa, 0xb9, 0x19, + 0x42, 0x08, 0xd4, 0x9c, 0xfc, 0x29, 0x23, 0x5f, 0x00, 0x37, 0xf8, 0x18, 0x16, + 0xb7, 0xd7, 0xdc, 0x30, 0xd3, 0x34, 0xac, 0x04, 0xe3, 0xab, 0xd1, 0x23, 0xe1, + 0xe4, 0x2b, 0xf2, 0x44, 0xc6, 0xf0, 0x3d, 0x20, 0xab, 0x3d, 0xde, 0xde, 0x40, + 0xf8, 0xe6, 0x63, 0x4f, 0x3d, 0x2a, 0x03, 0xe0, 0x14, 0x04, 0xf7, 0x08, 0xf1, + 0xab, 0x34, 0xe2, 0xd8, 0x05, 0xee, 0xea, 0xd2, 0x1c, 0xfa, 0xe6, 0xf9, 0x00, + 0xbf, 0x05, 0xe9, 0x1b, 0x1c, 0x2a, 0xd9, 0xbf, 0x1f, 0x2d, 0x22, 0xee, 0xe6, + 0x2e, 0xc1, 0xfb, 0xed, 0xc0, 0x3a, 0xfa, 0xe0, 0xdc, 0x0e, 0xb6, 0xac, 0xe7, + 0xea, 0x11, 0x37, 0x16, 0x47, 0xff, 0x1c, 0xdc, 0x70, 0x1d, 0xce, 0xfe, 0xce, + 0xef, 0x0f, 0xfc, 0xdc, 0xd5, 0x02, 0xff, 0x13, 0xcb, 0xc0, 0x2a, 0xf4, 0x2b, + 0xf4, 0x4c, 0x28, 0xd6, 0x0f, 0x12, 0x28, 0xd2, 0xf5, 0x14, 0x0e, 0x22, 0xd5, + 0x1f, 0xfe, 0x28, 0xd2, 0xdd, 0xe3, 0xe8, 0x0c, 0x12, 0xec, 0xee, 0x0c, 0xbd, + 0xdf, 0xe4, 0xbf, 0x81, 0x53, 0xf7, 0xce, 0x37, 0x1b, 0x30, 0x04, 0xd5, 0x1d, + 0xde, 0xf7, 0x10, 0x05, 0x11, 0x32, 0x03, 0xc6, 0xfc, 0xe8, 0xda, 0xea, 0xd4, + 0x3e, 0x0b, 0xfc, 0x17, 0x34, 0xd6, 0x56, 0x96, 0x25, 0xf0, 0xfc, 0x30, 0xe0, + 0xe7, 0x16, 0xe8, 0xcf, 0xe7, 0xe6, 0xfe, 0x97, 0xe4, 0xc1, 0x09, 0xe9, 0x6c, + 0x0e, 0xf8, 0xec, 0x2a, 0x04, 0x00, 0xe4, 0x23, 0x3c, 0xea, 0xb1, 0xf8, 0xcd, + 0x25, 0xdf, 0xcf, 0xfb, 0x05, 0x01, 0xf2, 0xf2, 0xb8, 0x0e, 0xcf, 0xf0, 0xec, + 0xf2, 0x19, 0xec, 0xea, 0xda, 0xe6, 0xef, 0xee, 0xe0, 0x81, 0xfc, 0xc5, 0x46, + 0xec, 0xca, 0x00, 0xf8, 0xe6, 0x07, 0xd6, 0x07, 0x3f, 0x03, 0x01, 0x25, 0x26, + 0xf1, 0xd0, 0xea, 0x0a, 0x0f, 0xeb, 0xe4, 0xec, 0xbc, 0xe0, 0x46, 0xe7, 0xf7, + 0xf1, 0x02, 0xdf, 0xe4, 0xdc, 0x51, 0xd0, 0xd7, 0xda, 0x38, 0xf0, 0x05, 0xf9, + 0x15, 0xf7, 0x01, 0x1a, 0xe9, 0xf2, 0x07, 0x19, 0xd7, 0xee, 0xd6, 0x2c, 0x24, + 0xa4, 0x33, 0xfd, 0x22, 0x13, 0x17, 0x59, 0xf0, 0x07, 0x25, 0xd8, 0xd9, 0xdf, + 0x35, 0xd7, 0xeb, 0x06, 0x00, 0xde, 0xf9, 0xe3, 0x0f, 0x54, 0xc6, 0x01, 0xfc, + 0x1f, 0x2d, 0x20, 0xcd, 0xc1, 0xfb, 0xc3, 0xb1, 0xc8, 0xf3, 0x49, 0xd4, 0x0a, + 0xf2, 0xfc, 0xe1, 0xd7, 0x19, 0xa0, 0x4d, 0x14, 0x33, 0x25, 0xf3, 0x0f, 0xa6, + 0xe8, 0x32, 0xf2, 0xde, 0xee, 0xd3, 0xf7, 0x38, 0xf7, 0x04, 0x43, 0x0a, 0xe5, + 0x17, 0xf2, 0x15, 0x0d, 0x46, 0x0a, 0x18, 0xb3, 0xf2, 0xe9, 0xaf, 0x03, 0xe0, + 0x0d, 0x42, 0xf3, 0xef, 0x36, 0xeb, 0xdf, 0xe7, 0xeb, 0xff, 0x13, 0x30, 0xb7, + 0xeb, 0xe9, 0xf9, 0xe6, 0x12, 0x11, 0x09, 0x25, 0xef, 0xf8, 0xf8, 0xf4, 0x03, + 0xf2, 0xdb, 0x10, 0x25, 0x06, 0xe6, 0x1f, 0x24, 0x16, 0xd3, 0xde, 0x0d, 0xb1, + 0xec, 0x30, 0x06, 0xf5, 0xd9, 0xb6, 0x11, 0x03, 0x11, 0xd8, 0xc3, 0xe1, 0x0b, + 0x04, 0x13, 0x37, 0xec, 0xd5, 0xda, 0xe6, 0xed, 0xf7, 0x16, 0x0f, 0x40, 0x29, + 0xd5, 0x20, 0xf9, 0x0c, 0xe8, 0x36, 0x3a, 0xe6, 0x26, 0xfe, 0xea, 0x22, 0xd6, + 0x0a, 0xc0, 0xee, 0x14, 0x44, 0x38, 0x2e, 0xe4, 0x0c, 0xd7, 0x27, 0xd0, 0x53, + 0xdd, 0xb1, 0x35, 0xf4, 0xdf, 0xd6, 0x7f, 0xf1, 0xcb, 0x33, 0xf2, 0x0d, 0x3c, + 0xee, 0x2e, 0x11, 0x2a, 0x38, 0x0d, 0xec, 0x6d, 0xe8, 0x2e, 0x28, 0xa4, 0xd7, + 0x44, 0x0e, 0x58, 0xfd, 0xd4, 0xfb, 0x2e, 0x0c, 0xf3, 0x04, 0x4f, 0x12, 0xf3, + 0x33, 0xf2, 0xf6, 0xc5, 0xd7, 0xfe, 0xf9, 0x2a, 0xef, 0xd0, 0x02, 0xb2, 0xfd, + 0x49, 0xae, 0xd9, 0x38, 0xf4, 0x1d, 0xf2, 0x42, 0x19, 0x10, 0x43, 0xb2, 0x15, + 0x03, 0x0c, 0xcb, 0x0d, 0x02, 0xde, 0x05, 0xd4, 0x05, 0x43, 0xcd, 0xa7, 0xe7, + 0xfd, 0xf5, 0x5f, 0x81, 0x5a, 0xd3, 0x0e, 0x00, 0x21, 0x00, 0xfa, 0xbc, 0x0a, + 0xd9, 0xdb, 0x00, 0xc5, 0x14, 0xef, 0xf4, 0x1f, 0xee, 0x4d, 0x5f, 0xaa, 0x19, + 0xd5, 0x04, 0x2c, 0xde, 0xd1, 0x21, 0xf9, 0xee, 0x6e, 0xc9, 0xbb, 0x15, 0xf0, + 0x10, 0xc4, 0x7c, 0xe3, 0xe3, 0x27, 0xe0, 0x4d, 0x16, 0x27, 0xaf, 0x0f, 0xbf, + 0xf1, 0x53, 0xfb, 0xa1, 0xde, 0x04, 0xcc, 0x36, 0xf3, 0x65, 0xf3, 0x01, 0xcd, + 0xea, 0x12, 0xe2, 0xd6, 0xa1, 0xa8, 0xf1, 0x04, 0x13, 0x41, 0xc5, 0xdc, 0x65, + 0xc9, 0x21, 0xfc, 0xf9, 0xfa, 0x18, 0xba, 0x3b, 0xd0, 0x81, 0xf4, 0x30, 0x25, + 0xff, 0xe2, 0x28, 0xff, 0xe8, 0xd2, 0xc2, 0x94, 0xc2, 0xe7, 0x1d, 0x48, 0xdf, + 0xbe, 0xe1, 0xce, 0xca, 0xfa, 0x12, 0x1e, 0xe3, 0xd6, 0x20, 0x44, 0xae, 0xcc, + 0xf8, 0xec, 0xe7, 0x22, 0x10, 0xa4, 0x4f, 0x21, 0x2a, 0x0a, 0xcf, 0x1b, 0xb6, + 0xec, 0xe8, 0x02, 0x0b, 0xe6, 0x1a, 0xe4, 0xcb, 0xa6, 0x13, 0xe1, 0xbf, 0xc7, + 0x96, 0xc0, 0xee, 0xd8, 0x00, 0x2c, 0x3d, 0xda, 0xe6, 0xc0, 0xf7, 0x13, 0xf8, + 0x1a, 0x30, 0xf0, 0xe5, 0x4d, 0x07, 0x18, 0x22, 0xa1, 0x04, 0xd1, 0xbe, 0x19, + 0xff, 0xef, 0xe0, 0xaa, 0x5b, 0xe0, 0xb9, 0xf3, 0x27, 0xc5, 0xd0, 0x04, 0x62, + 0xee, 0xda, 0x7b, 0x3a, 0xf8, 0x56, 0xbf, 0x26, 0x04, 0x09, 0xcb, 0x25, 0xf9, + 0xfd, 0x68, 0x04, 0xcf, 0x4e, 0x40, 0x32, 0x72, 0x18, 0x2b, 0xf1, 0xfd, 0x16, + 0x0a, 0xe3, 0xa4, 0x3b, 0x58, 0xf3, 0xba, 0x26, 0x41, 0xc8, 0x5a, 0x07, 0x6a, + 0x22, 0x4e, 0x2e, 0xaa, 0x37, 0x3f, 0x31, 0x14, 0x03, 0xf4, 0x10, 0xef, 0x31, + 0xce, 0x1e, 0xfe, 0xdf, 0x18, 0xe8, 0x18, 0x1a, 0x1b, 0xfb, 0xc5, 0xd1, 0x1f, + 0xdb, 0x1a, 0x31, 0xdd, 0x14, 0xb5, 0x6c, 0x74, 0x6d, 0xfe, 0x32, 0xec, 0xb0, + 0x24, 0x15, 0xfb, 0xd3, 0xca, 0xc4, 0x04, 0x02, 0xf2, 0x45, 0xcd, 0xfc, 0x0c, + 0x27, 0xe4, 0xf6, 0x29, 0x18, 0xd7, 0x35, 0xda, 0x01, 0x1b, 0x52, 0x13, 0x0b, + 0xef, 0xf0, 0x9a, 0x12, 0xbb, 0xc5, 0xdb, 0xda, 0xf5, 0xd3, 0x31, 0xcf, 0x49, + 0x23, 0x9a, 0xe4, 0xea, 0xd1, 0xe5, 0x05, 0xc9, 0xd3, 0x0b, 0xf2, 0x02, 0x36, + 0x13, 0xb2, 0x18, 0x1f, 0x33, 0xca, 0x0a, 0xe7, 0xfa, 0x41, 0xe9, 0xa3, 0xc1, + 0x7f, 0x98, 0x1a, 0x0f, 0x91, 0xe6, 0xe8, 0x1e, 0x40, 0xd4, 0xc4, 0xf6, 0x27, + 0xfe, 0x0b, 0x32, 0x1b, 0xfe, 0x19, 0x31, 0xfd, 0x14, 0xc2, 0xbe, 0xc0, 0xc9, + 0x26, 0xe3, 0xa3, 0xeb, 0x73, 0x5a, 0x44, 0xe4, 0xe3, 0xf2, 0x25, 0xed, 0xee, + 0x22, 0x1f, 0x08, 0xfb, 0x2b, 0xf3, 0x2a, 0xd3, 0xbc, 0xd2, 0xeb, 0x1d, 0xdc, + 0x02, 0x39, 0x04, 0x1b, 0x1b, 0xc2, 0xd3, 0x14, 0xeb, 0x1f, 0x05, 0x43, 0x10, + 0xec, 0xcb, 0xcb, 0x00, 0x15, 0x24, 0xf2, 0x00, 0x2b, 0xda, 0xf9, 0x02, 0xf0, + 0xfc, 0xce, 0x13, 0xfa, 0x11, 0xe4, 0xea, 0xc5, 0x61, 0xee, 0xd4, 0x1d, 0x08, + 0x7f, 0x1a, 0x44, 0x12, 0xef, 0x0a, 0xe2, 0xed, 0x08, 0x02, 0x21, 0x04, 0x4f, + 0x1c, 0x21, 0x04, 0x14, 0x10, 0xf7, 0xdb, 0xc8, 0x18, 0xde, 0x0a, 0x50, 0xac, + 0x25, 0x0e, 0xc4, 0x26, 0xeb, 0x28, 0x02, 0xed, 0x17, 0x2d, 0xf5, 0x0c, 0xf9, + 0xe1, 0x72, 0xe6, 0xbc, 0x23, 0x06, 0x01, 0xda, 0x1a, 0x15, 0xb4, 0x33, 0x02, + 0xe2, 0x1c, 0xcd, 0x0d, 0xd6, 0x19, 0x72, 0x17, 0xa9, 0x0e, 0x8e, 0xc6, 0xfa, + 0xd5, 0x29, 0x03, 0xd0, 0x26, 0x7f, 0x42, 0x18, 0xa7, 0x2a, 0x0c, 0x01, 0x00, + 0xfb, 0xe1, 0x23, 0x6e, 0x2c, 0xeb, 0x2f, 0x06, 0x1b, 0xf7, 0x16, 0x16, 0x5b, + 0xf8, 0x2f, 0x0c, 0x37, 0xde, 0xfc, 0xec, 0xff, 0x58, 0x18, 0x01, 0xc4, 0x9d, + 0xe5, 0xfc, 0x05, 0x37, 0x14, 0x12, 0xb5, 0xc4, 0xe8, 0xdf, 0x21, 0x33, 0x29, + 0x2b, 0x02, 0xa4, 0x3c, 0xd6, 0xfa, 0x20, 0xf5, 0x11, 0x03, 0x07, 0xb7, 0xd8, + 0xd0, 0xc0, 0xd5, 0x0f, 0xe3, 0xf4, 0xeb, 0xf0, 0xd7, 0x0e, 0x0b, 0x39, 0x29, + 0xdc, 0x0a, 0xfc, 0xf0, 0xec, 0x4c, 0x46, 0xf2, 0xfd, 0x33, 0x19, 0x13, 0x2c, + 0xe6, 0xc3, 0xdc, 0xfe, 0x1e, 0x23, 0x3a, 0x09, 0xfe, 0xfe, 0xce, 0x0e, 0xad, + 0x37, 0x4b, 0xc5, 0xec, 0xfa, 0xc4, 0x1b, 0x09, 0xf7, 0x1d, 0xef, 0xc1, 0x11, + 0x11, 0xfc, 0xe6, 0xc4, 0x0b, 0x15, 0x1d, 0x0b, 0xc8, 0xd2, 0xf9, 0x08, 0xb2, + 0x21, 0xf5, 0xf6, 0x2d, 0x30, 0xc4, 0x04, 0x0a, 0xe4, 0xc6, 0x09, 0x0b, 0xb0, + 0xf5, 0x06, 0x2b, 0x09, 0xcb, 0xc4, 0xf1, 0xf7, 0x41, 0x05, 0x08, 0xee, 0x41, + 0xeb, 0x34, 0x19, 0x28, 0x13, 0x03, 0xc4, 0xda, 0x1a, 0x27, 0x04, 0xf3, 0xda, + 0xf7, 0x02, 0xbe, 0x00, 0x36, 0xda, 0xb2, 0x60, 0xf9, 0xbf, 0x02, 0xe2, 0xce, + 0xf3, 0xd4, 0x11, 0x20, 0xe3, 0xc2, 0xac, 0x0f, 0x02, 0xf5, 0xef, 0x33, 0x38, + 0xe8, 0x1c, 0x12, 0x0e, 0x46, 0xc0, 0xe1, 0xf8, 0xda, 0x20, 0x21, 0xf2, 0x50, + 0xd7, 0x0e, 0x20, 0x04, 0x01, 0xfe, 0xb8, 0x35, 0xfb, 0x30, 0xc5, 0xe1, 0xe9, + 0xe2, 0xdc, 0x81, 0x70, 0xe7, 0x15, 0xfc, 0x6c, 0x05, 0xf9, 0x1b, 0x28, 0x29, + 0x06, 0x1b, 0xed, 0x86, 0x07, 0x17, 0xd7, 0x1c, 0xff, 0xb1, 0x18, 0xcd, 0xc1, + 0xeb, 0x31, 0xfe, 0xf8, 0xda, 0xf7, 0x02, 0x20, 0x09, 0xd6, 0x15, 0xd7, 0xe4, + 0x06, 0xdb, 0x11, 0xdb, 0xf4, 0x11, 0x15, 0xcc, 0x19, 0xed, 0xe4, 0x41, 0x2f, + 0xef, 0xfa, 0x0c, 0xe2, 0x07, 0x31, 0xf1, 0x30, 0xee, 0xf5, 0x09, 0x10, 0xe0, + 0xcb, 0x36, 0x20, 0x0d, 0xe4, 0x27, 0x3b, 0x1c, 0x1c, 0x3f, 0x0f, 0xd6, 0xef, + 0xee, 0x81, 0x30, 0x0d, 0xd5, 0x36, 0xf9, 0xd8, 0x12, 0xe5, 0x99, 0xf9, 0xb5, + 0x00, 0x0c, 0x3c, 0x18, 0x36, 0x30, 0xc0, 0x13, 0x06, 0xd7, 0xf6, 0x19, 0xbf, + 0xd5, 0x05, 0xfb, 0xbe, 0xf5, 0x20, 0xc8, 0x01, 0xe5, 0xd7, 0xf8, 0xe7, 0xe7, + 0xf4, 0xcc, 0xbc, 0xb8, 0x08, 0x1d, 0x24, 0x2d, 0x09, 0xf6, 0x1f, 0xef, 0xf0, + 0xff, 0x16, 0xef, 0x24, 0x0f, 0xf4, 0xed, 0xe9, 0x11, 0x16, 0x0e, 0xe6, 0x27, + 0x12, 0xe1, 0x0b, 0xdd, 0x2c, 0x12, 0x4e, 0xf0, 0x01, 0x08, 0xf5, 0x27, 0xcc, + 0xeb, 0xfc, 0x20, 0xf5, 0x23, 0xff, 0x2b, 0xaf, 0x0a, 0x6a, 0x57, 0xd8, 0xd1, + 0xec, 0xe3, 0xfc, 0x1b, 0xd9, 0x0e, 0xf7, 0x05, 0x05, 0x08, 0xbf, 0x05, 0xc6, + 0x0b, 0xf5, 0xdd, 0x0b, 0x1a, 0x00, 0x03, 0xdf, 0xc6, 0xf6, 0x0a, 0xfa, 0x05, + 0x19, 0xcf, 0xe1, 0x36, 0xd7, 0xb5, 0xf9, 0xe8, 0x14, 0x00, 0x08, 0xe3, 0x00, + 0x32, 0xda, 0xf6, 0x0f, 0x01, 0xec, 0x0a, 0x13, 0x04, 0xe4, 0xf3, 0x3e, 0xed, + 0x48, 0xf3, 0xf6, 0x03, 0x1a, 0x10, 0x02, 0xe7, 0xf0, 0xf9, 0xe1, 0xc8, 0xe8, + 0xec, 0x36, 0x19, 0x1f, 0x06, 0xdd, 0xe2, 0x05, 0xfb, 0x1b, 0x07, 0xec, 0xdc, + 0x00, 0xe1, 0x2b, 0xf7, 0x0b, 0xf7, 0x00, 0x03, 0x12, 0x15, 0x24, 0x0b, 0x00, + 0x00, 0x1d, 0xe6, 0xd6, 0x0f, 0x25, 0x7f, 0xe9, 0xd0, 0x44, 0x14, 0xcc, 0xe4, + 0xd8, 0xe4, 0xd6, 0xf2, 0x24, 0xf3, 0xfc, 0xc0, 0x05, 0xf9, 0x09, 0xe3, 0x03, + 0x46, 0xf3, 0xd3, 0xea, 0xe6, 0xea, 0xe6, 0xed, 0x02, 0xe7, 0xf5, 0xb4, 0x42, + 0x2e, 0xf5, 0xe2, 0x18, 0x36, 0xf2, 0x20, 0x12, 0xd7, 0xb3, 0x02, 0x0f, 0xfe, + 0x32, 0x08, 0xee, 0xde, 0xcf, 0xe7, 0xf9, 0xbd, 0x2a, 0x17, 0xf1, 0x0f, 0xdf, + 0x42, 0xe8, 0x24, 0x0c, 0xc7, 0xf3, 0x20, 0xfe, 0xec, 0x07, 0x31, 0xd9, 0xef, + 0x1b, 0x29, 0x0a, 0x32, 0xfa, 0xf8, 0x7f, 0xd4, 0x6f, 0x16, 0x1b, 0xae, 0xf6, + 0x25, 0x11, 0x04, 0xed, 0x07, 0xbf, 0x20, 0x06, 0xfd, 0xe1, 0xf7, 0xcd, 0xec, + 0x1e, 0xeb, 0x0a, 0xe0, 0xc2, 0xee, 0x17, 0x24, 0xc9, 0xdc, 0x17, 0x1f, 0x08, + 0xe7, 0x1c, 0xf3, 0x0a, 0x22, 0x09, 0xc3, 0xf2, 0x10, 0x27, 0xed, 0x07, 0x1e, + 0x36, 0x02, 0x12, 0x0e, 0x19, 0x12, 0x09, 0xe9, 0xfc, 0x20, 0xf5, 0xf0, 0x30, + 0xfb, 0x11, 0x45, 0x7f, 0xe6, 0x23, 0xb3, 0xfe, 0xe9, 0xff, 0x02, 0x1a, 0x1b, + 0x39, 0x01, 0xe7, 0xdf, 0xd3, 0x34, 0xce, 0xe3, 0x17, 0xed, 0xe4, 0x27, 0x2b, + 0xf7, 0x25, 0xc7, 0xf2, 0x2a, 0xbd, 0x28, 0xe7, 0xfd, 0xe4, 0x11, 0x27, 0x25, + 0x11, 0xf5, 0x0d, 0x21, 0xfc, 0xec, 0x09, 0xef, 0xdc, 0xd0, 0x05, 0x0b, 0xef, + 0x4e, 0x0f, 0x21, 0x0f, 0x42, 0xfa, 0xd5, 0x25, 0xd7, 0x2f, 0x24, 0x1d, 0x50, + 0xf6, 0x04, 0x1f, 0x27, 0x0a, 0x52, 0xca, 0xfb, 0xc1, 0x14, 0x1c, 0x2d, 0x3c, + 0x06, 0x0d, 0x33, 0x1c, 0x03, 0x02, 0xf9, 0xfa, 0x21, 0xeb, 0xeb, 0xf9, 0x06, + 0xe2, 0xf0, 0x1a, 0xe7, 0x01, 0xb2, 0x15, 0x0f, 0xb8, 0x2a, 0x04, 0xfb, 0x14, + 0xda, 0xe7, 0xff, 0x5f, 0xe1, 0xf2, 0x0d, 0xd8, 0xff, 0xf7, 0xbc, 0xe8, 0xa4, + 0x28, 0x1b, 0xee, 0xeb, 0x50, 0xef, 0x06, 0x04, 0xd0, 0xfa, 0xcd, 0x00, 0xc8, + 0xe7, 0x81, 0xf0, 0xdc, 0xee, 0xfb, 0xc1, 0xa8, 0xf9, 0x38, 0x12, 0x4c, 0x14, + 0x76, 0xe3, 0xf8, 0xf2, 0x50, 0xf9, 0xe5, 0x1c, 0xd8, 0x39, 0xf5, 0x76, 0x00, + 0x32, 0xca, 0x1b, 0xfd, 0xf9, 0x00, 0xf8, 0x12, 0x10, 0xed, 0x3b, 0x0c, 0x10, + 0xe9, 0x06, 0xee, 0xe9, 0xfc, 0xf0, 0x0c, 0x13, 0x1b, 0x06, 0x14, 0x15, 0xc4, + 0xc1, 0xbf, 0xfb, 0x34, 0xfc, 0xe4, 0x3b, 0x02, 0xcd, 0x35, 0x35, 0xed, 0x33, + 0x03, 0xef, 0x04, 0x36, 0xcc, 0xf6, 0xf2, 0x21, 0xe9, 0x15, 0xe1, 0xed, 0xdb, + 0x27, 0xf7, 0xbc, 0xb4, 0x20, 0xee, 0x01, 0xac, 0x4f, 0xc2, 0xbd, 0xfe, 0xc7, + 0xe5, 0x0a, 0x08, 0xbb, 0xf3, 0xf8, 0x47, 0xeb, 0xd6, 0x19, 0xf2, 0x65, 0x21, + 0x17, 0xb6, 0x0a, 0x11, 0x0f, 0xf0, 0xf4, 0x26, 0x19, 0xce, 0xd2, 0x4d, 0x2b, + 0xfa, 0x06, 0x10, 0x06, 0xe2, 0x37, 0x20, 0x3f, 0xef, 0x44, 0x4e, 0x1a, 0x57, + 0x43, 0x81, 0xae, 0x1e, 0x46, 0x1f, 0x0b, 0x3a, 0x03, 0xae, 0x0d, 0xeb, 0xd8, + 0xcc, 0x25, 0xe2, 0x32, 0xc8, 0xe5, 0x18, 0xcd, 0x1a, 0x1e, 0xe1, 0xde, 0x20, + 0x12, 0x30, 0xcf, 0xe5, 0xe8, 0x16, 0x31, 0x0e, 0x25, 0xfe, 0x17, 0x05, 0xe9, + 0xb7, 0xa1, 0x2e, 0xc2, 0x0d, 0xb8, 0x4a, 0xf7, 0xdf, 0xd8, 0xf9, 0xcf, 0xaa, + 0x36, 0x08, 0x2f, 0x0c, 0xca, 0x99, 0x02, 0xf8, 0x04, 0x22, 0xdd, 0x2c, 0xcb, + 0xf6, 0x13, 0x20, 0xef, 0x0f, 0xe4, 0x39, 0x32, 0x17, 0xef, 0xc3, 0xe6, 0x04, + 0xc3, 0xf0, 0xde, 0xcf, 0xdc, 0x4d, 0xf8, 0xbc, 0x12, 0xd4, 0x2b, 0xbe, 0xf7, + 0xb5, 0x12, 0x05, 0x02, 0xcb, 0x2e, 0xcc, 0x03, 0xbd, 0x5c, 0x11, 0xde, 0x2a, + 0xca, 0x33, 0xfb, 0xe9, 0xd8, 0x11, 0x64, 0xf6, 0xf7, 0x2f, 0xeb, 0x09, 0x47, + 0xf5, 0x29, 0x05, 0xfc, 0x27, 0xf2, 0xe0, 0xc3, 0x3e, 0x09, 0xf7, 0xec, 0xb5, + 0x11, 0xf8, 0x0d, 0x7f, 0xfa, 0xc4, 0x0c, 0xec, 0xf0, 0xea, 0x22, 0xe7, 0xd5, + 0xb4, 0xf5, 0xac, 0x14, 0xd8, 0xfb, 0xe0, 0xee, 0x22, 0xc7, 0x1c, 0xd8, 0x02, + 0xaa, 0xd9, 0xe2, 0x1f, 0x1f, 0xff, 0x25, 0x25, 0x1a, 0x20, 0xcd, 0xfa, 0x01, + 0xee, 0xec, 0xbf, 0x2e, 0x35, 0x07, 0x25, 0x16, 0x2d, 0x01, 0xcd, 0x19, 0x49, + 0xe4, 0x57, 0xff, 0xfb, 0xf2, 0xef, 0x09, 0x28, 0xf5, 0xa9, 0xd6, 0x00, 0xcf, + 0xf3, 0xe5, 0xc2, 0xfc, 0xca, 0xfd, 0x0d, 0x18, 0xde, 0x1d, 0xf4, 0xd7, 0x27, + 0x02, 0x33, 0x1e, 0xd7, 0x0c, 0x18, 0x41, 0x03, 0x1b, 0xee, 0x05, 0x26, 0x30, + 0x09, 0xd7, 0x14, 0xbd, 0xdf, 0x0e, 0xff, 0xe5, 0xfb, 0x28, 0xf8, 0x38, 0x17, + 0x08, 0xdd, 0xda, 0x15, 0xce, 0x08, 0xe6, 0xc4, 0xdc, 0x19, 0xe9, 0xd8, 0xc4, + 0x03, 0xe6, 0xcc, 0x4b, 0x0f, 0x1f, 0xc0, 0xfe, 0x15, 0xf1, 0x04, 0xec, 0x24, + 0xf7, 0xe8, 0x1f, 0x3c, 0xe9, 0x39, 0x23, 0x81, 0xac, 0xbf, 0x35, 0x2c, 0x14, + 0x00, 0xd5, 0x3b, 0xd0, 0x09, 0x03, 0xc3, 0xd6, 0x01, 0x01, 0xa9, 0xc0, 0x07, + 0x39, 0xa9, 0x2e, 0x0f, 0x44, 0xfb, 0x0a, 0x22, 0xe2, 0xc5, 0x21, 0x02, 0x21, + 0x08, 0x88, 0x10, 0xbc, 0xec, 0x9f, 0x27, 0x0e, 0xf8, 0xcd, 0xc6, 0x33, 0xf4, + 0x28, 0xc6, 0x07, 0x0f, 0x0c, 0x03, 0xc8, 0xde, 0xb4, 0xe9, 0x30, 0x1b, 0x37, + 0xe2, 0xcb, 0xef, 0x03, 0xc8, 0xdb, 0xcc, 0x0b, 0xf1, 0xc4, 0x34, 0x16, 0xb8, + 0x24, 0x40, 0x47, 0xe2, 0x10, 0x22, 0x0d, 0xaf, 0x01, 0x00, 0x18, 0x9a, 0x08, + 0xfd, 0x12, 0xd7, 0x0c, 0x37, 0x93, 0xdc, 0xcd, 0x20, 0xf0, 0x49, 0x14, 0x11, + 0xe3, 0x0c, 0xb8, 0xf0, 0x25, 0xd3, 0x30, 0x2d, 0x16, 0x47, 0x1f, 0x3e, 0xf6, + 0xc3, 0xfa, 0xb4, 0x41, 0x1d, 0xd1, 0x11, 0xff, 0xd5, 0xf3, 0xd6, 0x00, 0xef, + 0xcd, 0xb5, 0x13, 0xd4, 0xf8, 0xbb, 0xf0, 0x34, 0x6f, 0xb7, 0x1a, 0x05, 0xde, + 0xef, 0xf0, 0x2e, 0xd1, 0x10, 0xf0, 0xf2, 0xfb, 0x04, 0x04, 0xf3, 0xfe, 0x2a, + 0x23, 0x1d, 0xfa, 0x05, 0xc8, 0xcf, 0xb8, 0xcd, 0xb2, 0xf3, 0xe1, 0xd2, 0xc9, + 0x46, 0x26, 0x15, 0x0b, 0xea, 0x0d, 0x03, 0x0e, 0xa8, 0x00, 0xf7, 0x34, 0x1e, + 0x14, 0xe9, 0xed, 0x0f, 0x06, 0x12, 0xfb, 0xbe, 0x9f, 0x4d, 0xa7, 0x14, 0xd3, + 0x2f, 0xb5, 0xf7, 0x4b, 0x06, 0x2a, 0xdb, 0x23, 0x12, 0xaf, 0x05, 0xeb, 0x1c, + 0xad, 0xf4, 0xe9, 0xfd, 0x7f, 0xe1, 0xd3, 0xf7, 0x0f, 0x31, 0x28, 0xe0, 0xd3, + 0x2c, 0x16, 0xee, 0xcb, 0xfe, 0x12, 0xf0, 0xe8, 0xe9, 0xfa, 0x02, 0xc3, 0xcc, + 0xdd, 0xe8, 0xcc, 0xe2, 0xec, 0xf2, 0x00, 0x1f, 0xf9, 0xfc, 0xe7, 0xe3, 0xc6, + 0xb9, 0xdb, 0x58, 0x19, 0x2e, 0x04, 0x2e, 0x31, 0x39, 0x2c, 0xc8, 0xd4, 0xdd, + 0x1b, 0xf7, 0x22, 0xad, 0xd8, 0x13, 0x07, 0xc2, 0x27, 0xe6, 0x04, 0xee, 0xd2, + 0x0f, 0xd8, 0x16, 0x0a, 0x1b, 0x03, 0x09, 0xe9, 0xe0, 0x0d, 0xd2, 0x04, 0x09, + 0xc8, 0x29, 0x16, 0xe3, 0xe9, 0x23, 0xf5, 0x03, 0x40, 0xda, 0x58, 0x0e, 0x13, + 0x11, 0x01, 0x0d, 0x1d, 0x0a, 0x18, 0xa1, 0x3b, 0x7f, 0x7f, 0x1b, 0x3f, 0x06, + 0xd2, 0xee, 0xf8, 0x0f, 0x18, 0xf3, 0xca, 0xed, 0xe9, 0xef, 0x03, 0x2d, 0xe6, + 0xf6, 0x3e, 0x07, 0xf9, 0xe5, 0xf5, 0x2b, 0xee, 0xed, 0x1c, 0xfa, 0xfe, 0x14, + 0x1d, 0x12, 0x2d, 0xe8, 0xd1, 0xe7, 0x59, 0x9d, 0x0f, 0x02, 0xb8, 0xf9, 0x10, + 0x19, 0x10, 0xc5, 0x08, 0x5a, 0x19, 0xe2, 0x3c, 0xeb, 0x19, 0x0c, 0xc0, 0xe3, + 0x01, 0xed, 0xed, 0xc8, 0x08, 0xfc, 0xee, 0x29, 0xfc, 0x0c, 0x1a, 0xe3, 0x01, + 0xfe, 0xe1, 0x53, 0x0d, 0xd8, 0x01, 0xe6, 0x23, 0xfc, 0xfc, 0xbf, 0xfd, 0x14, + 0x4f, 0x08, 0xf8, 0x23, 0x05, 0xe1, 0xd3, 0xd6, 0xe1, 0x56, 0xb4, 0x01, 0xff, + 0xd6, 0xe6, 0xdd, 0x14, 0x0f, 0x2a, 0xf1, 0x00, 0xca, 0x21, 0xdf, 0x16, 0x0a, + 0x1f, 0xcf, 0x2a, 0x02, 0x56, 0xf8, 0x19, 0x1e, 0x10, 0xde, 0xf9, 0x0f, 0xdd, + 0xb2, 0x3c, 0x25, 0x1a, 0x30, 0xf8, 0x12, 0xf5, 0xbc, 0x5e, 0x0c, 0x1b, 0xfe, + 0x02, 0xec, 0x58, 0x29, 0x2e, 0xda, 0x07, 0xc8, 0x16, 0x1b, 0x1a, 0x2e, 0xd9, + 0xbb, 0x03, 0x24, 0xf5, 0x2c, 0x0f, 0xcf, 0x06, 0x7f, 0xf8, 0xc7, 0x14, 0xe2, + 0xd9, 0x05, 0xe5, 0x12, 0xf8, 0xd6, 0x01, 0xf0, 0xd4, 0x0e, 0x18, 0x1b, 0xd0, + 0x4c, 0xe3, 0xf5, 0xf9, 0xf6, 0xd5, 0xe4, 0xe9, 0x1a, 0xd1, 0x0b, 0x2d, 0xea, + 0x40, 0xf7, 0x29, 0xfb, 0xfa, 0x1f, 0xf8, 0xe0, 0xff, 0x05, 0x62, 0xf8, 0x08, + 0x7f, 0xaf, 0xdb, 0xe7, 0xe2, 0x39, 0xd6, 0xf7, 0xf7, 0xff, 0xce, 0xfc, 0x24, + 0x45, 0x0e, 0xfd, 0x58, 0xf7, 0xe0, 0x25, 0xdb, 0x1b, 0x19, 0xb7, 0x17, 0x1f, + 0x21, 0x11, 0xdd, 0x29, 0x26, 0x4a, 0x0a, 0x3a, 0x26, 0x07, 0x44, 0xcc, 0xe3, + 0x22, 0x3f, 0xb9, 0xe3, 0xf5, 0xcf, 0x30, 0xec, 0x27, 0xd7, 0x2f, 0x25, 0x04, + 0x13, 0x07, 0x1c, 0x05, 0x11, 0xef, 0xd2, 0x2c, 0xd5, 0x66, 0xf3, 0xea, 0xe1, + 0xff, 0xe3, 0xd3, 0x26, 0xc0, 0xd6, 0x2a, 0x40, 0x2d, 0xeb, 0x08, 0xed, 0x18, + 0x20, 0xf0, 0xe1, 0x13, 0x04, 0x12, 0x13, 0x27, 0x03, 0x0b, 0x04, 0x11, 0xf4, + 0xfe, 0x08, 0xdf, 0x2e, 0xd3, 0x17, 0xd1, 0xcd, 0xe9, 0xf0, 0x13, 0x08, 0x22, + 0x33, 0xda, 0xd9, 0xf9, 0xe9, 0x17, 0xfd, 0xe8, 0x05, 0x8f, 0xc6, 0xeb, 0xf9, + 0xc8, 0x31, 0xce, 0xa6, 0xde, 0xb9, 0xfb, 0xe1, 0x1d, 0xff, 0x0c, 0x78, 0xff, + 0xca, 0xf2, 0xb3, 0xfa, 0x0f, 0x23, 0xcb, 0x11, 0xbb, 0x3a, 0xe9, 0xda, 0xe6, + 0x12, 0xee, 0xeb, 0x01, 0xd7, 0xf8, 0xbb, 0xe7, 0xea, 0x23, 0x30, 0xff, 0xdb, + 0x0d, 0xc2, 0x33, 0x24, 0xcf, 0x56, 0xe1, 0xb0, 0xed, 0xe4, 0xfc, 0xdf, 0x2b, + 0x8e, 0x03, 0x1e, 0xeb, 0x05, 0xc0, 0xea, 0xbc, 0x2b, 0xce, 0x34, 0xd6, 0xdd, + 0xeb, 0x08, 0xeb, 0xd8, 0xc3, 0x5a, 0xc9, 0x05, 0x26, 0xc5, 0xd4, 0x0f, 0x65, + 0x26, 0x36, 0xde, 0xdf, 0xf1, 0x37, 0x27, 0x3e, 0xf3, 0xac, 0xbf, 0xfa, 0xd6, + 0x27, 0x0a, 0xda, 0x2d, 0xbf, 0x24, 0xc4, 0xe9, 0x63, 0xd8, 0xc0, 0x10, 0xe6, + 0x4f, 0xfc, 0x91, 0xb9, 0x1b, 0xec, 0xeb, 0x96, 0xf3, 0xd7, 0x5b, 0xe8, 0x74, + 0x1b, 0xdc, 0x07, 0x1d, 0x20, 0xf8, 0xef, 0xf9, 0xe2, 0x2d, 0x07, 0x3f, 0x28, + 0xf5, 0x7f, 0xdf, 0xc7, 0x1a, 0x18, 0x16, 0xcc, 0xd4, 0xf1, 0xf4, 0x19, 0xfc, + 0x22, 0xcf, 0xe4, 0xd8, 0x20, 0xf8, 0xaa, 0x3c, 0xde, 0x73, 0x0c, 0x25, 0x04, + 0x30, 0x19, 0xb3, 0x09, 0x4c, 0x46, 0x15, 0xfc, 0xd6, 0xe6, 0xcb, 0xef, 0xd6, + 0xfd, 0x26, 0x7f, 0x40, 0xcd, 0xd9, 0xfe, 0xfd, 0x1e, 0x19, 0xb9, 0xe2, 0x4d, + 0xfe, 0xf4, 0x05, 0xcb, 0x1f, 0xd2, 0x0d, 0xcc, 0xf6, 0xaf, 0x13, 0xf8, 0x0b, + 0x68, 0xcc, 0xd2, 0x6f, 0xac, 0x04, 0x36, 0x52, 0xf7, 0xef, 0xce, 0x00, 0x3c, + 0xb9, 0xd4, 0x0f, 0xf1, 0xe3, 0xf3, 0x33, 0x34, 0xef, 0x0c, 0xce, 0x59, 0x26, + 0x1f, 0xd9, 0xe3, 0x21, 0x16, 0x15, 0xf4, 0x08, 0x24, 0x20, 0x0a, 0x29, 0x02, + 0xe5, 0xcb, 0xf9, 0xe1, 0x32, 0x01, 0xf7, 0x05, 0x16, 0xe7, 0x28, 0xfd, 0x2f, + 0xce, 0xcf, 0x15, 0xdd, 0x55, 0xdd, 0xf3, 0x4b, 0x2e, 0xf9, 0xd4, 0x1d, 0x2f, + 0x43, 0x19, 0x99, 0xde, 0x81, 0xd3, 0xcd, 0xfa, 0x26, 0xcd, 0xcf, 0xcd, 0x10, + 0xe4, 0x0d, 0x44, 0xe9, 0x14, 0x6f, 0xcb, 0x46, 0xec, 0xf8, 0x11, 0xb7, 0xc6, + 0xf1, 0xee, 0xb8, 0x06, 0x83, 0xe2, 0xf1, 0xad, 0xec, 0x2e, 0x4a, 0xbe, 0x0b, + 0xf7, 0xf9, 0x03, 0x16, 0x0a, 0x16, 0xc7, 0x21, 0xe3, 0xc0, 0xd4, 0xf7, 0x49, + 0x17, 0xb5, 0x76, 0x03, 0x26, 0xc7, 0xe0, 0x2a, 0x1e, 0xd2, 0x28, 0x0f, 0xb2, + 0xf9, 0xf6, 0xbe, 0x60, 0x06, 0x15, 0xcf, 0xbc, 0x2c, 0xef, 0x08, 0xd7, 0x0d, + 0x02, 0xe6, 0x39, 0xb1, 0xc7, 0x0b, 0x0a, 0x40, 0x51, 0xe7, 0xe6, 0xcf, 0x11, + 0xa0, 0xce, 0xf7, 0x0f, 0xac, 0x14, 0xdd, 0x22, 0xe5, 0x01, 0xd0, 0xd6, 0x33, + 0xff, 0xa2, 0x1c, 0x02, 0xee, 0x24, 0x17, 0x46, 0xf3, 0x03, 0xf4, 0x17, 0xf8, + 0x01, 0xee, 0x47, 0x78, 0xf3, 0x24, 0x95, 0x16, 0xf0, 0x18, 0xc1, 0x21, 0xe9, + 0x45, 0x02, 0xf4, 0x21, 0x03, 0x2a, 0xe1, 0x27, 0x43, 0xdb, 0x2f, 0xf4, 0x1c, + 0xf1, 0xd3, 0x2a, 0xde, 0x45, 0xbd, 0x25, 0x65, 0xea, 0x09, 0x03, 0x0a, 0x43, + 0xec, 0x27, 0x2b, 0xe1, 0x9b, 0x0e, 0xf9, 0xe4, 0xda, 0x05, 0xc1, 0xe8, 0xe4, + 0x00, 0x05, 0x0e, 0xec, 0x02, 0xf3, 0xd8, 0x40, 0x33, 0x13, 0xc7, 0x04, 0xf7, + 0x3f, 0xf5, 0xe8, 0x16, 0x1e, 0xd1, 0xec, 0x0a, 0x15, 0x11, 0xd1, 0x09, 0x0e, + 0xd7, 0xf4, 0x0b, 0xd2, 0x28, 0xdf, 0xc2, 0x29, 0xe7, 0x43, 0x31, 0xeb, 0x52, + 0x0c, 0x20, 0xf2, 0xe2, 0xea, 0x00, 0xd3, 0x02, 0x61, 0x61, 0x0c, 0xed, 0xe7, + 0x1d, 0x06, 0xa3, 0xf7, 0xf0, 0xd8, 0xd3, 0x41, 0xe0, 0xe9, 0xc0, 0xf7, 0x07, + 0x35, 0x25, 0xf5, 0xb9, 0x05, 0xd5, 0xf2, 0x12, 0x16, 0x37, 0xdc, 0x00, 0x1d, + 0xba, 0xc4, 0x13, 0xe2, 0x37, 0x10, 0x09, 0x27, 0x7f, 0x01, 0xb9, 0x0b, 0xf7, + 0xf1, 0x1f, 0xe6, 0x13, 0xbc, 0xf2, 0xd4, 0x25, 0x31, 0x30, 0xff, 0xf3, 0xcb, + 0xc9, 0xd4, 0xe9, 0xe0, 0x00, 0xcb, 0x2d, 0xcd, 0xdb, 0xfc, 0xfd, 0x05, 0xdb, + 0xe0, 0xe6, 0x7f, 0xf5, 0x27, 0x19, 0xbf, 0xce, 0xed, 0xe5, 0x19, 0x11, 0xd4, + 0xc0, 0x11, 0x1b, 0x0f, 0x00, 0xcd, 0xe8, 0x08, 0x15, 0x05, 0xd0, 0x1c, 0xe1, + 0xf6, 0x28, 0x13, 0x1d, 0xf7, 0xef, 0xe9, 0xcc, 0x13, 0x54, 0x6e, 0x18, 0xe0, + 0xfe, 0x08, 0xc1, 0xc9, 0xfd, 0xee, 0xef, 0x03, 0x30, 0x3b, 0xd9, 0x01, 0xe9, + 0x11, 0xca, 0xc1, 0xe7, 0xfd, 0x49, 0x16, 0x0d, 0xb3, 0x0d, 0xfe, 0x3c, 0xfd, + 0xec, 0x15, 0xd5, 0x1c, 0x38, 0x0e, 0x37, 0xd9, 0x00, 0x33, 0xda, 0xfd, 0x19, + 0xfc, 0x21, 0xef, 0xe4, 0x3d, 0xfb, 0xd3, 0xf4, 0xfe, 0x1f, 0x17, 0x0b, 0x0e, + 0xd6, 0xae, 0xd1, 0xf7, 0x33, 0x0a, 0xf3, 0x1d, 0x07, 0xd8, 0xef, 0x27, 0xf7, + 0xe3, 0xec, 0xeb, 0x10, 0x37, 0x32, 0xe2, 0x06, 0xe9, 0xdb, 0x02, 0xd7, 0xd6, + 0xf3, 0xf2, 0x0f, 0x18, 0xf6, 0x26, 0xda, 0x20, 0x22, 0x1e, 0x01, 0xff, 0xef, + 0x25, 0x23, 0x25, 0x7f, 0x4f, 0x18, 0xd5, 0x1c, 0x01, 0x0b, 0xe7, 0xef, 0xe4, + 0xe5, 0x0c, 0xf0, 0xf8, 0xe3, 0x28, 0xbb, 0x35, 0xea, 0xec, 0x35, 0xf3, 0xc8, + 0xf2, 0xc4, 0xe7, 0x10, 0x00, 0x10, 0x01, 0x19, 0xf2, 0x0e, 0xff, 0x07, 0x0c, + 0xce, 0x40, 0x22, 0x3d, 0x0d, 0x07, 0xee, 0xcb, 0x30, 0xf8, 0x0b, 0xd6, 0xdb, + 0x01, 0xed, 0xed, 0xd0, 0xea, 0x32, 0x05, 0xe1, 0xf2, 0x1a, 0x1d, 0xec, 0x33, + 0xd0, 0x2a, 0x08, 0x20, 0xe3, 0x30, 0x03, 0xb1, 0x0c, 0x04, 0x30, 0xe7, 0xde, + 0xf8, 0xe5, 0x1b, 0x14, 0x05, 0xe0, 0x08, 0x1a, 0xee, 0xe1, 0x10, 0x12, 0x22, + 0x19, 0x1f, 0xfa, 0xc3, 0x14, 0x1b, 0x41, 0xd5, 0x46, 0x1b, 0xea, 0xde, 0x31, + 0x18, 0xfc, 0x39, 0xf6, 0xfd, 0x02, 0x1f, 0x5e, 0xed, 0x47, 0x0d, 0x81, 0xe8, + 0xc6, 0x35, 0x04, 0x2e, 0x10, 0x0d, 0xb4, 0x17, 0xf3, 0x19, 0x0e, 0x0c, 0x0e, + 0x14, 0x01, 0x60, 0x45, 0xda, 0x09, 0xd2, 0x10, 0xe8, 0xf7, 0x12, 0x53, 0xf1, + 0xff, 0x4f, 0x01, 0xe7, 0xd2, 0x00, 0xc2, 0xb3, 0xed, 0x2b, 0xf1, 0x28, 0xc1, + 0xfe, 0x3a, 0xf9, 0x1b, 0x16, 0xeb, 0x19, 0xf9, 0xff, 0x08, 0x43, 0x25, 0xf3, + 0x1a, 0x34, 0xb5, 0x33, 0xf8, 0xea, 0x87, 0x18, 0x18, 0xec, 0xe8, 0x13, 0xd1, + 0x24, 0xea, 0x00, 0xed, 0x13, 0xf2, 0xd0, 0x02, 0x01, 0x18, 0x17, 0xf9, 0x0e, + 0x23, 0x23, 0xf2, 0x13, 0x21, 0x1e, 0x01, 0xe8, 0x22, 0xd6, 0xc9, 0xee, 0xd9, + 0x1f, 0xfd, 0x08, 0xc4, 0x56, 0x2f, 0x2d, 0x8b, 0x15, 0x1b, 0xef, 0xf8, 0x0d, + 0xe2, 0x22, 0xeb, 0x15, 0x07, 0x55, 0xf4, 0x24, 0xf6, 0xd8, 0x06, 0xd7, 0x56, + 0x2b, 0x3a, 0xe1, 0x0a, 0x10, 0xa1, 0xfd, 0x7f, 0x22, 0xc6, 0xf9, 0x0c, 0xd3, + 0xdd, 0xd6, 0x15, 0x23, 0xfe, 0x6d, 0xdf, 0xe1, 0x21, 0xe1, 0xef, 0xed, 0xf6, + 0xcc, 0x1b, 0xdb, 0xf8, 0xfa, 0xeb, 0xf6, 0xef, 0xe5, 0xf4, 0x04, 0x24, 0x30, + 0x01, 0x2d, 0xf9, 0xfc, 0xfc, 0xf8, 0x06, 0x13, 0x31, 0x2f, 0xc8, 0xc5, 0xe8, + 0x61, 0xf2, 0x03, 0x00, 0xf4, 0xcd, 0xfb, 0xf5, 0x01, 0xf1, 0x0f, 0x26, 0x06, + 0xf5, 0xe8, 0xea, 0xc6, 0x00, 0x0a, 0xf5, 0xff, 0x2e, 0x08, 0xfa, 0xdb, 0xb7, + 0x24, 0x12, 0x1d, 0xf5, 0x1c, 0xd1, 0x3c, 0x0b, 0xef, 0x10, 0xea, 0x06, 0x16, + 0xe0, 0xa8, 0xd5, 0xdb, 0x19, 0xfe, 0x18, 0xe8, 0x08, 0x1c, 0x2b, 0x25, 0x27, + 0x0b, 0x38, 0x22, 0xf8, 0x17, 0xb1, 0x5f, 0xea, 0xe0, 0xa0, 0x53, 0x60, 0xe8, + 0x17, 0x12, 0x2d, 0x10, 0x49, 0x2b, 0xc0, 0xf4, 0xf0, 0xdc, 0x08, 0xb8, 0x0c, + 0x10, 0x16, 0x2a, 0xf7, 0xe7, 0xe4, 0x06, 0xfe, 0xc5, 0x31, 0x03, 0xef, 0xf6, + 0x4a, 0x1a, 0x27, 0x4b, 0x54, 0xd8, 0xcc, 0x00, 0xfa, 0xe0, 0xf0, 0x30, 0x0f, + 0x40, 0xdf, 0x00, 0x33, 0xf4, 0xd0, 0x13, 0x15, 0xfb, 0x29, 0xc6, 0x48, 0x0d, + 0x13, 0x06, 0x43, 0xcc, 0xe7, 0x7f, 0xe9, 0xed, 0x0b, 0x1c, 0x25, 0xfe, 0xf9, + 0xf9, 0xbd, 0xc4, 0xea, 0x2c, 0xdf, 0x0d, 0xc7, 0x20, 0x20, 0xe1, 0xde, 0x68, + 0xf2, 0x22, 0xcf, 0xef, 0x13, 0xff, 0xe8, 0x27, 0x0a, 0x48, 0xd4, 0x08, 0x68, + 0x1f, 0x14, 0xff, 0x0b, 0x1b, 0x49, 0xc7, 0xea, 0x04, 0xce, 0x0d, 0xd2, 0x99, + 0xe1, 0xd4, 0xff, 0xf6, 0x0c, 0x25, 0x30, 0x03, 0x43, 0x15, 0x35, 0xfa, 0xe9, + 0x21, 0x05, 0x1f, 0x27, 0x33, 0x1b, 0xd1, 0xdc, 0xf2, 0x29, 0xd0, 0xee, 0xfa, + 0xc1, 0x06, 0x13, 0xf0, 0x4b, 0x05, 0x17, 0xcf, 0xf8, 0x08, 0x0d, 0xf9, 0x36, + 0x11, 0xdf, 0xfe, 0xc7, 0xb0, 0xda, 0xea, 0x33, 0x5f, 0x3c, 0x20, 0xff, 0xff, + 0x17, 0x08, 0xd8, 0xf5, 0x22, 0xfa, 0xd6, 0xe6, 0x43, 0x17, 0xe2, 0x91, 0xfe, + 0xf6, 0x7a, 0xe3, 0xf2, 0xf1, 0x04, 0xff, 0xda, 0xf8, 0xee, 0x0d, 0xc8, 0xea, + 0xc5, 0xeb, 0x17, 0x06, 0x11, 0xd2, 0xfd, 0x7f, 0x1b, 0x0c, 0x37, 0xe1, 0x0d, + 0x3d, 0x3c, 0x3c, 0x35, 0x15, 0xe0, 0x32, 0x03, 0x1d, 0xe3, 0x0e, 0x13, 0xdd, + 0xd9, 0x14, 0x12, 0x08, 0xc5, 0x25, 0x1b, 0xd3, 0xfd, 0xe9, 0x05, 0x22, 0x18, + 0x29, 0x0c, 0xbc, 0xe0, 0x01, 0xdb, 0xdb, 0xe8, 0x39, 0x1b, 0x2d, 0x1c, 0xdf, + 0xf0, 0xfe, 0x2c, 0xec, 0xf5, 0x3f, 0x0f, 0xed, 0xf2, 0x2f, 0xf3, 0xf7, 0x23, + 0xff, 0x4e, 0xd2, 0xe6, 0x6b, 0x0b, 0x05, 0x11, 0xf4, 0xfb, 0x15, 0xe9, 0xed, + 0x16, 0x25, 0xa5, 0xfe, 0x47, 0x2a, 0xd7, 0xf6, 0x4c, 0x0b, 0xd7, 0xc7, 0xd6, + 0xe6, 0xcb, 0xcd, 0xfb, 0xec, 0xe7, 0x00, 0xd4, 0xda, 0x52, 0xe0, 0x21, 0xbf, + 0xcf, 0x3b, 0xe3, 0x1e, 0xbb, 0xab, 0x44, 0x56, 0x7e, 0xac, 0x26, 0x25, 0xfc, + 0xdb, 0xec, 0x01, 0xe9, 0xea, 0xf9, 0x49, 0x36, 0x03, 0x32, 0x04, 0x18, 0xfe, + 0xc3, 0xb2, 0xba, 0x7f, 0xec, 0xe6, 0xbf, 0x34, 0x01, 0x25, 0x0e, 0xde, 0xe6, + 0x0e, 0x8d, 0xcc, 0x28, 0x0c, 0x1a, 0x24, 0x1f, 0xd2, 0x1f, 0x01, 0x0b, 0x28, + 0xd7, 0xc9, 0x38, 0xf3, 0xc4, 0x5f, 0xf3, 0xcb, 0xea, 0xf3, 0xcf, 0xd0, 0xdc, + 0xe6, 0xd5, 0x1f, 0xc1, 0x1d, 0xfe, 0xfd, 0x88, 0x1e, 0xf1, 0x11, 0x05, 0x1b, + 0xec, 0xb0, 0xa4, 0xf1, 0x1c, 0xb8, 0x7b, 0x29, 0x10, 0x5d, 0x16, 0xf5, 0xb4, + 0xb7, 0x0a, 0x2b, 0x1d, 0x3c, 0xc0, 0xfd, 0xde, 0xe7, 0x32, 0xc6, 0x1a, 0xd4, + 0xc6, 0x17, 0x02, 0x06, 0xc4, 0xe0, 0x35, 0xaf, 0xd9, 0x02, 0xbf, 0x22, 0x59, + 0xc8, 0x14, 0xed, 0xb6, 0xd3, 0x5b, 0xf3, 0xb3, 0xd4, 0x19, 0xfd, 0x7f, 0xde, + 0x2d, 0xd5, 0xfe, 0xe5, 0x1e, 0xf5, 0xd5, 0xf0, 0x36, 0x07, 0xe1, 0x25, 0xc9, + 0x11, 0x29, 0x8b, 0xed, 0xbd, 0x19, 0x14, 0x74, 0xb3, 0xd9, 0xf0, 0x2d, 0x11, + 0x1e, 0xd4, 0x30, 0xb6, 0xe0, 0xff, 0xc4, 0x5d, 0xf5, 0x30, 0xc0, 0x96, 0x0c, + 0x03, 0x06, 0x11, 0xe5, 0xf3, 0xa1, 0x03, 0xe6, 0xe3, 0x31, 0xb7, 0x1b, 0x3c, + 0xec, 0xff, 0xef, 0x21, 0x10, 0x21, 0xdf, 0x18, 0xf2, 0x2e, 0xdf, 0xbc, 0x23, + 0x73, 0x0f, 0x05, 0xd4, 0x26, 0x0d, 0xf3, 0x02, 0xc9, 0x0d, 0x33, 0x3e, 0xd3, + 0xda, 0x21, 0xd8, 0xe9, 0x24, 0x18, 0x03, 0xd1, 0xf1, 0xdd, 0xec, 0xf0, 0x15, + 0x29, 0x12, 0x18, 0x00, 0xf4, 0x1c, 0xc1, 0x14, 0x47, 0xf6, 0xba, 0x5e, 0x0d, + 0x46, 0x17, 0x1e, 0x15, 0x05, 0x04, 0xd5, 0x1e, 0x6b, 0xea, 0x2e, 0x21, 0xab, + 0xf7, 0xc5, 0x4c, 0xdb, 0x31, 0x0a, 0x15, 0x07, 0x4d, 0x1a, 0xcf, 0xf3, 0x24, + 0xbf, 0x0e, 0x0d, 0xdf, 0xdb, 0x14, 0x01, 0x01, 0x38, 0x2d, 0x34, 0x2f, 0x1c, + 0x09, 0xde, 0x2c, 0x0c, 0xc0, 0xf0, 0x23, 0x02, 0xb5, 0x04, 0x3c, 0xd7, 0x1c, + 0xfb, 0x20, 0xc5, 0x04, 0xdf, 0x48, 0x15, 0x3d, 0x12, 0xeb, 0xe6, 0x12, 0xd1, + 0xde, 0x39, 0x33, 0x33, 0x05, 0xfb, 0xdb, 0xf3, 0x24, 0xd4, 0x1b, 0xd1, 0x30, + 0xe8, 0xff, 0x0e, 0xea, 0xfc, 0xf9, 0xcc, 0x4b, 0xd8, 0x36, 0xcd, 0x3e, 0xdd, + 0xf9, 0x03, 0xe2, 0xf9, 0x0a, 0xd2, 0xae, 0xf0, 0x1c, 0xe9, 0xf0, 0x28, 0x15, + 0x28, 0xac, 0x63, 0x33, 0x7f, 0xc7, 0xe9, 0xc8, 0x15, 0x34, 0xcd, 0xf4, 0xbe, + 0x08, 0x23, 0x39, 0xfc, 0x22, 0xf2, 0x02, 0xf9, 0x15, 0xb2, 0x21, 0xc6, 0x24, + 0x02, 0x93, 0xf1, 0xc3, 0x1d, 0x18, 0x1e, 0xde, 0xae, 0x01, 0xee, 0xb6, 0x67, + 0xe1, 0x26, 0xc2, 0x05, 0x01, 0x06, 0x28, 0x33, 0xfe, 0xe2, 0xe5, 0xd0, 0xbc, + 0x1b, 0xcf, 0x1b, 0xdb, 0x3f, 0xe4, 0x16, 0x15, 0x2d, 0x52, 0x5e, 0xfb, 0x22, + 0xd2, 0x46, 0xec, 0x15, 0xe9, 0x2c, 0xcd, 0x24, 0x22, 0xed, 0xea, 0xfa, 0xf5, + 0xc3, 0xf5, 0xb3, 0x81, 0x04, 0xf3, 0x90, 0xcc, 0x4f, 0xcd, 0x43, 0xe5, 0xfd, + 0x22, 0x9b, 0x15, 0x01, 0xc4, 0x2a, 0x3b, 0xe5, 0x04, 0x09, 0xe5, 0xaa, 0xf8, + 0xc2, 0xcc, 0x13, 0x11, 0x8b, 0x39, 0xaf, 0x0d, 0xfc, 0xee, 0xff, 0xfd, 0x1c, + 0xfe, 0xd6, 0x5f, 0xec, 0xcf, 0xc2, 0xc1, 0x0f, 0x68, 0x22, 0xf2, 0x3c, 0xd3, + 0xba, 0x12, 0x06, 0xfe, 0x11, 0x7d, 0xd1, 0xca, 0xdd, 0xcc, 0x15, 0x10, 0xed, + 0x05, 0xb8, 0xad, 0xbf, 0x16, 0x58, 0x2b, 0xed, 0x21, 0x1b, 0xf4, 0x27, 0xe7, + 0x00, 0xe0, 0x5f, 0x12, 0xc0, 0xc1, 0x0f, 0x45, 0xfa, 0xd1, 0x44, 0xed, 0x16, + 0x22, 0x02, 0xdc, 0xca, 0x4a, 0xca, 0xfb, 0xe7, 0xd9, 0xea, 0x2b, 0x12, 0xbb, + 0xcf, 0x21, 0xca, 0x1c, 0x1d, 0x39, 0xeb, 0xc8, 0xab, 0x21, 0xd5, 0xd0, 0x03, + 0xca, 0xf6, 0xcb, 0xe4, 0xf0, 0x3e, 0xd9, 0x2d, 0x03, 0x16, 0xfb, 0xfe, 0x08, + 0xeb, 0x36, 0x12, 0x16, 0x23, 0x17, 0x1d, 0x34, 0xe4, 0xfa, 0x19, 0x1a, 0xb1, + 0xfb, 0xea, 0x2b, 0x9a, 0xfe, 0xfb, 0x3d, 0x40, 0xd1, 0x5d, 0x5b, 0xe4, 0x2d, + 0xac, 0xd0, 0xc7, 0xfd, 0xca, 0x11, 0x7e, 0x2c, 0x01, 0xf9, 0xd2, 0x2b, 0xe4, + 0x7f, 0x20, 0xdd, 0xfc, 0xe6, 0x0c, 0x8c, 0x17, 0xff, 0xf5, 0x50, 0x23, 0x10, + 0xc7, 0x0f, 0x09, 0x20, 0xb1, 0xfe, 0xfa, 0xf9, 0x3e, 0x0a, 0xf6, 0xfa, 0x36, + 0xe2, 0xca, 0xf5, 0x26, 0x97, 0x3f, 0x0a, 0xcb, 0x17, 0xf6, 0x05, 0xdd, 0x41, + 0x00, 0xdc, 0xcc, 0x28, 0xed, 0xe7, 0xcd, 0xf4, 0xe9, 0xba, 0x81, 0xcb, 0xc1, + 0xc1, 0xfc, 0xde, 0x18, 0x11, 0xfc, 0xe8, 0x02, 0xf4, 0x05, 0x22, 0xd0, 0x06, + 0x0f, 0xed, 0x2c, 0x33, 0xfc, 0xf4, 0xf7, 0xd3, 0xf5, 0xb1, 0xcf, 0x01, 0xe3, + 0xf8, 0x05, 0xc9, 0xe7, 0xfb, 0x47, 0xad, 0xfc, 0x08, 0x0e, 0xb2, 0x20, 0xcb, + 0x16, 0xf9, 0x1e, 0x22, 0xec, 0xe4, 0x46, 0xf9, 0xf2, 0x5a, 0x01, 0xc7, 0xeb, + 0xfa, 0x25, 0xf2, 0xf5, 0x06, 0x26, 0xdc, 0x09, 0x05, 0xe1, 0xbd, 0xdc, 0x15, + 0x08, 0xa9, 0x10, 0x1d, 0xf9, 0x02, 0x28, 0xe1, 0xf9, 0x19, 0x0e, 0xf0, 0xed, + 0xe1, 0xef, 0x20, 0x44, 0x43, 0xd1, 0xf1, 0xfd, 0xc0, 0x1e, 0xda, 0x95, 0xd4, + 0xe8, 0x49, 0xed, 0xb3, 0xee, 0x2f, 0xc8, 0x03, 0xe9, 0x0c, 0x14, 0xde, 0xd9, + 0x2a, 0x75, 0xe6, 0xfd, 0x0d, 0x2e, 0x47, 0xd1, 0x33, 0x16, 0x12, 0xd0, 0x3a, + 0x7e, 0x12, 0xc5, 0xc4, 0xf8, 0xa0, 0xc1, 0x3e, 0x1e, 0xe6, 0x99, 0x3d, 0x06, + 0x00, 0xf5, 0xe8, 0xea, 0x73, 0xe3, 0x18, 0x07, 0x63, 0x26, 0xf2, 0xcf, 0xcc, + 0x0a, 0x1d, 0xcc, 0x35, 0x54, 0xd6, 0x3d, 0xcc, 0x44, 0xd2, 0xf2, 0x38, 0x09, + 0x07, 0xc2, 0x7f, 0xd3, 0xfb, 0x31, 0xfa, 0xdb, 0x07, 0xf8, 0x43, 0xab, 0x63, + 0x0f, 0xd5, 0x01, 0xff, 0xfb, 0xdb, 0x08, 0xfa, 0x1b, 0x38, 0xf9, 0x0f, 0x0c, + 0x40, 0xe6, 0xa5, 0xe0, 0xc5, 0x4f, 0x20, 0xe8, 0x3c, 0x2d, 0x21, 0xe6, 0xd9, + 0xef, 0x0a, 0xd1, 0xfd, 0xc7, 0xb6, 0x08, 0xb9, 0x95, 0x39, 0x60, 0x14, 0x0f, + 0xee, 0xdd, 0x12, 0x47, 0xe7, 0xaf, 0xdb, 0x10, 0xf9, 0x5d, 0x2b, 0x16, 0x0f, + 0xf8, 0x29, 0xda, 0x12, 0x00, 0x0f, 0xdf, 0xe0, 0x00, 0x0e, 0xdb, 0x0a, 0xc1, + 0x7f, 0x07, 0xf7, 0x47, 0xa1, 0xf5, 0xcc, 0xd9, 0xf8, 0x2b, 0xed, 0xf8, 0x1b, + 0xa4, 0xd2, 0xd2, 0x6b, 0x38, 0x26, 0x49, 0xee, 0x2e, 0x21, 0x0f, 0xee, 0xfe, + 0xe9, 0x40, 0xd5, 0xee, 0xe8, 0xd6, 0x3a, 0xbc, 0xd4, 0x1c, 0xf9, 0x10, 0xfa, + 0xde, 0xd3, 0x11, 0x2a, 0x00, 0x2c, 0x00, 0x25, 0xe1, 0x2d, 0xff, 0x1a, 0xfa, + 0x23, 0xf0, 0x26, 0xd7, 0xfd, 0xe7, 0x21, 0x3e, 0x02, 0xfa, 0x05, 0x08, 0x63, + 0x15, 0xc4, 0xcd, 0x1c, 0x34, 0xd3, 0x1d, 0xee, 0xea, 0x05, 0xa7, 0xed, 0xf8, + 0xed, 0xe9, 0xd7, 0xd7, 0x00, 0x0f, 0xcd, 0xdd, 0xfc, 0xd1, 0x09, 0xcf, 0xfe, + 0x3c, 0x00, 0xf5, 0xee, 0xf3, 0x04, 0x00, 0x44, 0xcf, 0x24, 0xe8, 0xf0, 0xcc, + 0xe1, 0x08, 0x14, 0x33, 0x18, 0xf0, 0x0b, 0x48, 0x64, 0xed, 0x0c, 0x2e, 0xe1, + 0xce, 0x27, 0xef, 0xee, 0x41, 0xf7, 0xba, 0xce, 0xce, 0xfa, 0x1d, 0xda, 0x90, + 0x11, 0xb5, 0xfb, 0xf7, 0xbd, 0xfa, 0xfb, 0x1b, 0x2d, 0xc1, 0xfa, 0x4c, 0x7f, + 0x0e, 0x9f, 0xc0, 0xce, 0x0f, 0xe9, 0xcb, 0xd1, 0x2f, 0x28, 0x03, 0xc9, 0xd5, + 0x39, 0x00, 0xec, 0xfa, 0x17, 0xef, 0xcf, 0xd9, 0xee, 0x1c, 0x65, 0xf8, 0x38, + 0x02, 0xfa, 0x2f, 0x1c, 0x23, 0xed, 0x3a, 0xde, 0x0b, 0x36, 0xf3, 0x50, 0x04, + 0x05, 0x13, 0xe5, 0x13, 0xec, 0xcd, 0xc8, 0xef, 0x09, 0xa9, 0xfd, 0x00, 0x0c, + 0x26, 0xe9, 0x04, 0x98, 0x05, 0xdf, 0x25, 0x38, 0x2f, 0xfb, 0x28, 0x90, 0x11, + 0x23, 0xbf, 0xc7, 0x0d, 0xe2, 0xce, 0x09, 0x21, 0x29, 0xe8, 0xeb, 0xc1, 0x15, + 0x40, 0xd3, 0x08, 0x12, 0xe2, 0x26, 0x36, 0x15, 0xab, 0x0b, 0x70, 0x05, 0x3d, + 0xf9, 0xcb, 0x52, 0xf5, 0xfb, 0xab, 0xdf, 0x0b, 0x2b, 0xd5, 0x1a, 0xde, 0x31, + 0xaa, 0x5e, 0x33, 0x01, 0x29, 0x0c, 0xad, 0x00, 0x07, 0x3c, 0x14, 0xd2, 0x22, + 0x07, 0xd6, 0x01, 0xed, 0xef, 0x26, 0x13, 0xf8, 0xe2, 0x28, 0xd8, 0xe8, 0x0f, + 0xf9, 0x34, 0xc2, 0xbc, 0xf3, 0xb5, 0x29, 0xe1, 0xd6, 0x39, 0x24, 0x3c, 0xff, + 0x09, 0x29, 0xc7, 0x25, 0x10, 0x08, 0xfe, 0x12, 0x02, 0xf0, 0x3e, 0xd5, 0x29, + 0x10, 0xb4, 0xe3, 0xda, 0xe8, 0x4a, 0xeb, 0x21, 0x1a, 0xe9, 0xfa, 0x3b, 0xe0, + 0xd1, 0xf2, 0xd5, 0x00, 0xc0, 0x22, 0x0d, 0xe2, 0x16, 0xe3, 0xe0, 0xa9, 0x03, + 0x7f, 0x02, 0x1d, 0x1d, 0xc7, 0x1b, 0x0c, 0x2d, 0xda, 0xf3, 0xde, 0xf8, 0x50, + 0x0e, 0xea, 0x0a, 0xb1, 0x15, 0x25, 0xdf, 0xff, 0x14, 0x03, 0xfc, 0xa3, 0xf7, + 0xd5, 0x3e, 0xa1, 0xc6, 0xe8, 0x56, 0xf0, 0xde, 0xd7, 0xe5, 0xe9, 0x1b, 0x27, + 0x17, 0x40, 0xf9, 0xd6, 0xde, 0x47, 0x4a, 0xd2, 0x1b, 0x15, 0xe9, 0xd4, 0x15, + 0x1b, 0xfa, 0x0a, 0xea, 0xe9, 0xfb, 0xd5, 0xd5, 0xcf, 0xf5, 0x36, 0xfb, 0x3a, + 0xf6, 0xf8, 0xf1, 0xec, 0x05, 0xe9, 0xf2, 0xfa, 0x14, 0xba, 0xec, 0xeb, 0x7f, + 0x4a, 0xfe, 0x16, 0x46, 0xd4, 0x09, 0xfe, 0xda, 0x08, 0xf7, 0xf1, 0x19, 0x38, + 0xf7, 0x33, 0xdf, 0xd7, 0x1b, 0x15, 0x28, 0xe7, 0x1b, 0xed, 0xeb, 0xed, 0x20, + 0x1a, 0xc0, 0x4c, 0xf7, 0x45, 0x59, 0xdc, 0x02, 0xcb, 0x07, 0x42, 0xd7, 0xd1, + 0xf8, 0xfc, 0x27, 0xea, 0x0d, 0xd9, 0xd3, 0xf1, 0xcc, 0x36, 0x10, 0x49, 0x29, + 0x14, 0x06, 0x14, 0xae, 0x16, 0x35, 0xc5, 0xf9, 0x02, 0x16, 0xde, 0xd7, 0x10, + 0x41, 0xbc, 0x2a, 0xfa, 0x1b, 0xc7, 0x13, 0xc9, 0x15, 0x2e, 0xe3, 0x0f, 0x2b, + 0xc3, 0xc0, 0x2a, 0xf3, 0x0e, 0x00, 0xd7, 0x24, 0x0d, 0x2f, 0xc8, 0xc8, 0xd4, + 0x14, 0x66, 0xc5, 0xd0, 0xd9, 0xe4, 0x3e, 0x8f, 0xb5, 0xe2, 0x27, 0x04, 0x3d, + 0xe4, 0xe4, 0x58, 0x28, 0xfa, 0xe8, 0xc6, 0x20, 0xf0, 0xf3, 0xfd, 0x12, 0x1a, + 0x09, 0xd0, 0xe1, 0xcb, 0xf2, 0xce, 0xd7, 0xa6, 0x18, 0x6c, 0x2e, 0x35, 0x4c, + 0x24, 0x48, 0xe3, 0x2b, 0xfe, 0xde, 0x18, 0xf6, 0xf0, 0x14, 0x27, 0xb9, 0xe2, + 0xc8, 0x08, 0xd9, 0x03, 0xf9, 0xcd, 0x30, 0x56, 0x1c, 0x24, 0x0a, 0xd9, 0xca, + 0xe2, 0xff, 0x04, 0xcb, 0x04, 0x19, 0x05, 0x35, 0xcf, 0x54, 0x17, 0x28, 0x04, + 0x00, 0x25, 0x08, 0xe2, 0xd3, 0x33, 0xc8, 0xde, 0xb4, 0x37, 0x0d, 0xd9, 0xf8, + 0xdf, 0x14, 0x81, 0x52, 0x36, 0x03, 0xdb, 0x12, 0x1f, 0xfe, 0x4a, 0x0c, 0xfd, + 0xe2, 0xec, 0xda, 0xfd, 0x21, 0x12, 0xf4, 0xe5, 0xc8, 0x0b, 0x12, 0x41, 0xae, + 0xe6, 0xfb, 0xee, 0x1c, 0xef, 0x04, 0x41, 0x11, 0xf0, 0x11, 0xe4, 0xdb, 0x21, + 0x1f, 0x07, 0xcf, 0x0c, 0x27, 0x1e, 0x1a, 0xde, 0xee, 0xcf, 0x24, 0x1b, 0x03, + 0xd9, 0xee, 0x06, 0xd6, 0xeb, 0xd4, 0xaa, 0x1a, 0xe4, 0x0a, 0x37, 0x07, 0x40, + 0xb7, 0xa3, 0x15, 0xe2, 0xc8, 0xd4, 0x11, 0x41, 0xff, 0x20, 0x3f, 0x4d, 0x31, + 0xbd, 0x14, 0xbb, 0x09, 0xfb, 0x3a, 0x40, 0xd1, 0x00, 0xed, 0xc5, 0xe6, 0x30, + 0xdb, 0x2f, 0xb1, 0x17, 0xdc, 0x21, 0x8d, 0xf2, 0x68, 0xd4, 0x27, 0xe7, 0xc8, + 0xbc, 0x08, 0xc4, 0xf6, 0xca, 0xd3, 0xcc, 0x23, 0xfc, 0x46, 0x3c, 0x52, 0xf6, + 0x14, 0x2f, 0xda, 0xf2, 0x18, 0xee, 0x42, 0xc5, 0xff, 0x09, 0xee, 0x1c, 0xf4, + 0xb4, 0xf7, 0x07, 0x45, 0xab, 0x1a, 0xd7, 0x9f, 0x20, 0x01, 0xbe, 0x0a, 0xbe, + 0xff, 0xf6, 0x1b, 0xef, 0x10, 0xce, 0xfe, 0xf4, 0x60, 0x2d, 0xd8, 0x14, 0x1b, + 0x26, 0x7f, 0x4e, 0xe2, 0xd7, 0xfb, 0xde, 0xd5, 0xe6, 0x32, 0xe8, 0x0a, 0x32, + 0xe4, 0xf8, 0x33, 0x2d, 0x32, 0x1b, 0x3a, 0xfa, 0x56, 0x18, 0x0e, 0xda, 0x2e, + 0xed, 0x81, 0x08, 0xe5, 0x32, 0xf5, 0xfd, 0xe4, 0xf7, 0xde, 0x00, 0x29, 0x05, + 0x34, 0x47, 0xc5, 0xdc, 0xd1, 0xe5, 0x75, 0x24, 0xc0, 0xda, 0xe5, 0xde, 0x19, + 0xfe, 0x19, 0x07, 0x61, 0xe5, 0xf7, 0xf9, 0x31, 0x0f, 0x06, 0xdf, 0x50, 0xdf, + 0x09, 0x10, 0x19, 0xf1, 0xde, 0x34, 0xc1, 0x7a, 0xfd, 0xcb, 0xda, 0xdf, 0xb6, + 0xa9, 0xf4, 0x37, 0xf2, 0x1d, 0xaf, 0x17, 0x16, 0x03, 0xf2, 0xc7, 0xd4, 0xd1, + 0x5d, 0x08, 0xc7, 0xb9, 0xf7, 0x33, 0x26, 0xf5, 0xd3, 0xf5, 0xce, 0xcb, 0x17, + 0x1e, 0x0e, 0xa2, 0xfe, 0xf7, 0x18, 0xfe, 0x68, 0x31, 0x67, 0xc4, 0x23, 0xc7, + 0x2b, 0x9f, 0x13, 0x34, 0xdc, 0x30, 0xcf, 0xea, 0xd3, 0xfb, 0x1a, 0xf9, 0x62, + 0x12, 0x15, 0xdf, 0x12, 0x2b, 0xcb, 0x0a, 0xee, 0x9e, 0xc6, 0xe6, 0x52, 0xf6, + 0x1b, 0xb3, 0x9c, 0x46, 0xf3, 0x29, 0x40, 0x18, 0xc7, 0xb5, 0x48, 0x22, 0xf0, + 0xae, 0xbf, 0xda, 0xfe, 0xbe, 0x36, 0xef, 0x01, 0xfd, 0xcf, 0xc0, 0x21, 0x52, + 0xf8, 0xf9, 0xdc, 0x98, 0xec, 0xf8, 0x08, 0x54, 0x3a, 0xf5, 0xc2, 0xea, 0x0d, + 0x03, 0xbc, 0xd2, 0xa6, 0x24, 0x7d, 0x4b, 0x01, 0xc9, 0x06, 0x10, 0x0a, 0xb6, + 0xf8, 0x12, 0x4c, 0xf5, 0xcc, 0xf4, 0x3a, 0xdf, 0xf8, 0xbf, 0x14, 0xdd, 0xbb, + 0xab, 0xea, 0xe0, 0x37, 0xa8, 0x7b, 0x0a, 0xea, 0x3c, 0x8c, 0x09, 0xf8, 0xe8, + 0xfc, 0xf1, 0x0d, 0x9d, 0x25, 0x1f, 0xf9, 0x16, 0xb2, 0xbb, 0x03, 0x07, 0xed, + 0xe0, 0xff, 0xbe, 0xab, 0xdc, 0xdd, 0x36, 0x56, 0xc3, 0x32, 0xe3, 0x2b, 0x81, + 0xfa, 0x68, 0xda, 0xd8, 0x55, 0x08, 0x0a, 0x05, 0x0a, 0x16, 0x01, 0xf9, 0xde, + 0xa5, 0x21, 0x38, 0xcf, 0x8e, 0x3d, 0xcd, 0xe3, 0xdd, 0xb4, 0x21, 0x19, 0xe7, + 0x2c, 0xa3, 0x0c, 0xca, 0xe4, 0xfd, 0x3d, 0xdd, 0xf5, 0xe8, 0x30, 0x06, 0x1e, + 0xab, 0xf0, 0xef, 0xda, 0x02, 0xe1, 0xe7, 0xcf, 0xeb, 0xfc, 0x1d, 0x16, 0x15, + 0x27, 0x06, 0xe3, 0x13, 0xe3, 0xee, 0x03, 0xdd, 0x10, 0x09, 0x1e, 0x02, 0xf8, + 0xf7, 0xd5, 0xe7, 0xd7, 0x01, 0xd9, 0xdd, 0x05, 0x28, 0xfb, 0x08, 0x01, 0x07, + 0xff, 0xf7, 0xca, 0x11, 0x30, 0x06, 0x11, 0xf6, 0x19, 0x00, 0x07, 0xe0, 0xf6, + 0xf3, 0xf7, 0x0e, 0x19, 0xc9, 0x08, 0xfd, 0xe2, 0x0a, 0x15, 0x01, 0x1f, 0x17, + 0xf9, 0xec, 0x46, 0xf7, 0xe6, 0xd5, 0xe3, 0x33, 0x0e, 0x0b, 0xf1, 0xfe, 0xe7, + 0x7f, 0xe8, 0xee, 0xe8, 0x1d, 0x11, 0xdd, 0xfd, 0x16, 0xfc, 0xe0, 0x07, 0xee, + 0x1f, 0x15, 0x01, 0x42, 0xd6, 0xe9, 0x0a, 0xeb, 0xea, 0xd2, 0xe1, 0xe1, 0x27, + 0xd4, 0x15, 0x23, 0x19, 0x03, 0xf2, 0xe9, 0xfd, 0xef, 0x03, 0x07, 0xf2, 0x11, + 0x06, 0xf9, 0xf3, 0x20, 0x07, 0x02, 0x5b, 0xf0, 0xd6, 0x3b, 0xf3, 0xf0, 0xcc, + 0x1e, 0xbf, 0xcb, 0x21, 0x12, 0xe9, 0x39, 0xea, 0xcd, 0xd6, 0x09, 0x43, 0x41, + 0x25, 0x0f, 0x35, 0x38, 0xf5, 0x26, 0x3d, 0x15, 0x02, 0x0b, 0xd8, 0x13, 0x1d, + 0x29, 0x0a, 0x03, 0xf6, 0x04, 0x36, 0x1f, 0x66, 0x1a, 0x41, 0x01, 0xe2, 0x01, + 0xf5, 0x09, 0xc9, 0xcf, 0x1a, 0x58, 0x4a, 0x1d, 0xf2, 0x69, 0xf7, 0x01, 0x3b, + 0x32, 0xda, 0xde, 0x19, 0xc3, 0x11, 0x05, 0x70, 0xb9, 0x07, 0x2e, 0xc0, 0xce, + 0x21, 0x2b, 0xfb, 0x16, 0xd3, 0xb8, 0xdc, 0xed, 0x3a, 0x20, 0xd8, 0xc6, 0x20, + 0xe6, 0xcd, 0x26, 0x2a, 0xd2, 0xf9, 0xeb, 0x2c, 0x52, 0xa9, 0x39, 0x11, 0x46, + 0xa1, 0x3f, 0x2e, 0xf6, 0x96, 0xe6, 0xcc, 0xca, 0xff, 0x2f, 0x1b, 0x81, 0x15, + 0x4f, 0x1e, 0x7d, 0xd4, 0x22, 0x02, 0xf2, 0xe3, 0xba, 0xf5, 0xde, 0xeb, 0x04, + 0x9c, 0xd7, 0x29, 0xd9, 0x43, 0xe6, 0x7f, 0x19, 0xec, 0x31, 0x40, 0xeb, 0x14, + 0x04, 0xf3, 0x0d, 0x04, 0x18, 0x15, 0xe5, 0xfa, 0xfc, 0xc7, 0xf8, 0x2a, 0xed, + 0x0a, 0xfa, 0x0c, 0xf1, 0xd5, 0x31, 0xdd, 0xe3, 0xf1, 0xe2, 0xec, 0x54, 0x00, + 0xd2, 0xf1, 0x28, 0x14, 0x10, 0xfb, 0xff, 0xeb, 0x08, 0xe1, 0x17, 0x22, 0x28, + 0xfe, 0x0d, 0xf7, 0x04, 0x16, 0x06, 0x12, 0xfe, 0xb4, 0xf4, 0x1e, 0xe0, 0xf3, + 0xec, 0x1c, 0xd2, 0x0c, 0x09, 0x39, 0x1b, 0xe2, 0x2e, 0xfb, 0xba, 0x00, 0x28, + 0xf1, 0x10, 0x08, 0x2c, 0xd7, 0x05, 0x20, 0xe7, 0xf9, 0x07, 0x24, 0xfd, 0xf1, + 0xe7, 0x1c, 0x04, 0xd5, 0xc8, 0xec, 0x2f, 0xfb, 0xfc, 0x0c, 0xe4, 0xec, 0x2a, + 0x2a, 0xc9, 0xf7, 0xff, 0xe3, 0xd3, 0xf2, 0x08, 0xe1, 0x35, 0xe6, 0xe9, 0x03, + 0x04, 0x04, 0x03, 0x0c, 0xce, 0xd0, 0x01, 0x2f, 0x39, 0x13, 0x15, 0x38, 0xfa, + 0xff, 0xf9, 0x20, 0x3b, 0x04, 0xbc, 0xe3, 0xd2, 0xfd, 0x0e, 0x11, 0x19, 0xe1, + 0x11, 0x0c, 0x19, 0xfb, 0xe7, 0xdd, 0x3b, 0xd4, 0xec, 0x31, 0x5f, 0x7f, 0x30, + 0x1c, 0xc2, 0xd7, 0x01, 0xcb, 0xe5, 0xf8, 0x14, 0xd5, 0x42, 0xf8, 0xf9, 0xb8, + 0xff, 0xd7, 0x1a, 0xf9, 0x28, 0xf0, 0x05, 0xe9, 0xdf, 0x0d, 0x0d, 0xce, 0x08, + 0xd7, 0xe2, 0x00, 0x49, 0x18, 0xf4, 0xb6, 0xe9, 0x34, 0x22, 0xf1, 0x10, 0x0e, + 0x1b, 0x28, 0x09, 0x29, 0xda, 0x23, 0x3d, 0xf1, 0x14, 0x12, 0xce, 0xf8, 0x27, + 0x0b, 0x0e, 0xf9, 0x4b, 0x10, 0xde, 0x1a, 0xc3, 0xf8, 0x3a, 0x0d, 0xef, 0x0d, + 0xff, 0x06, 0xb6, 0x02, 0x20, 0x0d, 0xee, 0xd4, 0xcb, 0xf5, 0x11, 0xd2, 0xfa, + 0xd7, 0x08, 0x5c, 0x11, 0xf6, 0x29, 0x0e, 0xec, 0x06, 0xde, 0xd0, 0xc7, 0xe2, + 0xef, 0x54, 0xfa, 0xec, 0xd6, 0x1f, 0xfd, 0xf4, 0xb2, 0x2a, 0x2a, 0x15, 0xfc, + 0x1c, 0x2e, 0x04, 0x1a, 0xb4, 0xd8, 0x03, 0x00, 0x19, 0xec, 0xb7, 0xfd, 0x2c, + 0x93, 0x65, 0xaa, 0xf9, 0x1a, 0x24, 0x37, 0x55, 0x7c, 0xe0, 0x52, 0x1c, 0x0d, + 0xf8, 0x2d, 0xef, 0xef, 0x1b, 0xd4, 0x21, 0x25, 0x16, 0x48, 0xe9, 0xef, 0xf1, + 0xe9, 0x0a, 0x35, 0x64, 0x35, 0xb9, 0x03, 0xe9, 0x0c, 0xab, 0xef, 0x57, 0xf2, + 0xd1, 0x23, 0x6a, 0x46, 0xbc, 0xf2, 0xfa, 0xc5, 0xf1, 0x3b, 0x0f, 0x22, 0xec, + 0xef, 0x1e, 0xfc, 0xe8, 0x94, 0xdf, 0xf5, 0xcb, 0x41, 0xd4, 0xef, 0x1d, 0x81, + 0x15, 0x40, 0x0d, 0x32, 0xf0, 0xa5, 0xe2, 0x17, 0x15, 0xd7, 0x04, 0xfa, 0xfb, + 0x89, 0x3e, 0x4d, 0x4b, 0x1c, 0x44, 0xdf, 0x0c, 0xdd, 0xec, 0x10, 0xf6, 0x2d, + 0xd4, 0xde, 0xfd, 0x16, 0x47, 0xe1, 0xb1, 0x31, 0x0a, 0x47, 0x90, 0xed, 0xd1, + 0xd2, 0xdb, 0xf4, 0xde, 0xea, 0xb2, 0xbc, 0xdc, 0x0f, 0xf0, 0xa9, 0x27, 0x16, + 0x57, 0x1d, 0x11, 0xff, 0x43, 0xcb, 0x22, 0x07, 0x15, 0xf4, 0x43, 0xc7, 0x02, + 0xc9, 0xb2, 0xee, 0x4f, 0xe6, 0x56, 0xbf, 0x02, 0xb9, 0x20, 0xb5, 0xde, 0x3b, + 0xa3, 0x0f, 0xe2, 0xfe, 0x1c, 0xf4, 0x33, 0x52, 0x04, 0xb5, 0x2e, 0x26, 0x88, + 0xc7, 0x10, 0xfc, 0xe5, 0x5c, 0xe6, 0xbc, 0xe9, 0x1c, 0x6b, 0xf2, 0x03, 0xd0, + 0x18, 0xb6, 0x18, 0x0f, 0x00, 0xde, 0xfc, 0x02, 0x6c, 0xca, 0xf1, 0xf8, 0x4a, + 0x3f, 0xeb, 0xaf, 0x14, 0xbe, 0xe1, 0xcc, 0x50, 0x15, 0x30, 0xeb, 0x06, 0xc2, + 0xfb, 0xce, 0xf9, 0x25, 0xe4, 0x1f, 0x1d, 0x08, 0x0e, 0xeb, 0xd9, 0xad, 0x19, + 0x0e, 0x02, 0xd9, 0x03, 0xf2, 0xfb, 0x14, 0xd9, 0xe2, 0xc6, 0x07, 0x81, 0xe4, + 0x1f, 0xcf, 0xe7, 0x3c, 0xb8, 0xda, 0x02, 0x61, 0x0d, 0xfe, 0x0c, 0x41, 0xc7, + 0xed, 0xf1, 0x2a, 0xce, 0x08, 0x2c, 0xe4, 0x28, 0xe9, 0x06, 0xa0, 0x28, 0xcc, + 0x0f, 0x14, 0xea, 0x15, 0x03, 0xee, 0xb3, 0x0a, 0xe7, 0x04, 0x38, 0xeb, 0xe8, + 0x28, 0x09, 0xe7, 0x13, 0x5b, 0x0f, 0x8d, 0x01, 0xd6, 0xcd, 0xed, 0xeb, 0xf7, + 0xf3, 0x00, 0x0a, 0x21, 0x4b, 0x19, 0xb6, 0xb0, 0x01, 0xdc, 0xe6, 0x43, 0xc8, + 0xce, 0x06, 0xb8, 0x3f, 0x31, 0xe0, 0xea, 0xcf, 0xf9, 0x56, 0xec, 0xc5, 0x81, + 0x32, 0xbd, 0xc3, 0xf9, 0x22, 0x53, 0x22, 0x00, 0xf2, 0x3b, 0xef, 0x1a, 0x45, + 0x9e, 0x60, 0x09, 0x42, 0xdd, 0x2a, 0x32, 0xf3, 0x3b, 0xfd, 0x2d, 0x08, 0xde, + 0x1d, 0x41, 0xdc, 0xd7, 0xdd, 0xe1, 0xf6, 0x09, 0xc3, 0x17, 0xd6, 0x69, 0x48, + 0xb6, 0xfa, 0xe4, 0x1a, 0xfb, 0x5b, 0xfc, 0xba, 0x08, 0x01, 0xec, 0xd6, 0xe0, + 0x26, 0xd2, 0xf5, 0x0c, 0xf6, 0x1c, 0xba, 0xdb, 0xf6, 0x21, 0xf9, 0x0d, 0x12, + 0x33, 0xe8, 0x04, 0xc8, 0xc2, 0x25, 0x0c, 0x18, 0xf6, 0xae, 0xd9, 0xef, 0xb7, + 0xbf, 0x3a, 0x20, 0x0a, 0x0a, 0x48, 0x05, 0x06, 0xcb, 0x0b, 0xb3, 0x24, 0xe2, + 0x51, 0xce, 0x17, 0xfd, 0xb3, 0x2d, 0x29, 0xf2, 0x04, 0x09, 0x61, 0xcc, 0xf1, + 0xb0, 0x2e, 0x4f, 0x19, 0x81, 0x2f, 0xfe, 0x3e, 0xae, 0xca, 0x11, 0x15, 0x79, + 0xd9, 0xb2, 0xf2, 0xe0, 0xed, 0x42, 0xaf, 0xba, 0x0a, 0xee, 0x2c, 0xd1, 0xee, + 0xf1, 0xbc, 0xe8, 0xd7, 0xd5, 0xfd, 0x02, 0xfd, 0x16, 0x46, 0xcf, 0xc5, 0xe8, + 0x37, 0x2d, 0xf5, 0x23, 0xe5, 0xf1, 0xc6, 0x17, 0x23, 0x3b, 0x55, 0xe6, 0x0f, + 0xeb, 0x5f, 0x07, 0x1f, 0x20, 0x27, 0x18, 0xd6, 0x01, 0xfc, 0x58, 0x02, 0xf1, + 0xe5, 0xe9, 0x13, 0x23, 0x16, 0xa9, 0xe7, 0x16, 0xe8, 0xc0, 0xfd, 0x48, 0x9a, + 0xfc, 0x15, 0xfa, 0xde, 0xce, 0x05, 0xb6, 0x20, 0xb0, 0xf2, 0x17, 0xf8, 0xd9, + 0x0a, 0x15, 0x34, 0x20, 0xcb, 0x05, 0x0d, 0x13, 0xe4, 0xed, 0xf2, 0xeb, 0xd2, + 0xff, 0x21, 0x0a, 0x24, 0x19, 0xc5, 0xff, 0xf5, 0xd8, 0xfc, 0xe4, 0xe9, 0xdd, + 0xf0, 0x22, 0x27, 0xf9, 0xda, 0xe7, 0xbc, 0x26, 0xfd, 0xdc, 0x0a, 0xc7, 0xf2, + 0xf8, 0x44, 0xd9, 0x57, 0x2a, 0xfd, 0x02, 0xf9, 0xf4, 0x28, 0x0e, 0x29, 0x39, + 0xe4, 0x7f, 0x62, 0xd6, 0x14, 0xd4, 0xda, 0x17, 0xdd, 0x3a, 0x1e, 0xcd, 0xea, + 0xfe, 0xd4, 0x00, 0xf1, 0xf9, 0xf2, 0x13, 0xe6, 0xf5, 0xe3, 0x7e, 0xfc, 0x18, + 0xbd, 0x10, 0x11, 0xde, 0x0f, 0x01, 0xd6, 0xcc, 0xbc, 0x1a, 0xe7, 0xdb, 0x0c, + 0x01, 0x08, 0x3c, 0x07, 0xe2, 0xfe, 0xc9, 0xd1, 0x04, 0xef, 0x34, 0xfe, 0x0b, + 0x20, 0x2c, 0x41, 0x66, 0x03, 0xe3, 0x24, 0xfe, 0xfc, 0x02, 0x44, 0xeb, 0x08, + 0xf3, 0x62, 0xfe, 0xfe, 0xf5, 0x28, 0xf8, 0x05, 0x08, 0xfe, 0xf4, 0x00, 0x02, + 0x37, 0xdc, 0xe9, 0x0c, 0xfd, 0x81, 0x22, 0xfa, 0xde, 0x2e, 0x05, 0xff, 0xfc, + 0x26, 0xf0, 0xf2, 0xcf, 0xf1, 0xf0, 0xdd, 0xd5, 0xee, 0x0d, 0xf3, 0xe6, 0xe1, + 0xfd, 0x06, 0x21, 0xdb, 0xf9, 0x32, 0xff, 0x2b, 0x15, 0xfe, 0x05, 0x19, 0x03, + 0xf3, 0x45, 0x02, 0x0a, 0x0f, 0x02, 0xe5, 0xfc, 0xd7, 0x03, 0xf1, 0xc9, 0x34, + 0xf2, 0x0d, 0x38, 0xf2, 0x06, 0x28, 0x2e, 0xc5, 0xc8, 0xf1, 0x0c, 0xd8, 0xe1, + 0x0b, 0xd3, 0xe7, 0xe7, 0x0d, 0xfb, 0xe8, 0x40, 0xf4, 0x14, 0x13, 0x13, 0xd0, + 0x01, 0xff, 0x13, 0x18, 0xf9, 0xf9, 0x58, 0xeb, 0xcf, 0xd8, 0x2b, 0xd4, 0xcb, + 0xe7, 0x26, 0x0b, 0xf0, 0x0a, 0x20, 0xf0, 0x11, 0xed, 0xd9, 0xe8, 0x07, 0xd3, + 0xd0, 0xed, 0xfd, 0x0b, 0x33, 0xf2, 0x03, 0x0f, 0x0e, 0x0a, 0x22, 0xea, 0xf7, + 0x24, 0xe0, 0x0f, 0x2c, 0xc2, 0x0e, 0x2b, 0xb9, 0x10, 0x16, 0xea, 0x04, 0x0b, + 0xe4, 0xf4, 0xcb, 0x81, 0xf3, 0x0b, 0x13, 0x03, 0x13, 0x31, 0xd5, 0xde, 0xf9, + 0x01, 0x00, 0xf3, 0xfd, 0xd3, 0xfd, 0x16, 0xcd, 0xef, 0x34, 0xb8, 0x31, 0x06, + 0x1a, 0x1a, 0xdf, 0x2c, 0x11, 0x25, 0xfb, 0x4a, 0x3e, 0xf5, 0xed, 0xed, 0x1b, + 0x25, 0xf7, 0xfd, 0xed, 0xf7, 0xe5, 0xfa, 0xea, 0xef, 0x24, 0x12, 0x04, 0xeb, + 0x08, 0x1e, 0xd8, 0xd9, 0x1e, 0xfc, 0xf6, 0xde, 0xe6, 0xe1, 0x10, 0xfe, 0x48, + 0x0f, 0x0c, 0xfd, 0xdd, 0x2e, 0x1a, 0xca, 0xfe, 0x33, 0x0a, 0xe2, 0x23, 0xcf, + 0xd1, 0x15, 0xed, 0x10, 0x2b, 0x05, 0xd7, 0x00, 0xf2, 0x18, 0xce, 0xe9, 0x0c, + 0x01, 0xf4, 0xed, 0x31, 0x21, 0x01, 0x09, 0x29, 0x06, 0x09, 0x3a, 0xdc, 0x55, + 0x10, 0xf4, 0x14, 0xfc, 0xa7, 0xf8, 0xb7, 0x33, 0xec, 0x23, 0xd5, 0xf6, 0xdc, + 0x09, 0xe0, 0x2c, 0x20, 0xd9, 0xb6, 0x36, 0x0a, 0x0a, 0x33, 0xef, 0x09, 0x1f, + 0xeb, 0xf6, 0x0a, 0x2d, 0xd5, 0xe1, 0xee, 0x17, 0xc0, 0xd6, 0x08, 0x44, 0xfd, + 0xd6, 0x17, 0x31, 0x09, 0xfc, 0x39, 0x48, 0x3b, 0x32, 0x0f, 0x30, 0xd9, 0xb1, + 0x6a, 0x03, 0x08, 0xf7, 0x11, 0xce, 0x2b, 0x0e, 0x2a, 0xe7, 0x34, 0xf8, 0x41, + 0x50, 0xed, 0x03, 0x25, 0x14, 0x38, 0xcd, 0xfe, 0xfe, 0xeb, 0x1a, 0x0d, 0x07, + 0x25, 0xcf, 0x2a, 0xe5, 0xfb, 0xe7, 0x60, 0xe6, 0x05, 0xf6, 0xed, 0xf1, 0xec, + 0x65, 0x01, 0x43, 0xf8, 0x33, 0x1a, 0xef, 0xf3, 0x16, 0xf5, 0xf8, 0xde, 0x19, + 0x35, 0xc8, 0xdf, 0xfe, 0xc5, 0x0d, 0xa7, 0x0f, 0x22, 0xef, 0x02, 0x18, 0xb5, + 0x0e, 0x18, 0x13, 0x63, 0x16, 0x57, 0xfc, 0xbf, 0xc2, 0x09, 0xea, 0xda, 0xf4, + 0xf8, 0xce, 0x1b, 0x56, 0xd0, 0x1d, 0xc3, 0x0b, 0xab, 0x20, 0x05, 0xf1, 0xcc, + 0xea, 0xa6, 0xec, 0xfa, 0xf0, 0x26, 0x06, 0x0b, 0x81, 0xe5, 0x21, 0xd7, 0x10, + 0xf3, 0xff, 0xf3, 0xf1, 0xed, 0x1c, 0x09, 0x18, 0x18, 0x0a, 0xf9, 0xee, 0xbd, + 0x6f, 0x11, 0xdc, 0xac, 0xd0, 0x24, 0xf0, 0xe8, 0xf1, 0x1a, 0xc8, 0xea, 0xd1, + 0x29, 0x23, 0xc2, 0xf0, 0x21, 0xb8, 0xe7, 0xfe, 0xec, 0x2c, 0xdb, 0x07, 0x13, + 0xca, 0x2a, 0xd3, 0xe6, 0x14, 0x20, 0xf4, 0xe2, 0x13, 0x02, 0x32, 0xff, 0x0d, + 0x02, 0x0b, 0x0f, 0x0c, 0x0e, 0x17, 0xf9, 0x21, 0x1b, 0xf2, 0x08, 0xb5, 0xfc, + 0xf5, 0xe6, 0xc4, 0xf1, 0xe9, 0x0d, 0x0b, 0xf7, 0xcf, 0xc9, 0x13, 0xf8, 0x33, + 0x0a, 0x02, 0x24, 0xc3, 0xf6, 0x0d, 0xc2, 0xdb, 0xf8, 0x45, 0xfe, 0x14, 0xf3, + 0xeb, 0xe1, 0xd3, 0x15, 0x32, 0x0d, 0xd0, 0xde, 0xec, 0x19, 0x14, 0x0b, 0xfe, + 0x0f, 0xf5, 0xe0, 0xea, 0x00, 0x22, 0x17, 0xd3, 0xd2, 0xfb, 0xf1, 0x17, 0x45, + 0x16, 0x19, 0x37, 0x81, 0xea, 0x0b, 0x3a, 0xf1, 0x49, 0x4c, 0xa8, 0x0d, 0x23, + 0xe5, 0x0c, 0xda, 0xea, 0x12, 0xda, 0xe3, 0xcd, 0x7c, 0x0d, 0x53, 0x0c, 0xc5, + 0x93, 0x45, 0xc9, 0x6e, 0x4f, 0xbb, 0xb7, 0xf1, 0x4c, 0xe2, 0xd4, 0xf6, 0xaa, + 0xe3, 0xce, 0xe7, 0x36, 0x98, 0xf2, 0x2d, 0x1e, 0x51, 0x15, 0xd3, 0x19, 0x5d, + 0xdf, 0xa7, 0x0a, 0x00, 0xea, 0xc4, 0x0b, 0x07, 0xe2, 0x45, 0xe9, 0x14, 0xd7, + 0x0b, 0x77, 0xb9, 0x26, 0xfb, 0xe4, 0x4d, 0x26, 0x16, 0x01, 0x8d, 0x49, 0x9e, + 0xf0, 0x00, 0x47, 0x95, 0x01, 0x27, 0xcd, 0xd8, 0x84, 0x09, 0xff, 0xcf, 0x17, + 0x81, 0x15, 0x17, 0xcf, 0xd2, 0x25, 0x31, 0x09, 0xa0, 0x8f, 0x0e, 0x21, 0x91, + 0x00, 0x04, 0xb2, 0x40, 0x1b, 0xea, 0xa6, 0x0d, 0x41, 0x16, 0xd5, 0xe9, 0xff, + 0x76, 0x16, 0x09, 0x1b, 0x02, 0x37, 0x44, 0x48, 0xf9, 0xef, 0xed, 0x2e, 0xe9, + 0x2c, 0x20, 0x17, 0xd5, 0xbe, 0xad, 0x4f, 0xe4, 0xfb, 0xee, 0xbb, 0x04, 0x0c, + 0xda, 0x2b, 0xe7, 0x0c, 0x20, 0x03, 0x2d, 0x01, 0xff, 0xc6, 0x2c, 0x30, 0xb0, + 0x31, 0xe4, 0xe4, 0xd4, 0xf3, 0xe0, 0xce, 0xe7, 0x04, 0x9d, 0x57, 0x0e, 0xf4, + 0xe3, 0x24, 0xf1, 0xe4, 0xef, 0xc4, 0xde, 0x32, 0xea, 0xfa, 0x0d, 0xa7, 0xf4, + 0x15, 0xc8, 0x11, 0xc2, 0x58, 0x2e, 0x8e, 0x28, 0xf2, 0x32, 0xc2, 0xfa, 0x2f, + 0xfa, 0x46, 0xf0, 0x73, 0x09, 0x9a, 0xca, 0x42, 0xaf, 0xa8, 0x18, 0xe5, 0x0f, + 0x05, 0x0d, 0x0c, 0xca, 0x0e, 0xd7, 0x27, 0x05, 0xe9, 0xc6, 0x19, 0x81, 0x0e, + 0xf6, 0xfc, 0xe7, 0x41, 0xe7, 0xd5, 0xe8, 0x0a, 0x10, 0x07, 0xd4, 0x3e, 0x06, + 0xcd, 0xc2, 0x01, 0x2d, 0xcd, 0x5a, 0xb4, 0x36, 0x05, 0x31, 0xd7, 0x10, 0xca, + 0x3c, 0x17, 0x00, 0x38, 0x20, 0xf9, 0xe7, 0xdd, 0xf8, 0x18, 0xad, 0x12, 0xa5, + 0xd4, 0xe2, 0xbf, 0xfa, 0x10, 0xbd, 0x1d, 0xb0, 0x2e, 0x20, 0xd9, 0x0e, 0xee, + 0xfb, 0xa3, 0xcd, 0xc4, 0xec, 0xef, 0xf2, 0xe4, 0x9e, 0xdb, 0xae, 0x0d, 0xff, + 0xec, 0x17, 0xa2, 0x09, 0x1b, 0xfb, 0xdf, 0x29, 0x00, 0xf2, 0xab, 0xe3, 0xdf, + 0xe5, 0xe5, 0x13, 0x73, 0x0f, 0x14, 0xf3, 0xba, 0xde, 0xdc, 0xc0, 0x14, 0x24, + 0x36, 0x2c, 0xbe, 0xe4, 0x11, 0xeb, 0x0e, 0x05, 0xd0, 0xfe, 0x2d, 0xc8, 0xf1, + 0x15, 0x17, 0x05, 0x7f, 0x17, 0xe1, 0xee, 0xfa, 0xf9, 0x22, 0x02, 0xfc, 0x2d, + 0xde, 0x37, 0x07, 0x0d, 0xef, 0x10, 0xdf, 0xfc, 0xc7, 0x42, 0xf4, 0x1d, 0xfe, + 0xfe, 0x04, 0xf9, 0x04, 0x3b, 0xd3, 0xf6, 0x54, 0xd0, 0xe5, 0xef, 0x2a, 0x13, + 0xd7, 0x0a, 0xde, 0xf3, 0x1c, 0x0b, 0x07, 0xae, 0xd7, 0xf4, 0x12, 0xe6, 0x18, + 0xa5, 0x16, 0xe3, 0xc7, 0xf7, 0xfa, 0x23, 0x06, 0x1a, 0x1d, 0xf0, 0x0a, 0x35, + 0x17, 0xef, 0xf6, 0x2f, 0xb1, 0xeb, 0x3a, 0xf6, 0x18, 0xed, 0x22, 0xff, 0xf0, + 0xee, 0x1c, 0xce, 0xdd, 0xe7, 0x1f, 0x0a, 0x0a, 0x23, 0x2e, 0xf2, 0xca, 0xff, + 0xd0, 0xf7, 0xef, 0x43, 0xdd, 0xf7, 0x7f, 0xe2, 0xfe, 0xe7, 0xe0, 0x07, 0xef, + 0xe1, 0xf6, 0x10, 0xef, 0xf2, 0x03, 0x9d, 0xef, 0x07, 0xf1, 0x4f, 0xf8, 0xfe, + 0x03, 0xf2, 0xf8, 0xf8, 0x02, 0xca, 0xaa, 0x53, 0x10, 0x1b, 0xfc, 0x08, 0x22, + 0xcc, 0xc1, 0xcf, 0xff, 0x00, 0xde, 0xea, 0x20, 0xcb, 0xfd, 0x12, 0xf3, 0xee, + 0xd5, 0xd0, 0xff, 0xf6, 0xff, 0x0a, 0xeb, 0xb2, 0xe6, 0x0e, 0xf5, 0x62, 0x02, + 0xff, 0x12, 0xdf, 0x13, 0x0c, 0x0b, 0x0a, 0xe6, 0xdc, 0x0b, 0x35, 0xea, 0x0d, + 0xd5, 0x12, 0xd8, 0xdd, 0x07, 0xf7, 0x23, 0xc5, 0x26, 0xbd, 0x25, 0xe9, 0xee, + 0x09, 0x0d, 0xb5, 0x13, 0xec, 0xc5, 0xe4, 0x03, 0x2a, 0x06, 0x18, 0xd0, 0xfb, + 0xe4, 0xf4, 0x30, 0x1f, 0x0d, 0x00, 0xfd, 0xef, 0xdb, 0x0a, 0x15, 0xe3, 0x18, + 0xfb, 0xed, 0x02, 0x39, 0x1b, 0x71, 0x53, 0xbb, 0xf3, 0x15, 0x1d, 0xd6, 0x3a, + 0x1d, 0x2f, 0x03, 0xd9, 0x1a, 0x0a, 0xf2, 0xe9, 0x1d, 0x2c, 0x4b, 0x10, 0x25, + 0xb4, 0x36, 0xd3, 0x04, 0xcd, 0x05, 0x18, 0xf0, 0xa9, 0xe7, 0xec, 0xdf, 0x0f, + 0xe5, 0x17, 0x1b, 0x4f, 0x21, 0x1a, 0x09, 0x11, 0xde, 0x32, 0xf8, 0xce, 0xfc, + 0x11, 0x00, 0x15, 0xbb, 0xf0, 0x03, 0xfd, 0x3c, 0x0a, 0xf3, 0xe5, 0x36, 0x1d, + 0xff, 0xe7, 0xe9, 0x03, 0xec, 0x32, 0x19, 0xcb, 0xd9, 0xc0, 0xe5, 0x49, 0x33, + 0x1f, 0xfa, 0xfe, 0xc8, 0x48, 0x2a, 0x0f, 0xd8, 0x1b, 0xda, 0xfc, 0xda, 0xfd, + 0xd8, 0x25, 0xc5, 0x2f, 0x01, 0xd0, 0x19, 0x05, 0x0a, 0xcd, 0xff, 0xf4, 0x19, + 0xfe, 0x0f, 0xfa, 0xf3, 0xe1, 0xd6, 0x17, 0xca, 0xe2, 0x7f, 0x23, 0x3e, 0x58, + 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xb0, 0xf8, 0xff, + 0xff, 0x83, 0xe2, 0xff, 0xff, 0xaa, 0x36, 0x00, 0x00, 0x77, 0x0c, 0x00, 0x00, + 0x9a, 0xfd, 0xff, 0xff, 0x9c, 0x0c, 0x00, 0x00, 0x0e, 0xde, 0xff, 0xff, 0xc0, + 0x1b, 0x00, 0x00, 0x7c, 0x04, 0x00, 0x00, 0x2e, 0xc5, 0xff, 0xff, 0xbe, 0x01, + 0x00, 0x00, 0xb1, 0x17, 0x00, 0x00, 0xb5, 0x0f, 0x00, 0x00, 0xf8, 0x48, 0x00, + 0x00, 0xc9, 0xfc, 0xff, 0xff, 0x57, 0xe2, 0xff, 0xff, 0x4b, 0x2a, 0x00, 0x00, + 0x08, 0xc1, 0xff, 0xff, 0xb2, 0x25, 0x00, 0x00, 0xb9, 0x01, 0x00, 0x00, 0xe9, + 0x24, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0xeb, 0xef, 0xff, 0xff, 0x4f, 0x0b, + 0x00, 0x00, 0xcd, 0x27, 0x00, 0x00, 0x3a, 0x07, 0x00, 0x00, 0x77, 0x25, 0x00, + 0x00, 0x61, 0x07, 0x00, 0x00, 0x54, 0x1c, 0x00, 0x00, 0x24, 0xfd, 0xff, 0xff, + 0xd9, 0xe1, 0xff, 0xff, 0xe5, 0xda, 0xff, 0xff, 0x6e, 0xf4, 0xff, 0xff, 0x9f, + 0x37, 0x00, 0x00, 0x64, 0xdf, 0xff, 0xff, 0xbb, 0x1c, 0x00, 0x00, 0xb9, 0x1d, + 0x00, 0x00, 0x8d, 0x09, 0x00, 0x00, 0x2f, 0x30, 0x00, 0x00, 0x66, 0x00, 0x00, + 0x00, 0xb2, 0xf9, 0xff, 0xff, 0x0a, 0x41, 0x00, 0x00, 0x53, 0x21, 0x00, 0x00, + 0xf0, 0x1a, 0x00, 0x00, 0x58, 0x43, 0x00, 0x00, 0xe0, 0x0d, 0x00, 0x00, 0x09, + 0x3b, 0x00, 0x00, 0xee, 0x06, 0x00, 0x00, 0xfa, 0x34, 0x00, 0x00, 0x8f, 0xff, + 0xff, 0xff, 0xa5, 0xef, 0xff, 0xff, 0xb6, 0x0f, 0x00, 0x00, 0x21, 0x1b, 0x00, + 0x00, 0x96, 0x05, 0x00, 0x00, 0xed, 0xf8, 0xff, 0xff, 0x5f, 0x15, 0x00, 0x00, + 0xa0, 0xc4, 0xff, 0xff, 0xa2, 0xe0, 0xff, 0xff, 0x52, 0x06, 0x00, 0x00, 0xbc, + 0x33, 0x00, 0x00, 0x54, 0xb9, 0xff, 0xff, 0xd5, 0xfd, 0xff, 0xff, 0xe2, 0x13, + 0x00, 0x00, 0xc4, 0x29, 0x00, 0x00, 0x09, 0x43, 0x00, 0x00, 0x25, 0x26, 0x00, + 0x00, 0xd0, 0xec, 0xff, 0xff, 0xea, 0x15, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x00, + 0xa2, 0x01, 0x00, 0x00, 0xde, 0xe7, 0xff, 0xff, 0x91, 0xe7, 0xff, 0xff, 0x4a, + 0x21, 0x00, 0x00, 0xf1, 0x25, 0x00, 0x00, 0xbb, 0x07, 0x00, 0x00, 0x1e, 0x04, + 0x00, 0x00, 0x2f, 0xe6, 0xff, 0xff, 0x31, 0x08, 0x00, 0x00, 0xa6, 0x1e, 0x00, + 0x00, 0x62, 0x1a, 0x00, 0x00, 0xc0, 0x17, 0x00, 0x00, 0xa5, 0x4d, 0x00, 0x00, + 0x6a, 0xe4, 0xff, 0xff, 0x4c, 0xf2, 0xff, 0xff, 0xad, 0x01, 0x00, 0x00, 0x94, + 0x22, 0x00, 0x00, 0x32, 0xe5, 0xff, 0xff, 0xd7, 0x3f, 0x00, 0x00, 0x80, 0xed, + 0xff, 0xff, 0x4f, 0x15, 0x00, 0x00, 0x08, 0xec, 0xff, 0xff, 0xc1, 0xe8, 0xff, + 0xff, 0x7d, 0xd4, 0xff, 0xff, 0x6e, 0xe7, 0xff, 0xff, 0x51, 0xd9, 0xff, 0xff, + 0x65, 0x2b, 0x00, 0x00, 0xc3, 0x13, 0x00, 0x00, 0x3e, 0xd4, 0xff, 0xff, 0x40, + 0x3e, 0x00, 0x00, 0xd7, 0xe5, 0xff, 0xff, 0x25, 0x53, 0x00, 0x00, 0xb2, 0xef, + 0xff, 0xff, 0x57, 0x1f, 0x00, 0x00, 0x0e, 0xf3, 0xff, 0xff, 0x71, 0x0a, 0x00, + 0x00, 0x0e, 0xfc, 0xff, 0xff, 0x43, 0x00, 0x00, 0x00, 0x60, 0x11, 0x00, 0x00, + 0x95, 0x09, 0x00, 0x00, 0xf8, 0x3a, 0x00, 0x00, 0x6b, 0x16, 0x00, 0x00, 0xe2, + 0xf2, 0xff, 0xff, 0x0b, 0xf8, 0xff, 0xff, 0x5c, 0xf6, 0xff, 0xff, 0xd7, 0x09, + 0x00, 0x00, 0x94, 0x26, 0x00, 0x00, 0xaa, 0x27, 0x00, 0x00, 0x40, 0x0d, 0x00, + 0x00, 0xd7, 0xf3, 0xff, 0xff, 0xa1, 0x1a, 0x00, 0x00, 0x97, 0xfa, 0xff, 0xff, + 0xce, 0xe1, 0xff, 0xff, 0x5e, 0x1c, 0x00, 0x00, 0x36, 0x13, 0x00, 0x00, 0xa1, + 0x37, 0x00, 0x00, 0xfe, 0x32, 0x00, 0x00, 0x9a, 0x26, 0x00, 0x00, 0x12, 0xf1, + 0xff, 0xff, 0x4a, 0x5a, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x0c, 0xb1, 0x0a, 0x7f, 0x0c, 0xfe, 0xf6, 0xff, 0x9a, 0xd5, 0xc9, 0x00, + 0xf8, 0xbc, 0xe4, 0xe0, 0x21, 0x28, 0x06, 0xed, 0x30, 0x1e, 0xca, 0xcf, 0x0f, + 0x05, 0xdb, 0xe9, 0xea, 0xd4, 0x0d, 0xb5, 0x30, 0xdd, 0xe8, 0x4b, 0xa3, 0xdc, + 0x1c, 0x2b, 0xf0, 0x3b, 0xcf, 0x1f, 0xda, 0x12, 0xfd, 0xfb, 0xd0, 0x20, 0xcb, + 0xb3, 0x12, 0x36, 0xd7, 0x35, 0xde, 0x03, 0x70, 0x03, 0x39, 0x05, 0xe8, 0xce, + 0x30, 0xf3, 0x3b, 0xfd, 0x35, 0x0b, 0x36, 0xaa, 0xff, 0xc6, 0x1a, 0xfd, 0x18, + 0x01, 0xc1, 0x2b, 0xc1, 0xfe, 0x0e, 0xef, 0x13, 0xd4, 0x04, 0x17, 0xde, 0xd9, + 0x01, 0xfb, 0xd7, 0xf8, 0xff, 0x0a, 0xf9, 0xf8, 0x0b, 0x23, 0xc1, 0x34, 0x52, + 0xd7, 0x2b, 0x8f, 0xe4, 0x39, 0x37, 0x39, 0xf5, 0xe4, 0x14, 0xed, 0xe2, 0x20, + 0xf8, 0x0f, 0x02, 0xba, 0x11, 0x24, 0xf7, 0x00, 0xc2, 0xf2, 0xe7, 0xf5, 0xb3, + 0xfa, 0xfa, 0xad, 0x42, 0x3c, 0x0d, 0x02, 0x20, 0x9f, 0x21, 0xb0, 0xfc, 0x22, + 0xf8, 0x29, 0xf9, 0x32, 0x1c, 0xf7, 0xbc, 0xff, 0xee, 0xa8, 0xfd, 0x31, 0x07, + 0x2b, 0x84, 0x03, 0xf6, 0x2e, 0xcc, 0xd9, 0x1e, 0x02, 0x0b, 0x10, 0x97, 0x49, + 0xcf, 0xcd, 0xd1, 0x38, 0xc5, 0xe6, 0xed, 0xb0, 0x2d, 0xdb, 0x2b, 0xfa, 0xf8, + 0xf0, 0xf5, 0xf5, 0x04, 0x44, 0x4f, 0xf1, 0x44, 0x44, 0xd0, 0x0f, 0x30, 0x27, + 0xaa, 0x22, 0x89, 0x00, 0xe5, 0x0f, 0xcb, 0x05, 0xef, 0x9e, 0xe9, 0xe5, 0xbd, + 0xe5, 0xd5, 0xe5, 0xd4, 0xd1, 0xff, 0xa6, 0xd8, 0x3a, 0xfb, 0x08, 0x09, 0xe9, + 0xde, 0x27, 0x54, 0xf2, 0xe4, 0x73, 0xe8, 0x0a, 0xfe, 0x1c, 0x61, 0x32, 0x22, + 0x16, 0xfe, 0xaf, 0x43, 0xcc, 0x1f, 0x26, 0x21, 0x50, 0x00, 0x7f, 0x05, 0xf0, + 0xf0, 0xf1, 0xad, 0x20, 0xfa, 0xe3, 0x40, 0xdc, 0xfc, 0x97, 0xef, 0xc5, 0x07, + 0x1f, 0xaf, 0xe6, 0xf5, 0x13, 0xf6, 0x08, 0x1e, 0xfe, 0xc4, 0xc7, 0x28, 0xde, + 0xf1, 0x11, 0xcb, 0x0c, 0x23, 0x1b, 0x15, 0x05, 0xe2, 0x00, 0x1e, 0xfd, 0x19, + 0xfc, 0x53, 0xe5, 0xfe, 0xb7, 0xab, 0x21, 0x0a, 0x46, 0x07, 0xcb, 0x3a, 0x1a, + 0x51, 0xfb, 0x01, 0xcd, 0xe6, 0xf7, 0xfc, 0xc3, 0x35, 0xcb, 0xf7, 0xd7, 0x21, + 0xe0, 0xfc, 0xea, 0x25, 0x9c, 0x24, 0xec, 0xfc, 0x4e, 0x1a, 0x21, 0x28, 0xb1, + 0xfd, 0xda, 0xde, 0x81, 0xf7, 0xc8, 0xe9, 0xaa, 0x1e, 0xd5, 0x4d, 0xf5, 0x36, + 0x05, 0x13, 0x03, 0x29, 0xfe, 0x09, 0x00, 0x05, 0xf0, 0xfc, 0xeb, 0xe2, 0xb9, + 0x27, 0x19, 0xd5, 0xca, 0xf9, 0xf8, 0x03, 0xee, 0x1c, 0xd9, 0xf5, 0xca, 0xf0, + 0xe0, 0xfa, 0xdb, 0x3d, 0x1f, 0x2b, 0x34, 0xf9, 0xe6, 0xd7, 0xdc, 0xd3, 0xfd, + 0xe9, 0xf2, 0xdd, 0x22, 0xcc, 0x2d, 0xff, 0xd5, 0xec, 0xda, 0x46, 0xb9, 0x5d, + 0x32, 0xda, 0xfe, 0xc0, 0xe1, 0x28, 0x28, 0x0c, 0x39, 0xec, 0x39, 0xf7, 0x25, + 0xf2, 0x0d, 0xf4, 0xcf, 0x22, 0xfa, 0x26, 0x11, 0x00, 0xb6, 0x81, 0x1e, 0x11, + 0xc1, 0xd6, 0x14, 0x1f, 0x12, 0x4f, 0xd0, 0xc7, 0xef, 0xf2, 0xd6, 0xf6, 0xed, + 0x1b, 0xfd, 0xda, 0xf3, 0x26, 0x08, 0xd4, 0x18, 0x2c, 0xc7, 0xf8, 0x15, 0xbd, + 0xf6, 0x24, 0x29, 0x0f, 0xa5, 0x1e, 0xcd, 0xd9, 0xf5, 0xa7, 0xea, 0x02, 0xd3, + 0x82, 0xf0, 0xfc, 0xdf, 0xbd, 0x45, 0x18, 0x70, 0x99, 0x21, 0x08, 0xc1, 0x1e, + 0xef, 0xee, 0xe7, 0x13, 0xbf, 0xcd, 0xe1, 0x30, 0xe7, 0xcf, 0xf3, 0x0e, 0x58, + 0xed, 0xd2, 0xf3, 0x10, 0xf1, 0x07, 0xe1, 0x06, 0xe5, 0xf8, 0xda, 0x2c, 0x05, + 0x03, 0xc2, 0xea, 0xfd, 0xc3, 0xf4, 0xe5, 0x5c, 0xf1, 0x06, 0xcc, 0x59, 0xd7, + 0x33, 0xda, 0x58, 0xee, 0xf6, 0xdf, 0x23, 0xc3, 0xde, 0xaf, 0xf4, 0x38, 0x2b, + 0x08, 0x43, 0xd8, 0x0d, 0x55, 0x22, 0x67, 0x5b, 0x54, 0xd2, 0xf9, 0x6b, 0xdf, + 0x18, 0x01, 0x0b, 0x1f, 0x5f, 0x01, 0xfc, 0x18, 0x2e, 0x15, 0x73, 0xea, 0xec, + 0x10, 0xa3, 0x9f, 0x19, 0xe8, 0xfe, 0x81, 0xff, 0xfd, 0x2c, 0xc1, 0xd7, 0xc6, + 0xf9, 0x47, 0xfa, 0x3f, 0x03, 0xd4, 0x11, 0x2c, 0xbe, 0xd9, 0xa0, 0x1c, 0x12, + 0xfc, 0x07, 0x03, 0x0e, 0xea, 0x4a, 0xe4, 0xb9, 0xab, 0xf6, 0xf9, 0x1c, 0xfe, + 0x08, 0xe7, 0xe6, 0xe5, 0xce, 0x22, 0xe3, 0x9a, 0xd8, 0xf6, 0x25, 0xbb, 0x95, + 0x5c, 0x09, 0xd1, 0xe1, 0x10, 0xf4, 0xe0, 0xca, 0x10, 0x19, 0xb4, 0xfe, 0x34, + 0x3a, 0xc7, 0x0e, 0xc1, 0xa2, 0x7a, 0xdd, 0xef, 0x39, 0xfc, 0x13, 0xdf, 0xad, + 0xea, 0xeb, 0xd7, 0x45, 0x1d, 0xd9, 0x13, 0x6b, 0x33, 0xb3, 0x33, 0xcb, 0xdb, + 0x94, 0x0a, 0x64, 0xf7, 0xee, 0x0b, 0x04, 0xdb, 0x55, 0x37, 0x2a, 0x66, 0xeb, + 0xb6, 0x13, 0xf2, 0xdb, 0x2d, 0xe9, 0x29, 0xff, 0xe9, 0x10, 0xe5, 0xc1, 0xf7, + 0xb3, 0x4b, 0xdc, 0x24, 0x10, 0xe2, 0xcc, 0xc5, 0xd2, 0xc2, 0xd2, 0x37, 0xe9, + 0xb5, 0x4a, 0x0e, 0x46, 0xda, 0x35, 0xca, 0x40, 0xf4, 0xcf, 0xcb, 0x05, 0xe1, + 0xa6, 0x1c, 0xce, 0x89, 0xc6, 0x4c, 0xe6, 0x32, 0x85, 0x0c, 0xaa, 0x16, 0xe6, + 0xef, 0x2d, 0xf2, 0x05, 0xb6, 0x5e, 0x2a, 0x39, 0x24, 0x96, 0x4c, 0xbd, 0xc8, + 0xea, 0x22, 0xb9, 0x01, 0x2a, 0x27, 0x12, 0xe8, 0xf3, 0xaa, 0x5e, 0x24, 0x26, + 0x01, 0xe2, 0xf5, 0x61, 0x31, 0x9e, 0xc4, 0x4c, 0xb4, 0x0f, 0xbf, 0xd8, 0xf2, + 0xe4, 0x10, 0x12, 0xa1, 0x48, 0xdd, 0xec, 0x3b, 0xc0, 0x9f, 0x4a, 0xb4, 0xf0, + 0x6c, 0x4b, 0xae, 0x12, 0x2b, 0xdc, 0x02, 0x8a, 0x6f, 0x08, 0xb1, 0x81, 0xb7, + 0x23, 0x42, 0xfc, 0x4b, 0xda, 0x64, 0xe5, 0xff, 0xc3, 0x32, 0x63, 0xc0, 0xdf, + 0xb6, 0x3d, 0xfc, 0xfa, 0xec, 0xea, 0x4d, 0x28, 0xe4, 0xdc, 0x47, 0xcb, 0xf6, + 0xb9, 0xfc, 0x06, 0x2d, 0xb2, 0xc0, 0xdb, 0x40, 0xcb, 0x2d, 0x15, 0xfb, 0xf9, + 0xfd, 0x39, 0x19, 0x19, 0x1c, 0xc5, 0x05, 0x03, 0xc1, 0x49, 0xe4, 0x05, 0x40, + 0x2f, 0xb8, 0x34, 0x81, 0xf8, 0xe6, 0xa2, 0xbb, 0xf4, 0xed, 0x5d, 0x0b, 0x1b, + 0x10, 0x1a, 0xfa, 0x5b, 0x01, 0xfc, 0xf2, 0xd6, 0xdb, 0x37, 0x0d, 0x4e, 0x32, + 0x36, 0xe1, 0x2a, 0x2a, 0x37, 0x3e, 0xd8, 0x1e, 0x53, 0xe8, 0x79, 0x1d, 0x23, + 0x15, 0x0e, 0x42, 0x40, 0xed, 0xca, 0x2c, 0x03, 0xe0, 0xbd, 0xda, 0x33, 0xfd, + 0x46, 0x25, 0xfd, 0x78, 0xd0, 0xc4, 0x29, 0xc6, 0xe7, 0xd8, 0x4c, 0xd4, 0xf7, + 0x28, 0x62, 0xcc, 0xef, 0x0d, 0x4f, 0xf1, 0x12, 0xdb, 0x12, 0xc9, 0xc8, 0xe8, + 0xbe, 0x7b, 0xf3, 0xc0, 0xe4, 0x16, 0x16, 0x3c, 0xd7, 0xe9, 0x01, 0xf5, 0x2a, + 0x19, 0x41, 0x9a, 0x8e, 0xc5, 0xd8, 0xec, 0xe4, 0x1f, 0xff, 0xdb, 0xf7, 0xbd, + 0x17, 0xfa, 0xda, 0x01, 0x06, 0x48, 0xf6, 0x2e, 0xcc, 0xc9, 0xbd, 0xf5, 0xdf, + 0x55, 0xf7, 0x12, 0xcf, 0xd4, 0x78, 0xb3, 0x11, 0x43, 0x37, 0x68, 0x47, 0xc6, + 0xf4, 0x1e, 0x4d, 0xc6, 0x3c, 0xb9, 0xb8, 0x21, 0x31, 0x02, 0x25, 0xe9, 0x18, + 0xec, 0x02, 0x81, 0x09, 0xf6, 0xec, 0x04, 0xff, 0xed, 0x26, 0xa4, 0x4f, 0x9f, + 0xba, 0x0d, 0x4d, 0x42, 0x3f, 0x3a, 0x28, 0x02, 0x48, 0x59, 0xdb, 0xdb, 0xf1, + 0xe7, 0x3f, 0x41, 0xaf, 0xba, 0x32, 0x8c, 0xcb, 0x2e, 0x23, 0xca, 0x20, 0x05, + 0x53, 0x00, 0x03, 0xc2, 0x15, 0x1f, 0xa6, 0xaf, 0x21, 0xe1, 0xc0, 0xb0, 0xc8, + 0xde, 0xa9, 0x43, 0xd7, 0x33, 0x03, 0x1f, 0x43, 0xb1, 0x09, 0x9e, 0x0c, 0x14, + 0x0d, 0xbc, 0x36, 0x10, 0x0d, 0x13, 0xc6, 0xe3, 0x4f, 0x1d, 0xd1, 0xc8, 0xca, + 0x08, 0xee, 0xb1, 0x07, 0x23, 0xe7, 0x04, 0x0d, 0x04, 0x1a, 0x15, 0x00, 0x3f, + 0x06, 0xf4, 0xc9, 0xde, 0x08, 0xd3, 0x74, 0x10, 0x1d, 0x2f, 0x27, 0xa3, 0xf4, + 0xc4, 0xff, 0xe8, 0x02, 0x1f, 0x0e, 0xe7, 0xfd, 0x23, 0x08, 0xd9, 0xe5, 0xb8, + 0xba, 0xf4, 0x3e, 0xca, 0xe9, 0xc6, 0xe7, 0xaf, 0x15, 0x20, 0xed, 0x7b, 0xd8, + 0x02, 0x06, 0xf3, 0xa2, 0x39, 0xf3, 0x81, 0xeb, 0xce, 0xef, 0xf8, 0x22, 0x25, + 0xf5, 0xde, 0x12, 0xf1, 0x14, 0x47, 0xe0, 0xf0, 0xf6, 0xfe, 0xba, 0xec, 0xea, + 0xe6, 0x2e, 0x0f, 0x10, 0x1a, 0x58, 0xef, 0xf9, 0x0e, 0x0c, 0xc2, 0xe2, 0xd3, + 0xee, 0xfc, 0x12, 0x1c, 0x3d, 0xdf, 0xd9, 0x35, 0x1a, 0xe6, 0x0b, 0x21, 0xc6, + 0x0a, 0x07, 0xeb, 0xc5, 0xe2, 0x33, 0xef, 0x0b, 0xed, 0x1b, 0x23, 0x03, 0x1e, + 0xdb, 0x10, 0xde, 0xc2, 0x7f, 0x2d, 0xe8, 0xa9, 0x15, 0x03, 0xe2, 0xd0, 0x41, + 0x5c, 0x1d, 0xdf, 0xff, 0x0e, 0xea, 0xe1, 0xc6, 0xef, 0x15, 0x09, 0x1a, 0x21, + 0x14, 0xec, 0xfa, 0xe9, 0xe8, 0x1c, 0x75, 0x1b, 0xb6, 0x2c, 0x11, 0x25, 0xfd, + 0x37, 0x12, 0xc5, 0xcd, 0x1f, 0x1d, 0x24, 0xd9, 0x25, 0x1c, 0xb0, 0xfb, 0x03, + 0xca, 0x13, 0x13, 0x22, 0x09, 0x08, 0x33, 0x13, 0xfe, 0xd7, 0x4a, 0xfc, 0xcc, + 0xfa, 0x04, 0xee, 0xe8, 0xbb, 0xc7, 0xfa, 0xdf, 0x13, 0xd8, 0xed, 0x20, 0x1b, + 0xbc, 0x09, 0xf3, 0x1c, 0x05, 0x3c, 0x55, 0xef, 0x24, 0x1a, 0x18, 0x65, 0xe0, + 0x31, 0xcb, 0x21, 0x41, 0x0a, 0x18, 0xf9, 0xed, 0xf0, 0x20, 0xee, 0x01, 0x28, + 0xe0, 0xc6, 0xc7, 0xc2, 0xf6, 0xee, 0x07, 0x40, 0xe7, 0xf7, 0xfc, 0x2a, 0xf3, + 0x15, 0x53, 0x0e, 0x09, 0xd9, 0x18, 0xcf, 0x02, 0x0f, 0x21, 0xfe, 0xfe, 0x04, + 0xf1, 0xc4, 0x47, 0xd7, 0x1f, 0xf9, 0xfd, 0x08, 0x41, 0xf5, 0xe7, 0xed, 0x1b, + 0x03, 0xc8, 0xe0, 0xf6, 0xf5, 0x05, 0x23, 0x03, 0x33, 0x2a, 0x11, 0x2b, 0xfe, + 0x23, 0x03, 0xf9, 0x08, 0x20, 0xc7, 0xfd, 0xeb, 0xf9, 0xf4, 0x0b, 0x0a, 0xfa, + 0xcb, 0x33, 0x08, 0xf1, 0x26, 0xdf, 0xf8, 0x09, 0xbc, 0x03, 0x13, 0x4e, 0xfc, + 0x1e, 0xf0, 0x29, 0x0e, 0x16, 0x31, 0x1b, 0xfb, 0x0b, 0x06, 0xed, 0xcf, 0xf3, + 0xc5, 0x16, 0x05, 0x05, 0xec, 0xfd, 0x1c, 0x37, 0xd2, 0xe2, 0x1b, 0x03, 0x24, + 0xfa, 0x3f, 0x1e, 0xf9, 0xe2, 0x1f, 0x05, 0xcc, 0x02, 0x7f, 0xff, 0xfe, 0x09, + 0x4f, 0x23, 0x00, 0x18, 0x0a, 0x01, 0x42, 0x05, 0xea, 0xd1, 0xdc, 0xfb, 0x16, + 0x3f, 0x23, 0x00, 0xe6, 0xf7, 0x0a, 0x1e, 0xdd, 0x02, 0x18, 0xf9, 0x14, 0xdd, + 0xf2, 0x31, 0x19, 0xfd, 0x2e, 0xf7, 0xf4, 0xe7, 0x24, 0x9e, 0xd1, 0x05, 0x5c, + 0xde, 0xb1, 0x1a, 0xe0, 0x32, 0xb6, 0x05, 0x0b, 0x14, 0x46, 0xde, 0x3a, 0xe4, + 0xfa, 0x14, 0xe2, 0xe2, 0xdc, 0x32, 0x02, 0xd1, 0x21, 0xfd, 0x14, 0x22, 0x13, + 0x02, 0xfd, 0x08, 0x9a, 0x02, 0xd1, 0x4b, 0xf3, 0xe4, 0x13, 0xc1, 0xcb, 0x09, + 0x02, 0xec, 0xbb, 0x17, 0x25, 0x81, 0x48, 0x27, 0xea, 0xcd, 0x0e, 0x18, 0xdc, + 0x17, 0x04, 0x15, 0x38, 0x04, 0xeb, 0xd3, 0xe2, 0xf6, 0xac, 0xe8, 0xbf, 0xb9, + 0x3f, 0xed, 0xe4, 0xee, 0x2c, 0x13, 0x11, 0xee, 0xba, 0x0f, 0x14, 0x07, 0xc1, + 0x0f, 0xde, 0xea, 0xe4, 0x57, 0xfb, 0x00, 0x27, 0x3d, 0x31, 0x1e, 0x3d, 0xf0, + 0x0e, 0x0b, 0x15, 0xdc, 0xcc, 0xd5, 0x27, 0x6f, 0xf7, 0xe6, 0xfb, 0x32, 0x56, + 0xf8, 0xe0, 0xcc, 0x48, 0x06, 0x1e, 0xfb, 0x08, 0xf9, 0xff, 0x1e, 0x03, 0x1b, + 0x17, 0xa0, 0x6a, 0xc6, 0x63, 0x0d, 0x62, 0xd6, 0xd1, 0xc9, 0xea, 0x35, 0x41, + 0xe8, 0x0c, 0x12, 0x32, 0xe1, 0xe1, 0x12, 0x70, 0xff, 0x05, 0x35, 0x19, 0xf1, + 0xf3, 0x07, 0xec, 0x0e, 0xd5, 0xe6, 0xed, 0x6d, 0xd5, 0xf9, 0x32, 0xea, 0x30, + 0xb9, 0xe5, 0x3d, 0xe2, 0xe3, 0xfb, 0xd2, 0x05, 0x23, 0xcc, 0x9c, 0xa5, 0xc5, + 0xe9, 0x03, 0x1d, 0x52, 0xe0, 0x09, 0x0b, 0xe4, 0xeb, 0xd5, 0xba, 0x12, 0x1d, + 0xdd, 0x19, 0x25, 0xbb, 0xba, 0x2b, 0x4c, 0xf8, 0xbe, 0xe3, 0xf3, 0x32, 0xff, + 0xb0, 0x31, 0x0c, 0x21, 0x0f, 0x0e, 0x3b, 0x0d, 0xc1, 0x0a, 0xc9, 0x15, 0x91, + 0x17, 0xd4, 0x19, 0x99, 0xea, 0xb4, 0xdb, 0x3c, 0x10, 0xef, 0xaa, 0x04, 0xf8, + 0xfe, 0x04, 0xd3, 0xf4, 0x36, 0xf9, 0x7f, 0xc4, 0xf0, 0x29, 0xd9, 0x0d, 0x00, + 0xc1, 0x31, 0xf3, 0xee, 0x23, 0x27, 0x37, 0xe6, 0xd1, 0xcf, 0xe0, 0xfb, 0xc8, + 0x2a, 0x36, 0x17, 0xd0, 0xcf, 0xfa, 0xe1, 0x34, 0x0d, 0x1a, 0x01, 0x2a, 0xe4, + 0xf2, 0xf8, 0x10, 0x49, 0xd8, 0xff, 0x18, 0xea, 0x2c, 0xf4, 0xb5, 0x37, 0x00, + 0x14, 0x13, 0xed, 0xfe, 0xd4, 0x9f, 0xf6, 0xf3, 0xd5, 0xbc, 0x0f, 0xe8, 0xb5, + 0x1e, 0x1a, 0x48, 0x10, 0x27, 0xc7, 0xf0, 0x26, 0xea, 0x40, 0xf8, 0x0c, 0x53, + 0x00, 0xdf, 0x28, 0xdf, 0xf3, 0xbc, 0x19, 0xf5, 0x1d, 0x98, 0x33, 0xfa, 0xeb, + 0x1c, 0xeb, 0xbb, 0x03, 0xf7, 0x45, 0x11, 0x27, 0x08, 0xfd, 0x06, 0x0b, 0xe3, + 0xd9, 0xf1, 0xb0, 0xff, 0xe5, 0xf0, 0xed, 0x08, 0x29, 0xc5, 0x05, 0xf1, 0xd5, + 0x1a, 0xd7, 0xc8, 0xcb, 0x7f, 0x81, 0xea, 0xe3, 0xef, 0xb9, 0xef, 0x1a, 0x10, + 0xe0, 0x2c, 0xd0, 0x34, 0x4d, 0xf2, 0x08, 0x25, 0xff, 0xb5, 0x0d, 0xfe, 0xd8, + 0x13, 0x50, 0x2f, 0x2c, 0xee, 0x68, 0xdd, 0x3c, 0x03, 0xf1, 0xf5, 0x3b, 0xe9, + 0xc4, 0xf4, 0x33, 0x06, 0xe1, 0xfd, 0x21, 0xb7, 0xf7, 0x15, 0xf9, 0xc0, 0xf9, + 0xd2, 0x1a, 0xfb, 0xbe, 0xd5, 0x37, 0x20, 0x02, 0xe4, 0x2b, 0xef, 0xe6, 0xec, + 0xad, 0xc2, 0xf6, 0xe7, 0x08, 0x15, 0xe3, 0x5f, 0xdc, 0xff, 0xaa, 0xfa, 0x02, + 0x1c, 0xf8, 0xf9, 0x12, 0x1a, 0x42, 0xc0, 0x00, 0x34, 0x02, 0x02, 0x27, 0x3c, + 0xeb, 0x11, 0x59, 0xd4, 0xea, 0x33, 0x1e, 0xb7, 0x07, 0x32, 0x01, 0xf5, 0x28, + 0x7f, 0x09, 0x0b, 0xde, 0xe8, 0x46, 0x54, 0xa0, 0xff, 0x08, 0x15, 0x19, 0x02, + 0x12, 0xa5, 0xd4, 0x05, 0xbe, 0x1f, 0x2d, 0xae, 0xd4, 0x2c, 0x29, 0xe9, 0xe3, + 0x18, 0x9e, 0x49, 0x4a, 0xe8, 0xe5, 0xbc, 0x84, 0xbe, 0x47, 0x3f, 0xb9, 0x25, + 0xc5, 0xbe, 0x19, 0xeb, 0x36, 0xf3, 0xe2, 0x0f, 0x10, 0x32, 0xe9, 0x04, 0x1a, + 0xe9, 0xe2, 0xc2, 0xf7, 0x22, 0x02, 0xff, 0xfa, 0xff, 0xcb, 0x0b, 0xcd, 0x08, + 0xd2, 0xf2, 0x17, 0xf4, 0x30, 0x30, 0x29, 0xdd, 0xc0, 0xfa, 0xed, 0x04, 0xff, + 0xfd, 0x2c, 0x02, 0xc6, 0x09, 0x01, 0x03, 0x3b, 0x00, 0x0e, 0x01, 0xe1, 0xd8, + 0x0d, 0x2c, 0x02, 0x0c, 0xe4, 0xf6, 0x2e, 0x39, 0xe1, 0xc3, 0x33, 0xfa, 0xe0, + 0xd7, 0x17, 0x00, 0x10, 0x29, 0x2c, 0xec, 0x43, 0xfe, 0xc6, 0x19, 0xe1, 0x18, + 0x51, 0xec, 0x0e, 0x3b, 0xda, 0xf1, 0xb5, 0xd7, 0xfc, 0xb1, 0xe7, 0x4d, 0xcb, + 0xf8, 0xe1, 0xb9, 0xec, 0x09, 0xb4, 0xd5, 0x53, 0x23, 0xc5, 0x2d, 0x1b, 0xaf, + 0xd8, 0xc8, 0xf3, 0x14, 0x50, 0x03, 0xf9, 0x2d, 0x1c, 0xe0, 0x0a, 0xda, 0xd7, + 0xf4, 0x29, 0x37, 0x26, 0xec, 0xc4, 0x07, 0x17, 0x58, 0xef, 0x2f, 0xfc, 0x17, + 0x23, 0xe4, 0x55, 0x39, 0x0c, 0x32, 0x0d, 0xc1, 0x0c, 0x4a, 0x12, 0x02, 0xf7, + 0x12, 0x25, 0x03, 0xfa, 0x7f, 0x21, 0x03, 0xd2, 0x49, 0x29, 0x07, 0xa4, 0x24, + 0x11, 0xfb, 0xd2, 0x01, 0x02, 0xf7, 0x04, 0x12, 0xe0, 0x03, 0x14, 0x40, 0x11, + 0xea, 0x15, 0x03, 0x43, 0xe1, 0x23, 0xed, 0xdb, 0xe1, 0xe8, 0xe9, 0x00, 0x3e, + 0xd3, 0x6b, 0xdc, 0xe1, 0x05, 0x0a, 0xe5, 0xe8, 0xda, 0xf4, 0xcb, 0x00, 0x7f, + 0x45, 0xfc, 0x37, 0x36, 0xcd, 0x05, 0x09, 0xc8, 0x33, 0x56, 0x02, 0xd9, 0xda, + 0xfe, 0x04, 0xeb, 0x07, 0xd4, 0xdf, 0xd0, 0x07, 0xe4, 0xf7, 0x10, 0x38, 0x14, + 0xd6, 0x1b, 0x44, 0x22, 0xdf, 0xef, 0x19, 0xde, 0xf2, 0xdb, 0x04, 0x19, 0xd4, + 0x35, 0xf9, 0xd6, 0xba, 0x02, 0xe8, 0xcc, 0xec, 0x35, 0x0f, 0x2e, 0xf1, 0xf5, + 0xef, 0xdc, 0x0b, 0xcb, 0xe3, 0x16, 0x05, 0xce, 0xff, 0x07, 0xae, 0x45, 0xe9, + 0x1e, 0x0d, 0xc5, 0x33, 0x27, 0xd4, 0x21, 0x2c, 0x05, 0xed, 0xdd, 0xe6, 0xf4, + 0x29, 0xc4, 0xf0, 0xc7, 0xca, 0x21, 0x68, 0xf9, 0x09, 0x01, 0xc4, 0xf8, 0xf5, + 0x9a, 0x22, 0x0b, 0x2c, 0xf1, 0x18, 0xfa, 0x37, 0x0b, 0x03, 0x28, 0xcf, 0x05, + 0x20, 0x15, 0xe8, 0x42, 0xe7, 0xe0, 0x02, 0x98, 0xa1, 0x50, 0x1b, 0x16, 0x5a, + 0x22, 0xb6, 0x2c, 0x61, 0xea, 0xce, 0x96, 0x45, 0xfd, 0xd2, 0xfe, 0xff, 0xbd, + 0xee, 0x54, 0xff, 0xf6, 0x17, 0x20, 0xf5, 0x31, 0x22, 0xe8, 0xbd, 0xfa, 0xfc, + 0xb5, 0xe1, 0xad, 0x07, 0xe0, 0xf2, 0xf4, 0x1b, 0xb0, 0x22, 0xfd, 0x11, 0x35, + 0x38, 0xb8, 0xb9, 0xcf, 0x03, 0x2d, 0x10, 0xd8, 0x16, 0xb7, 0x04, 0x2a, 0x4f, + 0x06, 0x03, 0x1c, 0x5f, 0xfc, 0x11, 0x23, 0xe0, 0xe9, 0x33, 0x73, 0x2f, 0x40, + 0x31, 0xbe, 0x10, 0xd8, 0xd4, 0x1e, 0xea, 0xd5, 0xf4, 0x0e, 0x3c, 0x5d, 0xcb, + 0xd1, 0xef, 0x92, 0xf6, 0x2c, 0xdc, 0x03, 0x1c, 0xfa, 0x7f, 0xdd, 0xd9, 0xc0, + 0xea, 0xe6, 0xf4, 0xea, 0xf9, 0xd4, 0x01, 0xde, 0xc4, 0xfc, 0x01, 0x07, 0xd7, + 0xd3, 0xef, 0xe5, 0x1b, 0x2f, 0x29, 0x2a, 0xdb, 0x3d, 0x1a, 0xc2, 0xf7, 0xf2, + 0x12, 0xe2, 0x30, 0x3f, 0x21, 0x0d, 0xda, 0xfa, 0x0a, 0x55, 0xdd, 0xfa, 0x1f, + 0xd0, 0xfd, 0xc3, 0xfd, 0x35, 0xfb, 0x2b, 0xeb, 0xe3, 0xf9, 0x42, 0xed, 0x1a, + 0x12, 0x3a, 0x19, 0xa6, 0x4e, 0x27, 0x13, 0x1e, 0xe4, 0xf8, 0x66, 0x57, 0x70, + 0x93, 0x8a, 0xeb, 0x03, 0xb7, 0xfd, 0x64, 0x1b, 0xde, 0xfd, 0x20, 0xd2, 0x49, + 0xc8, 0x27, 0x12, 0x05, 0x24, 0x21, 0x15, 0x0e, 0x0a, 0x1a, 0xfb, 0x68, 0xcb, + 0xd1, 0x0d, 0xf3, 0xf7, 0x7f, 0x71, 0xc7, 0x0b, 0xd7, 0x35, 0xfd, 0xd0, 0xcb, + 0x1d, 0x19, 0xdc, 0x1c, 0x35, 0xe0, 0xcd, 0xfb, 0x13, 0x43, 0x32, 0x4a, 0xfa, + 0x21, 0xf8, 0x07, 0x4e, 0x1a, 0xf8, 0xe7, 0xbf, 0x06, 0xec, 0xeb, 0x29, 0x21, + 0xd4, 0x38, 0x1e, 0xd7, 0x0a, 0x81, 0xe0, 0x00, 0x12, 0xf7, 0x6b, 0xd5, 0xf9, + 0x0e, 0xee, 0x09, 0x08, 0x12, 0xee, 0x3d, 0x39, 0x0b, 0xe7, 0x12, 0x18, 0x34, + 0x19, 0x08, 0x0b, 0xfb, 0x33, 0xe2, 0x39, 0x2f, 0x01, 0xda, 0xfc, 0xde, 0x0a, + 0xfe, 0x1e, 0xf9, 0xeb, 0x2f, 0xbc, 0xed, 0xf3, 0xc1, 0x05, 0x2c, 0xea, 0xf2, + 0xfb, 0xe0, 0xf5, 0xf2, 0x11, 0x22, 0xd4, 0x67, 0x02, 0x1e, 0x14, 0xdc, 0x1b, + 0xf4, 0xc2, 0xf5, 0xcf, 0x04, 0x44, 0x36, 0xe7, 0xdd, 0xc4, 0xde, 0x10, 0xe1, + 0xf6, 0x20, 0x2f, 0x17, 0x11, 0xfe, 0xfc, 0x03, 0xd9, 0x5b, 0x16, 0xff, 0xdc, + 0xf6, 0xfb, 0xdc, 0xda, 0x0e, 0x15, 0x14, 0xfc, 0x3b, 0xe3, 0xc8, 0x6f, 0x22, + 0x9d, 0xf3, 0xf7, 0x28, 0x44, 0x0b, 0x19, 0x21, 0xf7, 0xfe, 0x0f, 0xe0, 0x36, + 0xd3, 0x32, 0xe4, 0xdf, 0x32, 0x31, 0x07, 0xdf, 0xd3, 0xe1, 0x48, 0xe6, 0xde, + 0x08, 0xda, 0xd9, 0xf2, 0x1c, 0x06, 0xbe, 0xfc, 0x19, 0xd7, 0xe8, 0x03, 0xf2, + 0x04, 0x2a, 0x06, 0x1d, 0x0b, 0x1a, 0x21, 0x20, 0x47, 0xfe, 0x32, 0xc4, 0x17, + 0x13, 0x03, 0x26, 0xc3, 0xd6, 0xff, 0xe2, 0x81, 0x2b, 0xe9, 0xfc, 0x01, 0xf0, + 0x37, 0x11, 0x16, 0xb9, 0x01, 0xf5, 0x0c, 0xdf, 0x07, 0xd6, 0xe8, 0x3d, 0xf2, + 0xeb, 0xd5, 0x09, 0xfa, 0xc6, 0xf0, 0xe5, 0xfa, 0x24, 0x0e, 0xef, 0xdc, 0x07, + 0xfb, 0x64, 0x54, 0xd4, 0xf0, 0x26, 0x5d, 0xd0, 0xd8, 0xe5, 0xe7, 0x2b, 0xe9, + 0x13, 0x1d, 0x69, 0x4c, 0x2f, 0x68, 0x18, 0xd4, 0x62, 0x31, 0x33, 0x3e, 0xf1, + 0x42, 0x25, 0x90, 0xd6, 0x6b, 0xdf, 0xef, 0xc4, 0x0d, 0x05, 0x04, 0x32, 0x20, + 0x17, 0x13, 0x0f, 0xcb, 0x09, 0x04, 0x18, 0x1f, 0x21, 0x51, 0xe9, 0xdf, 0x18, + 0xa4, 0x30, 0xfd, 0xba, 0xb9, 0xca, 0x5f, 0xe7, 0xd9, 0xc7, 0x94, 0x30, 0x23, + 0xfb, 0x1d, 0xd8, 0xf7, 0xf3, 0xb1, 0x3e, 0xfa, 0xf9, 0xcb, 0x09, 0x33, 0x34, + 0xe3, 0xf3, 0x27, 0xf6, 0xf5, 0xf7, 0xd2, 0xfa, 0xe4, 0xdf, 0xd7, 0x42, 0xca, + 0x11, 0x11, 0x2e, 0x3c, 0x12, 0x3f, 0xcf, 0x0e, 0xf4, 0xd5, 0x23, 0xf1, 0x2c, + 0x1b, 0x14, 0xdb, 0xf7, 0xfe, 0xec, 0x00, 0xc4, 0xe4, 0x01, 0x04, 0x1d, 0xe9, + 0x2c, 0xde, 0x1e, 0x28, 0xe0, 0xe9, 0x06, 0xf4, 0x34, 0xf3, 0xf5, 0xdf, 0xb1, + 0x0d, 0x20, 0xd5, 0x21, 0xf3, 0x31, 0x57, 0xfd, 0x09, 0x17, 0x2a, 0x21, 0xe3, + 0xf2, 0xf8, 0x0d, 0xcc, 0x0d, 0x45, 0x05, 0x05, 0x13, 0x05, 0x25, 0x06, 0xe5, + 0x0d, 0xd4, 0xe7, 0x1e, 0x2c, 0x1f, 0x24, 0x1f, 0xe5, 0x0f, 0x19, 0xe5, 0xfd, + 0x0b, 0xd8, 0x20, 0xd8, 0x0a, 0x30, 0x32, 0xde, 0x02, 0xc0, 0xee, 0xf5, 0x32, + 0x12, 0x7f, 0x0d, 0x0a, 0xc0, 0x01, 0x05, 0xfb, 0x05, 0x13, 0xf9, 0xf9, 0x72, + 0x09, 0x3e, 0x1f, 0xf8, 0x40, 0x28, 0x3c, 0x1a, 0x26, 0xde, 0xf6, 0xc6, 0x27, + 0x28, 0xc7, 0x28, 0x31, 0x0b, 0x28, 0x21, 0xe5, 0xd0, 0x08, 0x1e, 0x69, 0x42, + 0xf0, 0x0b, 0x21, 0x2f, 0xe3, 0xf0, 0x17, 0xd7, 0xdb, 0xc8, 0x02, 0x3b, 0x4b, + 0xe5, 0xe5, 0xe9, 0xfc, 0x0d, 0x0c, 0xf1, 0xf1, 0xd3, 0xe5, 0xc5, 0x3b, 0xd8, + 0x3d, 0xfc, 0x0f, 0x03, 0xfa, 0x1f, 0xf4, 0x1a, 0x09, 0x24, 0xf4, 0xad, 0xeb, + 0x23, 0x6a, 0xee, 0x59, 0x69, 0x1d, 0xf9, 0x3d, 0xe3, 0x11, 0x64, 0x4b, 0x15, + 0x1e, 0x7f, 0x3e, 0x14, 0x05, 0xfc, 0x0a, 0x0b, 0x70, 0xf3, 0x0f, 0x29, 0x35, + 0xec, 0x1a, 0x5b, 0x26, 0x20, 0x33, 0xb8, 0x32, 0x05, 0xf6, 0xd2, 0xfc, 0xcc, + 0x22, 0x89, 0x01, 0x43, 0x0b, 0x04, 0x41, 0x3e, 0xf6, 0x00, 0xea, 0x15, 0x2a, + 0xf1, 0xf4, 0xa8, 0x24, 0xf1, 0xe0, 0x21, 0xae, 0xd7, 0xf1, 0xe6, 0x7f, 0x51, + 0xc4, 0x46, 0x00, 0x27, 0x41, 0xb9, 0xf4, 0x20, 0xfb, 0xdf, 0xdc, 0x16, 0xfa, + 0xb7, 0xf1, 0x0c, 0x0d, 0xe2, 0x02, 0xe4, 0xf8, 0x5c, 0xfd, 0x0b, 0x25, 0xcb, + 0xb4, 0xed, 0xd8, 0x98, 0x4e, 0xf2, 0xd1, 0x00, 0x32, 0xd2, 0x45, 0x1d, 0xff, + 0x9c, 0xec, 0x65, 0x26, 0x28, 0x16, 0x32, 0x29, 0x2d, 0x11, 0x2c, 0xce, 0xef, + 0x11, 0xfe, 0xc9, 0x1e, 0xec, 0x58, 0xfd, 0x2f, 0xe8, 0xbf, 0x38, 0x4c, 0x1d, + 0x18, 0xde, 0xb2, 0xd6, 0xa0, 0xe8, 0x2c, 0xf1, 0x2f, 0xe4, 0xab, 0x61, 0x0f, + 0x36, 0xc4, 0xc3, 0x09, 0x0d, 0xd6, 0xbb, 0x03, 0xfa, 0xfd, 0x27, 0xcf, 0xc1, + 0x53, 0xdf, 0x3e, 0x02, 0x1d, 0x1e, 0xf5, 0x39, 0x0e, 0x79, 0x09, 0x13, 0xe6, + 0x47, 0xd5, 0xe8, 0x31, 0x5f, 0x03, 0x1b, 0x1a, 0x3e, 0x04, 0xfa, 0xf6, 0x41, + 0x12, 0xef, 0x5a, 0x47, 0x16, 0xed, 0xfc, 0x18, 0x11, 0x1d, 0xdc, 0xd5, 0xfd, + 0xaa, 0xc3, 0xeb, 0x3f, 0xe0, 0xcf, 0xf9, 0x41, 0xac, 0x13, 0x1c, 0x02, 0x24, + 0x1a, 0xfe, 0x81, 0x3b, 0x1a, 0x1a, 0x2a, 0xd4, 0x20, 0xdf, 0xc7, 0x37, 0xa8, + 0xe6, 0xa4, 0xdc, 0xb3, 0x17, 0xe6, 0x23, 0xd7, 0x03, 0xdb, 0xdd, 0x16, 0x14, + 0xf0, 0xf1, 0x11, 0xff, 0x4b, 0x66, 0xf4, 0x09, 0xe8, 0x00, 0x12, 0xe3, 0x12, + 0xae, 0x09, 0xbb, 0x25, 0x02, 0xd1, 0x20, 0x17, 0x05, 0x33, 0x5c, 0x34, 0xc0, + 0xb0, 0xf4, 0x0e, 0x11, 0xd9, 0xcd, 0x28, 0xbf, 0xe2, 0xfd, 0xa8, 0x05, 0xe5, + 0x1e, 0x0e, 0x0b, 0x10, 0xfd, 0x14, 0x2c, 0xd8, 0xbc, 0xcd, 0x58, 0x4d, 0xaa, + 0xc4, 0x04, 0x30, 0xea, 0x01, 0x46, 0xef, 0x60, 0x3d, 0xe8, 0x39, 0xbb, 0x21, + 0xee, 0x31, 0x41, 0xa8, 0xdc, 0x27, 0xf8, 0xe7, 0xf5, 0x0a, 0xf6, 0x3b, 0xdd, + 0xe8, 0xf8, 0xea, 0x2f, 0xc8, 0xdf, 0xe9, 0x09, 0x2a, 0x0f, 0xff, 0x06, 0x0d, + 0xdf, 0x01, 0xc4, 0xf9, 0xdc, 0x30, 0x0b, 0xe0, 0xcf, 0xf8, 0x02, 0x0c, 0xec, + 0xd6, 0x1b, 0x19, 0xee, 0xfe, 0x19, 0x0b, 0x5d, 0xd8, 0x53, 0x2b, 0xb0, 0x3f, + 0x11, 0xb5, 0xb8, 0x2f, 0xad, 0xe5, 0xfd, 0x2a, 0x00, 0xd3, 0x45, 0x0b, 0x00, + 0xba, 0xeb, 0xd1, 0x36, 0xea, 0x2f, 0x08, 0x99, 0xed, 0x7f, 0x1a, 0x2e, 0xff, + 0x29, 0x04, 0x0e, 0x1b, 0x05, 0xba, 0xd5, 0x27, 0xaf, 0xf9, 0x24, 0x5b, 0xf6, + 0x7a, 0x42, 0x12, 0xc3, 0x5c, 0xf6, 0x07, 0x21, 0x0e, 0x38, 0x15, 0x20, 0xe0, + 0xf4, 0xe5, 0xde, 0xe1, 0xc2, 0xda, 0xe0, 0xe7, 0xde, 0xcb, 0xf7, 0xfe, 0xd3, + 0x02, 0x49, 0x21, 0x02, 0x4b, 0x9d, 0x07, 0x44, 0x8f, 0x16, 0x47, 0x2b, 0xfe, + 0x17, 0x22, 0x4a, 0xff, 0xd6, 0xe7, 0x8e, 0xf7, 0x31, 0xff, 0x24, 0x17, 0x2c, + 0xdb, 0xfd, 0x4c, 0xb6, 0x40, 0xc5, 0xe6, 0x0f, 0x1f, 0xc4, 0x3c, 0xba, 0xf9, + 0x05, 0x03, 0xee, 0x09, 0x09, 0x11, 0xde, 0xfb, 0xd8, 0x06, 0xe1, 0x30, 0x0a, + 0xf5, 0x20, 0xc9, 0xd5, 0x04, 0x13, 0xe9, 0x00, 0xef, 0xfb, 0x12, 0x03, 0x09, + 0x2b, 0xbe, 0xd8, 0x02, 0x0d, 0xf4, 0x23, 0xc5, 0xfd, 0x1d, 0xe1, 0xef, 0x27, + 0xe4, 0x11, 0xcc, 0x30, 0x10, 0x36, 0xe5, 0x20, 0x1c, 0x06, 0x26, 0x1d, 0xfe, + 0x15, 0xd5, 0xe4, 0xbf, 0x18, 0xda, 0xd6, 0x10, 0x14, 0xda, 0xcb, 0xeb, 0xea, + 0x15, 0xf3, 0x08, 0x59, 0x25, 0xf5, 0x19, 0x2a, 0xf8, 0xdb, 0x00, 0x7f, 0x0c, + 0xf1, 0xe1, 0x26, 0x00, 0xfc, 0xfb, 0x05, 0xf8, 0xae, 0x05, 0xf2, 0xe5, 0xfc, + 0xf2, 0xfb, 0xfc, 0xf7, 0xf6, 0xe4, 0x17, 0x31, 0xc3, 0xf3, 0xf7, 0xd0, 0x69, + 0xef, 0xfc, 0xeb, 0x1c, 0xd0, 0xda, 0x1b, 0x09, 0x38, 0xc0, 0xfc, 0xfb, 0x03, + 0xca, 0xcf, 0x7f, 0x0b, 0xfb, 0xe1, 0xd4, 0x1d, 0xad, 0xd7, 0xe5, 0x0f, 0x12, + 0x33, 0x50, 0x01, 0x00, 0x08, 0x14, 0x30, 0x15, 0xd2, 0xdb, 0xcd, 0xe7, 0x02, + 0x2b, 0xf9, 0xfb, 0x04, 0xf9, 0x08, 0xc7, 0xca, 0xf1, 0xec, 0xd1, 0xf0, 0xde, + 0xe5, 0x0c, 0xff, 0xe9, 0x24, 0xe7, 0xfb, 0x4b, 0xc8, 0xeb, 0x2c, 0x36, 0xe1, + 0x53, 0xfb, 0xe9, 0xf3, 0xc7, 0x00, 0xe2, 0xee, 0x61, 0xea, 0x09, 0x30, 0xea, + 0xc3, 0xec, 0x0e, 0x57, 0xcd, 0xde, 0x35, 0xe4, 0xf2, 0xcd, 0x0a, 0x01, 0x56, + 0x37, 0xdc, 0xf1, 0x26, 0x0c, 0x34, 0xd2, 0x45, 0x11, 0x0e, 0xef, 0xce, 0x03, + 0xc4, 0xfd, 0x1e, 0x0e, 0xf8, 0x50, 0x07, 0x38, 0xf3, 0x00, 0x03, 0x34, 0x12, + 0xd9, 0x2b, 0x0a, 0xed, 0xdc, 0x24, 0xef, 0xcb, 0x3b, 0x10, 0x1a, 0xc9, 0xdc, + 0x28, 0x13, 0x4b, 0xd5, 0x03, 0xdb, 0xf3, 0x49, 0xff, 0xb3, 0xb3, 0xf9, 0x0a, + 0xc4, 0xf0, 0xf5, 0xf1, 0x0d, 0xda, 0x0d, 0xec, 0x0b, 0x0d, 0xdb, 0xfa, 0xcd, + 0x14, 0x0d, 0x0b, 0xce, 0x1b, 0x17, 0x01, 0xf6, 0xf1, 0x07, 0x09, 0xe4, 0x1e, + 0xe5, 0xee, 0x29, 0x10, 0xda, 0x92, 0xf1, 0x21, 0xec, 0xe5, 0x27, 0xfa, 0x14, + 0x08, 0xe8, 0x03, 0xdc, 0xfa, 0xee, 0x18, 0xeb, 0xfd, 0xf0, 0xe5, 0xf9, 0xea, + 0xf3, 0xb4, 0xff, 0xde, 0xff, 0xeb, 0xf9, 0x39, 0x03, 0x09, 0xf0, 0x0e, 0xe1, + 0xfd, 0x1c, 0x13, 0xd5, 0xff, 0xdf, 0x10, 0x10, 0x2f, 0xef, 0x08, 0x81, 0xe7, + 0xd9, 0x33, 0xe3, 0xf9, 0x2a, 0xda, 0xf7, 0xd8, 0xe1, 0xb5, 0xfb, 0x10, 0xfa, + 0xd9, 0xf1, 0xe1, 0x05, 0x0c, 0x14, 0xf3, 0x0f, 0x36, 0xfe, 0xf8, 0x26, 0x0d, + 0x05, 0x04, 0xbd, 0x2a, 0xd1, 0xf7, 0xe1, 0x08, 0xe4, 0xde, 0xfd, 0xd2, 0xe8, + 0xf1, 0x0e, 0x0d, 0x01, 0xe1, 0xdc, 0x45, 0xb3, 0x98, 0xb8, 0xe3, 0xf7, 0x05, + 0xc8, 0x19, 0xf3, 0x02, 0xe4, 0xf2, 0x13, 0xe6, 0xf8, 0xf2, 0x17, 0xc4, 0xf0, + 0xe3, 0xdc, 0x01, 0xd0, 0xe4, 0x3a, 0xcc, 0xfb, 0x04, 0x08, 0xd7, 0xfc, 0xd3, + 0x08, 0x22, 0xeb, 0x3e, 0x55, 0xa9, 0xcd, 0xf4, 0x16, 0x41, 0x17, 0x1b, 0xd4, + 0xfd, 0xfa, 0xd4, 0x4d, 0x23, 0x30, 0x42, 0x62, 0x54, 0xd9, 0xd6, 0x35, 0xf7, + 0x26, 0x65, 0x09, 0x20, 0xdb, 0x7f, 0xfa, 0xf7, 0xf4, 0x19, 0xab, 0xb5, 0x17, + 0xd4, 0x04, 0xde, 0xbd, 0xbb, 0x0b, 0x2e, 0xe8, 0x06, 0x0b, 0xf2, 0x0e, 0x0a, + 0x07, 0x21, 0x16, 0xe4, 0xda, 0x69, 0xd8, 0x1a, 0x63, 0x1d, 0xe9, 0xf3, 0xf0, + 0x09, 0xdc, 0xbf, 0xcf, 0xc9, 0x1e, 0x22, 0xdf, 0x43, 0x39, 0x20, 0x30, 0x42, + 0x20, 0xd2, 0xc3, 0x1a, 0x00, 0x1d, 0xda, 0x2b, 0x34, 0x1d, 0x18, 0xda, 0x2e, + 0xfe, 0xdc, 0x03, 0xb6, 0xee, 0x00, 0x2e, 0xe7, 0x12, 0xcd, 0xf4, 0x4d, 0x1f, + 0x19, 0x3d, 0xc9, 0xfc, 0x00, 0xfd, 0xfe, 0xf2, 0x22, 0xca, 0x2f, 0xe5, 0xff, + 0x01, 0xef, 0x2f, 0xc3, 0xf3, 0x36, 0x19, 0x31, 0x15, 0xc5, 0x07, 0x0b, 0x21, + 0x2b, 0xae, 0xe6, 0x63, 0xe4, 0x03, 0xf4, 0xe4, 0xfe, 0xd6, 0x2b, 0xdc, 0x10, + 0xfa, 0x08, 0x02, 0xd3, 0xd9, 0xc5, 0x37, 0xe4, 0x18, 0xa3, 0x45, 0xee, 0xc1, + 0xf1, 0x20, 0x03, 0xf8, 0x27, 0xfc, 0x37, 0x2e, 0x1c, 0xb2, 0xf7, 0xf4, 0xad, + 0x04, 0xb5, 0xf6, 0x11, 0x1f, 0xe2, 0x00, 0x20, 0x03, 0x0d, 0x07, 0xf7, 0x2b, + 0xf6, 0x5d, 0xc7, 0x0e, 0x55, 0xf0, 0xfc, 0x86, 0x0a, 0x4c, 0xdb, 0xfc, 0x33, + 0xa3, 0xff, 0x75, 0x26, 0x03, 0xe0, 0xc5, 0xca, 0x1d, 0x22, 0x1d, 0xed, 0xe8, + 0x96, 0x7d, 0x05, 0x3e, 0xdb, 0x4b, 0x38, 0xd3, 0x7f, 0x26, 0xfb, 0xfa, 0xf8, + 0xcc, 0x0a, 0x10, 0x40, 0x66, 0x5b, 0x27, 0x21, 0xc0, 0x0a, 0x1d, 0xeb, 0x1c, + 0x1f, 0xb9, 0xf8, 0x1f, 0xf2, 0xff, 0xc9, 0x5c, 0xd3, 0x58, 0xda, 0x02, 0xe6, + 0xdf, 0xe3, 0xf8, 0x10, 0x10, 0x37, 0xfa, 0x02, 0x58, 0xec, 0xdf, 0x28, 0xb3, + 0x40, 0xf4, 0x26, 0xd8, 0xf6, 0xad, 0x06, 0xe8, 0x0e, 0xf4, 0xa7, 0x19, 0x26, + 0xd3, 0xe5, 0x2c, 0x13, 0xa8, 0xf6, 0xbc, 0x81, 0xda, 0xea, 0xd7, 0xf9, 0xf6, + 0x60, 0x53, 0x06, 0xd8, 0xff, 0xcc, 0xf0, 0x0d, 0xe3, 0xee, 0xc0, 0xe8, 0xf8, + 0xed, 0x1f, 0x2a, 0x11, 0x26, 0xbb, 0x44, 0x07, 0x0a, 0xd9, 0xe8, 0xe6, 0x10, + 0xb8, 0x19, 0x25, 0xd6, 0xbe, 0x3d, 0x1d, 0xdd, 0xe1, 0xfd, 0xf3, 0xee, 0x38, + 0x0a, 0xe0, 0x0c, 0xeb, 0x02, 0x04, 0x00, 0x24, 0x0a, 0xdf, 0x29, 0x15, 0x0b, + 0xba, 0xf6, 0x95, 0x46, 0xc3, 0x04, 0x63, 0x4e, 0xb3, 0x12, 0xd5, 0xd5, 0x72, + 0xe1, 0xf6, 0xf1, 0x16, 0x40, 0xfd, 0xf7, 0x4e, 0x6d, 0xfc, 0xbf, 0xf2, 0xfb, + 0x18, 0x15, 0xd1, 0x00, 0x0e, 0x00, 0xea, 0xfa, 0xfd, 0x77, 0x3b, 0xe0, 0x7f, + 0xf7, 0x01, 0xf8, 0x14, 0xfc, 0x93, 0xcd, 0xcc, 0xe0, 0xe5, 0xdd, 0x03, 0xec, + 0xce, 0x1e, 0xe0, 0x1f, 0x18, 0xf9, 0xd1, 0xe5, 0xf6, 0x4c, 0xf1, 0xcb, 0x03, + 0x3a, 0xcf, 0xd7, 0xe1, 0xce, 0xc9, 0x0d, 0x37, 0xae, 0x0e, 0xd4, 0x39, 0xea, + 0xe7, 0xf2, 0xfa, 0x11, 0xf5, 0xeb, 0x17, 0xf7, 0x3b, 0x10, 0xd2, 0x32, 0x02, + 0xee, 0xe5, 0xb9, 0xf7, 0xcb, 0xfa, 0x14, 0xf7, 0x0a, 0xf3, 0x34, 0x1f, 0xf4, + 0x3c, 0xf8, 0x0b, 0xcd, 0xd3, 0x18, 0x0f, 0x21, 0x0c, 0xd8, 0xdf, 0x22, 0x09, + 0xfd, 0xdb, 0x1b, 0xe4, 0x19, 0x1e, 0x11, 0xff, 0x18, 0xbe, 0xdf, 0x26, 0x4b, + 0xe2, 0x11, 0x69, 0xfe, 0x3f, 0x26, 0x68, 0xea, 0x04, 0xae, 0xd4, 0x05, 0xfd, + 0xf9, 0x0e, 0x4e, 0xde, 0x21, 0xf0, 0x48, 0x0f, 0x2f, 0xc0, 0xc3, 0x90, 0xf6, + 0x0f, 0x1e, 0x64, 0x03, 0xb7, 0x41, 0x24, 0x7f, 0x25, 0xcd, 0xe6, 0x10, 0xdf, + 0xb9, 0xb9, 0xe3, 0xd5, 0x90, 0xc2, 0x19, 0xd9, 0x0f, 0xc5, 0xe0, 0xd6, 0x34, + 0xb5, 0xf2, 0xf6, 0x6b, 0x4e, 0x0b, 0xe1, 0xcb, 0x33, 0xf3, 0x4e, 0xf5, 0xf5, + 0xc9, 0x7b, 0xc4, 0xb6, 0xc4, 0x25, 0xc0, 0x0b, 0xc5, 0x40, 0xbb, 0x12, 0x1c, + 0x9e, 0xb5, 0x40, 0x01, 0xc3, 0x2f, 0xfc, 0x3a, 0x1a, 0xc9, 0xe0, 0xff, 0x9d, + 0x8e, 0x3e, 0xd9, 0x09, 0xc1, 0xf7, 0x12, 0xd0, 0xe3, 0x0d, 0xd9, 0xbf, 0x35, + 0x21, 0xa1, 0x8a, 0x46, 0xb7, 0xed, 0xee, 0xaa, 0xbc, 0x02, 0x13, 0x00, 0xda, + 0x51, 0x92, 0x59, 0x64, 0xfc, 0xce, 0xec, 0xd2, 0x08, 0xda, 0x22, 0xf2, 0x0d, + 0x65, 0x14, 0x06, 0x0c, 0x18, 0x4d, 0x08, 0xb8, 0xc5, 0x3b, 0x90, 0x57, 0xec, + 0xdf, 0x08, 0x32, 0xf6, 0x3a, 0x16, 0x59, 0xd1, 0x44, 0xd8, 0x03, 0x12, 0x22, + 0xe6, 0xf3, 0x1f, 0xf2, 0x16, 0x71, 0xe1, 0x0b, 0xe8, 0xeb, 0xdc, 0xdb, 0xd9, + 0x2e, 0x04, 0xe5, 0x39, 0x29, 0x5d, 0x11, 0x11, 0x18, 0x2b, 0xd5, 0xda, 0xfc, + 0x1d, 0x2b, 0x2c, 0xe6, 0xf2, 0xff, 0x0d, 0xd4, 0xfb, 0xfc, 0x66, 0x07, 0xf7, + 0x2c, 0xef, 0xf3, 0x27, 0x13, 0x0f, 0xeb, 0xdd, 0x1b, 0x9d, 0xdb, 0xf6, 0xbe, + 0xd2, 0x0f, 0xa7, 0x13, 0x41, 0x32, 0x0b, 0x1d, 0x3d, 0xd7, 0xfa, 0x1a, 0xd7, + 0xfe, 0x01, 0x0b, 0xe9, 0xd6, 0x2d, 0xfb, 0x02, 0xed, 0x12, 0xed, 0xcd, 0xd6, + 0x06, 0x7f, 0x6f, 0x01, 0x46, 0x2f, 0xf8, 0x24, 0x00, 0xa9, 0x48, 0x07, 0xff, + 0x1d, 0xe2, 0x38, 0x17, 0xf5, 0x3b, 0xfc, 0x01, 0x56, 0xbf, 0x47, 0x03, 0x19, + 0x5c, 0x16, 0x03, 0x44, 0xce, 0xe5, 0x22, 0xeb, 0xb0, 0x2a, 0x0f, 0xdb, 0x01, + 0xe0, 0x0c, 0x13, 0x18, 0xd5, 0x16, 0x57, 0x09, 0xf5, 0x4c, 0x1f, 0x3e, 0xf3, + 0xed, 0xd5, 0xfd, 0xee, 0xd8, 0xf0, 0xdd, 0xd7, 0xf9, 0x2e, 0x1d, 0xe7, 0xb3, + 0x33, 0xe1, 0x16, 0x38, 0xff, 0x17, 0x08, 0xab, 0xfa, 0xd8, 0xa7, 0xdb, 0xfa, + 0x02, 0x05, 0xb7, 0x59, 0xf0, 0xde, 0xd6, 0x12, 0xc1, 0x08, 0x00, 0x05, 0xd4, + 0xf0, 0xe7, 0x21, 0xcb, 0x0c, 0xf1, 0x34, 0x02, 0x0a, 0xfb, 0x29, 0xe4, 0xed, + 0xb9, 0xac, 0xda, 0x10, 0x2f, 0x2f, 0xf5, 0x18, 0x7f, 0xfa, 0x6f, 0x35, 0x15, + 0x4a, 0xf9, 0x20, 0x0f, 0x1e, 0x04, 0x23, 0x0c, 0x0b, 0x31, 0x3e, 0x3a, 0xfb, + 0xea, 0xfd, 0x06, 0x05, 0xd6, 0x0e, 0x13, 0x3f, 0xed, 0xf5, 0x53, 0xcc, 0xbc, + 0x21, 0xd1, 0xd8, 0x0e, 0x20, 0xc6, 0x03, 0x0d, 0x55, 0xef, 0xe7, 0xe0, 0x15, + 0xd6, 0xfb, 0x42, 0x35, 0xeb, 0x95, 0xa0, 0xd5, 0x0b, 0x07, 0x10, 0xda, 0x28, + 0x04, 0xe9, 0xdf, 0x2d, 0xed, 0x0e, 0x13, 0xc5, 0xf8, 0x09, 0xe7, 0x35, 0xc5, + 0xfc, 0x12, 0x03, 0xf9, 0xe6, 0x15, 0x03, 0xf0, 0x23, 0xe8, 0xe3, 0xed, 0xf0, + 0x10, 0xec, 0x15, 0x28, 0xf6, 0xf0, 0x1d, 0x2d, 0x2b, 0x19, 0x06, 0xf4, 0x03, + 0x1c, 0x3a, 0xe0, 0x09, 0xc6, 0xe7, 0xea, 0x24, 0xf0, 0x2a, 0x5a, 0xfb, 0xfe, + 0x13, 0x48, 0x0b, 0x14, 0xed, 0x18, 0xf5, 0xeb, 0x29, 0x24, 0xe0, 0x08, 0x3d, + 0x09, 0xc6, 0x81, 0xec, 0x29, 0xfa, 0xed, 0xe5, 0x0a, 0xfa, 0x11, 0xf9, 0xa2, + 0x1d, 0xe6, 0xf5, 0xf4, 0x05, 0xe9, 0x1d, 0x54, 0xeb, 0xcc, 0x19, 0x52, 0xea, + 0x2e, 0xf9, 0xf4, 0x04, 0x05, 0x34, 0xd2, 0x2b, 0xd6, 0x02, 0x1e, 0xfc, 0x09, + 0x07, 0x2d, 0x17, 0x3b, 0x08, 0xc2, 0x28, 0x14, 0xf0, 0x21, 0xe0, 0x20, 0xc6, + 0x40, 0xfd, 0xfb, 0x2a, 0x1f, 0xf1, 0x0b, 0x0f, 0x0f, 0x09, 0xf2, 0xf3, 0xd2, + 0x5c, 0x46, 0xdc, 0x04, 0xc8, 0x9b, 0xeb, 0xf9, 0x99, 0x33, 0xdc, 0x3a, 0x02, + 0xe1, 0xf1, 0xe6, 0xcb, 0x21, 0x0e, 0xea, 0xa8, 0x15, 0xe7, 0x41, 0xe8, 0x15, + 0xf6, 0x3f, 0x35, 0xe2, 0xe2, 0xe1, 0x44, 0x38, 0x40, 0xc1, 0xac, 0xde, 0x1f, + 0xd5, 0xd5, 0xfb, 0x01, 0x4e, 0x43, 0x2d, 0xea, 0xe4, 0xdb, 0xa9, 0xbf, 0x8b, + 0x21, 0xc2, 0x18, 0xf0, 0x30, 0x11, 0x2e, 0x11, 0xfe, 0x9d, 0xb9, 0xc2, 0x7f, + 0xbd, 0x12, 0x0f, 0x19, 0x41, 0x6f, 0xfe, 0xf9, 0xd4, 0x21, 0x0a, 0x60, 0x0b, + 0x09, 0xcb, 0xf4, 0x09, 0xe4, 0xee, 0x0e, 0x35, 0x3e, 0x08, 0x26, 0x73, 0x15, + 0x33, 0x12, 0x1b, 0xf0, 0xed, 0xdf, 0x22, 0x27, 0x0f, 0x09, 0x06, 0xc0, 0x52, + 0xfb, 0x22, 0x29, 0x39, 0x2a, 0xf6, 0xed, 0x38, 0x22, 0xe8, 0x24, 0x1e, 0xe0, + 0xbe, 0xe7, 0xec, 0x28, 0x46, 0x0f, 0x2e, 0xf6, 0x0e, 0xfb, 0xd9, 0x53, 0xef, + 0xcf, 0x18, 0x20, 0xdd, 0xb6, 0xf8, 0x3d, 0xeb, 0xd6, 0xdd, 0xe4, 0xd3, 0xd2, + 0xed, 0xdf, 0xc3, 0xd0, 0x02, 0x3b, 0xf9, 0xd7, 0xfb, 0x0f, 0xff, 0xf7, 0x19, + 0xcc, 0xfe, 0xe5, 0xe8, 0x35, 0xda, 0xf4, 0x06, 0xfc, 0x1b, 0xcd, 0xdf, 0x13, + 0xd5, 0xee, 0xdf, 0x32, 0xf6, 0x2f, 0x2c, 0xbb, 0xfc, 0xf0, 0x00, 0xe5, 0xe3, + 0x1f, 0xda, 0x10, 0xd7, 0x3d, 0x29, 0xec, 0xf0, 0xf3, 0xe9, 0x7f, 0xe3, 0xb8, + 0xdf, 0x40, 0x4e, 0xd4, 0xec, 0x1f, 0x16, 0x30, 0xe7, 0x17, 0x12, 0x0c, 0xe2, + 0xd3, 0x18, 0x04, 0x1c, 0xc8, 0x21, 0xd4, 0x11, 0xf0, 0xbd, 0xdf, 0xe1, 0xf5, + 0xd2, 0x14, 0x56, 0xeb, 0x14, 0x09, 0x04, 0xfe, 0x14, 0xfb, 0xac, 0xec, 0xc1, + 0x1e, 0x2f, 0x1e, 0xfa, 0xdd, 0x00, 0x68, 0xdd, 0xee, 0xd2, 0x31, 0x4d, 0xfe, + 0x01, 0xf3, 0x6e, 0xbc, 0xbd, 0xff, 0x0a, 0xf2, 0xc3, 0xeb, 0x12, 0xcc, 0xc2, + 0x91, 0x03, 0x0d, 0x66, 0xe2, 0xd6, 0xd3, 0xc6, 0xd1, 0xd4, 0x3c, 0xe0, 0xdb, + 0x4d, 0x0f, 0xd8, 0xa0, 0xe3, 0xd0, 0xbd, 0x01, 0x0c, 0xe6, 0xed, 0x0f, 0x3d, + 0x16, 0x26, 0x36, 0x0e, 0x0c, 0x07, 0x00, 0x68, 0x34, 0x05, 0x14, 0xf1, 0x87, + 0xea, 0x32, 0xbd, 0x5b, 0xaf, 0x42, 0x31, 0xec, 0xd4, 0x2f, 0x81, 0x65, 0x25, + 0x07, 0x3e, 0x3e, 0x30, 0x15, 0x8e, 0xcf, 0x9e, 0x13, 0xf8, 0x03, 0xc6, 0x2a, + 0x37, 0x1a, 0xfc, 0x13, 0x27, 0xe2, 0x96, 0xd2, 0x2c, 0xe6, 0xfd, 0x32, 0xca, + 0xc6, 0x1a, 0x2d, 0xa5, 0xe0, 0x05, 0xed, 0xfe, 0x2c, 0x17, 0xdb, 0x19, 0x18, + 0xf4, 0x4e, 0x10, 0xf9, 0x6b, 0x15, 0x0a, 0x30, 0x1c, 0x3e, 0x50, 0x86, 0xdf, + 0x29, 0x24, 0x13, 0xe6, 0xbe, 0x2d, 0x24, 0x1d, 0x04, 0xc5, 0xd0, 0x11, 0x1a, + 0x04, 0x04, 0xdb, 0xf6, 0xe8, 0x0f, 0x15, 0xe3, 0xc4, 0x08, 0x2d, 0xfb, 0xd7, + 0x17, 0x35, 0xc2, 0x1b, 0x23, 0xdd, 0x0f, 0x17, 0xf8, 0xf0, 0x0d, 0x1c, 0xd1, + 0x6e, 0xc5, 0xc6, 0x08, 0x13, 0xd3, 0xed, 0x56, 0x10, 0xde, 0xf5, 0x23, 0x01, + 0x06, 0x0b, 0x19, 0xee, 0xff, 0x0d, 0x5c, 0xe3, 0x07, 0x27, 0x0e, 0x35, 0xdb, + 0x14, 0xe5, 0x1f, 0x2d, 0x23, 0xf5, 0x32, 0xee, 0xc9, 0xd4, 0xe2, 0xe9, 0x18, + 0xec, 0x3b, 0xe6, 0xd0, 0x04, 0x05, 0xd9, 0xff, 0xa8, 0xf0, 0xcc, 0xd2, 0xed, + 0x09, 0x00, 0xf6, 0xeb, 0xec, 0xbe, 0x0d, 0x20, 0xf7, 0x40, 0x22, 0x0f, 0x08, + 0x30, 0xd5, 0x28, 0xb1, 0x1f, 0x1b, 0x15, 0x09, 0xf1, 0x0b, 0xd4, 0xd1, 0x17, + 0x81, 0x15, 0x01, 0x2a, 0x03, 0x3d, 0xe0, 0xce, 0x1a, 0x37, 0xd6, 0xb6, 0x14, + 0xe5, 0xe3, 0xbe, 0x18, 0xee, 0x27, 0xe0, 0xff, 0xc5, 0xf6, 0xea, 0xcb, 0x5a, + 0xdf, 0xf0, 0x49, 0xc1, 0xe9, 0xdc, 0xab, 0x3d, 0x0d, 0x17, 0xf8, 0x1c, 0xdb, + 0x02, 0xcf, 0x24, 0xe7, 0x16, 0xee, 0x20, 0x06, 0x13, 0x39, 0x30, 0x19, 0xd0, + 0xb6, 0x25, 0x01, 0xe8, 0x62, 0xc8, 0x00, 0xd5, 0x5b, 0xf5, 0x16, 0xec, 0x16, + 0x04, 0x55, 0x28, 0xf3, 0xdb, 0xde, 0xea, 0x40, 0xe1, 0x4c, 0x33, 0xca, 0xdd, + 0x0d, 0x21, 0xfc, 0x00, 0x41, 0x23, 0xec, 0x3d, 0xe0, 0xdf, 0xd2, 0x1b, 0x4b, + 0x38, 0xfd, 0xd2, 0xf1, 0xc9, 0x95, 0xfe, 0x55, 0xea, 0xdc, 0xfd, 0xcc, 0x37, + 0x26, 0x24, 0x28, 0xf3, 0x49, 0xd4, 0xdb, 0x25, 0xdf, 0x11, 0x13, 0x24, 0x19, + 0x04, 0x4e, 0x14, 0xc7, 0x0c, 0xfb, 0x0c, 0x26, 0x13, 0xf0, 0x05, 0x16, 0x81, + 0xa2, 0x22, 0xf5, 0xf9, 0xe1, 0x11, 0xc7, 0xea, 0xf4, 0xec, 0xf2, 0x1d, 0x1d, + 0x33, 0x34, 0x55, 0xaf, 0x06, 0x2d, 0xde, 0x90, 0xc1, 0x4c, 0x0a, 0x07, 0xc5, + 0xfa, 0x6f, 0x2c, 0xdf, 0x40, 0x06, 0xe6, 0xff, 0x27, 0x18, 0xab, 0x60, 0x7f, + 0xf0, 0x55, 0xf7, 0x9b, 0xdf, 0xc7, 0xe3, 0x19, 0xed, 0x20, 0xa5, 0xfe, 0xfa, + 0xdd, 0xd7, 0x0b, 0xe1, 0x7c, 0x38, 0xea, 0x00, 0x1e, 0xea, 0xd4, 0x12, 0xba, + 0xe7, 0xa3, 0x23, 0xbd, 0x5b, 0x04, 0x24, 0x3f, 0xe0, 0xbc, 0x13, 0x19, 0xf6, + 0xf4, 0xeb, 0xeb, 0x0d, 0x58, 0x52, 0x2b, 0x0d, 0x3b, 0x1f, 0xfa, 0xdf, 0xfb, + 0xb2, 0xc3, 0xe2, 0x58, 0xb0, 0xf4, 0xd2, 0xdf, 0xe5, 0xe9, 0xf9, 0xc5, 0xda, + 0xcf, 0x48, 0x0c, 0xdb, 0xe4, 0xcf, 0xd6, 0x2f, 0x2d, 0xea, 0x38, 0x34, 0x17, + 0xfd, 0x3a, 0xe9, 0xce, 0x1b, 0x00, 0x29, 0x13, 0xc4, 0xe6, 0xef, 0xc8, 0x1d, + 0xdd, 0x3f, 0x0a, 0x2a, 0xc4, 0x05, 0x0e, 0x43, 0xdb, 0xea, 0xf1, 0xe9, 0xb1, + 0x53, 0xea, 0xa5, 0x11, 0xf7, 0x2a, 0x17, 0xb4, 0x06, 0xda, 0xcc, 0xe9, 0x09, + 0xcc, 0xe2, 0x81, 0x39, 0xd4, 0xdd, 0xf6, 0x06, 0x06, 0x9c, 0xd7, 0x20, 0x60, + 0xe6, 0x2d, 0xea, 0xc8, 0x42, 0xd4, 0x26, 0xf3, 0x20, 0x18, 0xf0, 0x37, 0x56, + 0xcc, 0xe3, 0x50, 0xe8, 0xef, 0x2e, 0xe2, 0x46, 0xdd, 0x68, 0xe2, 0xfe, 0x07, + 0xa6, 0x98, 0xed, 0x4e, 0xd6, 0xe2, 0x9f, 0xd3, 0x5f, 0xc9, 0xd5, 0x1f, 0xc9, + 0x09, 0xd5, 0xa8, 0x06, 0xfe, 0xe1, 0xe1, 0xc2, 0x70, 0x25, 0xf1, 0xc4, 0x42, + 0x3c, 0x57, 0xa9, 0xce, 0xea, 0x17, 0x3f, 0x00, 0xdc, 0x1b, 0xdc, 0xd0, 0xf8, + 0xb7, 0xfe, 0xd5, 0x00, 0xcd, 0xe7, 0xe9, 0xcd, 0xbf, 0x0b, 0x46, 0x1f, 0xe4, + 0x32, 0xde, 0xbc, 0x19, 0x18, 0xd7, 0x20, 0xd2, 0xf2, 0x39, 0x4d, 0x30, 0x26, + 0x41, 0xec, 0xcd, 0xc8, 0x10, 0xeb, 0xcf, 0xe3, 0xdd, 0xeb, 0x2a, 0xfd, 0x3c, + 0x2b, 0x8e, 0xe5, 0xfa, 0xc9, 0xf0, 0x08, 0x19, 0xb0, 0xb9, 0xeb, 0x1e, 0xd0, + 0xfb, 0xf9, 0xce, 0x12, 0x50, 0x31, 0xcb, 0x5b, 0xae, 0xf5, 0xf4, 0xec, 0x08, + 0xcd, 0x37, 0xdf, 0x1b, 0xfa, 0x0d, 0xf5, 0xf4, 0xf8, 0xb2, 0xff, 0xd8, 0x3f, + 0xe6, 0xcc, 0x0c, 0xeb, 0xf3, 0x28, 0xee, 0x01, 0xf2, 0x14, 0x81, 0x22, 0x0d, + 0xfb, 0x00, 0xf0, 0xe1, 0x2b, 0xee, 0x1a, 0xec, 0xf5, 0x0b, 0xe9, 0xb6, 0x0e, + 0xdf, 0xc6, 0x21, 0x11, 0xfd, 0xdf, 0xd2, 0x15, 0xf9, 0x17, 0xf6, 0x2d, 0xfd, + 0xf9, 0xda, 0x02, 0xcf, 0x16, 0xff, 0x0e, 0x11, 0x20, 0x55, 0x29, 0xdd, 0xd1, + 0x62, 0xc9, 0xfd, 0xb5, 0x26, 0x1e, 0xc1, 0x0b, 0x22, 0xf7, 0x19, 0x0e, 0x11, + 0x08, 0xa6, 0x14, 0x02, 0xe1, 0xf8, 0xd4, 0xc8, 0x16, 0xd2, 0xf2, 0xee, 0xf2, + 0xb0, 0x05, 0xf1, 0xf9, 0x0c, 0xc1, 0x09, 0x1a, 0x0b, 0xf2, 0x45, 0xf3, 0x74, + 0xdb, 0x0e, 0x0d, 0xda, 0xf1, 0xd2, 0x19, 0xdf, 0xf4, 0xd9, 0xad, 0xf5, 0x0b, + 0x2d, 0x1a, 0xda, 0x17, 0xfd, 0x0f, 0x2f, 0x2a, 0x1a, 0xf0, 0xea, 0x06, 0xc0, + 0x00, 0x2a, 0x56, 0x0d, 0x65, 0xad, 0x37, 0xd8, 0xfa, 0xde, 0xae, 0xe8, 0x14, + 0xf2, 0xec, 0xf2, 0x23, 0x13, 0x2f, 0xcd, 0xec, 0x09, 0xf0, 0xa5, 0xee, 0x0a, + 0xee, 0xfa, 0xe0, 0xb2, 0x0f, 0xd6, 0x2a, 0x40, 0xff, 0x0d, 0xe0, 0x0a, 0xdd, + 0x1c, 0x09, 0x62, 0x07, 0x47, 0x08, 0xf9, 0xec, 0xa0, 0xbf, 0x30, 0x04, 0x10, + 0xdd, 0x39, 0x34, 0x7f, 0x1a, 0x18, 0x41, 0xc4, 0xe5, 0xf4, 0x34, 0x4d, 0xf8, + 0xde, 0xfa, 0x1d, 0x2e, 0x19, 0xff, 0xec, 0x1f, 0xff, 0xea, 0xfd, 0x0b, 0x0a, + 0x0b, 0x2d, 0x1d, 0xc5, 0xd0, 0xda, 0xe7, 0xd4, 0x3e, 0x3a, 0xff, 0x14, 0x1c, + 0xc9, 0x92, 0x21, 0x17, 0xe4, 0xfc, 0xd4, 0xc1, 0x6b, 0xe1, 0xf4, 0xd0, 0x08, + 0xc6, 0xdd, 0x5d, 0xc6, 0x61, 0x62, 0x16, 0x2a, 0xd8, 0xcd, 0x21, 0x19, 0xe0, + 0xd4, 0x1d, 0x41, 0xde, 0xdd, 0x10, 0x1d, 0x08, 0x37, 0x57, 0x06, 0x0d, 0xe9, + 0x0f, 0x67, 0x8e, 0x29, 0xf8, 0xd8, 0xba, 0xf7, 0xb9, 0xde, 0xfa, 0xaa, 0x07, + 0xa1, 0x07, 0xda, 0x02, 0x00, 0xf6, 0x18, 0x09, 0xe8, 0x1b, 0x1d, 0x07, 0x07, + 0x20, 0x54, 0xd3, 0x00, 0xc6, 0x4b, 0xb4, 0x41, 0xfb, 0xee, 0xf7, 0xf1, 0xdd, + 0xdf, 0xf7, 0x0e, 0x31, 0xc4, 0x39, 0x0e, 0x00, 0xcd, 0x06, 0xd5, 0x18, 0x1a, + 0x01, 0xf5, 0x17, 0x81, 0x3d, 0x3e, 0xd9, 0x1a, 0x3c, 0x0b, 0xf2, 0x45, 0x0d, + 0xa6, 0xd2, 0x1a, 0xb9, 0x4e, 0x0b, 0xcb, 0x3c, 0xeb, 0xfd, 0x28, 0xdc, 0xc6, + 0x12, 0xa4, 0xe5, 0xe4, 0xdd, 0xae, 0xa7, 0xe3, 0xd4, 0xe3, 0x20, 0xb9, 0xc2, + 0x01, 0x0b, 0xd4, 0x11, 0xe3, 0x44, 0xdd, 0xee, 0xcc, 0xf0, 0xb5, 0x1c, 0xf9, + 0x04, 0x52, 0xc3, 0x39, 0xf8, 0xeb, 0x03, 0x75, 0xf4, 0x17, 0x32, 0x25, 0x31, + 0xc0, 0x25, 0xf6, 0xfc, 0x58, 0xe8, 0xcf, 0xe7, 0x1e, 0xe7, 0x23, 0x04, 0x30, + 0x12, 0x1e, 0xec, 0xd6, 0x11, 0x37, 0x12, 0xdd, 0x23, 0xc4, 0xfe, 0x00, 0x05, + 0x02, 0xfc, 0xbb, 0xf4, 0xea, 0x01, 0x1c, 0x37, 0xe6, 0xd5, 0x52, 0x05, 0x13, + 0x31, 0xf7, 0xde, 0x10, 0xe9, 0xdd, 0xf2, 0xef, 0xdc, 0x01, 0x0d, 0xc9, 0x5f, + 0x09, 0xdd, 0x2f, 0x15, 0xdb, 0xe7, 0xf9, 0x97, 0x50, 0x0e, 0xf0, 0x60, 0xdd, + 0x4b, 0x54, 0xeb, 0x02, 0x1d, 0xf6, 0x1a, 0x24, 0xc4, 0xd9, 0x0f, 0x26, 0x91, + 0x7f, 0xdc, 0xf8, 0xf6, 0x3c, 0x4f, 0x32, 0x11, 0xf7, 0x3d, 0x1a, 0x26, 0xf0, + 0x0b, 0x17, 0xfa, 0xd5, 0xe2, 0x04, 0x15, 0xf3, 0xe9, 0xff, 0xba, 0xf9, 0x28, + 0xe9, 0xe9, 0xe8, 0x0a, 0xf3, 0x1f, 0x42, 0xdc, 0x0b, 0x0a, 0x08, 0x3f, 0xf5, + 0x01, 0x30, 0x10, 0xce, 0x93, 0xc9, 0x11, 0x13, 0xd9, 0xf0, 0xc2, 0xb7, 0xeb, + 0x0c, 0x0a, 0xde, 0xe3, 0x1e, 0x75, 0xc7, 0x3b, 0x32, 0xf5, 0x28, 0x1e, 0x26, + 0xf0, 0x4e, 0xfe, 0xa7, 0xeb, 0xd1, 0xf6, 0xa6, 0xf1, 0xdd, 0x2c, 0x06, 0x3c, + 0x25, 0xfc, 0x62, 0x30, 0xa0, 0x0c, 0xe2, 0x94, 0xca, 0xa4, 0x1c, 0xd7, 0xc4, + 0x32, 0x11, 0xc0, 0xe3, 0xe9, 0xce, 0xee, 0xf7, 0x02, 0x7f, 0xf3, 0xd9, 0xe1, + 0xe3, 0x46, 0x57, 0xe7, 0xa9, 0xaf, 0x14, 0x0d, 0x1a, 0x0a, 0xc3, 0xfc, 0xc8, + 0xfc, 0x18, 0xc7, 0xde, 0x17, 0x00, 0xd7, 0x59, 0x17, 0xe2, 0xed, 0x3d, 0x9e, + 0x6a, 0x1c, 0x39, 0x18, 0x43, 0x0b, 0x0f, 0xd9, 0xab, 0xed, 0x13, 0x41, 0x11, + 0xcd, 0xe4, 0x60, 0xeb, 0xee, 0xb1, 0x02, 0xe9, 0x0a, 0x05, 0xee, 0x29, 0xe5, + 0xfc, 0xe3, 0xb5, 0xd4, 0xb2, 0x0f, 0xd9, 0xf7, 0xf8, 0xf6, 0x01, 0xf5, 0xfd, + 0xf5, 0x0b, 0xe9, 0xd7, 0x10, 0x0a, 0xca, 0xd8, 0xd7, 0xf4, 0xc7, 0x12, 0xe7, + 0x34, 0xd5, 0xf9, 0xeb, 0xff, 0x1b, 0x12, 0xe7, 0xd4, 0xc3, 0xee, 0xec, 0x4d, + 0x22, 0xf2, 0xe6, 0x37, 0x1b, 0xc5, 0x06, 0x2d, 0x03, 0xd2, 0xcf, 0x0f, 0xfe, + 0x20, 0xef, 0xe1, 0x17, 0xf1, 0xdf, 0x08, 0x3b, 0xd8, 0xd8, 0x03, 0xfd, 0x2e, + 0xdf, 0x4c, 0xed, 0xb9, 0x10, 0xe3, 0xdc, 0x19, 0xff, 0xdf, 0xf5, 0x05, 0x42, + 0xb1, 0x92, 0x87, 0xd0, 0xf6, 0xe7, 0xec, 0xe7, 0xf5, 0xd0, 0xdb, 0xd5, 0xe0, + 0xc9, 0xc9, 0xf9, 0xc1, 0x16, 0xfd, 0x65, 0xeb, 0x18, 0xfc, 0xeb, 0x01, 0x07, + 0x05, 0xe9, 0x05, 0xdc, 0x18, 0xee, 0xe7, 0x3f, 0xf9, 0x23, 0x16, 0x06, 0x20, + 0xfd, 0x01, 0x0d, 0x00, 0xde, 0xfb, 0xe4, 0x27, 0xea, 0xca, 0xbb, 0xe3, 0x0a, + 0xd8, 0x27, 0x81, 0xed, 0x14, 0x1a, 0xfa, 0x15, 0x8f, 0x1d, 0xf2, 0xed, 0xf3, + 0x65, 0xe6, 0x1c, 0x52, 0xd7, 0x2b, 0xe5, 0x10, 0xaf, 0x30, 0x4b, 0xd2, 0xfd, + 0x2a, 0x22, 0x2b, 0x34, 0xe6, 0xeb, 0x07, 0x37, 0xe9, 0x1b, 0x70, 0x06, 0xe1, + 0xe5, 0x02, 0x02, 0xd9, 0x03, 0x07, 0x05, 0x19, 0xfd, 0xf4, 0xe0, 0xad, 0x07, + 0xf8, 0x2f, 0x08, 0x1c, 0x1a, 0x1e, 0xfb, 0xef, 0xf4, 0xcd, 0x00, 0x10, 0xff, + 0x1a, 0x05, 0xb1, 0xb8, 0xd7, 0x08, 0x90, 0xe7, 0xc2, 0xf6, 0xcb, 0x10, 0xce, + 0x9f, 0x91, 0x0e, 0xbc, 0x3d, 0xbb, 0xd8, 0xc9, 0xe9, 0xf7, 0xc3, 0xf8, 0x2f, + 0x09, 0xaa, 0x01, 0x20, 0xe0, 0x3b, 0x04, 0x7f, 0x5c, 0xd7, 0x11, 0x38, 0x06, + 0xe7, 0x25, 0x0f, 0x9d, 0x2f, 0x2c, 0xea, 0x32, 0x3f, 0x21, 0x1b, 0x01, 0xb4, + 0xe3, 0xf3, 0x6a, 0xce, 0xf6, 0x19, 0xbd, 0xe7, 0x0d, 0xec, 0xc8, 0xba, 0x9a, + 0x1e, 0x41, 0x18, 0x29, 0x28, 0x03, 0xef, 0x07, 0xe7, 0xf4, 0xce, 0xf5, 0xed, + 0xcb, 0x3c, 0xdd, 0x05, 0x02, 0xe1, 0x00, 0xf7, 0x14, 0x25, 0x23, 0x06, 0xe6, + 0x33, 0x13, 0x0c, 0xe4, 0xc8, 0x7f, 0xc4, 0xf8, 0x15, 0x18, 0x0b, 0xe9, 0xed, + 0x36, 0x39, 0xfe, 0xfa, 0x0c, 0x20, 0x47, 0xe2, 0x00, 0x32, 0xcc, 0xc3, 0xf3, + 0x2d, 0xef, 0x04, 0x05, 0xb6, 0x03, 0xea, 0xc4, 0xfc, 0xf7, 0xe4, 0xfe, 0xfd, + 0xfd, 0x10, 0x05, 0x0f, 0xee, 0x0d, 0x2b, 0x18, 0xe2, 0xe8, 0x17, 0xfc, 0x24, + 0xf0, 0xec, 0x1f, 0xd1, 0xa1, 0x07, 0xfb, 0x13, 0x09, 0x00, 0x00, 0x02, 0xfb, + 0x10, 0x0a, 0x27, 0x04, 0xf3, 0xf6, 0xee, 0xf5, 0x04, 0x46, 0x08, 0x07, 0xf7, + 0x0d, 0x02, 0x01, 0x20, 0x1b, 0xfc, 0x24, 0x28, 0xc9, 0x02, 0x01, 0x12, 0xe9, + 0xf8, 0x17, 0x58, 0x0f, 0xfa, 0x28, 0xed, 0xfb, 0x16, 0xc0, 0xfe, 0xd8, 0xfb, + 0x1e, 0x2e, 0xeb, 0x23, 0x7f, 0x06, 0xfc, 0x01, 0x25, 0x38, 0xcd, 0x2b, 0xed, + 0xf4, 0x1d, 0x00, 0x28, 0xe4, 0x62, 0x0e, 0x03, 0x1c, 0xc4, 0x1e, 0xce, 0xe2, + 0x0d, 0xeb, 0xf3, 0x1e, 0xfe, 0xff, 0x7a, 0x32, 0xdd, 0xb6, 0xda, 0x09, 0x3e, + 0xf1, 0xc3, 0x1b, 0x37, 0x0a, 0x13, 0xe0, 0x11, 0x22, 0xef, 0xe6, 0xfe, 0xdc, + 0xf1, 0x04, 0xbb, 0xfe, 0xe5, 0x97, 0xc8, 0x2a, 0x9d, 0xcf, 0x11, 0xea, 0xf0, + 0xfe, 0x24, 0x08, 0xb9, 0x07, 0xf4, 0x18, 0x44, 0xea, 0x36, 0x09, 0x2a, 0xfa, + 0x42, 0x5f, 0x9c, 0xe1, 0xf0, 0x06, 0x22, 0x4d, 0xaf, 0xfb, 0xfb, 0x07, 0xe5, + 0xfd, 0xf4, 0xc8, 0xe8, 0x0f, 0x0b, 0x0f, 0x52, 0x4b, 0x26, 0xfb, 0x0e, 0x31, + 0x2e, 0xdf, 0xe3, 0x31, 0x22, 0x31, 0xcd, 0x33, 0x19, 0x00, 0x06, 0x01, 0xb8, + 0xee, 0x09, 0xf7, 0x08, 0xe1, 0xd7, 0xfe, 0xf8, 0xc4, 0x38, 0xf7, 0xfc, 0xd4, + 0xe0, 0x04, 0x1a, 0x1d, 0x33, 0x12, 0x05, 0xb7, 0xd9, 0x65, 0xee, 0x1c, 0x15, + 0xe8, 0x31, 0xc9, 0xc8, 0x1a, 0x1a, 0xfd, 0x23, 0x2a, 0xe7, 0xf4, 0xc1, 0x39, + 0xd2, 0xaa, 0xd2, 0xf7, 0xe1, 0x21, 0xe6, 0x1f, 0xe4, 0x32, 0x16, 0x11, 0xbd, + 0x1b, 0x98, 0x2d, 0x0a, 0x24, 0x0c, 0x6d, 0x6a, 0xdd, 0x00, 0x23, 0x3c, 0xbb, + 0x58, 0xc9, 0x0e, 0xd6, 0xec, 0xdc, 0xc8, 0xa1, 0x2d, 0xea, 0x3a, 0xff, 0x01, + 0x99, 0xd0, 0xc0, 0x7f, 0xfc, 0x89, 0x9f, 0x2d, 0x2e, 0xf3, 0xb0, 0x2a, 0x01, + 0x1a, 0xc0, 0xde, 0x39, 0xe2, 0xe6, 0xda, 0xc5, 0x51, 0x20, 0xf9, 0x4b, 0x05, + 0xf2, 0xe2, 0xe1, 0x17, 0xbb, 0x3c, 0xff, 0xd1, 0xd4, 0x13, 0xed, 0x25, 0x1c, + 0xe6, 0x02, 0x1e, 0xf5, 0x02, 0x21, 0x27, 0xbb, 0x32, 0x06, 0xa7, 0xe5, 0xef, + 0x06, 0xbc, 0x70, 0xff, 0x17, 0x4c, 0x1e, 0xd3, 0xef, 0x17, 0xe5, 0xf4, 0x00, + 0x6a, 0x0d, 0x0e, 0x0e, 0x51, 0x03, 0xe6, 0x24, 0xf0, 0xfa, 0xee, 0x38, 0x04, + 0x62, 0x12, 0x3a, 0xde, 0x1c, 0x11, 0x5a, 0xdf, 0xe0, 0x31, 0xe6, 0xc6, 0xe3, + 0xe8, 0x51, 0xe4, 0xc4, 0xf9, 0x19, 0xf3, 0xf1, 0x53, 0x07, 0xdf, 0x25, 0x2e, + 0x10, 0xda, 0x1f, 0xb4, 0xed, 0xfd, 0xf6, 0xfb, 0x0d, 0xc1, 0x1d, 0xdd, 0xd9, + 0x27, 0xbe, 0xbc, 0x39, 0xbb, 0x11, 0xcc, 0xe2, 0xcf, 0x34, 0x00, 0x34, 0x13, + 0xe8, 0x1f, 0x11, 0x81, 0x07, 0xb0, 0x32, 0x01, 0x22, 0x07, 0xc3, 0x0a, 0x0a, + 0xfd, 0x1c, 0x34, 0x4b, 0xd4, 0xfe, 0x05, 0xab, 0x0c, 0xcf, 0x07, 0x14, 0xd1, + 0x29, 0xf3, 0xf4, 0xb6, 0xd5, 0x54, 0xf5, 0x07, 0x70, 0xfb, 0xfa, 0xe3, 0xcc, + 0x12, 0xe6, 0xfd, 0x34, 0xac, 0x00, 0xf9, 0x03, 0x48, 0x3c, 0xce, 0xbe, 0x12, + 0xe4, 0xc7, 0x04, 0x1f, 0xe3, 0x0d, 0xd9, 0x32, 0xf5, 0x48, 0x04, 0x4f, 0xf7, + 0xeb, 0x2e, 0x34, 0x18, 0x2e, 0xef, 0x15, 0x02, 0x04, 0x16, 0xbb, 0xe3, 0xdd, + 0x16, 0x18, 0xfa, 0xee, 0xe0, 0xf7, 0x28, 0x22, 0x07, 0x0c, 0x0f, 0x37, 0xe5, + 0xf2, 0xdd, 0xe3, 0xfd, 0xfb, 0xcc, 0x7c, 0xf2, 0x1d, 0xf5, 0x2d, 0x08, 0xd3, + 0xc0, 0xdb, 0xeb, 0x09, 0x0f, 0xf3, 0x08, 0x03, 0xed, 0x1e, 0x02, 0x1a, 0x42, + 0xd9, 0xf4, 0x0c, 0xfe, 0xf1, 0xe7, 0xf1, 0x15, 0x0f, 0x11, 0xc7, 0xf5, 0xc4, + 0x01, 0xf4, 0x04, 0xe0, 0x13, 0xbf, 0xd2, 0x0d, 0x40, 0xec, 0x2a, 0x21, 0xdb, + 0x5a, 0x0d, 0x5b, 0xb5, 0x17, 0xf3, 0xf3, 0x15, 0xfd, 0xea, 0xf7, 0xdd, 0x10, + 0x07, 0xfd, 0x36, 0x7f, 0xb2, 0xf6, 0x28, 0x19, 0xff, 0xc0, 0x03, 0x16, 0x17, + 0xec, 0x03, 0xec, 0xdf, 0xc7, 0xf8, 0xe8, 0xc3, 0x03, 0x2b, 0x08, 0xef, 0x0c, + 0x18, 0x22, 0xf7, 0x2b, 0xe5, 0xde, 0x9f, 0x11, 0x20, 0x0f, 0x32, 0xbd, 0xfe, + 0x1d, 0x13, 0xac, 0x3d, 0xf7, 0xdd, 0x54, 0x09, 0x5a, 0x45, 0xd1, 0x10, 0xf6, + 0x19, 0xe1, 0x07, 0x6d, 0xda, 0xf8, 0xc5, 0x17, 0x13, 0xf7, 0xb8, 0x03, 0x27, + 0xee, 0x1c, 0xc9, 0xed, 0x58, 0xdc, 0xcb, 0x12, 0x04, 0x00, 0xee, 0xda, 0xfc, + 0xfd, 0xe8, 0x00, 0xfb, 0x06, 0x23, 0xf6, 0x1d, 0xf8, 0x2b, 0xe0, 0x1e, 0x41, + 0xe4, 0xd1, 0x7f, 0x06, 0x0f, 0xf8, 0xcb, 0x33, 0x09, 0x32, 0xec, 0x23, 0xfb, + 0xf0, 0x19, 0x05, 0x17, 0xf1, 0x2a, 0x11, 0xba, 0xbc, 0xd9, 0xea, 0xf0, 0xdf, + 0x4e, 0xff, 0x1a, 0xf2, 0x12, 0x1f, 0xe9, 0xf6, 0xd6, 0x1b, 0xa9, 0xfc, 0xf3, + 0xd2, 0xc1, 0x17, 0x17, 0xe7, 0x0e, 0x13, 0xf1, 0xff, 0x21, 0xe7, 0xf8, 0xd8, + 0xf3, 0xbe, 0x3d, 0xd3, 0x9b, 0xf7, 0x2b, 0x2f, 0xe4, 0xae, 0x56, 0xd6, 0x20, + 0xd3, 0x14, 0xcf, 0x25, 0xd4, 0xd8, 0x07, 0x81, 0xee, 0x24, 0x01, 0x1a, 0x0c, + 0xd4, 0xc5, 0xf9, 0x09, 0xeb, 0xf9, 0xd4, 0xcd, 0xe3, 0x07, 0x0c, 0xd5, 0x08, + 0x03, 0xfc, 0xea, 0x0f, 0x10, 0x00, 0x4e, 0xee, 0x23, 0xda, 0xca, 0xce, 0xff, + 0x09, 0xea, 0x26, 0xd2, 0x2a, 0x06, 0xd9, 0xf5, 0x04, 0x01, 0xdc, 0xf9, 0xf9, + 0x6b, 0x01, 0xeb, 0xfe, 0x09, 0x05, 0xef, 0xd0, 0x30, 0xe8, 0xf4, 0xfa, 0xed, + 0x03, 0x29, 0xc6, 0x00, 0xe2, 0xd0, 0xf5, 0xb9, 0xf9, 0x09, 0xb3, 0xf5, 0xd7, + 0xeb, 0xee, 0x24, 0x2f, 0xf6, 0x05, 0x05, 0xfe, 0x09, 0xd7, 0xcb, 0x4a, 0xea, + 0x36, 0x17, 0xeb, 0xd0, 0x14, 0xee, 0x12, 0xb8, 0xe0, 0x0a, 0x21, 0xe8, 0x1c, + 0x13, 0x07, 0x08, 0xf2, 0x39, 0xe5, 0x0a, 0x0e, 0x4e, 0x3f, 0x2d, 0x0e, 0x11, + 0xb3, 0xdf, 0xe7, 0xf3, 0xe8, 0x0a, 0xfd, 0x19, 0x29, 0x2c, 0x2d, 0xef, 0x3f, + 0xf6, 0x51, 0x2f, 0xf8, 0x1c, 0xea, 0x1c, 0x6a, 0x3a, 0x40, 0xcf, 0x49, 0xfc, + 0x2d, 0x11, 0xd4, 0x42, 0x2b, 0x1c, 0xde, 0xfa, 0x1b, 0x2f, 0xee, 0x24, 0xfd, + 0x21, 0xff, 0x0f, 0x24, 0xe8, 0x25, 0xb6, 0xd8, 0xe0, 0xef, 0xdb, 0x25, 0xb4, + 0xc4, 0xfc, 0xb5, 0x34, 0x2f, 0x58, 0xfe, 0x3a, 0xe4, 0x1d, 0x7a, 0x3e, 0xf0, + 0x33, 0x20, 0xf2, 0x11, 0xea, 0xd6, 0xec, 0xd9, 0xa0, 0x36, 0xb9, 0x01, 0xdc, + 0x14, 0x07, 0x32, 0xc3, 0x50, 0x7f, 0x14, 0x53, 0x50, 0x11, 0xd8, 0x62, 0xe7, + 0xfa, 0x00, 0x4b, 0xe6, 0x15, 0x3b, 0x20, 0x1d, 0x27, 0xfc, 0x9f, 0x01, 0x50, + 0x15, 0x0a, 0x59, 0x60, 0x37, 0x44, 0xd3, 0xf6, 0x1c, 0xfd, 0x13, 0x02, 0x0c, + 0x3d, 0x04, 0xc2, 0xdd, 0x39, 0x1e, 0x3a, 0xbc, 0xf9, 0xcb, 0xf9, 0x20, 0x0d, + 0xdd, 0xcc, 0xfd, 0x27, 0x0c, 0xf2, 0xfa, 0x30, 0x17, 0x9a, 0xa7, 0xf6, 0xc5, + 0x0a, 0x3c, 0x22, 0xca, 0xe6, 0x17, 0x09, 0xbc, 0x5f, 0xc4, 0x22, 0xb0, 0xfe, + 0x60, 0xfb, 0x61, 0xc6, 0x0b, 0x10, 0xdb, 0xed, 0x0f, 0x4c, 0x4d, 0xf5, 0xf0, + 0xe2, 0x1a, 0xfc, 0x07, 0xe2, 0xd5, 0x29, 0x01, 0x4e, 0x08, 0xba, 0xf7, 0x05, + 0xdb, 0x13, 0x02, 0x06, 0x0b, 0x32, 0x57, 0xc0, 0x23, 0x01, 0xd8, 0x25, 0x3c, + 0x43, 0x37, 0x09, 0x36, 0x1d, 0x1d, 0x69, 0x70, 0x03, 0xb2, 0x4e, 0xea, 0xf9, + 0xce, 0x10, 0xe9, 0x7f, 0xd5, 0xe5, 0x09, 0x4a, 0xd4, 0x82, 0x43, 0x21, 0x13, + 0x9d, 0x83, 0x32, 0x11, 0xf5, 0x2f, 0xcc, 0xd9, 0xfb, 0xb6, 0x6b, 0x09, 0x4c, + 0x65, 0x30, 0xae, 0x02, 0x1e, 0x06, 0xfb, 0xc5, 0xa6, 0xbc, 0xbe, 0xf1, 0x10, + 0x27, 0xd3, 0x66, 0xc6, 0x1b, 0x08, 0x16, 0xd3, 0x11, 0xe7, 0xef, 0xf5, 0x58, + 0x1b, 0xe6, 0xaf, 0x18, 0xe5, 0x3e, 0xef, 0xd9, 0xc6, 0x2f, 0x46, 0xc2, 0x09, + 0x2b, 0x08, 0x0a, 0x08, 0x17, 0x11, 0x1c, 0x1d, 0x2c, 0xf7, 0xf8, 0x14, 0xfc, + 0x2f, 0xff, 0xe3, 0xf0, 0x35, 0x4a, 0x28, 0xe4, 0x09, 0xf8, 0xfd, 0xce, 0x36, + 0xbe, 0xf3, 0xdc, 0x9f, 0x3c, 0xdd, 0xe1, 0xe7, 0x13, 0xb2, 0xeb, 0xe9, 0xfd, + 0xb7, 0x1a, 0xf7, 0x09, 0x46, 0xf5, 0x13, 0x0d, 0x01, 0x13, 0x5d, 0x22, 0xfa, + 0xe7, 0xe4, 0x37, 0x1d, 0x14, 0xf5, 0xf4, 0xff, 0xd1, 0x1e, 0xf0, 0xff, 0x8c, + 0xf8, 0xcf, 0x0e, 0xbc, 0x24, 0x09, 0xd8, 0xc1, 0xfe, 0xca, 0x04, 0xd7, 0x09, + 0xf8, 0xc9, 0xf0, 0xaf, 0xd4, 0xb6, 0xd8, 0x2b, 0xe0, 0xfe, 0x0a, 0xf0, 0xd9, + 0x00, 0x7f, 0xf4, 0xf0, 0x2d, 0xbb, 0x18, 0xdb, 0x02, 0xed, 0xd1, 0x0c, 0xb6, + 0xcf, 0x0f, 0x16, 0xe5, 0x0a, 0xfc, 0xd7, 0x5e, 0x1d, 0xc0, 0x31, 0xe5, 0xd0, + 0x20, 0x0e, 0x5b, 0xee, 0x6a, 0xf4, 0x1c, 0xfa, 0xeb, 0xda, 0xff, 0x2a, 0x26, + 0x43, 0x04, 0x20, 0xd1, 0xfd, 0x46, 0x00, 0xf1, 0x30, 0x36, 0x63, 0xe8, 0xf1, + 0xe7, 0x4a, 0x42, 0xf4, 0xe8, 0xcc, 0x4e, 0xdc, 0xac, 0x0c, 0xb7, 0xb8, 0x1f, + 0xff, 0x27, 0xbd, 0xe1, 0x02, 0xdb, 0x2c, 0x1e, 0xe8, 0xb2, 0xea, 0xa0, 0x16, + 0x13, 0x59, 0xf0, 0xc2, 0x12, 0x1a, 0x5d, 0xea, 0xd9, 0xf5, 0x0f, 0xdc, 0xdf, + 0xdb, 0xc9, 0xff, 0xc9, 0xd7, 0xde, 0xdb, 0xf6, 0xca, 0x98, 0xed, 0xcd, 0x57, + 0xc9, 0xc8, 0xbf, 0x5d, 0xfe, 0x01, 0x99, 0xfb, 0x6d, 0x2a, 0xed, 0xe1, 0xdd, + 0x2b, 0x40, 0x19, 0xdb, 0xd5, 0x18, 0x04, 0xa1, 0x4c, 0xb6, 0x52, 0xb5, 0x10, + 0x0e, 0x07, 0x0f, 0xd1, 0xfb, 0xf6, 0x05, 0x33, 0xc6, 0xee, 0xe1, 0x91, 0xd5, + 0x0e, 0xca, 0xfd, 0xc9, 0x1b, 0xce, 0xff, 0xfb, 0x25, 0xdb, 0x7f, 0x03, 0x3c, + 0x0f, 0xcf, 0xfc, 0x49, 0x2e, 0x4e, 0xc1, 0xeb, 0xdf, 0x08, 0xc1, 0x26, 0xe7, + 0xee, 0xd0, 0xea, 0xf6, 0xf2, 0xc6, 0xe4, 0x0b, 0xef, 0x1b, 0x01, 0xa5, 0x09, + 0x24, 0xdf, 0xd7, 0xe0, 0xf7, 0xc6, 0x36, 0x44, 0xde, 0xcb, 0x1a, 0xcc, 0xe7, + 0xd0, 0xe9, 0x7f, 0x63, 0x0d, 0x21, 0x08, 0x01, 0x0f, 0x15, 0x05, 0xcc, 0x0a, + 0xcd, 0xee, 0xd5, 0x0a, 0x2b, 0xb2, 0x49, 0xf0, 0x16, 0x08, 0x2d, 0xff, 0x37, + 0x05, 0x19, 0x04, 0xcd, 0xfc, 0x1f, 0xe0, 0xd0, 0xa6, 0xf7, 0x6b, 0xcd, 0xf6, + 0x54, 0x26, 0xb8, 0xb5, 0x27, 0x0c, 0x01, 0xe1, 0x58, 0xdf, 0x15, 0xf6, 0xd2, + 0x1c, 0x21, 0xd5, 0x16, 0x07, 0xeb, 0xf2, 0x43, 0xd0, 0xbe, 0xf3, 0xca, 0xf5, + 0x0e, 0xdd, 0x0b, 0x01, 0xe2, 0xf5, 0xf5, 0xe4, 0xfa, 0xf0, 0x01, 0xe5, 0x0c, + 0xf9, 0x16, 0xfa, 0xe0, 0xf4, 0x12, 0xfb, 0x16, 0x33, 0xe7, 0xc5, 0x07, 0x25, + 0x12, 0xa6, 0xcd, 0x03, 0x08, 0xe1, 0xe1, 0xec, 0xf4, 0xe0, 0x20, 0x0c, 0x73, + 0xc2, 0x33, 0xed, 0x00, 0xf3, 0x2c, 0xed, 0x1f, 0x04, 0x24, 0x3e, 0xdd, 0x3c, + 0x15, 0x4d, 0x1b, 0x0e, 0x0a, 0xf9, 0x35, 0x29, 0xdd, 0x1b, 0xbd, 0x51, 0x32, + 0x04, 0x0d, 0xfa, 0x38, 0x6a, 0xd5, 0x2c, 0x25, 0x1c, 0x07, 0xd4, 0xf5, 0x0e, + 0xbf, 0x06, 0xfc, 0x2c, 0x0b, 0x2a, 0x3b, 0xf9, 0xab, 0x24, 0x1e, 0xf0, 0x04, + 0xe7, 0x18, 0xd9, 0xf1, 0x00, 0xeb, 0x09, 0xe1, 0xd2, 0xfc, 0xf1, 0xf4, 0xf0, + 0xf3, 0x48, 0x1b, 0x0d, 0xd7, 0xfa, 0xcf, 0xff, 0xc4, 0xf0, 0xe0, 0xc9, 0x81, + 0x70, 0x09, 0xbe, 0x17, 0xad, 0x19, 0x99, 0xea, 0xd4, 0x02, 0x1d, 0x1c, 0xd4, + 0xdb, 0xf3, 0x3c, 0xbe, 0xc9, 0x2a, 0x1f, 0xe4, 0x4a, 0xeb, 0x06, 0x04, 0x47, + 0xfd, 0xc7, 0xa7, 0xca, 0xed, 0xf0, 0xca, 0xd0, 0xc6, 0xf4, 0x16, 0xc0, 0xe4, + 0xdb, 0x0b, 0xde, 0x0d, 0xd2, 0xda, 0xbd, 0xe4, 0x09, 0x0d, 0xa3, 0x04, 0x91, + 0x06, 0xfa, 0x26, 0x00, 0xfb, 0xe1, 0xe6, 0xe4, 0x1f, 0xf7, 0x04, 0xef, 0x5a, + 0x11, 0xe2, 0x27, 0x40, 0xe7, 0x0d, 0xd4, 0x3a, 0xf9, 0xe5, 0x2f, 0xac, 0xf8, + 0x3a, 0xd7, 0xe7, 0x07, 0xda, 0xd9, 0xec, 0xd7, 0xfa, 0x25, 0xc2, 0xfd, 0xed, + 0xd9, 0x02, 0xc4, 0x4e, 0x2f, 0x48, 0x0c, 0xc5, 0x25, 0xc2, 0xf5, 0x3b, 0x0a, + 0x42, 0xe2, 0x32, 0xdd, 0xba, 0xfc, 0xe2, 0xda, 0x2a, 0xd7, 0xd0, 0x1c, 0xc2, + 0x22, 0x6b, 0xe0, 0xf1, 0x06, 0x02, 0xfe, 0xeb, 0xdb, 0x16, 0x17, 0x07, 0xc5, + 0x10, 0x00, 0xeb, 0x2f, 0x11, 0xd4, 0xfc, 0x0b, 0x1f, 0xee, 0xc1, 0xe4, 0x7f, + 0x1e, 0xe6, 0xc3, 0xe6, 0x19, 0x10, 0xd3, 0x0e, 0xea, 0x19, 0xef, 0x5c, 0xf8, + 0x2a, 0x08, 0xfe, 0x0d, 0x2a, 0x44, 0x10, 0xe3, 0xf4, 0x04, 0x4f, 0x2e, 0xd7, + 0xcb, 0x05, 0x45, 0xf6, 0xf2, 0x0f, 0x03, 0xe7, 0x0e, 0x0c, 0xf6, 0x0b, 0xf0, + 0x26, 0xe9, 0xfd, 0xc8, 0xad, 0x15, 0x25, 0xc7, 0xf6, 0x4f, 0x13, 0xed, 0x09, + 0x14, 0xe8, 0xc2, 0xfc, 0xe9, 0x0a, 0xbf, 0x48, 0x42, 0xf1, 0x53, 0x37, 0xdb, + 0x36, 0xcf, 0xdf, 0x0e, 0x11, 0x19, 0x02, 0xe7, 0x09, 0x5d, 0x0f, 0xf5, 0x2a, + 0x22, 0xd6, 0x27, 0xe2, 0xf4, 0x4e, 0x86, 0x00, 0xbc, 0xbc, 0xec, 0xca, 0xfc, + 0xf4, 0xfb, 0x24, 0xf5, 0x2b, 0x14, 0x0b, 0x31, 0x51, 0xae, 0xb8, 0x1f, 0x13, + 0xff, 0x34, 0xee, 0xd1, 0x0f, 0x19, 0x1b, 0x72, 0xfe, 0x5f, 0x15, 0x00, 0x0f, + 0xbe, 0x09, 0x1b, 0xeb, 0xf4, 0x41, 0x21, 0x73, 0xa9, 0xc3, 0x17, 0xf0, 0x27, + 0xc2, 0x06, 0x57, 0xd5, 0xf1, 0x34, 0x39, 0x1b, 0x81, 0x4a, 0x09, 0x23, 0x9e, + 0x2b, 0xee, 0xdb, 0x21, 0x65, 0x03, 0x33, 0xdd, 0x0b, 0x06, 0x1f, 0x6e, 0x2b, + 0x02, 0xe8, 0x11, 0x09, 0x16, 0xfc, 0xf0, 0xfe, 0xda, 0xf2, 0xd3, 0xfc, 0xb3, + 0xfd, 0x07, 0xea, 0x05, 0x3a, 0xc6, 0x02, 0xff, 0x5c, 0xa1, 0x42, 0x36, 0x1b, + 0x36, 0x04, 0xd2, 0xfc, 0x03, 0x2b, 0xf4, 0x08, 0xfc, 0xb0, 0x14, 0x52, 0x06, + 0x13, 0x60, 0x26, 0xde, 0xd4, 0x06, 0xfb, 0xcf, 0xd4, 0xe6, 0xf4, 0x1f, 0x02, + 0x1c, 0xfd, 0xf8, 0x04, 0x33, 0xc4, 0x07, 0xe3, 0x56, 0x47, 0x03, 0x36, 0x1a, + 0x7f, 0x19, 0xb0, 0x1c, 0x53, 0x0c, 0xb4, 0xfc, 0x44, 0x14, 0x01, 0x2e, 0x22, + 0x1a, 0xf5, 0x11, 0xf3, 0xd1, 0xe6, 0xd7, 0x37, 0xfb, 0xc8, 0x17, 0xe7, 0x2d, + 0x07, 0x36, 0xe4, 0xd4, 0x0e, 0x19, 0x10, 0x0e, 0x3c, 0x1a, 0xb8, 0x3c, 0x37, + 0x14, 0xeb, 0xf4, 0xda, 0xe0, 0xed, 0x0f, 0x04, 0x06, 0xe8, 0xc7, 0x27, 0xed, + 0xf5, 0xcf, 0xc8, 0x18, 0x4c, 0x2c, 0xf0, 0xb4, 0x28, 0x3b, 0x0e, 0xf6, 0xd9, + 0x12, 0xdd, 0xe6, 0xce, 0xf5, 0xdf, 0x01, 0xb9, 0xef, 0x08, 0x3c, 0x1b, 0xe1, + 0xcc, 0x0f, 0x18, 0xf8, 0xf0, 0xfd, 0xc3, 0xf9, 0xf4, 0xd8, 0x07, 0xe7, 0xdb, + 0xe8, 0xe2, 0x2a, 0x11, 0x0d, 0x2c, 0x3e, 0xe8, 0x14, 0x3e, 0xdf, 0x0b, 0xef, + 0x28, 0xea, 0x24, 0xd6, 0x1f, 0xf3, 0xef, 0x1c, 0x16, 0xfd, 0xcd, 0xd4, 0x42, + 0xc3, 0x7f, 0x0a, 0x07, 0x1d, 0x09, 0x28, 0x3e, 0x01, 0xec, 0xf0, 0x11, 0xd1, + 0x58, 0xf0, 0x39, 0x43, 0x1f, 0x1b, 0x48, 0x05, 0xec, 0x34, 0x0a, 0x23, 0x08, + 0x01, 0xfd, 0x08, 0x01, 0x41, 0xec, 0x12, 0xed, 0xf1, 0xed, 0xe8, 0xc3, 0x20, + 0xf2, 0xe1, 0x11, 0xce, 0xd7, 0xd8, 0xf2, 0xcf, 0x01, 0x0c, 0x0c, 0x17, 0xc9, + 0x06, 0x26, 0x27, 0x09, 0xed, 0x0d, 0x20, 0x04, 0xcf, 0xb2, 0xe4, 0xe9, 0xda, + 0x08, 0x12, 0x5b, 0xcd, 0xe9, 0xef, 0x14, 0xe2, 0x4d, 0xcc, 0xf0, 0x15, 0x06, + 0x10, 0xec, 0xd8, 0x51, 0xea, 0xce, 0x0b, 0x35, 0xcc, 0xdb, 0xcf, 0xfa, 0x0e, + 0x32, 0xe5, 0x11, 0x16, 0x05, 0x2e, 0xd0, 0xf8, 0xee, 0xf9, 0x15, 0xf7, 0x25, + 0xf4, 0xe3, 0x12, 0xe6, 0xcf, 0xdb, 0xf8, 0x06, 0x0f, 0xe3, 0x36, 0xed, 0x09, + 0xf8, 0xe4, 0x0d, 0xe0, 0xe2, 0x08, 0xe3, 0xee, 0x09, 0xe4, 0x11, 0x1c, 0x3b, + 0xaf, 0xee, 0x08, 0xfe, 0xed, 0x00, 0xf8, 0xf9, 0xe2, 0x4c, 0x0a, 0x0f, 0x0d, + 0xff, 0x07, 0xf1, 0xfc, 0x09, 0xf8, 0x21, 0xf0, 0xc6, 0x0d, 0xf5, 0xf8, 0xd8, + 0x35, 0x20, 0xeb, 0x16, 0xea, 0xfd, 0x20, 0xd1, 0xe0, 0xd6, 0xde, 0xfe, 0xe3, + 0xe1, 0x0f, 0x81, 0xf9, 0x29, 0xf5, 0x60, 0xca, 0xf8, 0x0f, 0xff, 0x0a, 0x0c, + 0xd9, 0xe2, 0xc9, 0x1e, 0xf3, 0x06, 0xfc, 0xff, 0xe6, 0xd9, 0x25, 0x1c, 0xf0, + 0x19, 0xfa, 0xef, 0xd3, 0xcb, 0xdb, 0x0b, 0x06, 0xe1, 0xfb, 0xec, 0xe8, 0x00, + 0x16, 0x11, 0xf8, 0x1d, 0xf4, 0x06, 0x1e, 0x09, 0xe6, 0x18, 0xdc, 0xe7, 0x04, + 0x0c, 0x06, 0xd2, 0x08, 0xec, 0xf6, 0xd3, 0xf2, 0xfc, 0xf7, 0xd3, 0xe8, 0xfd, + 0x0a, 0xf0, 0x07, 0x0e, 0xc6, 0xe2, 0x0e, 0x13, 0xd8, 0x04, 0x0e, 0xf2, 0xef, + 0x01, 0x03, 0xea, 0x22, 0xdd, 0x03, 0x00, 0xaa, 0x21, 0xe2, 0x23, 0xdf, 0x06, + 0xe0, 0xec, 0xe6, 0x26, 0xd6, 0xf2, 0xeb, 0x04, 0xf5, 0xcd, 0xee, 0x10, 0xfd, + 0xc9, 0x7f, 0x15, 0x0f, 0xfc, 0x16, 0x26, 0x19, 0xca, 0x10, 0x11, 0xda, 0x1f, + 0x06, 0x0b, 0x12, 0x1d, 0xfa, 0xf5, 0x04, 0xd3, 0xfe, 0xfd, 0x21, 0xee, 0x1a, + 0x05, 0x12, 0x0e, 0x0d, 0xe4, 0xe5, 0x10, 0xf5, 0xd8, 0xf2, 0x1a, 0x0c, 0x29, + 0x0f, 0xfe, 0xdd, 0xda, 0xe2, 0x02, 0xf8, 0x01, 0xf6, 0x04, 0xdf, 0x2e, 0xf2, + 0xd4, 0x40, 0xb5, 0xf4, 0xa3, 0xcb, 0x09, 0x54, 0x33, 0xea, 0xe8, 0xb3, 0x16, + 0x1a, 0x41, 0x06, 0x1e, 0x39, 0x1c, 0x09, 0xed, 0x31, 0x26, 0x69, 0xce, 0x19, + 0xba, 0x52, 0xea, 0xab, 0x21, 0xd8, 0xc9, 0xca, 0x0b, 0x3c, 0xd4, 0x7f, 0xda, + 0x01, 0x51, 0x12, 0xe7, 0x29, 0x1c, 0x9e, 0xea, 0xea, 0xea, 0xe0, 0xf4, 0xeb, + 0xf0, 0x1e, 0xed, 0x0e, 0xc8, 0x0d, 0xbb, 0xc6, 0xcc, 0xc7, 0xc6, 0xc2, 0xf3, + 0xf8, 0x2f, 0x14, 0x90, 0xe5, 0x9c, 0xcf, 0xf3, 0xb5, 0xa2, 0x8d, 0x09, 0xcc, + 0xe7, 0x00, 0xed, 0x6c, 0x83, 0xc1, 0xc6, 0xab, 0xf6, 0xef, 0x04, 0x4e, 0xe4, + 0x43, 0x12, 0xdd, 0x1a, 0xb0, 0x2e, 0xc8, 0xff, 0xe4, 0xf5, 0xce, 0xe7, 0x1d, + 0xd4, 0x18, 0x0c, 0x19, 0x18, 0x2f, 0x9c, 0x49, 0x13, 0x54, 0x1b, 0x07, 0x0f, + 0xc6, 0xb4, 0xcf, 0xd8, 0xed, 0x0f, 0xeb, 0x3b, 0xfd, 0x49, 0xf9, 0x60, 0x08, + 0x26, 0xec, 0xfe, 0x05, 0xee, 0x12, 0x76, 0xde, 0xdf, 0x0c, 0xe1, 0x18, 0xfc, + 0x24, 0xeb, 0x98, 0x20, 0x39, 0x9f, 0xfc, 0xd6, 0x2e, 0x3b, 0xee, 0xfc, 0x0e, + 0xdd, 0xd5, 0x1e, 0x18, 0xb0, 0xb3, 0xeb, 0xb3, 0xf4, 0xf9, 0x28, 0x71, 0xe2, + 0x91, 0x07, 0xe1, 0x1a, 0xd9, 0xc5, 0xfb, 0x20, 0xcb, 0x7a, 0x27, 0xe0, 0x26, + 0x38, 0xde, 0x65, 0xf7, 0xba, 0xd1, 0xe6, 0x05, 0x0b, 0x00, 0xff, 0x28, 0x9c, + 0xe9, 0xff, 0x08, 0x23, 0xca, 0xb7, 0x3b, 0xc8, 0x06, 0x64, 0xc3, 0xe0, 0xe8, + 0x33, 0xdb, 0x6d, 0x46, 0x81, 0xce, 0x21, 0x0a, 0x6e, 0x02, 0x19, 0xee, 0xbf, + 0x2a, 0x9b, 0xf0, 0x2b, 0xe9, 0x76, 0x16, 0x69, 0xfa, 0x05, 0xd5, 0xf5, 0x3d, + 0x1f, 0xc0, 0x24, 0x1e, 0x0d, 0x38, 0xe5, 0x48, 0xf9, 0xf5, 0xf9, 0x35, 0x21, + 0x9a, 0x5b, 0x1d, 0x19, 0x17, 0x18, 0xda, 0x53, 0xe1, 0xf5, 0x06, 0xf5, 0x0a, + 0xf1, 0xff, 0xf1, 0x4c, 0xe8, 0x02, 0xdd, 0x0e, 0x91, 0x56, 0xd9, 0xdb, 0xf5, + 0xea, 0x44, 0xfb, 0xe0, 0x21, 0xc9, 0xd8, 0x27, 0xc4, 0xc3, 0x0d, 0xf0, 0xd2, + 0xf3, 0xfe, 0x8d, 0x32, 0xfc, 0xf5, 0x29, 0x45, 0x40, 0x3a, 0xf5, 0x2f, 0x24, + 0xe6, 0x47, 0xef, 0x35, 0x1b, 0x07, 0x29, 0xd9, 0xe2, 0x14, 0xe0, 0x01, 0x32, + 0xf7, 0xbb, 0x20, 0xe2, 0x6b, 0x01, 0x7f, 0xed, 0xe0, 0x1c, 0xe0, 0x18, 0xe2, + 0x4a, 0x17, 0xb8, 0x22, 0xa2, 0xeb, 0x59, 0xe9, 0x1c, 0x1e, 0x99, 0x3a, 0x3b, + 0x44, 0xf8, 0xb2, 0x23, 0xe9, 0xc4, 0x0d, 0xa7, 0xe1, 0x16, 0x0b, 0xc8, 0xac, + 0xce, 0xb2, 0xcd, 0x17, 0x20, 0xd7, 0xdc, 0x15, 0x2b, 0xd7, 0x9d, 0x33, 0x8d, + 0x10, 0x43, 0x94, 0x35, 0x14, 0xd6, 0xf6, 0x3c, 0x02, 0x5e, 0xf7, 0x4a, 0xc0, + 0xfa, 0xf2, 0xfe, 0xf8, 0x28, 0x04, 0x17, 0xb8, 0xee, 0x19, 0xf1, 0xb9, 0x81, + 0xcc, 0x3a, 0xfe, 0xe4, 0x07, 0x51, 0x7a, 0x84, 0x29, 0x13, 0xb6, 0xb7, 0xf4, + 0x0c, 0x04, 0x93, 0xc4, 0x33, 0xe9, 0x38, 0xc6, 0x09, 0x0b, 0x01, 0xec, 0xec, + 0xfc, 0x3a, 0xc2, 0x4f, 0x4a, 0xc4, 0xcf, 0x1d, 0xaa, 0x27, 0xe9, 0x0a, 0x78, + 0xee, 0x1a, 0xfa, 0xc2, 0x01, 0xe7, 0xef, 0xf8, 0x10, 0x3c, 0x45, 0x43, 0xe8, + 0x24, 0x10, 0xaf, 0x60, 0x3a, 0x52, 0x17, 0xed, 0xce, 0xf5, 0xe7, 0x23, 0x3a, + 0xa3, 0xf8, 0x4f, 0x6e, 0x35, 0xd6, 0x6d, 0x23, 0xdb, 0xaf, 0xce, 0x4a, 0xfd, + 0xd8, 0xb1, 0x0f, 0xbb, 0xa3, 0x3b, 0xcf, 0xbf, 0xf6, 0xfc, 0xd1, 0xc6, 0x96, + 0xf5, 0x4f, 0xea, 0x0a, 0x0d, 0x32, 0xbd, 0xac, 0xe3, 0x9a, 0x29, 0x0b, 0xde, + 0x1a, 0x05, 0x21, 0x4c, 0x22, 0x2b, 0xbc, 0x47, 0x4e, 0xcc, 0xe1, 0x57, 0xe4, + 0xbf, 0x89, 0x36, 0xd6, 0x69, 0xf9, 0x91, 0x14, 0xc4, 0x17, 0x4c, 0xf6, 0xec, + 0xe6, 0x17, 0x02, 0xf7, 0xde, 0x0d, 0x0b, 0xd9, 0x10, 0xee, 0xcd, 0xdc, 0xf8, + 0x04, 0xbc, 0xf7, 0x00, 0xff, 0xfb, 0xd7, 0xb7, 0xd5, 0x21, 0xf1, 0xad, 0xd6, + 0xec, 0x38, 0x12, 0x7c, 0x07, 0xec, 0xc0, 0xf8, 0xeb, 0xba, 0x3f, 0xdd, 0xfb, + 0xd5, 0x2c, 0x0a, 0x01, 0xe4, 0xfe, 0xbe, 0xf5, 0x24, 0xba, 0xf2, 0x1a, 0xda, + 0xe5, 0x2e, 0xdf, 0xdc, 0xf0, 0x0f, 0x56, 0x0e, 0xf9, 0xe4, 0x03, 0x9c, 0xcb, + 0xca, 0xc9, 0xeb, 0x11, 0x15, 0x26, 0x0d, 0x1a, 0xc5, 0x2f, 0x14, 0x16, 0x04, + 0xf3, 0xfc, 0x21, 0xc8, 0xd7, 0x24, 0xe5, 0xfc, 0x81, 0xe9, 0x1c, 0xe9, 0xd6, + 0x13, 0xf9, 0x50, 0xdd, 0xe6, 0x30, 0x0d, 0xdf, 0xc9, 0xe2, 0xfd, 0x4f, 0x00, + 0x30, 0xd6, 0xf7, 0x0e, 0xee, 0xd0, 0x01, 0x12, 0x16, 0xf3, 0x17, 0x39, 0xa2, + 0xd6, 0x21, 0xf4, 0x02, 0xcf, 0xe9, 0xe6, 0x7f, 0xf6, 0x2d, 0x1b, 0x05, 0xe3, + 0x31, 0xf8, 0x4d, 0xfb, 0xa2, 0xe8, 0xef, 0x49, 0x04, 0x0d, 0xfd, 0xfc, 0x34, + 0x11, 0x37, 0xfd, 0x1c, 0x28, 0xca, 0xf3, 0xcd, 0x18, 0x2d, 0xde, 0xf9, 0xf0, + 0x19, 0x22, 0xb8, 0xab, 0xd2, 0x1e, 0x2c, 0xd0, 0x50, 0x31, 0xfa, 0xde, 0xf2, + 0x1d, 0xec, 0x5b, 0xef, 0xf2, 0x17, 0x04, 0x2a, 0x27, 0xd8, 0x87, 0x15, 0xf4, + 0xe0, 0x0a, 0xb4, 0x1a, 0xda, 0xe5, 0xf2, 0x13, 0x2f, 0x59, 0x29, 0x02, 0x66, + 0x5e, 0x00, 0xb4, 0x1e, 0x10, 0xf9, 0x9e, 0xda, 0xb0, 0x1b, 0xd2, 0xe5, 0x06, + 0x0d, 0x14, 0xff, 0x0c, 0x30, 0x3b, 0x24, 0x26, 0xd5, 0xcb, 0xcb, 0x1f, 0xf7, + 0x30, 0xf5, 0x36, 0xfa, 0x10, 0xac, 0xfb, 0x03, 0x2d, 0x4d, 0x2f, 0xe3, 0xf1, + 0x1a, 0xe4, 0xc7, 0x1d, 0x09, 0xd4, 0x5a, 0x39, 0xe5, 0xe6, 0x4b, 0x13, 0x23, + 0xcb, 0xf7, 0xde, 0x14, 0x38, 0x50, 0x2a, 0x26, 0xe1, 0xbc, 0xf4, 0x16, 0xe3, + 0x08, 0x32, 0x30, 0x75, 0x10, 0x07, 0x1d, 0xd9, 0x15, 0xa5, 0xf9, 0xc2, 0xf1, + 0xf2, 0x10, 0x18, 0xf5, 0x01, 0x4c, 0xf6, 0x6e, 0xf1, 0x0e, 0xdb, 0xc8, 0xf9, + 0x3c, 0x07, 0xe5, 0xfb, 0xea, 0xa4, 0x1c, 0x10, 0x29, 0x26, 0x27, 0x13, 0x0a, + 0x6c, 0xec, 0x0b, 0xc2, 0xd2, 0x15, 0xa3, 0xfa, 0xcd, 0x9a, 0x11, 0x08, 0x23, + 0xe1, 0xed, 0x3c, 0xf9, 0x1f, 0x00, 0xeb, 0x04, 0x47, 0x2f, 0x0f, 0x1f, 0x7f, + 0xcf, 0xd5, 0xe3, 0x5e, 0x20, 0x6e, 0x13, 0x33, 0x1c, 0xed, 0x7b, 0x18, 0xc1, + 0xeb, 0xbf, 0x38, 0x60, 0x4c, 0xd9, 0xf7, 0xee, 0xf7, 0x03, 0x49, 0xb6, 0xee, + 0xc3, 0x3d, 0x05, 0x73, 0xa3, 0x1b, 0x22, 0xfa, 0x14, 0x25, 0xc5, 0xf5, 0x9a, + 0x0b, 0x00, 0xde, 0x33, 0xff, 0x10, 0x1b, 0x3e, 0xff, 0x00, 0xea, 0xdb, 0xb4, + 0x48, 0xde, 0xe8, 0xeb, 0x0d, 0xe4, 0xfc, 0x14, 0x1c, 0x0d, 0x4d, 0xf4, 0x04, + 0x40, 0xae, 0x1e, 0x5c, 0x61, 0x66, 0xda, 0xa7, 0xed, 0xde, 0xfd, 0x21, 0xa4, + 0x3f, 0xd0, 0x04, 0x76, 0xe9, 0xfd, 0x60, 0xe3, 0xa4, 0x34, 0x00, 0x39, 0x08, + 0xce, 0xcf, 0xd3, 0x0a, 0xd7, 0xd5, 0x2d, 0x07, 0x1c, 0xe4, 0xf4, 0x6a, 0xf5, + 0x38, 0xf8, 0xf3, 0x24, 0x4b, 0x25, 0x17, 0x10, 0x01, 0x16, 0x1f, 0x17, 0x02, + 0x02, 0xf6, 0x08, 0xd6, 0xd0, 0x3e, 0x3f, 0xeb, 0x2f, 0x4d, 0x3f, 0x7f, 0x90, + 0xf4, 0xe2, 0x08, 0x23, 0x10, 0xd6, 0xf5, 0xc7, 0xb4, 0x23, 0x2e, 0xaf, 0xff, + 0xed, 0x94, 0xb6, 0xec, 0xea, 0xb7, 0x49, 0x43, 0xb6, 0x41, 0x3b, 0x0a, 0xe0, + 0xdb, 0x29, 0x0b, 0x6a, 0x9c, 0xcb, 0x15, 0x16, 0xe5, 0xd6, 0x4b, 0xb6, 0x0b, + 0x42, 0xed, 0x06, 0x04, 0x4b, 0xcb, 0x52, 0x51, 0x18, 0x41, 0x1c, 0x0c, 0xfb, + 0x12, 0xe9, 0xce, 0x0f, 0xca, 0x4d, 0x3f, 0x2e, 0x12, 0x0d, 0xd2, 0x2a, 0xf9, + 0xed, 0x3e, 0x2d, 0xd5, 0xb9, 0x75, 0xe1, 0x0a, 0x31, 0xda, 0x39, 0x42, 0xc0, + 0xda, 0x2a, 0x38, 0x12, 0xdc, 0xde, 0xc5, 0xe1, 0x28, 0x0c, 0x55, 0xd4, 0xfd, + 0xf5, 0xea, 0x38, 0xe9, 0xfe, 0x0c, 0x55, 0x51, 0x2a, 0x2f, 0x17, 0xee, 0xf6, + 0xed, 0x07, 0xb2, 0xf6, 0xf4, 0x22, 0xf9, 0x55, 0x28, 0xf5, 0xdf, 0xc9, 0xd5, + 0x09, 0x2f, 0xd6, 0xae, 0x3b, 0xc3, 0xf1, 0x44, 0xd4, 0x0b, 0xb8, 0x46, 0x18, + 0xc5, 0xdb, 0xf4, 0x1e, 0xe9, 0x4a, 0x64, 0x00, 0x33, 0xbc, 0x03, 0xe6, 0x3e, + 0x2a, 0x20, 0xf9, 0xb8, 0x2a, 0xec, 0xc9, 0x11, 0xcc, 0xea, 0x2f, 0x1b, 0x1d, + 0xe6, 0x1c, 0xd9, 0xd9, 0xd7, 0x22, 0xd8, 0x17, 0xd7, 0x0c, 0x45, 0xbb, 0xed, + 0xb8, 0x74, 0x0d, 0x20, 0xd1, 0x19, 0x1d, 0xf0, 0xf9, 0x7f, 0x2f, 0xee, 0x30, + 0x2c, 0xf4, 0xf6, 0x1a, 0x05, 0x10, 0xfe, 0xca, 0xff, 0xf6, 0xdb, 0x0c, 0xde, + 0x23, 0xcc, 0xec, 0x08, 0x09, 0xf4, 0xd8, 0xda, 0xd6, 0xf7, 0xfd, 0x0c, 0x3c, + 0xfe, 0xdb, 0xdd, 0x00, 0x20, 0xfa, 0x32, 0xdb, 0x11, 0xee, 0xc7, 0xf6, 0x0c, + 0xe9, 0xe8, 0xf2, 0x3d, 0x18, 0xf3, 0x28, 0xba, 0x08, 0xdc, 0x04, 0xca, 0x04, + 0xbb, 0xfe, 0x24, 0x8f, 0xf1, 0xc3, 0x1c, 0x48, 0x0b, 0x13, 0x08, 0xd1, 0x05, + 0x5c, 0xf2, 0xfd, 0x0d, 0xee, 0xf8, 0x27, 0xc2, 0x3d, 0xd6, 0x1e, 0x2c, 0x03, + 0xef, 0x55, 0xfd, 0xef, 0xe2, 0x18, 0x08, 0xee, 0x04, 0x0b, 0xdd, 0xfe, 0x0c, + 0x5a, 0xd3, 0xf9, 0xec, 0x05, 0x2e, 0x02, 0x5a, 0x2f, 0xf0, 0x3c, 0xe4, 0xee, + 0x28, 0xe1, 0x15, 0xda, 0xbd, 0xda, 0x22, 0x4d, 0xe2, 0x6e, 0xab, 0x22, 0xec, + 0xfd, 0x12, 0xfb, 0xec, 0x20, 0x12, 0x81, 0xf8, 0xe9, 0xef, 0x11, 0x17, 0x28, + 0x45, 0x92, 0x0a, 0xb5, 0x10, 0x35, 0xbe, 0xf3, 0xdb, 0x31, 0xea, 0xf1, 0xeb, + 0xe4, 0x2c, 0xfe, 0xe1, 0x1c, 0xf4, 0x20, 0xd9, 0x23, 0xfc, 0x07, 0x2b, 0xab, + 0x13, 0x2d, 0x2b, 0xdf, 0x2b, 0xf6, 0x31, 0xe7, 0x06, 0xef, 0x06, 0xfb, 0x02, + 0xec, 0x18, 0x33, 0x81, 0x23, 0x0c, 0x01, 0xba, 0x09, 0x3e, 0x6a, 0x67, 0x1b, + 0xe1, 0x0e, 0x07, 0xfd, 0xd9, 0xd7, 0x04, 0xff, 0xd2, 0x2b, 0x08, 0x2c, 0xad, + 0xc6, 0x10, 0x2f, 0x11, 0xf0, 0xde, 0x03, 0xd6, 0x40, 0xe7, 0x38, 0x04, 0xfa, + 0xfb, 0xfa, 0x40, 0x14, 0x0f, 0xe8, 0xea, 0xdb, 0xf9, 0xc7, 0x35, 0x27, 0xe3, + 0x16, 0x45, 0x1c, 0xe8, 0x2c, 0x2a, 0x36, 0xc3, 0xf2, 0x2e, 0xee, 0x6f, 0x5b, + 0xe8, 0x27, 0x27, 0xf5, 0xa3, 0x1b, 0x00, 0x44, 0xec, 0xcf, 0xd9, 0x2b, 0x53, + 0x12, 0xeb, 0xd8, 0xeb, 0xbf, 0x0e, 0x43, 0xa8, 0x0f, 0xd3, 0x17, 0xcf, 0x10, + 0x2e, 0x0d, 0xe8, 0xff, 0xe2, 0xf6, 0x1a, 0xd6, 0x08, 0x24, 0x4a, 0xa8, 0x0d, + 0x13, 0x28, 0x3a, 0x1c, 0x69, 0x25, 0x08, 0xfc, 0x15, 0x0a, 0x17, 0x14, 0xe4, + 0xb7, 0xe9, 0xdc, 0x06, 0xd8, 0xf9, 0x3a, 0x02, 0xe4, 0x16, 0x35, 0x3f, 0xfb, + 0x11, 0x7f, 0x0b, 0x1e, 0x10, 0x4b, 0x10, 0x48, 0xe5, 0x20, 0xe3, 0xe4, 0x3f, + 0x28, 0xd9, 0x0b, 0xe4, 0xec, 0xe3, 0x0b, 0xbd, 0xe3, 0xe2, 0x77, 0x1e, 0xdd, + 0x07, 0x30, 0x1e, 0xd6, 0xe9, 0x0d, 0xeb, 0xc4, 0xfd, 0x14, 0xed, 0xe1, 0x21, + 0xfc, 0xe8, 0xcb, 0x31, 0xd4, 0x2b, 0xff, 0x4e, 0xff, 0xf3, 0xe6, 0x32, 0xff, + 0x16, 0x10, 0xfe, 0xce, 0xc4, 0x04, 0xf6, 0xe6, 0x25, 0xa6, 0x1a, 0x15, 0x08, + 0x1c, 0x21, 0xd2, 0xd2, 0xd9, 0x1f, 0xd3, 0x09, 0xff, 0x1c, 0xeb, 0xf1, 0x08, + 0xda, 0xc6, 0xff, 0xd7, 0x3c, 0x38, 0x29, 0xf2, 0x22, 0x01, 0xf8, 0x00, 0xec, + 0xd1, 0xe6, 0x34, 0x1d, 0xe9, 0xe4, 0x03, 0xda, 0xfe, 0x11, 0x09, 0xf9, 0xef, + 0x38, 0x0c, 0xe1, 0x59, 0xc6, 0xbe, 0xff, 0xcf, 0x1b, 0xe6, 0xf5, 0xf4, 0x2d, + 0x15, 0xe5, 0xca, 0x32, 0x3a, 0x09, 0xa1, 0x0e, 0x17, 0xd9, 0xe4, 0x02, 0xee, + 0xeb, 0x19, 0xcd, 0xcd, 0xf0, 0xe0, 0xdc, 0x1f, 0xec, 0xcc, 0xd3, 0x16, 0xfb, + 0xbf, 0xa6, 0x0f, 0xf0, 0x17, 0xd6, 0xcd, 0x18, 0xcc, 0xca, 0x56, 0x1e, 0xe9, + 0x1f, 0xb8, 0x7f, 0xc6, 0x30, 0xe2, 0xf3, 0xba, 0x0b, 0xf8, 0xcd, 0xf8, 0x1e, + 0xc8, 0x01, 0xeb, 0xec, 0xe4, 0x1a, 0x21, 0x27, 0xab, 0xe5, 0xe9, 0xed, 0x0a, + 0xfd, 0xe5, 0x1f, 0x02, 0xee, 0xfa, 0xef, 0x14, 0x61, 0x39, 0xf6, 0xf0, 0xeb, + 0x01, 0x15, 0xee, 0x1b, 0xf0, 0xe2, 0xb0, 0x0a, 0x33, 0x58, 0xc4, 0xd4, 0x02, + 0xe1, 0x0e, 0xb6, 0xce, 0x4e, 0xd5, 0x2b, 0x13, 0x11, 0x0e, 0x18, 0xce, 0xf6, + 0x49, 0x01, 0x5a, 0xc9, 0x27, 0x00, 0x38, 0xfd, 0x06, 0x2a, 0x3b, 0xd6, 0x29, + 0xe7, 0x34, 0xc6, 0x0b, 0xe4, 0xf5, 0x5b, 0xe3, 0x04, 0xbb, 0xb3, 0x2f, 0xac, + 0xd9, 0x35, 0x53, 0x2f, 0xb3, 0xf6, 0x18, 0x38, 0xb0, 0x05, 0x12, 0x37, 0x1d, + 0x00, 0x0b, 0xda, 0x42, 0xd7, 0xb3, 0xda, 0xd9, 0x00, 0xf7, 0xe8, 0xdc, 0x01, + 0xd4, 0x20, 0x18, 0xe0, 0x6e, 0xf5, 0x44, 0x28, 0xdb, 0xcd, 0xe3, 0x2f, 0xc3, + 0x25, 0x32, 0xef, 0x39, 0x0c, 0x0e, 0xf0, 0xd4, 0x0c, 0xe0, 0xee, 0x12, 0x49, + 0x2b, 0xbe, 0x1f, 0x38, 0xe4, 0xec, 0x8e, 0x01, 0xf5, 0xf2, 0xc8, 0xad, 0xfe, + 0xe8, 0x03, 0xd3, 0xc9, 0x3d, 0x18, 0x13, 0x26, 0xd4, 0xd5, 0x26, 0xcf, 0xef, + 0xf8, 0xec, 0xea, 0x5e, 0x17, 0x32, 0xf0, 0x0b, 0xe1, 0x68, 0x81, 0x31, 0xe6, + 0xc0, 0x09, 0x06, 0xe9, 0xf0, 0x1b, 0xef, 0x51, 0x4f, 0x50, 0xfa, 0xdb, 0xe0, + 0x0b, 0xf5, 0xe8, 0xd4, 0xd8, 0x1d, 0x06, 0x15, 0xf0, 0x05, 0xfd, 0xd6, 0x01, + 0xff, 0x3b, 0xd7, 0x07, 0xf2, 0xa4, 0xd4, 0x06, 0xfa, 0x10, 0xf9, 0xe9, 0xf0, + 0x17, 0x28, 0xff, 0x0b, 0x1b, 0xe2, 0x1f, 0xfa, 0xf9, 0x2b, 0x19, 0xd1, 0xe8, + 0xe2, 0xcd, 0x25, 0xd6, 0xf5, 0xcf, 0x4a, 0xff, 0xec, 0x09, 0x1f, 0xee, 0xfd, + 0x1c, 0xde, 0x7f, 0x4d, 0x50, 0xd1, 0xef, 0x25, 0xe1, 0xc5, 0xcc, 0xae, 0x1a, + 0xc9, 0x11, 0xf9, 0x13, 0x1b, 0x0f, 0xf5, 0xef, 0x23, 0x0f, 0x09, 0x22, 0x18, + 0x3c, 0x2b, 0xcc, 0xdf, 0xf1, 0x12, 0x17, 0xdc, 0x39, 0xe1, 0xf0, 0xee, 0x1a, + 0x04, 0xf3, 0x1a, 0x0e, 0x14, 0xe5, 0xf2, 0x41, 0x1f, 0xeb, 0x39, 0xe7, 0xfa, + 0x0b, 0x26, 0xc7, 0xe9, 0xd8, 0xde, 0xfa, 0x17, 0x55, 0x08, 0xe7, 0xe4, 0xba, + 0xf5, 0xfe, 0xf6, 0x40, 0x10, 0x0c, 0xda, 0x02, 0x19, 0xe3, 0x19, 0xe5, 0xf0, + 0xaf, 0xe7, 0xd1, 0x34, 0x2b, 0xfa, 0x07, 0xec, 0xd4, 0xcc, 0x15, 0xdb, 0xf9, + 0x20, 0x1b, 0xc8, 0x08, 0xf0, 0xda, 0xe0, 0xef, 0x30, 0x19, 0xe1, 0xfa, 0xf1, + 0x1b, 0xe7, 0xd1, 0x00, 0xbc, 0xc7, 0x1a, 0xcd, 0xfb, 0x1a, 0xf5, 0x3b, 0xde, + 0xd0, 0x81, 0xf1, 0xe5, 0x08, 0xe8, 0xe6, 0xdf, 0x03, 0x42, 0xff, 0x41, 0x14, + 0x15, 0xde, 0xc1, 0x01, 0xfc, 0x93, 0xe2, 0x02, 0xae, 0x55, 0xfc, 0xbf, 0xd9, + 0x0a, 0xff, 0x3a, 0xc5, 0xf3, 0xf5, 0x36, 0xeb, 0x25, 0x01, 0xd1, 0xeb, 0xcc, + 0xeb, 0x29, 0x73, 0x11, 0xd5, 0xed, 0x1f, 0x19, 0x07, 0xf5, 0xe3, 0x6e, 0xe2, + 0x0e, 0x09, 0x02, 0x32, 0xf7, 0x96, 0xdd, 0x2a, 0x34, 0x06, 0x25, 0x4a, 0xf6, + 0xef, 0xd7, 0x22, 0x1f, 0xe1, 0x15, 0x16, 0x05, 0x69, 0xe4, 0x10, 0x11, 0x5a, + 0x10, 0xd5, 0xf4, 0xce, 0xb4, 0xd1, 0x2f, 0xbf, 0x0f, 0x38, 0xfc, 0xbe, 0xf2, + 0xb4, 0xee, 0x99, 0xeb, 0x10, 0xf4, 0x25, 0xf9, 0x05, 0x04, 0xec, 0xff, 0x2b, + 0x4f, 0x16, 0xc3, 0xe7, 0xfb, 0xed, 0xf6, 0xe4, 0xfd, 0xbf, 0xf7, 0x1b, 0x43, + 0x11, 0xd2, 0x37, 0x49, 0xe6, 0x11, 0xd6, 0x10, 0xdc, 0xed, 0x21, 0xf2, 0xcd, + 0x14, 0x1f, 0x04, 0x2e, 0x02, 0xf3, 0xf4, 0x18, 0xe3, 0x0b, 0x36, 0xeb, 0xe5, + 0xec, 0xc3, 0x17, 0xac, 0xd1, 0xce, 0x99, 0xdd, 0x00, 0x0e, 0x33, 0xe1, 0x7c, + 0xff, 0x50, 0x19, 0x02, 0x3c, 0xe9, 0x0d, 0x59, 0xf5, 0x23, 0xd4, 0x2a, 0x37, + 0xf3, 0x7f, 0xb9, 0xef, 0x0d, 0xe0, 0x00, 0x37, 0x0f, 0xf7, 0x07, 0x1e, 0x43, + 0xb6, 0x15, 0x0e, 0xce, 0xf8, 0x24, 0x50, 0x00, 0x13, 0x99, 0xe1, 0x10, 0x17, + 0x44, 0xd7, 0x23, 0xe2, 0x65, 0xbe, 0xed, 0x0e, 0x30, 0x08, 0x59, 0xa0, 0x48, + 0xf4, 0x06, 0xf4, 0x9e, 0xb8, 0xfb, 0x09, 0xfb, 0x18, 0x2f, 0x1a, 0x24, 0xdc, + 0xa5, 0xd1, 0xda, 0xc6, 0xb2, 0xea, 0xd4, 0xc8, 0x2e, 0x3c, 0xd5, 0xf8, 0x1d, + 0xa2, 0xdb, 0x29, 0xf3, 0xb9, 0x95, 0x04, 0x09, 0xa0, 0x38, 0x14, 0xba, 0xfb, + 0xfc, 0x2a, 0xa7, 0xb9, 0xd0, 0x35, 0xfb, 0x47, 0xf4, 0xa3, 0xb4, 0x33, 0x9d, + 0xa5, 0x06, 0x55, 0xbc, 0xe3, 0x54, 0x43, 0x18, 0xff, 0xdd, 0xce, 0x3f, 0xca, + 0xa4, 0x3c, 0x1b, 0x3a, 0x09, 0xe9, 0xb6, 0xd9, 0x1b, 0xf9, 0x31, 0x99, 0x06, + 0x23, 0x59, 0x61, 0xef, 0xeb, 0x33, 0xb6, 0x8b, 0xd7, 0x96, 0x4e, 0xfe, 0x23, + 0x81, 0x09, 0xf5, 0x61, 0xb0, 0x2d, 0x21, 0x56, 0x54, 0xfe, 0xf9, 0x22, 0x32, + 0x63, 0xfa, 0xd4, 0x59, 0x53, 0x72, 0x26, 0xf9, 0xfa, 0x0a, 0xda, 0x08, 0xfa, + 0x4d, 0x52, 0x2e, 0xac, 0x10, 0xc9, 0x0a, 0x27, 0x14, 0xff, 0xcf, 0xf8, 0x10, + 0x18, 0x24, 0xa9, 0x1d, 0xe8, 0xf1, 0x22, 0x18, 0xde, 0xd3, 0xd7, 0x1b, 0xdd, + 0xf5, 0x22, 0xae, 0x17, 0xea, 0xf3, 0x00, 0xf5, 0xd4, 0x2a, 0xe3, 0xf7, 0x1c, + 0xf2, 0x29, 0x1f, 0x96, 0xc9, 0x08, 0x19, 0x1d, 0x40, 0xe4, 0x90, 0x0b, 0xff, + 0x5c, 0xe7, 0x81, 0x08, 0xf1, 0x09, 0xe4, 0xf3, 0x26, 0xe0, 0x1d, 0xee, 0xfa, + 0x41, 0x1e, 0x32, 0xcd, 0xec, 0x27, 0x2f, 0xe1, 0x6d, 0x0f, 0xac, 0xcf, 0x24, + 0xd4, 0x09, 0xde, 0xeb, 0x05, 0x22, 0x35, 0xb9, 0x36, 0xd9, 0x02, 0x02, 0x99, + 0x06, 0x0e, 0x41, 0xd1, 0xc6, 0xb8, 0xb5, 0x48, 0xed, 0x49, 0x3b, 0xea, 0xaa, + 0xff, 0x32, 0x20, 0xdc, 0xf9, 0xee, 0x4b, 0xe8, 0xcd, 0x07, 0xfd, 0xa3, 0xf7, + 0x7b, 0xea, 0x13, 0xe4, 0x0c, 0x0c, 0x58, 0x45, 0xf5, 0xf3, 0x39, 0x2b, 0xff, + 0xab, 0xdc, 0x16, 0x2f, 0xf2, 0x26, 0x49, 0xf7, 0x37, 0x00, 0xcc, 0xc6, 0xd3, + 0x09, 0xe9, 0x05, 0xea, 0x12, 0x49, 0x11, 0xe9, 0x17, 0x01, 0xdd, 0x13, 0xf3, + 0x0a, 0x84, 0xdf, 0x0a, 0x23, 0xc9, 0x22, 0xef, 0xd8, 0x12, 0xd5, 0x28, 0x07, + 0x01, 0xb6, 0xd9, 0xcf, 0x0a, 0xc6, 0xef, 0xe3, 0x11, 0xcb, 0xf6, 0x1c, 0x06, + 0xe7, 0xfd, 0xe9, 0x08, 0xfc, 0x58, 0xb7, 0x25, 0x0c, 0x6c, 0xc0, 0x25, 0xb6, + 0xef, 0x1c, 0x04, 0x5c, 0x1f, 0xef, 0xf4, 0xd1, 0xe1, 0x0e, 0xf9, 0xd1, 0xe1, + 0x2c, 0xff, 0x45, 0xe5, 0xf1, 0x4b, 0x01, 0xcb, 0x1e, 0xfd, 0xf0, 0x21, 0xcd, + 0x25, 0x26, 0x12, 0xe0, 0xfb, 0x20, 0xd5, 0xf1, 0xf7, 0x19, 0x0e, 0x18, 0x3b, + 0xde, 0xca, 0xaf, 0x41, 0x20, 0xbf, 0x93, 0x81, 0x09, 0xf9, 0xba, 0xe6, 0xff, + 0xf1, 0xb8, 0x09, 0x4b, 0xf3, 0xe7, 0xdd, 0xe6, 0x07, 0xfd, 0xf4, 0xf1, 0x60, + 0x63, 0xf6, 0x0c, 0xd1, 0x12, 0xf9, 0xf6, 0x01, 0xdf, 0xf0, 0x81, 0xd9, 0xfb, + 0xdd, 0x01, 0xbf, 0x47, 0x25, 0xdd, 0xd8, 0x84, 0x00, 0x1d, 0x26, 0x0f, 0xf4, + 0x3a, 0x26, 0xeb, 0x18, 0x02, 0xf6, 0xfd, 0xf3, 0x01, 0xf8, 0x24, 0xb8, 0xbf, + 0xf1, 0xdc, 0x23, 0xfb, 0x0b, 0xbb, 0x09, 0x48, 0x3b, 0xfc, 0x0d, 0x1b, 0x06, + 0x4d, 0xfe, 0xa7, 0xf6, 0x23, 0xf8, 0xb9, 0x4b, 0x02, 0x75, 0xf5, 0xf5, 0x16, + 0x06, 0x14, 0xcc, 0xf4, 0xfa, 0x7d, 0x03, 0xc3, 0x0e, 0x01, 0x13, 0x1a, 0xcd, + 0xed, 0x20, 0xef, 0x25, 0xa7, 0xf4, 0xea, 0x11, 0x55, 0xe6, 0x14, 0xe1, 0x09, + 0xe1, 0xdd, 0xfb, 0xc5, 0x62, 0x2a, 0xfb, 0xfa, 0xea, 0xfb, 0x24, 0xac, 0xec, + 0xd8, 0xe0, 0xf2, 0xea, 0xda, 0xda, 0xe2, 0x73, 0xc8, 0x0f, 0x96, 0xdb, 0xe4, + 0xc7, 0xd0, 0xf6, 0x47, 0xd4, 0x08, 0xbe, 0x5b, 0xe7, 0xfc, 0x2e, 0x43, 0x24, + 0xbb, 0x2d, 0xff, 0xe7, 0x3a, 0xf9, 0x06, 0xf7, 0xeb, 0xf4, 0xf3, 0xc3, 0xd2, + 0xe3, 0x0c, 0xd3, 0xe2, 0xee, 0x0a, 0x04, 0xef, 0xf6, 0x30, 0x26, 0x0f, 0xec, + 0xbb, 0xc8, 0x0a, 0xd0, 0x14, 0xe1, 0xf1, 0x27, 0x00, 0xe9, 0xe8, 0xdd, 0x01, + 0x20, 0xd8, 0x47, 0x16, 0xf0, 0xe6, 0x0a, 0xd6, 0x1b, 0x34, 0xe7, 0x26, 0x14, + 0xf6, 0xfe, 0x2d, 0xdc, 0xec, 0xdf, 0xed, 0xea, 0xea, 0x10, 0x30, 0x0a, 0xdb, + 0xe6, 0x35, 0x24, 0xf7, 0xf9, 0x44, 0xfd, 0x1b, 0xac, 0xc1, 0x2e, 0xc7, 0x15, + 0xd4, 0xd4, 0xd4, 0x1a, 0xeb, 0xe7, 0x21, 0x2f, 0xe6, 0x0c, 0xe8, 0x38, 0x3e, + 0xd9, 0x05, 0x38, 0xac, 0xf2, 0xe0, 0xeb, 0xd7, 0x0b, 0xf9, 0xfb, 0xf7, 0x08, + 0x02, 0x24, 0x10, 0x7f, 0xe9, 0xe1, 0x1c, 0x2b, 0x0f, 0x10, 0x05, 0xec, 0x4e, + 0xc7, 0xf6, 0xd4, 0xf6, 0x1e, 0xd8, 0x0a, 0xdc, 0x1b, 0xbb, 0xc6, 0xde, 0x1a, + 0xfe, 0x30, 0xae, 0x1b, 0x29, 0x53, 0x06, 0xed, 0xd9, 0x08, 0xf4, 0xd2, 0x1c, + 0x19, 0x14, 0x14, 0xc1, 0x20, 0x11, 0x14, 0x31, 0x00, 0x0c, 0x26, 0xe7, 0x1c, + 0xbf, 0x1a, 0xe5, 0xcf, 0xb5, 0xe9, 0x00, 0xec, 0x1d, 0xc0, 0x7f, 0x33, 0xd1, + 0xfb, 0x1b, 0x30, 0x02, 0xf5, 0x25, 0x00, 0xe9, 0xcd, 0x4a, 0x21, 0x16, 0xc2, + 0x49, 0xe2, 0xfc, 0xc4, 0x39, 0xbc, 0x11, 0xce, 0x4e, 0xf2, 0xff, 0xfe, 0x01, + 0xe9, 0x23, 0x30, 0xfa, 0x27, 0xd8, 0x24, 0xeb, 0x52, 0xd5, 0xec, 0xce, 0x09, + 0xcf, 0xe6, 0xe9, 0x12, 0xe8, 0xe0, 0x06, 0x0a, 0x46, 0xfe, 0x09, 0x29, 0xcf, + 0xc1, 0x10, 0x42, 0x27, 0xec, 0xf8, 0x30, 0x00, 0x21, 0x2b, 0x02, 0xc4, 0x21, + 0xbe, 0x2a, 0xfc, 0xe6, 0xf9, 0xf3, 0xdd, 0xf7, 0x05, 0xd6, 0xc8, 0xd8, 0x23, + 0x1b, 0xeb, 0x20, 0x11, 0x2f, 0x11, 0xe2, 0xf6, 0xe7, 0xb6, 0x26, 0xec, 0xfb, + 0x02, 0xef, 0x01, 0xec, 0x08, 0xed, 0xe3, 0xc8, 0x2c, 0x13, 0x37, 0x14, 0x3e, + 0xd3, 0xe0, 0x0b, 0xdc, 0x14, 0xee, 0xcf, 0x2b, 0xe4, 0xf2, 0xf3, 0xbc, 0xdd, + 0xfa, 0xfa, 0xd2, 0xf0, 0x26, 0xb7, 0x31, 0xd0, 0x07, 0x0e, 0x03, 0x4a, 0x43, + 0x0a, 0x1a, 0xf1, 0x25, 0xf4, 0x4b, 0x06, 0xef, 0x37, 0xf0, 0x13, 0x1c, 0xe2, + 0xe1, 0xd7, 0x1d, 0xe1, 0xe6, 0xf6, 0x44, 0xe9, 0xd1, 0x05, 0xf2, 0x36, 0x2e, + 0xfd, 0x34, 0x0a, 0xc2, 0x43, 0xd2, 0x15, 0xfc, 0x20, 0x0a, 0xd5, 0xe7, 0xcb, + 0xf6, 0x0f, 0xe5, 0xf8, 0xfd, 0x06, 0x0a, 0xdf, 0xe5, 0x14, 0x1b, 0x24, 0xb8, + 0x00, 0xc9, 0x16, 0x0b, 0x0b, 0xdd, 0x03, 0x34, 0xfa, 0x10, 0x2b, 0x08, 0x2a, + 0x5e, 0xdd, 0x7f, 0xf4, 0xe6, 0xcf, 0xd6, 0xfb, 0x06, 0xe3, 0xcb, 0x06, 0xf3, + 0x2b, 0x15, 0xee, 0xa3, 0xc6, 0xee, 0x06, 0xf2, 0x2f, 0xef, 0x20, 0xee, 0x0d, + 0x0f, 0x05, 0xf5, 0xf6, 0xe0, 0xcf, 0xde, 0xfc, 0x17, 0xea, 0xec, 0xd0, 0x17, + 0xf2, 0x1e, 0x02, 0x1c, 0xe8, 0x0a, 0x47, 0xd8, 0xdf, 0xed, 0xfb, 0xf1, 0xf4, + 0x0b, 0x3b, 0x08, 0xf0, 0x13, 0xf3, 0xe3, 0xcd, 0x3f, 0xc4, 0x15, 0x00, 0x7a, + 0x35, 0x05, 0x0a, 0xda, 0x09, 0xf3, 0x06, 0xfb, 0x1d, 0x23, 0xf8, 0xe1, 0xda, + 0xe6, 0xfd, 0x4b, 0x26, 0x20, 0x50, 0xe5, 0xf1, 0x30, 0xbf, 0xfd, 0xf3, 0x25, + 0xf3, 0xc1, 0x0a, 0x23, 0xb9, 0x51, 0x11, 0xde, 0xbf, 0x1f, 0x0c, 0x08, 0xf7, + 0x00, 0x1a, 0xe2, 0x0b, 0xe5, 0xed, 0xea, 0x10, 0xda, 0x0e, 0x16, 0xfa, 0xf7, + 0xf3, 0xfc, 0xa2, 0xde, 0xe8, 0x29, 0x44, 0xa0, 0x16, 0xcf, 0x81, 0x34, 0xf7, + 0xea, 0xf6, 0xe9, 0x3f, 0x30, 0x17, 0x1a, 0xe9, 0x06, 0xfc, 0xd4, 0xd6, 0xf8, + 0x30, 0x0c, 0x4c, 0xe9, 0x07, 0x02, 0xf8, 0xe4, 0xf5, 0xdd, 0xea, 0xfa, 0x1a, + 0xad, 0xbb, 0x41, 0x60, 0x0f, 0x31, 0x18, 0x43, 0xdd, 0x1f, 0x04, 0x0a, 0x1f, + 0x06, 0xb0, 0xd2, 0xbd, 0x38, 0x15, 0x1e, 0xfe, 0xf4, 0xc1, 0x27, 0xeb, 0xe8, + 0x05, 0x18, 0xea, 0x39, 0xf1, 0xdd, 0x44, 0xc6, 0xda, 0x12, 0xef, 0xe9, 0x36, + 0x0e, 0x1b, 0x23, 0x17, 0x07, 0xf9, 0xfd, 0x81, 0x28, 0x2e, 0x26, 0xf3, 0xae, + 0xf5, 0x19, 0x35, 0x2c, 0x1b, 0x05, 0xda, 0xd2, 0x0a, 0xe0, 0x0b, 0xb3, 0xf5, + 0xd6, 0xcd, 0xf1, 0x0f, 0xf9, 0xf8, 0xed, 0xb9, 0x22, 0x23, 0xbf, 0x19, 0x07, + 0xec, 0xd9, 0x06, 0xce, 0xbd, 0xfd, 0xdf, 0xfb, 0xdc, 0x03, 0xb6, 0xdd, 0xd3, + 0xb3, 0x01, 0xe4, 0x0f, 0x3c, 0xa9, 0xd8, 0xc8, 0x8f, 0x0c, 0x39, 0xce, 0x22, + 0x00, 0x1e, 0xb2, 0xf3, 0xec, 0x1f, 0xfb, 0x0b, 0xf8, 0x26, 0xfc, 0x47, 0x34, + 0x33, 0x08, 0x16, 0xe5, 0x0a, 0x05, 0xd4, 0xe5, 0xdd, 0xe9, 0x0d, 0xc7, 0xdf, + 0x11, 0xf9, 0x05, 0x21, 0x01, 0x27, 0xf3, 0xdb, 0xfa, 0xd4, 0x07, 0xc8, 0xd9, + 0xf8, 0x05, 0xd6, 0xdb, 0xf0, 0xbd, 0x21, 0xec, 0xfd, 0x04, 0x39, 0x4d, 0xc9, + 0x29, 0x7f, 0xea, 0xf1, 0xfb, 0xd0, 0xdb, 0x25, 0xda, 0x19, 0xd2, 0x0c, 0xec, + 0xa8, 0xe2, 0xf5, 0x13, 0xcc, 0x05, 0x0a, 0xa0, 0xee, 0xe4, 0x0a, 0x1e, 0x06, + 0x0c, 0xf1, 0xd0, 0xef, 0x02, 0xde, 0x30, 0x06, 0x03, 0x10, 0xda, 0x31, 0x74, + 0x21, 0xd1, 0xff, 0xe9, 0xf6, 0xd8, 0xf9, 0x25, 0x56, 0xf3, 0xe7, 0x06, 0x25, + 0x06, 0xf3, 0xf7, 0x03, 0xd6, 0x08, 0xeb, 0xf7, 0xea, 0xf0, 0x1d, 0x64, 0x0b, + 0xcf, 0xf5, 0x30, 0x48, 0xce, 0x2e, 0xc1, 0xe5, 0xd9, 0xf2, 0xdc, 0x3c, 0x0d, + 0xf3, 0x07, 0xfa, 0xf3, 0xc5, 0xc0, 0xd9, 0x11, 0xd3, 0x02, 0xe6, 0x32, 0xba, + 0x43, 0x31, 0x07, 0xfd, 0xc1, 0xed, 0xfe, 0xef, 0x43, 0xd7, 0x06, 0x52, 0xf8, + 0x2c, 0xf1, 0x51, 0x1a, 0xd8, 0x23, 0x03, 0x1e, 0x23, 0x21, 0xb8, 0xf7, 0x1e, + 0xf7, 0xff, 0x04, 0x28, 0xfc, 0xff, 0x14, 0x6c, 0x13, 0x1c, 0xbb, 0xca, 0x13, + 0x47, 0x19, 0x29, 0xff, 0xde, 0x1d, 0xfe, 0xee, 0xb6, 0x18, 0xc3, 0xf1, 0x1a, + 0xd5, 0x11, 0xc7, 0xd7, 0x2c, 0xc5, 0x27, 0x24, 0x07, 0x19, 0x02, 0xb3, 0xe0, + 0xfc, 0x0a, 0x3d, 0xc0, 0x13, 0x04, 0x37, 0xca, 0x1f, 0x02, 0x32, 0xd3, 0xdf, + 0x0b, 0xf7, 0x1c, 0xd1, 0x39, 0x14, 0xe4, 0xec, 0xf2, 0xef, 0x02, 0x12, 0x1a, + 0xf1, 0xce, 0x15, 0xe5, 0xef, 0xdd, 0x1b, 0x15, 0x26, 0x48, 0x1b, 0xd1, 0x28, + 0x1e, 0x4a, 0x38, 0xc6, 0x81, 0xb2, 0x42, 0x1c, 0xa6, 0x16, 0xd5, 0xee, 0xc5, + 0x00, 0xd8, 0x09, 0xda, 0x18, 0xde, 0xdb, 0xfa, 0xec, 0x34, 0xd2, 0x15, 0x34, + 0x0d, 0x61, 0x1b, 0xc2, 0xe0, 0xe2, 0xef, 0xec, 0xf4, 0x13, 0xe7, 0x13, 0xde, + 0xf3, 0x4d, 0xe5, 0xdf, 0x22, 0xde, 0x13, 0x40, 0x06, 0x1d, 0xe2, 0xf6, 0xad, + 0x6f, 0xaf, 0x23, 0x3f, 0xda, 0xf1, 0xfd, 0xf8, 0xae, 0xdd, 0xf9, 0xc1, 0x0a, + 0xfa, 0x42, 0x81, 0x23, 0xf9, 0xf8, 0x54, 0xcb, 0xbb, 0x21, 0xfa, 0xbd, 0xe8, + 0xca, 0x38, 0x51, 0xe0, 0xdd, 0x10, 0x69, 0xf0, 0x2b, 0x0d, 0x23, 0xf3, 0x0e, + 0xd3, 0xa8, 0xe9, 0x22, 0xf4, 0xec, 0x3b, 0x6b, 0x0e, 0xce, 0xfb, 0x50, 0xe1, + 0x1d, 0x60, 0x2d, 0x2f, 0x0d, 0x16, 0xe2, 0x67, 0xa3, 0x09, 0x2b, 0xed, 0x06, + 0x02, 0x7c, 0x29, 0xc7, 0xc6, 0x1a, 0xe6, 0x4e, 0xc6, 0x3a, 0xdc, 0xb9, 0x2e, + 0xaf, 0x31, 0x51, 0x94, 0x39, 0x12, 0xd6, 0x2a, 0x0d, 0xd9, 0xd8, 0x35, 0x3e, + 0x15, 0x26, 0x17, 0xd8, 0x33, 0x0e, 0x93, 0x76, 0x01, 0x01, 0xdf, 0x11, 0x07, + 0xda, 0xa0, 0xa9, 0x46, 0x36, 0x3f, 0xe2, 0xa4, 0xd2, 0x0a, 0xf9, 0xae, 0x0f, + 0xad, 0x09, 0x20, 0xec, 0x9c, 0x6a, 0x6e, 0xee, 0xba, 0x08, 0x47, 0xd2, 0x03, + 0xf2, 0xc0, 0x4f, 0x34, 0xfb, 0xa3, 0x62, 0x5a, 0xdf, 0xfd, 0x1e, 0xfe, 0xf5, + 0x6f, 0xe6, 0x12, 0x08, 0x30, 0x20, 0xbd, 0xcd, 0x0f, 0xe6, 0xde, 0x01, 0xad, + 0x1d, 0x62, 0xef, 0x20, 0x4c, 0x61, 0x10, 0xba, 0x2b, 0x19, 0x08, 0xcf, 0x50, + 0xf7, 0xdc, 0xc6, 0x4e, 0xe5, 0xee, 0x2b, 0xd7, 0x03, 0x1a, 0xf6, 0xe8, 0xe5, + 0xbd, 0x33, 0x1c, 0xe4, 0xf1, 0x95, 0xcd, 0xce, 0x58, 0x1b, 0x00, 0x42, 0x7f, + 0x84, 0x6e, 0xce, 0x0f, 0xbd, 0x20, 0xe9, 0x18, 0x1b, 0x1e, 0xfd, 0x14, 0x32, + 0x2b, 0xfd, 0xd3, 0x25, 0xe2, 0x13, 0xfb, 0x02, 0x57, 0xfd, 0x58, 0x20, 0xfc, + 0xf1, 0x9d, 0xfc, 0x02, 0xf5, 0xf4, 0xfc, 0xba, 0xcd, 0x77, 0xfe, 0x04, 0x7a, + 0xa9, 0x01, 0x19, 0xc0, 0xef, 0xeb, 0xd4, 0xe3, 0x19, 0x22, 0x54, 0xe5, 0xd7, + 0x06, 0xfe, 0xb5, 0xe7, 0xdc, 0xa0, 0x15, 0xc1, 0xfc, 0x23, 0xf5, 0xd9, 0x29, + 0x23, 0x47, 0xfe, 0x3c, 0x8c, 0xe8, 0xd6, 0xb7, 0xff, 0x04, 0xdb, 0xf9, 0xe3, + 0xe7, 0x20, 0x90, 0x10, 0xed, 0x11, 0xde, 0xff, 0xfc, 0xf6, 0xf1, 0x0c, 0xa8, + 0x6b, 0xc3, 0x12, 0x0f, 0x26, 0x1e, 0x07, 0x5b, 0x3f, 0xc4, 0xee, 0xf0, 0x40, + 0xdb, 0x7f, 0xba, 0x23, 0x5d, 0xac, 0xcf, 0x15, 0x42, 0x32, 0x0f, 0x51, 0x32, + 0x06, 0xc3, 0x23, 0xe3, 0xfa, 0x24, 0x2d, 0xf8, 0x35, 0xdf, 0x4c, 0x34, 0xb1, + 0x88, 0x08, 0x16, 0x2a, 0x3d, 0x15, 0x95, 0x3c, 0x4e, 0xe4, 0xdc, 0xb4, 0x1b, + 0xdb, 0xc0, 0x14, 0x5e, 0xd5, 0xe5, 0xc8, 0xb7, 0x0f, 0xe4, 0xdd, 0x40, 0x22, + 0xde, 0xfb, 0x1d, 0x38, 0xe5, 0xf7, 0xd4, 0xeb, 0xfe, 0x0d, 0xed, 0x63, 0x30, + 0x43, 0x5d, 0xd5, 0xf9, 0xe3, 0x09, 0xf5, 0xee, 0x13, 0x07, 0xd0, 0x03, 0xf3, + 0xe1, 0x48, 0x1f, 0x41, 0x29, 0xdf, 0x02, 0x1b, 0x1f, 0x0d, 0x10, 0xf1, 0xc2, + 0x00, 0x2a, 0x9b, 0x08, 0xcd, 0x30, 0x01, 0xd9, 0x06, 0x1b, 0x07, 0xee, 0xf3, + 0x06, 0x2d, 0x4a, 0xf4, 0xfd, 0x1b, 0x2f, 0xc9, 0x1b, 0xda, 0xc8, 0x19, 0x1b, + 0xcd, 0x19, 0xf9, 0x00, 0x13, 0xf5, 0xe7, 0x09, 0x22, 0x7f, 0x0d, 0xed, 0x11, + 0x71, 0x01, 0x1e, 0x02, 0x09, 0x08, 0x27, 0xe0, 0x4b, 0xec, 0xe8, 0x0a, 0x2c, + 0xe4, 0x2c, 0x00, 0xff, 0xf6, 0x20, 0x14, 0xe7, 0xcb, 0xc5, 0xf8, 0xf1, 0x04, + 0x26, 0x17, 0x18, 0xff, 0x10, 0xd1, 0x0d, 0x2b, 0xe8, 0x06, 0x19, 0xcf, 0xf3, + 0xe0, 0xc5, 0xcd, 0x31, 0x27, 0xe3, 0x52, 0x0c, 0x0f, 0xcf, 0x0a, 0x18, 0x20, + 0xe7, 0xf1, 0xa9, 0xdb, 0x13, 0xf4, 0x02, 0x16, 0xf2, 0xfb, 0x36, 0xea, 0xf9, + 0x2c, 0x1f, 0x13, 0x3e, 0x2a, 0x5f, 0xb2, 0x3e, 0xd9, 0xee, 0xdf, 0x1d, 0x32, + 0x2d, 0xf4, 0x30, 0x1b, 0xfc, 0xf1, 0xee, 0xca, 0xf9, 0x20, 0xb4, 0xfc, 0x18, + 0x3f, 0x4b, 0xb2, 0xa4, 0x17, 0xeb, 0x39, 0xc9, 0xe1, 0xef, 0x1a, 0x4e, 0xea, + 0x50, 0xf5, 0x00, 0x1f, 0x05, 0x20, 0x70, 0x08, 0x28, 0x08, 0xd1, 0xc0, 0xf1, + 0xfe, 0xc6, 0xbc, 0xdf, 0x1c, 0xca, 0x75, 0x42, 0x1f, 0x5a, 0xda, 0x44, 0x38, + 0x0f, 0xde, 0x81, 0x10, 0xea, 0x39, 0xec, 0xf5, 0x1b, 0xfc, 0x12, 0x2a, 0xdf, + 0xa4, 0xee, 0xf0, 0xed, 0xaa, 0xf3, 0xaf, 0xfc, 0x03, 0x7d, 0x17, 0xe2, 0x01, + 0xf2, 0x07, 0xcd, 0x14, 0x02, 0xc5, 0xf7, 0xaa, 0x21, 0xe9, 0x7e, 0xe0, 0xdd, + 0xf6, 0xec, 0xfa, 0x0a, 0x52, 0x15, 0x0a, 0xef, 0x3a, 0x33, 0xe1, 0xfa, 0x4f, + 0x28, 0x7b, 0xc6, 0x9f, 0xe6, 0x42, 0x18, 0x68, 0xdf, 0x0f, 0x5d, 0xef, 0xda, + 0x3d, 0x0f, 0xad, 0xb0, 0x40, 0xee, 0xbc, 0xcd, 0xdf, 0x09, 0x01, 0xdf, 0x54, + 0xe7, 0x18, 0x00, 0xd6, 0x26, 0xf7, 0x41, 0xc3, 0xa7, 0x0f, 0x0b, 0xc4, 0x02, + 0x13, 0x14, 0x2a, 0xc6, 0x5c, 0xf6, 0x33, 0xb5, 0x09, 0x22, 0x66, 0xbe, 0xdd, + 0x3e, 0xe8, 0x7a, 0xfc, 0xec, 0xbd, 0xb5, 0x23, 0x35, 0xd7, 0x20, 0x98, 0x2b, + 0x03, 0xe9, 0xef, 0x0e, 0x13, 0x0c, 0xcf, 0xb3, 0x26, 0x53, 0x0f, 0xca, 0x00, + 0x2c, 0xf6, 0x9b, 0x30, 0xf7, 0xfd, 0xa8, 0x4e, 0xb6, 0xe1, 0x49, 0x1b, 0x21, + 0x02, 0x29, 0xff, 0xe9, 0xc4, 0xc5, 0x20, 0x73, 0x3a, 0xd1, 0x56, 0x00, 0xc4, + 0x30, 0xcd, 0xc6, 0x18, 0xe8, 0x64, 0x6f, 0xd5, 0x22, 0xec, 0x17, 0x81, 0xff, + 0x06, 0xad, 0xa8, 0xe0, 0x04, 0xe1, 0xfd, 0xfc, 0x23, 0x46, 0x20, 0xb9, 0xe6, + 0xf5, 0x3b, 0x0d, 0x15, 0x2f, 0xfd, 0x0a, 0x43, 0xe4, 0x26, 0x12, 0x30, 0x07, + 0x36, 0x2d, 0x0e, 0xca, 0xf4, 0x22, 0xf7, 0x01, 0x2a, 0xf1, 0x25, 0xdf, 0x72, + 0x27, 0x27, 0x2d, 0x38, 0x41, 0xb9, 0xcb, 0xb3, 0xff, 0x1d, 0x09, 0x20, 0x23, + 0xdf, 0x29, 0xfe, 0x16, 0x20, 0xb1, 0x31, 0xfe, 0xf2, 0xe6, 0xf8, 0x1f, 0xf4, + 0xe8, 0xe1, 0xa7, 0xe4, 0x30, 0x12, 0xe1, 0xdf, 0xf5, 0x49, 0xf7, 0xe8, 0xf7, + 0x09, 0xc3, 0xf4, 0x5b, 0xf2, 0xb3, 0x90, 0xb9, 0xfe, 0x25, 0xe6, 0xff, 0xde, + 0x91, 0xcf, 0xe2, 0xfa, 0x7f, 0xeb, 0x15, 0xcf, 0x1d, 0xc7, 0x08, 0x24, 0xf2, + 0xd9, 0xe8, 0x19, 0xf2, 0xf5, 0x07, 0x18, 0xfc, 0x17, 0xfb, 0xfc, 0x1c, 0x1a, + 0x7b, 0xf0, 0x1d, 0x06, 0x10, 0x42, 0x3b, 0xdb, 0x09, 0xf2, 0xbc, 0x8c, 0x38, + 0xfa, 0xd4, 0x5c, 0x2e, 0xfc, 0x23, 0x13, 0x22, 0xfe, 0x24, 0xeb, 0x5a, 0xe1, + 0xe9, 0x0e, 0x81, 0xee, 0x63, 0xf3, 0xf7, 0xfe, 0xd6, 0x29, 0xec, 0x15, 0xe4, + 0x0e, 0xe7, 0xe1, 0xd0, 0xe2, 0xf1, 0xc8, 0x22, 0x29, 0xf3, 0x25, 0x39, 0x3a, + 0xfe, 0x1c, 0xdf, 0x05, 0x31, 0x12, 0x13, 0xc7, 0xea, 0xd5, 0x1e, 0xc8, 0xf2, + 0x14, 0xef, 0xd0, 0x26, 0x59, 0xb4, 0x1d, 0xf2, 0xeb, 0x07, 0xfe, 0x20, 0xf3, + 0xb6, 0x21, 0xac, 0xd0, 0xda, 0xe8, 0xfa, 0x3f, 0x10, 0xf7, 0x04, 0x1b, 0x40, + 0x11, 0x33, 0xeb, 0xfe, 0x25, 0xda, 0xbd, 0xe9, 0x22, 0xe0, 0x39, 0xf0, 0xb0, + 0xf1, 0x68, 0x15, 0x0b, 0xe2, 0x09, 0xc0, 0xac, 0x06, 0xdf, 0x13, 0xc9, 0xcb, + 0x36, 0xe1, 0x22, 0xde, 0x0d, 0x25, 0x1d, 0xf7, 0x07, 0xcf, 0x39, 0x47, 0x1f, + 0x7b, 0x2f, 0xf9, 0x4a, 0xea, 0x1b, 0x14, 0x11, 0xef, 0x10, 0x27, 0x07, 0x0a, + 0xec, 0x33, 0x07, 0x1a, 0xed, 0x32, 0xff, 0x28, 0xe0, 0xe1, 0xfe, 0xe8, 0x11, + 0xdf, 0x28, 0xba, 0x10, 0x20, 0xb6, 0xfb, 0x0a, 0xf3, 0x00, 0xe2, 0x0d, 0xfb, + 0xf0, 0xda, 0xe8, 0x15, 0xe1, 0x2d, 0xdb, 0x27, 0xfe, 0xe2, 0xfb, 0xfb, 0xcd, + 0x0a, 0x0d, 0xe2, 0x1a, 0xfd, 0xf0, 0x42, 0x29, 0x03, 0xe9, 0x0d, 0xf7, 0xf3, + 0xed, 0xf0, 0xeb, 0x16, 0xf0, 0xde, 0x18, 0x0b, 0x15, 0xed, 0x54, 0xbc, 0x07, + 0xe1, 0xff, 0xf9, 0x14, 0xf9, 0xe1, 0xf3, 0xfe, 0xdd, 0x00, 0xe8, 0xe4, 0xe0, + 0xe6, 0x0a, 0xcc, 0x01, 0xd0, 0xe6, 0xd7, 0x0b, 0xe4, 0x02, 0x40, 0x2d, 0xcb, + 0xe4, 0x15, 0xd8, 0xfb, 0xf9, 0xf2, 0x10, 0xd4, 0xef, 0x18, 0xcd, 0xcd, 0xda, + 0x7f, 0xfe, 0x05, 0x2b, 0xea, 0xf7, 0xe6, 0x0e, 0x2d, 0xed, 0x01, 0xd4, 0xfa, + 0xe5, 0x02, 0x07, 0x29, 0x03, 0xf7, 0x1b, 0x1a, 0x06, 0xdf, 0x27, 0xef, 0xec, + 0xdf, 0x26, 0x03, 0xf5, 0xee, 0xfc, 0xda, 0xd2, 0xf9, 0x0a, 0x4a, 0xf7, 0xcc, + 0x63, 0x39, 0x36, 0xcb, 0x2c, 0x05, 0xdd, 0x36, 0xe4, 0xbd, 0xdc, 0xb2, 0x0a, + 0xc5, 0xb9, 0x17, 0x7f, 0x02, 0xd4, 0xf7, 0x07, 0x19, 0x3d, 0x0e, 0xc6, 0xc8, + 0xcd, 0xc9, 0x06, 0xe3, 0xb2, 0xac, 0xd3, 0x25, 0xdb, 0xfb, 0x21, 0x33, 0xe9, + 0x30, 0x8c, 0x21, 0xc4, 0xbc, 0xa1, 0x24, 0xaa, 0xc3, 0x06, 0xec, 0xe3, 0x36, + 0x32, 0xa2, 0x62, 0xf9, 0xa2, 0x17, 0x25, 0x0e, 0xee, 0x06, 0x32, 0xdb, 0xfd, + 0x00, 0x77, 0xf4, 0xc2, 0x1c, 0x47, 0xee, 0x06, 0xb0, 0x4a, 0xaf, 0xe8, 0x03, + 0xc2, 0x1f, 0xc9, 0xe7, 0xd9, 0xea, 0xf7, 0x00, 0xe5, 0xc7, 0x10, 0x39, 0x6c, + 0xd7, 0x19, 0xf8, 0x0d, 0x12, 0xd1, 0x0d, 0x2b, 0x01, 0xfe, 0x50, 0xc4, 0xb5, + 0xe8, 0x06, 0x0c, 0xe7, 0x38, 0x77, 0xe9, 0xec, 0x0e, 0x0c, 0xf0, 0xff, 0xef, + 0x02, 0x0b, 0x05, 0xa3, 0x27, 0xc5, 0x2a, 0x20, 0x14, 0xed, 0x26, 0xbf, 0x20, + 0x04, 0xd0, 0x19, 0x30, 0x06, 0x2e, 0x43, 0x1a, 0xe5, 0xef, 0xd5, 0xf2, 0xe7, + 0xf4, 0xc4, 0x24, 0xee, 0x4b, 0xf1, 0x2d, 0x00, 0xe4, 0xe9, 0x16, 0x3c, 0x34, + 0x1a, 0x9d, 0xf4, 0xe1, 0xc8, 0xf9, 0x38, 0x0d, 0xff, 0x26, 0x10, 0x24, 0xf9, + 0x97, 0xa9, 0x3c, 0x34, 0xd8, 0xcd, 0xf8, 0x21, 0x0c, 0xc9, 0xe8, 0x07, 0xc2, + 0xfc, 0x3c, 0xb3, 0xe1, 0xdc, 0x13, 0xed, 0xa4, 0x59, 0xe6, 0x11, 0xfa, 0x22, + 0xd5, 0x0c, 0x1d, 0x27, 0x1e, 0x25, 0xb9, 0x03, 0xe8, 0xfe, 0x36, 0xf1, 0xd9, + 0x3f, 0x1d, 0xe5, 0x32, 0xca, 0xf7, 0x0d, 0x28, 0x37, 0xe3, 0xf2, 0xf3, 0xef, + 0xe9, 0xf8, 0xfa, 0x22, 0xd9, 0x5f, 0x06, 0x55, 0xf8, 0xd3, 0x05, 0x17, 0x37, + 0x72, 0xf6, 0xb3, 0x12, 0x2b, 0x06, 0xd3, 0xee, 0x17, 0x13, 0x3b, 0x29, 0x81, + 0x87, 0xe5, 0x40, 0x4c, 0x06, 0xd2, 0x3f, 0x7f, 0x0b, 0x4c, 0x48, 0x3e, 0xc6, + 0xf4, 0x36, 0xc2, 0xde, 0x28, 0x02, 0x2d, 0xef, 0x08, 0x06, 0x27, 0x48, 0x62, + 0x19, 0x3c, 0x0f, 0xe7, 0x10, 0x1f, 0xd4, 0xcb, 0x87, 0xff, 0xd0, 0xfb, 0xe4, + 0xfd, 0x13, 0x21, 0xff, 0xcb, 0x1f, 0xe4, 0x4e, 0x0d, 0x18, 0xf8, 0x6b, 0x30, + 0xeb, 0xfe, 0x35, 0x34, 0xd3, 0x33, 0xe3, 0xb8, 0x57, 0xd8, 0xee, 0xc0, 0xbd, + 0xa8, 0xea, 0xfd, 0xc5, 0x02, 0x1b, 0xda, 0x61, 0xf2, 0xe5, 0xf7, 0x15, 0x05, + 0x13, 0xda, 0xda, 0xc0, 0x06, 0xaf, 0x1c, 0xd7, 0xd0, 0x58, 0x45, 0x2e, 0xdd, + 0xfa, 0xd6, 0x5b, 0xec, 0xbd, 0x14, 0xc5, 0x26, 0xd7, 0x18, 0x0c, 0x19, 0xba, + 0xf1, 0x08, 0x13, 0x22, 0x1c, 0xda, 0x68, 0x44, 0x0d, 0x30, 0x2c, 0xf3, 0xdc, + 0x4a, 0x19, 0x1d, 0x2d, 0x1c, 0x21, 0x30, 0x00, 0xf3, 0x1f, 0x01, 0xed, 0xea, + 0xc2, 0x56, 0xe7, 0xe6, 0xce, 0xf1, 0xfc, 0x15, 0x19, 0x7f, 0x9a, 0x9c, 0xa4, + 0x47, 0xf6, 0x08, 0xe9, 0x8c, 0x11, 0xaa, 0x12, 0xcc, 0x22, 0xea, 0xb8, 0xe5, + 0xea, 0x16, 0x01, 0xdf, 0x9f, 0x96, 0xfd, 0x46, 0x22, 0x0e, 0xc1, 0x11, 0x04, + 0xa9, 0xf6, 0xc7, 0xf0, 0x04, 0x4e, 0xea, 0xdb, 0x8e, 0x39, 0x05, 0xdb, 0xe4, + 0xf4, 0x8d, 0xd7, 0x15, 0x27, 0xb0, 0x18, 0xf3, 0xe0, 0xd8, 0xf1, 0x3b, 0x1b, + 0x17, 0x5c, 0xd4, 0x31, 0x13, 0xc9, 0x08, 0x00, 0xbf, 0x2a, 0x5e, 0x4e, 0x03, + 0x1b, 0xe1, 0x32, 0x20, 0xfa, 0x38, 0x2e, 0x26, 0x4d, 0xe0, 0x0c, 0x28, 0x00, + 0x54, 0x99, 0xd7, 0x10, 0x2f, 0x27, 0xef, 0x0c, 0x14, 0xd4, 0xa5, 0x45, 0x18, + 0xf1, 0x10, 0xec, 0x43, 0x9f, 0xdc, 0xe7, 0xce, 0xbb, 0x13, 0x32, 0xdd, 0x29, + 0x91, 0x3f, 0xdc, 0x02, 0x02, 0xf8, 0xcf, 0x2b, 0x47, 0xa4, 0x48, 0xdb, 0x29, + 0x2b, 0xe8, 0xfd, 0x08, 0x0d, 0xf6, 0x4a, 0x02, 0xf4, 0x13, 0x28, 0x17, 0xd9, + 0x2f, 0x0b, 0x3a, 0xd5, 0x0e, 0xee, 0x00, 0x0a, 0x0e, 0x26, 0xf8, 0xf1, 0x1a, + 0x0a, 0x13, 0x53, 0x01, 0xda, 0xac, 0x50, 0xfb, 0xe0, 0xe0, 0x14, 0xf8, 0x02, + 0xdd, 0xe6, 0x10, 0x3f, 0xc6, 0xff, 0x33, 0x0f, 0x32, 0xf7, 0x2f, 0x09, 0x69, + 0xeb, 0xd9, 0xe3, 0x36, 0xec, 0xeb, 0x25, 0x11, 0xed, 0xdc, 0x3d, 0x0c, 0x02, + 0x41, 0xd1, 0xe4, 0xff, 0xc5, 0x1a, 0xf3, 0x08, 0x14, 0xd9, 0x7f, 0xee, 0x12, + 0xda, 0x2e, 0xd4, 0xfd, 0xe2, 0xcf, 0xe9, 0xc1, 0x34, 0xcc, 0xe1, 0x1d, 0x15, + 0x24, 0xcf, 0x22, 0x5b, 0xa4, 0x09, 0x11, 0xca, 0xd6, 0xdf, 0xea, 0x18, 0x0e, + 0x58, 0xce, 0x0b, 0x1c, 0x02, 0x08, 0xce, 0x26, 0xca, 0x27, 0x45, 0xce, 0x2b, + 0x13, 0xcf, 0xea, 0xdf, 0x5f, 0x54, 0xcf, 0xe5, 0x88, 0x0d, 0x13, 0xfb, 0xf6, + 0xcf, 0xe3, 0xf1, 0xfb, 0xd1, 0x03, 0x21, 0x41, 0xd5, 0x09, 0x0c, 0xd7, 0xda, + 0x0e, 0xcb, 0xf8, 0xe4, 0xe8, 0x02, 0xee, 0xbc, 0x2b, 0x08, 0x2c, 0xf8, 0xdc, + 0xdb, 0xcc, 0x2f, 0x14, 0x19, 0x3f, 0x14, 0x3f, 0xe1, 0xde, 0xfc, 0x0c, 0xc7, + 0xea, 0x30, 0x07, 0xfc, 0xe4, 0x18, 0xe9, 0xe8, 0xdb, 0xf4, 0xae, 0xeb, 0xf9, + 0x3b, 0xb2, 0xf2, 0xe4, 0xf9, 0x01, 0x28, 0xd9, 0x49, 0x03, 0xc5, 0xdb, 0xd5, + 0x1e, 0x1b, 0x10, 0xfe, 0xea, 0xef, 0x23, 0x40, 0x45, 0x13, 0xe3, 0x27, 0xeb, + 0x29, 0x1e, 0xfe, 0xf8, 0x4f, 0x1a, 0x2f, 0xea, 0x0b, 0x09, 0x1f, 0x10, 0xda, + 0xed, 0xe7, 0xfa, 0xee, 0x3e, 0xee, 0xcd, 0x10, 0xed, 0x51, 0xe6, 0x1b, 0x21, + 0xca, 0x1a, 0x7f, 0xed, 0x1b, 0xbd, 0xfc, 0x28, 0xf2, 0xe2, 0x2f, 0xec, 0xd1, + 0x2b, 0xf8, 0xdc, 0x6a, 0x16, 0x35, 0x44, 0x42, 0xf9, 0x24, 0xf3, 0xf1, 0xb8, + 0x39, 0xd9, 0xeb, 0xfe, 0x46, 0x0b, 0xd4, 0xf6, 0xf8, 0x3c, 0xf8, 0x27, 0x22, + 0x16, 0x1b, 0x10, 0x37, 0x28, 0xfa, 0x02, 0x05, 0xc5, 0xdd, 0x27, 0xdb, 0x46, + 0xe4, 0xb9, 0x0d, 0xfc, 0x0b, 0xc8, 0xf6, 0xeb, 0xf9, 0x0b, 0x16, 0xfc, 0xf7, + 0xd6, 0xd3, 0x00, 0xdc, 0x11, 0xe3, 0x35, 0xf9, 0xf1, 0xea, 0xde, 0x11, 0x15, + 0x5b, 0x29, 0xeb, 0xeb, 0xfe, 0x0e, 0xcf, 0xe1, 0xe6, 0xf7, 0xe7, 0xf7, 0xda, + 0x0a, 0xed, 0x16, 0x66, 0xcc, 0xd2, 0x24, 0xf8, 0x35, 0x10, 0xc9, 0xdb, 0xe3, + 0x26, 0x1d, 0xdc, 0xd7, 0x1c, 0x26, 0x58, 0x0d, 0x0f, 0x15, 0x41, 0x02, 0x09, + 0xc6, 0x15, 0x1e, 0xff, 0xf8, 0xe2, 0x19, 0xdd, 0xeb, 0x12, 0x81, 0x1b, 0xe6, + 0x41, 0xe2, 0x1f, 0xe5, 0xfc, 0xa1, 0xe8, 0xe5, 0x06, 0x1c, 0xd8, 0xf7, 0x23, + 0x30, 0xd3, 0xd1, 0x5c, 0xa7, 0xcb, 0x35, 0x01, 0x07, 0x67, 0xe0, 0x15, 0x1b, + 0x0f, 0xf9, 0x17, 0x4b, 0xe9, 0xfc, 0xf9, 0xad, 0xe6, 0x0d, 0x12, 0x07, 0x23, + 0xd3, 0x0d, 0xef, 0x0a, 0x42, 0xff, 0xe6, 0x17, 0xe4, 0x19, 0xd5, 0x24, 0x43, + 0xde, 0x4a, 0xc7, 0xca, 0xde, 0xeb, 0x28, 0xbe, 0x27, 0x10, 0xe3, 0x0e, 0x0c, + 0xc6, 0xaf, 0x34, 0xc5, 0xc5, 0xa9, 0xdd, 0xde, 0x10, 0xfc, 0xdd, 0x3a, 0x20, + 0x2e, 0x05, 0xbb, 0xe3, 0xfe, 0xca, 0x10, 0x09, 0x4e, 0x0b, 0x7f, 0xf5, 0xf3, + 0x08, 0x0b, 0x27, 0xc9, 0xdb, 0x1d, 0xe0, 0xd7, 0xf4, 0xfb, 0x0c, 0x05, 0xf7, + 0x1f, 0xe5, 0xce, 0xd9, 0xda, 0x4a, 0xd6, 0xd6, 0x4e, 0x88, 0x31, 0xee, 0xfb, + 0xd5, 0x36, 0xc7, 0x1d, 0xee, 0xef, 0x08, 0xdd, 0x34, 0x34, 0x31, 0xce, 0xf1, + 0xda, 0xdf, 0x0e, 0xda, 0xd6, 0x18, 0xdf, 0xdf, 0xfd, 0x1b, 0xde, 0xfc, 0xde, + 0xc0, 0x9d, 0xfe, 0xde, 0xf2, 0x1c, 0x04, 0xbf, 0x0a, 0x05, 0x8b, 0x11, 0xb2, + 0x1e, 0x1d, 0xa5, 0xea, 0x1d, 0xe9, 0xe4, 0x19, 0xcc, 0x13, 0xcb, 0x19, 0x0f, + 0xf1, 0xb0, 0xcf, 0xe6, 0xec, 0x01, 0xdb, 0x11, 0xf4, 0x3e, 0x33, 0x16, 0xcc, + 0x1a, 0xf2, 0xff, 0xa5, 0xef, 0xce, 0x13, 0x12, 0x18, 0x12, 0xf0, 0xe4, 0xf3, + 0xea, 0x06, 0xbf, 0xc4, 0xf9, 0x33, 0xc1, 0x06, 0x1f, 0xe1, 0xd0, 0x27, 0xef, + 0xfb, 0xfa, 0xdb, 0x06, 0x2b, 0xff, 0xe2, 0xbe, 0x17, 0xdb, 0x1b, 0x09, 0xf7, + 0x2d, 0x0d, 0x4a, 0x2c, 0x0c, 0x33, 0xfd, 0x03, 0x01, 0xe1, 0xf4, 0x4b, 0x05, + 0x0b, 0xcf, 0x36, 0x33, 0xed, 0x26, 0x09, 0xe1, 0x13, 0x09, 0x04, 0x35, 0x17, + 0xf2, 0x35, 0xd3, 0xfe, 0x2b, 0xdc, 0x56, 0x3a, 0xdc, 0x1c, 0xd2, 0x2f, 0x01, + 0xe4, 0x9f, 0x36, 0x71, 0xd5, 0x30, 0xe3, 0x12, 0x44, 0x25, 0xec, 0x81, 0xfb, + 0x4a, 0x08, 0xe3, 0x4a, 0x22, 0xd4, 0x37, 0xd4, 0x37, 0x1f, 0x37, 0xd1, 0x07, + 0x1d, 0xdd, 0x06, 0xfb, 0x10, 0x0c, 0xd8, 0x74, 0x07, 0xa3, 0xe4, 0x31, 0xe8, + 0xd0, 0xce, 0x21, 0x1b, 0xea, 0xb1, 0x0b, 0x5e, 0xef, 0x1c, 0x3d, 0xab, 0x42, + 0xfe, 0xf0, 0x43, 0x02, 0xd9, 0x3e, 0xe1, 0x36, 0x08, 0x89, 0x0a, 0xeb, 0xf9, + 0xdb, 0x3d, 0xca, 0xfa, 0x15, 0xed, 0x31, 0xab, 0xef, 0x41, 0xe8, 0x1a, 0xb3, + 0x4d, 0x18, 0x25, 0x39, 0x2d, 0x3e, 0xd9, 0xf9, 0x69, 0xd5, 0x30, 0x44, 0x0c, + 0x12, 0x31, 0x19, 0x51, 0x4b, 0x41, 0x26, 0x09, 0x38, 0x09, 0xcc, 0xe1, 0xed, + 0xd2, 0xf5, 0xe1, 0xe5, 0x0f, 0x0b, 0x04, 0xe0, 0xcc, 0xbe, 0x3b, 0x40, 0x18, + 0xfa, 0x10, 0xde, 0xf8, 0x2b, 0x81, 0xf7, 0x16, 0x87, 0x31, 0x47, 0x23, 0x38, + 0x12, 0x69, 0x5b, 0xd9, 0xff, 0xe7, 0xf3, 0xcb, 0x63, 0xfb, 0x48, 0x17, 0xfc, + 0x06, 0xf2, 0x15, 0xde, 0x20, 0xc8, 0x03, 0xd8, 0xe7, 0xfe, 0x31, 0xd3, 0xa7, + 0x0d, 0xf3, 0x1c, 0xf4, 0x7e, 0xd6, 0x28, 0x35, 0x13, 0x23, 0x0b, 0x00, 0xd9, + 0x09, 0x1d, 0xe0, 0x81, 0xb9, 0x45, 0xd1, 0x05, 0xe7, 0x32, 0xe5, 0x5e, 0x76, + 0xd4, 0x1a, 0x05, 0xfb, 0xef, 0xe5, 0xd3, 0x04, 0xbe, 0xea, 0xd3, 0xd7, 0xcd, + 0x43, 0xad, 0x0f, 0x0e, 0xf2, 0xed, 0x5c, 0x0a, 0x27, 0xe7, 0x08, 0xa2, 0x1f, + 0x18, 0x13, 0x12, 0x1d, 0xcc, 0x15, 0x12, 0xbc, 0xf5, 0xc1, 0x08, 0x00, 0x07, + 0xc9, 0xd6, 0xda, 0xf6, 0xcf, 0x2a, 0x14, 0xe2, 0xf8, 0xad, 0x37, 0xee, 0xfc, + 0xdd, 0xdb, 0x2b, 0x0f, 0x07, 0xf7, 0xdb, 0x26, 0xf8, 0x28, 0xf9, 0x1d, 0xf3, + 0x30, 0xed, 0x75, 0xff, 0xf7, 0x29, 0xf8, 0x16, 0x64, 0x15, 0xe1, 0xf9, 0x09, + 0xd9, 0xb8, 0xd9, 0xed, 0x47, 0xd6, 0xdd, 0x2c, 0x1c, 0xca, 0xe8, 0x94, 0x37, + 0x04, 0x20, 0x7f, 0x3d, 0x60, 0xfa, 0x1a, 0xdf, 0xc4, 0x1e, 0xf5, 0x02, 0xee, + 0x22, 0x2b, 0xfe, 0x15, 0xcf, 0x0f, 0x51, 0xfd, 0xf7, 0xdc, 0xd3, 0xf3, 0xf0, + 0xf4, 0xd8, 0xb6, 0xd2, 0x01, 0xed, 0x17, 0x1b, 0xdf, 0xf7, 0xc6, 0xf0, 0xd0, + 0x06, 0xdf, 0xd0, 0xd1, 0x22, 0x1c, 0x08, 0x28, 0x08, 0x20, 0xff, 0x64, 0x1b, + 0xa8, 0x05, 0x44, 0xdf, 0xe6, 0xca, 0xed, 0x08, 0x1f, 0xd7, 0x21, 0xff, 0xb5, + 0x6a, 0xa8, 0x45, 0x15, 0x06, 0x46, 0xa7, 0xe2, 0x10, 0xfa, 0x0e, 0xfe, 0xc2, + 0x27, 0xc3, 0x21, 0xd2, 0xef, 0x13, 0xa9, 0xed, 0x05, 0xac, 0x2d, 0xf4, 0x16, + 0xdc, 0xae, 0x3b, 0x15, 0xdf, 0xdc, 0xcc, 0x19, 0xfa, 0xfd, 0x21, 0xb0, 0xe3, + 0xe3, 0x46, 0xbd, 0xf8, 0xae, 0xd8, 0xed, 0x1f, 0x5b, 0xe4, 0xdc, 0x26, 0xff, + 0x01, 0xdb, 0x4f, 0x2d, 0x4c, 0xe1, 0xf9, 0xcc, 0xef, 0xbc, 0xb1, 0x0a, 0x20, + 0x0e, 0xef, 0x23, 0x18, 0x26, 0xaa, 0xea, 0xce, 0x0b, 0xc3, 0xb3, 0xf9, 0xf0, + 0xe3, 0xf4, 0xf0, 0xf9, 0xf2, 0x35, 0xda, 0xe8, 0x1b, 0xe0, 0xbc, 0x1e, 0xf2, + 0xbe, 0x1a, 0x28, 0x07, 0x10, 0xfb, 0xca, 0xe5, 0x19, 0xe9, 0x1f, 0x07, 0x1e, + 0xee, 0x58, 0xde, 0x05, 0xfe, 0xd2, 0xc1, 0xfc, 0x38, 0x2f, 0xdb, 0x09, 0x37, + 0xea, 0xd2, 0x23, 0x38, 0xe3, 0xde, 0xbe, 0x24, 0xd3, 0x06, 0x33, 0xda, 0xea, + 0xea, 0x1e, 0x2a, 0x23, 0x38, 0x1c, 0x13, 0x10, 0x24, 0xed, 0x7f, 0x01, 0xb5, + 0xad, 0xe0, 0x03, 0x04, 0xb3, 0xf4, 0xfe, 0xfe, 0x1e, 0xb9, 0xe3, 0xd2, 0x15, + 0xfe, 0x22, 0xf5, 0x26, 0x71, 0xe5, 0xa6, 0x0f, 0x14, 0x6f, 0xe2, 0xca, 0xbb, + 0x10, 0x97, 0xed, 0xea, 0x3f, 0xcf, 0x3b, 0xe6, 0xbe, 0xdf, 0x10, 0xbc, 0xa9, + 0x15, 0xea, 0x20, 0x09, 0x30, 0x95, 0x2f, 0xa0, 0x27, 0x17, 0xb8, 0xd6, 0x2c, + 0x25, 0x3f, 0xec, 0xb4, 0x76, 0xf3, 0xf9, 0x36, 0x45, 0x0d, 0xc6, 0x55, 0x39, + 0x3b, 0xe9, 0x13, 0x20, 0xa0, 0x36, 0xdc, 0x07, 0x26, 0xb2, 0xcc, 0x81, 0x02, + 0xba, 0x24, 0xc5, 0xf2, 0x01, 0xdf, 0xc9, 0x5f, 0x26, 0x04, 0x18, 0x2f, 0xdb, + 0x27, 0x2c, 0x53, 0xc1, 0x9a, 0xe2, 0x65, 0xcd, 0x0b, 0xd8, 0xbe, 0x15, 0x41, + 0x35, 0x24, 0x36, 0xf2, 0xb1, 0x07, 0xfc, 0xfb, 0x44, 0x58, 0x3c, 0x2a, 0x24, + 0xf4, 0xd9, 0xe8, 0xd1, 0xb5, 0x28, 0xed, 0xcf, 0xb6, 0xc6, 0xd4, 0x09, 0x09, + 0xdd, 0x0e, 0xc5, 0xeb, 0xf5, 0x17, 0xfe, 0xbf, 0x25, 0xc4, 0x15, 0x00, 0x3c, + 0xf8, 0xe4, 0xea, 0x16, 0xe6, 0xf7, 0xfd, 0xb1, 0x19, 0xe1, 0xf2, 0xfd, 0xcc, + 0x33, 0x18, 0x5e, 0x00, 0xc1, 0xfe, 0x51, 0x1c, 0x5b, 0x0e, 0xde, 0x05, 0xe5, + 0xef, 0xee, 0xef, 0xbe, 0x5b, 0xf2, 0xbb, 0xb6, 0x0d, 0x20, 0xef, 0xd9, 0x1a, + 0x50, 0x04, 0x32, 0xe8, 0xf6, 0x04, 0xe9, 0x12, 0xd0, 0xf7, 0x20, 0xe6, 0xd9, + 0xb7, 0xe4, 0xd6, 0xc9, 0x4a, 0x0e, 0x4f, 0xbf, 0xf1, 0x19, 0x2e, 0x5b, 0xbe, + 0xec, 0xac, 0x2a, 0x19, 0xb3, 0xef, 0x21, 0xe0, 0x1a, 0xf0, 0x33, 0x16, 0x12, + 0xe1, 0xe0, 0xeb, 0xec, 0xd2, 0xdf, 0xf3, 0xb0, 0x2e, 0x2a, 0x53, 0xef, 0xf5, + 0x1c, 0x2b, 0xbd, 0x8a, 0xea, 0x2c, 0xd0, 0x24, 0x27, 0xef, 0x1e, 0xf9, 0x81, + 0xcf, 0x00, 0x3b, 0x0d, 0xfe, 0x20, 0x23, 0xf0, 0x0e, 0x1a, 0x2b, 0x02, 0xdc, + 0x46, 0xcb, 0xf4, 0x1e, 0xfb, 0x1e, 0xdf, 0x6c, 0xd3, 0xe8, 0xfd, 0x06, 0x53, + 0x0d, 0x2f, 0x26, 0x11, 0x22, 0xc0, 0xcf, 0x7e, 0xff, 0xc4, 0xfe, 0x14, 0xf9, + 0x06, 0x35, 0xed, 0xd5, 0x3e, 0xdf, 0xf9, 0xe9, 0x0d, 0xe6, 0x36, 0xa0, 0xe2, + 0x24, 0xc9, 0x25, 0xab, 0xf7, 0xec, 0x15, 0x33, 0x98, 0xd7, 0x22, 0xb0, 0xdd, + 0x5d, 0x1f, 0xda, 0x01, 0xe5, 0x0d, 0xe7, 0xdf, 0xee, 0x9c, 0x33, 0xc4, 0xf0, + 0xfc, 0x3d, 0x1d, 0xea, 0x1b, 0x2c, 0xcf, 0x37, 0x32, 0xdc, 0xc2, 0x0c, 0xc0, + 0x53, 0x0b, 0xc8, 0xd6, 0x2f, 0xeb, 0xfc, 0xb7, 0x1e, 0x26, 0xaf, 0x25, 0x0e, + 0x2b, 0x05, 0x2f, 0x05, 0x20, 0x93, 0x0c, 0xd1, 0xa7, 0x0f, 0x6e, 0xf2, 0x01, + 0xc1, 0x32, 0xdd, 0x00, 0xea, 0xef, 0xcc, 0xc7, 0xf8, 0xec, 0xa3, 0x25, 0x0a, + 0xb6, 0xb1, 0x00, 0x26, 0xa6, 0x22, 0x34, 0x11, 0x07, 0x1b, 0xd1, 0xf1, 0xba, + 0x46, 0x08, 0xe0, 0xcf, 0x81, 0x36, 0xd9, 0x24, 0xf8, 0xff, 0x54, 0x39, 0x25, + 0xf2, 0x17, 0x3a, 0xd5, 0x15, 0xfd, 0xd8, 0x12, 0x19, 0x24, 0x08, 0x22, 0x0a, + 0x01, 0xd7, 0x24, 0xbb, 0x00, 0xbf, 0x0c, 0xcf, 0xd8, 0xde, 0x25, 0x2c, 0x68, + 0xf3, 0xf5, 0xd8, 0xab, 0x18, 0x17, 0x46, 0x0a, 0xd9, 0x31, 0xaa, 0x30, 0x68, + 0xe8, 0x08, 0xc7, 0xf2, 0x01, 0x90, 0xf7, 0xca, 0x76, 0xba, 0x53, 0xe9, 0xef, + 0x0a, 0xb3, 0x1f, 0xe9, 0x27, 0x1a, 0x7b, 0xff, 0xef, 0x3f, 0x08, 0xb2, 0x24, + 0x85, 0x03, 0xbf, 0x44, 0xdc, 0xe2, 0x00, 0xf7, 0xe7, 0x9a, 0x3d, 0xf6, 0xbc, + 0x99, 0xff, 0x1f, 0x3c, 0xca, 0x8c, 0x85, 0xef, 0x18, 0xf3, 0xfd, 0xbc, 0xcd, + 0x14, 0x3c, 0x27, 0xf8, 0x23, 0xcc, 0xfc, 0x81, 0xa6, 0x28, 0x1b, 0x48, 0xd8, + 0x16, 0xfe, 0x0b, 0x13, 0xbb, 0xdb, 0xdd, 0x04, 0xd0, 0xda, 0x05, 0xf9, 0x0f, + 0xd7, 0xfe, 0xce, 0x38, 0x33, 0x25, 0x26, 0xfb, 0x3f, 0x46, 0xe4, 0xb9, 0xe4, + 0x97, 0xb3, 0xfa, 0x15, 0x31, 0x00, 0x06, 0xa0, 0x04, 0xdf, 0xb4, 0x1e, 0x1c, + 0x0b, 0xd6, 0xcc, 0xc4, 0x10, 0xc7, 0xf6, 0xde, 0x07, 0x3e, 0x87, 0xef, 0x49, + 0x13, 0xf5, 0xfe, 0xdf, 0x29, 0x69, 0x0c, 0xf9, 0x13, 0x2d, 0x7f, 0x33, 0xdc, + 0x36, 0xfe, 0x03, 0xd7, 0x09, 0x0c, 0x2c, 0x1c, 0x2f, 0x73, 0x00, 0x25, 0xff, + 0xd5, 0x52, 0xd9, 0xe2, 0x5e, 0xa6, 0x00, 0x12, 0x12, 0x0a, 0xe5, 0x07, 0x33, + 0xbc, 0x21, 0x00, 0xf2, 0xe5, 0xf4, 0x22, 0xfd, 0x07, 0xf7, 0x33, 0xef, 0x52, + 0x14, 0xf3, 0xdd, 0xd8, 0x43, 0xf7, 0xbe, 0xf6, 0xf0, 0xd9, 0x35, 0x00, 0xe3, + 0x4b, 0xf0, 0x0f, 0xfa, 0xfe, 0x2c, 0x3e, 0xe0, 0xf7, 0xcf, 0x1e, 0xf1, 0x3b, + 0xf3, 0xd3, 0x35, 0xbd, 0x51, 0x15, 0xed, 0xdd, 0x00, 0xec, 0x24, 0x1e, 0x3f, + 0x1e, 0xdf, 0xed, 0xfb, 0x58, 0x0a, 0xf9, 0x28, 0xeb, 0xc6, 0xda, 0xd9, 0x0a, + 0x01, 0xc4, 0x1d, 0xe4, 0xfc, 0xcb, 0xc6, 0xba, 0xc7, 0xef, 0x0e, 0xca, 0x40, + 0xe5, 0x02, 0xce, 0x30, 0xcd, 0x47, 0xe3, 0x10, 0x02, 0x16, 0x07, 0xf2, 0x03, + 0xf1, 0xec, 0x0a, 0x32, 0x19, 0xf3, 0x03, 0xe0, 0x26, 0x1e, 0xc8, 0x00, 0xf4, + 0x11, 0x14, 0xd8, 0xe4, 0x0e, 0x0a, 0x27, 0x16, 0x26, 0x0b, 0x04, 0x2f, 0x12, + 0x67, 0x10, 0xce, 0xf5, 0xb7, 0xf4, 0xe1, 0xed, 0xcf, 0xed, 0xfa, 0x12, 0xf0, + 0x0b, 0xf7, 0xe9, 0x0d, 0xe7, 0x25, 0xdf, 0xe9, 0xe9, 0x3d, 0xea, 0xe6, 0x1e, + 0x20, 0xee, 0x15, 0x02, 0x2f, 0x11, 0x07, 0xb0, 0x1a, 0xce, 0xf0, 0x61, 0xae, + 0x0c, 0xe5, 0xdf, 0x06, 0x15, 0xed, 0xe2, 0x12, 0x27, 0xfe, 0x03, 0xf7, 0x0a, + 0xf8, 0x06, 0x38, 0xfe, 0xfd, 0x26, 0xfa, 0xf2, 0xf9, 0x2d, 0xea, 0xb2, 0x11, + 0xd7, 0x19, 0x7f, 0xcf, 0x17, 0x29, 0x03, 0x35, 0xfb, 0xe1, 0xd1, 0xf7, 0xdd, + 0x7c, 0xfb, 0x16, 0x31, 0x14, 0x16, 0xe4, 0xcf, 0xe4, 0xc3, 0x4e, 0x1e, 0x10, + 0xf5, 0x07, 0xe7, 0xe8, 0xf1, 0x05, 0x21, 0xe3, 0xb3, 0x18, 0x07, 0x12, 0x45, + 0x04, 0xaf, 0x0a, 0xca, 0x16, 0x7a, 0xf6, 0x09, 0x04, 0xf8, 0x09, 0x1e, 0xe9, + 0x4b, 0xbf, 0x14, 0xe9, 0x0d, 0xbc, 0x0d, 0x23, 0x01, 0xd1, 0xfe, 0x1f, 0xce, + 0x4c, 0x17, 0xc1, 0x2e, 0xdc, 0x07, 0x09, 0x5a, 0x06, 0x23, 0x03, 0x2d, 0x18, + 0x33, 0xf5, 0xfe, 0xc6, 0xbe, 0x07, 0xd4, 0x5d, 0x0a, 0x0a, 0x29, 0x28, 0xf6, + 0x53, 0x19, 0xea, 0x15, 0xcf, 0x2b, 0xe9, 0x28, 0xda, 0x96, 0xf2, 0x36, 0x7e, + 0xe7, 0xfc, 0x42, 0xe6, 0x81, 0x2a, 0x4f, 0xec, 0xe6, 0xe2, 0x1f, 0x96, 0xe2, + 0xc7, 0xe1, 0xfe, 0x19, 0xe4, 0x04, 0x29, 0xb7, 0x2c, 0x2c, 0xde, 0xa7, 0x1d, + 0x94, 0x56, 0xe2, 0x0d, 0xc1, 0xe0, 0xc5, 0x72, 0xf6, 0x20, 0x40, 0xd1, 0x7c, + 0xce, 0xb8, 0x54, 0xe4, 0x4d, 0x0c, 0xfb, 0xad, 0xf0, 0x45, 0x3f, 0x18, 0xef, + 0xf3, 0x19, 0xfe, 0x14, 0x92, 0x61, 0xf8, 0x31, 0xe5, 0x1a, 0xd4, 0x0a, 0xe8, + 0x19, 0xe9, 0xd7, 0x0e, 0x6d, 0x00, 0x0e, 0x32, 0x22, 0xc5, 0xe7, 0x07, 0x2d, + 0xfe, 0xd0, 0x5b, 0x35, 0xf5, 0xc2, 0xef, 0xd6, 0xd0, 0xca, 0xc1, 0x20, 0xcd, + 0x11, 0xce, 0xee, 0xf7, 0x7f, 0x2b, 0x39, 0x98, 0xfe, 0x1b, 0xc4, 0x28, 0xd1, + 0x1a, 0x03, 0x0c, 0xd8, 0x25, 0x11, 0xf5, 0x41, 0xfd, 0xe6, 0x20, 0x37, 0x0a, + 0x08, 0xe8, 0xbb, 0xbe, 0x96, 0xe5, 0x0b, 0x06, 0xf0, 0x14, 0x25, 0x3a, 0x61, + 0xe6, 0x63, 0x22, 0x3c, 0xe8, 0xd9, 0xf6, 0xf1, 0xa2, 0x1e, 0xf7, 0x19, 0x1d, + 0xfb, 0xbf, 0x32, 0x0f, 0xdf, 0x11, 0x37, 0x2f, 0xf2, 0x6c, 0x4a, 0xf3, 0x1d, + 0x1f, 0xa1, 0xde, 0x3a, 0x3f, 0xd4, 0xdf, 0xea, 0xd1, 0x03, 0xe3, 0xb9, 0x16, + 0x44, 0xb3, 0xd1, 0xda, 0xfc, 0x44, 0x42, 0xea, 0x27, 0x58, 0xd8, 0x08, 0xe0, + 0xea, 0x02, 0xf9, 0x25, 0x26, 0x56, 0x9a, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x04, 0x00, 0x00, 0x81, 0x60, 0xec, 0x3a, 0xec, 0xce, 0xe9, 0xca, 0x06, + 0xcc, 0xe2, 0x3f, 0xee, 0x7f, 0x81, 0x6d, 0xe5, 0xaa, 0x7f, 0x89, 0x78, 0x19, + 0xbb, 0xcc, 0x3e, 0x59, 0x17, 0x4d, 0x3b, 0xc4, 0x54, 0xf7, 0x98, 0xf1, 0xe8, + 0xc3, 0xa9, 0xcb, 0xe8, 0xf1, 0x51, 0xe5, 0x50, 0xb1, 0xcb, 0x5f, 0x3d, 0x7f, + 0x01, 0xb4, 0xab, 0xe4, 0x42, 0xf5, 0x3e, 0x7f, 0xfe, 0xad, 0x60, 0x71, 0x96, + 0x47, 0xd3, 0x08, 0xf2, 0xf9, 0x4d, 0x34, 0x60, 0x7f, 0x71, 0x7f, 0xba, 0xc9, + 0xd9, 0xac, 0x9c, 0x5c, 0x31, 0x70, 0x81, 0xfb, 0xc7, 0x21, 0x88, 0x57, 0x7f, + 0xf8, 0x99, 0xa6, 0x2f, 0xdd, 0xf5, 0x7f, 0x18, 0x0d, 0x59, 0x96, 0xb0, 0xd1, + 0xf2, 0xad, 0xc6, 0x5e, 0x84, 0xb4, 0x81, 0xd1, 0xf3, 0xae, 0x7f, 0x77, 0x0b, + 0xd7, 0xbc, 0x27, 0x04, 0xd0, 0xcf, 0xae, 0xd1, 0x5a, 0xd6, 0xfe, 0x7f, 0x1d, + 0xc8, 0x21, 0xb2, 0xfa, 0xcf, 0x04, 0xc6, 0x32, 0xf6, 0xd6, 0x10, 0xcc, 0xce, + 0x60, 0x32, 0x4b, 0x14, 0x73, 0x81, 0xd5, 0x33, 0x83, 0xeb, 0x3c, 0x85, 0xa4, + 0x7f, 0xc9, 0xdd, 0xcb, 0x7f, 0x0a, 0x52, 0xec, 0x42, 0xcc, 0x20, 0xd2, 0x81, + 0xd9, 0xe4, 0x4a, 0x7f, 0x45, 0xf5, 0x30, 0xc4, 0xff, 0x35, 0x69, 0xc2, 0xdc, + 0xc5, 0xd0, 0x4e, 0x31, 0x69, 0xd8, 0x15, 0x5f, 0x59, 0x35, 0x31, 0x13, 0xbf, + 0xf7, 0x33, 0x1c, 0xd6, 0x51, 0x7f, 0x50, 0xf7, 0x4c, 0x1e, 0xed, 0x81, 0xf5, + 0xec, 0x1e, 0x3a, 0x21, 0x9e, 0xf2, 0xf7, 0x7c, 0x36, 0xbd, 0xe8, 0xb8, 0x86, + 0xe1, 0xd9, 0x7f, 0x5e, 0x2f, 0xb0, 0xdc, 0x89, 0x15, 0xd3, 0x38, 0x81, 0xd5, + 0x8e, 0x16, 0x18, 0x2d, 0xc1, 0xf7, 0x31, 0xc5, 0x70, 0x3c, 0xf3, 0xae, 0x81, + 0xb7, 0xcf, 0xcf, 0xc3, 0x37, 0xab, 0x7f, 0x39, 0x97, 0x0b, 0xde, 0xe3, 0x81, + 0x8b, 0xb9, 0x02, 0x0b, 0xb0, 0xac, 0x4d, 0xaa, 0x01, 0x56, 0x56, 0x36, 0x74, + 0x84, 0x94, 0x7f, 0xd6, 0xd8, 0x47, 0xad, 0xbc, 0xbf, 0xe0, 0x81, 0x9e, 0x2b, + 0xf0, 0xcc, 0x42, 0xbb, 0xdc, 0x11, 0xbc, 0x83, 0xd0, 0xe5, 0xd5, 0x04, 0xd6, + 0x5b, 0x02, 0x51, 0xbe, 0x87, 0xc6, 0x31, 0x2a, 0xe5, 0xf6, 0xe8, 0x81, 0x02, + 0x7f, 0x32, 0x3d, 0xc8, 0x7f, 0xcd, 0x4c, 0x7f, 0x81, 0x25, 0x1a, 0x0d, 0x1a, + 0x6c, 0x7f, 0x22, 0x48, 0x70, 0x63, 0x58, 0x18, 0x81, 0xcf, 0xdc, 0x96, 0x7d, + 0xb0, 0x74, 0xd1, 0xdf, 0x81, 0x46, 0x3a, 0xe3, 0x52, 0x28, 0x7f, 0x81, 0xcd, + 0x56, 0xf2, 0xd9, 0xfb, 0x81, 0xd8, 0x1c, 0xad, 0xf9, 0xcc, 0x46, 0x95, 0xd2, + 0x92, 0xca, 0xe3, 0xdd, 0x6d, 0x2e, 0x3c, 0xfb, 0xd0, 0xc1, 0xde, 0x96, 0xe5, + 0x3a, 0x7f, 0x40, 0xaf, 0x6b, 0xde, 0xb4, 0xf9, 0xfb, 0xce, 0x1e, 0xee, 0xc7, + 0x03, 0x30, 0x14, 0xc5, 0xed, 0xe6, 0x81, 0x7f, 0x89, 0xee, 0xb9, 0xf9, 0xcd, + 0x1b, 0x66, 0xb9, 0x5a, 0x86, 0x34, 0x4c, 0x9f, 0xf0, 0x54, 0x23, 0x0c, 0x7f, + 0xf6, 0x7f, 0x00, 0x81, 0x5f, 0x46, 0x0a, 0x3b, 0xc5, 0x19, 0x2c, 0x12, 0x19, + 0xb4, 0x7f, 0x81, 0x81, 0x53, 0xdd, 0x29, 0x3a, 0x81, 0xf5, 0x7f, 0x1d, 0x09, + 0x0c, 0x2b, 0x2d, 0x13, 0x8f, 0xe0, 0x12, 0x04, 0xef, 0x4c, 0x7f, 0x0f, 0x04, + 0x4a, 0x35, 0xdf, 0x7f, 0xb4, 0xff, 0x85, 0x38, 0xfa, 0x40, 0x05, 0x7f, 0x32, + 0xd5, 0x7f, 0xc7, 0x12, 0x81, 0x53, 0x99, 0xc2, 0xb6, 0xd9, 0xea, 0x27, 0x20, + 0xe9, 0xf4, 0xff, 0x3c, 0x99, 0x7d, 0x62, 0x0b, 0x7f, 0x81, 0x7f, 0x34, 0xa2, + 0xd4, 0x19, 0xcf, 0xb0, 0x1f, 0x7b, 0x1e, 0xcb, 0xd7, 0x4c, 0x34, 0xc0, 0xb3, + 0xb6, 0xcf, 0x9c, 0xf8, 0xb0, 0x04, 0xd7, 0x07, 0xbf, 0x00, 0xb0, 0x4a, 0x7f, + 0x81, 0x81, 0x13, 0x11, 0xd8, 0x88, 0xba, 0x0d, 0x81, 0xe8, 0xc2, 0x2c, 0x1b, + 0x36, 0x0d, 0x24, 0x81, 0x7f, 0xbd, 0x78, 0x3c, 0x04, 0x05, 0xe0, 0x2f, 0x08, + 0x44, 0xaf, 0x57, 0x7f, 0x48, 0xe5, 0xc1, 0x03, 0x03, 0x49, 0xf9, 0xf2, 0xf4, + 0xad, 0xd8, 0x02, 0x58, 0x41, 0x81, 0xc2, 0xaa, 0x0b, 0x1b, 0x01, 0x64, 0x19, + 0xee, 0x7f, 0xf0, 0xe7, 0xd0, 0x19, 0xe5, 0x2f, 0x01, 0x25, 0x17, 0x7f, 0xf0, + 0x06, 0xdd, 0xc1, 0x1d, 0x03, 0x66, 0x39, 0x52, 0xcc, 0x4a, 0x81, 0xde, 0x35, + 0x45, 0x7f, 0x44, 0xef, 0xa4, 0x21, 0xc0, 0xe1, 0x18, 0xfd, 0x7f, 0x42, 0xf6, + 0x9e, 0x81, 0x81, 0x5c, 0x7f, 0xa9, 0x6f, 0x9e, 0x0a, 0x73, 0xe5, 0xdd, 0xd1, + 0xf1, 0x38, 0x4a, 0x1e, 0xf0, 0xb6, 0xde, 0xfc, 0xf6, 0x39, 0xe0, 0xf8, 0x5a, + 0x9e, 0x81, 0xaa, 0xb5, 0xd9, 0xe5, 0xe2, 0xe8, 0xd3, 0xa4, 0x24, 0xc7, 0xc3, + 0x7f, 0x1a, 0xdc, 0xeb, 0x2e, 0x16, 0x0a, 0x30, 0xf0, 0xf2, 0xab, 0xb8, 0x66, + 0x81, 0x95, 0x17, 0x81, 0x7f, 0xba, 0x1a, 0xe9, 0xdd, 0x09, 0x2d, 0x7f, 0x35, + 0xab, 0x04, 0x13, 0x7f, 0xc7, 0x45, 0x09, 0x7f, 0x56, 0x0c, 0x09, 0xea, 0xc4, + 0x19, 0x7f, 0x08, 0x0e, 0xcf, 0xcd, 0x33, 0x28, 0x06, 0x3c, 0xe6, 0x75, 0x08, + 0xd8, 0xf1, 0xb4, 0x2e, 0xff, 0x7f, 0x3d, 0x7f, 0x6f, 0x17, 0x0f, 0x2a, 0x09, + 0x04, 0x1c, 0x96, 0x33, 0x2c, 0x7f, 0xf6, 0x89, 0xe9, 0x09, 0x65, 0xa8, 0x2c, + 0x42, 0xe4, 0xb9, 0xd5, 0xef, 0xed, 0x81, 0x00, 0x45, 0xe5, 0x7f, 0x20, 0x13, + 0x6c, 0x4f, 0x02, 0xbd, 0x59, 0x8c, 0xbc, 0xdd, 0xe1, 0x57, 0xe5, 0x6e, 0x7f, + 0x7e, 0x27, 0x3f, 0xa7, 0x0a, 0x9f, 0x7f, 0x7f, 0x51, 0x16, 0xed, 0xba, 0x91, + 0x06, 0x69, 0xf2, 0xc3, 0x46, 0xb4, 0x81, 0xd7, 0x54, 0xa1, 0x83, 0x20, 0x3f, + 0xef, 0x58, 0x7f, 0xb7, 0x37, 0xd0, 0xf5, 0x23, 0x50, 0xa0, 0xb3, 0x85, 0x4a, + 0x1f, 0xf4, 0x89, 0x3d, 0x7f, 0x7f, 0x96, 0xdb, 0x51, 0x5f, 0xf0, 0x7f, 0xdf, + 0x64, 0x3a, 0x87, 0x7f, 0x7f, 0x25, 0x99, 0xaa, 0xdc, 0xda, 0xd2, 0x67, 0xd9, + 0xab, 0x5c, 0x82, 0xc9, 0x20, 0xe2, 0xfd, 0xdf, 0xf9, 0x09, 0xaa, 0x81, 0xf4, + 0x89, 0x7f, 0x14, 0xf2, 0x0e, 0x24, 0x6b, 0x31, 0x23, 0xd6, 0x00, 0xe2, 0x4a, + 0xac, 0x31, 0x1c, 0xfb, 0xc4, 0x98, 0xd0, 0xcc, 0x66, 0x13, 0x13, 0xcf, 0x5a, + 0x38, 0x81, 0xfc, 0x98, 0x08, 0xaa, 0xc1, 0xbe, 0x33, 0x99, 0x4a, 0xd7, 0x7f, + 0x3f, 0x09, 0x2c, 0xfc, 0xf9, 0x11, 0xcd, 0xa1, 0x30, 0x81, 0xde, 0x7d, 0x7f, + 0x7f, 0x3b, 0xcd, 0x4d, 0x1e, 0x3c, 0x39, 0x83, 0x86, 0xad, 0xb6, 0x7f, 0xd8, + 0x7f, 0x7f, 0xa5, 0xf5, 0xb6, 0xbf, 0x16, 0xfc, 0xc0, 0x18, 0x7f, 0xad, 0x97, + 0x23, 0x81, 0xf2, 0x5f, 0xe8, 0x04, 0xf9, 0x81, 0x89, 0x8c, 0xbd, 0xe9, 0xb6, + 0xd9, 0xbb, 0x3e, 0x26, 0xd2, 0xce, 0x15, 0x6d, 0xe7, 0xd7, 0x62, 0x7f, 0x50, + 0xc3, 0x3d, 0xd4, 0x54, 0xc6, 0x81, 0xe2, 0xd0, 0x8b, 0x5f, 0x92, 0xd2, 0xbc, + 0xdc, 0x93, 0x22, 0x04, 0x7f, 0xc8, 0xf2, 0xa1, 0xe6, 0x3a, 0xba, 0xb1, 0x6c, + 0x31, 0xea, 0xff, 0xfb, 0x19, 0x19, 0x23, 0xf7, 0xfc, 0xf5, 0x35, 0xd1, 0x1e, + 0x4e, 0xd9, 0x81, 0x21, 0xb7, 0xa0, 0xf6, 0xf6, 0x34, 0xfd, 0x17, 0x34, 0x1c, + 0x00, 0xbf, 0x43, 0x9b, 0x07, 0x0e, 0x0f, 0xf2, 0xda, 0xd1, 0x42, 0x2a, 0xb3, + 0x32, 0x89, 0xf3, 0x7f, 0x7f, 0xd7, 0x7f, 0xab, 0x13, 0xd5, 0xea, 0x68, 0x54, + 0xc8, 0x7f, 0x2d, 0x4a, 0xde, 0x14, 0x7f, 0xbe, 0x84, 0xe3, 0x0f, 0xba, 0xee, + 0xff, 0xc0, 0x1f, 0x81, 0x29, 0x88, 0xc1, 0x64, 0x31, 0xd8, 0xdc, 0x20, 0x9d, + 0x70, 0x14, 0xf3, 0x49, 0xee, 0xf1, 0xe0, 0xb5, 0xa0, 0xf3, 0x94, 0x4c, 0xb0, + 0x1c, 0xf8, 0x3c, 0xed, 0x1e, 0x4e, 0xb8, 0x99, 0xfa, 0x4e, 0x16, 0x18, 0x6a, + 0x08, 0x57, 0xa6, 0x4b, 0xe4, 0x94, 0x9e, 0x7f, 0x31, 0xb9, 0x50, 0xab, 0x11, + 0x3a, 0xd5, 0x18, 0x81, 0xf0, 0x50, 0xbf, 0x46, 0xda, 0xae, 0x3e, 0x7f, 0x11, + 0x02, 0x26, 0x07, 0x2a, 0xa6, 0xb6, 0x7f, 0xc1, 0x7f, 0xb6, 0x4f, 0x7f, 0xbe, + 0x05, 0xd6, 0x35, 0x01, 0x2f, 0x9f, 0x68, 0x49, 0x7f, 0x1e, 0x75, 0x3c, 0xb7, + 0x6f, 0xac, 0xfd, 0x07, 0x48, 0x15, 0x05, 0x6d, 0x15, 0xd5, 0x3d, 0x00, 0xf3, + 0xa4, 0x10, 0xf9, 0xa1, 0xdf, 0x6d, 0xaf, 0x03, 0xa9, 0x37, 0x7f, 0xbb, 0x91, + 0x75, 0x5e, 0xc1, 0x7f, 0x3c, 0x07, 0xb5, 0xd2, 0x34, 0xda, 0xe3, 0xf1, 0xe2, + 0x9e, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x12, 0xd3, + 0xfd, 0xe4, 0x0c, 0x1f, 0x00, 0x20, 0xd0, 0xd2, 0xbf, 0x02, 0x26, 0x05, 0x27, + 0xdf, 0x04, 0x17, 0x3b, 0xf9, 0xde, 0xdc, 0x14, 0x32, 0xce, 0xc8, 0x26, 0x11, + 0x0d, 0xd0, 0xda, 0xfd, 0x0e, 0x33, 0x3c, 0x29, 0xdf, 0xe9, 0xea, 0x03, 0xc2, + 0xe8, 0x1c, 0xca, 0xdb, 0x7f, 0xbb, 0xeb, 0xcb, 0x29, 0x16, 0x1d, 0xbb, 0x1b, + 0xeb, 0xf4, 0x05, 0xf2, 0x23, 0xff, 0xc1, 0x1b, 0xdf, 0x58, 0x03, 0x22, 0xa7, + 0xdf, 0x2e, 0x06, 0x90, 0x1d, 0xf7, 0x04, 0x06, 0x28, 0x2c, 0x21, 0xff, 0xf1, + 0x12, 0x9f, 0x06, 0x2a, 0xce, 0xd6, 0xdd, 0x0e, 0xf2, 0x1e, 0x05, 0xfd, 0x38, + 0xdd, 0x38, 0xff, 0x43, 0xfb, 0xc4, 0x1e, 0x2f, 0xee, 0x53, 0xcb, 0xdd, 0xf8, + 0xf4, 0x47, 0xbb, 0x16, 0x3e, 0xc4, 0xf8, 0x0f, 0xeb, 0xfa, 0x0a, 0x36, 0xcf, + 0xe7, 0xe5, 0x0a, 0x0e, 0xe4, 0x9a, 0x14, 0xcc, 0x01, 0xf5, 0x07, 0xd5, 0xba, + 0xe2, 0xef, 0xfc, 0xc5, 0xe4, 0x17, 0x25, 0xed, 0x11, 0xf8, 0xf3, 0xd7, 0xdf, + 0xe7, 0xef, 0x42, 0xed, 0xcc, 0xd0, 0x05, 0xb8, 0xf1, 0xdc, 0x23, 0x63, 0x2e, + 0x16, 0xf0, 0x02, 0xd5, 0x23, 0xfc, 0x43, 0xf9, 0xe4, 0x31, 0xce, 0x0d, 0xdd, + 0x36, 0xed, 0x02, 0xcf, 0xd1, 0xc6, 0x0b, 0x29, 0x7f, 0x33, 0xda, 0x3c, 0xbc, + 0xed, 0xed, 0x18, 0xb3, 0xfc, 0x11, 0x19, 0x55, 0x0f, 0x16, 0xbd, 0x2c, 0xec, + 0x25, 0xf0, 0xe4, 0x08, 0x35, 0x38, 0x05, 0x2a, 0xd1, 0xdc, 0xd9, 0x0c, 0xe2, + 0xda, 0xee, 0x24, 0xd1, 0x01, 0x02, 0x2e, 0xd1, 0x0f, 0x35, 0xcf, 0xd4, 0xe6, + 0x13, 0x19, 0xff, 0x36, 0x02, 0x0f, 0xe5, 0x14, 0xe4, 0xf6, 0xee, 0xed, 0xdd, + 0xd4, 0xcd, 0xc3, 0xff, 0xfb, 0x49, 0xe4, 0xe2, 0xc9, 0xf7, 0xb6, 0xf0, 0xed, + 0x0d, 0x23, 0xf8, 0xdd, 0xff, 0xd8, 0xcf, 0x03, 0x0a, 0x16, 0xdc, 0xf3, 0x0c, + 0x27, 0xfa, 0x00, 0x0d, 0x24, 0x0a, 0xea, 0x2d, 0x11, 0x1c, 0x06, 0xef, 0x75, + 0xfb, 0x0e, 0x10, 0xf0, 0x29, 0xc6, 0xff, 0xe1, 0xfb, 0xf0, 0xeb, 0xee, 0x0c, + 0x35, 0x31, 0x4e, 0x3b, 0x16, 0x09, 0xb2, 0x05, 0x31, 0x28, 0xba, 0x33, 0xd9, + 0x18, 0x3a, 0xb7, 0xf0, 0xe5, 0x17, 0xd8, 0x0d, 0x2f, 0xf8, 0xdc, 0xbc, 0xdd, + 0xf4, 0x3c, 0x20, 0xf4, 0x12, 0x11, 0x1d, 0x3f, 0xee, 0x0d, 0x16, 0x17, 0xaf, + 0xfd, 0xd8, 0xdd, 0x16, 0xf8, 0x1c, 0xc0, 0xff, 0xe7, 0xfa, 0xef, 0x18, 0x03, + 0x0a, 0xdd, 0xfe, 0x18, 0x19, 0xed, 0xec, 0x7f, 0xf2, 0x06, 0xf4, 0x30, 0x04, + 0x10, 0x0a, 0xfb, 0x15, 0xd6, 0x25, 0xd2, 0xe2, 0x02, 0xd8, 0x16, 0x1b, 0x47, + 0x1a, 0x0b, 0xe9, 0xc9, 0x27, 0xd1, 0xc7, 0xfc, 0x06, 0x04, 0x25, 0xd7, 0xe8, + 0xfa, 0x17, 0x07, 0x4d, 0xe8, 0x1d, 0xe3, 0x20, 0xfb, 0xc4, 0xd4, 0xbe, 0x81, + 0xd0, 0xf0, 0x03, 0x0a, 0x0b, 0x5b, 0x00, 0x3c, 0x31, 0x43, 0x3c, 0xfa, 0x23, + 0xcf, 0x2b, 0xdf, 0x3e, 0x5a, 0xed, 0x05, 0xab, 0x5f, 0xcb, 0x05, 0xfb, 0x0b, + 0xd5, 0xed, 0xe9, 0xca, 0x18, 0x2e, 0x39, 0x49, 0xca, 0x0f, 0x44, 0xf4, 0x9c, + 0xa9, 0x14, 0xef, 0xd3, 0x04, 0xed, 0xd0, 0x13, 0xe4, 0x05, 0x2d, 0xb2, 0x11, + 0xff, 0xcb, 0x06, 0xd4, 0x15, 0xad, 0x19, 0x43, 0x0b, 0xf9, 0xec, 0xd8, 0x1f, + 0xcf, 0xd7, 0x03, 0xe3, 0x11, 0x29, 0x1a, 0x24, 0x00, 0x1a, 0xdc, 0x2b, 0x1d, + 0x48, 0xfb, 0xdb, 0xe4, 0xe9, 0xb8, 0x0b, 0x2c, 0x2a, 0x1a, 0xc4, 0x12, 0xc2, + 0xbf, 0xeb, 0xdb, 0x17, 0x7c, 0xfa, 0xe6, 0xfe, 0xe5, 0x0a, 0xdc, 0x11, 0x49, + 0xe3, 0x08, 0x21, 0xf3, 0x39, 0xe7, 0x50, 0x44, 0x03, 0x11, 0xf9, 0x51, 0xfc, + 0xff, 0x2b, 0x2c, 0x12, 0xf5, 0xde, 0x15, 0x12, 0xa7, 0x18, 0xea, 0x12, 0xba, + 0xf2, 0x01, 0xe1, 0x0e, 0x2c, 0xf3, 0xff, 0x10, 0xbd, 0xcc, 0x34, 0xf0, 0x0c, + 0x0b, 0xf3, 0x1b, 0xf9, 0xf9, 0xbf, 0x7f, 0xf0, 0x06, 0x58, 0x4b, 0xcb, 0xf7, + 0x0d, 0xa3, 0x0e, 0x06, 0xe1, 0x17, 0x0d, 0xe4, 0x1d, 0x46, 0x0f, 0xd5, 0xdf, + 0x27, 0xfc, 0x2e, 0xec, 0x30, 0x09, 0xf2, 0x10, 0xc6, 0xd9, 0x00, 0xde, 0x68, + 0x3e, 0x73, 0xea, 0x12, 0xf9, 0xc5, 0xdf, 0x3c, 0x4c, 0x42, 0xe1, 0x08, 0x22, + 0x1f, 0x11, 0x10, 0xcc, 0x22, 0x18, 0x02, 0x51, 0x11, 0x03, 0xee, 0xd6, 0xf1, + 0x31, 0x02, 0xd8, 0x10, 0x0e, 0xf5, 0xd5, 0x3f, 0x0e, 0xea, 0xbf, 0x1d, 0x26, + 0x3a, 0x36, 0x0e, 0x2d, 0x10, 0xf8, 0x4c, 0x5a, 0x2c, 0x16, 0x52, 0xe4, 0x1a, + 0x29, 0xf7, 0x96, 0xcc, 0x38, 0xf2, 0xe3, 0x13, 0x4f, 0x13, 0xc0, 0xfb, 0x14, + 0xe9, 0xf3, 0x01, 0x00, 0x25, 0xce, 0xe7, 0xd4, 0xde, 0xe0, 0xe0, 0x10, 0xd0, + 0x04, 0xfe, 0xce, 0x10, 0xd6, 0xf3, 0x18, 0xaa, 0x07, 0xe4, 0x38, 0x15, 0xe0, + 0xd6, 0xb8, 0xf3, 0x12, 0xc6, 0xf6, 0x3b, 0xfe, 0x6f, 0xfe, 0xe3, 0x13, 0xdd, + 0xcd, 0xf8, 0x12, 0x42, 0x15, 0xf2, 0x4f, 0x04, 0x14, 0xc7, 0xf5, 0xc8, 0xd8, + 0xec, 0xe4, 0x0b, 0xfa, 0xe2, 0x21, 0x1e, 0xdd, 0x3b, 0xd7, 0xf8, 0xe8, 0x44, + 0xc2, 0x10, 0xb0, 0xc8, 0x01, 0xfc, 0x1c, 0xf0, 0xec, 0x00, 0xd2, 0x1f, 0xeb, + 0xe0, 0x07, 0xeb, 0x2d, 0x4c, 0x33, 0x2a, 0x21, 0x99, 0xea, 0x17, 0xe9, 0x2c, + 0xe2, 0xee, 0x11, 0xd3, 0x3a, 0x11, 0x25, 0xd7, 0x89, 0x25, 0x33, 0x43, 0x0e, + 0x24, 0x21, 0x0b, 0xe5, 0x0f, 0x20, 0x0e, 0xc8, 0x39, 0xaa, 0xd8, 0x21, 0x81, + 0xca, 0xed, 0x22, 0x46, 0xf5, 0x0e, 0x20, 0x06, 0xf1, 0x10, 0xce, 0xec, 0xe8, + 0xd8, 0x34, 0x01, 0x13, 0x03, 0x19, 0x18, 0x29, 0xde, 0xbc, 0x0f, 0x3c, 0xcc, + 0xf8, 0x7f, 0xf4, 0xd2, 0x63, 0x00, 0xf0, 0x27, 0xfc, 0xd4, 0xe6, 0x03, 0x32, + 0xf7, 0x4b, 0xc4, 0x0e, 0xdc, 0x0a, 0x05, 0xb4, 0xec, 0xe2, 0xce, 0x04, 0xe4, + 0x0a, 0xb6, 0x1b, 0x12, 0xea, 0x40, 0x0f, 0x56, 0x0a, 0xe5, 0x00, 0x30, 0x25, + 0x04, 0x34, 0x0a, 0xe7, 0xf3, 0xed, 0x07, 0x1d, 0x19, 0x18, 0xf4, 0x11, 0xe6, + 0x01, 0xe4, 0x3e, 0x44, 0xd8, 0xc3, 0x89, 0x05, 0xdb, 0xd0, 0x13, 0x1a, 0xe1, + 0xd0, 0xdf, 0x30, 0x21, 0xd5, 0xf5, 0xcf, 0x24, 0xea, 0xe7, 0x07, 0xd5, 0x15, + 0xfc, 0x18, 0x70, 0xea, 0x27, 0xf8, 0x12, 0x18, 0xe9, 0xb6, 0xeb, 0xeb, 0xdb, + 0x1d, 0xe0, 0x05, 0xc1, 0xef, 0xdc, 0xc3, 0x2c, 0x1d, 0x37, 0xeb, 0xf4, 0x6f, + 0xd8, 0xe9, 0x20, 0xf5, 0xff, 0x15, 0xbd, 0x2a, 0x0f, 0x02, 0xee, 0x02, 0x1a, + 0x4b, 0xeb, 0xd3, 0x03, 0xd0, 0xf0, 0xf3, 0x1b, 0xf3, 0x29, 0x10, 0x06, 0x72, + 0xf6, 0xfa, 0xec, 0xec, 0x30, 0xed, 0xff, 0x3e, 0xdb, 0x1b, 0x17, 0x32, 0xa2, + 0xee, 0x03, 0xe8, 0x7f, 0x1b, 0xdf, 0x5d, 0xea, 0xa0, 0x20, 0x2d, 0x15, 0x0e, + 0xdb, 0x0f, 0xf9, 0x0d, 0x1b, 0xe0, 0x55, 0xce, 0xd9, 0xc2, 0xa5, 0xb6, 0xfa, + 0xf0, 0xbb, 0xe6, 0xea, 0x5c, 0x31, 0x76, 0xa8, 0xc6, 0xd1, 0x47, 0xfa, 0x21, + 0xdd, 0x10, 0x0d, 0x35, 0xd2, 0xfe, 0xe4, 0xe4, 0xf4, 0xcc, 0x3d, 0x67, 0x0a, + 0x12, 0x4c, 0x2b, 0xfa, 0xc8, 0x58, 0xe9, 0x2e, 0xfe, 0x2b, 0xc7, 0x09, 0x5f, + 0x35, 0x34, 0x21, 0x14, 0xe7, 0x3e, 0x19, 0x00, 0x15, 0x6b, 0x21, 0x0c, 0xf8, + 0x5a, 0x27, 0x78, 0x0b, 0x45, 0xf8, 0x21, 0xe1, 0x2e, 0x2d, 0xd5, 0x19, 0xf8, + 0xcf, 0x5e, 0xfd, 0xe1, 0x36, 0x20, 0xcd, 0xef, 0xfa, 0x2a, 0xcf, 0x5d, 0x2a, + 0xda, 0xe5, 0xe1, 0xf5, 0xd9, 0xe1, 0xb5, 0x0e, 0x03, 0xb5, 0xe5, 0xea, 0xbb, + 0xeb, 0x06, 0xf9, 0xe7, 0x16, 0x0d, 0xfe, 0xbe, 0x23, 0xd5, 0x14, 0x1d, 0xf7, + 0xd5, 0xdf, 0xef, 0xec, 0xd4, 0x2d, 0xda, 0xce, 0x3c, 0x98, 0x24, 0x02, 0xfe, + 0xac, 0xd4, 0x53, 0x26, 0xcf, 0xfa, 0xd0, 0xeb, 0x5c, 0xcb, 0x19, 0xd2, 0x21, + 0xde, 0x18, 0x4f, 0xfd, 0x35, 0x16, 0xd7, 0x1e, 0x13, 0x92, 0x1d, 0x1f, 0x00, + 0x54, 0x24, 0x37, 0xf0, 0xd1, 0xe3, 0xba, 0xd5, 0x21, 0xd9, 0xf6, 0xfd, 0xb7, + 0x08, 0xb4, 0xd5, 0x43, 0xe3, 0x1e, 0x05, 0x56, 0xc5, 0x56, 0xd8, 0x3e, 0xef, + 0xe2, 0x08, 0xd4, 0xc5, 0xed, 0x13, 0x2e, 0x25, 0xd1, 0x20, 0xd4, 0xe0, 0xfd, + 0xfb, 0x81, 0xe7, 0xf0, 0xb2, 0xde, 0x00, 0xe5, 0xef, 0xec, 0xd1, 0x08, 0xee, + 0xed, 0xe1, 0x4e, 0xd2, 0xd2, 0xee, 0x25, 0x25, 0x39, 0x8f, 0x05, 0xfa, 0x52, + 0x0f, 0x27, 0x01, 0x07, 0x06, 0xc8, 0x81, 0x11, 0x2d, 0x17, 0xc3, 0xe2, 0x00, + 0x34, 0x6e, 0xf5, 0xe3, 0x36, 0x19, 0x2b, 0xed, 0xe9, 0xc5, 0x61, 0xdb, 0x16, + 0xe3, 0xfe, 0xfe, 0x0f, 0x5c, 0xe7, 0xd4, 0xe0, 0xdb, 0xe9, 0x3a, 0x04, 0xed, + 0xbe, 0xb6, 0x28, 0x25, 0x1a, 0x3e, 0x27, 0xb7, 0xc7, 0x11, 0xb2, 0x1d, 0xbc, + 0x1f, 0x5a, 0x03, 0xa7, 0xeb, 0x4c, 0x47, 0x38, 0x55, 0xf8, 0x0e, 0xff, 0xf8, + 0xc5, 0x19, 0xca, 0xe0, 0x34, 0xed, 0x20, 0x17, 0xc5, 0xc7, 0x09, 0x18, 0xd3, + 0x95, 0xdc, 0xb3, 0x0f, 0xf7, 0xf8, 0x78, 0xc3, 0x29, 0xeb, 0x16, 0xf0, 0x16, + 0x09, 0xf9, 0xe2, 0xdf, 0xe9, 0xa4, 0x15, 0x39, 0x25, 0xf1, 0xe6, 0xf6, 0x1a, + 0xc1, 0x12, 0xd6, 0xd0, 0x0c, 0xfa, 0x00, 0xe6, 0xe5, 0xd6, 0xb9, 0x29, 0x64, + 0x07, 0x10, 0xc9, 0x0c, 0x17, 0xfc, 0xf9, 0x3a, 0xe4, 0xc1, 0x15, 0xdb, 0x01, + 0xcd, 0x4f, 0xc8, 0xbf, 0xda, 0x2a, 0x28, 0x0c, 0x14, 0x0a, 0xbb, 0x15, 0xda, + 0xe8, 0x23, 0xfa, 0x36, 0xf4, 0xe7, 0xd1, 0xe1, 0x27, 0x05, 0x5e, 0x1c, 0x39, + 0x49, 0xf4, 0x0d, 0x12, 0x09, 0x37, 0xcc, 0xc2, 0xcc, 0xff, 0x5e, 0xce, 0xd1, + 0x32, 0x19, 0xf7, 0x02, 0xde, 0x27, 0x0d, 0xcb, 0xf9, 0xf1, 0x16, 0x0d, 0xf9, + 0x16, 0xfe, 0x7f, 0xf7, 0x0b, 0x7a, 0xc7, 0xdf, 0xbd, 0x01, 0x0e, 0x07, 0xe6, + 0xe7, 0x3d, 0x10, 0x04, 0xd3, 0xf7, 0x08, 0xd8, 0x29, 0x76, 0xca, 0xea, 0xf9, + 0x0a, 0x0a, 0x33, 0xe9, 0x15, 0x40, 0xce, 0xd7, 0x28, 0x12, 0xfe, 0xd8, 0xba, + 0xe6, 0x05, 0x3f, 0x43, 0x13, 0xce, 0xf3, 0x2a, 0x30, 0x23, 0x70, 0x1c, 0x11, + 0xca, 0xf1, 0x08, 0x21, 0x1b, 0x05, 0x9f, 0xcc, 0xe4, 0x24, 0xf9, 0x0e, 0x15, + 0x04, 0xfa, 0x0d, 0x17, 0x17, 0x26, 0xe5, 0xf9, 0xbd, 0xea, 0xf8, 0xe2, 0x10, + 0xe1, 0xf4, 0x39, 0xfd, 0x05, 0x0c, 0x10, 0x11, 0xd2, 0x27, 0xf2, 0xf3, 0x01, + 0x21, 0x0c, 0xdd, 0x24, 0x09, 0xf2, 0xf4, 0x02, 0x3f, 0x51, 0xfd, 0x1f, 0xfc, + 0x0f, 0xf3, 0x28, 0xf0, 0xfc, 0xd4, 0xcb, 0xee, 0x50, 0xd6, 0xff, 0x31, 0x22, + 0x06, 0x2a, 0xd5, 0x2b, 0x02, 0xee, 0xd3, 0x0f, 0xf7, 0x0c, 0xef, 0x7f, 0xdb, + 0x36, 0xec, 0xcf, 0x0e, 0xf0, 0x1a, 0xf5, 0x41, 0x2f, 0x10, 0xdd, 0x13, 0xe5, + 0xf5, 0x06, 0x2a, 0x02, 0x13, 0x00, 0x1a, 0x10, 0xea, 0x05, 0x13, 0x12, 0x15, + 0x08, 0x1e, 0x07, 0x2d, 0x5e, 0x2c, 0x14, 0x09, 0x4c, 0xe5, 0x31, 0xf1, 0xff, + 0x24, 0x33, 0xb9, 0x08, 0xfb, 0x03, 0x28, 0xf0, 0x08, 0x4f, 0xde, 0x18, 0xe2, + 0xea, 0x19, 0xf1, 0xfc, 0x33, 0x36, 0x2a, 0x04, 0xf8, 0x21, 0x3f, 0xd7, 0x0d, + 0xdf, 0xf4, 0x26, 0xe0, 0xfc, 0xf9, 0xe4, 0xff, 0x07, 0x00, 0xe1, 0x12, 0xfe, + 0x55, 0xd4, 0x51, 0x10, 0x1a, 0x4b, 0x0c, 0x26, 0xf9, 0xfe, 0x28, 0x05, 0x20, + 0xfe, 0x0e, 0xb8, 0xc2, 0x18, 0xe5, 0x19, 0x3a, 0xce, 0xf7, 0x06, 0x06, 0xb3, + 0xea, 0xfc, 0xf6, 0xf1, 0xe9, 0xfa, 0xf4, 0xe7, 0xd7, 0x1b, 0x10, 0xd9, 0x28, + 0xc7, 0xfe, 0xfa, 0x20, 0x23, 0x03, 0x0c, 0xfc, 0xdc, 0xf2, 0xe0, 0xf0, 0xf0, + 0x15, 0x3e, 0xb7, 0xd5, 0x04, 0xf6, 0x7f, 0x14, 0xdb, 0xef, 0x56, 0xe2, 0x07, + 0x29, 0x06, 0x0d, 0xe7, 0x13, 0x43, 0xef, 0xee, 0xf6, 0x26, 0xec, 0xfb, 0xdf, + 0xb5, 0x08, 0x1c, 0xde, 0x07, 0x37, 0xe0, 0xa4, 0x1a, 0x17, 0xe7, 0x20, 0xdf, + 0xce, 0x07, 0x1e, 0x4a, 0x00, 0xf9, 0x0e, 0xb7, 0x1d, 0xf5, 0xe8, 0xd7, 0x3e, + 0xc0, 0xd6, 0xf7, 0x01, 0x25, 0x0d, 0xec, 0x05, 0x13, 0x0d, 0xf4, 0xa2, 0x14, + 0x26, 0xe8, 0x22, 0xcd, 0x15, 0x1d, 0xe2, 0xf1, 0x3e, 0xf5, 0x05, 0xfa, 0xc4, + 0x11, 0x30, 0x32, 0xd7, 0xd4, 0x04, 0x12, 0x0d, 0x48, 0xe3, 0xa7, 0x07, 0xf0, + 0x87, 0x7a, 0xe9, 0x60, 0x5b, 0x00, 0xcb, 0xd4, 0xb6, 0x9d, 0x4a, 0x51, 0xf4, + 0xd5, 0xc5, 0xe2, 0x7f, 0xf6, 0x33, 0xc8, 0x6b, 0x06, 0x37, 0xdc, 0xdf, 0x26, + 0x0a, 0x50, 0x00, 0x1c, 0x3f, 0xc1, 0x0d, 0x33, 0xd7, 0x1f, 0x90, 0xf9, 0xf3, + 0xe7, 0x15, 0xac, 0xe6, 0x11, 0x12, 0xfe, 0x26, 0x22, 0x22, 0x63, 0xf8, 0xa5, + 0x4d, 0xeb, 0xc5, 0x54, 0x34, 0xc2, 0xec, 0x33, 0x33, 0x65, 0x0d, 0x3a, 0x4e, + 0x1a, 0x05, 0xcf, 0x11, 0x1c, 0xbf, 0x46, 0x6a, 0xe1, 0xfc, 0x34, 0x89, 0x42, + 0x2a, 0xea, 0xc4, 0xdb, 0xcc, 0x40, 0xe7, 0xf7, 0xf2, 0x92, 0xdc, 0x0d, 0x55, + 0x0e, 0x0a, 0xfc, 0x14, 0x06, 0xf5, 0x1a, 0xb6, 0x0e, 0xd1, 0x53, 0xdb, 0x36, + 0x12, 0x16, 0x08, 0xd4, 0x16, 0x0f, 0x33, 0xef, 0xc4, 0x4b, 0xb1, 0x1e, 0xf6, + 0xe5, 0x47, 0x0a, 0xfe, 0xc4, 0xfd, 0x04, 0x35, 0xfc, 0x15, 0x2b, 0xe2, 0x23, + 0x0c, 0x2a, 0x17, 0x7f, 0xc5, 0xe2, 0xb6, 0xb3, 0x23, 0xf3, 0xd0, 0xac, 0xe5, + 0xd0, 0xc5, 0xf7, 0xe2, 0xf4, 0x06, 0x1b, 0x0d, 0x1e, 0xe8, 0x10, 0x0b, 0xe8, + 0x1d, 0xe3, 0xdd, 0xc0, 0xe2, 0x15, 0xc7, 0x3f, 0xe9, 0xf5, 0xca, 0x0b, 0xf1, + 0x5e, 0x4c, 0x6e, 0xf3, 0xce, 0xde, 0xf9, 0xec, 0x33, 0xe8, 0xf3, 0x13, 0xe1, + 0x1a, 0xf5, 0x08, 0xf3, 0x1b, 0x3c, 0x1e, 0xf0, 0xd7, 0x18, 0xfe, 0x2e, 0x24, + 0xff, 0x08, 0x3f, 0xa6, 0x36, 0x31, 0xe0, 0x12, 0x0d, 0xd1, 0x49, 0xeb, 0x6e, + 0xdb, 0x3e, 0xea, 0x08, 0xe0, 0xc0, 0x19, 0xd8, 0x04, 0xcc, 0xd9, 0x02, 0xff, + 0x0d, 0x31, 0x00, 0xcb, 0x0e, 0xed, 0x57, 0x1d, 0xe0, 0xdb, 0x6a, 0xf0, 0xf3, + 0xee, 0xbd, 0xc2, 0x27, 0x06, 0xe4, 0xf0, 0x15, 0xcb, 0x09, 0xdf, 0x10, 0xe4, + 0xdf, 0xbb, 0xe2, 0x1b, 0x1b, 0x19, 0x14, 0xb6, 0x1a, 0x95, 0x50, 0xdf, 0x32, + 0xfd, 0xd6, 0x20, 0x1e, 0x00, 0x20, 0x14, 0x3f, 0x3d, 0x38, 0x09, 0x10, 0x31, + 0x28, 0x0f, 0xeb, 0xfb, 0xda, 0xd2, 0x0c, 0xe7, 0x31, 0xe8, 0x0f, 0x1e, 0xdb, + 0x30, 0x27, 0xa2, 0x00, 0x03, 0xfe, 0x01, 0x08, 0xe7, 0x89, 0xdd, 0x9b, 0x7f, + 0x0b, 0x01, 0xf1, 0xea, 0xf5, 0xdc, 0xae, 0xf5, 0x28, 0x02, 0x42, 0xfb, 0x53, + 0xea, 0x25, 0x13, 0x18, 0xfc, 0x19, 0x10, 0x3a, 0xe5, 0x04, 0xe5, 0xf4, 0x0b, + 0xf8, 0xfa, 0xff, 0x29, 0x3e, 0x0b, 0x15, 0x00, 0x26, 0xfb, 0x2f, 0x08, 0x2c, + 0xc9, 0x12, 0xda, 0xe2, 0x1f, 0xe1, 0x2c, 0x4f, 0x69, 0x13, 0x07, 0xcb, 0xd6, + 0xe6, 0x1c, 0xf7, 0x15, 0x04, 0x19, 0xd8, 0x06, 0x24, 0x03, 0x04, 0x0b, 0xe3, + 0xf8, 0x1b, 0xce, 0xeb, 0x01, 0x05, 0xf9, 0x05, 0xff, 0xdd, 0xe9, 0x16, 0x1f, + 0x0b, 0x0f, 0xed, 0xd8, 0x32, 0x27, 0xda, 0xe4, 0x2a, 0xfb, 0xd1, 0xed, 0x07, + 0xd9, 0xfd, 0x13, 0xe9, 0x11, 0x0d, 0xd3, 0xf9, 0x11, 0xf8, 0xfa, 0xc4, 0xe6, + 0xe5, 0x0c, 0xd8, 0xed, 0x10, 0xcf, 0xf9, 0xd9, 0x50, 0x0b, 0x18, 0xf8, 0xe2, + 0xf5, 0xe9, 0xee, 0xea, 0xe3, 0x10, 0x2f, 0xd5, 0xf4, 0xe5, 0xdf, 0xd3, 0xde, + 0x22, 0x09, 0xf2, 0x02, 0xe1, 0xfc, 0xf2, 0xe3, 0xb7, 0x25, 0x05, 0x22, 0xd0, + 0x1d, 0x10, 0x39, 0xf4, 0xf8, 0xd2, 0x09, 0x20, 0x7f, 0xe8, 0x1a, 0x13, 0x0c, + 0x11, 0xf6, 0x10, 0xe9, 0xf0, 0x17, 0x33, 0xd2, 0xf7, 0xde, 0x0a, 0xe3, 0xd6, + 0xf8, 0x12, 0x00, 0xb4, 0x05, 0xe0, 0x00, 0x1a, 0xef, 0xdc, 0xd0, 0x11, 0xe0, + 0x41, 0xdf, 0x06, 0x13, 0x15, 0x1e, 0xe8, 0xc2, 0xc0, 0xe7, 0x16, 0x19, 0xed, + 0x50, 0xd5, 0xe2, 0x04, 0xcb, 0x17, 0x04, 0x0c, 0xa6, 0xa6, 0x06, 0xee, 0x33, + 0x1a, 0x44, 0x30, 0x12, 0xda, 0x39, 0x15, 0x9a, 0xea, 0x22, 0x1a, 0xc8, 0x21, + 0xd2, 0xcb, 0x37, 0xcb, 0x04, 0xe6, 0x48, 0x03, 0x28, 0x13, 0x0a, 0xf4, 0xdd, + 0xea, 0xd8, 0xed, 0x99, 0xfa, 0xb7, 0xce, 0xec, 0x26, 0xfb, 0x2e, 0x23, 0x3e, + 0xfa, 0x9e, 0xb7, 0xc7, 0x3d, 0x36, 0xdc, 0xf3, 0x32, 0x33, 0xe3, 0xf3, 0xe4, + 0xfd, 0x0e, 0xef, 0xef, 0xc8, 0xe1, 0xeb, 0x52, 0x11, 0xd7, 0xf2, 0xd3, 0x30, + 0xec, 0x53, 0xe4, 0xe8, 0x7f, 0x01, 0xf3, 0x28, 0xdb, 0x45, 0x2c, 0xf7, 0x33, + 0x0b, 0x20, 0x00, 0x5d, 0xf6, 0x25, 0xd4, 0x04, 0xf7, 0x1b, 0x1a, 0x03, 0x14, + 0xb8, 0x10, 0xdd, 0xe9, 0x31, 0x3c, 0xd5, 0x01, 0xfb, 0xfd, 0xd2, 0xd7, 0x37, + 0xdf, 0x0a, 0x40, 0x1f, 0xe5, 0xd8, 0xd7, 0x9f, 0xcd, 0xe6, 0x1f, 0x02, 0xf9, + 0xe2, 0x7b, 0x2f, 0x2f, 0x22, 0x03, 0xf1, 0xfc, 0x19, 0xd5, 0x41, 0x03, 0x4d, + 0xf7, 0xd1, 0x19, 0x30, 0x04, 0xae, 0x25, 0x59, 0x7f, 0xc4, 0x09, 0x28, 0x31, + 0x0b, 0x24, 0xb8, 0x6e, 0xbd, 0xe7, 0x33, 0xd4, 0xfa, 0xda, 0x1e, 0xe3, 0xe6, + 0x2a, 0xb5, 0x2d, 0x1f, 0xf8, 0xbc, 0x48, 0x09, 0x2e, 0xfe, 0x4a, 0x24, 0x13, + 0xd1, 0xde, 0x52, 0xb8, 0x34, 0x9f, 0x12, 0xd2, 0xd5, 0xf5, 0xd6, 0x03, 0x14, + 0x1f, 0x11, 0x15, 0x47, 0x71, 0x13, 0x02, 0xde, 0xdc, 0xd9, 0x01, 0x64, 0x51, + 0x04, 0xb0, 0x1d, 0x22, 0x03, 0xc7, 0xbc, 0x24, 0xc1, 0xca, 0x0d, 0x04, 0x41, + 0x1c, 0x3b, 0xcc, 0x11, 0xdd, 0x0b, 0xe8, 0x34, 0x30, 0xf9, 0xf1, 0x30, 0xba, + 0xde, 0x94, 0x07, 0x4a, 0x30, 0x4d, 0x20, 0x13, 0x04, 0xf5, 0xda, 0xf1, 0xe4, + 0xfe, 0x24, 0x43, 0xf2, 0xfc, 0x0a, 0xd3, 0x1b, 0x14, 0x0f, 0xd6, 0xf4, 0xfa, + 0xf4, 0x15, 0xed, 0x41, 0x37, 0xdc, 0xe3, 0xe6, 0xe9, 0x0d, 0xff, 0x11, 0xcc, + 0x1b, 0x66, 0x44, 0x9e, 0x27, 0x1a, 0x33, 0xf7, 0x18, 0xc2, 0xdf, 0xea, 0x28, + 0x0f, 0xf5, 0x02, 0x06, 0x1c, 0xe7, 0x09, 0xf2, 0x35, 0xf1, 0x05, 0x1d, 0x9d, + 0x3a, 0x03, 0x1c, 0x41, 0xd4, 0xfb, 0x56, 0x12, 0x1d, 0x15, 0xf6, 0x09, 0x0e, + 0xe4, 0xee, 0x05, 0x0c, 0xb3, 0xee, 0xc9, 0xea, 0xe2, 0x41, 0xe0, 0xdb, 0x19, + 0x35, 0xf7, 0x6b, 0x2f, 0xdf, 0xc2, 0xff, 0x03, 0xeb, 0xf2, 0x3e, 0x19, 0xcf, + 0x32, 0xfa, 0xb8, 0x2f, 0x04, 0x25, 0xca, 0x1f, 0x09, 0x68, 0x3e, 0x13, 0x07, + 0xdc, 0x07, 0x01, 0xe4, 0x1b, 0x7f, 0x38, 0xf5, 0xff, 0xf8, 0xe0, 0xf3, 0x05, + 0x04, 0xdb, 0xdf, 0x33, 0x31, 0x1d, 0xf6, 0x1e, 0xe2, 0x0b, 0x10, 0xf9, 0x0a, + 0x0d, 0xaf, 0xdb, 0xe6, 0xde, 0x10, 0x04, 0x11, 0xb5, 0xd3, 0x37, 0xd0, 0xe7, + 0x0f, 0x16, 0xd5, 0xd1, 0x13, 0xd0, 0x1e, 0x18, 0x3b, 0xda, 0x01, 0x35, 0x1c, + 0xe7, 0xba, 0xfd, 0xe3, 0x2d, 0x8e, 0x18, 0x3c, 0xf1, 0x05, 0x29, 0x05, 0x30, + 0xa6, 0xd5, 0x09, 0xf0, 0x7f, 0xe2, 0xe0, 0xdf, 0xe6, 0xd6, 0xef, 0x0d, 0xb9, + 0x16, 0x3f, 0x06, 0x0c, 0x2a, 0xdf, 0x2f, 0x16, 0xeb, 0xe8, 0xbf, 0x6e, 0xf2, + 0xe8, 0xc9, 0x7c, 0x30, 0xf4, 0xdd, 0xef, 0xeb, 0xd2, 0xbb, 0x1e, 0x01, 0x01, + 0x3c, 0xdf, 0xe1, 0xff, 0xc1, 0x28, 0xde, 0x07, 0x2b, 0x0a, 0x14, 0xb9, 0x13, + 0xcc, 0x23, 0xfe, 0x57, 0xfb, 0xbb, 0xed, 0x05, 0x20, 0x36, 0xc1, 0x52, 0xf7, + 0xb6, 0x59, 0x0e, 0xf0, 0xe8, 0xe1, 0xf9, 0xee, 0xf6, 0x30, 0x07, 0x0a, 0x52, + 0x3d, 0xf4, 0xe8, 0xe0, 0x06, 0xdb, 0xe8, 0x0a, 0x45, 0x18, 0x2d, 0xd2, 0xb4, + 0xef, 0xc7, 0xb6, 0xe9, 0xc8, 0x5f, 0x0d, 0xc9, 0x05, 0xef, 0x4a, 0xd9, 0xb1, + 0x32, 0x0d, 0x44, 0x18, 0x90, 0x0a, 0x1f, 0xf4, 0xe8, 0xf2, 0x86, 0xec, 0x66, + 0x19, 0x1e, 0x04, 0x6f, 0xb0, 0xda, 0x1f, 0x07, 0x00, 0xde, 0x41, 0xc9, 0xeb, + 0x41, 0xeb, 0x14, 0xa1, 0x0a, 0xec, 0xb1, 0x62, 0xae, 0x0d, 0x9b, 0xd7, 0x14, + 0xeb, 0x0e, 0x13, 0xff, 0x47, 0xcc, 0xfc, 0x49, 0xca, 0x58, 0xc2, 0x26, 0xb8, + 0x1d, 0x45, 0xa7, 0xec, 0xe5, 0x33, 0x0f, 0x01, 0xc7, 0x06, 0xca, 0xf3, 0xd3, + 0x2a, 0xfc, 0xda, 0x0c, 0x05, 0xc4, 0x03, 0xda, 0x44, 0xd1, 0xed, 0xd8, 0x2a, + 0x0f, 0x2e, 0x19, 0xf1, 0x06, 0x2f, 0xee, 0xcd, 0xe9, 0xda, 0x30, 0x03, 0x19, + 0x04, 0x62, 0xf6, 0x19, 0xdc, 0xe5, 0x61, 0xb4, 0xef, 0xf6, 0x81, 0xa6, 0xdb, + 0x59, 0xdf, 0xf1, 0x00, 0xdb, 0x08, 0xf0, 0x2c, 0xc7, 0xef, 0xc0, 0xe0, 0xe5, + 0x0a, 0x01, 0x2b, 0x2d, 0x09, 0xff, 0x82, 0xf4, 0xe0, 0xf0, 0xd0, 0xd2, 0x59, + 0x7d, 0x20, 0xc5, 0x34, 0xa9, 0x3f, 0x4b, 0xd5, 0x02, 0xe3, 0x1a, 0xf0, 0xbb, + 0xe6, 0xd9, 0xe7, 0xfa, 0x0f, 0x35, 0xef, 0xd7, 0xdb, 0x06, 0x40, 0xf0, 0xa9, + 0xff, 0xf0, 0x22, 0x37, 0xfe, 0xe7, 0x25, 0xa3, 0x34, 0xd4, 0x2d, 0xdf, 0x14, + 0x90, 0x29, 0x2a, 0x1c, 0xc5, 0x3f, 0xd3, 0xdc, 0x06, 0x0c, 0xb6, 0x7f, 0x69, + 0x52, 0x10, 0xca, 0x10, 0x27, 0xc2, 0xc1, 0xdc, 0xc1, 0x02, 0xe8, 0x21, 0xff, + 0xf6, 0x15, 0x17, 0xf7, 0xcb, 0x1f, 0x14, 0xa2, 0xe3, 0xcc, 0x5a, 0x0e, 0x46, + 0x10, 0xcd, 0x00, 0x12, 0xd5, 0x0e, 0xf4, 0xc9, 0x28, 0xc3, 0xb8, 0xf0, 0x01, + 0xb4, 0xf4, 0x1d, 0x8a, 0x33, 0x1a, 0xde, 0xdb, 0x37, 0x11, 0xf1, 0x1a, 0x14, + 0xfd, 0x4f, 0xd4, 0xc2, 0x09, 0xed, 0x3a, 0xf8, 0xb3, 0xc3, 0xec, 0x34, 0x05, + 0xe0, 0x35, 0x11, 0xd6, 0x08, 0xe8, 0xc4, 0x2b, 0x22, 0xf6, 0xf8, 0x02, 0x24, + 0x19, 0x46, 0xde, 0xaf, 0x34, 0xff, 0x04, 0xe7, 0x11, 0x16, 0xe5, 0xbd, 0xe5, + 0x1a, 0x1a, 0xf9, 0xe1, 0x16, 0x16, 0x5d, 0xf1, 0xbe, 0x32, 0xd7, 0x05, 0x01, + 0xd5, 0xee, 0xd2, 0x39, 0xd2, 0x1a, 0xe3, 0xea, 0x57, 0x6a, 0x31, 0xa5, 0xe4, + 0xc9, 0xf8, 0x05, 0xa4, 0xc8, 0x25, 0xde, 0xaf, 0x13, 0x7f, 0x16, 0xb7, 0xb2, + 0xfa, 0x32, 0xe2, 0x4e, 0x11, 0xa5, 0x3b, 0x06, 0xee, 0x42, 0xd8, 0x3a, 0xfd, + 0xc6, 0x1f, 0x50, 0x11, 0xf8, 0x30, 0xf6, 0xeb, 0xfd, 0xf4, 0xfa, 0xf7, 0x38, + 0x0b, 0x3a, 0x34, 0x47, 0xf8, 0x25, 0xfc, 0xe4, 0x19, 0x35, 0x2e, 0xd2, 0xcb, + 0xd5, 0xe8, 0x24, 0xcb, 0x05, 0x21, 0x12, 0xf2, 0xfb, 0x1e, 0x34, 0xed, 0xfe, + 0xf6, 0x39, 0xde, 0x27, 0x0a, 0x28, 0x1a, 0x21, 0x0b, 0x11, 0x00, 0xf5, 0xf7, + 0x02, 0x35, 0x0f, 0xe0, 0x1f, 0xe5, 0xd9, 0x70, 0x2e, 0x08, 0xd6, 0x3a, 0x1f, + 0xda, 0x0f, 0x0a, 0xf0, 0xdb, 0xe3, 0x01, 0xe6, 0xe2, 0xdb, 0xec, 0xf5, 0xf6, + 0x0a, 0x8e, 0xd8, 0xf7, 0xb1, 0xef, 0x26, 0x0a, 0x1a, 0x19, 0xc2, 0x09, 0xe1, + 0xe4, 0x44, 0xdc, 0x35, 0x19, 0x16, 0xea, 0xb9, 0x27, 0x05, 0x24, 0x25, 0xda, + 0xfa, 0xe7, 0x0e, 0x0c, 0xfc, 0x42, 0xa9, 0xd8, 0x1c, 0x23, 0x4a, 0x4c, 0xf8, + 0x40, 0x11, 0xf4, 0x26, 0xf2, 0xeb, 0xca, 0x0b, 0xe7, 0xfc, 0x2a, 0xd2, 0x08, + 0xd0, 0xf5, 0xb8, 0xf9, 0x61, 0x0e, 0xf6, 0xdc, 0xe4, 0xdb, 0xd5, 0xfd, 0xb2, + 0x07, 0x0f, 0xc0, 0x81, 0x00, 0x22, 0xfe, 0xdb, 0x0c, 0xc6, 0xff, 0x15, 0x20, + 0xfa, 0xbc, 0xd2, 0xc6, 0xb9, 0xf6, 0xf2, 0xfa, 0x19, 0x28, 0xef, 0x32, 0xe3, + 0xec, 0x28, 0x1a, 0x59, 0xc9, 0xf8, 0x08, 0xc6, 0x20, 0xf3, 0x22, 0xcd, 0xbe, + 0x20, 0x29, 0xd4, 0x0f, 0x30, 0x36, 0xc2, 0x1f, 0x0e, 0xdc, 0x4f, 0xf9, 0x03, + 0xd6, 0x1c, 0x42, 0xed, 0xee, 0x15, 0x24, 0x33, 0xe7, 0x61, 0x05, 0xc8, 0x0d, + 0x3c, 0xc8, 0x00, 0xdd, 0xe1, 0x15, 0x4e, 0x22, 0xfe, 0x2d, 0x04, 0x00, 0x44, + 0xc3, 0xee, 0x17, 0xf8, 0x36, 0xee, 0x2c, 0x3c, 0xec, 0x7f, 0x04, 0x18, 0xc6, + 0xc3, 0x1f, 0xd6, 0x1f, 0xcb, 0xfe, 0x26, 0xeb, 0x09, 0x4a, 0x33, 0x15, 0x41, + 0x27, 0x05, 0x18, 0x5d, 0x06, 0xf7, 0xf9, 0x04, 0xd5, 0xf3, 0xff, 0x2d, 0xea, + 0xd7, 0x5c, 0x1c, 0xcb, 0x1c, 0x1d, 0x0d, 0xd6, 0x42, 0x15, 0x6f, 0x6f, 0x27, + 0xdf, 0x02, 0x1b, 0x03, 0x21, 0x2d, 0x43, 0x0a, 0x14, 0xf5, 0xe8, 0xef, 0x49, + 0x10, 0x1e, 0x1e, 0xf6, 0x52, 0x33, 0xfe, 0x21, 0x23, 0xd3, 0xed, 0xd6, 0x15, + 0xed, 0xdb, 0x27, 0x02, 0xb8, 0x30, 0x2c, 0xf7, 0xe4, 0xf4, 0x35, 0xc2, 0xbf, + 0xd7, 0xdd, 0xf9, 0x42, 0xfe, 0xd7, 0x20, 0xd8, 0x7f, 0xf7, 0xc2, 0x2b, 0x28, + 0xee, 0x00, 0xce, 0x09, 0xe3, 0x23, 0x23, 0xc9, 0x13, 0xf7, 0x14, 0xe7, 0xd4, + 0xf8, 0xf3, 0x22, 0xf3, 0xf4, 0x07, 0xa1, 0xf4, 0xbb, 0x03, 0xb3, 0x29, 0x17, + 0x20, 0xff, 0xe8, 0x05, 0x56, 0x72, 0x2a, 0x3b, 0x3c, 0xf6, 0x03, 0x27, 0xb6, + 0xf5, 0x15, 0xdc, 0x7f, 0x56, 0x0c, 0xd7, 0xed, 0x76, 0xb2, 0x15, 0x49, 0xf5, + 0x03, 0xde, 0xd6, 0x09, 0xc6, 0xe2, 0x28, 0x32, 0xe1, 0x29, 0x53, 0xfe, 0x34, + 0xf8, 0xe5, 0x05, 0x29, 0x09, 0xed, 0x51, 0x0a, 0x33, 0xf6, 0xf1, 0xfa, 0x0c, + 0xf4, 0x24, 0xad, 0x42, 0xe0, 0xa7, 0xfc, 0xc9, 0xad, 0x04, 0xeb, 0x31, 0x22, + 0xdd, 0x14, 0xf7, 0x0b, 0x9e, 0x0d, 0xd2, 0xee, 0xdd, 0xfb, 0x03, 0xca, 0x0a, + 0x0c, 0xdf, 0xd8, 0x16, 0xf3, 0xcb, 0x5a, 0x38, 0xe7, 0xd9, 0xee, 0xd6, 0x01, + 0x0c, 0xc4, 0x5d, 0xfd, 0xe7, 0xee, 0x0a, 0xf7, 0x25, 0x5d, 0x0b, 0xd9, 0x10, + 0xda, 0xd4, 0xfb, 0xc3, 0x06, 0x2f, 0x1f, 0x20, 0xe1, 0x09, 0xf6, 0x19, 0x0a, + 0x2c, 0xda, 0xa2, 0xec, 0xda, 0x21, 0x0f, 0x25, 0xc3, 0xf3, 0xeb, 0x40, 0xe5, + 0x01, 0xe9, 0x04, 0xf8, 0x05, 0xcf, 0xe4, 0x51, 0x35, 0x0c, 0xea, 0xe3, 0xc0, + 0xdc, 0xd6, 0xec, 0x64, 0x38, 0x7f, 0xd3, 0x5f, 0xde, 0x08, 0xe7, 0x2e, 0xfe, + 0xec, 0xd5, 0xeb, 0x33, 0xe0, 0xcf, 0x19, 0xde, 0x36, 0xf4, 0xe8, 0x19, 0xdb, + 0xee, 0xf3, 0xf4, 0x27, 0x22, 0x12, 0xf4, 0xd8, 0xe3, 0xd0, 0xe2, 0x14, 0x3e, + 0xfa, 0xed, 0xeb, 0x03, 0xfb, 0x49, 0x0a, 0x31, 0xec, 0x22, 0xe4, 0x8e, 0xf7, + 0xed, 0xd5, 0xf2, 0x09, 0xe0, 0x0f, 0xea, 0xa8, 0xec, 0x3a, 0x11, 0xd7, 0xc9, + 0x14, 0x93, 0x17, 0xff, 0x01, 0xeb, 0x0e, 0x02, 0xe8, 0x6a, 0xe1, 0x3d, 0x3a, + 0xb7, 0xd2, 0xdd, 0x18, 0x3f, 0xf2, 0x4a, 0xc6, 0x08, 0x7f, 0x56, 0xe5, 0xe5, + 0x36, 0xe7, 0xee, 0xe4, 0xa1, 0x95, 0xb0, 0x47, 0x04, 0x19, 0xfd, 0xdd, 0x28, + 0xd6, 0x4a, 0xd1, 0x04, 0xcf, 0xbd, 0xf1, 0x9b, 0xfc, 0xe5, 0x2a, 0x2c, 0x29, + 0xfc, 0xcd, 0x2a, 0xb3, 0x0a, 0xe9, 0x0f, 0x94, 0x6d, 0x20, 0x2b, 0xff, 0xc3, + 0xe9, 0x12, 0xb3, 0xa6, 0x5a, 0xbf, 0xfb, 0x14, 0x36, 0x2a, 0x05, 0x3b, 0x51, + 0x0f, 0xf9, 0xc7, 0xdd, 0xdb, 0x30, 0x9d, 0xbc, 0x2f, 0x07, 0x0b, 0x28, 0x1a, + 0xb4, 0xbd, 0x1c, 0x0a, 0x5c, 0x32, 0xe0, 0xee, 0x1a, 0x15, 0x22, 0x13, 0x03, + 0x1d, 0xfb, 0x02, 0x6c, 0xcb, 0x01, 0x62, 0xc2, 0x1f, 0x4d, 0x19, 0x3d, 0x31, + 0xf5, 0x04, 0xee, 0xf9, 0x45, 0x38, 0x05, 0x08, 0xe9, 0xdd, 0x2a, 0xe4, 0xc3, + 0xfc, 0x13, 0x02, 0xe5, 0x30, 0xf0, 0x12, 0xe9, 0x4a, 0xda, 0x21, 0x29, 0x30, + 0x2e, 0xc0, 0x36, 0x05, 0xe0, 0xaa, 0xda, 0x10, 0xd2, 0x32, 0xeb, 0xf3, 0xf0, + 0x7f, 0x22, 0x36, 0x08, 0xec, 0x9b, 0xb6, 0xdb, 0xe1, 0xfe, 0x07, 0xd7, 0xf2, + 0xb3, 0x0e, 0x1e, 0xec, 0x25, 0x32, 0x1d, 0x2d, 0x11, 0x1e, 0xe1, 0x69, 0x35, + 0x23, 0x51, 0x00, 0xf1, 0x64, 0xfd, 0xba, 0x51, 0xdb, 0xfb, 0xcb, 0xfa, 0x4f, + 0x01, 0x22, 0x37, 0x3c, 0x2d, 0x47, 0xc9, 0xe4, 0x0e, 0x0a, 0xc2, 0x6b, 0xa4, + 0x01, 0xbd, 0xe4, 0xd4, 0xde, 0x60, 0x0e, 0x00, 0xc6, 0x39, 0x06, 0xed, 0xf3, + 0xcf, 0xfb, 0x3a, 0xf4, 0xdd, 0xf4, 0xd5, 0x22, 0x2f, 0x10, 0x57, 0x25, 0x09, + 0xdc, 0x37, 0xb7, 0x09, 0xf5, 0x18, 0xfe, 0x28, 0x27, 0x10, 0x49, 0x18, 0xde, + 0x08, 0xd3, 0x1b, 0x1d, 0xee, 0xc6, 0x55, 0xde, 0xd0, 0xf1, 0xff, 0xeb, 0x18, + 0x79, 0xfd, 0xbf, 0xf3, 0x05, 0x09, 0x1e, 0x24, 0xec, 0xc7, 0xe5, 0xfe, 0x0c, + 0x25, 0x3a, 0x7f, 0xf9, 0x0a, 0xd2, 0x3a, 0xc1, 0x01, 0x50, 0x05, 0xe9, 0x37, + 0x20, 0xfc, 0xe7, 0x1b, 0xf8, 0xeb, 0xdc, 0x13, 0xec, 0x1e, 0x0f, 0xef, 0x29, + 0xe7, 0xbf, 0x03, 0xda, 0x02, 0xdf, 0xea, 0x10, 0xe9, 0xfa, 0x77, 0xed, 0x47, + 0xe2, 0x1d, 0x1d, 0x0c, 0x66, 0xe4, 0xca, 0xc0, 0x1d, 0x6f, 0xfa, 0xeb, 0x0f, + 0xb3, 0xfb, 0xec, 0xff, 0x04, 0xd4, 0xe1, 0x08, 0x34, 0xc3, 0xe3, 0xe2, 0x03, + 0xde, 0x0c, 0xeb, 0xfb, 0x1a, 0x12, 0xe6, 0xdc, 0x19, 0x31, 0xfe, 0xe0, 0x16, + 0x4d, 0x32, 0x51, 0xe7, 0xdf, 0x13, 0xcf, 0x41, 0xf9, 0x4b, 0x28, 0xf9, 0xea, + 0xe9, 0xbd, 0x15, 0xcc, 0x28, 0x18, 0xef, 0xba, 0xdf, 0x26, 0x2c, 0x1b, 0xde, + 0x09, 0xeb, 0xe9, 0x0d, 0xb4, 0x6e, 0xcc, 0x43, 0x1a, 0x2b, 0xf1, 0xf9, 0x3c, + 0xe5, 0x30, 0x28, 0x05, 0xd8, 0x3e, 0x45, 0x17, 0xe2, 0xde, 0x1f, 0x2e, 0x30, + 0x34, 0xcc, 0xb2, 0xda, 0xd8, 0xf7, 0xe0, 0x0f, 0xf4, 0x94, 0x03, 0xc4, 0xcf, + 0x46, 0x3f, 0x18, 0xd8, 0x7f, 0x29, 0x0a, 0xa1, 0x27, 0x48, 0xfa, 0xe3, 0xf4, + 0xbe, 0xcf, 0x29, 0x0a, 0xf5, 0xf7, 0x39, 0x00, 0xc7, 0x47, 0x08, 0xeb, 0xa8, + 0xb7, 0xc6, 0x07, 0xf2, 0xf3, 0x37, 0x53, 0x4b, 0x0c, 0x19, 0xc4, 0xff, 0xe3, + 0x2a, 0x18, 0x17, 0x12, 0x9a, 0x25, 0x06, 0x21, 0x3e, 0xd0, 0xb5, 0x11, 0x0d, + 0x0b, 0x8e, 0x51, 0xdc, 0xed, 0x9f, 0x13, 0xa6, 0x25, 0x23, 0x07, 0xf5, 0xcc, + 0xf9, 0xf0, 0x76, 0x08, 0xd0, 0xe5, 0x0d, 0xf0, 0xf2, 0xd7, 0xeb, 0x74, 0xe0, + 0x29, 0xd7, 0xdb, 0xcb, 0xc1, 0x2a, 0xb6, 0x12, 0xd7, 0x17, 0x2e, 0x3a, 0x38, + 0xd9, 0x34, 0xe3, 0x11, 0x19, 0x03, 0x05, 0x1f, 0xd5, 0xe4, 0x4a, 0x24, 0xdf, + 0x16, 0xf2, 0x21, 0x08, 0xcd, 0x2c, 0xdb, 0x21, 0xbd, 0x3a, 0xf7, 0xf9, 0xba, + 0xfb, 0x8a, 0x88, 0x23, 0xd3, 0xc6, 0xcd, 0x34, 0xd8, 0x0c, 0xed, 0xc3, 0xee, + 0x1b, 0xbe, 0xf2, 0x40, 0xe0, 0xc3, 0x03, 0x1b, 0xe9, 0x36, 0x02, 0xf1, 0xf5, + 0xb3, 0x31, 0x2f, 0xf7, 0xdf, 0xf4, 0x6c, 0x0d, 0x81, 0xf8, 0x15, 0x0e, 0x10, + 0xf7, 0x45, 0xc4, 0xdf, 0xb6, 0xdf, 0x34, 0x02, 0xe5, 0xff, 0xfd, 0xfe, 0x19, + 0xfa, 0x15, 0xe7, 0x27, 0xfb, 0x6d, 0xcd, 0xea, 0xa7, 0x07, 0x85, 0x37, 0x07, + 0xd7, 0xf5, 0x07, 0xf5, 0xee, 0xc8, 0x37, 0xd1, 0xd7, 0x03, 0xe5, 0xe8, 0x11, + 0xf7, 0x3c, 0xe4, 0x29, 0x40, 0x20, 0xd6, 0x07, 0xaf, 0x35, 0xb7, 0xe6, 0xeb, + 0x2e, 0x2d, 0x0b, 0xfd, 0xf2, 0xeb, 0xe8, 0xf0, 0x4d, 0xf8, 0x28, 0xf8, 0xf1, + 0xf2, 0x0e, 0xd8, 0x18, 0xf7, 0xe9, 0x0b, 0xdb, 0x29, 0xf7, 0xed, 0xfb, 0x0e, + 0x5b, 0x10, 0xd6, 0x45, 0xf3, 0xae, 0xd6, 0xdc, 0x3a, 0x3c, 0xbc, 0xed, 0xb7, + 0xed, 0x1e, 0xe7, 0xe6, 0x05, 0x1a, 0x04, 0x20, 0xe4, 0xdd, 0xd8, 0xfb, 0x00, + 0xe1, 0xfb, 0xe4, 0xdc, 0x04, 0xc3, 0xf6, 0x37, 0x14, 0x02, 0x26, 0xe7, 0xe3, + 0xe8, 0xbd, 0xea, 0x23, 0xbe, 0x0e, 0xe6, 0x3f, 0x1c, 0x3a, 0x74, 0xcf, 0x38, + 0xc2, 0xf6, 0xc2, 0x12, 0x41, 0xfd, 0x35, 0x45, 0x35, 0xf8, 0x20, 0x0c, 0x07, + 0xad, 0xfa, 0x10, 0x0b, 0xd3, 0xf3, 0xd4, 0xdd, 0xf4, 0x03, 0x0b, 0xd7, 0x2a, + 0x3a, 0x07, 0x26, 0x14, 0xd9, 0xb3, 0x01, 0xdf, 0xdb, 0xf3, 0xdf, 0xd6, 0xfa, + 0x3e, 0xb8, 0xea, 0x37, 0xe8, 0x03, 0x1e, 0xe0, 0x0c, 0x3e, 0xf9, 0xca, 0xbe, + 0x7f, 0xfe, 0x4a, 0x17, 0x3d, 0x01, 0xcc, 0xf9, 0x4e, 0xdb, 0xd6, 0xd5, 0xdc, + 0xd2, 0xfe, 0x2b, 0x03, 0xdb, 0xd9, 0x40, 0xf2, 0xf3, 0x2a, 0xb8, 0x0e, 0xff, + 0xc0, 0x02, 0xad, 0xed, 0xf2, 0xed, 0x25, 0xf8, 0x8f, 0xec, 0xfa, 0x20, 0xe6, + 0xf0, 0x0b, 0xcd, 0x3d, 0x03, 0x11, 0x15, 0x18, 0x09, 0x0a, 0x46, 0x14, 0xff, + 0xfd, 0xb1, 0x1f, 0x30, 0xf7, 0x1d, 0xf5, 0x04, 0x23, 0x2c, 0xf6, 0x33, 0x4b, + 0xc1, 0x0a, 0x33, 0xb6, 0xc2, 0x1c, 0xac, 0x04, 0x45, 0xee, 0xfc, 0xa2, 0x16, + 0xfc, 0x00, 0x16, 0xee, 0x16, 0xf3, 0x26, 0xcc, 0x05, 0xea, 0xca, 0x34, 0xba, + 0x0f, 0x2e, 0x16, 0xd9, 0xcc, 0x06, 0x0c, 0x06, 0x29, 0x30, 0x14, 0xfb, 0xe3, + 0xfc, 0xfe, 0x37, 0x52, 0xdd, 0xfd, 0xea, 0xc2, 0x1e, 0xdf, 0x2a, 0x3b, 0x0d, + 0xf2, 0xed, 0x1c, 0xf2, 0x81, 0xd9, 0xe8, 0x25, 0x78, 0x2e, 0x20, 0xe8, 0xa8, + 0x12, 0x29, 0x26, 0xf8, 0x3c, 0xfb, 0x3f, 0x14, 0x75, 0xfd, 0xb5, 0x06, 0x65, + 0x92, 0xe5, 0x44, 0x0a, 0xc7, 0xba, 0x28, 0xff, 0xde, 0x0c, 0x20, 0x35, 0xd1, + 0x21, 0x1a, 0x69, 0x33, 0x50, 0x1d, 0x27, 0xda, 0x8d, 0x1c, 0xea, 0x31, 0x12, + 0x57, 0x11, 0x1f, 0xfc, 0xa4, 0xfd, 0xe3, 0xea, 0x09, 0xef, 0xce, 0x27, 0x09, + 0x4a, 0xe7, 0xea, 0x0c, 0xcc, 0xef, 0x3c, 0x56, 0xee, 0xfa, 0x3b, 0x1b, 0xdb, + 0x23, 0xec, 0x23, 0xb4, 0xc9, 0xdd, 0xfd, 0x56, 0xe1, 0x44, 0xbd, 0xb8, 0x3f, + 0xc5, 0xc6, 0xef, 0xe1, 0x1e, 0xea, 0xe7, 0xd4, 0x0d, 0x3b, 0x5d, 0x73, 0x29, + 0x0b, 0xdd, 0xfb, 0xf0, 0x53, 0xc7, 0xb3, 0x21, 0x3d, 0x81, 0xb6, 0x11, 0xbb, + 0xb9, 0x0d, 0x14, 0x6a, 0x65, 0xfe, 0x9e, 0x0d, 0x2a, 0x45, 0x9d, 0x29, 0x31, + 0x04, 0xe5, 0xf5, 0x37, 0x40, 0x25, 0xca, 0xfc, 0x57, 0x1f, 0xde, 0x37, 0x50, + 0x33, 0x1b, 0x04, 0xfd, 0x14, 0xef, 0x37, 0x34, 0x3f, 0xf3, 0xd3, 0xc3, 0xa8, + 0xf4, 0x1d, 0xd7, 0x91, 0x2d, 0xe1, 0x02, 0xb9, 0xf9, 0xb9, 0xcb, 0x2b, 0xd3, + 0x04, 0xe0, 0x34, 0x17, 0xec, 0x0a, 0xda, 0xe3, 0x14, 0xd4, 0x25, 0x24, 0x97, + 0xfe, 0xe4, 0x0e, 0x35, 0xe9, 0xb5, 0xdd, 0x1b, 0x2b, 0x24, 0xc0, 0xdf, 0x0a, + 0xd6, 0xf6, 0xf3, 0x12, 0xe0, 0xe8, 0xf8, 0xdb, 0xdf, 0x26, 0xdd, 0xaf, 0x1b, + 0xf4, 0x0c, 0x15, 0x54, 0x0c, 0x06, 0xea, 0x11, 0xe1, 0x3b, 0xbc, 0xc0, 0x3a, + 0xf7, 0xb6, 0x1b, 0xc9, 0xea, 0x6c, 0xd3, 0xe4, 0x06, 0xcc, 0xfd, 0x5e, 0x11, + 0x3d, 0xfb, 0xea, 0x08, 0xd5, 0xad, 0xe3, 0x31, 0xd5, 0xd4, 0x17, 0x02, 0x09, + 0x24, 0xcb, 0x04, 0xed, 0x10, 0xf5, 0x06, 0xcf, 0xe1, 0x17, 0x17, 0xc2, 0x23, + 0xeb, 0x17, 0x1e, 0xff, 0x81, 0xd6, 0xe5, 0xea, 0xea, 0xf2, 0x05, 0x11, 0xe5, + 0xd5, 0xe8, 0x6d, 0x14, 0x15, 0x12, 0xdd, 0x99, 0x55, 0x96, 0xb2, 0xfc, 0xe4, + 0xb3, 0xba, 0x22, 0xee, 0x0b, 0xe3, 0x32, 0xfb, 0xe0, 0x20, 0xfb, 0x09, 0x39, + 0xde, 0xe6, 0xe0, 0x09, 0xc3, 0xf6, 0x25, 0x18, 0x01, 0x20, 0x38, 0x30, 0x0a, + 0x16, 0xeb, 0x29, 0xdc, 0x18, 0x09, 0xf2, 0x7e, 0xed, 0x5e, 0xcb, 0x1c, 0xf9, + 0xec, 0x21, 0x2b, 0x20, 0xe9, 0x38, 0x42, 0x04, 0x06, 0x21, 0xb6, 0xf7, 0x15, + 0xda, 0xd7, 0xd8, 0x53, 0xb7, 0x00, 0xc8, 0xef, 0x28, 0x56, 0x10, 0x13, 0x14, + 0x14, 0xe2, 0x28, 0xc1, 0x50, 0xb7, 0x28, 0x42, 0xd5, 0x48, 0xf2, 0x2a, 0xef, + 0x0c, 0xeb, 0x00, 0xfd, 0xeb, 0xe0, 0x54, 0x4a, 0xdb, 0xcc, 0x0b, 0x22, 0x35, + 0x16, 0x18, 0xf5, 0x01, 0xfa, 0x7f, 0xfb, 0xa9, 0x44, 0x2c, 0x1e, 0xff, 0x30, + 0xb6, 0x2c, 0x92, 0x22, 0xcb, 0x64, 0xf0, 0x64, 0x11, 0x29, 0x0a, 0xdb, 0xfe, + 0x0f, 0xdc, 0xf0, 0x70, 0xcf, 0x1e, 0x0d, 0x00, 0x2c, 0xe3, 0x15, 0x1e, 0xc0, + 0xd1, 0x6c, 0xed, 0x14, 0x36, 0xcb, 0xc0, 0xe2, 0x14, 0xc7, 0x26, 0x0d, 0x10, + 0xc6, 0x0d, 0xab, 0x19, 0xfa, 0xf4, 0x0b, 0x01, 0xeb, 0x40, 0x1d, 0xee, 0x0b, + 0xeb, 0x76, 0xeb, 0xd8, 0xe7, 0x03, 0x2f, 0xca, 0x11, 0xf1, 0x08, 0xec, 0xc8, + 0x07, 0xf5, 0xdc, 0x05, 0xfd, 0x61, 0x43, 0xcf, 0xe9, 0xa4, 0x0e, 0x4c, 0xe7, + 0xe5, 0x59, 0xc0, 0xe0, 0xd0, 0xd9, 0xdc, 0xd9, 0xee, 0x23, 0xd0, 0x01, 0xed, + 0x14, 0xa4, 0xd9, 0x02, 0x0c, 0x4c, 0x47, 0x4b, 0x33, 0x23, 0x2a, 0x25, 0xd1, + 0x17, 0x16, 0xf3, 0x10, 0x04, 0x09, 0xde, 0x17, 0x0e, 0xff, 0x60, 0x11, 0xf2, + 0xd7, 0x07, 0x05, 0xe4, 0xe1, 0x15, 0x7f, 0x2c, 0x06, 0xe6, 0x22, 0xdb, 0x17, + 0x11, 0x03, 0x33, 0x2c, 0xbc, 0x15, 0xfe, 0xcc, 0x21, 0x23, 0x08, 0xd9, 0xf7, + 0xfd, 0xc3, 0x10, 0x27, 0xf2, 0x37, 0x4c, 0xd0, 0xec, 0x12, 0xeb, 0x55, 0x07, + 0xcd, 0xf6, 0x07, 0x3f, 0xe8, 0x09, 0xe6, 0x36, 0xf3, 0xe5, 0x19, 0x12, 0x18, + 0xdc, 0xd7, 0xc6, 0xe5, 0xc5, 0x2e, 0xc8, 0x14, 0x07, 0xc8, 0x01, 0x04, 0x7f, + 0x03, 0x47, 0x2a, 0xc2, 0xaf, 0x6a, 0x1b, 0xe9, 0xe3, 0x00, 0xfb, 0xe3, 0x08, + 0x29, 0x3f, 0xf7, 0xe4, 0x27, 0x9b, 0x2c, 0xa4, 0xb5, 0xe3, 0xc9, 0xc3, 0xd2, + 0x10, 0xe6, 0x7f, 0x87, 0x0e, 0xde, 0xf3, 0xd9, 0xde, 0xb7, 0xd7, 0xed, 0x41, + 0xc8, 0x1a, 0xdf, 0xae, 0xe8, 0xbb, 0x11, 0xd0, 0xfa, 0xe9, 0x71, 0xe3, 0x2d, + 0xa5, 0x35, 0xf4, 0xed, 0xf1, 0xea, 0x13, 0x31, 0x3b, 0x08, 0x33, 0x39, 0x27, + 0x18, 0xb6, 0xcb, 0xc3, 0x18, 0xfc, 0x1d, 0x0a, 0x27, 0xa2, 0x1e, 0xa5, 0xdb, + 0xfb, 0xcf, 0xda, 0xa7, 0xd2, 0xa3, 0xe5, 0xf6, 0xf6, 0xdd, 0xfb, 0x10, 0x05, + 0xf0, 0x44, 0xe1, 0xb1, 0x1c, 0xec, 0xe0, 0x16, 0x05, 0xdb, 0x68, 0xc9, 0x0a, + 0xf2, 0xf2, 0x1f, 0x21, 0x3c, 0xd0, 0xca, 0xe9, 0x2a, 0xd8, 0xe1, 0x76, 0xb3, + 0x61, 0xef, 0xd0, 0xf2, 0x2d, 0xf8, 0x4a, 0xfd, 0xf1, 0x01, 0xba, 0xfd, 0x02, + 0x41, 0xba, 0x3b, 0xe9, 0xd4, 0xe6, 0x53, 0x1a, 0x04, 0xba, 0xe6, 0x46, 0xb5, + 0xfa, 0x1b, 0xcc, 0x2f, 0xeb, 0x0f, 0xe9, 0xdc, 0x61, 0xbe, 0xed, 0x20, 0x27, + 0x9e, 0xed, 0x94, 0x34, 0x24, 0x14, 0xaa, 0xf9, 0xf2, 0x1f, 0x2a, 0x24, 0x22, + 0xe8, 0xb5, 0x0d, 0xbd, 0xda, 0xef, 0xd3, 0xca, 0x7f, 0x56, 0xd4, 0x02, 0x06, + 0xf3, 0xe6, 0xe0, 0x6c, 0xc8, 0xa0, 0xd8, 0xd0, 0xef, 0x3a, 0xbe, 0x42, 0xd7, + 0x22, 0xfe, 0x36, 0xe6, 0x06, 0x1a, 0xf3, 0x0d, 0x1c, 0x10, 0xe9, 0xce, 0xde, + 0x19, 0x20, 0x0b, 0xc8, 0xfc, 0x0a, 0xd4, 0xf3, 0xe0, 0x0a, 0xe0, 0xe0, 0xd2, + 0x0c, 0xf6, 0xfc, 0xf8, 0x22, 0xe6, 0xee, 0x65, 0x0a, 0x7f, 0x35, 0x0b, 0x2f, + 0xee, 0x08, 0xeb, 0xf7, 0xdd, 0xf8, 0x1d, 0x25, 0x21, 0xf1, 0x07, 0xe5, 0xf5, + 0x3c, 0x66, 0xf6, 0x0d, 0xe9, 0x0e, 0xe0, 0x17, 0xe5, 0xf5, 0xee, 0x0b, 0x14, + 0x06, 0xfa, 0x00, 0x23, 0x17, 0xd0, 0x00, 0xe4, 0xcc, 0x38, 0xf2, 0xd1, 0x12, + 0xf0, 0x12, 0xe5, 0xed, 0x0b, 0xe6, 0x38, 0x42, 0x2e, 0xb9, 0xfd, 0x14, 0xd3, + 0x09, 0xf4, 0xe4, 0x1e, 0x45, 0xd8, 0xc4, 0xff, 0x3d, 0xea, 0xf7, 0x01, 0x0d, + 0xea, 0x0c, 0xf2, 0x06, 0x07, 0x0c, 0xd0, 0x05, 0xda, 0x3b, 0xfb, 0x19, 0x0e, + 0x70, 0xc2, 0xfb, 0xdc, 0x2a, 0x22, 0x10, 0xe6, 0xd3, 0xf0, 0x1d, 0x4b, 0xb1, + 0x36, 0xf5, 0x1f, 0xdb, 0xf5, 0x03, 0x15, 0xe6, 0xe9, 0xee, 0xf8, 0x0f, 0x18, + 0x2e, 0x02, 0x0e, 0x23, 0xfe, 0x1a, 0x33, 0x1c, 0xa6, 0x0f, 0xf7, 0x67, 0x0e, + 0x0b, 0x33, 0xc7, 0x0a, 0x92, 0x19, 0x1c, 0x35, 0x17, 0xe6, 0xf8, 0x05, 0xd5, + 0x0b, 0x11, 0x13, 0xfa, 0x63, 0x15, 0xee, 0xcd, 0xdc, 0x2c, 0xe5, 0xed, 0x17, + 0x14, 0xdb, 0xcd, 0xec, 0x09, 0x37, 0x3b, 0x71, 0xfe, 0xed, 0x44, 0xc5, 0x4a, + 0xbb, 0xaa, 0x12, 0xec, 0x06, 0x20, 0xde, 0x88, 0xac, 0xfc, 0x7d, 0x08, 0xf8, + 0x0e, 0xb1, 0xef, 0xd2, 0xea, 0xf8, 0x5e, 0xfa, 0xd8, 0xb1, 0x2d, 0xf0, 0x0f, + 0x2b, 0xfe, 0x21, 0x0a, 0xc2, 0xe4, 0x0a, 0xe2, 0xa3, 0x2b, 0x40, 0x3c, 0xa7, + 0xcb, 0x28, 0x21, 0xd4, 0xa2, 0xd8, 0xdd, 0x28, 0xbc, 0xdd, 0x2f, 0x7f, 0x29, + 0xd4, 0x20, 0xa9, 0x32, 0xb9, 0x3a, 0x2d, 0x06, 0x12, 0x00, 0x82, 0xfe, 0xd2, + 0x4b, 0x5d, 0x12, 0xf4, 0x42, 0xae, 0xbd, 0x62, 0xbc, 0xfe, 0x29, 0x04, 0x10, + 0xe9, 0xd0, 0x00, 0x40, 0x28, 0x3f, 0xd9, 0x0b, 0x01, 0x1a, 0x10, 0x21, 0x01, + 0xe5, 0x5f, 0x26, 0x06, 0x26, 0x15, 0x25, 0xbc, 0x32, 0x19, 0x07, 0x44, 0xba, + 0x07, 0xe7, 0xf4, 0x06, 0x14, 0x33, 0xf4, 0x15, 0xf9, 0xd2, 0xe5, 0x27, 0x1e, + 0x15, 0x57, 0x00, 0xfb, 0xe3, 0x12, 0xf1, 0x36, 0x02, 0x38, 0x03, 0x1b, 0xda, + 0x42, 0x0a, 0x31, 0x66, 0x19, 0x16, 0xc4, 0xf1, 0x1d, 0xf9, 0x36, 0x52, 0xea, + 0x4d, 0x2b, 0x20, 0xdd, 0xfd, 0x3a, 0x4a, 0x7f, 0xd5, 0xf9, 0xc5, 0x2e, 0x40, + 0xe9, 0x19, 0xe7, 0x16, 0xd0, 0xd1, 0xf4, 0xdb, 0xd4, 0xe4, 0xe0, 0x06, 0x09, + 0xee, 0xe5, 0xe6, 0x5d, 0xd9, 0x49, 0xcf, 0x25, 0xef, 0x17, 0x13, 0xea, 0xd5, + 0xe1, 0xe4, 0xf2, 0x39, 0x14, 0x22, 0xe6, 0x37, 0xf6, 0x08, 0x0a, 0x17, 0x09, + 0xfc, 0x12, 0xef, 0xf0, 0xfe, 0xdb, 0x0f, 0x29, 0x2e, 0x03, 0xeb, 0xfa, 0x00, + 0xf9, 0x0c, 0x3a, 0xf2, 0xdf, 0xe8, 0xe4, 0xfa, 0xfa, 0xdd, 0x11, 0x01, 0xe7, + 0x0a, 0x0c, 0xde, 0x02, 0xf8, 0xe9, 0x25, 0x28, 0x08, 0x0c, 0x03, 0x0c, 0xe2, + 0xdb, 0xe1, 0x17, 0xfe, 0x06, 0xdb, 0x19, 0x19, 0x0e, 0x21, 0x3f, 0x12, 0x19, + 0xa7, 0x04, 0x96, 0x01, 0x12, 0xfe, 0xfb, 0xd7, 0xfc, 0xe8, 0x2b, 0xfc, 0x0d, + 0x00, 0xfe, 0xf6, 0x49, 0x02, 0xeb, 0xf0, 0x22, 0x5b, 0x09, 0x7f, 0x07, 0x02, + 0xc5, 0x24, 0xbe, 0x13, 0x3a, 0x02, 0x1f, 0x32, 0x45, 0xe9, 0xf9, 0xee, 0xea, + 0x0a, 0x11, 0xeb, 0xf0, 0xeb, 0xfc, 0xe2, 0x0b, 0xc4, 0xfe, 0xf2, 0x14, 0xe2, + 0x01, 0xf3, 0xde, 0x1c, 0xd3, 0x11, 0x17, 0x25, 0xc9, 0xfa, 0x06, 0xdf, 0xc6, + 0xf3, 0x0b, 0xef, 0x18, 0x0e, 0xf9, 0xff, 0x0c, 0xec, 0xff, 0xf7, 0xed, 0xe9, + 0x02, 0xc1, 0xd1, 0x12, 0xdd, 0xe3, 0x18, 0x17, 0x07, 0x33, 0x1b, 0xf3, 0x06, + 0x1a, 0x0c, 0x2d, 0xe0, 0xe9, 0xf2, 0xd0, 0xf2, 0xec, 0x1d, 0xdf, 0x03, 0xfc, + 0x06, 0x05, 0xea, 0x20, 0x20, 0xd8, 0x1d, 0xf4, 0xff, 0x13, 0xf2, 0x19, 0xec, + 0xf3, 0xe2, 0xeb, 0xd9, 0x04, 0x2d, 0x15, 0x13, 0x2e, 0xfd, 0xd0, 0xed, 0x20, + 0xfd, 0x06, 0xf1, 0xdd, 0x1c, 0x4d, 0x08, 0xf1, 0x13, 0x01, 0xfc, 0x1a, 0xf4, + 0x0d, 0xff, 0xf6, 0x14, 0x03, 0x1c, 0x3a, 0xf0, 0x7f, 0xe9, 0xff, 0xec, 0xec, + 0x2a, 0xfa, 0x04, 0xd9, 0x27, 0x23, 0xd0, 0xec, 0xff, 0x14, 0xf8, 0x07, 0x08, + 0xe6, 0x0c, 0x29, 0x0e, 0x18, 0xeb, 0xdf, 0x0d, 0x18, 0xe5, 0x21, 0x01, 0x18, + 0x3a, 0xf9, 0xf2, 0x2a, 0x25, 0x11, 0xd6, 0x1f, 0x0b, 0x29, 0x4a, 0x03, 0xee, + 0x00, 0xf8, 0x15, 0x07, 0x27, 0x05, 0xff, 0x06, 0x05, 0xe9, 0xd9, 0x2f, 0x0b, + 0x13, 0x06, 0xff, 0x0b, 0x1e, 0xed, 0x22, 0x17, 0x0b, 0xfd, 0xea, 0x38, 0xd1, + 0x23, 0x08, 0x1b, 0xce, 0xaa, 0x34, 0x09, 0x3a, 0xd8, 0xe0, 0x15, 0x10, 0xf8, + 0x29, 0xec, 0xf3, 0xf4, 0x23, 0x21, 0xba, 0xf9, 0x0d, 0x12, 0x30, 0x03, 0xbb, + 0xfa, 0xfb, 0xd2, 0xd4, 0x06, 0x16, 0x07, 0xff, 0xfc, 0x0d, 0xfe, 0xd9, 0xc8, + 0xe1, 0x46, 0xc0, 0x13, 0xe3, 0xe5, 0xed, 0xf2, 0x31, 0xae, 0x29, 0x98, 0xfb, + 0xca, 0xdc, 0xea, 0x08, 0xdb, 0x2b, 0x2d, 0xf3, 0x16, 0x67, 0xe0, 0xef, 0x13, + 0x40, 0xfb, 0xe2, 0x35, 0x62, 0x30, 0x57, 0xa1, 0x12, 0xf1, 0xc1, 0xed, 0xe5, + 0xe2, 0x1e, 0xc3, 0xd9, 0xf2, 0x3f, 0x4a, 0x05, 0xba, 0x24, 0x81, 0xb0, 0x18, + 0x01, 0xea, 0x04, 0x5b, 0x36, 0xcc, 0xab, 0xe0, 0xe9, 0xc8, 0xc8, 0x50, 0xdd, + 0xde, 0x42, 0x02, 0xd3, 0xe3, 0xdd, 0x10, 0xef, 0x63, 0xf8, 0xdd, 0xba, 0xdf, + 0xd4, 0xe1, 0xff, 0xfc, 0xc6, 0x26, 0xfa, 0xc5, 0x39, 0x11, 0x2d, 0x29, 0xfd, + 0xaa, 0x2d, 0xbd, 0xbe, 0x04, 0xde, 0xea, 0xe6, 0xd1, 0xf0, 0xfd, 0x62, 0x0c, + 0xf7, 0x15, 0x0e, 0xc0, 0x33, 0xff, 0xe9, 0x33, 0xee, 0xdc, 0xc8, 0xdd, 0x11, + 0x04, 0xe3, 0x24, 0xe7, 0x0f, 0x27, 0xf3, 0x07, 0x0d, 0xc3, 0x05, 0x15, 0xde, + 0x2e, 0xfc, 0xf9, 0x17, 0x41, 0x01, 0xf5, 0x7f, 0x38, 0xd6, 0xff, 0xfd, 0xef, + 0x02, 0xd1, 0xca, 0xe4, 0xfc, 0xfe, 0x5b, 0xeb, 0xfb, 0x16, 0xda, 0xda, 0xd3, + 0x00, 0x16, 0xcf, 0xe3, 0x1b, 0x52, 0x08, 0x3f, 0x1e, 0xe0, 0x3c, 0xc5, 0x1c, + 0x6a, 0xf5, 0xf6, 0xff, 0x0c, 0xf6, 0x04, 0xc6, 0xa2, 0x1f, 0xf1, 0xe9, 0x25, + 0x1e, 0x0b, 0xc6, 0x0b, 0x1c, 0xca, 0x00, 0xf8, 0xb6, 0xda, 0xe2, 0x19, 0xd7, + 0xd1, 0x00, 0xe7, 0x0c, 0x1b, 0x1a, 0xc7, 0x04, 0xd8, 0xee, 0xd2, 0xdf, 0xf0, + 0x3b, 0xff, 0xc0, 0x6c, 0x20, 0xed, 0x24, 0x07, 0x0f, 0x18, 0x3c, 0xd9, 0x2d, + 0x29, 0x05, 0xf3, 0xf3, 0x06, 0xe0, 0xde, 0x13, 0xdc, 0xf9, 0x38, 0xb0, 0x22, + 0x24, 0x02, 0x56, 0x1e, 0xf1, 0xf1, 0x02, 0xe0, 0xd7, 0xf4, 0x22, 0xdb, 0xf3, + 0xf6, 0xc3, 0x0d, 0xda, 0xc8, 0xf4, 0x21, 0xd8, 0xf5, 0x2f, 0x24, 0x37, 0xfc, + 0x23, 0x28, 0xd5, 0x16, 0x1f, 0xb9, 0x0b, 0xfa, 0xd6, 0xf9, 0xe1, 0xdd, 0xe1, + 0xe1, 0xf5, 0xd3, 0xd8, 0x39, 0x04, 0x19, 0x2f, 0xc1, 0x04, 0xe3, 0xb8, 0x10, + 0xc7, 0x36, 0x56, 0xf1, 0xf4, 0xea, 0xf4, 0x60, 0x1e, 0xe3, 0x05, 0x40, 0xe8, + 0x98, 0xed, 0xed, 0x01, 0x2b, 0x0d, 0xea, 0xc0, 0xee, 0x7f, 0xee, 0x03, 0x03, + 0x14, 0xa6, 0xf7, 0x2d, 0xdf, 0xf9, 0xd7, 0x29, 0x01, 0xe8, 0x06, 0x04, 0xeb, + 0xe0, 0x0e, 0x1d, 0x3e, 0x26, 0x14, 0x9c, 0xf3, 0xc9, 0x02, 0xc1, 0x13, 0x1b, + 0x03, 0x0c, 0xfa, 0xf7, 0xe6, 0xf9, 0xfc, 0xfd, 0xc9, 0xc8, 0x5f, 0xc9, 0xfb, + 0xd9, 0x10, 0xb6, 0xd9, 0xc4, 0xd0, 0xcd, 0xf6, 0x14, 0x3e, 0xc1, 0xff, 0xef, + 0x1c, 0x0f, 0xe2, 0xab, 0x03, 0xf1, 0x02, 0xd6, 0x2b, 0x17, 0x16, 0xfd, 0xdb, + 0x1b, 0xda, 0xee, 0xc4, 0x34, 0x2a, 0xf2, 0xcd, 0xfc, 0x24, 0xdb, 0x14, 0xbc, + 0x28, 0xc3, 0xc0, 0xce, 0xbd, 0x25, 0x08, 0xe0, 0x21, 0xf9, 0x48, 0xeb, 0xdd, + 0x9e, 0xe1, 0xb7, 0x14, 0xbd, 0xd1, 0x17, 0x03, 0xbc, 0xe4, 0x2f, 0x29, 0x05, + 0x13, 0x7f, 0x0e, 0x04, 0xf4, 0x18, 0x05, 0x05, 0x3e, 0x55, 0x3f, 0xeb, 0x0d, + 0x17, 0xe9, 0x44, 0xfc, 0x84, 0xdc, 0x1f, 0xc0, 0x48, 0xe3, 0x01, 0xb5, 0xe7, + 0xfb, 0x2b, 0xf9, 0xdc, 0x1f, 0xdd, 0x15, 0x55, 0xfa, 0xfa, 0xc3, 0xdd, 0x09, + 0x20, 0xe8, 0xf3, 0x0b, 0xda, 0xf3, 0xf3, 0x15, 0x1d, 0x1d, 0x18, 0x07, 0x20, + 0x35, 0x32, 0xf7, 0x2b, 0x17, 0x59, 0xc7, 0xc2, 0xec, 0xd6, 0xfc, 0xfc, 0x2f, + 0xec, 0xea, 0x37, 0xb9, 0x0d, 0x2e, 0xf4, 0x55, 0xb2, 0xd6, 0xbb, 0x0b, 0xca, + 0x35, 0xdc, 0x12, 0xfe, 0x09, 0x45, 0xec, 0xfb, 0xe8, 0x23, 0x0c, 0xda, 0xe6, + 0xf8, 0x40, 0xf9, 0x12, 0xd0, 0x17, 0xc8, 0xe8, 0x7f, 0x1e, 0xe3, 0x21, 0x18, + 0x08, 0x16, 0xc8, 0x3c, 0x31, 0xdc, 0x78, 0xc4, 0x01, 0x52, 0xeb, 0x69, 0x0b, + 0xf9, 0x0b, 0xce, 0x36, 0xcf, 0x3b, 0xd8, 0xe4, 0x1d, 0xcc, 0xea, 0x04, 0x0d, + 0x18, 0x2f, 0x05, 0xe5, 0x15, 0x01, 0x10, 0x37, 0xde, 0xe6, 0x24, 0x03, 0xcf, + 0x11, 0xb5, 0xeb, 0x4c, 0x3d, 0x17, 0xfc, 0x18, 0x4d, 0xb8, 0x72, 0x32, 0xc8, + 0x04, 0x12, 0xed, 0xe8, 0xc0, 0x30, 0x3c, 0x12, 0xdb, 0x18, 0xd9, 0xd5, 0xd8, + 0x05, 0xbb, 0xb9, 0x4d, 0x04, 0xd9, 0x37, 0xed, 0xfa, 0xf2, 0xf6, 0xed, 0xbd, + 0x4e, 0x8d, 0xf4, 0x2d, 0x09, 0xd8, 0x83, 0xed, 0xad, 0xec, 0x37, 0xe7, 0x21, + 0xdd, 0xd3, 0x23, 0xc7, 0x07, 0xe8, 0xc7, 0x18, 0xd3, 0x5f, 0x13, 0xe4, 0x00, + 0xdc, 0xff, 0x02, 0x28, 0x4a, 0x5f, 0xf3, 0x1a, 0x4b, 0xe8, 0xc5, 0x3e, 0x17, + 0x1d, 0x42, 0x02, 0x20, 0x01, 0x2c, 0x1d, 0xf7, 0x04, 0xe3, 0x29, 0x09, 0x45, + 0x11, 0x11, 0xe3, 0x09, 0x2c, 0xe0, 0x19, 0x17, 0xd7, 0x65, 0x0e, 0x05, 0x14, + 0x4b, 0xc9, 0xfa, 0xed, 0x0b, 0xe4, 0x13, 0xe6, 0xce, 0xad, 0xc3, 0xdb, 0xf8, + 0x1f, 0x20, 0x25, 0x01, 0xd7, 0x47, 0xb7, 0xfe, 0x29, 0x0a, 0xd5, 0x24, 0xfe, + 0x7f, 0xbe, 0xe1, 0xd7, 0x05, 0xd5, 0xae, 0x7c, 0x5c, 0x3c, 0xaf, 0xd7, 0x57, + 0xb7, 0x16, 0xaf, 0x28, 0xdd, 0xef, 0x23, 0x0d, 0xc6, 0x0b, 0x0c, 0x22, 0x96, + 0xc8, 0x1d, 0x9b, 0xdd, 0xe7, 0x01, 0xea, 0x2d, 0x0f, 0xc9, 0xff, 0x45, 0x13, + 0x26, 0x29, 0x08, 0x31, 0x98, 0xcf, 0xd2, 0xdc, 0x07, 0xd4, 0xeb, 0x0b, 0xd1, + 0x3c, 0x74, 0xc8, 0xe4, 0xef, 0x0c, 0xc4, 0xc8, 0x11, 0xa6, 0x64, 0xf9, 0xf9, + 0xf5, 0x4a, 0xc7, 0x2c, 0x19, 0x30, 0x27, 0x0d, 0xff, 0x44, 0x56, 0xc6, 0xc7, + 0xe8, 0xf5, 0xe8, 0xf7, 0xf6, 0x9e, 0x20, 0xf9, 0x19, 0x0b, 0x30, 0xe3, 0x0b, + 0xb4, 0x14, 0xd6, 0x57, 0xef, 0xb7, 0x06, 0xfd, 0xf7, 0xc7, 0x05, 0xf9, 0xfb, + 0x00, 0x29, 0x23, 0xbf, 0x99, 0x26, 0x16, 0xd6, 0x03, 0xa5, 0x46, 0x49, 0xd2, + 0x37, 0x7f, 0x24, 0xe7, 0xfc, 0xa2, 0x38, 0x43, 0x53, 0xd9, 0xdb, 0xf5, 0xe9, + 0xdb, 0x78, 0xd2, 0xd9, 0x4e, 0xec, 0x0c, 0x1b, 0xb5, 0xc5, 0xa7, 0xe6, 0x2e, + 0xf4, 0x0a, 0xf5, 0x18, 0xa6, 0x23, 0x0f, 0xc0, 0xfe, 0xf3, 0x16, 0xd4, 0xfa, + 0x74, 0x11, 0x16, 0xda, 0x13, 0xc1, 0x2a, 0xd7, 0x0c, 0xf8, 0x0e, 0xe1, 0xcb, + 0x12, 0x28, 0xb4, 0x43, 0x0e, 0xe0, 0x27, 0xd0, 0xd0, 0xc1, 0x0c, 0x12, 0xd7, + 0xe1, 0xc8, 0x40, 0xf3, 0x7d, 0xa7, 0x14, 0xd0, 0x38, 0xdb, 0x1d, 0x2b, 0xc2, + 0x3a, 0xd1, 0xa3, 0xbf, 0x50, 0xea, 0xf7, 0x32, 0xe9, 0xfd, 0x01, 0x1d, 0x15, + 0x06, 0x1f, 0x9a, 0xe4, 0xf7, 0x32, 0x29, 0xff, 0xc5, 0x02, 0xb3, 0xd8, 0x61, + 0x0a, 0x10, 0xf8, 0xfb, 0xf5, 0xfe, 0xd6, 0x06, 0x05, 0xe4, 0xc4, 0x0a, 0x7f, + 0x90, 0xa0, 0x05, 0xce, 0x2e, 0xe3, 0xab, 0x24, 0xe9, 0x17, 0x10, 0xc2, 0xf8, + 0xcc, 0x00, 0xf5, 0x11, 0xf0, 0x24, 0xd5, 0xe5, 0x08, 0x07, 0xc8, 0xf3, 0x00, + 0x23, 0xb0, 0x28, 0x54, 0xd0, 0x45, 0xe9, 0x03, 0xdf, 0xf3, 0xf5, 0x21, 0xcc, + 0x14, 0xfb, 0xfa, 0xbc, 0x1d, 0x04, 0xe3, 0xf9, 0x26, 0x03, 0x08, 0xf8, 0xfd, + 0x2e, 0xc9, 0xd6, 0x0f, 0xe2, 0x37, 0x4a, 0x14, 0xec, 0x1d, 0x61, 0xb6, 0x1c, + 0xdc, 0xbe, 0x09, 0x04, 0x2e, 0x02, 0xa8, 0xe2, 0xeb, 0x0b, 0x64, 0x20, 0x5a, + 0xe9, 0x16, 0xbd, 0xf3, 0xba, 0x19, 0x22, 0xe5, 0x18, 0xfc, 0xd6, 0xa2, 0x29, + 0x2e, 0x23, 0x1d, 0xdd, 0x16, 0x19, 0x01, 0xcf, 0x5a, 0x1e, 0xfe, 0xe5, 0xf5, + 0x7f, 0xee, 0xb4, 0x1c, 0xf6, 0xbf, 0xe0, 0xfb, 0xd1, 0x01, 0xf7, 0xef, 0xdf, + 0xd9, 0x56, 0xe0, 0x35, 0xc6, 0xd2, 0xd0, 0xc5, 0x2d, 0xc8, 0xf6, 0x93, 0x6c, + 0xf9, 0xe4, 0x0b, 0xe6, 0xf6, 0x9c, 0xfd, 0x67, 0xb7, 0xfb, 0x2b, 0x25, 0xff, + 0xf5, 0x1f, 0xe2, 0x03, 0x04, 0x03, 0xf3, 0xb8, 0x40, 0x6b, 0x09, 0xee, 0x7e, + 0xeb, 0xa1, 0x0a, 0x38, 0xe3, 0x0a, 0x73, 0xfd, 0xbc, 0xcb, 0x4e, 0x9f, 0xe3, + 0xd1, 0xfe, 0x00, 0xd9, 0xfa, 0x0f, 0x00, 0x36, 0x86, 0x50, 0x33, 0x0d, 0xfe, + 0xff, 0x17, 0xd4, 0x70, 0xd9, 0xc9, 0xc6, 0x10, 0xeb, 0x36, 0x16, 0x15, 0xe2, + 0x41, 0xf1, 0xe8, 0xdb, 0xfb, 0x00, 0xed, 0x44, 0x51, 0x2d, 0xf7, 0xe8, 0xe3, + 0x27, 0x38, 0x22, 0x16, 0xfa, 0x30, 0xe9, 0x4f, 0x5c, 0xe3, 0x30, 0x46, 0xd2, + 0xeb, 0xd2, 0xac, 0xc3, 0xf4, 0xb9, 0x02, 0xb6, 0xd8, 0xea, 0x4a, 0xa3, 0xf8, + 0xbf, 0xcb, 0xc2, 0x1e, 0xfa, 0xb5, 0x35, 0xdf, 0xf6, 0xfb, 0xe8, 0xf8, 0x2d, + 0x39, 0x81, 0xd7, 0xea, 0xc4, 0x67, 0x9b, 0xb2, 0x3d, 0xe1, 0xdb, 0xf0, 0x12, + 0xd9, 0xea, 0xda, 0xca, 0xa9, 0xf5, 0xdc, 0x0d, 0xf9, 0x13, 0xc7, 0xe7, 0xc2, + 0x1d, 0xed, 0xc0, 0x5a, 0xcf, 0x67, 0x26, 0xce, 0x04, 0x16, 0x2f, 0xdd, 0xee, + 0x3a, 0x1c, 0xe5, 0x25, 0x20, 0xd1, 0xd7, 0x14, 0x77, 0xff, 0xea, 0xc1, 0xca, + 0xbc, 0x06, 0x13, 0xff, 0x21, 0xc2, 0x03, 0xff, 0x03, 0x03, 0x0c, 0x60, 0x06, + 0x26, 0xc5, 0x24, 0x3b, 0x0b, 0x2e, 0x14, 0xf4, 0x06, 0x14, 0x00, 0x12, 0xeb, + 0xe6, 0x29, 0xe1, 0x18, 0x16, 0x27, 0x15, 0xde, 0x28, 0xe6, 0xef, 0x26, 0xd2, + 0xe9, 0xaf, 0xf6, 0xfd, 0x3f, 0x2c, 0x18, 0x0e, 0xfe, 0xd1, 0xc0, 0x22, 0x0e, + 0x37, 0x00, 0xfb, 0xf6, 0xf1, 0xdf, 0x0f, 0x27, 0xfb, 0x34, 0xf9, 0x24, 0xdd, + 0xec, 0xf7, 0x01, 0xff, 0x1b, 0x3e, 0x29, 0xc5, 0xf4, 0x43, 0x27, 0x3c, 0xed, + 0x17, 0x0d, 0x04, 0x22, 0xcc, 0xff, 0x39, 0x08, 0x81, 0xc8, 0x44, 0x13, 0x0e, + 0xe7, 0x15, 0x2d, 0xda, 0xef, 0xed, 0x17, 0x1e, 0xc5, 0x01, 0x03, 0x08, 0x0a, + 0x15, 0x1b, 0x03, 0xfa, 0x04, 0xed, 0xf0, 0xd8, 0xfc, 0xe7, 0x24, 0x12, 0xcb, + 0x17, 0x18, 0x10, 0x4d, 0xe7, 0x0a, 0x10, 0x12, 0xf8, 0xa0, 0x02, 0xfb, 0x35, + 0x0f, 0xe6, 0x17, 0x21, 0xe1, 0x1e, 0x02, 0x13, 0x15, 0x0f, 0x12, 0x0b, 0xe6, + 0x06, 0x62, 0x40, 0xdd, 0x72, 0xe8, 0x00, 0xb4, 0xef, 0x2b, 0x02, 0xe9, 0xd5, + 0x02, 0x99, 0x1c, 0xc4, 0x2b, 0xf6, 0xf8, 0x04, 0xeb, 0x1b, 0xfd, 0xe3, 0xa1, + 0x49, 0x95, 0xe8, 0x0a, 0x14, 0xc8, 0xaf, 0xb1, 0x8f, 0xf3, 0x1f, 0x0b, 0xda, + 0x10, 0x9f, 0xdc, 0x02, 0xd8, 0xce, 0x3d, 0xf5, 0x02, 0x0d, 0x1b, 0x16, 0x17, + 0x29, 0xf2, 0xeb, 0x3e, 0x54, 0xba, 0x96, 0xcf, 0xbf, 0x2d, 0x2d, 0x00, 0x1c, + 0xcd, 0x2e, 0xe3, 0xce, 0x0c, 0x9c, 0x3d, 0x36, 0xa5, 0x3b, 0xdd, 0xb2, 0x30, + 0x07, 0xfd, 0x39, 0x00, 0x09, 0x03, 0x11, 0xa0, 0xfc, 0x66, 0xfd, 0xe8, 0xec, + 0xf3, 0xac, 0xb9, 0xcf, 0x1a, 0x98, 0xfe, 0x9a, 0xbc, 0x17, 0x1e, 0xe0, 0x0f, + 0x0d, 0x59, 0xbd, 0xfd, 0xeb, 0x27, 0xec, 0xda, 0x0e, 0x44, 0xd4, 0x3c, 0xb9, + 0x27, 0xbd, 0x07, 0xd8, 0x34, 0xa1, 0xf5, 0x24, 0x7f, 0x41, 0x15, 0x17, 0x69, + 0x43, 0x08, 0x09, 0x18, 0xe6, 0xd0, 0xf1, 0xf4, 0x10, 0x06, 0xd1, 0xda, 0xeb, + 0xcb, 0x55, 0x24, 0xd9, 0xe1, 0x22, 0x09, 0xbd, 0x11, 0xe8, 0x00, 0xe6, 0x3a, + 0xfd, 0x27, 0x31, 0x03, 0x00, 0x1a, 0x33, 0x76, 0x5a, 0x40, 0x7f, 0x44, 0x33, + 0x00, 0xff, 0xc3, 0x18, 0xca, 0x9b, 0xfe, 0xf5, 0x3b, 0x02, 0xf6, 0x1d, 0xef, + 0xe4, 0xf9, 0x1a, 0xc6, 0x1f, 0x1c, 0xff, 0x12, 0x0c, 0xed, 0x0e, 0xf9, 0x05, + 0x30, 0xfe, 0x3a, 0xd7, 0xba, 0xbc, 0x3c, 0x1d, 0xe9, 0x0d, 0x13, 0xc8, 0x5a, + 0x3d, 0xdd, 0xef, 0x23, 0x07, 0xf1, 0x12, 0x00, 0xd5, 0x01, 0xff, 0xde, 0xd3, + 0x06, 0x05, 0xce, 0x26, 0x19, 0xcc, 0xf6, 0xf2, 0x08, 0xe3, 0xbb, 0xf3, 0xe9, + 0x04, 0x08, 0x25, 0x51, 0xe8, 0xd3, 0x54, 0x0f, 0x1a, 0xf3, 0x68, 0x1f, 0x61, + 0x1a, 0xdf, 0xff, 0xfa, 0x1b, 0xb9, 0x59, 0x33, 0xd7, 0x03, 0x0c, 0x35, 0x1d, + 0x14, 0xcf, 0x81, 0x96, 0xce, 0x91, 0xf0, 0x20, 0xc3, 0xe5, 0x3e, 0xb8, 0x05, + 0x03, 0xfd, 0x19, 0xac, 0xee, 0xcc, 0x60, 0x55, 0xe8, 0x52, 0x0a, 0x25, 0xb8, + 0x28, 0xd4, 0xcc, 0x00, 0xc4, 0x29, 0x1c, 0x26, 0xf6, 0x1b, 0x0e, 0xdd, 0x0d, + 0x36, 0x0b, 0x41, 0xe6, 0x49, 0xec, 0x04, 0x0d, 0xe4, 0xea, 0xad, 0xdf, 0xc7, + 0x06, 0x6a, 0xf9, 0x1d, 0xfc, 0x31, 0xf4, 0xfb, 0x59, 0x00, 0x97, 0x72, 0x00, + 0xb7, 0xc8, 0x47, 0x48, 0xff, 0xdc, 0xe8, 0xf0, 0x21, 0xee, 0x27, 0xf6, 0x26, + 0x2b, 0xf0, 0x3f, 0xac, 0x40, 0x4b, 0x11, 0x06, 0x21, 0x0a, 0x32, 0x12, 0x54, + 0xf5, 0x1c, 0xe1, 0x1c, 0x64, 0x4e, 0x65, 0x45, 0xfd, 0xcf, 0xeb, 0xff, 0xf3, + 0xe1, 0x28, 0x25, 0x11, 0xeb, 0xe8, 0xbc, 0xf3, 0x59, 0xe1, 0xa3, 0xc5, 0xc0, + 0xc0, 0xea, 0x48, 0xaf, 0xb6, 0x0f, 0xc7, 0x06, 0xe6, 0x0e, 0x32, 0xfe, 0xf8, + 0x14, 0xde, 0x58, 0x27, 0x49, 0x1f, 0xe9, 0x3b, 0x5d, 0xde, 0x09, 0xe8, 0x04, + 0x20, 0xec, 0xf9, 0xc2, 0x25, 0x62, 0x1b, 0xbf, 0x28, 0x23, 0x09, 0x3d, 0x06, + 0xf9, 0x52, 0x3b, 0xdd, 0xf9, 0xbd, 0x8a, 0x4a, 0x1b, 0xe5, 0xfb, 0xec, 0x0e, + 0x13, 0xdd, 0xa7, 0xc3, 0xeb, 0xd4, 0x24, 0xb7, 0xc9, 0xc4, 0xe5, 0xd4, 0xc8, + 0x4d, 0x2f, 0xf9, 0x1e, 0x4a, 0xf6, 0x12, 0xf4, 0x47, 0x1d, 0xff, 0xf3, 0xfb, + 0xa2, 0xda, 0xf2, 0xfe, 0x2c, 0xf5, 0x0d, 0xbb, 0x2d, 0x07, 0x0a, 0xcd, 0x41, + 0xd7, 0xcd, 0xec, 0xbf, 0x13, 0x12, 0xf0, 0x05, 0xf3, 0xe7, 0x7f, 0x06, 0x1c, + 0x0e, 0x1c, 0xf8, 0x55, 0xd2, 0xd1, 0x16, 0x36, 0xd9, 0x1a, 0x19, 0x39, 0x34, + 0x01, 0xe4, 0xfa, 0xb7, 0x2c, 0x29, 0xf3, 0x06, 0xe8, 0xac, 0x12, 0xcc, 0x05, + 0x13, 0xee, 0x14, 0x10, 0xda, 0xf8, 0xe4, 0xc9, 0xed, 0x10, 0x0a, 0xce, 0x66, + 0xbf, 0x0a, 0x11, 0x0a, 0xdd, 0xf2, 0x1c, 0x0f, 0x26, 0xd6, 0x2b, 0x25, 0xef, + 0x01, 0xcc, 0x24, 0xfa, 0x7f, 0xe8, 0xff, 0x1b, 0xf4, 0x40, 0xd1, 0xf5, 0xf2, + 0xcf, 0xae, 0xd3, 0x01, 0xec, 0xda, 0x34, 0x11, 0x0d, 0x17, 0xe3, 0x09, 0xe3, + 0xfb, 0xe9, 0xe4, 0xf1, 0xdc, 0xaa, 0x9c, 0x58, 0x02, 0xcf, 0xff, 0xfc, 0x30, + 0x3e, 0xdc, 0xc0, 0xf9, 0x23, 0xee, 0xed, 0x15, 0xcb, 0xc6, 0xe3, 0x30, 0x36, + 0x6f, 0xc6, 0x27, 0xe3, 0xf0, 0xcc, 0xee, 0x0a, 0xe0, 0x32, 0xfd, 0x39, 0x0b, + 0x16, 0x04, 0x06, 0x58, 0x1d, 0xd8, 0x6b, 0xe8, 0x20, 0x1b, 0x08, 0x68, 0x0b, + 0xd6, 0xe5, 0x0a, 0xee, 0x2f, 0x26, 0xbf, 0xee, 0xe8, 0xc7, 0x23, 0xcc, 0x54, + 0x12, 0xef, 0x06, 0x18, 0xb7, 0x17, 0xb5, 0x2a, 0xd5, 0xed, 0xe8, 0x31, 0x39, + 0x0b, 0x07, 0xb1, 0xf1, 0x15, 0x18, 0x32, 0xe1, 0xf3, 0xda, 0x00, 0x14, 0x1c, + 0xe4, 0xf3, 0x19, 0x1b, 0x0a, 0x56, 0x09, 0x24, 0xf8, 0x19, 0x07, 0x14, 0x3c, + 0xd3, 0xa6, 0xbb, 0xe5, 0x4e, 0xfe, 0xb6, 0xc1, 0x16, 0xea, 0xcd, 0xf6, 0xf6, + 0xf2, 0x45, 0x23, 0xd8, 0xe8, 0xf4, 0xf9, 0x41, 0x2f, 0xd8, 0x0c, 0x0e, 0xb4, + 0x1c, 0xee, 0x3c, 0xbb, 0xd8, 0xe9, 0x7f, 0xe2, 0x11, 0x0d, 0x87, 0x4a, 0x58, + 0x19, 0x1f, 0xf6, 0xeb, 0xdf, 0xc0, 0xda, 0x30, 0xd6, 0xe6, 0xe6, 0x9c, 0x41, + 0x1a, 0x19, 0x1c, 0xbc, 0x6d, 0x02, 0x1b, 0x01, 0x20, 0xb7, 0x00, 0xdc, 0x0d, + 0xf0, 0xfe, 0xf9, 0x05, 0x14, 0x06, 0x20, 0xdc, 0xf7, 0x04, 0xec, 0x19, 0xf5, + 0xd6, 0xeb, 0x25, 0xd0, 0x49, 0xcc, 0x15, 0x00, 0xfe, 0xce, 0xfe, 0xe3, 0x0d, + 0x41, 0x1b, 0x0c, 0x0e, 0xec, 0xdf, 0xdc, 0x1b, 0xb8, 0x0f, 0x4a, 0xd4, 0xee, + 0x2d, 0xcf, 0x61, 0x14, 0xed, 0x28, 0xe6, 0xc1, 0x25, 0x35, 0xc1, 0x21, 0xe3, + 0x38, 0x0e, 0xe1, 0xf6, 0xe9, 0xe9, 0x08, 0xe8, 0xf7, 0xd3, 0xf0, 0x02, 0xeb, + 0x08, 0x07, 0x32, 0xf6, 0xd6, 0xfd, 0x27, 0x05, 0xf1, 0xea, 0x2d, 0xff, 0xeb, + 0xd0, 0xeb, 0xec, 0xed, 0x06, 0xfe, 0xec, 0x3a, 0x7f, 0x37, 0x23, 0xee, 0x17, + 0xd4, 0x14, 0xed, 0x48, 0x21, 0x08, 0x12, 0x17, 0x0b, 0x38, 0xca, 0xdf, 0x48, + 0x2d, 0xcb, 0x29, 0x2e, 0xf6, 0x33, 0xf7, 0xe8, 0xc6, 0xf1, 0xc9, 0xf5, 0x35, + 0x0e, 0xf6, 0xbc, 0x03, 0xf9, 0x1a, 0xfa, 0x3c, 0x07, 0x13, 0x29, 0x13, 0xe4, + 0x0f, 0x2e, 0x49, 0xec, 0xeb, 0x08, 0x07, 0x0f, 0x0e, 0xb8, 0x2e, 0xf1, 0xfb, + 0x06, 0xcb, 0x4f, 0x2d, 0xec, 0x5a, 0x00, 0x03, 0x17, 0xba, 0xe3, 0xcd, 0x01, + 0x98, 0xe3, 0x65, 0x29, 0xb4, 0x0b, 0x53, 0x3a, 0xed, 0x0f, 0x02, 0xee, 0xd0, + 0x12, 0x39, 0xda, 0x11, 0x09, 0xe0, 0x1e, 0x13, 0x08, 0x0a, 0xf4, 0xd5, 0x20, + 0xb8, 0x06, 0x29, 0x3b, 0xc3, 0xd8, 0x3d, 0x2e, 0x08, 0xe5, 0x0f, 0x02, 0xb1, + 0xf9, 0xe2, 0xef, 0x14, 0x4a, 0x09, 0xe7, 0xdf, 0x21, 0x2b, 0x2c, 0xd2, 0x39, + 0xef, 0xd5, 0x05, 0xd0, 0xff, 0xde, 0xbb, 0x0e, 0x1b, 0x0f, 0xf8, 0x01, 0x0a, + 0x4e, 0xe8, 0xd8, 0xfb, 0xf6, 0xe6, 0x01, 0x13, 0x4b, 0x00, 0xfa, 0xe6, 0xd1, + 0x11, 0x18, 0x56, 0x06, 0xf0, 0xd6, 0xf5, 0x6f, 0x09, 0x04, 0xcc, 0x01, 0xf7, + 0x2a, 0x57, 0xfc, 0xd3, 0x19, 0xfd, 0x3f, 0xc4, 0xf2, 0xe3, 0x03, 0xff, 0xff, + 0xc7, 0xc9, 0xf4, 0x0a, 0x18, 0xf0, 0x03, 0xfa, 0x06, 0xdd, 0x23, 0xc6, 0xfe, + 0xfb, 0x2d, 0x22, 0x0d, 0xd7, 0x39, 0x38, 0x11, 0xfc, 0xc5, 0x01, 0x0e, 0x58, + 0x81, 0xd7, 0xe5, 0xf7, 0x06, 0xfc, 0xfe, 0x13, 0x11, 0xe1, 0x09, 0xf1, 0xc0, + 0x39, 0x17, 0xc3, 0xcd, 0xf1, 0xf2, 0x19, 0xf2, 0xc0, 0xf5, 0x06, 0xe9, 0xeb, + 0x36, 0xe5, 0x22, 0x54, 0x08, 0xea, 0xd5, 0x4f, 0xd3, 0x0b, 0x12, 0xd2, 0x2d, + 0xf0, 0xea, 0x44, 0xec, 0xe1, 0xa5, 0x1c, 0x29, 0x0b, 0xd4, 0xd2, 0x0a, 0x50, + 0xed, 0x1a, 0x0c, 0x75, 0xfc, 0x63, 0x13, 0x09, 0x32, 0xd9, 0x03, 0x0d, 0x11, + 0xb0, 0xb5, 0x54, 0x2d, 0xd8, 0xff, 0xb2, 0x0b, 0x24, 0xf9, 0xf4, 0xc0, 0x18, + 0xf2, 0x19, 0xb8, 0x26, 0x08, 0xd1, 0xda, 0xd9, 0xf9, 0xc5, 0x22, 0xef, 0xcb, + 0x00, 0x1e, 0x06, 0x71, 0xf2, 0x7f, 0xa4, 0xfc, 0xff, 0x04, 0xd1, 0xeb, 0x04, + 0xd8, 0x48, 0xf5, 0x0e, 0xd0, 0xe9, 0x12, 0x1a, 0x07, 0xf0, 0xee, 0xb3, 0x20, + 0x19, 0x8a, 0xc8, 0xf1, 0x2d, 0x09, 0x2e, 0x19, 0x3d, 0x0b, 0x56, 0x11, 0x54, + 0x50, 0x0b, 0x00, 0x1e, 0x43, 0x19, 0x1e, 0xfa, 0x1e, 0xff, 0xde, 0x38, 0x19, + 0xf6, 0xee, 0x0f, 0x13, 0xd6, 0x04, 0x01, 0x00, 0xf2, 0x32, 0x03, 0x1b, 0x29, + 0x56, 0x23, 0xd7, 0xce, 0x44, 0x0a, 0x09, 0x04, 0x1d, 0x00, 0xf9, 0xc8, 0x3a, + 0xec, 0x36, 0x28, 0x4f, 0x2e, 0x03, 0xf3, 0xe7, 0xdb, 0xf9, 0xdd, 0x3e, 0xd1, + 0xd9, 0x60, 0xaa, 0x3d, 0xe0, 0x16, 0xe1, 0x01, 0xfe, 0xb1, 0xe4, 0x03, 0x26, + 0xb2, 0xf3, 0x2a, 0x7f, 0xbc, 0x07, 0x42, 0xa5, 0xf4, 0x09, 0x51, 0x31, 0x2f, + 0xbb, 0xe6, 0x01, 0xec, 0xf0, 0xb2, 0x38, 0x11, 0x65, 0x1b, 0x1f, 0x1d, 0xc9, + 0x36, 0xf2, 0xed, 0xd0, 0x06, 0x0a, 0xdf, 0x1d, 0x58, 0x44, 0xe7, 0x0a, 0x0f, + 0x20, 0x04, 0xde, 0x35, 0x3d, 0x04, 0x27, 0x5d, 0xfd, 0x44, 0x0c, 0x03, 0x3d, + 0x2a, 0xf9, 0xdd, 0x0a, 0xca, 0x06, 0xfc, 0xc5, 0x19, 0xd7, 0x44, 0x47, 0x17, + 0x3d, 0x31, 0x09, 0x16, 0x0e, 0xfb, 0x00, 0xdb, 0xf4, 0x17, 0x59, 0x08, 0xe9, + 0x30, 0xe0, 0x28, 0x03, 0xfe, 0x16, 0x04, 0xd0, 0x26, 0xed, 0x20, 0x34, 0xbd, + 0xc6, 0x02, 0xd9, 0xfe, 0x09, 0xf9, 0x36, 0x5f, 0x24, 0xba, 0xea, 0x2a, 0xde, + 0xd2, 0x9d, 0x9f, 0xf9, 0x02, 0x9d, 0x29, 0xb0, 0x2c, 0xca, 0x11, 0x15, 0x2c, + 0x04, 0xe4, 0xc4, 0x03, 0xba, 0x1a, 0xdd, 0x0f, 0x1b, 0x7f, 0xfb, 0x51, 0x18, + 0x10, 0x31, 0x18, 0x4b, 0x07, 0xe3, 0x22, 0xb7, 0xf5, 0xba, 0xed, 0x3e, 0x2d, + 0x16, 0xf7, 0xeb, 0x48, 0xdd, 0x1a, 0xe0, 0xdf, 0xee, 0x20, 0xca, 0xf9, 0x1b, + 0x23, 0x3e, 0xd1, 0xcd, 0xc7, 0xde, 0x62, 0x44, 0xce, 0x0d, 0xc4, 0xee, 0x17, + 0xda, 0x03, 0x35, 0xed, 0xd2, 0x4c, 0xfc, 0x5a, 0x09, 0x33, 0x5f, 0xdc, 0xe6, + 0xdc, 0x45, 0xab, 0x4b, 0x1c, 0x0b, 0xac, 0xf6, 0x2f, 0xb9, 0x4d, 0x18, 0xd5, + 0x59, 0xb1, 0x20, 0x58, 0xe4, 0xc2, 0x2c, 0x02, 0x24, 0xfd, 0x31, 0x04, 0xd4, + 0xcd, 0xe0, 0x26, 0x05, 0xe5, 0xe3, 0xef, 0xf2, 0xd3, 0x22, 0x7f, 0xdf, 0xf2, + 0xd3, 0x02, 0x08, 0xc0, 0xe3, 0xd5, 0xfc, 0xf8, 0xf4, 0xc4, 0x30, 0xd5, 0x22, + 0x0c, 0xea, 0x1c, 0xde, 0xc4, 0xf2, 0xdc, 0xe5, 0x0b, 0xbe, 0xf9, 0x66, 0x0c, + 0x05, 0xfa, 0xe1, 0xdc, 0x31, 0xdc, 0xe6, 0x13, 0x30, 0x1e, 0x1b, 0xf8, 0x01, + 0x10, 0x5f, 0x16, 0x07, 0xcd, 0x2a, 0x24, 0xec, 0xc6, 0x2d, 0x1e, 0x00, 0xf6, + 0xdd, 0xb9, 0xf3, 0xf9, 0x14, 0x35, 0xd8, 0x53, 0x07, 0x1c, 0xec, 0x52, 0xc6, + 0x14, 0xe0, 0x0e, 0x1f, 0xe7, 0x12, 0x05, 0xf1, 0x2d, 0xcf, 0xf9, 0xef, 0xf4, + 0xeb, 0xfd, 0xfc, 0x0e, 0xf7, 0xd3, 0x1a, 0xf0, 0xee, 0xd6, 0xe9, 0xf9, 0xea, + 0xc6, 0xce, 0x16, 0xd8, 0xe7, 0x01, 0x2f, 0x3d, 0x00, 0xfe, 0xee, 0xf7, 0xfb, + 0xd7, 0x1d, 0xdc, 0x4f, 0xed, 0xf8, 0x2d, 0x1d, 0xd6, 0x50, 0xd3, 0x07, 0x36, + 0x35, 0xcb, 0xde, 0xe0, 0x14, 0x03, 0xfd, 0xd4, 0xe5, 0x5b, 0xdc, 0xee, 0xf9, + 0xda, 0x23, 0x34, 0x0e, 0xee, 0xe6, 0xdd, 0x2c, 0xd8, 0xec, 0xe8, 0xd4, 0x61, + 0xf4, 0x36, 0xfc, 0x1f, 0x29, 0xeb, 0x05, 0x11, 0xe7, 0xa6, 0x14, 0x03, 0x08, + 0x0e, 0x02, 0xe3, 0xd1, 0xcd, 0x34, 0x14, 0x05, 0xf7, 0xd0, 0xce, 0x32, 0x81, + 0xff, 0xc6, 0xf7, 0x14, 0x00, 0x5b, 0xfb, 0xf6, 0x43, 0x30, 0x0e, 0x1d, 0x14, + 0x43, 0xe1, 0xcf, 0x05, 0x45, 0xe9, 0xa7, 0x0c, 0x55, 0xe7, 0x1c, 0x17, 0xc7, + 0x18, 0xd9, 0x97, 0xd0, 0xbf, 0xe3, 0x0f, 0xe0, 0xc9, 0x26, 0xe3, 0xb5, 0xc3, + 0xe8, 0x29, 0x27, 0xfa, 0xb4, 0x1d, 0xd4, 0x35, 0xce, 0x28, 0xf9, 0x30, 0xc0, + 0x24, 0xf0, 0x58, 0x08, 0xf6, 0x28, 0xe7, 0xe2, 0x19, 0x0d, 0x00, 0xd5, 0x01, + 0x26, 0xfb, 0x7f, 0xf7, 0xeb, 0xc0, 0xcc, 0xe3, 0xc3, 0xc9, 0xf8, 0x2d, 0xae, + 0x17, 0x25, 0x25, 0xbe, 0xc9, 0x2e, 0x3f, 0x94, 0x39, 0xbe, 0x01, 0xf9, 0x1d, + 0x9a, 0xb7, 0x03, 0xdd, 0xdb, 0x1a, 0xfd, 0x32, 0x0d, 0x0d, 0xf2, 0x38, 0xca, + 0x42, 0x67, 0xfc, 0x0b, 0xa9, 0xf4, 0xd4, 0x35, 0xee, 0xfa, 0x20, 0x12, 0xea, + 0x2d, 0xcb, 0xdd, 0xe3, 0xec, 0xe2, 0xf5, 0x44, 0x18, 0xef, 0x66, 0xdd, 0xfa, + 0xe2, 0xaf, 0x3e, 0xdc, 0xbc, 0xf2, 0x95, 0x4a, 0xa9, 0xed, 0x08, 0x4f, 0x0d, + 0x3d, 0x3b, 0x32, 0x3b, 0xf8, 0xda, 0x28, 0x77, 0xff, 0x00, 0x26, 0x46, 0x49, + 0xfc, 0xc8, 0xf9, 0x41, 0xd6, 0x02, 0x3e, 0xf3, 0xb4, 0xee, 0x0f, 0x3b, 0x28, + 0x2e, 0x1e, 0x0b, 0xc9, 0x37, 0x20, 0xf2, 0xed, 0x20, 0xa1, 0x06, 0xfa, 0xe0, + 0xc6, 0xca, 0x1f, 0x04, 0x23, 0x2b, 0x0f, 0x3d, 0xc7, 0x20, 0xf6, 0xd2, 0x5e, + 0xcc, 0xf7, 0xcf, 0x20, 0xca, 0xe2, 0x17, 0xba, 0x1b, 0x13, 0x01, 0xc3, 0xa7, + 0xe2, 0x66, 0xe8, 0xd6, 0xa1, 0x1f, 0x20, 0x98, 0x39, 0x1f, 0x6f, 0xeb, 0xc1, + 0x18, 0xec, 0xc6, 0x41, 0x13, 0x10, 0xff, 0xe1, 0x17, 0xe7, 0x53, 0xc9, 0x1a, + 0xd5, 0x03, 0x0e, 0x20, 0x29, 0xaf, 0x0f, 0xfc, 0x06, 0xe6, 0x1a, 0xfe, 0x47, + 0xee, 0x82, 0xa3, 0xc9, 0xfc, 0xaa, 0x9d, 0xff, 0xef, 0xd2, 0x1c, 0xff, 0x16, + 0x17, 0x9e, 0x44, 0x7f, 0x9e, 0x4c, 0xba, 0x17, 0x4c, 0xe0, 0x09, 0xca, 0xa8, + 0x45, 0x27, 0xcb, 0xdb, 0x55, 0x16, 0xf8, 0x13, 0xf2, 0xd5, 0xf8, 0xf2, 0x43, + 0x9e, 0xa4, 0x4e, 0xe7, 0x05, 0x38, 0xdd, 0x33, 0x62, 0xf9, 0xdf, 0xd6, 0x88, + 0xd1, 0xf8, 0x05, 0xcf, 0xe8, 0x57, 0xe8, 0x17, 0xe1, 0xef, 0x1d, 0x2c, 0xc7, + 0xb0, 0xcd, 0x2b, 0x88, 0x0e, 0xc5, 0xc1, 0x07, 0xff, 0xdc, 0x0f, 0x07, 0x17, + 0x49, 0xd9, 0xe5, 0x34, 0xe1, 0xe6, 0xef, 0xf2, 0xcb, 0xdd, 0x1c, 0xf6, 0x38, + 0xfe, 0xf4, 0xe5, 0x14, 0x21, 0xcc, 0x36, 0x28, 0x07, 0x4c, 0xfc, 0x03, 0xbe, + 0x2f, 0xe3, 0xf6, 0xfb, 0xfb, 0x1a, 0x1c, 0x20, 0x11, 0xe2, 0x1b, 0xc8, 0x01, + 0xf8, 0xc6, 0x1a, 0x81, 0x69, 0xd5, 0x3d, 0xfa, 0xe3, 0xef, 0xb2, 0x29, 0xe6, + 0xdd, 0x1b, 0xf8, 0xf6, 0x37, 0xf6, 0x3a, 0x5f, 0xca, 0xdc, 0x49, 0x0a, 0xcf, + 0xd3, 0xd6, 0x29, 0x6a, 0xf6, 0xeb, 0x00, 0x31, 0x2e, 0x4d, 0xf2, 0x15, 0xec, + 0xf8, 0xf0, 0x2f, 0xd3, 0xf0, 0xd6, 0x22, 0x27, 0x24, 0xf2, 0xe2, 0x20, 0x12, + 0x25, 0xfb, 0x2c, 0xec, 0xd0, 0xdc, 0x0f, 0x37, 0x09, 0xfd, 0xe6, 0xfd, 0x25, + 0xe0, 0xfe, 0x38, 0x09, 0xde, 0xf8, 0xe6, 0xed, 0xe6, 0x0f, 0xe4, 0x12, 0xd2, + 0xbf, 0xef, 0x09, 0x33, 0x1a, 0x2d, 0xe8, 0xdb, 0xd5, 0xe8, 0x2d, 0x12, 0x01, + 0x2a, 0xe3, 0x81, 0xf9, 0xd0, 0x0e, 0xd7, 0xfc, 0x1d, 0xea, 0x17, 0xf1, 0x00, + 0x4b, 0xd0, 0x0b, 0xe4, 0x10, 0xfa, 0x19, 0xd2, 0xf1, 0x11, 0xe9, 0xcf, 0xc6, + 0x16, 0x20, 0x1d, 0x04, 0x15, 0x04, 0xe5, 0xc6, 0x14, 0x2b, 0x03, 0xd4, 0xc2, + 0xfd, 0xfb, 0x10, 0xc2, 0x0b, 0xd3, 0xfe, 0x2f, 0xec, 0x16, 0xfc, 0x32, 0xdf, + 0xfe, 0xe1, 0x0b, 0xf7, 0x42, 0xfc, 0xf7, 0xc8, 0xc0, 0x38, 0xed, 0xc9, 0xd5, + 0x43, 0xf6, 0xd6, 0xc5, 0xcc, 0xf8, 0xd0, 0x20, 0xf9, 0xe2, 0x30, 0xf4, 0x27, + 0x20, 0x0d, 0x5b, 0x13, 0xe0, 0x01, 0x18, 0xe9, 0xff, 0xde, 0x00, 0x44, 0xea, + 0xdd, 0x11, 0xf8, 0x05, 0x01, 0xfb, 0x3c, 0x0e, 0xe6, 0xf2, 0xba, 0x00, 0xfa, + 0x09, 0x0d, 0x03, 0xcf, 0xec, 0x3c, 0x12, 0x05, 0xc5, 0x07, 0xd6, 0xf7, 0x2c, + 0xf3, 0x2a, 0xe9, 0x18, 0xef, 0xe4, 0x0e, 0xd0, 0x8e, 0x1c, 0xb9, 0x2b, 0xa7, + 0x1f, 0xe6, 0xfc, 0xb9, 0x54, 0xda, 0x2b, 0xd8, 0xd2, 0xee, 0xfd, 0x7f, 0x0f, + 0xfc, 0xae, 0xc7, 0xd8, 0xfd, 0x0a, 0xa7, 0xdf, 0xc9, 0x0d, 0xf8, 0xe6, 0x21, + 0x01, 0x23, 0x0b, 0x28, 0xb5, 0x30, 0xdf, 0x4e, 0xc1, 0x42, 0x37, 0xd0, 0xd1, + 0x15, 0xfc, 0xfd, 0x48, 0x24, 0xd8, 0xd3, 0x46, 0x0f, 0x2e, 0x37, 0xb9, 0xde, + 0xc3, 0x9f, 0x4b, 0x29, 0x13, 0x04, 0xc8, 0x0c, 0xdc, 0x8d, 0x47, 0x18, 0x0d, + 0x3f, 0xb9, 0x42, 0xfe, 0x17, 0x40, 0xcb, 0xd0, 0x4a, 0x0d, 0xcc, 0x05, 0x0f, + 0xd5, 0x74, 0x5f, 0x3e, 0xba, 0xcf, 0xe9, 0xf9, 0x92, 0xd7, 0xf3, 0x13, 0x28, + 0x1a, 0xbf, 0xf7, 0xcd, 0xeb, 0x32, 0x48, 0x0f, 0xcf, 0x2e, 0xec, 0x4d, 0x04, + 0x3a, 0xe1, 0xff, 0x1f, 0x29, 0xb4, 0xf6, 0xe6, 0x26, 0x0d, 0x99, 0xae, 0xbb, + 0xed, 0xfa, 0xbd, 0xea, 0xd3, 0x09, 0x57, 0x1b, 0x0f, 0x10, 0x00, 0xb0, 0x38, + 0xf8, 0xfe, 0xdf, 0xff, 0x1a, 0xd2, 0x66, 0xe5, 0x22, 0x22, 0xfe, 0xe7, 0xe2, + 0xfb, 0x7f, 0x10, 0xd2, 0xf4, 0x42, 0x59, 0x63, 0xc7, 0x52, 0x0b, 0x0c, 0xf5, + 0xda, 0x04, 0xc7, 0x09, 0xe2, 0xfb, 0xf0, 0xf7, 0x23, 0x1e, 0xb7, 0x65, 0xf2, + 0xec, 0xf5, 0x10, 0xd6, 0xae, 0xff, 0x30, 0xd0, 0x2e, 0x14, 0xc9, 0x30, 0xec, + 0x2f, 0xdd, 0xea, 0xf2, 0x39, 0x0d, 0xf0, 0xfd, 0x0e, 0x08, 0x33, 0x00, 0x05, + 0xe3, 0x01, 0x21, 0xba, 0x1f, 0xf3, 0xea, 0xe1, 0x19, 0xa8, 0xea, 0xbf, 0xf6, + 0xb2, 0x17, 0x39, 0x0f, 0x25, 0x29, 0x3f, 0x2f, 0x12, 0x0a, 0x3a, 0xdd, 0x37, + 0x26, 0xed, 0x51, 0xeb, 0xdc, 0xdd, 0x27, 0x02, 0xfe, 0x38, 0x31, 0xcc, 0xb3, + 0x17, 0x15, 0xc9, 0xea, 0xea, 0x19, 0x08, 0xf7, 0x25, 0x02, 0xdc, 0xc6, 0xd2, + 0xe8, 0x32, 0xe9, 0xe8, 0x01, 0x38, 0xc8, 0xea, 0x30, 0xdb, 0x1c, 0x05, 0x21, + 0xca, 0x9d, 0x2c, 0x1e, 0xe2, 0xa6, 0x5e, 0x68, 0xb6, 0x14, 0xee, 0xe5, 0x05, + 0x1a, 0xf7, 0xb0, 0x1c, 0xd5, 0x16, 0xcb, 0x29, 0x23, 0xe4, 0x03, 0x03, 0xd9, + 0xee, 0xb8, 0xf7, 0x4a, 0x1d, 0xc8, 0xd1, 0x70, 0x14, 0x1d, 0xf0, 0x35, 0xb7, + 0x97, 0xfd, 0x81, 0x28, 0xb7, 0x46, 0xe7, 0x10, 0x42, 0xf5, 0x2b, 0x17, 0xd5, + 0x2b, 0xb7, 0xcf, 0x60, 0xfa, 0xe4, 0xf3, 0xf2, 0xd3, 0x19, 0xc8, 0xb5, 0xda, + 0xea, 0x4f, 0x04, 0xd5, 0xe0, 0x47, 0x69, 0x4c, 0x3c, 0xe8, 0x40, 0x00, 0xc2, + 0x40, 0x99, 0xf4, 0x0a, 0x2e, 0xe6, 0xdb, 0x1d, 0x00, 0x8b, 0x0f, 0xd8, 0xfb, + 0x1d, 0x13, 0xf8, 0x36, 0x2b, 0x28, 0xfe, 0xe6, 0xc6, 0x78, 0xbc, 0x12, 0xea, + 0xa2, 0xf7, 0x26, 0x0d, 0x15, 0x31, 0x2e, 0x0a, 0xd4, 0x0f, 0xf2, 0x64, 0x37, + 0x45, 0xa7, 0xf1, 0x2a, 0xdf, 0xe8, 0x0e, 0xd8, 0xac, 0x33, 0x1f, 0xe1, 0xc3, + 0x06, 0xf5, 0x27, 0x00, 0x27, 0xd7, 0xc6, 0x23, 0xbc, 0x29, 0x31, 0xe2, 0x29, + 0xe6, 0x3f, 0xda, 0x35, 0xb8, 0x18, 0x46, 0x4b, 0x78, 0x4b, 0x24, 0xfd, 0xf8, + 0x2e, 0x11, 0x50, 0xb0, 0xe1, 0xf8, 0x5b, 0x0a, 0xf5, 0x0e, 0x18, 0xba, 0xce, + 0x1a, 0x72, 0xc4, 0x06, 0xf2, 0x0c, 0x10, 0x7e, 0xc5, 0x28, 0x55, 0xfe, 0x08, + 0xe8, 0x22, 0x9d, 0x0c, 0xcb, 0x7f, 0xb3, 0xe5, 0xe6, 0xd3, 0xa0, 0xab, 0xc6, + 0xbd, 0xfe, 0x1a, 0x15, 0xf1, 0x44, 0xfe, 0xe8, 0x1e, 0x13, 0xef, 0x11, 0xc6, + 0x4d, 0x66, 0x0d, 0xde, 0xd5, 0x41, 0xf5, 0x9b, 0x7c, 0x2c, 0x1a, 0x51, 0x08, + 0xce, 0xdf, 0xec, 0x4e, 0x4b, 0x2c, 0xfa, 0x3c, 0x09, 0xac, 0xea, 0xd0, 0x2c, + 0xfc, 0x06, 0x0f, 0x0d, 0x3b, 0xd1, 0x10, 0x12, 0x5f, 0xdb, 0x12, 0xfe, 0x01, + 0xeb, 0xcb, 0xe7, 0xb3, 0x29, 0xdd, 0xf7, 0x14, 0x0b, 0x02, 0x12, 0xe1, 0xf9, + 0x05, 0x5f, 0xfb, 0x0a, 0xed, 0xe9, 0xcd, 0x04, 0x14, 0x1a, 0xe7, 0x40, 0x1c, + 0xab, 0xfc, 0x48, 0xf4, 0x0c, 0xfc, 0xfd, 0x00, 0x0e, 0x27, 0x1c, 0x2f, 0x29, + 0x09, 0x08, 0x08, 0xf9, 0xea, 0x2e, 0x0b, 0x1f, 0x06, 0xe8, 0xe2, 0xdd, 0xff, + 0x19, 0x21, 0x55, 0x03, 0xed, 0x4d, 0xcc, 0x64, 0x09, 0x64, 0x06, 0x57, 0x11, + 0xcb, 0x08, 0xd1, 0x7d, 0x28, 0x23, 0xf9, 0x39, 0x17, 0xed, 0x0c, 0xda, 0xe0, + 0x08, 0xf4, 0x06, 0xed, 0x21, 0x06, 0xda, 0x3d, 0x1d, 0x01, 0x28, 0xec, 0xc7, + 0x2a, 0x1d, 0x1a, 0x4d, 0x2f, 0xb4, 0xf8, 0x0c, 0xe2, 0x07, 0x02, 0xd5, 0x0c, + 0xe3, 0x25, 0x03, 0x31, 0x41, 0xf8, 0xeb, 0xed, 0xe8, 0xd3, 0x1c, 0xb0, 0x12, + 0x05, 0x81, 0x26, 0x10, 0x02, 0x3d, 0x4a, 0xf3, 0xdf, 0x4e, 0xf4, 0x16, 0x27, + 0xf3, 0xee, 0xe1, 0xac, 0xd4, 0xbe, 0x1c, 0x18, 0xe9, 0x4d, 0xf9, 0xd4, 0xca, + 0x3b, 0xe7, 0xde, 0x20, 0xf3, 0x07, 0x0f, 0x07, 0xe6, 0xfe, 0xf1, 0xc5, 0x64, + 0xe4, 0x01, 0x06, 0x10, 0xff, 0xe8, 0x22, 0x1e, 0x34, 0xee, 0x47, 0x15, 0x25, + 0xbc, 0xee, 0x4d, 0x2b, 0xf6, 0xe5, 0x17, 0xc6, 0x37, 0x05, 0x13, 0x84, 0x05, + 0x1e, 0x0d, 0x0d, 0xee, 0xcf, 0x4e, 0x4a, 0xdf, 0xd7, 0xf2, 0x06, 0xfa, 0x90, + 0xd0, 0x72, 0xdc, 0xcc, 0xbc, 0x08, 0x0a, 0xa6, 0xb7, 0xf0, 0xcc, 0x13, 0xbe, + 0x5c, 0x3e, 0x08, 0x0e, 0x14, 0x02, 0x30, 0xdf, 0x3b, 0x4a, 0x13, 0xf0, 0x2f, + 0x27, 0x02, 0xdf, 0x27, 0x24, 0x23, 0xfe, 0x10, 0x08, 0x69, 0x3f, 0xbb, 0xfc, + 0x6d, 0x3d, 0x28, 0xed, 0xed, 0xed, 0x3a, 0xe3, 0xda, 0x81, 0x14, 0xd6, 0xe3, + 0xd6, 0xc5, 0xec, 0x37, 0x38, 0x25, 0x1c, 0xe7, 0x0a, 0x1b, 0x16, 0xe9, 0xfa, + 0xf4, 0xe6, 0x0b, 0x07, 0x22, 0x12, 0x16, 0xf4, 0x0a, 0xd1, 0xfe, 0x06, 0xdd, + 0xe3, 0xfa, 0x0e, 0x14, 0x25, 0x05, 0xed, 0x44, 0xf6, 0xd1, 0xeb, 0xfd, 0xf5, + 0x19, 0xe9, 0xe8, 0x1b, 0x0d, 0xed, 0x0b, 0x1c, 0x33, 0xec, 0xeb, 0xe5, 0x08, + 0x09, 0x25, 0x09, 0xe6, 0xf3, 0x01, 0x38, 0x00, 0x0d, 0x11, 0x05, 0x17, 0x0a, + 0x08, 0x08, 0xfb, 0x7f, 0xe8, 0x02, 0xff, 0x1c, 0x4d, 0xe8, 0xf9, 0xd3, 0x0f, + 0x21, 0xdb, 0xda, 0x17, 0xca, 0xf6, 0x1f, 0x07, 0x00, 0x09, 0x0d, 0xfb, 0x34, + 0x0e, 0x01, 0xfa, 0xd8, 0xf5, 0x23, 0x00, 0x48, 0x14, 0xfd, 0x0d, 0x20, 0x0d, + 0xf3, 0x03, 0x01, 0x1b, 0xf5, 0x2f, 0xf4, 0xe7, 0xe9, 0xdf, 0xb7, 0xd3, 0x1e, + 0x41, 0x0a, 0xe6, 0x18, 0xe6, 0xf7, 0xfa, 0x0f, 0x2b, 0x01, 0xe5, 0xcb, 0x27, + 0xfc, 0xf6, 0x07, 0xe0, 0xed, 0xe6, 0x12, 0xe1, 0xd9, 0xf2, 0xec, 0x19, 0x18, + 0xf3, 0xf9, 0x16, 0xd3, 0x00, 0x0b, 0x19, 0xee, 0x23, 0x02, 0x1e, 0xec, 0xfe, + 0xfd, 0xee, 0x07, 0x03, 0xe6, 0x00, 0xd9, 0xe4, 0x19, 0x07, 0x02, 0xfb, 0xf1, + 0xda, 0xbf, 0xe6, 0xd1, 0xf7, 0xf5, 0xc8, 0x14, 0x08, 0x04, 0xed, 0x7f, 0x01, + 0xd7, 0x48, 0x02, 0x0a, 0x4f, 0x05, 0xdb, 0x0d, 0x39, 0x1d, 0x00, 0xf0, 0xe6, + 0x02, 0x17, 0xd9, 0x21, 0xf4, 0xf1, 0x36, 0xe8, 0xe1, 0x07, 0xa2, 0xfc, 0xe3, + 0xf7, 0x05, 0x1c, 0x19, 0xf0, 0x19, 0x19, 0xe6, 0xe3, 0x03, 0x08, 0x1e, 0xe2, + 0x26, 0x17, 0xeb, 0x0e, 0x17, 0x33, 0xe3, 0x14, 0xef, 0xf3, 0xd6, 0xfb, 0xe3, + 0x2a, 0xd7, 0x0d, 0x16, 0x0b, 0x05, 0xf4, 0xe7, 0xf6, 0x28, 0xf3, 0x05, 0xde, + 0xab, 0xf3, 0xeb, 0xf7, 0xd2, 0xd0, 0x14, 0xfb, 0xfc, 0x0b, 0x1b, 0x18, 0xe8, + 0x14, 0x27, 0xfe, 0x3b, 0x19, 0x0a, 0xc0, 0x18, 0xef, 0x01, 0x2d, 0x04, 0x10, + 0x26, 0x33, 0x3b, 0xef, 0x20, 0xeb, 0xfc, 0x0e, 0xc7, 0x1c, 0x12, 0x22, 0xeb, + 0x23, 0xe2, 0x4f, 0x00, 0x32, 0xc3, 0x0d, 0x27, 0xb4, 0xf5, 0xca, 0xd1, 0xdf, + 0x2b, 0x8e, 0xc5, 0xe7, 0xf2, 0x15, 0xf7, 0x3c, 0xac, 0xba, 0x17, 0xec, 0xfb, + 0x0a, 0x0a, 0xc5, 0x3f, 0x93, 0x3e, 0x1c, 0xe9, 0xf3, 0xff, 0xd7, 0x2e, 0xcb, + 0x04, 0x1a, 0x1e, 0x18, 0xfa, 0x0d, 0x18, 0xdd, 0xf1, 0x55, 0x15, 0x60, 0xb8, + 0x2e, 0xd1, 0x11, 0x0b, 0x64, 0x02, 0xa6, 0x0f, 0x12, 0x06, 0x19, 0x08, 0xd9, + 0xec, 0xf5, 0xee, 0x05, 0x81, 0x5e, 0xc6, 0x16, 0x0b, 0x08, 0xf0, 0xec, 0xde, + 0x12, 0xf4, 0xe6, 0x63, 0xff, 0x22, 0xd8, 0xf3, 0xfb, 0x1c, 0xe6, 0x2d, 0x14, + 0x0b, 0x1c, 0x08, 0xb7, 0xee, 0xe9, 0x1f, 0xe4, 0x12, 0x19, 0x18, 0x09, 0xcf, + 0xcc, 0xb0, 0x21, 0xf9, 0xda, 0x08, 0x01, 0x38, 0xe7, 0x37, 0xe5, 0x04, 0xfc, + 0x30, 0x05, 0xec, 0x58, 0x12, 0x20, 0xfd, 0x11, 0x0a, 0xe7, 0x28, 0xfb, 0x01, + 0xe7, 0xec, 0xde, 0x49, 0x21, 0xf4, 0xfc, 0x19, 0x0f, 0xa5, 0xf2, 0xd2, 0xec, + 0xf4, 0x47, 0xd6, 0xc7, 0xb6, 0x5d, 0xf7, 0x0e, 0xc1, 0x36, 0xed, 0x16, 0x25, + 0xd7, 0xe6, 0x05, 0x14, 0x40, 0x3d, 0x01, 0xee, 0xdf, 0x35, 0x5c, 0xe2, 0x0a, + 0x3c, 0xf5, 0xe8, 0x0a, 0x33, 0x09, 0x2b, 0xc2, 0x03, 0x3c, 0xfe, 0xfd, 0x39, + 0xdc, 0x03, 0x12, 0xf6, 0x14, 0x07, 0xf0, 0xd8, 0x2a, 0xe0, 0x34, 0x0e, 0x13, + 0x0e, 0xfc, 0x0d, 0x39, 0x1c, 0xe3, 0x04, 0x25, 0xfd, 0x1c, 0x1d, 0xdb, 0x25, + 0xdd, 0x4a, 0x06, 0x0f, 0x0e, 0x11, 0xe4, 0x1f, 0xd6, 0xf0, 0x23, 0xec, 0x10, + 0xf5, 0x87, 0xb0, 0x36, 0xf7, 0x19, 0x2b, 0x1a, 0xbc, 0x04, 0x81, 0xdc, 0xd0, + 0xd4, 0xd7, 0x37, 0x09, 0xe8, 0xc0, 0xcc, 0x30, 0xf9, 0x25, 0xd4, 0x9f, 0x09, + 0x2c, 0xf8, 0x15, 0x71, 0x01, 0xfe, 0x20, 0xeb, 0x0a, 0xd9, 0x22, 0xe4, 0xfc, + 0x4e, 0x15, 0xef, 0xfe, 0x11, 0x3b, 0xf9, 0x1c, 0xc8, 0xec, 0xf2, 0x08, 0xf3, + 0xda, 0x24, 0xdf, 0xe4, 0x1e, 0x56, 0xfd, 0xc8, 0xf9, 0x1a, 0xec, 0xcb, 0xbb, + 0x3e, 0xfe, 0xdf, 0x4e, 0x12, 0x1d, 0x6f, 0xac, 0x01, 0x2e, 0x2f, 0xe2, 0xd3, + 0xf1, 0x05, 0xdd, 0xc4, 0xdc, 0xdd, 0xf1, 0x03, 0x0e, 0xd0, 0xdb, 0xbb, 0xb6, + 0x13, 0x42, 0x2b, 0x1b, 0x45, 0xf5, 0x16, 0xad, 0xc7, 0xf6, 0x28, 0xc5, 0xe9, + 0x45, 0x3d, 0xbd, 0x08, 0x03, 0x02, 0x86, 0x26, 0x1c, 0x2b, 0x7f, 0xf2, 0xcb, + 0xf9, 0xbd, 0x60, 0x04, 0x37, 0x37, 0xdf, 0xd6, 0x00, 0x09, 0x22, 0x17, 0x01, + 0x32, 0xd0, 0xcf, 0x3f, 0x35, 0x7b, 0x36, 0x1e, 0xcb, 0x08, 0xe9, 0x20, 0xd9, + 0x39, 0x3c, 0x20, 0x4d, 0xa2, 0x1c, 0xe4, 0xef, 0xf7, 0xd7, 0x05, 0xfe, 0xc0, + 0xe8, 0x3a, 0xff, 0x0f, 0xf2, 0xec, 0x0a, 0xe6, 0x00, 0x2f, 0xe5, 0x19, 0xa6, + 0xf1, 0xd4, 0xef, 0xd5, 0x29, 0xa5, 0x31, 0x02, 0x9c, 0xf9, 0x04, 0x08, 0xac, + 0xfb, 0xf9, 0xe1, 0xea, 0xe8, 0xd1, 0xe8, 0xe0, 0x2d, 0xb8, 0xd7, 0xde, 0x2f, + 0xc1, 0xf7, 0x0e, 0x07, 0xe8, 0x06, 0xb1, 0x4a, 0x42, 0xd1, 0x9e, 0xcf, 0x21, + 0x98, 0x7f, 0xef, 0x23, 0x30, 0xff, 0xee, 0xc5, 0xc3, 0x2d, 0x06, 0xc4, 0x34, + 0x00, 0x41, 0xb3, 0x07, 0x52, 0xf7, 0x24, 0x14, 0xee, 0xfe, 0xde, 0xf2, 0xae, + 0x11, 0xef, 0xe7, 0x21, 0xde, 0x26, 0x19, 0x1a, 0x14, 0xfb, 0xb5, 0x36, 0xcc, + 0x36, 0xf8, 0x01, 0xb9, 0xe7, 0x07, 0xe2, 0x61, 0x02, 0x3e, 0x14, 0x20, 0xd4, + 0x09, 0xf9, 0xc8, 0xe2, 0xf6, 0x11, 0x1f, 0x30, 0xd0, 0xfb, 0xfa, 0x31, 0x50, + 0x6b, 0xdb, 0xf3, 0x2d, 0xf5, 0xf1, 0xb1, 0x36, 0x00, 0xf9, 0xee, 0x01, 0x14, + 0x36, 0xe1, 0x19, 0xea, 0xea, 0xeb, 0x2d, 0x25, 0x06, 0xb4, 0x47, 0x48, 0xcf, + 0x2f, 0x00, 0xdc, 0x14, 0xd3, 0x95, 0xe1, 0x1f, 0x1b, 0xb6, 0xfe, 0xc8, 0xdf, + 0xa8, 0xc0, 0xff, 0x06, 0xca, 0xd4, 0x05, 0x07, 0x07, 0xcc, 0xa7, 0xb2, 0xca, + 0x5a, 0x7f, 0x22, 0x09, 0xc1, 0xaf, 0xaf, 0xf9, 0xf2, 0xcb, 0xde, 0x04, 0x07, + 0x91, 0x95, 0x6c, 0xd8, 0xc7, 0xaf, 0xba, 0x0a, 0xe8, 0x33, 0x35, 0x0c, 0x06, + 0xaf, 0xf7, 0xd6, 0x46, 0x39, 0xeb, 0xf2, 0x62, 0x26, 0x02, 0xec, 0x14, 0x17, + 0xee, 0x52, 0x5a, 0x1e, 0xe8, 0xe4, 0x06, 0x18, 0x12, 0x42, 0x0d, 0x42, 0xdb, + 0x23, 0xca, 0x0e, 0xfe, 0x0a, 0xfe, 0xd6, 0x23, 0xf1, 0x2c, 0x7e, 0xee, 0xae, + 0xa2, 0x33, 0x82, 0xc3, 0xe3, 0x00, 0xf0, 0xff, 0xd7, 0xd0, 0xd3, 0xf1, 0xbe, + 0x4c, 0x4f, 0xe8, 0x48, 0x0c, 0xa2, 0xdd, 0x42, 0x21, 0xc9, 0x2b, 0x8c, 0x11, + 0xf6, 0x1b, 0xcf, 0x5a, 0xd0, 0x30, 0xd4, 0x1d, 0x34, 0xf0, 0xf9, 0xcb, 0xef, + 0xb7, 0xda, 0xf5, 0x2a, 0xeb, 0xce, 0x1a, 0x8a, 0xda, 0xff, 0x78, 0xd3, 0x01, + 0x3c, 0xea, 0xf4, 0xe2, 0x34, 0x81, 0x04, 0xa4, 0x1c, 0x1a, 0x12, 0xb6, 0x62, + 0xbd, 0x11, 0xa1, 0xf3, 0x37, 0x51, 0xb7, 0x2f, 0x05, 0xd2, 0xed, 0xac, 0x44, + 0x07, 0xdf, 0x1c, 0x0f, 0xf3, 0xcf, 0xf1, 0x2d, 0xc1, 0xc0, 0xd8, 0x0b, 0x47, + 0xf9, 0x42, 0xde, 0x1d, 0x05, 0x02, 0xfd, 0x02, 0x0a, 0xae, 0x45, 0x12, 0x0f, + 0xc8, 0x29, 0xbb, 0xc0, 0x07, 0xe3, 0xd3, 0x32, 0xeb, 0x4f, 0xc7, 0x58, 0x63, + 0x96, 0xe3, 0x7b, 0xc6, 0xff, 0xe2, 0xf4, 0x48, 0x53, 0xf0, 0xda, 0x0a, 0xd4, + 0xd4, 0x19, 0x63, 0xf9, 0x0f, 0x16, 0x26, 0x1f, 0xec, 0xff, 0x18, 0x7f, 0x1e, + 0x0b, 0x13, 0x31, 0xfe, 0xf8, 0x1a, 0xec, 0x28, 0xe7, 0xcc, 0xf1, 0xe1, 0xd3, + 0xfd, 0x0e, 0xdd, 0xef, 0xeb, 0xf0, 0xae, 0x00, 0xc9, 0x10, 0xf1, 0xf4, 0xc7, + 0x16, 0x51, 0xdf, 0xe1, 0x0e, 0xef, 0x0e, 0x0b, 0x1b, 0xd4, 0xd8, 0xdb, 0xc4, + 0x21, 0xdf, 0xe5, 0xea, 0x5a, 0xe9, 0x26, 0x4f, 0x1e, 0x1e, 0x13, 0x24, 0x34, + 0x3f, 0xb9, 0xfb, 0xf3, 0xe8, 0x3d, 0x40, 0x06, 0x0b, 0x1c, 0xf0, 0x2b, 0x26, + 0xe7, 0x14, 0x18, 0xff, 0x40, 0xeb, 0x0b, 0xd6, 0x12, 0xc1, 0x45, 0xda, 0xfc, + 0x0b, 0x25, 0x14, 0x3d, 0xe9, 0xf8, 0x08, 0x52, 0x15, 0xf9, 0x01, 0xa7, 0xe4, + 0xc3, 0xee, 0xfa, 0xe3, 0x10, 0x17, 0xef, 0xea, 0x05, 0x1b, 0x0c, 0xec, 0x0a, + 0x39, 0xf1, 0xdf, 0xe3, 0xb8, 0xdb, 0xfb, 0x2a, 0xd9, 0xc8, 0x39, 0x0b, 0x1b, + 0xe0, 0xf4, 0x0e, 0xf0, 0x43, 0xb3, 0x13, 0xcd, 0xfd, 0xd0, 0xdb, 0x03, 0xe6, + 0xe4, 0xf4, 0xf1, 0xf8, 0x36, 0x01, 0x0f, 0xfe, 0x15, 0x0f, 0xf3, 0x0e, 0x35, + 0xfe, 0x04, 0xd3, 0xca, 0x00, 0xd4, 0xd9, 0x2e, 0x16, 0x48, 0x33, 0x25, 0xbc, + 0x14, 0x23, 0xf3, 0xaa, 0xec, 0xc6, 0xea, 0x08, 0x7f, 0xc1, 0x04, 0x27, 0x0e, + 0xfb, 0x54, 0xad, 0x08, 0xea, 0x1a, 0xfb, 0xe0, 0xcc, 0xf3, 0xd6, 0xd6, 0x50, + 0x20, 0xe7, 0x0a, 0xdc, 0x24, 0x05, 0xeb, 0xd4, 0xbe, 0xdf, 0xe6, 0x12, 0x0a, + 0xfc, 0x1d, 0xe7, 0xca, 0x10, 0xf9, 0x02, 0xde, 0xe9, 0xc1, 0xe3, 0xd6, 0x1f, + 0x02, 0xec, 0xda, 0x1f, 0xd3, 0x05, 0x21, 0xd8, 0x22, 0xfb, 0x11, 0x0e, 0x32, + 0x40, 0xdc, 0x05, 0xeb, 0xca, 0x31, 0x26, 0xd4, 0xf8, 0xfa, 0xf6, 0x0f, 0xcd, + 0xd3, 0x1c, 0x5f, 0xd7, 0xda, 0xee, 0x3a, 0x26, 0x14, 0xe5, 0xe0, 0xeb, 0xfa, + 0xf6, 0x0e, 0x17, 0x2d, 0xca, 0xad, 0x4d, 0x32, 0xe2, 0xfe, 0x3a, 0xed, 0xda, + 0x17, 0xde, 0xba, 0xf2, 0x2b, 0xf0, 0x0c, 0xe0, 0xca, 0x0a, 0x38, 0x04, 0x25, + 0xe9, 0x0e, 0xd2, 0x52, 0xd5, 0x20, 0x2f, 0xe5, 0x4c, 0x1d, 0x1f, 0x11, 0xdc, + 0x34, 0x3c, 0x34, 0x1f, 0xe2, 0x24, 0x0b, 0xf8, 0x25, 0x35, 0xe0, 0xf1, 0x97, + 0xf3, 0x1a, 0xfb, 0x02, 0x4b, 0xeb, 0x2c, 0x32, 0xea, 0x3e, 0xdd, 0x14, 0x2c, + 0xf2, 0x12, 0x24, 0xc7, 0xe4, 0x47, 0x67, 0x32, 0x81, 0x0e, 0x03, 0x40, 0x39, + 0x4f, 0x33, 0x15, 0x12, 0xe2, 0x26, 0xc7, 0xf9, 0x09, 0xff, 0x22, 0x3f, 0xf3, + 0x01, 0xab, 0x15, 0xd1, 0x31, 0xdf, 0xd6, 0xdf, 0x24, 0xe4, 0x10, 0x04, 0x5e, + 0x19, 0xe0, 0x09, 0xfe, 0x39, 0x10, 0x23, 0x7e, 0x17, 0x1e, 0xc7, 0xa6, 0x22, + 0x0b, 0x3f, 0x11, 0xf3, 0x05, 0x3c, 0x1b, 0x40, 0x0e, 0x44, 0xf4, 0x0d, 0x1c, + 0x0d, 0xdb, 0xe0, 0xe0, 0x30, 0x1a, 0xf6, 0xf4, 0x20, 0x4d, 0x3c, 0x01, 0xff, + 0x09, 0xd6, 0x02, 0xe8, 0x12, 0xe7, 0xde, 0xc6, 0x19, 0xe3, 0x15, 0x1e, 0x11, + 0xda, 0xca, 0x46, 0x07, 0xe9, 0xba, 0x1a, 0x1d, 0xec, 0xd5, 0xfc, 0x31, 0x18, + 0x0e, 0x55, 0x04, 0xe5, 0xd4, 0x02, 0x0c, 0xfe, 0xfe, 0xc6, 0x2c, 0xfe, 0xa2, + 0xed, 0xe7, 0x25, 0xe4, 0xfe, 0xf5, 0x55, 0x1d, 0xe7, 0x7f, 0xe6, 0x00, 0xeb, + 0x00, 0xfb, 0xde, 0xe5, 0x0a, 0xa8, 0x36, 0xe7, 0x26, 0xf4, 0xb7, 0xf7, 0x4d, + 0x05, 0xfc, 0xc3, 0xfd, 0xec, 0xfb, 0xe4, 0xfc, 0xfe, 0xe4, 0xfc, 0x20, 0xe3, + 0xd6, 0x1b, 0xf2, 0x46, 0xe8, 0x3b, 0x03, 0xe2, 0x4b, 0xec, 0x0e, 0x37, 0x14, + 0xf9, 0x2e, 0xde, 0xd6, 0x3b, 0xdf, 0x14, 0xd6, 0xec, 0x3e, 0x24, 0xeb, 0xd3, + 0xc8, 0xd6, 0x3c, 0xfd, 0xf8, 0xe9, 0xde, 0x11, 0xed, 0x08, 0x16, 0x08, 0xe4, + 0xd4, 0x0f, 0xbb, 0xe4, 0x1e, 0x1f, 0xe5, 0xd9, 0xdb, 0x31, 0x03, 0xff, 0x0d, + 0xf8, 0x3e, 0x0a, 0x7f, 0x67, 0xe0, 0xdb, 0xf6, 0x09, 0x01, 0x57, 0xf5, 0xe8, + 0x04, 0x0f, 0xed, 0x11, 0xfe, 0xe0, 0x24, 0x04, 0xfb, 0xe0, 0x28, 0xc3, 0xe0, + 0x09, 0x03, 0x41, 0xf3, 0xd7, 0xde, 0x2b, 0x21, 0xc6, 0xe7, 0x1c, 0x38, 0xe3, + 0xb8, 0xed, 0x18, 0x3b, 0x25, 0xaf, 0xfb, 0xe1, 0xd0, 0xd5, 0xf7, 0x25, 0x16, + 0xfb, 0xbf, 0xed, 0x29, 0xf4, 0x1e, 0xdc, 0xf4, 0xb8, 0x20, 0x32, 0xe6, 0xe7, + 0x11, 0xec, 0xe7, 0xff, 0x43, 0x12, 0x01, 0xf5, 0x92, 0x0e, 0xef, 0x10, 0xd3, + 0x19, 0xdf, 0xfe, 0x32, 0xf5, 0xf1, 0xf7, 0x21, 0xc6, 0x36, 0x1a, 0xf4, 0x1f, + 0xd6, 0xf4, 0xf4, 0xf4, 0xd4, 0x01, 0x17, 0x17, 0x07, 0xf6, 0x1f, 0x33, 0xf9, + 0xd2, 0x0f, 0xe7, 0x13, 0x15, 0x2f, 0xd4, 0x1c, 0xe2, 0xf0, 0x38, 0x1f, 0xfd, + 0x39, 0xee, 0xe4, 0x18, 0x14, 0xdc, 0xc0, 0xe1, 0xea, 0x20, 0xbf, 0x06, 0xda, + 0x38, 0x0c, 0xb9, 0x15, 0x0c, 0xf3, 0x27, 0xde, 0xc2, 0x18, 0xee, 0xf6, 0x1a, + 0xdf, 0x1b, 0xbc, 0x3b, 0x01, 0x6a, 0xdf, 0xeb, 0xd3, 0xc7, 0x06, 0xff, 0x58, + 0xf5, 0xbd, 0x32, 0x0c, 0xcc, 0xe2, 0x2c, 0x37, 0x9d, 0x1e, 0x0d, 0x91, 0x4a, + 0xc9, 0xb6, 0x4a, 0xc4, 0x12, 0xbd, 0xce, 0xed, 0x43, 0x15, 0x22, 0x10, 0x54, + 0xe5, 0xd2, 0x57, 0xd3, 0xe7, 0xb9, 0x18, 0x2a, 0x13, 0x43, 0xa2, 0x39, 0xec, + 0x01, 0xb0, 0x03, 0x56, 0x10, 0xf8, 0xb5, 0xfb, 0x2a, 0xbb, 0x58, 0xc4, 0x18, + 0x2f, 0xd0, 0xac, 0xfa, 0xeb, 0x04, 0xf4, 0x66, 0xfb, 0x00, 0xae, 0xb8, 0xef, + 0x52, 0x81, 0x1d, 0xef, 0xcc, 0x1a, 0x16, 0x26, 0xce, 0x20, 0x0b, 0x3f, 0x01, + 0x2c, 0xf5, 0xf1, 0xf8, 0x12, 0xec, 0xfd, 0x55, 0xf9, 0x90, 0xdd, 0x35, 0xf9, + 0xf2, 0xe2, 0x12, 0xc9, 0x0c, 0xe2, 0x0c, 0xfe, 0xd6, 0x16, 0x41, 0xe4, 0xea, + 0xce, 0x07, 0xff, 0xdb, 0x37, 0xd6, 0xd3, 0xc7, 0xd9, 0x0c, 0x11, 0x06, 0x3c, + 0x4b, 0xfc, 0x09, 0x8f, 0xd1, 0x19, 0x28, 0xfa, 0x26, 0xcc, 0xf5, 0x1b, 0x7f, + 0x08, 0x12, 0xde, 0xce, 0xd0, 0xc8, 0xc3, 0xf8, 0x1f, 0x27, 0xd2, 0x09, 0x55, + 0xbc, 0x3e, 0xc6, 0x0e, 0xcf, 0x43, 0x34, 0xbf, 0xb3, 0xe4, 0xdd, 0x0b, 0xa6, + 0x9a, 0x93, 0x7b, 0x13, 0x68, 0xff, 0x15, 0x14, 0xfe, 0x1c, 0x49, 0x38, 0xaf, + 0x46, 0xd6, 0x1c, 0x12, 0x18, 0x34, 0x10, 0xff, 0xc5, 0xe8, 0x37, 0xfe, 0xa2, + 0x00, 0x0e, 0xfe, 0x1d, 0x29, 0x15, 0xd6, 0xb3, 0x11, 0x06, 0x24, 0x16, 0x23, + 0x97, 0xbf, 0xf2, 0x89, 0x09, 0xe1, 0xf5, 0x20, 0xc7, 0x01, 0xfc, 0xa3, 0x03, + 0x28, 0xf3, 0x10, 0x30, 0x34, 0x7f, 0xce, 0x54, 0xdf, 0x42, 0x29, 0xcc, 0x0d, + 0xb7, 0x03, 0xd3, 0xec, 0xe2, 0xf1, 0x03, 0xed, 0xd4, 0x30, 0x76, 0xe5, 0x24, + 0xe8, 0x3e, 0xfd, 0x65, 0x2d, 0xe5, 0xe8, 0xea, 0x13, 0x0e, 0x45, 0xf7, 0x1d, + 0xd6, 0x34, 0x23, 0x06, 0xb4, 0x25, 0x26, 0x53, 0xac, 0x18, 0xdf, 0xf4, 0x32, + 0x1a, 0x3f, 0xf6, 0x07, 0x18, 0x00, 0xf8, 0xa5, 0x0c, 0xfa, 0xf3, 0x3b, 0xd7, + 0x22, 0xb6, 0x65, 0xe4, 0xf9, 0x4c, 0x06, 0xc4, 0xf2, 0x05, 0x45, 0xe7, 0x3f, + 0x07, 0xf7, 0xea, 0x4b, 0xff, 0xb5, 0xbd, 0x53, 0xfa, 0xe9, 0xc5, 0xde, 0x6d, + 0x50, 0xc3, 0xfb, 0xc8, 0x06, 0x04, 0xcc, 0x13, 0x16, 0x14, 0xbd, 0xce, 0x18, + 0xc4, 0xee, 0xc0, 0xe4, 0xe2, 0xe5, 0xf9, 0x17, 0xb4, 0x25, 0x82, 0x1e, 0x3b, + 0x15, 0x13, 0x2e, 0xd8, 0x00, 0x3a, 0x18, 0xfc, 0xe6, 0xf7, 0xf2, 0xf0, 0xec, + 0x1b, 0x19, 0xf5, 0x3e, 0x86, 0x1e, 0x1a, 0x31, 0xc6, 0xf7, 0x01, 0x00, 0xf9, + 0x3d, 0x27, 0xfa, 0xd5, 0x0b, 0xef, 0x7f, 0x06, 0x26, 0xc3, 0xf5, 0xad, 0xe9, + 0x2a, 0x8b, 0x09, 0x7f, 0x21, 0x4f, 0x1d, 0xf0, 0x5e, 0x5b, 0xe0, 0xf7, 0x53, + 0x2a, 0x1e, 0xd7, 0xed, 0x09, 0x55, 0xda, 0xed, 0xcd, 0x25, 0x06, 0x05, 0x57, + 0xd8, 0xc8, 0x99, 0x01, 0xc7, 0xd3, 0x16, 0x20, 0x0f, 0x20, 0x03, 0xb3, 0xd2, + 0x28, 0x54, 0x0b, 0x5d, 0x25, 0xaa, 0x83, 0xa2, 0x71, 0x14, 0xdc, 0x63, 0x50, + 0xee, 0xf4, 0x33, 0x12, 0x06, 0x0d, 0x8e, 0xce, 0xd3, 0xbc, 0xf3, 0x08, 0x07, + 0xf0, 0x0c, 0xd3, 0x1d, 0xba, 0x0b, 0xd8, 0x30, 0x37, 0xdc, 0xc5, 0xce, 0xfe, + 0xbc, 0xee, 0xd0, 0xf2, 0xec, 0x38, 0xbf, 0xee, 0xcb, 0x2b, 0x78, 0xfb, 0x1b, + 0x19, 0xd6, 0xce, 0xdd, 0xfe, 0x34, 0x31, 0xf5, 0xd2, 0xfd, 0xc9, 0xf4, 0x0b, + 0xff, 0xf2, 0x52, 0xee, 0xd4, 0xbd, 0x91, 0xdc, 0xf9, 0x81, 0xf4, 0xbd, 0xcc, + 0xea, 0xe6, 0xe6, 0x12, 0x45, 0xcf, 0xef, 0xcc, 0x0c, 0xe2, 0x2d, 0x32, 0xca, + 0x36, 0xdd, 0x2c, 0x0e, 0x18, 0x18, 0x2b, 0x02, 0x14, 0x19, 0x1a, 0xf9, 0xfe, + 0x46, 0xf3, 0xb3, 0xd1, 0xed, 0xe6, 0x1e, 0xee, 0x35, 0x3e, 0xbb, 0x31, 0x91, + 0xdd, 0xd3, 0x40, 0x3a, 0x2d, 0xb9, 0x24, 0xb3, 0x49, 0xe4, 0xf2, 0xef, 0x32, + 0x27, 0xcb, 0xd3, 0x09, 0x12, 0x18, 0x08, 0xc3, 0xc0, 0x0b, 0xd3, 0xe0, 0x08, + 0xfa, 0x1a, 0xfe, 0xf0, 0x2b, 0xc1, 0x2b, 0x51, 0x23, 0x04, 0xc9, 0xed, 0xa8, + 0x10, 0xfe, 0x11, 0x07, 0x33, 0x12, 0xf6, 0x09, 0x40, 0x28, 0xf7, 0x05, 0xe9, + 0xe5, 0xeb, 0x49, 0x45, 0x08, 0x43, 0x26, 0xf9, 0xa9, 0x77, 0x00, 0x07, 0xaa, + 0xdd, 0xd1, 0xe4, 0xbe, 0xf0, 0x17, 0xfd, 0x47, 0xee, 0xf4, 0x19, 0x4e, 0xd5, + 0xb5, 0x24, 0xfa, 0x04, 0xfd, 0x2b, 0x04, 0xc2, 0x4b, 0x25, 0xed, 0x1f, 0xe1, + 0xfc, 0xb6, 0xeb, 0x30, 0xfa, 0x03, 0xf7, 0x33, 0x03, 0xd6, 0x1d, 0x10, 0x90, + 0xd2, 0xb8, 0x04, 0x17, 0xb6, 0x14, 0xe0, 0x27, 0xf4, 0x28, 0x15, 0xd3, 0xeb, + 0x24, 0x0b, 0x98, 0xb7, 0xc5, 0x63, 0xef, 0x1d, 0x02, 0xc1, 0x23, 0xaf, 0x75, + 0x24, 0xca, 0x17, 0xb6, 0xb8, 0x34, 0xcf, 0x2e, 0x1b, 0xd6, 0x47, 0xbe, 0x45, + 0xff, 0xdb, 0xff, 0xea, 0x45, 0xf3, 0x27, 0xb8, 0xff, 0xd2, 0xdc, 0x18, 0xb4, + 0xbe, 0xe5, 0xe3, 0xdf, 0xa9, 0xd6, 0xf6, 0xfb, 0xc1, 0xee, 0x09, 0x00, 0x28, + 0x8a, 0x24, 0x00, 0xe3, 0x81, 0xd7, 0x1d, 0xc1, 0xd6, 0x23, 0xad, 0x2c, 0xd1, + 0xa7, 0x01, 0xe6, 0x0b, 0xb0, 0x07, 0x00, 0x29, 0xfa, 0xc5, 0xd3, 0xd1, 0xcb, + 0xc6, 0x28, 0xe7, 0xb6, 0x20, 0x2d, 0xee, 0x00, 0x07, 0xc3, 0xf8, 0xf5, 0xf2, + 0xc3, 0x28, 0x2f, 0x1e, 0x34, 0xe3, 0xf0, 0xcf, 0xe1, 0xec, 0x2c, 0xdb, 0x0c, + 0x17, 0xe4, 0xfa, 0xd0, 0xfe, 0xed, 0x32, 0x0c, 0xdc, 0xdd, 0xe8, 0x4d, 0x10, + 0xfe, 0xe4, 0xfd, 0xf1, 0x03, 0xf7, 0xdd, 0xf6, 0xe5, 0xe7, 0x14, 0xc7, 0xfe, + 0x09, 0xc4, 0x33, 0x19, 0x15, 0x39, 0x07, 0x2e, 0xca, 0x06, 0xcb, 0x7f, 0x07, + 0x07, 0xf8, 0xf3, 0xe8, 0xd9, 0x29, 0xec, 0xf6, 0xe1, 0x06, 0xca, 0x0b, 0xfe, + 0xce, 0x05, 0xe6, 0x22, 0xfb, 0xe5, 0xd5, 0xd1, 0xbe, 0x03, 0x06, 0x20, 0x24, + 0x18, 0xe8, 0x11, 0xc7, 0xed, 0xf0, 0x1e, 0xfc, 0x10, 0xcb, 0x17, 0x00, 0x1f, + 0x20, 0x04, 0xdd, 0xe9, 0x0a, 0x45, 0x35, 0x2b, 0x08, 0xfa, 0x4d, 0xcb, 0xd6, + 0xd9, 0x0d, 0xd1, 0x1e, 0xee, 0xda, 0x09, 0x60, 0xfd, 0xf1, 0x3d, 0xf2, 0xfa, + 0x0f, 0x27, 0x73, 0xd7, 0x78, 0x21, 0xeb, 0xc7, 0xec, 0x1f, 0x40, 0x04, 0x52, + 0xdb, 0x13, 0xe5, 0xf6, 0x09, 0xef, 0xc2, 0xef, 0x0d, 0x45, 0xd5, 0x06, 0x41, + 0x14, 0xee, 0xe8, 0x0a, 0x15, 0xf1, 0x62, 0xe0, 0x05, 0xe7, 0x14, 0xff, 0x11, + 0xf1, 0xf7, 0x7f, 0x02, 0x41, 0xd9, 0x12, 0xf7, 0xe7, 0xdb, 0x03, 0xf0, 0xc7, + 0xc0, 0xe2, 0x0b, 0xf1, 0x33, 0xf1, 0x29, 0xe0, 0xf1, 0xe9, 0xc3, 0x37, 0xd0, + 0xf1, 0x18, 0xe7, 0xbb, 0x0a, 0xf5, 0xf8, 0x27, 0x19, 0xdd, 0x25, 0x0f, 0x25, + 0x2d, 0xff, 0x2b, 0xcf, 0x02, 0x0e, 0x00, 0x19, 0xc8, 0xee, 0x12, 0x15, 0xd6, + 0x09, 0xf6, 0xcf, 0x10, 0xfd, 0x0f, 0xe1, 0xba, 0xfe, 0x09, 0x0d, 0x2a, 0xdf, + 0x34, 0xeb, 0xfc, 0x3b, 0xf4, 0x24, 0xf9, 0xf4, 0xfb, 0xe7, 0xdc, 0xeb, 0x1c, + 0xf0, 0x5c, 0xe6, 0x0f, 0x0b, 0x41, 0xce, 0xec, 0xe1, 0xad, 0x10, 0x19, 0x10, + 0x02, 0x28, 0x15, 0xdc, 0x10, 0xf8, 0xdb, 0x3e, 0x43, 0xec, 0x27, 0xfd, 0x1c, + 0xc2, 0x49, 0xee, 0xed, 0x06, 0x09, 0xfb, 0x3e, 0x4d, 0xd2, 0x25, 0x1d, 0x01, + 0x09, 0x01, 0xfd, 0xef, 0x3e, 0xe1, 0xd6, 0x05, 0x0e, 0xfc, 0x1c, 0xd2, 0xd6, + 0x3f, 0xe3, 0xff, 0xfb, 0xf8, 0x5a, 0xe8, 0x2d, 0x0a, 0x10, 0xb0, 0x1b, 0x70, + 0xa0, 0xbc, 0xdc, 0xb8, 0xb6, 0x23, 0xde, 0x42, 0xe7, 0x64, 0x51, 0xe8, 0x1b, + 0xa1, 0x07, 0x3f, 0xc3, 0xcd, 0x4a, 0xdb, 0xa0, 0xb4, 0x2e, 0x19, 0x35, 0x23, + 0x55, 0xf4, 0x07, 0xf7, 0x1c, 0xb8, 0x07, 0x09, 0x2d, 0x25, 0x56, 0xe9, 0xed, + 0x0d, 0x19, 0x25, 0xf2, 0xfa, 0xe4, 0x08, 0xa0, 0xed, 0xe8, 0x2e, 0x07, 0xdd, + 0x47, 0x7f, 0x12, 0xdb, 0xd0, 0x18, 0x37, 0x32, 0x07, 0xe2, 0xc6, 0xfa, 0xf6, + 0x1e, 0x43, 0x34, 0x0d, 0x5e, 0xce, 0xd7, 0xc8, 0xc0, 0xe2, 0xee, 0xf9, 0x1b, + 0x4c, 0x15, 0xfd, 0xf7, 0x19, 0xe7, 0x0e, 0x19, 0xb0, 0x0b, 0x25, 0x81, 0xf3, + 0x04, 0xe3, 0xe8, 0x1a, 0xd9, 0xdb, 0xee, 0xee, 0x3b, 0x10, 0xe1, 0xce, 0x0f, + 0xca, 0xec, 0x75, 0x48, 0x31, 0xcd, 0xef, 0xf9, 0xcb, 0xee, 0x07, 0xe5, 0x56, + 0xf3, 0x0f, 0x3e, 0xc9, 0x65, 0xe5, 0x3c, 0x0f, 0xd5, 0xd8, 0xf7, 0xfc, 0xf7, + 0xea, 0xdb, 0x09, 0xce, 0xfb, 0xc9, 0xb9, 0x5d, 0xf7, 0xdb, 0x13, 0xd7, 0x09, + 0x1d, 0x24, 0xec, 0xed, 0xe4, 0x5e, 0xdd, 0xc7, 0x1d, 0x0c, 0x25, 0xe2, 0xed, + 0x18, 0xbc, 0x1f, 0xfe, 0x23, 0xfe, 0xe5, 0xf2, 0xae, 0x17, 0xb3, 0x23, 0x62, + 0xef, 0xd5, 0xfc, 0xe0, 0xe0, 0xe0, 0xc1, 0xfd, 0xf6, 0x0f, 0xd1, 0x07, 0x08, + 0x03, 0xe2, 0xe2, 0x05, 0x18, 0x00, 0x2b, 0xfe, 0x00, 0xa6, 0xdf, 0x30, 0x11, + 0xf5, 0x17, 0x0b, 0xd7, 0xf0, 0xc3, 0x29, 0xfc, 0xd0, 0xe9, 0xe9, 0x0a, 0xce, + 0x35, 0xdb, 0x2b, 0xee, 0xc5, 0x0b, 0x10, 0xa7, 0x15, 0x18, 0x0f, 0xb5, 0xf4, + 0x2e, 0x0a, 0x22, 0xe9, 0x2c, 0x2f, 0xcd, 0x09, 0x63, 0xcb, 0x06, 0xeb, 0x28, + 0xdc, 0x40, 0x7f, 0xeb, 0x47, 0x25, 0xf8, 0x06, 0x76, 0x10, 0x24, 0x68, 0xa0, + 0x05, 0x2a, 0x02, 0xbf, 0xf3, 0x09, 0x5f, 0x2c, 0xe4, 0xd7, 0x01, 0xdb, 0x1b, + 0x25, 0x1e, 0xeb, 0xe4, 0xcb, 0x21, 0xe2, 0x06, 0xcf, 0xc3, 0x58, 0x03, 0x61, + 0x1b, 0x4b, 0xcf, 0x05, 0x29, 0xe4, 0xca, 0xe3, 0xe3, 0xdd, 0xfc, 0xe3, 0xba, + 0xd8, 0x0c, 0x0c, 0xe4, 0xfc, 0x0e, 0x1a, 0xf2, 0x16, 0x2d, 0x14, 0x06, 0xda, + 0x52, 0xee, 0xdc, 0xf4, 0xf7, 0xfe, 0x07, 0x2c, 0xd5, 0xd7, 0xfd, 0x03, 0x05, + 0xc4, 0x12, 0xeb, 0xdd, 0x0d, 0x0b, 0x4a, 0xd1, 0xf8, 0xc4, 0x22, 0x15, 0x02, + 0xf8, 0xf8, 0x12, 0x13, 0xf9, 0x17, 0xb0, 0x06, 0xc4, 0x1a, 0x23, 0x3b, 0xfd, + 0xee, 0xb7, 0x03, 0x14, 0x3a, 0x1b, 0x48, 0xd6, 0x2c, 0x36, 0x3c, 0xb3, 0x18, + 0x09, 0x0c, 0x08, 0x01, 0x5a, 0xf0, 0x21, 0xc3, 0x2b, 0x08, 0xce, 0xbb, 0xec, + 0x21, 0xa5, 0x20, 0xbd, 0xe0, 0xe9, 0x1d, 0x2d, 0x06, 0x55, 0x50, 0x14, 0x92, + 0xcd, 0x3b, 0x76, 0xdc, 0xfc, 0xf0, 0x69, 0x0a, 0x36, 0x35, 0xc5, 0x7b, 0x06, + 0x73, 0x0a, 0xfb, 0x11, 0xcb, 0xdf, 0x47, 0xd9, 0x0f, 0xc1, 0x30, 0x23, 0xc1, + 0xf8, 0x15, 0x3d, 0x2c, 0x05, 0x63, 0x35, 0xfa, 0x15, 0x0e, 0xe4, 0xea, 0x2c, + 0xb2, 0x19, 0xd9, 0x81, 0xf4, 0x33, 0x35, 0xfc, 0xc6, 0xec, 0x0c, 0xcc, 0x89, + 0x5d, 0xcd, 0x02, 0xf5, 0x27, 0x2b, 0xcf, 0xb7, 0xf0, 0xb6, 0x03, 0x29, 0x2b, + 0x71, 0x1c, 0xe9, 0x11, 0x23, 0xeb, 0x1b, 0x40, 0xed, 0x27, 0x6d, 0x56, 0xdb, + 0xac, 0xf9, 0xaf, 0x08, 0x22, 0xf0, 0x15, 0x13, 0x00, 0x2d, 0x29, 0xf2, 0xa7, + 0x16, 0xee, 0x28, 0x3a, 0x21, 0x17, 0xef, 0x10, 0xfc, 0xde, 0x12, 0x1f, 0x32, + 0xc9, 0x09, 0x5c, 0x0f, 0xe9, 0xc9, 0x0a, 0x11, 0x29, 0x1f, 0x1f, 0xb0, 0xd7, + 0x34, 0xd6, 0xe5, 0xe9, 0xe6, 0x48, 0x0c, 0xe7, 0xdd, 0x0c, 0x12, 0xfb, 0xdc, + 0x49, 0xec, 0xd8, 0x00, 0xd8, 0xe7, 0x38, 0xff, 0xf6, 0x47, 0xe0, 0xfe, 0xfc, + 0x28, 0xdf, 0x09, 0xcf, 0x2b, 0xdc, 0xe7, 0xc3, 0x2c, 0x3b, 0xe3, 0x21, 0x14, + 0x3b, 0xec, 0x1a, 0x23, 0x0a, 0x0e, 0xd6, 0x1a, 0x2b, 0x23, 0xfb, 0xff, 0xdf, + 0xe5, 0xf2, 0x1d, 0x16, 0x04, 0xf2, 0x44, 0xbf, 0xd8, 0xe2, 0xd5, 0x14, 0x00, + 0x23, 0x03, 0x0f, 0x81, 0xd1, 0xda, 0xb4, 0xc3, 0x08, 0xfd, 0xf6, 0xfc, 0xee, + 0xef, 0x10, 0x41, 0xc5, 0x44, 0x12, 0xff, 0xf4, 0xf8, 0xc1, 0xdc, 0xf2, 0x27, + 0x0a, 0x0c, 0x04, 0x0b, 0xe7, 0x0d, 0x05, 0x20, 0x34, 0xed, 0xe4, 0x3e, 0xfe, + 0x01, 0xfd, 0x08, 0xd1, 0x04, 0xf2, 0x22, 0xe3, 0x1c, 0x09, 0x26, 0xf6, 0xe2, + 0x47, 0xee, 0xf4, 0xc9, 0xe8, 0xd1, 0xf7, 0x5d, 0xed, 0x9d, 0x2a, 0x34, 0xee, + 0xc9, 0xd7, 0xcf, 0xf6, 0xff, 0x0d, 0x10, 0xfb, 0xb6, 0x0d, 0x18, 0x29, 0xde, + 0x9d, 0xd3, 0x35, 0xeb, 0xe0, 0x34, 0xe8, 0x53, 0x02, 0x1a, 0xd5, 0xda, 0x10, + 0xad, 0xc4, 0x10, 0x81, 0xe8, 0x39, 0x43, 0x05, 0xe7, 0xfb, 0x0c, 0xe1, 0xc8, + 0xe9, 0x13, 0x28, 0x54, 0xf9, 0xcb, 0xcf, 0xe3, 0x02, 0xd9, 0x16, 0xe7, 0xce, + 0xf3, 0x12, 0xe2, 0x19, 0xff, 0xcb, 0x26, 0xc0, 0xa8, 0xa7, 0x3e, 0x15, 0x03, + 0xdf, 0x41, 0xf2, 0xf2, 0x07, 0xbb, 0xe1, 0xbb, 0x00, 0xde, 0x1c, 0xf6, 0x06, + 0xcf, 0xdb, 0xd8, 0xf4, 0x21, 0x1f, 0x30, 0xeb, 0xc7, 0xf1, 0xd4, 0x25, 0x2a, + 0x0d, 0xad, 0x03, 0x0a, 0x02, 0x14, 0x2c, 0x12, 0x0a, 0x32, 0x0b, 0x36, 0xb4, + 0xf6, 0xf3, 0xfa, 0x72, 0xf9, 0xd0, 0x32, 0xaa, 0xd0, 0x0b, 0xbc, 0x2f, 0x29, + 0x3e, 0xea, 0xf1, 0xd8, 0xb4, 0x64, 0x2e, 0xc6, 0xcb, 0x18, 0x11, 0xe9, 0xd8, + 0xdd, 0xe7, 0x0c, 0x36, 0x0c, 0x1c, 0x16, 0xe0, 0x17, 0x1d, 0x0e, 0xd3, 0x99, + 0xb9, 0xee, 0xf7, 0xe7, 0xe0, 0xf2, 0xd2, 0x68, 0xc9, 0xe7, 0xe6, 0x17, 0x27, + 0x37, 0xf4, 0x7f, 0x16, 0xea, 0x3c, 0xc3, 0x20, 0x15, 0xf4, 0xf4, 0x09, 0x3e, + 0x39, 0x23, 0xd6, 0xdf, 0x18, 0x35, 0xd0, 0xd9, 0xb9, 0x2a, 0xd6, 0x23, 0xe4, + 0xbb, 0xe1, 0xd1, 0x0e, 0xae, 0x3f, 0xff, 0xa7, 0x0f, 0x26, 0x0c, 0x04, 0x03, + 0xcb, 0xe1, 0xff, 0xff, 0xf8, 0xd4, 0xe9, 0x14, 0xd7, 0x09, 0xee, 0x44, 0xe3, + 0xeb, 0xee, 0xfe, 0x0a, 0xf5, 0xf0, 0x20, 0xe5, 0x4c, 0xf1, 0x10, 0xf1, 0xf5, + 0xce, 0x23, 0xe0, 0xfe, 0xe7, 0xe5, 0x0b, 0x0d, 0x20, 0xe0, 0x0e, 0xdf, 0xf5, + 0xed, 0x7f, 0xf7, 0xf4, 0x33, 0x09, 0x45, 0xf2, 0xf3, 0x1f, 0x0d, 0x0f, 0x1c, + 0x32, 0x03, 0x04, 0x69, 0xff, 0x6e, 0x5a, 0xf1, 0xfc, 0x07, 0xf5, 0x07, 0xcd, + 0xdc, 0x0c, 0x4e, 0x2a, 0x2b, 0x28, 0x21, 0x20, 0xf3, 0x9e, 0xe3, 0x1d, 0x17, + 0xfe, 0x03, 0xa3, 0x07, 0x17, 0x14, 0xee, 0xed, 0x34, 0x10, 0xaa, 0x3c, 0x23, + 0xe8, 0x02, 0x28, 0x1c, 0xb9, 0xad, 0xe6, 0x4c, 0xaa, 0xb2, 0xfa, 0x1c, 0xfa, + 0x23, 0x62, 0x00, 0xf3, 0x32, 0xd2, 0x1f, 0xf0, 0xaa, 0x06, 0xf8, 0x9f, 0x2b, + 0x2c, 0xdc, 0xd7, 0xdb, 0xa9, 0xd6, 0xef, 0x0e, 0xe1, 0x08, 0xfe, 0x3d, 0x02, + 0xfa, 0xf7, 0x0b, 0x0f, 0xdf, 0x4d, 0x38, 0xf5, 0xea, 0x07, 0xea, 0xfa, 0x22, + 0xf0, 0xfb, 0x22, 0xe6, 0xd7, 0xdc, 0xdc, 0x65, 0x25, 0xf5, 0xdf, 0xc9, 0x09, + 0xe3, 0x4d, 0x0f, 0xee, 0xcb, 0x00, 0xf8, 0x5e, 0xd2, 0xc1, 0xfb, 0xd9, 0x2d, + 0x17, 0x93, 0x29, 0xf2, 0xfe, 0xe9, 0x8d, 0xba, 0xd8, 0xda, 0x39, 0x1b, 0xec, + 0xe7, 0xdc, 0xcb, 0xc4, 0xe7, 0x14, 0xdf, 0xd5, 0xce, 0xf2, 0x24, 0x2f, 0x3d, + 0xc0, 0xc9, 0x08, 0xa8, 0xf7, 0x2c, 0xf2, 0xce, 0x33, 0xcb, 0x39, 0x2d, 0x0c, + 0xdf, 0xaf, 0xd2, 0xda, 0xb9, 0x9e, 0x25, 0xbe, 0xa7, 0x12, 0x8e, 0x0b, 0xdc, + 0xe9, 0x23, 0xdd, 0xea, 0xb0, 0x4c, 0xdd, 0x1d, 0xc3, 0x0e, 0xd8, 0x37, 0xf2, + 0x0a, 0x01, 0x36, 0x00, 0x81, 0xeb, 0x40, 0xee, 0xb7, 0xee, 0xf3, 0x49, 0x35, + 0xdc, 0xbc, 0xd3, 0xe3, 0xf2, 0x0c, 0x19, 0xfd, 0xb0, 0xb7, 0x37, 0xe2, 0xda, + 0x32, 0x22, 0xe4, 0xe7, 0xc6, 0xeb, 0x01, 0x38, 0xc5, 0x2a, 0x34, 0x57, 0x52, + 0x34, 0xec, 0x09, 0xfc, 0x0e, 0x03, 0xcc, 0xde, 0xb4, 0xe9, 0x19, 0x16, 0x38, + 0x31, 0xff, 0xf1, 0xc2, 0xf6, 0xbb, 0x06, 0x22, 0x0e, 0x3e, 0xfc, 0xae, 0x12, + 0xf5, 0xe9, 0xc3, 0xed, 0x21, 0x58, 0x74, 0x3e, 0x00, 0xf9, 0xc3, 0x21, 0x29, + 0xfd, 0x0e, 0xdb, 0x17, 0xdb, 0xe4, 0xe6, 0xfc, 0xe9, 0xfa, 0x35, 0x11, 0xf2, + 0xdc, 0x2e, 0x3a, 0xf5, 0x1e, 0xf7, 0xd5, 0x05, 0xe3, 0x3c, 0xec, 0x0a, 0xbf, + 0xc6, 0xf2, 0x08, 0xf0, 0x04, 0xdf, 0x04, 0x23, 0xf6, 0xfb, 0xef, 0x45, 0xaf, + 0x06, 0x35, 0xec, 0xfd, 0x04, 0xe4, 0xeb, 0xf6, 0x06, 0xe0, 0x0e, 0x12, 0xf2, + 0xfc, 0xda, 0x13, 0x66, 0xe9, 0xde, 0xfe, 0xdd, 0x24, 0xf5, 0xd1, 0xed, 0xf3, + 0xc4, 0x33, 0xcb, 0x28, 0xe0, 0xfb, 0x19, 0xf2, 0xf3, 0xed, 0xe9, 0xdc, 0xf8, + 0x01, 0x0a, 0xf3, 0x01, 0xd7, 0xf6, 0xf6, 0x16, 0xea, 0xcb, 0x7f, 0xdf, 0xee, + 0xca, 0xbd, 0x1e, 0xe9, 0xe3, 0xd3, 0xf0, 0x49, 0xd5, 0xee, 0x0b, 0xed, 0xf5, + 0x24, 0xd7, 0x20, 0xf2, 0xcc, 0x21, 0xf2, 0x2e, 0xd7, 0xde, 0xe6, 0x02, 0xcc, + 0x37, 0xd1, 0xd5, 0x0e, 0x32, 0x42, 0x0c, 0xff, 0xd8, 0x5e, 0x46, 0xe6, 0xe5, + 0xec, 0xfa, 0xe3, 0xd1, 0xdf, 0x2d, 0x30, 0x1f, 0xde, 0xf9, 0xe6, 0xef, 0xdc, + 0x09, 0xdc, 0xe9, 0xcf, 0x2a, 0x03, 0xbc, 0xd0, 0x2e, 0x77, 0x30, 0xe5, 0xe7, + 0x2d, 0xc2, 0xf5, 0xcb, 0x0f, 0x1e, 0x7f, 0xf8, 0x2d, 0x07, 0x24, 0xf6, 0x24, + 0xc3, 0x14, 0x76, 0x0e, 0xee, 0x04, 0x05, 0xf0, 0x31, 0xed, 0xa1, 0xe1, 0x30, + 0x13, 0x26, 0xf4, 0xe4, 0xa4, 0xca, 0xbf, 0x22, 0xd9, 0x58, 0xd1, 0xde, 0xd3, + 0xff, 0x2f, 0xca, 0xf4, 0x72, 0xe8, 0xd3, 0xe0, 0xfb, 0x0a, 0xf7, 0x26, 0x07, + 0xdb, 0x3e, 0xe7, 0x45, 0xf1, 0x19, 0x09, 0xdf, 0xcd, 0x3d, 0x0c, 0x25, 0x16, + 0x0e, 0xe6, 0xd8, 0xe4, 0x2b, 0x06, 0x1d, 0x37, 0x12, 0xee, 0x0e, 0x49, 0x0f, + 0x1d, 0x29, 0xe2, 0x11, 0xec, 0xb7, 0xff, 0x3a, 0xce, 0x07, 0xd5, 0x14, 0xfb, + 0xfa, 0xc2, 0x06, 0x7f, 0x19, 0x0d, 0x06, 0xf7, 0x3c, 0xcb, 0xf0, 0x68, 0x1a, + 0xf1, 0xdf, 0xf3, 0x22, 0x1e, 0xe5, 0x0d, 0xde, 0x1c, 0xcd, 0xda, 0x09, 0xe4, + 0xf9, 0xed, 0xd5, 0xf7, 0xe4, 0xaa, 0xe6, 0x99, 0xe3, 0x1a, 0x02, 0x16, 0xa8, + 0x22, 0xee, 0x37, 0x03, 0xf0, 0x3c, 0xd7, 0xe4, 0xbf, 0xb1, 0xd2, 0x1b, 0x69, + 0x51, 0xe5, 0x16, 0xf7, 0x03, 0xb2, 0x9a, 0xbe, 0x04, 0xe6, 0xe3, 0x1b, 0x05, + 0x0a, 0x07, 0x08, 0x21, 0xd5, 0xf7, 0x0a, 0x0e, 0x1a, 0xda, 0x12, 0x33, 0xf8, + 0x24, 0xf2, 0x4d, 0x01, 0x0c, 0x31, 0xe6, 0xd7, 0xcb, 0xf9, 0x09, 0x1a, 0xdf, + 0x02, 0xb3, 0xd2, 0x13, 0xe8, 0x0e, 0x1b, 0x42, 0xcd, 0x00, 0x2a, 0x34, 0x73, + 0xca, 0xc5, 0x25, 0x07, 0x08, 0xf6, 0x3b, 0xcb, 0x0e, 0xbf, 0x07, 0xf0, 0xc7, + 0x33, 0xf0, 0xdc, 0x40, 0x09, 0x5b, 0xc3, 0x00, 0x5f, 0xcd, 0xf0, 0xf3, 0x38, + 0xf9, 0x42, 0xe1, 0x07, 0x04, 0x36, 0x2a, 0xd1, 0xba, 0xfc, 0x62, 0xd4, 0x0f, + 0xe3, 0x7f, 0x2e, 0xee, 0x65, 0xd1, 0xdb, 0xbd, 0x35, 0x03, 0x47, 0xfd, 0x9c, + 0x37, 0x30, 0xce, 0x3a, 0x18, 0xe6, 0x35, 0xb2, 0x11, 0x97, 0xa7, 0xf9, 0xe4, + 0xea, 0x3a, 0x07, 0xf6, 0xe7, 0x57, 0x1a, 0xf4, 0xe6, 0x56, 0xdc, 0x96, 0x30, + 0x58, 0x35, 0xe8, 0x0e, 0x05, 0xfa, 0x0b, 0x36, 0x0a, 0xaa, 0xdc, 0x14, 0x01, + 0x06, 0x2c, 0xe7, 0x23, 0xda, 0x08, 0x23, 0xbd, 0xa4, 0x19, 0x24, 0xfb, 0x1f, + 0x25, 0xe2, 0x1a, 0x1b, 0xf6, 0x0b, 0x23, 0xcf, 0x30, 0xc5, 0xfd, 0xe9, 0x2d, + 0xdf, 0x64, 0xe2, 0x05, 0x50, 0x08, 0xcc, 0xd1, 0xbc, 0xe0, 0x93, 0xfe, 0x09, + 0xa5, 0x04, 0xf4, 0xec, 0x03, 0x28, 0xbe, 0x38, 0x24, 0x11, 0x0b, 0x2d, 0xdd, + 0x1c, 0xc9, 0x0f, 0x40, 0xfd, 0x03, 0x06, 0xe8, 0x11, 0xa0, 0x07, 0xe1, 0x0a, + 0xf9, 0xcc, 0xbb, 0x43, 0x0b, 0x32, 0xcf, 0xbe, 0x2c, 0xbc, 0xb0, 0xe8, 0x05, + 0x1b, 0x21, 0xb5, 0xfe, 0xd7, 0x4a, 0xa6, 0x08, 0x0c, 0x0c, 0x83, 0xea, 0x11, + 0xfe, 0x45, 0xdb, 0xe8, 0x22, 0xc5, 0xfe, 0xee, 0x11, 0x0a, 0x13, 0xdb, 0xf1, + 0x81, 0xf7, 0x29, 0x1b, 0xd1, 0xfc, 0xd6, 0x22, 0xb5, 0x9b, 0x36, 0x17, 0x1e, + 0x45, 0xa9, 0x4f, 0x13, 0x29, 0x04, 0xae, 0xee, 0x0b, 0xe4, 0x03, 0x64, 0x20, + 0xf2, 0x1a, 0x04, 0xf1, 0x48, 0xd9, 0xd0, 0x2d, 0xf2, 0xd7, 0x13, 0x37, 0x1c, + 0xe0, 0xc6, 0xd3, 0xd7, 0x17, 0x37, 0xba, 0xb2, 0xa0, 0xce, 0x2b, 0xb1, 0xf8, + 0xd6, 0x14, 0xf3, 0xea, 0x23, 0xff, 0xdb, 0x20, 0xba, 0xdf, 0xff, 0xd7, 0xfd, + 0x0e, 0xe0, 0x11, 0xec, 0xfd, 0xcc, 0x02, 0x2a, 0xfb, 0x28, 0x2e, 0xf2, 0xe4, + 0x2c, 0x44, 0xf1, 0x36, 0xc6, 0xeb, 0x19, 0xbd, 0x30, 0x07, 0xf3, 0xe9, 0x15, + 0xe6, 0xef, 0xf4, 0x01, 0x08, 0x3a, 0x00, 0xdf, 0x02, 0xeb, 0xfc, 0xf4, 0x21, + 0xa2, 0x5d, 0x06, 0xd1, 0x10, 0x03, 0x12, 0xcb, 0xf5, 0xb2, 0x05, 0xdf, 0xd0, + 0x1a, 0x1b, 0x15, 0x18, 0x05, 0xe1, 0xf1, 0xee, 0xf5, 0xdc, 0xff, 0x81, 0x1e, + 0x02, 0x25, 0xc9, 0xe5, 0xfd, 0xd2, 0xf2, 0xfb, 0xcb, 0x13, 0x29, 0x79, 0x1a, + 0x07, 0xb1, 0xea, 0xed, 0xf6, 0xdf, 0xeb, 0xd2, 0xdf, 0x35, 0xea, 0xed, 0x48, + 0xb2, 0xc3, 0xe1, 0xb6, 0xdb, 0x13, 0x01, 0x16, 0x10, 0xcd, 0xfb, 0xeb, 0x10, + 0xe5, 0x0e, 0x11, 0xfa, 0x2d, 0x0b, 0xf4, 0xd6, 0xf6, 0xbf, 0x2a, 0xda, 0x17, + 0xfd, 0xde, 0xfd, 0xf2, 0xce, 0xdb, 0x36, 0xe9, 0x1e, 0xcc, 0x20, 0xed, 0x15, + 0x13, 0xe1, 0x1f, 0xec, 0xdb, 0x21, 0xc5, 0x1d, 0xf3, 0xf7, 0x09, 0x1f, 0xd5, + 0x01, 0x25, 0xc7, 0xfc, 0x11, 0xc2, 0x2f, 0xff, 0x34, 0x10, 0x15, 0xf3, 0x0e, + 0x33, 0x24, 0x37, 0xea, 0x04, 0x10, 0xff, 0x16, 0xcf, 0x0e, 0x07, 0x17, 0xb5, + 0xfe, 0xb2, 0x49, 0xe6, 0xda, 0xff, 0x12, 0x05, 0x1e, 0xdc, 0xea, 0x21, 0x0b, + 0xde, 0xe8, 0xeb, 0x4f, 0xe3, 0xf7, 0xe3, 0x1e, 0x04, 0xdf, 0x1d, 0x00, 0xfa, + 0xcd, 0xe2, 0x0d, 0xd7, 0x1a, 0x00, 0xf1, 0xd8, 0xf1, 0xf8, 0xe2, 0xf9, 0xdc, + 0xe5, 0xc7, 0xfd, 0x09, 0x0c, 0xe7, 0x05, 0x10, 0xc8, 0xd6, 0x0f, 0x11, 0xb9, + 0x45, 0xdc, 0x09, 0xd3, 0xfc, 0xba, 0xe7, 0x5c, 0xda, 0x0e, 0xfb, 0x24, 0xf3, + 0x6a, 0xc1, 0x04, 0xd4, 0x13, 0xb9, 0x02, 0xd9, 0xf0, 0x16, 0xf1, 0x18, 0x03, + 0x06, 0x20, 0x0f, 0xe6, 0xee, 0xef, 0xc1, 0xe5, 0xe2, 0x7f, 0x28, 0xf9, 0x06, + 0xed, 0x7e, 0xa6, 0x2f, 0x1d, 0xc2, 0xf6, 0xdd, 0x03, 0xed, 0x05, 0x1c, 0x1d, + 0x8c, 0xe5, 0x0f, 0xe2, 0x9b, 0x1d, 0xf3, 0x14, 0xdf, 0x2d, 0x22, 0x08, 0x48, + 0xed, 0xef, 0xf2, 0x05, 0xc2, 0xd4, 0xd9, 0x1a, 0x59, 0x01, 0xeb, 0x9c, 0xdc, + 0xe0, 0x01, 0xce, 0x09, 0x16, 0xd6, 0xed, 0xe6, 0xda, 0xbf, 0xbe, 0x0a, 0x03, + 0xf5, 0xd7, 0xdd, 0x3c, 0x22, 0x66, 0xf2, 0x4b, 0x2c, 0x7f, 0x0c, 0xa9, 0x62, + 0x8f, 0xb3, 0x6b, 0x2f, 0x13, 0x0b, 0xff, 0xbf, 0x01, 0xa8, 0xd2, 0xe4, 0x8e, + 0x39, 0x59, 0xc7, 0x4c, 0xff, 0x1e, 0xeb, 0x32, 0xf9, 0x0e, 0xf2, 0x50, 0x56, + 0x2b, 0xe5, 0x0c, 0x25, 0xf8, 0xe9, 0xf0, 0x30, 0xf7, 0x17, 0x47, 0xaf, 0xfa, + 0xd8, 0x22, 0x2b, 0xd1, 0xca, 0x3e, 0xda, 0x01, 0x21, 0xf5, 0x63, 0x0d, 0xfa, + 0xed, 0x33, 0x7c, 0xc8, 0xd5, 0x49, 0x28, 0x0d, 0xe1, 0xe4, 0x1c, 0x41, 0xfb, + 0x12, 0xec, 0xae, 0x5f, 0x1b, 0xe8, 0x3b, 0x05, 0xb7, 0xe8, 0x04, 0x1d, 0xd1, + 0xfe, 0xbd, 0x10, 0xe9, 0x2b, 0xc9, 0x35, 0x04, 0x0e, 0x3e, 0xe7, 0xe8, 0xd0, + 0x76, 0xe3, 0xec, 0xd8, 0x43, 0xf8, 0xbe, 0x12, 0x0a, 0x21, 0xd0, 0xfc, 0x3a, + 0xd7, 0xf5, 0xe2, 0x4b, 0xea, 0xda, 0x1c, 0xce, 0x05, 0x37, 0xff, 0x2f, 0xda, + 0x40, 0x0f, 0x22, 0xfa, 0xd8, 0x01, 0xcc, 0xd2, 0x2c, 0xf7, 0x1d, 0x4e, 0x7f, + 0xdd, 0xe6, 0x0f, 0xcc, 0xe2, 0xe7, 0x12, 0xa9, 0xda, 0xcb, 0xe9, 0x06, 0x0e, + 0x04, 0x3e, 0xf7, 0xed, 0x06, 0xc4, 0xd3, 0xdf, 0xcf, 0xbe, 0xa9, 0xd8, 0xf2, + 0x2d, 0x21, 0x54, 0xc1, 0x19, 0xfa, 0x1f, 0xfa, 0xbb, 0xed, 0x48, 0x29, 0x04, + 0x41, 0x0e, 0x72, 0x06, 0x19, 0x2a, 0x16, 0x05, 0x25, 0xf1, 0x35, 0x1f, 0xfc, + 0x0e, 0x06, 0xc1, 0x0e, 0xf6, 0x2b, 0xad, 0x1e, 0xfe, 0x26, 0xf3, 0x81, 0x27, + 0xaf, 0x9b, 0x08, 0xf9, 0x38, 0xf2, 0x9a, 0x92, 0x21, 0xe5, 0x3b, 0x3b, 0x5b, + 0xa0, 0xf8, 0x07, 0x1e, 0x39, 0xe7, 0x0c, 0xbf, 0x33, 0x41, 0xed, 0xb0, 0x27, + 0x42, 0x02, 0x2a, 0xf8, 0x15, 0xd1, 0x10, 0xbe, 0xfd, 0x04, 0xfc, 0xb9, 0x4a, + 0x2f, 0x0f, 0xfc, 0xfe, 0xbf, 0xae, 0x47, 0xc9, 0x12, 0xa2, 0xe0, 0xea, 0x41, + 0x47, 0x59, 0xdb, 0x21, 0x09, 0x15, 0x1a, 0xf1, 0x23, 0xcb, 0xab, 0x53, 0x35, + 0x0d, 0x8a, 0xcf, 0x06, 0xf1, 0x28, 0xe3, 0xfd, 0x2f, 0xe8, 0x2c, 0x0c, 0xe8, + 0x3d, 0xed, 0x5a, 0xe1, 0xb1, 0x18, 0x1b, 0x4e, 0xf4, 0x2e, 0xd3, 0x0c, 0x20, + 0x23, 0x3c, 0xd6, 0xbc, 0x25, 0x1c, 0x26, 0x33, 0xe9, 0x0f, 0xcb, 0x2c, 0x2b, + 0x13, 0xda, 0xb5, 0x08, 0xeb, 0xc2, 0xd1, 0x1b, 0xd5, 0x26, 0xf0, 0x33, 0xf6, + 0xec, 0x00, 0xf1, 0x14, 0x23, 0x02, 0x0d, 0xf8, 0x26, 0x2a, 0xef, 0xdf, 0xc6, + 0xdd, 0xd5, 0xeb, 0xf3, 0x09, 0x0d, 0x4f, 0x06, 0x39, 0xf5, 0xea, 0x05, 0x3d, + 0x15, 0xb7, 0x27, 0xa0, 0xed, 0xdb, 0xe7, 0x02, 0xa3, 0x17, 0xdf, 0xdf, 0xc0, + 0x07, 0x13, 0xef, 0x39, 0xd9, 0xe5, 0x92, 0x2f, 0xf1, 0x3b, 0x29, 0x7f, 0x78, + 0xdb, 0xea, 0xf1, 0x3d, 0x4d, 0x5f, 0x17, 0x52, 0xcf, 0x1b, 0xdc, 0x24, 0x40, + 0x0a, 0x03, 0x21, 0xea, 0x01, 0xd9, 0x4c, 0xfa, 0x08, 0x35, 0xe5, 0xfe, 0xf6, + 0x0f, 0x46, 0xf5, 0x17, 0x15, 0x24, 0xed, 0x09, 0x15, 0x0c, 0x23, 0xe9, 0x3f, + 0x14, 0xf7, 0xc0, 0xfb, 0x13, 0x41, 0xd5, 0xe5, 0xd1, 0xe2, 0xb0, 0xee, 0x1f, + 0x20, 0xec, 0x23, 0xf9, 0xe9, 0x75, 0xfb, 0x1c, 0x5b, 0x0e, 0x28, 0x01, 0xea, + 0xf6, 0xe0, 0x0f, 0xfc, 0xe5, 0x25, 0x47, 0xaa, 0x1e, 0xf2, 0x3f, 0xf9, 0x0f, + 0x07, 0x12, 0xd3, 0xb2, 0xc5, 0xd3, 0x3d, 0xd7, 0x07, 0x2c, 0xc7, 0xcb, 0x39, + 0x16, 0xf7, 0xdf, 0x4f, 0xc7, 0x21, 0x22, 0x30, 0xaa, 0xb5, 0x18, 0xbf, 0x2d, + 0xf3, 0x0d, 0xf8, 0x46, 0x10, 0x86, 0x3d, 0xef, 0x3c, 0x4f, 0x29, 0xfc, 0xe4, + 0xd3, 0x27, 0xf7, 0x1f, 0x26, 0x29, 0xf1, 0xd0, 0x29, 0xe6, 0xf0, 0xd1, 0x04, + 0xac, 0xdd, 0xd9, 0xa6, 0xfc, 0xd0, 0xd4, 0x09, 0x11, 0x4a, 0x32, 0xe2, 0xf9, + 0xeb, 0xfc, 0xcb, 0xf9, 0x3b, 0xc5, 0xd3, 0x95, 0x50, 0x3e, 0x16, 0x94, 0xe7, + 0xcb, 0xcb, 0xda, 0x3e, 0xd5, 0x0a, 0xc7, 0x1d, 0x06, 0xe0, 0x7f, 0x31, 0x62, + 0x01, 0x1d, 0x37, 0x4e, 0xeb, 0x14, 0x04, 0xf2, 0x2a, 0x05, 0xd9, 0x4a, 0x34, + 0xec, 0x1f, 0x32, 0x89, 0xf6, 0xcd, 0x5e, 0x1e, 0x28, 0x1a, 0x3e, 0xea, 0xdd, + 0x1a, 0x49, 0xfd, 0x25, 0x26, 0x2d, 0xde, 0xe5, 0xdb, 0xd9, 0x33, 0x42, 0xda, + 0x0b, 0x21, 0xf3, 0xd6, 0xe5, 0x13, 0x1e, 0x12, 0xcb, 0x45, 0x12, 0x2c, 0x1f, + 0x3b, 0xba, 0x1c, 0x0d, 0xfe, 0x9e, 0xe5, 0x3d, 0x17, 0x47, 0x81, 0xe8, 0xd8, + 0x28, 0xe5, 0xf9, 0x0e, 0xc2, 0x2b, 0xe2, 0xb7, 0xf2, 0x2c, 0x02, 0x04, 0x51, + 0xfa, 0x07, 0xb7, 0x25, 0x05, 0x10, 0xb0, 0xe3, 0xd9, 0x0f, 0x03, 0x0f, 0x03, + 0x15, 0xeb, 0xea, 0xdf, 0xe6, 0x96, 0xfe, 0xf0, 0x0d, 0x19, 0xdd, 0xea, 0xfd, + 0xf3, 0x4a, 0xb3, 0xc6, 0x0e, 0x19, 0xe7, 0xf9, 0x0d, 0x1c, 0x22, 0xff, 0xd7, + 0x15, 0xce, 0x31, 0xde, 0xd4, 0xe1, 0xee, 0x16, 0x04, 0x2d, 0x01, 0xe6, 0xd2, + 0x22, 0x1b, 0x9c, 0xc9, 0xdc, 0xef, 0xf4, 0x2d, 0x0f, 0xaf, 0xb0, 0x0c, 0xde, + 0xf4, 0x2c, 0x32, 0x19, 0x99, 0x10, 0xe2, 0x08, 0xbe, 0x0a, 0xe3, 0x13, 0x4c, + 0x08, 0x0b, 0xeb, 0x03, 0xfb, 0x3d, 0xc4, 0xcb, 0xf5, 0xff, 0x22, 0xd6, 0xe8, + 0x0e, 0xd3, 0xc0, 0x55, 0xbc, 0x2b, 0x3c, 0xe4, 0x18, 0x0e, 0xd5, 0xe5, 0xd0, + 0xe3, 0x2e, 0x27, 0x18, 0x2a, 0x02, 0x09, 0xf2, 0xf1, 0x12, 0x32, 0x14, 0xbd, + 0xe9, 0x46, 0x0b, 0xe5, 0xf4, 0x1b, 0xf7, 0xde, 0xf9, 0xf4, 0xcd, 0xe9, 0xbe, + 0x05, 0xc8, 0x4c, 0xd7, 0x0e, 0x1c, 0xec, 0xca, 0x23, 0xe4, 0xf1, 0xf0, 0xf6, + 0xfe, 0x27, 0xcf, 0x9f, 0xda, 0xd6, 0x3a, 0xfe, 0xd3, 0xd8, 0xf2, 0xb3, 0x77, + 0x08, 0xba, 0xc9, 0xbb, 0x8e, 0x14, 0xed, 0x1d, 0x17, 0xe3, 0xfd, 0xcf, 0xef, + 0x7f, 0x1a, 0xde, 0x0a, 0x38, 0x15, 0xc5, 0xef, 0xbf, 0xf5, 0x32, 0xd4, 0x08, + 0xcc, 0xcb, 0x05, 0xfc, 0x1e, 0xf3, 0xda, 0xdb, 0x2c, 0x19, 0x14, 0xf0, 0x1a, + 0x38, 0x23, 0xa8, 0xa2, 0x09, 0x1f, 0x1c, 0x22, 0xe2, 0xe1, 0x04, 0x53, 0x1d, + 0xf7, 0x50, 0x0f, 0xf3, 0x2d, 0x1b, 0x2e, 0xe3, 0xfb, 0x25, 0x17, 0xe2, 0xef, + 0x68, 0xfe, 0xff, 0x3d, 0xdb, 0xed, 0xdd, 0xe2, 0xbe, 0x07, 0xfd, 0x41, 0x1c, + 0x1e, 0xed, 0xca, 0xf0, 0x1b, 0xe6, 0x0b, 0xe4, 0x1e, 0x30, 0xf0, 0xfd, 0x1a, + 0x5c, 0xa1, 0xc4, 0x16, 0x15, 0xfa, 0x15, 0x11, 0xe4, 0xdb, 0x28, 0xd5, 0xfa, + 0xf7, 0xdd, 0xf3, 0x9a, 0x67, 0xc6, 0xfc, 0xf8, 0x0b, 0x07, 0xaf, 0x38, 0xaa, + 0xea, 0xf1, 0x10, 0x49, 0x3c, 0x19, 0x7f, 0x33, 0xc8, 0xeb, 0x59, 0x12, 0xc7, + 0xe4, 0xea, 0x24, 0x4c, 0x07, 0x44, 0x1a, 0x0b, 0x00, 0x61, 0x0f, 0x10, 0xef, + 0x20, 0xd9, 0x69, 0x4c, 0xc5, 0xd1, 0xe1, 0x1e, 0x0a, 0xf2, 0xe9, 0xef, 0x4c, + 0x4a, 0xf5, 0x35, 0x00, 0xcd, 0xd8, 0xe9, 0x71, 0x53, 0x1a, 0xff, 0xfb, 0x22, + 0x16, 0xf0, 0x1d, 0xdf, 0xb1, 0xc3, 0xef, 0xf9, 0xe5, 0x10, 0xde, 0x02, 0x4f, + 0xe4, 0x12, 0xfd, 0x0c, 0x66, 0x28, 0xc7, 0xf6, 0x5d, 0x06, 0xfe, 0xcd, 0x99, + 0x03, 0xc8, 0xc8, 0x06, 0xc5, 0xcf, 0x06, 0x4f, 0xb1, 0x50, 0x1b, 0xf4, 0xbd, + 0xb1, 0x40, 0x5f, 0x23, 0x9e, 0x27, 0x16, 0xd3, 0x4e, 0x2c, 0xe7, 0xaf, 0xe0, + 0xf3, 0xed, 0xc9, 0x35, 0x0a, 0x15, 0x2b, 0xea, 0x81, 0x9f, 0x08, 0x0c, 0x25, + 0x14, 0x12, 0xb0, 0xc3, 0x2c, 0x5a, 0xe9, 0x3f, 0x70, 0xf0, 0x00, 0xdb, 0xd1, + 0xeb, 0xf8, 0x08, 0x33, 0xf6, 0xfb, 0x51, 0xde, 0xd6, 0xc4, 0x46, 0x36, 0xf0, + 0x8f, 0x0c, 0x5a, 0x44, 0xf6, 0x15, 0xfa, 0xf2, 0xf7, 0xcb, 0x01, 0xa2, 0xe0, + 0x3d, 0xeb, 0x43, 0x12, 0xf7, 0xfd, 0xe8, 0x64, 0x12, 0xe5, 0xd7, 0xcb, 0xf1, + 0x32, 0xfb, 0x0a, 0x81, 0x13, 0xf8, 0xf9, 0xc9, 0xab, 0xec, 0x09, 0xe6, 0xdf, + 0xf1, 0x10, 0x0c, 0xe8, 0xcd, 0xf2, 0xfe, 0x34, 0x05, 0xf7, 0x9d, 0xfb, 0xeb, + 0x55, 0x06, 0xe5, 0x1f, 0xc0, 0xa1, 0xb8, 0xd0, 0x21, 0xdd, 0x5a, 0xd1, 0x14, + 0x09, 0xfb, 0xfa, 0x24, 0xf5, 0x7f, 0x06, 0xe1, 0x38, 0xd2, 0x0f, 0x14, 0x07, + 0xf4, 0x10, 0x16, 0x20, 0x09, 0x16, 0x2f, 0xff, 0x2a, 0xdf, 0xd8, 0xea, 0x0d, + 0xe1, 0xd2, 0xe8, 0xda, 0xba, 0xd8, 0x24, 0x15, 0xc4, 0x14, 0xc7, 0x08, 0x00, + 0x1e, 0xc3, 0xe0, 0xaf, 0xf9, 0x05, 0x0f, 0xe9, 0x2c, 0xc9, 0x36, 0xff, 0xcc, + 0xf2, 0xec, 0xdb, 0xda, 0x2f, 0x26, 0xe4, 0x11, 0xeb, 0x56, 0x1c, 0x62, 0xd2, + 0x03, 0xd1, 0x26, 0xc6, 0xe0, 0xc0, 0xef, 0xe3, 0x30, 0xe4, 0xc1, 0x35, 0x1c, + 0x1d, 0xc9, 0x0b, 0xd2, 0xe0, 0x14, 0x2e, 0xf2, 0xd9, 0x0d, 0xd9, 0xea, 0x33, + 0xeb, 0x09, 0x15, 0xfb, 0x11, 0xb0, 0xe7, 0xe7, 0x0c, 0xdd, 0xca, 0x16, 0xe1, + 0xfe, 0xd9, 0x06, 0x04, 0x1e, 0x06, 0xe3, 0x0d, 0xeb, 0x02, 0xe7, 0x05, 0xfd, + 0xb0, 0xee, 0xd1, 0xf3, 0xa5, 0xee, 0xf1, 0xd2, 0xf3, 0xd6, 0x07, 0x12, 0xf3, + 0x0a, 0xf5, 0x0b, 0xd9, 0x13, 0xbd, 0x10, 0x1a, 0x4d, 0x04, 0xcf, 0x02, 0x00, + 0x0e, 0x2f, 0xfc, 0xec, 0x2d, 0x2c, 0x50, 0x12, 0xdf, 0xf0, 0x23, 0xdc, 0xb8, + 0xf0, 0xcf, 0xcd, 0x06, 0x63, 0x04, 0x42, 0x12, 0x2b, 0x3f, 0x29, 0x48, 0xdd, + 0xd9, 0xcc, 0xc6, 0xf8, 0xb5, 0xff, 0xeb, 0xc6, 0x51, 0xfd, 0x3b, 0xf0, 0x12, + 0x8e, 0x03, 0xea, 0x38, 0x81, 0xea, 0x18, 0x06, 0xcd, 0xc3, 0xfb, 0x08, 0xff, + 0xd5, 0x17, 0xc5, 0xa1, 0xfd, 0x12, 0x08, 0xfb, 0x3c, 0x0a, 0x12, 0xf9, 0xd9, + 0xe5, 0xc8, 0x25, 0x2e, 0xba, 0x1f, 0xfd, 0xf7, 0x03, 0x41, 0xd9, 0x9d, 0x34, + 0xde, 0x39, 0x5c, 0x2b, 0x05, 0x2d, 0x00, 0x34, 0x28, 0xe6, 0x21, 0x38, 0xd2, + 0x09, 0x06, 0xb9, 0x47, 0xdf, 0x07, 0xc7, 0x23, 0xfc, 0x27, 0x32, 0xf5, 0xe0, + 0x24, 0x22, 0xee, 0xde, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x83, 0x0b, 0x00, 0x00, 0xa8, 0x27, 0x00, 0x00, 0x47, 0xe1, 0xff, 0xff, + 0xd6, 0xfd, 0xff, 0xff, 0x40, 0xca, 0xff, 0xff, 0xd3, 0x25, 0x00, 0x00, 0xc2, + 0xff, 0xff, 0xff, 0xeb, 0xc2, 0xff, 0xff, 0xb1, 0x52, 0x00, 0x00, 0x51, 0x09, + 0x00, 0x00, 0x31, 0xea, 0xff, 0xff, 0x65, 0xc3, 0xff, 0xff, 0x59, 0x09, 0x00, + 0x00, 0x6a, 0xe3, 0xff, 0xff, 0x33, 0x02, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x2f, 0x23, 0x00, 0x00, 0x26, 0x02, 0x00, 0x00, 0x66, 0xd9, 0xff, 0xff, 0x7a, + 0xd8, 0xff, 0xff, 0x0b, 0x15, 0x00, 0x00, 0xfd, 0x2e, 0x00, 0x00, 0xd7, 0x2c, + 0x00, 0x00, 0x87, 0xef, 0xff, 0xff, 0x41, 0x23, 0x00, 0x00, 0x3a, 0x9e, 0xff, + 0xff, 0x43, 0xfe, 0xff, 0xff, 0x16, 0x10, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, + 0x72, 0xda, 0xff, 0xff, 0x66, 0xfa, 0xff, 0xff, 0x64, 0xfe, 0xff, 0xff, 0x34, + 0x2d, 0x00, 0x00, 0x62, 0x0b, 0x00, 0x00, 0xa6, 0x08, 0x00, 0x00, 0xf3, 0xd2, + 0xff, 0xff, 0x7d, 0x49, 0x00, 0x00, 0x8a, 0xd6, 0xff, 0xff, 0x06, 0xf0, 0xff, + 0xff, 0x90, 0x3d, 0x00, 0x00, 0xfd, 0x18, 0x00, 0x00, 0xe3, 0xee, 0xff, 0xff, + 0x05, 0x01, 0x00, 0x00, 0x6e, 0xb2, 0xff, 0xff, 0xb3, 0x0a, 0x00, 0x00, 0xaa, + 0xdd, 0xff, 0xff, 0x1c, 0x39, 0x00, 0x00, 0xa0, 0x10, 0x00, 0x00, 0x90, 0x05, + 0x00, 0x00, 0x95, 0x29, 0x00, 0x00, 0x4f, 0xfc, 0xff, 0xff, 0x92, 0x0a, 0x00, + 0x00, 0xb0, 0x0a, 0x00, 0x00, 0x3d, 0x2d, 0x00, 0x00, 0x52, 0x0c, 0x00, 0x00, + 0xdc, 0x25, 0x00, 0x00, 0x4a, 0xdb, 0xff, 0xff, 0x9c, 0x36, 0x00, 0x00, 0xff, + 0xd2, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x14, 0xf2, 0xff, 0xff, 0x3d, 0x0d, + 0x00, 0x00, 0x45, 0x03, 0x00, 0x00, 0x39, 0xe4, 0xff, 0xff, 0xdb, 0x02, 0x00, + 0x00, 0xf0, 0xed, 0xff, 0xff, 0xfb, 0xbf, 0xff, 0xff, 0xd1, 0xee, 0xff, 0xff, + 0x42, 0x1d, 0x00, 0x00, 0x27, 0x0f, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x00, 0xd1, + 0x39, 0x00, 0x00, 0x96, 0xf2, 0xff, 0xff, 0xe6, 0x2b, 0x00, 0x00, 0x0a, 0x27, + 0x00, 0x00, 0x06, 0xe2, 0xff, 0xff, 0x10, 0x0b, 0x00, 0x00, 0x6e, 0xdf, 0xff, + 0xff, 0x57, 0xde, 0xff, 0xff, 0x74, 0xf7, 0xff, 0xff, 0x30, 0xf3, 0xff, 0xff, + 0xbf, 0x13, 0x00, 0x00, 0x3f, 0x05, 0x00, 0x00, 0x0c, 0xe5, 0xff, 0xff, 0xe7, + 0xf8, 0xff, 0xff, 0xd3, 0x1e, 0x00, 0x00, 0xa7, 0x1f, 0x00, 0x00, 0x44, 0x21, + 0x00, 0x00, 0xf1, 0xf6, 0xff, 0xff, 0xe1, 0x1a, 0x00, 0x00, 0x60, 0xbc, 0xff, + 0xff, 0x73, 0x09, 0x00, 0x00, 0x71, 0x06, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, + 0x9e, 0x31, 0x00, 0x00, 0xac, 0xe8, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, 0xff, + 0x21, 0x00, 0x00, 0xa2, 0x5b, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0xff, 0x56, 0x04, + 0x00, 0x00, 0xf1, 0xd9, 0xff, 0xff, 0xca, 0x27, 0x00, 0x00, 0x21, 0xf1, 0xff, + 0xff, 0x40, 0xd0, 0xff, 0xff, 0xdb, 0x06, 0x00, 0x00, 0xec, 0x3e, 0x00, 0x00, + 0x9e, 0x0e, 0x00, 0x00, 0x0b, 0xe9, 0xff, 0xff, 0x7e, 0x4a, 0x00, 0x00, 0x0a, + 0x1e, 0x00, 0x00, 0x30, 0xfe, 0xff, 0xff, 0x95, 0x0b, 0x00, 0x00, 0x06, 0xf8, + 0xff, 0xff, 0x74, 0x43, 0x00, 0x00, 0x71, 0x2a, 0x00, 0x00, 0x8a, 0x16, 0x00, + 0x00, 0x65, 0xf5, 0xff, 0xff, 0x23, 0x02, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, + 0x4f, 0xd5, 0xff, 0xff, 0x5e, 0x0a, 0x00, 0x00, 0x88, 0x32, 0x00, 0x00, 0x7a, + 0x18, 0x00, 0x00, 0x51, 0xd4, 0xff, 0xff, 0xc7, 0x25, 0x00, 0x00, 0xc8, 0x2f, + 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0xfa, 0xe0, 0xfe, 0xff, 0x04, 0x00, 0x00, + 0x00, 0x80, 0x04, 0x00, 0x00, 0x7a, 0x88, 0xba, 0x3f, 0xcb, 0xb5, 0x1d, 0xad, + 0x81, 0xb9, 0xc1, 0x77, 0x18, 0xa7, 0xd0, 0x76, 0xe0, 0xc9, 0x65, 0x02, 0x04, + 0x58, 0xcb, 0x92, 0x70, 0x2b, 0x7f, 0x0d, 0x7f, 0x0f, 0xfd, 0xf2, 0xe0, 0x7f, + 0xc6, 0xe5, 0xd2, 0x81, 0xe6, 0xe8, 0x7f, 0xd1, 0xf3, 0x34, 0xc3, 0x2c, 0x86, + 0x8f, 0x7f, 0xdf, 0x81, 0xa4, 0x7f, 0x19, 0x0d, 0x08, 0x1e, 0x8b, 0xff, 0xbf, + 0x04, 0x2c, 0x70, 0xff, 0x7f, 0xc1, 0xe3, 0xe3, 0xac, 0xd1, 0x71, 0xf6, 0xe3, + 0xb3, 0x8f, 0x22, 0x5a, 0x1b, 0x81, 0x87, 0x3a, 0xd1, 0x12, 0x05, 0x1a, 0x4e, + 0x7d, 0xba, 0x7f, 0xfe, 0xf9, 0x65, 0x0e, 0xbe, 0x90, 0xb0, 0x91, 0xcc, 0xb0, + 0x84, 0xbd, 0x7f, 0x1e, 0x81, 0xec, 0x7f, 0x9e, 0x6f, 0x9e, 0x0a, 0xe9, 0x81, + 0x3f, 0xe3, 0x81, 0x81, 0x34, 0x46, 0xc9, 0xc9, 0x06, 0x96, 0x09, 0x27, 0xbe, + 0x2a, 0xdb, 0x46, 0x74, 0xef, 0xe6, 0xe0, 0x81, 0xa7, 0x58, 0x06, 0xd8, 0x7f, + 0xf5, 0x7c, 0x4c, 0xaa, 0xb5, 0x18, 0x7f, 0xea, 0x7f, 0xf0, 0x19, 0x7f, 0x11, + 0xed, 0xbf, 0x7f, 0x95, 0x77, 0x46, 0x18, 0x62, 0xf5, 0xe2, 0x27, 0x9a, 0x81, + 0xf6, 0xf1, 0x42, 0x00, 0x5c, 0xf9, 0xc1, 0x7f, 0xb7, 0x6b, 0x81, 0x47, 0x68, + 0x23, 0xad, 0xb4, 0x38, 0xf8, 0xfa, 0x37, 0x96, 0x5f, 0x81, 0x16, 0x74, 0x7f, + 0x47, 0x19, 0x2b, 0xb0, 0xa7, 0x8f, 0xb8, 0xd1, 0xca, 0x69, 0x11, 0xf8, 0x81, + 0x81, 0x2e, 0x7f, 0xfe, 0x81, 0x2d, 0xdb, 0xe0, 0xf9, 0x1b, 0x41, 0xeb, 0x06, + 0x24, 0x81, 0x8d, 0x81, 0x19, 0xab, 0x8c, 0x33, 0xa2, 0x81, 0xc8, 0xd3, 0x55, + 0x29, 0x03, 0xe4, 0xdd, 0x26, 0x0b, 0x52, 0x12, 0x07, 0x5a, 0x91, 0x67, 0x0e, + 0x99, 0xbf, 0x7f, 0x3c, 0x50, 0xbe, 0x81, 0x99, 0xac, 0x03, 0x78, 0x0f, 0xbc, + 0xdc, 0x81, 0x81, 0xbc, 0x95, 0x15, 0xc7, 0x7f, 0xe8, 0xc8, 0x76, 0x19, 0xb4, + 0x6b, 0xd6, 0x81, 0x3f, 0xf5, 0x1b, 0xd0, 0xfd, 0x42, 0x58, 0x81, 0x16, 0x95, + 0x7e, 0xe2, 0x7f, 0x18, 0xd9, 0x20, 0xe2, 0x15, 0xde, 0xdd, 0x2b, 0x93, 0x8e, + 0x7f, 0xe1, 0x2c, 0x15, 0x1a, 0x12, 0xc0, 0xfc, 0xfc, 0x20, 0x20, 0x00, 0x24, + 0x52, 0xd6, 0x9b, 0x8f, 0xec, 0x11, 0x2b, 0xaf, 0xda, 0xd6, 0x09, 0x2e, 0x2d, + 0xe9, 0x22, 0x0c, 0x81, 0xf4, 0x1c, 0x81, 0x4e, 0x02, 0x9b, 0xa4, 0x99, 0x48, + 0xe7, 0x17, 0x52, 0x07, 0xd3, 0xd8, 0xc8, 0xeb, 0x7f, 0xfe, 0x01, 0xff, 0xbd, + 0x1f, 0x89, 0xb2, 0xef, 0x8a, 0x83, 0xe1, 0xcd, 0x1c, 0x19, 0x36, 0x8d, 0xdf, + 0x9b, 0xfb, 0x5a, 0xf5, 0x09, 0x97, 0x03, 0xbd, 0x63, 0x14, 0x16, 0xbe, 0xc0, + 0xe8, 0x7f, 0x8c, 0xf0, 0x47, 0xab, 0xf6, 0xc4, 0x7f, 0x2f, 0xb1, 0xdd, 0x75, + 0xd0, 0x7f, 0x1e, 0x30, 0xa4, 0x07, 0x79, 0xb2, 0x0b, 0xce, 0x23, 0xb7, 0x81, + 0xb9, 0xcc, 0xf1, 0xea, 0x03, 0x7e, 0x18, 0x01, 0x36, 0x81, 0xc4, 0xf5, 0xe2, + 0xe5, 0x17, 0x7f, 0xb9, 0x2f, 0x81, 0x41, 0xb9, 0xdb, 0x44, 0x22, 0x76, 0xbc, + 0x71, 0xe7, 0x78, 0x6a, 0x37, 0x40, 0xf8, 0x0d, 0x08, 0xf7, 0xc1, 0x84, 0x0b, + 0x63, 0x5c, 0x27, 0x81, 0x81, 0xdb, 0xa3, 0xb3, 0xe8, 0x41, 0xbb, 0x3a, 0x37, + 0xb5, 0xc1, 0x81, 0xb7, 0x7b, 0x53, 0xe7, 0xce, 0x77, 0x72, 0x7f, 0x4f, 0xd2, + 0xb9, 0x7f, 0xeb, 0x69, 0x7f, 0x09, 0x5a, 0x1b, 0xd4, 0xca, 0xd5, 0xce, 0x1b, + 0x18, 0xb5, 0x1b, 0x1e, 0x82, 0x78, 0xf0, 0xc1, 0xe6, 0x18, 0x7f, 0x22, 0x81, + 0x71, 0x06, 0x60, 0xbf, 0x03, 0x2f, 0x9c, 0x17, 0x5d, 0x52, 0xa2, 0x03, 0x40, + 0x81, 0xa1, 0xf8, 0xdd, 0xe2, 0x7f, 0x34, 0x2e, 0x7f, 0x20, 0x05, 0x8d, 0x3b, + 0x7f, 0x02, 0xbb, 0xcd, 0x7f, 0xfb, 0x2f, 0x57, 0x7f, 0x3d, 0x07, 0xaf, 0x42, + 0x04, 0x81, 0x04, 0xe5, 0x38, 0x26, 0x40, 0x0c, 0x81, 0x21, 0xdd, 0x33, 0xee, + 0x39, 0x3c, 0x4c, 0xb4, 0x1a, 0xf8, 0xd5, 0x81, 0xb2, 0x63, 0xe8, 0x25, 0x2a, + 0x1e, 0x10, 0x2a, 0x7f, 0xdf, 0xe6, 0x36, 0x38, 0x90, 0xc6, 0x12, 0xcf, 0x0b, + 0x35, 0x8c, 0xd9, 0x88, 0x81, 0x94, 0x2f, 0x09, 0x07, 0x43, 0xd2, 0x81, 0x2e, + 0xc2, 0x19, 0x8b, 0x7f, 0x53, 0x81, 0x71, 0x4c, 0x2a, 0x16, 0x31, 0x02, 0x09, + 0xfb, 0x39, 0x40, 0x1b, 0xe4, 0x15, 0x81, 0xe9, 0xcb, 0x81, 0xb3, 0x44, 0xdf, + 0x7f, 0x7f, 0xfb, 0xc7, 0x81, 0x81, 0x31, 0xfd, 0xdc, 0x1b, 0xb1, 0x47, 0x81, + 0xdb, 0x82, 0x25, 0x7f, 0x14, 0x21, 0x2d, 0x01, 0xd2, 0xd4, 0x06, 0xa5, 0xc4, + 0xd8, 0xb2, 0x86, 0x2e, 0x57, 0x2d, 0x4e, 0x0b, 0xb1, 0xfe, 0x00, 0xa3, 0x20, + 0xe1, 0x3f, 0xef, 0xa2, 0xfa, 0x6f, 0xc5, 0x2e, 0xb2, 0xea, 0x3a, 0x32, 0xb7, + 0xef, 0x7f, 0x7f, 0x39, 0xa9, 0xdd, 0xbb, 0x1f, 0xa9, 0x20, 0x24, 0x15, 0x4e, + 0x20, 0xf1, 0xd2, 0x0d, 0x11, 0x47, 0x88, 0x32, 0xc1, 0x75, 0x1b, 0xbb, 0xe9, + 0xe2, 0x0d, 0x1c, 0xe3, 0x21, 0x7f, 0xe5, 0x81, 0x0f, 0xa2, 0xaa, 0xd1, 0xeb, + 0x12, 0xa6, 0xc4, 0xbe, 0x41, 0x16, 0xc3, 0x29, 0x1d, 0xf7, 0x12, 0xd8, 0x6f, + 0x89, 0x6c, 0x30, 0xb6, 0xea, 0x59, 0x45, 0x09, 0x2b, 0x17, 0xf4, 0xd5, 0x33, + 0xd7, 0xe7, 0xe7, 0xe6, 0xb4, 0xd9, 0xff, 0xc2, 0x7c, 0x81, 0x81, 0x65, 0xdb, + 0x81, 0xfa, 0xfe, 0x46, 0xf2, 0xc2, 0xb9, 0xb0, 0xfc, 0xef, 0xc8, 0x9f, 0xb1, + 0x16, 0xd4, 0x6f, 0x7f, 0x46, 0xd7, 0xb0, 0x9b, 0xde, 0xc0, 0x20, 0xd7, 0x81, + 0x0c, 0xc9, 0x71, 0x08, 0xf4, 0xff, 0x21, 0xd8, 0xc4, 0x3f, 0xef, 0x81, 0x8c, + 0xaf, 0xa5, 0xd0, 0xc4, 0xdc, 0xfe, 0x2f, 0xb4, 0x81, 0x0d, 0x06, 0x76, 0x53, + 0xeb, 0xc9, 0x6c, 0xa9, 0xbf, 0xea, 0xe6, 0x08, 0xe5, 0x27, 0x81, 0x7f, 0xac, + 0xf6, 0xd0, 0xf9, 0xd5, 0x8c, 0xf2, 0xd8, 0x41, 0xe9, 0x7f, 0xfe, 0x7f, 0xed, + 0xb2, 0x06, 0xe3, 0x7b, 0xe7, 0xba, 0xfc, 0x7f, 0xfc, 0xf4, 0x9c, 0xb9, 0xcf, + 0x4f, 0x81, 0xe2, 0x81, 0x9a, 0xf7, 0x06, 0xfe, 0x29, 0xdf, 0xfd, 0x78, 0x5f, + 0x1d, 0x94, 0xd2, 0x54, 0x49, 0x9c, 0xb8, 0xbc, 0xc2, 0x21, 0x08, 0x30, 0x1e, + 0xcc, 0x1c, 0x88, 0xd9, 0xf7, 0x03, 0xd9, 0x9d, 0x90, 0x07, 0xc3, 0xd9, 0x98, + 0xc7, 0xb3, 0x81, 0xd2, 0x0c, 0xd3, 0xc7, 0xab, 0x38, 0xab, 0x51, 0x1b, 0xfe, + 0xdc, 0x1e, 0x7f, 0x4f, 0x00, 0x2c, 0x0f, 0xe1, 0xb9, 0xb7, 0xe7, 0xc2, 0xfe, + 0x0d, 0x7f, 0xf2, 0x7f, 0xff, 0xbd, 0xb0, 0x45, 0x16, 0x16, 0xb6, 0x03, 0xf5, + 0xd4, 0x02, 0xf2, 0x81, 0x04, 0xbd, 0xe3, 0x39, 0xae, 0x2b, 0xff, 0x58, 0x07, + 0x39, 0x4a, 0xa2, 0xf0, 0xb2, 0x2d, 0xe7, 0x0f, 0xc4, 0x78, 0x43, 0xe8, 0xae, + 0xe0, 0x88, 0xc5, 0x11, 0x81, 0x8e, 0x1e, 0x06, 0xad, 0x74, 0xe4, 0x8a, 0x59, + 0x18, 0x6e, 0x61, 0xff, 0x47, 0xe9, 0x7f, 0x7f, 0x86, 0xda, 0xda, 0xc1, 0x99, + 0x0b, 0xc2, 0xa0, 0xf8, 0x81, 0xb4, 0x2b, 0xff, 0x7f, 0x38, 0x2f, 0x7f, 0xbc, + 0xcd, 0x4a, 0x21, 0xc1, 0x18, 0x84, 0xd6, 0x7f, 0x7f, 0x6e, 0x7f, 0x09, 0x7f, + 0xbc, 0xdc, 0x3a, 0x8e, 0xa6, 0xd4, 0x50, 0x5a, 0xfd, 0x67, 0xf0, 0x83, 0xa1, + 0x56, 0x0c, 0x08, 0xb5, 0x2b, 0xb4, 0xa8, 0x81, 0x7f, 0x7f, 0x10, 0xc1, 0x1b, + 0x1d, 0xa1, 0x16, 0xde, 0xfd, 0x01, 0x81, 0xad, 0x92, 0x81, 0xf5, 0x70, 0x51, + 0x16, 0x33, 0x09, 0x0e, 0x1b, 0xf7, 0x40, 0x20, 0xf2, 0x88, 0xde, 0xf3, 0x7f, + 0xea, 0xc2, 0xe6, 0xff, 0x93, 0x43, 0x1e, 0xb8, 0x50, 0x06, 0x3d, 0xa5, 0x4d, + 0x92, 0xe3, 0xc6, 0xf8, 0x0e, 0x21, 0xb3, 0xe4, 0x65, 0xe7, 0x81, 0xd6, 0xb5, + 0x2a, 0x0a, 0x24, 0x3d, 0x7f, 0xe5, 0xdd, 0xe5, 0xcf, 0x30, 0x7f, 0xeb, 0x56, + 0x35, 0xa5, 0x36, 0xd0, 0x98, 0x62, 0xec, 0xbd, 0xe4, 0xdd, 0x0d, 0xe7, 0xb9, + 0x81, 0x32, 0x87, 0xb6, 0x3d, 0x23, 0x62, 0xb7, 0x08, 0x4f, 0xba, 0xa0, 0x27, + 0x17, 0x85, 0x78, 0xd1, 0xf7, 0x26, 0x58, 0xe9, 0x1c, 0xf8, 0x41, 0x2c, 0xed, + 0x19, 0xd6, 0x37, 0x0b, 0xe4, 0x1c, 0xf6, 0xfb, 0xd0, 0xb6, 0x3a, 0x56, 0xc1, + 0xfa, 0xac, 0x2d, 0x85, 0x10, 0xa9, 0x4d, 0x58, 0xe1, 0x5f, 0xdf, 0x43, 0xc4, + 0x4d, 0xcb, 0x05, 0x84, 0x8b, 0x0f, 0x3c, 0xf5, 0x11, 0xec, 0x42, 0x1f, 0x07, + 0x86, 0xe5, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x6d, + 0xed, 0xff, 0xff, 0xdb, 0x1e, 0x00, 0x00, 0x18, 0xfe, 0xff, 0xff, 0x76, 0xf4, + 0xff, 0xff, 0xae, 0x0b, 0x00, 0x00, 0x99, 0x20, 0x00, 0x00, 0xc0, 0xfa, 0xff, + 0xff, 0xb1, 0xf6, 0xff, 0xff, 0xed, 0x27, 0x00, 0x00, 0xa2, 0xf4, 0xff, 0xff, + 0xd0, 0xf9, 0xff, 0xff, 0x66, 0xee, 0xff, 0xff, 0xfc, 0xfa, 0xff, 0xff, 0xed, + 0x18, 0x00, 0x00, 0x3a, 0x25, 0x00, 0x00, 0x7f, 0xfb, 0xff, 0xff, 0xd1, 0xf3, + 0xff, 0xff, 0xcf, 0x13, 0x00, 0x00, 0x83, 0xf0, 0xff, 0xff, 0x7d, 0xf0, 0xff, + 0xff, 0xd8, 0xeb, 0xff, 0xff, 0x9a, 0xe8, 0xff, 0xff, 0x66, 0x05, 0x00, 0x00, + 0xe2, 0x15, 0x00, 0x00, 0x28, 0x22, 0x00, 0x00, 0xcf, 0xf4, 0xff, 0xff, 0xca, + 0x0a, 0x00, 0x00, 0xb4, 0xe9, 0xff, 0xff, 0xf8, 0xf3, 0xff, 0xff, 0x63, 0xee, + 0xff, 0xff, 0x31, 0xfd, 0xff, 0xff, 0xd9, 0xed, 0xff, 0xff, 0x3f, 0x15, 0x00, + 0x00, 0x93, 0xf1, 0xff, 0xff, 0x87, 0x1b, 0x00, 0x00, 0x27, 0x12, 0x00, 0x00, + 0x04, 0x16, 0x00, 0x00, 0xfb, 0x1f, 0x00, 0x00, 0x8f, 0xe9, 0xff, 0xff, 0x89, + 0x12, 0x00, 0x00, 0x49, 0xde, 0xff, 0xff, 0x40, 0xfa, 0xff, 0xff, 0xaa, 0xf6, + 0xff, 0xff, 0x6a, 0xf2, 0xff, 0xff, 0xe6, 0xfb, 0xff, 0xff, 0x08, 0xf5, 0xff, + 0xff, 0x5c, 0x23, 0x00, 0x00, 0xdd, 0xf9, 0xff, 0xff, 0xd2, 0xe6, 0xff, 0xff, + 0x41, 0xee, 0xff, 0xff, 0x23, 0x13, 0x00, 0x00, 0xb0, 0x1e, 0x00, 0x00, 0xfb, + 0xed, 0xff, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x5b, 0xfe, 0xff, 0xff, 0xe9, 0xf1, + 0xff, 0xff, 0xed, 0x21, 0x00, 0x00, 0x71, 0x0e, 0x00, 0x00, 0xab, 0x1e, 0x00, + 0x00, 0x1a, 0x18, 0x00, 0x00, 0x09, 0x0f, 0x00, 0x00, 0xc1, 0xf1, 0xff, 0xff, + 0xe8, 0xf4, 0xff, 0xff, 0x88, 0x15, 0x00, 0x00, 0xc7, 0xe9, 0xff, 0xff, 0xbc, + 0x09, 0x00, 0x00, 0x67, 0x1e, 0x00, 0x00, 0xe3, 0x0b, 0x00, 0x00, 0x99, 0x1e, + 0x00, 0x00, 0xda, 0xfc, 0xff, 0xff, 0x18, 0xf8, 0xff, 0xff, 0x84, 0xe0, 0xff, + 0xff, 0x9f, 0xf1, 0xff, 0xff, 0xb7, 0x2b, 0x00, 0x00, 0xc3, 0x15, 0x00, 0x00, + 0x48, 0xe7, 0xff, 0xff, 0x39, 0xdd, 0xff, 0xff, 0x72, 0xfe, 0xff, 0xff, 0x52, + 0x02, 0x00, 0x00, 0xcd, 0x24, 0x00, 0x00, 0x7b, 0xf6, 0xff, 0xff, 0x4f, 0xff, + 0xff, 0xff, 0xa7, 0xea, 0xff, 0xff, 0x04, 0xf1, 0xff, 0xff, 0xd9, 0xf1, 0xff, + 0xff, 0xb5, 0xee, 0xff, 0xff, 0xc0, 0xec, 0xff, 0xff, 0x99, 0x1b, 0x00, 0x00, + 0x8e, 0xfd, 0xff, 0xff, 0xb7, 0x10, 0x00, 0x00, 0x9d, 0x1d, 0x00, 0x00, 0x75, + 0x09, 0x00, 0x00, 0x62, 0x06, 0x00, 0x00, 0xf7, 0x15, 0x00, 0x00, 0x17, 0xfc, + 0xff, 0xff, 0x5a, 0x01, 0x00, 0x00, 0xe4, 0x1d, 0x00, 0x00, 0xe8, 0x14, 0x00, + 0x00, 0x56, 0x1a, 0x00, 0x00, 0xa1, 0x15, 0x00, 0x00, 0x35, 0xf8, 0xff, 0xff, + 0x02, 0xfb, 0xff, 0xff, 0x84, 0xf9, 0xff, 0xff, 0xf8, 0x1c, 0x00, 0x00, 0x3d, + 0x12, 0x00, 0x00, 0xa0, 0xef, 0xff, 0xff, 0xff, 0x11, 0x00, 0x00, 0x81, 0xfc, + 0xff, 0xff, 0x4e, 0x12, 0x00, 0x00, 0x17, 0xf6, 0xff, 0xff, 0x27, 0xf4, 0xff, + 0xff, 0xae, 0x09, 0x00, 0x00, 0x51, 0xe8, 0xff, 0xff, 0x5d, 0xed, 0xff, 0xff, + 0x5d, 0x14, 0x00, 0x00, 0xb7, 0x1a, 0x00, 0x00, 0xdd, 0xfd, 0xff, 0xff, 0xf6, + 0xeb, 0xff, 0xff, 0x0c, 0x18, 0x00, 0x00, 0x21, 0x1f, 0x00, 0x00, 0xfe, 0x10, + 0x00, 0x00, 0xdd, 0x26, 0x00, 0x00, 0xe9, 0x19, 0x00, 0x00, 0x75, 0xf6, 0xff, + 0xff, 0x11, 0xe2, 0xff, 0xff, 0x66, 0xe5, 0xff, 0xff, 0x5d, 0xf3, 0xff, 0xff, + 0x38, 0xf3, 0xff, 0xff, 0x92, 0xe7, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x83, 0xe7, 0xff, 0xff, 0x46, 0xa8, 0xff, 0xff, 0x14, 0x34, + 0x00, 0x00, 0x10, 0xc0, 0xff, 0xff, 0x53, 0x11, 0x00, 0x00, 0xdd, 0x11, 0x00, + 0x00, 0xc2, 0xfc, 0xff, 0xff, 0xbe, 0xe0, 0xff, 0xff, 0x50, 0xa6, 0xff, 0xff, + 0x1a, 0xdd, 0xff, 0xff, 0xfa, 0x08, 0x00, 0x00, 0xb3, 0xff, 0xff, 0xff, 0x51, + 0x9b, 0xff, 0xff, 0x87, 0x11, 0x00, 0x00, 0x50, 0xc7, 0xff, 0xff, 0x3a, 0xe3, + 0xff, 0xff, 0xa8, 0xd9, 0xff, 0xff, 0x4d, 0xac, 0xff, 0xff, 0x4d, 0x2b, 0x00, + 0x00, 0x07, 0x05, 0x00, 0x00, 0x9f, 0xf2, 0xff, 0xff, 0x4b, 0xb8, 0xff, 0xff, + 0x71, 0xf0, 0xff, 0xff, 0xa4, 0x2b, 0x00, 0x00, 0xfc, 0xd5, 0xff, 0xff, 0x24, + 0x0d, 0x00, 0x00, 0xc8, 0xd9, 0xff, 0xff, 0x6e, 0xff, 0xff, 0xff, 0x1b, 0x38, + 0x00, 0x00, 0x4e, 0xbf, 0xff, 0xff, 0x3e, 0x9b, 0x00, 0x00, 0xb4, 0xf5, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xff, 0x2a, 0xd5, 0xff, 0xff, 0x56, 0xc7, 0xff, 0xff, + 0x6d, 0x11, 0x00, 0x00, 0x3c, 0xda, 0xff, 0xff, 0x5a, 0x32, 0x00, 0x00, 0x0a, + 0xf8, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x86, 0xf1, 0xff, 0xff, 0x1d, 0x04, + 0x00, 0x00, 0x4a, 0xe3, 0xff, 0xff, 0xe1, 0xa5, 0xff, 0xff, 0xef, 0x3e, 0x00, + 0x00, 0x27, 0xb7, 0xff, 0xff, 0xf4, 0x28, 0x00, 0x00, 0x86, 0x27, 0x00, 0x00, + 0xb4, 0xed, 0xff, 0xff, 0x29, 0xf4, 0xff, 0xff, 0x5f, 0xe3, 0xff, 0xff, 0x46, + 0x14, 0x00, 0x00, 0xa7, 0x1c, 0x00, 0x00, 0x83, 0x1f, 0x00, 0x00, 0xc6, 0x24, + 0x00, 0x00, 0x63, 0x1c, 0x00, 0x00, 0xf9, 0xf6, 0xff, 0xff, 0xad, 0x0f, 0x00, + 0x00, 0x8a, 0xbb, 0xff, 0xff, 0xf0, 0xe4, 0xff, 0xff, 0xcf, 0xce, 0xff, 0xff, + 0x15, 0xe9, 0xff, 0xff, 0xf4, 0xbf, 0xff, 0xff, 0x77, 0xbf, 0xff, 0xff, 0x01, + 0x0e, 0x00, 0x00, 0xf9, 0x16, 0x00, 0x00, 0x06, 0xd7, 0xff, 0xff, 0x6b, 0xe6, + 0xff, 0xff, 0x34, 0xd2, 0xff, 0xff, 0xb6, 0x2d, 0x00, 0x00, 0xf8, 0x95, 0xff, + 0xff, 0xaa, 0x16, 0x00, 0x00, 0xba, 0x02, 0x00, 0x00, 0x49, 0xe0, 0xff, 0xff, + 0x48, 0x14, 0x00, 0x00, 0x9d, 0x09, 0x00, 0x00, 0x7e, 0x89, 0xff, 0xff, 0x6b, + 0xfb, 0xff, 0xff, 0x66, 0xc7, 0xff, 0xff, 0xe1, 0xe6, 0xff, 0xff, 0x27, 0x2c, + 0x00, 0x00, 0x08, 0xf3, 0xff, 0xff, 0x31, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0xf6, 0xec, 0xff, 0xff, 0x0c, 0x25, 0x00, 0x00, 0x1d, 0x0c, 0x00, 0x00, + 0xd1, 0xc1, 0xff, 0xff, 0x73, 0x87, 0xff, 0xff, 0x65, 0xf8, 0xff, 0xff, 0x79, + 0xbe, 0xff, 0xff, 0xb1, 0xcf, 0xff, 0xff, 0x37, 0xf7, 0xff, 0xff, 0xe6, 0xc0, + 0xff, 0xff, 0x7b, 0xef, 0xff, 0xff, 0x52, 0xe0, 0xff, 0xff, 0x24, 0xa5, 0xff, + 0xff, 0x72, 0xad, 0xff, 0xff, 0x4e, 0x25, 0x00, 0x00, 0x2c, 0xfd, 0xff, 0xff, + 0x52, 0x29, 0x00, 0x00, 0x42, 0xf8, 0xff, 0xff, 0xde, 0xe4, 0xff, 0xff, 0x79, + 0x04, 0x00, 0x00, 0xe1, 0x1b, 0x00, 0x00, 0x5c, 0x10, 0x00, 0x00, 0x2b, 0x2a, + 0x00, 0x00, 0x45, 0x0b, 0x00, 0x00, 0x04, 0xc5, 0xff, 0xff, 0x5c, 0x39, 0x00, + 0x00, 0x50, 0xf1, 0xff, 0xff, 0x17, 0xb8, 0xff, 0xff, 0xf4, 0xf8, 0xff, 0xff, + 0x1b, 0xe6, 0xff, 0xff, 0xb2, 0x0d, 0x00, 0x00, 0xd2, 0xae, 0xff, 0xff, 0x4a, + 0xee, 0xff, 0xff, 0x7d, 0x2e, 0x00, 0x00, 0x8d, 0xe7, 0xff, 0xff, 0x92, 0x03, + 0x00, 0x00, 0xd6, 0x34, 0x00, 0x00, 0x1c, 0xdf, 0xff, 0xff, 0x85, 0xab, 0xff, + 0xff, 0xbf, 0x4b, 0x00, 0x00, 0x9b, 0x3e, 0x00, 0x00, 0x09, 0xd6, 0xff, 0xff, + 0x7a, 0x00, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0x76, 0x36, 0x00, 0x00, 0x80, + 0x94, 0xff, 0xff, 0x6b, 0xf7, 0xff, 0xff, 0x0c, 0x1b, 0x00, 0x00, 0xa6, 0x95, + 0xff, 0xff, 0x64, 0xd4, 0xff, 0xff, 0xc0, 0x0f, 0x00, 0x00, 0xea, 0x1c, 0x00, + 0x00, 0x41, 0x01, 0x00, 0x00, 0xba, 0x1d, 0x00, 0x00, 0x80, 0x2a, 0x00, 0x00, + 0x9a, 0x13, 0x00, 0x00, 0xf0, 0x27, 0x00, 0x00, 0x31, 0x0d, 0x00, 0x00, 0x9f, + 0x13, 0x00, 0x00, 0xde, 0xf1, 0xff, 0xff, 0x9b, 0xcf, 0xff, 0xff, 0xe5, 0xf4, + 0xff, 0xff, 0xbc, 0xc5, 0xff, 0xff, 0xea, 0xf1, 0xff, 0xff, 0x32, 0xf6, 0xff, + 0xff, 0x12, 0xf2, 0xff, 0xff, 0x6e, 0xdf, 0xff, 0xff, 0x44, 0xd2, 0xff, 0xff, + 0xa6, 0x54, 0x00, 0x00, 0x6b, 0x31, 0x00, 0x00, 0x48, 0x09, 0x00, 0x00, 0x77, + 0xee, 0xff, 0xff, 0xbb, 0xbc, 0xff, 0xff, 0x7c, 0xb5, 0xff, 0xff, 0x87, 0x1c, + 0x00, 0x00, 0xba, 0xda, 0xff, 0xff, 0x2e, 0xe9, 0xff, 0xff, 0xd0, 0xff, 0xff, + 0xff, 0x8a, 0xc1, 0xff, 0xff, 0x23, 0x42, 0xff, 0xff, 0xdf, 0xe8, 0xff, 0xff, + 0x13, 0x12, 0x00, 0x00, 0x63, 0xe5, 0xff, 0xff, 0xdf, 0xe9, 0xff, 0xff, 0xcc, + 0xc5, 0xff, 0xff, 0xfd, 0xe2, 0xff, 0xff, 0x43, 0xf5, 0xff, 0xff, 0x30, 0xf5, + 0xff, 0xff, 0x60, 0x1e, 0x00, 0x00, 0x62, 0x9f, 0xff, 0xff, 0xcb, 0x0b, 0x00, + 0x00, 0xd1, 0x5c, 0x00, 0x00, 0xe9, 0xdf, 0xff, 0xff, 0xec, 0x20, 0x00, 0x00, + 0x47, 0xfb, 0xff, 0xff, 0x94, 0x9e, 0xff, 0xff, 0x45, 0x0e, 0x00, 0x00, 0x27, + 0x0b, 0x00, 0x00, 0x26, 0xdb, 0xff, 0xff, 0xdf, 0xbb, 0xff, 0xff, 0x61, 0x51, + 0x00, 0x00, 0xd9, 0x1d, 0x00, 0x00, 0xa9, 0xb5, 0xff, 0xff, 0xb9, 0x5a, 0x00, + 0x00, 0xea, 0xd7, 0xff, 0xff, 0x02, 0xfb, 0xff, 0xff, 0x0c, 0x48, 0x00, 0x00, + 0x29, 0xea, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0xf5, 0x1a, 0x00, 0x00, 0x14, + 0x14, 0x00, 0x00, 0x22, 0x0b, 0x00, 0x00, 0xbc, 0x24, 0x00, 0x00, 0xeb, 0xda, + 0xff, 0xff, 0xed, 0xe8, 0xff, 0xff, 0x13, 0x12, 0x00, 0x00, 0xcd, 0x0a, 0x00, + 0x00, 0x8a, 0x28, 0x00, 0x00, 0x62, 0x03, 0x00, 0x00, 0xd2, 0x8f, 0xff, 0xff, + 0x0f, 0x08, 0x00, 0x00, 0x4c, 0x41, 0x00, 0x00, 0x95, 0xd9, 0xff, 0xff, 0xea, + 0xfc, 0xff, 0xff, 0x6a, 0x01, 0x00, 0x00, 0x4b, 0x95, 0xff, 0xff, 0x6e, 0x0f, + 0x00, 0x00, 0x41, 0x0f, 0x00, 0x00, 0xea, 0xfc, 0xff, 0xff, 0x55, 0xe8, 0xff, + 0xff, 0xab, 0x8a, 0xff, 0xff, 0x77, 0xa9, 0xff, 0xff, 0x6e, 0x38, 0x00, 0x00, + 0xc8, 0x1e, 0x00, 0x00, 0x31, 0xf0, 0xff, 0xff, 0x41, 0x99, 0xff, 0xff, 0x0c, + 0x0a, 0x00, 0x00, 0x51, 0xc6, 0xff, 0xff, 0xdc, 0x28, 0x00, 0x00, 0x22, 0xad, + 0xff, 0xff, 0xee, 0x2b, 0x00, 0x00, 0x99, 0xf0, 0xff, 0xff, 0x0b, 0xf2, 0xff, + 0xff, 0xba, 0x32, 0x00, 0x00, 0xc4, 0x3c, 0x00, 0x00, 0x7c, 0xb2, 0xff, 0xff, + 0xac, 0x07, 0x00, 0x00, 0x6d, 0x0d, 0x00, 0x00, 0xef, 0x15, 0x00, 0x00, 0xce, + 0xf9, 0xff, 0xff, 0x2f, 0x11, 0x00, 0x00, 0x8f, 0x10, 0x00, 0x00, 0xe2, 0x05, + 0x00, 0x00, 0xda, 0xdc, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, 0xc1, 0x10, 0x00, + 0x00, 0xc0, 0xeb, 0xff, 0xff, 0x4b, 0xe1, 0xff, 0xff, 0x72, 0xec, 0xff, 0xff, + 0xeb, 0xe4, 0xff, 0xff, 0x34, 0x31, 0x00, 0x00, 0xe0, 0xf9, 0xff, 0xff, 0x9b, + 0x23, 0x00, 0x00, 0xa3, 0xd8, 0xff, 0xff, 0xb1, 0xb6, 0xff, 0xff, 0xa7, 0xec, + 0xff, 0xff, 0x15, 0x23, 0x00, 0x00, 0xd3, 0xa3, 0xff, 0xff, 0xa2, 0xb1, 0xff, + 0xff, 0x3d, 0x29, 0x00, 0x00, 0xfb, 0xbc, 0xff, 0xff, 0x77, 0x29, 0x00, 0x00, + 0x9e, 0xeb, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x95, + 0xe3, 0x77, 0xf4, 0x7f, 0x81, 0x9d, 0xe6, 0x15, 0xa6, 0xc2, 0xba, 0xf5, 0xf3, + 0xe8, 0x03, 0xf1, 0xfb, 0x0d, 0xf2, 0x23, 0xfb, 0xef, 0x4c, 0xfd, 0xab, 0xd0, + 0x0e, 0xcf, 0xb8, 0x81, 0x84, 0xf1, 0xdf, 0xfb, 0xdb, 0xf8, 0xed, 0xe9, 0x07, + 0x2a, 0xac, 0xd3, 0xee, 0x40, 0x81, 0xc6, 0x20, 0xe7, 0xe4, 0xdd, 0x7f, 0xf8, + 0xe1, 0x24, 0x7f, 0xe7, 0x4f, 0xd3, 0x0c, 0xbc, 0x16, 0xc7, 0xc7, 0xec, 0xca, + 0xa6, 0x84, 0xae, 0xe2, 0x1d, 0x19, 0xb8, 0xe5, 0xc8, 0x89, 0xfb, 0xca, 0xf3, + 0xf9, 0xd6, 0xd1, 0xdf, 0xca, 0x2a, 0x46, 0x81, 0x2a, 0xf8, 0xc2, 0x09, 0xb0, + 0xa9, 0xf4, 0x0b, 0xb7, 0xfd, 0xdf, 0x74, 0xa9, 0xda, 0xed, 0x19, 0xba, 0xa3, + 0x01, 0xf1, 0x9e, 0xec, 0x17, 0x10, 0xf8, 0x95, 0x09, 0x20, 0xc7, 0xa0, 0xb3, + 0xc9, 0x1f, 0xd1, 0xcf, 0xe7, 0xf3, 0x7f, 0xe4, 0xcc, 0xbc, 0x81, 0xe9, 0xd9, + 0xc9, 0xf3, 0x02, 0xd3, 0x46, 0x3c, 0x81, 0xbc, 0xdf, 0xee, 0xe3, 0xdf, 0x02, + 0x23, 0xfe, 0xf8, 0xd4, 0x19, 0xd4, 0xa0, 0x7f, 0x0a, 0x0e, 0x26, 0xe4, 0x16, + 0x8b, 0x81, 0xee, 0xf8, 0xf1, 0xe8, 0xdb, 0xeb, 0x90, 0xc4, 0x2c, 0x9b, 0xf2, + 0xe9, 0x7f, 0x81, 0xb4, 0xf6, 0xaf, 0x8a, 0x51, 0xee, 0xee, 0x21, 0xe1, 0xa7, + 0xfb, 0x89, 0xd3, 0xce, 0x25, 0xcf, 0xa4, 0xb1, 0xe2, 0x6b, 0x14, 0x56, 0x81, + 0xa5, 0x20, 0xe2, 0xd1, 0xe2, 0xb6, 0x7f, 0x35, 0xff, 0xb6, 0xdd, 0x37, 0xf1, + 0x06, 0x18, 0x56, 0x02, 0xfd, 0xdd, 0xd1, 0x8c, 0x93, 0xfc, 0xee, 0xeb, 0xf8, + 0xf1, 0xbb, 0xa8, 0x2c, 0xbb, 0xdf, 0xeb, 0xf2, 0x13, 0xd8, 0xe1, 0x18, 0xfa, + 0x86, 0xd4, 0xb5, 0x81, 0xa2, 0xdb, 0xd5, 0x0a, 0xe0, 0x15, 0x2c, 0xca, 0xe9, + 0x05, 0xec, 0xc6, 0xf0, 0xa5, 0xe2, 0x0e, 0x0b, 0xed, 0x2e, 0x1e, 0xf8, 0x35, + 0xc5, 0xb3, 0x35, 0x33, 0x1f, 0xe4, 0x92, 0x2a, 0xcc, 0xf7, 0x8c, 0x02, 0x23, + 0x81, 0x0b, 0x41, 0xfa, 0x53, 0x0a, 0xfb, 0xe1, 0xd0, 0xd8, 0xf2, 0x8d, 0xc0, + 0x5d, 0xc2, 0xe0, 0x81, 0x81, 0xfd, 0x10, 0xbc, 0x1b, 0x81, 0xef, 0x38, 0x09, + 0xe8, 0x47, 0x9b, 0x35, 0x7f, 0x84, 0xcd, 0x60, 0xce, 0x81, 0x12, 0xb2, 0xa0, + 0x7f, 0xbe, 0x74, 0x7f, 0x81, 0x36, 0x25, 0x25, 0xfd, 0x92, 0x1e, 0xf9, 0xb9, + 0x1d, 0x12, 0xc7, 0xf2, 0x72, 0xfd, 0x74, 0xe0, 0x05, 0xf6, 0xad, 0xd1, 0xec, + 0xe8, 0x1c, 0x15, 0x0c, 0x1d, 0xf1, 0x81, 0xe7, 0x4a, 0x81, 0x0d, 0x0d, 0xbf, + 0xf5, 0x27, 0x0b, 0x44, 0xff, 0x19, 0x81, 0x53, 0xb8, 0x1e, 0xcb, 0x39, 0xeb, + 0x81, 0x7f, 0xfd, 0xd0, 0xd0, 0x81, 0x24, 0x7f, 0xa6, 0xf1, 0x81, 0xcb, 0x46, + 0xc7, 0x88, 0xe6, 0x81, 0x09, 0xff, 0x3c, 0x2a, 0xb1, 0x81, 0xf9, 0xe2, 0x81, + 0xa4, 0x04, 0x8f, 0xcc, 0x7f, 0xd0, 0x47, 0xf2, 0x45, 0xef, 0xd9, 0xa9, 0xec, + 0xf1, 0xc7, 0x68, 0xf4, 0xd0, 0xdf, 0xa0, 0xe1, 0xfd, 0x85, 0x6a, 0xda, 0x45, + 0x97, 0x6c, 0x7f, 0x00, 0xb0, 0x42, 0xf9, 0x7f, 0xe0, 0x16, 0xb7, 0xb1, 0xe7, + 0x89, 0x1e, 0x0a, 0x81, 0x20, 0x08, 0x81, 0xdd, 0x32, 0x3a, 0x9c, 0x03, 0x7f, + 0x08, 0xfb, 0xd2, 0x81, 0x10, 0xfa, 0x1c, 0xa0, 0x9b, 0x81, 0x3a, 0xd7, 0xb5, + 0x43, 0x73, 0x90, 0x36, 0x53, 0x88, 0x15, 0x9d, 0x9b, 0xdf, 0xc3, 0x7f, 0x8e, + 0x42, 0xdf, 0x1e, 0xf0, 0x37, 0x81, 0x60, 0xdc, 0x2f, 0xc5, 0x0e, 0x22, 0x2e, + 0x1b, 0xa9, 0x06, 0x01, 0xd9, 0xbd, 0xf7, 0x7f, 0x7f, 0x81, 0xef, 0x81, 0xc8, + 0x81, 0x06, 0xb1, 0xcb, 0x81, 0xf7, 0x14, 0x4b, 0x0e, 0x11, 0xe4, 0xdb, 0xf4, + 0x34, 0xb9, 0x91, 0xda, 0x0e, 0x30, 0x7f, 0x06, 0x37, 0x41, 0xe4, 0x7f, 0x7e, + 0x7f, 0xe3, 0x81, 0xe2, 0xb8, 0x04, 0x25, 0x7b, 0x00, 0x1d, 0x74, 0xb6, 0x0f, + 0x40, 0xbb, 0xcb, 0xa5, 0x81, 0xc0, 0xef, 0x0e, 0x28, 0x27, 0xdb, 0x56, 0xdd, + 0x2e, 0xd9, 0xed, 0x4b, 0xec, 0x20, 0x5e, 0x32, 0x1f, 0xc3, 0xd6, 0xb1, 0xe4, + 0x3f, 0xe6, 0xff, 0x1c, 0xd6, 0xbc, 0x12, 0xe8, 0x81, 0x20, 0x11, 0x7f, 0x42, + 0x42, 0x3f, 0x08, 0x81, 0x97, 0xd0, 0x7f, 0x81, 0xeb, 0x58, 0xda, 0x57, 0x1d, + 0x08, 0x81, 0x38, 0x81, 0xef, 0xe1, 0x03, 0xa3, 0x32, 0x14, 0x90, 0xf8, 0x48, + 0xe3, 0x09, 0xb1, 0xd1, 0x10, 0x22, 0x26, 0x89, 0xe3, 0x15, 0xc9, 0x08, 0x44, + 0xc1, 0x9f, 0xde, 0x7f, 0xec, 0x7f, 0xdf, 0xfe, 0xf4, 0x21, 0x6e, 0x05, 0xe6, + 0xf1, 0xda, 0x7f, 0xb4, 0x56, 0x47, 0xe7, 0x9d, 0x7f, 0x91, 0x67, 0x03, 0xc2, + 0xed, 0x01, 0xe2, 0xee, 0x81, 0xcc, 0xea, 0xed, 0x8b, 0xbb, 0xad, 0xcf, 0x98, + 0x1d, 0xe1, 0xfa, 0xf4, 0x01, 0x7f, 0x00, 0x7f, 0x6b, 0xc7, 0xfb, 0x7f, 0x97, + 0x16, 0xd8, 0x19, 0x10, 0xf8, 0x60, 0x4d, 0xb2, 0x8c, 0xe6, 0x32, 0x2d, 0x18, + 0x25, 0xc9, 0xa2, 0x7d, 0x61, 0x7f, 0x3d, 0x0d, 0xd8, 0xcd, 0xe6, 0x11, 0x0c, + 0x17, 0xd4, 0x4d, 0xde, 0xf9, 0x79, 0x49, 0x7f, 0xec, 0x81, 0xc4, 0xb0, 0xca, + 0xfd, 0xc2, 0x63, 0xa0, 0xf5, 0xbe, 0x43, 0x12, 0x45, 0xc6, 0x7f, 0xb2, 0x7f, + 0xe6, 0x94, 0x24, 0x1c, 0xda, 0x1b, 0x5a, 0xa8, 0x2d, 0x1d, 0x35, 0xde, 0x36, + 0x4a, 0x0f, 0x22, 0x11, 0xc5, 0x7e, 0xff, 0x5c, 0xbb, 0xd3, 0xa8, 0xd9, 0xb4, + 0x09, 0xdc, 0xbf, 0xed, 0x23, 0xdd, 0xd1, 0xdd, 0x0a, 0x1c, 0x05, 0x81, 0x91, + 0xd3, 0xd0, 0xa3, 0x33, 0xe4, 0x0e, 0x0c, 0x81, 0x15, 0x89, 0xd7, 0x81, 0x39, + 0x0c, 0x3f, 0xef, 0xff, 0xcc, 0xe8, 0x78, 0x48, 0x5c, 0xec, 0x2c, 0x78, 0xed, + 0x7f, 0x7f, 0xd2, 0xca, 0x34, 0xfe, 0x10, 0x9d, 0xcd, 0x0a, 0xb0, 0xed, 0xa3, + 0x86, 0xe5, 0x51, 0x81, 0xa6, 0x0c, 0x46, 0x35, 0x57, 0x88, 0xed, 0x81, 0xb8, + 0xfb, 0x13, 0xa7, 0x2b, 0x2e, 0x0c, 0xae, 0x7f, 0x81, 0x81, 0x7f, 0x7f, 0xed, + 0x84, 0xd9, 0x0f, 0xb2, 0x76, 0x00, 0xc9, 0x19, 0xdb, 0xf1, 0xf1, 0xf2, 0x41, + 0x27, 0x7f, 0x0c, 0x15, 0xfa, 0x36, 0x29, 0x92, 0x1f, 0xe5, 0x19, 0x7f, 0x33, + 0x7f, 0x7f, 0x81, 0x3a, 0x55, 0x8e, 0xa9, 0x7f, 0x25, 0xaa, 0xde, 0x25, 0xa7, + 0xaa, 0x58, 0x00, 0x20, 0x41, 0x0d, 0x08, 0x81, 0x1e, 0x7f, 0xe2, 0xb8, 0xc9, + 0x35, 0xca, 0xb9, 0xa6, 0x31, 0x66, 0x25, 0xdc, 0x54, 0xbc, 0x63, 0x35, 0xa7, + 0xe1, 0x0c, 0xc6, 0xbf, 0xee, 0xd8, 0xb7, 0xe2, 0x0d, 0xf5, 0xe5, 0x00, 0x28, + 0x72, 0x6f, 0xd9, 0xdb, 0xf6, 0x54, 0xe2, 0x8a, 0xe8, 0x0a, 0x70, 0x16, 0xdc, + 0x60, 0xb8, 0xe0, 0x25, 0x73, 0x7f, 0x2c, 0xe6, 0xf3, 0xbd, 0x7f, 0x7f, 0x1e, + 0xcb, 0xc5, 0xdc, 0xdf, 0xaa, 0x1e, 0x69, 0x72, 0xdb, 0x9e, 0xc8, 0xf2, 0xc5, + 0x1e, 0xf0, 0x6e, 0x5c, 0x98, 0x03, 0x54, 0x30, 0x41, 0x7f, 0x7f, 0xe8, 0xc2, + 0x81, 0x32, 0x81, 0xcc, 0xea, 0xf7, 0xb6, 0x7f, 0x04, 0x03, 0x02, 0x83, 0x28, + 0x62, 0x22, 0xd1, 0xbe, 0xd9, 0xf1, 0xfb, 0x5c, 0x3b, 0x81, 0x60, 0x3e, 0x81, + 0xdd, 0xde, 0x7f, 0xe4, 0xa6, 0xe0, 0x54, 0xdc, 0x7f, 0xd7, 0x2b, 0x6d, 0x1b, + 0x7f, 0x81, 0x33, 0xad, 0x7f, 0x9b, 0x83, 0x7f, 0xdc, 0x7f, 0x4c, 0x4b, 0x04, + 0x01, 0x49, 0xef, 0xe5, 0xfe, 0xbf, 0xfc, 0xa5, 0x2f, 0x08, 0x5e, 0xa2, 0xb8, + 0x7f, 0x61, 0x7f, 0xbd, 0x65, 0x0f, 0x7f, 0x3b, 0xd9, 0x53, 0x2d, 0xd8, 0x7f, + 0x89, 0xdf, 0x34, 0x3f, 0x51, 0x0a, 0x7f, 0xb7, 0x68, 0xd3, 0x2a, 0x7f, 0x7f, + 0x38, 0xa5, 0xf4, 0xff, 0x7f, 0x7f, 0xb2, 0x7f, 0xaa, 0xe1, 0x81, 0xfc, 0xe4, + 0x92, 0x7f, 0x7f, 0x7f, 0x0e, 0x38, 0x71, 0xb0, 0x7f, 0x81, 0x98, 0xbe, 0x7f, + 0x7f, 0x81, 0xef, 0xee, 0x1f, 0xf8, 0x3f, 0x4e, 0x14, 0x1d, 0x31, 0x81, 0x9c, + 0xe3, 0xa9, 0xc2, 0x7d, 0x6d, 0x00, 0x28, 0x04, 0x06, 0xc3, 0xb8, 0xeb, 0x53, + 0x12, 0x65, 0x81, 0xdd, 0x7f, 0xe9, 0xaf, 0x75, 0xbb, 0x2e, 0x55, 0xf8, 0x1d, + 0xdd, 0x7f, 0x81, 0x2f, 0xbe, 0x81, 0x64, 0x0f, 0x81, 0x7f, 0x0f, 0x14, 0xc1, + 0x7f, 0x6b, 0x7f, 0xb3, 0x15, 0x10, 0x54, 0xf8, 0x1d, 0x6f, 0xce, 0xa2, 0x81, + 0x33, 0x10, 0x79, 0x77, 0x1a, 0x7f, 0x10, 0x51, 0xd2, 0xd9, 0x38, 0xe8, 0xfc, + 0x35, 0x09, 0x5b, 0xc8, 0x20, 0x7f, 0x7f, 0x33, 0x72, 0xd2, 0xaf, 0x4c, 0x7f, + 0x3f, 0x81, 0x81, 0xa8, 0x71, 0xd5, 0x7f, 0x57, 0x10, 0x43, 0xce, 0x7f, 0xe1, + 0xf3, 0x10, 0xf3, 0xf9, 0xab, 0xd9, 0xdf, 0xa4, 0x7f, 0x76, 0x1a, 0xe4, 0x7f, + 0xac, 0xb8, 0x7f, 0x0b, 0x7f, 0xb0, 0x7f, 0x81, 0x17, 0x9f, 0xf5, 0x9a, 0xd4, + 0x4f, 0x66, 0xea, 0x7f, 0x97, 0x0f, 0x16, 0xdf, 0x52, 0xd3, 0x7f, 0xf0, 0x0f, + 0x20, 0xee, 0x00, 0x23, 0x50, 0x2d, 0x19, 0x48, 0xbd, 0xf2, 0x13, 0x81, 0xdb, + 0x81, 0x51, 0xfe, 0x1e, 0x17, 0x1d, 0x28, 0x7f, 0xd1, 0x11, 0x3d, 0x73, 0x90, + 0xdf, 0x7f, 0x4a, 0x2f, 0x35, 0x0c, 0x97, 0x7f, 0x7f, 0x13, 0xad, 0xdf, 0x86, + 0x14, 0x29, 0xbb, 0x19, 0x7f, 0x05, 0x23, 0x20, 0xfb, 0xf5, 0x10, 0x7f, 0xa5, + 0xfe, 0xf7, 0x1b, 0xfd, 0x0e, 0xbb, 0x20, 0xac, 0x81, 0x00, 0x14, 0x26, 0xd0, + 0x7f, 0x7f, 0x06, 0x16, 0xd3, 0xfe, 0x7f, 0xd6, 0x6c, 0x99, 0xba, 0x0d, 0xf7, + 0x13, 0x39, 0x30, 0xb7, 0x7f, 0xaf, 0x1a, 0x30, 0x59, 0x78, 0x0d, 0x7d, 0x4a, + 0x67, 0xfc, 0x45, 0x32, 0x40, 0xea, 0xd5, 0xf2, 0xf6, 0xa0, 0x75, 0xe0, 0x03, + 0xc8, 0x43, 0xe7, 0x23, 0xee, 0x4e, 0x09, 0x39, 0x45, 0x18, 0xc8, 0xd9, 0x40, + 0xe7, 0xde, 0xe3, 0x03, 0xcf, 0xf8, 0xcb, 0x08, 0x37, 0xc6, 0xc7, 0x7f, 0x19, + 0x6c, 0x0e, 0x7f, 0x17, 0xc1, 0xf8, 0x21, 0xc3, 0xaf, 0x7f, 0x7f, 0xa9, 0x7f, + 0x24, 0x81, 0x40, 0x16, 0x1e, 0x0e, 0x63, 0x56, 0x08, 0xee, 0x52, 0xb4, 0xf3, + 0xf2, 0xb1, 0x44, 0x07, 0xe8, 0x4d, 0xf7, 0x7f, 0xe9, 0xed, 0x7f, 0x1b, 0xcc, + 0x09, 0x0f, 0x7f, 0xc7, 0x15, 0x81, 0x1c, 0x81, 0xa6, 0x37, 0x22, 0x98, 0x7f, + 0x7f, 0x56, 0xca, 0x72, 0xf8, 0x81, 0xab, 0x3a, 0xf5, 0x3b, 0x07, 0xe5, 0xd2, + 0x2b, 0xf6, 0xaf, 0x23, 0x0d, 0x89, 0x7c, 0x7f, 0x77, 0x7c, 0xb7, 0xae, 0x4b, + 0x81, 0x4e, 0xda, 0x7f, 0x4b, 0x42, 0xd3, 0x05, 0x2d, 0x25, 0xf5, 0xdc, 0x4c, + 0x06, 0x7f, 0x0d, 0x5b, 0x20, 0x7f, 0xad, 0x84, 0x06, 0x9b, 0xd6, 0x6e, 0x05, + 0x58, 0x06, 0xeb, 0xe6, 0xa9, 0xd2, 0x01, 0xce, 0xcb, 0x81, 0x7f, 0xb7, 0x89, + 0xd3, 0x0d, 0x36, 0x19, 0xd7, 0x90, 0x55, 0xb2, 0x13, 0xd0, 0x2a, 0x81, 0xe9, + 0xeb, 0x78, 0x31, 0x1b, 0xc2, 0xf5, 0x0f, 0x40, 0xa1, 0x0e, 0x81, 0xd7, 0xeb, + 0xfd, 0xf6, 0x3d, 0xf8, 0xde, 0xdd, 0x7f, 0xb1, 0xff, 0x7f, 0x06, 0x81, 0x7f, + 0xd7, 0x54, 0xfc, 0x38, 0x3d, 0xd4, 0x41, 0xdb, 0xf9, 0xce, 0x64, 0xcf, 0xfd, + 0x6c, 0xd9, 0x81, 0xcd, 0xa5, 0x0a, 0xd0, 0xf7, 0xf6, 0x90, 0x60, 0x7f, 0xfa, + 0xa6, 0x0f, 0xf1, 0x7f, 0xf9, 0xc6, 0x37, 0xd3, 0x25, 0x0b, 0x4a, 0x0d, 0xae, + 0x81, 0x0f, 0x47, 0xf5, 0x38, 0xe7, 0x48, 0x38, 0xae, 0x7f, 0x0d, 0xef, 0x1b, + 0xcd, 0xbc, 0xfd, 0x35, 0xfd, 0x41, 0x20, 0xc9, 0x81, 0x15, 0xe6, 0xfe, 0x08, + 0x25, 0x23, 0x14, 0x7f, 0xb8, 0x1c, 0xf7, 0x6c, 0xf2, 0xe0, 0x1f, 0xca, 0x97, + 0xe6, 0x0d, 0x41, 0xfb, 0x28, 0x57, 0x9d, 0xa0, 0xfe, 0x07, 0xe3, 0x0f, 0xeb, + 0x11, 0x69, 0x3e, 0x0e, 0xf1, 0xcb, 0x1d, 0xef, 0xd2, 0xd3, 0x7f, 0x52, 0x7f, + 0x56, 0x71, 0xdc, 0x4d, 0xf3, 0x22, 0xf5, 0xb0, 0x0f, 0x2c, 0x0a, 0x9d, 0x65, + 0x5d, 0xff, 0x09, 0xde, 0x7f, 0xe1, 0xc2, 0x48, 0xd2, 0x02, 0x0f, 0xfe, 0xe7, + 0xf0, 0xfe, 0xd4, 0x10, 0x3d, 0xd9, 0x0f, 0xdf, 0x4b, 0x97, 0x32, 0xcf, 0xc3, + 0xc2, 0xb2, 0xe8, 0x27, 0xb5, 0x7f, 0xea, 0x05, 0xf3, 0xee, 0x10, 0x71, 0xa7, + 0xa9, 0x1b, 0x7f, 0x93, 0xc4, 0x12, 0x95, 0xb0, 0xe2, 0xd1, 0x10, 0x8e, 0xb7, + 0x7f, 0x43, 0xc0, 0x01, 0xba, 0xf4, 0x2a, 0xa5, 0xd8, 0x4f, 0xc1, 0xc6, 0xf9, + 0x1a, 0xc1, 0xc9, 0xb6, 0x16, 0xd9, 0x2d, 0x7f, 0xcb, 0xd0, 0x52, 0xbc, 0x3a, + 0x2a, 0xe3, 0x23, 0xd0, 0xcd, 0x43, 0x04, 0xc8, 0x2f, 0xf7, 0x50, 0x20, 0x53, + 0x11, 0xc9, 0xfe, 0x04, 0xf8, 0xd0, 0x09, 0x81, 0xbf, 0xaf, 0x12, 0x53, 0x1f, + 0xda, 0x4a, 0xf4, 0xfa, 0x0f, 0x0f, 0x18, 0xd6, 0x50, 0xc9, 0x2b, 0x7f, 0xfe, + 0x85, 0x58, 0x67, 0x1b, 0x7f, 0xfd, 0xf1, 0x05, 0x9f, 0x7f, 0x29, 0x4c, 0x2b, + 0xde, 0x4d, 0xe4, 0x17, 0x32, 0xd2, 0xee, 0x7b, 0xe8, 0x28, 0x81, 0x24, 0x6f, + 0x16, 0x2d, 0x21, 0xb6, 0x11, 0xa9, 0xd2, 0xaf, 0xc0, 0xed, 0xf4, 0x05, 0x7f, + 0xaf, 0x06, 0x2b, 0xb9, 0xb8, 0x38, 0xad, 0x13, 0xf8, 0xfb, 0xeb, 0x81, 0x1e, + 0xca, 0x5b, 0x4b, 0x09, 0x39, 0x01, 0x6d, 0xd9, 0x32, 0xfe, 0x81, 0xec, 0xf8, + 0x36, 0xaf, 0xe4, 0x7f, 0xe8, 0xa3, 0xc1, 0x08, 0xad, 0x43, 0xd7, 0xf1, 0xf7, + 0xde, 0x40, 0x00, 0x81, 0x46, 0xa5, 0xac, 0x8f, 0x1f, 0xc9, 0x5c, 0xe2, 0xe6, + 0xf8, 0xf9, 0xf9, 0x6e, 0x1f, 0x89, 0x52, 0x7f, 0xb9, 0xeb, 0xbd, 0x0d, 0xe7, + 0x0e, 0x0e, 0xfc, 0xe9, 0x95, 0x43, 0x16, 0x2a, 0x24, 0xed, 0x7f, 0x25, 0xf4, + 0x09, 0x49, 0x08, 0x30, 0x70, 0xf0, 0x84, 0x5b, 0x35, 0xa8, 0x81, 0x7e, 0x95, + 0x1d, 0xcd, 0xbb, 0xfd, 0xcf, 0x24, 0xd4, 0xe0, 0xff, 0x57, 0x17, 0xfc, 0xd2, + 0x0f, 0x81, 0xbf, 0x8c, 0xef, 0xbe, 0x6a, 0x7f, 0x61, 0xcb, 0xe6, 0x2e, 0xf3, + 0x2a, 0xb9, 0x22, 0xef, 0x4d, 0x81, 0x0a, 0xee, 0x1e, 0x9d, 0xc9, 0xcb, 0x2e, + 0xe5, 0x0c, 0xee, 0xd7, 0xe6, 0x13, 0x43, 0x7c, 0x1f, 0x00, 0x09, 0x22, 0x28, + 0x07, 0xd4, 0x81, 0x81, 0xd0, 0xad, 0xf3, 0xd9, 0xec, 0x61, 0xa0, 0xab, 0x1d, + 0xd6, 0x43, 0xe3, 0xe9, 0xd7, 0x29, 0xd1, 0xc2, 0xeb, 0xf4, 0x81, 0xdf, 0xf9, + 0x0e, 0x81, 0x11, 0x0d, 0xe4, 0x81, 0xff, 0xfb, 0xe2, 0xd5, 0x2a, 0x5d, 0x5d, + 0x0c, 0xef, 0x99, 0x1e, 0x46, 0xd8, 0x81, 0xb1, 0xfb, 0x48, 0x22, 0xd8, 0xf3, + 0xf0, 0x00, 0xb2, 0xb1, 0xf3, 0xcf, 0xe5, 0xc8, 0x8d, 0x26, 0xba, 0xe9, 0xa2, + 0xba, 0xe0, 0x43, 0xce, 0xb4, 0xfb, 0x7f, 0x7f, 0x81, 0xc1, 0x06, 0x2f, 0x41, + 0x59, 0xe5, 0x17, 0x00, 0x2b, 0x46, 0xc1, 0x7f, 0x09, 0x5c, 0x11, 0xe9, 0x1e, + 0x0f, 0xab, 0xf9, 0x2b, 0x21, 0x59, 0x35, 0xf5, 0x36, 0xc8, 0x1a, 0xb3, 0x81, + 0x81, 0xb3, 0x81, 0x81, 0xbe, 0xdd, 0xce, 0xe1, 0x25, 0x16, 0xfd, 0x22, 0xe6, + 0x91, 0x4f, 0x2d, 0x05, 0xdd, 0x9b, 0xf0, 0xdd, 0xf4, 0x1b, 0x0f, 0xe7, 0x02, + 0x41, 0x19, 0x75, 0xce, 0xb0, 0x97, 0x16, 0x63, 0xe2, 0x36, 0x9a, 0xf4, 0xf6, + 0xb8, 0x75, 0x16, 0x14, 0x1e, 0xfe, 0xcc, 0xcb, 0xd7, 0x42, 0x7f, 0x20, 0xdf, + 0x1f, 0x2a, 0x1f, 0x81, 0x51, 0x7f, 0xec, 0x2e, 0xdf, 0xf0, 0x16, 0xb3, 0x28, + 0x75, 0x40, 0x9f, 0x3a, 0x58, 0x0c, 0x2f, 0x56, 0x81, 0xe7, 0xe5, 0x3e, 0xbe, + 0xdb, 0xfc, 0x09, 0x22, 0xf4, 0xf1, 0x72, 0x0c, 0xf2, 0x8d, 0x32, 0xc2, 0xb8, + 0xbb, 0x9c, 0xd8, 0xa0, 0xf0, 0x10, 0x16, 0xf5, 0xd0, 0x9b, 0x7f, 0xda, 0x14, + 0xce, 0x13, 0xcd, 0xed, 0xc3, 0x5d, 0x1e, 0xf6, 0x13, 0xdb, 0xf0, 0xdb, 0xde, + 0x18, 0xfa, 0x24, 0x5a, 0xe8, 0x3f, 0xee, 0xb1, 0x0c, 0x81, 0x41, 0xea, 0x4a, + 0x4c, 0xe9, 0x1c, 0xff, 0x29, 0xf5, 0xa7, 0xaf, 0xbf, 0xe7, 0xe3, 0xbf, 0x04, + 0x23, 0xd8, 0x23, 0xba, 0xc8, 0xda, 0x31, 0xac, 0x5d, 0x7f, 0x28, 0xcf, 0xb8, + 0x07, 0xf2, 0xfa, 0x91, 0x2b, 0xd0, 0x36, 0xb2, 0x6c, 0x54, 0xce, 0xf4, 0x32, + 0xc8, 0x88, 0x07, 0xe3, 0x07, 0x7f, 0xc0, 0xd6, 0x1d, 0x40, 0x14, 0xcf, 0xf6, + 0xec, 0x97, 0xf7, 0xc5, 0x0f, 0xe1, 0x0e, 0x81, 0xcd, 0xbc, 0x7f, 0x7f, 0xdd, + 0x18, 0x52, 0xa3, 0xe7, 0xba, 0xf1, 0x81, 0x21, 0x18, 0xbb, 0xbd, 0xf6, 0x20, + 0xed, 0x0a, 0x06, 0x04, 0xbb, 0x7f, 0x15, 0xf5, 0xa0, 0x23, 0x2e, 0x3d, 0xdf, + 0x1e, 0xba, 0x4a, 0x5e, 0x40, 0x81, 0x10, 0x10, 0x2d, 0x24, 0xf4, 0x23, 0x29, + 0x85, 0x60, 0xd0, 0x79, 0x19, 0xc9, 0x81, 0x4a, 0x36, 0x3a, 0xf3, 0x5f, 0xaa, + 0xf7, 0xd7, 0xb9, 0x31, 0xca, 0xb9, 0xee, 0xe1, 0x55, 0xed, 0x13, 0xc2, 0x6d, + 0x0a, 0x0d, 0xee, 0xe3, 0xcd, 0x9f, 0x12, 0xa3, 0xd0, 0x28, 0xc3, 0x29, 0x27, + 0xbc, 0x81, 0xbd, 0xd4, 0x4c, 0xf1, 0xe6, 0x7f, 0xc2, 0x34, 0xf5, 0xda, 0xbb, + 0x05, 0xe1, 0xaa, 0xf4, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x4d, 0x01, 0x00, 0x00, 0x79, 0xed, 0xff, 0xff, 0xca, 0xfe, 0xff, 0xff, + 0x59, 0xf6, 0xff, 0xff, 0xc4, 0x12, 0x00, 0x00, 0xf6, 0x08, 0x00, 0x00, 0x87, + 0xf9, 0xff, 0xff, 0x54, 0xf8, 0xff, 0xff, 0x99, 0xeb, 0xff, 0xff, 0x08, 0xfd, + 0xff, 0xff, 0x78, 0xf8, 0xff, 0xff, 0xa9, 0x0a, 0x00, 0x00, 0xf6, 0xf3, 0xff, + 0xff, 0xaa, 0x06, 0x00, 0x00, 0x1e, 0xf9, 0xff, 0xff, 0x54, 0xfd, 0xff, 0xff, + 0x55, 0xf5, 0xff, 0xff, 0x0b, 0xed, 0xff, 0xff, 0x00, 0x09, 0x00, 0x00, 0xa0, + 0xfe, 0xff, 0xff, 0x26, 0x00, 0x00, 0x00, 0x06, 0xfb, 0xff, 0xff, 0x4b, 0xf5, + 0xff, 0xff, 0xa6, 0x0d, 0x00, 0x00, 0x49, 0xf8, 0xff, 0xff, 0xef, 0x09, 0x00, + 0x00, 0x42, 0x0b, 0x00, 0x00, 0x1f, 0x0a, 0x00, 0x00, 0xb6, 0xfc, 0xff, 0xff, + 0x5e, 0x12, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x5d, 0xf5, 0xff, 0xff, 0x5f, + 0xf4, 0xff, 0xff, 0x81, 0xf5, 0xff, 0xff, 0xec, 0x07, 0x00, 0x00, 0x86, 0x06, + 0x00, 0x00, 0x1f, 0xfb, 0xff, 0xff, 0x94, 0x0d, 0x00, 0x00, 0x0d, 0xfe, 0xff, + 0xff, 0x7f, 0x04, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0xdb, 0x0d, 0x00, 0x00, + 0xad, 0xef, 0xff, 0xff, 0xc9, 0xf1, 0xff, 0xff, 0x9e, 0x0b, 0x00, 0x00, 0x30, + 0x0c, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x00, 0x51, 0xfe, 0xff, 0xff, 0x76, 0xfe, + 0xff, 0xff, 0x12, 0xfd, 0xff, 0xff, 0x1c, 0xf9, 0xff, 0xff, 0x44, 0xf8, 0xff, + 0xff, 0xdf, 0xf9, 0xff, 0xff, 0x12, 0x07, 0x00, 0x00, 0x6c, 0x03, 0x00, 0x00, + 0xbf, 0x07, 0x00, 0x00, 0x15, 0x07, 0x00, 0x00, 0x81, 0xf9, 0xff, 0xff, 0xd3, + 0x07, 0x00, 0x00, 0xd5, 0xee, 0xff, 0xff, 0xb3, 0xfb, 0xff, 0xff, 0x80, 0x05, + 0x00, 0x00, 0xb4, 0xf6, 0xff, 0xff, 0xe6, 0xf9, 0xff, 0xff, 0xe5, 0x03, 0x00, + 0x00, 0xc2, 0x07, 0x00, 0x00, 0xbc, 0x05, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, + 0xc9, 0x04, 0x00, 0x00, 0xfb, 0xfc, 0xff, 0xff, 0x8e, 0xee, 0xff, 0xff, 0x1c, + 0x0a, 0x00, 0x00, 0x52, 0x01, 0x00, 0x00, 0xfa, 0xf4, 0xff, 0xff, 0xb5, 0x06, + 0x00, 0x00, 0x65, 0x0d, 0x00, 0x00, 0x82, 0xe8, 0xff, 0xff, 0x20, 0x03, 0x00, + 0x00, 0x2a, 0xf7, 0xff, 0xff, 0x60, 0xf3, 0xff, 0xff, 0xaf, 0x09, 0x00, 0x00, + 0xcd, 0xfb, 0xff, 0xff, 0x43, 0x05, 0x00, 0x00, 0x77, 0x04, 0x00, 0x00, 0x70, + 0x0c, 0x00, 0x00, 0x85, 0xf3, 0xff, 0xff, 0x78, 0x05, 0x00, 0x00, 0x62, 0x06, + 0x00, 0x00, 0x8b, 0xf8, 0xff, 0xff, 0xd1, 0x06, 0x00, 0x00, 0x1b, 0x0f, 0x00, + 0x00, 0x16, 0xfb, 0xff, 0xff, 0x22, 0x06, 0x00, 0x00, 0x1b, 0xf8, 0xff, 0xff, + 0x7a, 0x08, 0x00, 0x00, 0xee, 0xff, 0xff, 0xff, 0xe4, 0xf4, 0xff, 0xff, 0xc0, + 0xf7, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 0x5b, 0x05, 0x00, 0x00, 0xed, 0xf7, + 0xff, 0xff, 0x4f, 0xfc, 0xff, 0xff, 0x31, 0x09, 0x00, 0x00, 0x78, 0x03, 0x00, + 0x00, 0x5c, 0x09, 0x00, 0x00, 0x1d, 0x03, 0x00, 0x00, 0x9b, 0x0d, 0x00, 0x00, + 0xeb, 0x12, 0x00, 0x00, 0xdd, 0xf8, 0xff, 0xff, 0x4b, 0xff, 0xff, 0xff, 0xe7, + 0xee, 0xff, 0xff, 0xf4, 0xf7, 0xff, 0xff, 0x40, 0xfe, 0xff, 0xff, 0xc6, 0xfa, + 0xff, 0xff, 0x2e, 0xfa, 0xff, 0xff, 0x1b, 0xf1, 0xff, 0xff, 0x72, 0x07, 0x00, + 0x00, 0xb3, 0x09, 0x00, 0x00, 0x77, 0xfc, 0xff, 0xff, 0x35, 0x08, 0x00, 0x00, + 0x47, 0x06, 0x00, 0x00, 0x2b, 0xf9, 0xff, 0xff, 0x4e, 0x0f, 0x00, 0x00, 0x78, + 0x0a, 0x00, 0x00, 0xf9, 0x03, 0x00, 0x00, 0x76, 0x0a, 0x00, 0x00, 0xa6, 0xfc, + 0xff, 0xff, 0xfa, 0x03, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xee, 0xff, + 0xff, 0x86, 0x0b, 0x00, 0x00, 0xba, 0x09, 0x00, 0x00, 0x40, 0xfb, 0xff, 0xff, + 0x11, 0xfc, 0xff, 0xff, 0x17, 0x06, 0x00, 0x00, 0xf2, 0x08, 0x00, 0x00, 0x52, + 0x0e, 0x00, 0x00, 0xe3, 0x18, 0x00, 0x00, 0x92, 0x05, 0x00, 0x00, 0x90, 0xfb, + 0xff, 0xff, 0xc9, 0xff, 0xff, 0xff, 0x6c, 0xf4, 0xff, 0xff, 0x8e, 0xfe, 0xff, + 0xff, 0x44, 0xf9, 0xff, 0xff, 0xe7, 0x05, 0x00, 0x00, 0xb1, 0xfc, 0xff, 0xff, + 0x7e, 0xfb, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xbe, 0xfa, 0xff, 0xff, 0x00, + 0x02, 0x00, 0x00, 0xf3, 0xfd, 0xff, 0xff, 0x0a, 0x0f, 0x00, 0x00, 0xca, 0xfc, + 0xff, 0xff, 0x10, 0x03, 0x00, 0x00, 0x6f, 0xfd, 0xff, 0xff, 0x0f, 0xf9, 0xff, + 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x32, 0x0a, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, + 0x74, 0xff, 0xff, 0xff, 0x8d, 0x09, 0x00, 0x00, 0x7b, 0x0a, 0x00, 0x00, 0x20, + 0xe9, 0xff, 0xff, 0x2b, 0xef, 0xff, 0xff, 0x82, 0xfa, 0xff, 0xff, 0xeb, 0x12, + 0x00, 0x00, 0xd2, 0xfc, 0xff, 0xff, 0x88, 0x08, 0x00, 0x00, 0xd6, 0xfa, 0xff, + 0xff, 0x3a, 0x08, 0x00, 0x00, 0x8d, 0xfe, 0xff, 0xff, 0xbd, 0x01, 0x00, 0x00, + 0x51, 0x09, 0x00, 0x00, 0x98, 0x0b, 0x00, 0x00, 0x40, 0xfe, 0xff, 0xff, 0x66, + 0x09, 0x00, 0x00, 0xd4, 0xff, 0xff, 0xff, 0x20, 0x0c, 0x00, 0x00, 0x9b, 0xf8, + 0xff, 0xff, 0x6c, 0xf8, 0xff, 0xff, 0x6d, 0x08, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0xb7, 0x0c, 0x00, 0x00, 0x88, 0xeb, 0xff, 0xff, 0xe2, 0x12, 0x00, 0x00, + 0xa7, 0x01, 0x00, 0x00, 0xf0, 0xfb, 0xff, 0xff, 0xfc, 0xfb, 0xff, 0xff, 0x29, + 0x0e, 0x00, 0x00, 0x89, 0xff, 0xff, 0xff, 0xef, 0x09, 0x00, 0x00, 0xdb, 0xf5, + 0xff, 0xff, 0xba, 0xec, 0xff, 0xff, 0xc1, 0x01, 0x00, 0x00, 0x5a, 0x12, 0x00, + 0x00, 0xc6, 0x04, 0x00, 0x00, 0x26, 0x06, 0x00, 0x00, 0x85, 0xfb, 0xff, 0xff, + 0xf6, 0x05, 0x00, 0x00, 0x98, 0x0d, 0x00, 0x00, 0x15, 0xfe, 0xff, 0xff, 0xc3, + 0xfc, 0xff, 0xff, 0xa9, 0xff, 0xff, 0xff, 0x9d, 0xe8, 0xff, 0xff, 0x22, 0x03, + 0x00, 0x00, 0x77, 0xf8, 0xff, 0xff, 0x3b, 0xf3, 0xff, 0xff, 0x0c, 0x0b, 0x00, + 0x00, 0x48, 0x07, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0xcd, 0xf0, 0xff, 0xff, + 0x0b, 0x01, 0x00, 0x00, 0xb4, 0x04, 0x00, 0x00, 0xb8, 0xf3, 0xff, 0xff, 0x65, + 0xfa, 0xff, 0xff, 0x14, 0xfd, 0xff, 0xff, 0x8f, 0xf8, 0xff, 0xff, 0x02, 0x02, + 0x00, 0x00, 0x76, 0x0a, 0x00, 0x00, 0xc9, 0xeb, 0xff, 0xff, 0x2f, 0xf9, 0xff, + 0xff, 0xd3, 0xf6, 0xff, 0xff, 0xe9, 0x0b, 0x00, 0x00, 0x6e, 0x06, 0x00, 0x00, + 0x04, 0x12, 0x00, 0x00, 0x8c, 0xfc, 0xff, 0xff, 0xa1, 0x09, 0x00, 0x00, 0x8f, + 0x13, 0x00, 0x00, 0xc1, 0xff, 0xff, 0xff, 0x7f, 0xfa, 0xff, 0xff, 0x26, 0xff, + 0xff, 0xff, 0x99, 0x05, 0x00, 0x00, 0x81, 0xf9, 0xff, 0xff, 0x40, 0x00, 0x00, + 0x00, 0xf5, 0xf9, 0xff, 0xff, 0x6f, 0x06, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xff, + 0x86, 0x14, 0x00, 0x00, 0xde, 0x09, 0x00, 0x00, 0xed, 0x08, 0x00, 0x00, 0xc3, + 0xf8, 0xff, 0xff, 0x97, 0x11, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00, 0xe1, 0x0e, + 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1a, 0x0b, 0x00, + 0x00, 0xef, 0xf8, 0xff, 0xff, 0x6b, 0xf2, 0xff, 0xff, 0x84, 0xfa, 0xff, 0xff, + 0xf4, 0x03, 0x00, 0x00, 0xa0, 0xf2, 0xff, 0xff, 0x09, 0xf4, 0xff, 0xff, 0xe5, + 0x01, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, 0xb6, 0xf8, + 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0xe0, 0xe1, + 0x99, 0x03, 0x3c, 0xd2, 0xd9, 0xe7, 0x1b, 0xd9, 0xfc, 0x13, 0xfd, 0xc8, 0xf4, + 0xf1, 0xd0, 0xde, 0x12, 0x10, 0x00, 0x1b, 0xf6, 0xcc, 0xb8, 0xb2, 0x38, 0x35, + 0xf0, 0xfa, 0x07, 0xfe, 0xe4, 0x1b, 0x21, 0x2b, 0xdd, 0xee, 0x36, 0xe1, 0xe5, + 0xc3, 0xfd, 0xff, 0xfe, 0xe7, 0xdb, 0xeb, 0x08, 0xc4, 0xcf, 0xb6, 0xe8, 0xff, + 0x1d, 0x2c, 0xf2, 0xe8, 0xfd, 0x1e, 0x51, 0x30, 0xca, 0x11, 0x30, 0xde, 0xb4, + 0x00, 0xf1, 0xed, 0x25, 0xfc, 0x8b, 0xfd, 0x26, 0xe2, 0xfb, 0x9e, 0xe3, 0xde, + 0xbb, 0x08, 0xf7, 0xef, 0x01, 0x0d, 0xca, 0xde, 0x01, 0xe6, 0x00, 0x34, 0xfa, + 0x31, 0x0b, 0xa5, 0xe9, 0x02, 0x4a, 0x28, 0xf1, 0xaa, 0x08, 0xdf, 0x36, 0xce, + 0xbe, 0xf6, 0x14, 0xf4, 0xd9, 0x2d, 0xbf, 0xe0, 0x25, 0x04, 0xeb, 0xd0, 0xf7, + 0xca, 0xfb, 0x12, 0x25, 0x3b, 0x14, 0xf2, 0xf9, 0x08, 0xf9, 0x00, 0xc4, 0x3c, + 0x0f, 0x23, 0xe8, 0xc8, 0xec, 0x0b, 0xd0, 0x05, 0xbc, 0xeb, 0xfd, 0xb8, 0xfb, + 0x26, 0xe7, 0xea, 0xfb, 0x12, 0x43, 0xf6, 0xc2, 0x10, 0x81, 0xcb, 0xc3, 0x12, + 0xfe, 0x1b, 0xfc, 0xea, 0x12, 0x1c, 0x04, 0xea, 0x46, 0x12, 0x37, 0x28, 0x12, + 0x32, 0x1a, 0xdd, 0x23, 0xe5, 0x01, 0xff, 0xfa, 0x25, 0x33, 0x03, 0x10, 0xed, + 0x0a, 0xde, 0xff, 0x19, 0xcf, 0xd6, 0xdc, 0x2c, 0xf7, 0x09, 0x1a, 0xf1, 0xed, + 0xde, 0xee, 0xe8, 0x14, 0x0e, 0x33, 0xe8, 0xd9, 0xa7, 0xec, 0x45, 0x2f, 0x06, + 0xd9, 0x19, 0xed, 0xd0, 0x2d, 0xcd, 0x1d, 0xe4, 0xc8, 0xee, 0xc4, 0xf2, 0xcb, + 0xff, 0xda, 0x41, 0x4a, 0xd5, 0xe1, 0x15, 0xed, 0xc4, 0x1b, 0x11, 0xdd, 0x24, + 0x30, 0x0a, 0x23, 0xbe, 0xfc, 0x23, 0xf0, 0x56, 0xd1, 0xdd, 0xf4, 0xd8, 0xd1, + 0x19, 0xd5, 0x27, 0x2e, 0xb0, 0xd2, 0x23, 0xe4, 0x30, 0x01, 0xe8, 0xef, 0x41, + 0x23, 0x12, 0xfd, 0xe8, 0xd8, 0xec, 0x4b, 0xdd, 0x02, 0xb9, 0xae, 0x0f, 0xe0, + 0x14, 0xf1, 0x18, 0x33, 0xf8, 0xf7, 0x43, 0xf4, 0x27, 0xf8, 0xed, 0x18, 0xe0, + 0x5b, 0xc4, 0xed, 0xde, 0x17, 0xf0, 0x2f, 0xc5, 0x1a, 0xda, 0xe6, 0xc5, 0xfa, + 0x34, 0xe0, 0xe6, 0xaf, 0xc0, 0xcf, 0x25, 0xe4, 0xed, 0xf4, 0xd6, 0x18, 0x1a, + 0xbb, 0xf4, 0xd3, 0xa8, 0x81, 0xef, 0xd0, 0x27, 0x28, 0xda, 0x45, 0xe8, 0x4f, + 0x0e, 0xd9, 0x20, 0x0a, 0xdc, 0xe0, 0x03, 0x2a, 0xfb, 0xd6, 0x1a, 0x2d, 0x42, + 0xef, 0x1e, 0x20, 0x12, 0xda, 0x2c, 0x02, 0xd8, 0xb6, 0x21, 0x56, 0xd5, 0x9a, + 0x1d, 0x18, 0x02, 0x1c, 0xd3, 0xe4, 0x07, 0x19, 0xfe, 0xd5, 0xfe, 0x02, 0xf1, + 0xf2, 0x20, 0x2f, 0x17, 0x21, 0xc3, 0xdf, 0x27, 0xf6, 0x18, 0x11, 0x9b, 0xe4, + 0x3d, 0x03, 0xe9, 0x31, 0x0d, 0xce, 0x0b, 0x0f, 0xb0, 0xfa, 0x08, 0xe3, 0xf2, + 0x1e, 0x2a, 0xff, 0x50, 0xc1, 0x13, 0x09, 0xf3, 0xea, 0xe8, 0x3f, 0x19, 0x22, + 0xc2, 0x14, 0xfd, 0x2c, 0x0c, 0xb9, 0x09, 0x30, 0x1a, 0xf8, 0xe7, 0xde, 0xbc, + 0x9a, 0xfd, 0xc0, 0x1c, 0x22, 0xee, 0x00, 0x30, 0xc9, 0xf5, 0x3d, 0xdd, 0x32, + 0x13, 0x36, 0xc0, 0xf1, 0x3a, 0x16, 0x0e, 0xd6, 0xb1, 0x12, 0x08, 0x03, 0x03, + 0xfa, 0xf1, 0x24, 0xfc, 0x1c, 0xd5, 0x2b, 0xd0, 0xc2, 0xcc, 0xe9, 0x17, 0x30, + 0x0b, 0xb2, 0x15, 0x6e, 0xeb, 0xf4, 0xf2, 0x2a, 0xb6, 0x2f, 0x17, 0xd8, 0x24, + 0xf3, 0x04, 0x04, 0xd8, 0xc2, 0x02, 0x2d, 0xd9, 0xf0, 0xe8, 0xe0, 0x2c, 0x06, + 0x11, 0xd4, 0xe2, 0x1e, 0x32, 0x2c, 0xf1, 0xc2, 0x10, 0xca, 0xfa, 0xe6, 0x35, + 0xc3, 0xee, 0x14, 0x39, 0x29, 0x1b, 0xf5, 0xc8, 0x24, 0xfa, 0x2b, 0x08, 0x4f, + 0x37, 0xcb, 0x1e, 0x1a, 0xb0, 0xf4, 0xbd, 0xfa, 0xe7, 0xda, 0x06, 0x11, 0xdd, + 0xfd, 0xee, 0xf7, 0x04, 0xce, 0xfe, 0x07, 0x25, 0xd4, 0xec, 0xf6, 0xe7, 0x2e, + 0xec, 0x17, 0xed, 0x1b, 0xe7, 0xdf, 0xf3, 0x0d, 0xdf, 0x16, 0x3a, 0x6a, 0x10, + 0x1e, 0x0f, 0x03, 0xfa, 0xfd, 0x09, 0xcf, 0xde, 0xfc, 0x08, 0xfd, 0xf3, 0x16, + 0xe6, 0x11, 0x04, 0x1d, 0xf9, 0xba, 0xf2, 0x06, 0xfa, 0x21, 0xae, 0x29, 0x0f, + 0xc7, 0xed, 0x09, 0x44, 0xfd, 0x20, 0xe5, 0xf5, 0x2a, 0xcd, 0xd6, 0xec, 0x01, + 0x27, 0xd9, 0xff, 0x02, 0x34, 0xde, 0x31, 0xbc, 0xd6, 0xfc, 0xf5, 0xfd, 0xe2, + 0xf4, 0xe9, 0xbb, 0xfc, 0x37, 0xe9, 0x06, 0xfc, 0xeb, 0xdc, 0xf5, 0xd6, 0xe8, + 0x07, 0x23, 0x15, 0x10, 0xe7, 0xcb, 0xcb, 0x2f, 0x04, 0xe2, 0xff, 0xf1, 0x0d, + 0x3a, 0xfb, 0x01, 0xf9, 0xfe, 0x48, 0xef, 0xf1, 0xea, 0xc9, 0xe4, 0xcc, 0xd9, + 0x06, 0xdd, 0xf1, 0xfe, 0xdd, 0xd0, 0x00, 0x03, 0xce, 0xf8, 0x25, 0xfe, 0xf1, + 0x00, 0xd7, 0xe7, 0x1c, 0xce, 0x16, 0xec, 0x26, 0xdd, 0x23, 0xe1, 0xf0, 0xee, + 0xd0, 0x04, 0xb5, 0xfc, 0xcc, 0x49, 0xfc, 0xf0, 0x01, 0xff, 0xb8, 0xfc, 0x24, + 0x16, 0xde, 0x16, 0x14, 0x31, 0x0a, 0xf2, 0x1d, 0xe4, 0x08, 0xfd, 0xfd, 0x00, + 0xd2, 0x1b, 0x11, 0xf3, 0x37, 0xee, 0x39, 0xfc, 0xde, 0xd6, 0x04, 0xe4, 0xd7, + 0xc6, 0xc8, 0x0f, 0x25, 0x25, 0xdb, 0x14, 0x04, 0x1c, 0xf1, 0xcf, 0xab, 0x66, + 0xe4, 0x1a, 0x03, 0xe8, 0xed, 0x20, 0x1a, 0x0d, 0xfc, 0xd3, 0xd8, 0xc3, 0xf3, + 0x12, 0xaa, 0x2b, 0x0e, 0x11, 0xea, 0xd5, 0xfc, 0xf0, 0xd7, 0xe7, 0x08, 0x33, + 0xcd, 0xec, 0xfe, 0x10, 0xf2, 0xf8, 0x18, 0x17, 0x01, 0xf8, 0xfb, 0x33, 0xaf, + 0x21, 0xdd, 0xef, 0x00, 0xe7, 0x7f, 0xf4, 0x10, 0xf7, 0x09, 0x13, 0xfc, 0x06, + 0x3d, 0xbf, 0x39, 0x9c, 0xd6, 0xd2, 0xf8, 0xfa, 0xc4, 0xdb, 0x01, 0x2b, 0xb8, + 0xef, 0x12, 0x15, 0xf3, 0xd8, 0xca, 0xe4, 0xfc, 0xda, 0x03, 0xaf, 0x0b, 0xff, + 0xcf, 0xfc, 0xca, 0xd1, 0xcf, 0xe5, 0x10, 0xb0, 0xf4, 0x26, 0xf2, 0x04, 0x1f, + 0xcd, 0xca, 0x02, 0x00, 0xe4, 0xd1, 0x2d, 0x01, 0xe5, 0xc1, 0xfa, 0x82, 0xfb, + 0x0d, 0x1e, 0x2f, 0xfa, 0x16, 0x02, 0xd3, 0x12, 0xef, 0xfc, 0x3f, 0xfa, 0x0c, + 0x91, 0xf5, 0x02, 0x0f, 0xf3, 0xb5, 0xcc, 0xc6, 0xc9, 0xee, 0x24, 0xaa, 0xc7, + 0xf8, 0xd9, 0xc4, 0x9d, 0xe8, 0x0c, 0xf1, 0x25, 0xe6, 0x17, 0xdf, 0xaa, 0xf8, + 0x20, 0x02, 0xb2, 0xca, 0xee, 0xdf, 0x07, 0x0d, 0x1a, 0xda, 0xd4, 0xa5, 0xe5, + 0xbb, 0xb2, 0xe0, 0x2b, 0xe9, 0xb1, 0x2a, 0xdb, 0xd1, 0xeb, 0xf1, 0xde, 0xe3, + 0x00, 0xbc, 0x10, 0xd7, 0xc1, 0x2d, 0x9e, 0xe8, 0xf2, 0x09, 0xbd, 0xe6, 0xc0, + 0xea, 0xed, 0xde, 0x3e, 0xf7, 0xc2, 0xdd, 0x24, 0xe0, 0xf5, 0xb1, 0x2c, 0x1a, + 0xd7, 0x2d, 0x2b, 0xe6, 0xd9, 0x0e, 0xdc, 0x19, 0x3e, 0x02, 0xb9, 0xd1, 0xec, + 0xb0, 0x03, 0x09, 0xcc, 0x24, 0xf0, 0xc6, 0xf2, 0xf5, 0x30, 0xb5, 0x03, 0x06, + 0x1f, 0xe2, 0xc8, 0xb4, 0xe8, 0xfd, 0x38, 0xf9, 0xfa, 0x09, 0xf5, 0xf4, 0xd0, + 0xec, 0xde, 0x05, 0xed, 0xcc, 0xf4, 0xee, 0xde, 0xfb, 0xd7, 0x06, 0xba, 0x07, + 0xd3, 0xf3, 0xeb, 0x1a, 0x43, 0x29, 0x04, 0x22, 0xaa, 0xbb, 0xea, 0xf4, 0xbe, + 0x1d, 0xf9, 0x11, 0xf9, 0xeb, 0xc4, 0x0a, 0xa0, 0xfd, 0xfb, 0x16, 0xd7, 0x12, + 0x07, 0xe8, 0x46, 0xef, 0xed, 0x5a, 0xd0, 0x10, 0xd6, 0xbc, 0x08, 0x27, 0x08, + 0x5a, 0x00, 0xe7, 0x1a, 0xbb, 0x81, 0x11, 0xd4, 0x3f, 0xe7, 0xfb, 0xef, 0xce, + 0xd0, 0x21, 0xd5, 0xfb, 0x65, 0xf8, 0x0f, 0x16, 0x4f, 0xdb, 0xf4, 0xde, 0xfe, + 0x2c, 0xc5, 0xf7, 0x06, 0xd0, 0x2d, 0xf5, 0xe1, 0x92, 0x27, 0x28, 0xea, 0xfe, + 0xf3, 0x0c, 0xc6, 0xd9, 0xeb, 0xd9, 0xef, 0xf5, 0x23, 0x00, 0x06, 0x1b, 0x24, + 0xd1, 0xff, 0xdf, 0x57, 0xb7, 0x17, 0xd8, 0x0c, 0x12, 0x48, 0xf0, 0xbe, 0x18, + 0x1a, 0x58, 0xf0, 0xc6, 0xd3, 0xc2, 0x1d, 0x17, 0xfa, 0x42, 0xdf, 0x20, 0xe8, + 0xdb, 0xf1, 0xdf, 0x04, 0xcf, 0x0b, 0xdd, 0xe0, 0x00, 0x5e, 0x02, 0x68, 0xc4, + 0x0c, 0x1b, 0x14, 0x11, 0x35, 0xf9, 0x4a, 0xb3, 0xf0, 0xb9, 0x91, 0x1e, 0xff, + 0xe3, 0x2f, 0x0f, 0xf0, 0xed, 0xd1, 0xe9, 0x21, 0xd5, 0x06, 0x1f, 0xef, 0xad, + 0x18, 0xf2, 0x99, 0xc5, 0xea, 0xf2, 0x71, 0xef, 0xe5, 0x2a, 0x2a, 0x4e, 0x7f, + 0x40, 0x44, 0xc9, 0x2b, 0xde, 0x2e, 0x0e, 0xf3, 0x61, 0x45, 0xd0, 0xe7, 0x3a, + 0xac, 0x21, 0x5a, 0xe2, 0x0f, 0xe5, 0x18, 0xdf, 0xd5, 0xd9, 0x1e, 0xe9, 0xe7, + 0x2d, 0x29, 0xe5, 0xa1, 0x06, 0x00, 0xcc, 0x02, 0x01, 0xc8, 0x05, 0xd5, 0x4f, + 0xbc, 0xee, 0xfd, 0x5f, 0xbf, 0x34, 0xd1, 0x10, 0xf1, 0xe6, 0x64, 0xf2, 0x1f, + 0x08, 0x3c, 0xb6, 0x05, 0x4d, 0x00, 0x0c, 0xe5, 0x0d, 0xde, 0xf3, 0x06, 0x7e, + 0x44, 0xc2, 0xae, 0xe4, 0xef, 0xd2, 0xe9, 0xfd, 0xff, 0x34, 0x9a, 0xd8, 0x28, + 0x24, 0x0a, 0xe8, 0xe8, 0xa2, 0xd9, 0xed, 0x06, 0xee, 0xd9, 0xfc, 0xf7, 0x0d, + 0xa6, 0xfb, 0x2c, 0xfd, 0xb2, 0xcc, 0xfc, 0xd8, 0x13, 0xdd, 0xde, 0xe8, 0xe4, + 0x17, 0xee, 0x20, 0x49, 0xd6, 0x41, 0x30, 0xe7, 0xfc, 0x05, 0xdb, 0xe0, 0x21, + 0xe4, 0xcc, 0xcc, 0xee, 0xcc, 0xf2, 0xb3, 0xed, 0x04, 0xf8, 0xc2, 0x72, 0x0c, + 0xea, 0x4d, 0x31, 0x2c, 0xb7, 0x37, 0xdd, 0xbe, 0xfe, 0xe6, 0x22, 0x20, 0xf6, + 0xea, 0x02, 0x05, 0x65, 0xda, 0xd1, 0xff, 0xee, 0x34, 0x0c, 0x92, 0x85, 0xed, + 0xde, 0x1b, 0xd3, 0x65, 0xe1, 0xb2, 0x25, 0x23, 0x02, 0xb0, 0xbf, 0x41, 0xb2, + 0xc7, 0xfb, 0x10, 0x04, 0x1b, 0xc1, 0xe6, 0xde, 0xaf, 0x0d, 0x01, 0x8f, 0xff, + 0xd8, 0xf6, 0xa0, 0x1d, 0xd5, 0x03, 0xdd, 0xc6, 0xf8, 0x05, 0xc6, 0x25, 0x3f, + 0x05, 0x9f, 0xfd, 0x1c, 0xd0, 0x0c, 0xc2, 0xe0, 0x09, 0xec, 0x1e, 0xcf, 0x30, + 0x18, 0xdb, 0x5a, 0x09, 0x87, 0xda, 0xd8, 0xc8, 0x00, 0x47, 0x2d, 0x09, 0x09, + 0xf0, 0x1e, 0x0d, 0xfa, 0xfd, 0xc3, 0xbd, 0xfe, 0x4f, 0x3b, 0x03, 0x1e, 0xe0, + 0x8f, 0xcb, 0x97, 0x05, 0xbc, 0xea, 0xec, 0x2b, 0xfd, 0x1b, 0xb2, 0x04, 0x9e, + 0xe7, 0xf3, 0x38, 0xe7, 0x46, 0x37, 0x24, 0x1c, 0x44, 0xa7, 0xeb, 0x03, 0xd7, + 0x27, 0xed, 0x0d, 0x14, 0xbd, 0xbf, 0xea, 0x11, 0x0b, 0xd6, 0x33, 0x2f, 0x62, + 0xdd, 0x3e, 0xf9, 0x3e, 0x23, 0x10, 0xf3, 0x30, 0xf3, 0x3f, 0xe2, 0xe4, 0x14, + 0xf9, 0x3f, 0x13, 0xd3, 0xfe, 0xd0, 0x27, 0x0f, 0x81, 0xd5, 0xf6, 0xf9, 0xe0, + 0xec, 0x19, 0x92, 0x50, 0x90, 0x27, 0x48, 0xf8, 0x13, 0xd6, 0x90, 0x4b, 0x07, + 0x25, 0x07, 0x08, 0xd0, 0x23, 0xdc, 0xfe, 0xe9, 0xe1, 0x12, 0x23, 0x2f, 0x85, + 0xdd, 0xc6, 0x32, 0x30, 0xea, 0x28, 0x0b, 0xd7, 0xf5, 0xe8, 0xa1, 0x0f, 0xe2, + 0x18, 0x38, 0xed, 0xda, 0x1a, 0xe6, 0x1f, 0xb7, 0x06, 0xdc, 0xe5, 0xda, 0xbc, + 0x15, 0x83, 0x18, 0xfa, 0xbd, 0xc6, 0xe7, 0xf0, 0x53, 0xe9, 0x07, 0x2a, 0x38, + 0xfe, 0x16, 0xd7, 0xe4, 0xfa, 0x2b, 0xfc, 0x9b, 0x17, 0x3b, 0x1d, 0x13, 0xa9, + 0x16, 0xb6, 0x57, 0xcf, 0xff, 0x21, 0xde, 0x45, 0x30, 0x81, 0x0f, 0x14, 0xe7, + 0xec, 0xf7, 0xeb, 0xc8, 0xb7, 0xed, 0xda, 0xbb, 0xa2, 0x06, 0x03, 0xfa, 0x59, + 0xfa, 0xf8, 0xa5, 0xf2, 0x06, 0xf0, 0xd2, 0xdb, 0x38, 0xaf, 0xf1, 0x29, 0x39, + 0xf9, 0xe8, 0xfb, 0xcf, 0x1a, 0xe5, 0xff, 0xab, 0xb8, 0xf5, 0x13, 0xba, 0xb9, + 0xe6, 0xd6, 0xe5, 0xeb, 0x11, 0x9b, 0xc4, 0x1c, 0x36, 0x26, 0x2c, 0x15, 0xf7, + 0x17, 0xf9, 0xf1, 0x0b, 0x07, 0x9c, 0x23, 0xfd, 0xbd, 0xe0, 0xb8, 0xfb, 0x33, + 0xc9, 0x08, 0xd7, 0xf4, 0x29, 0xeb, 0xf9, 0x22, 0xe4, 0x0f, 0xd3, 0x4a, 0xe3, + 0x31, 0x12, 0x3d, 0x39, 0xfc, 0xba, 0xe6, 0xaf, 0xd5, 0x1d, 0x15, 0xe4, 0xed, + 0xfa, 0xe1, 0xf3, 0x65, 0xa2, 0xc9, 0xca, 0xf3, 0x32, 0xc4, 0xf8, 0xb6, 0xf3, + 0x25, 0x2f, 0x1e, 0xc3, 0xc3, 0xdb, 0x06, 0xe0, 0x31, 0xe7, 0x2c, 0x3d, 0xfd, + 0xde, 0xdd, 0x34, 0xd1, 0x17, 0xcf, 0x0a, 0xc6, 0xfe, 0x04, 0xdd, 0x25, 0x10, + 0xde, 0x08, 0xe9, 0x28, 0xc8, 0xe7, 0x25, 0x81, 0xad, 0xe6, 0x12, 0xfe, 0x61, + 0x19, 0xb1, 0x05, 0x55, 0x75, 0x29, 0xc9, 0xe3, 0xe7, 0xf6, 0xc8, 0x95, 0x01, + 0x19, 0xe1, 0x06, 0xe2, 0x02, 0x4a, 0x59, 0x28, 0xe8, 0x16, 0x19, 0x21, 0xe8, + 0xd6, 0x89, 0x61, 0xb7, 0xe7, 0xcf, 0xbb, 0xcd, 0xe2, 0xbe, 0x70, 0x09, 0xf8, + 0x3b, 0xd4, 0x15, 0xee, 0x1a, 0x3c, 0x15, 0x3d, 0xff, 0xcc, 0xb9, 0x9e, 0x3d, + 0xcc, 0xe9, 0x0e, 0xf6, 0x01, 0x94, 0xf0, 0xf7, 0x0c, 0xb6, 0x14, 0x12, 0x26, + 0xe8, 0x2c, 0xd6, 0xce, 0xee, 0xd7, 0x4a, 0xae, 0x37, 0xa9, 0x12, 0x0c, 0x09, + 0xb0, 0x17, 0x0b, 0xce, 0xc6, 0x11, 0xd6, 0x40, 0x0e, 0x13, 0x1e, 0x07, 0x1a, + 0xf3, 0xdb, 0x26, 0x12, 0xc6, 0xf7, 0xff, 0xf3, 0x05, 0x2d, 0xc9, 0xe4, 0xf4, + 0xf8, 0x45, 0x12, 0x03, 0x23, 0x16, 0xc0, 0xeb, 0x25, 0x1a, 0xe4, 0xf0, 0x06, + 0x07, 0x04, 0x56, 0xaa, 0x0f, 0x20, 0x07, 0xba, 0x12, 0xcb, 0x0d, 0x1b, 0x46, + 0xd7, 0xf1, 0x29, 0xf6, 0xe6, 0x3d, 0xf5, 0xd0, 0x2f, 0xe6, 0x0f, 0x96, 0xe0, + 0x0c, 0xde, 0x34, 0xd1, 0x1c, 0xa5, 0xb3, 0x03, 0x5e, 0xd2, 0xd5, 0xaf, 0xf4, + 0xed, 0x25, 0xd2, 0x0d, 0x18, 0xdc, 0xa4, 0x09, 0x05, 0xcb, 0x2e, 0x1c, 0xe6, + 0xd0, 0xc2, 0xba, 0x22, 0xc6, 0xb9, 0xf4, 0xd2, 0x37, 0x17, 0x4b, 0xf7, 0x16, + 0xe8, 0xe6, 0x0e, 0x32, 0x5d, 0x0c, 0x6b, 0x3b, 0x1d, 0x68, 0xf7, 0xf1, 0xd0, + 0xaa, 0x25, 0x10, 0x0a, 0x36, 0xe9, 0xd0, 0x2a, 0xf8, 0xb5, 0x06, 0xe6, 0x54, + 0xec, 0xe8, 0x40, 0xfc, 0x1d, 0xcc, 0xd3, 0x0b, 0x17, 0x46, 0xc6, 0x54, 0xf9, + 0xec, 0xee, 0x07, 0x2f, 0xf5, 0x2b, 0xf7, 0x0f, 0xeb, 0x0d, 0xe9, 0xe2, 0xea, + 0xdb, 0xf0, 0xbf, 0x24, 0xe7, 0xd9, 0x22, 0x11, 0xed, 0x32, 0xff, 0xe8, 0x3a, + 0xec, 0x0a, 0xf6, 0xe8, 0xc9, 0xf1, 0xca, 0xee, 0x1b, 0x0d, 0xf2, 0xf4, 0x1a, + 0x57, 0x1a, 0x01, 0xcc, 0xcb, 0xb5, 0xcc, 0x2a, 0xcd, 0xf1, 0xd4, 0x24, 0x19, + 0xa6, 0xf6, 0x2a, 0x15, 0x3a, 0x07, 0x28, 0xcf, 0xdf, 0x24, 0x20, 0x0e, 0xe7, + 0x1e, 0xf1, 0x00, 0x0a, 0x4f, 0xfb, 0x0f, 0x19, 0x13, 0xbd, 0xc8, 0x1a, 0xdb, + 0x11, 0xf8, 0x01, 0xd1, 0x12, 0xb8, 0x3d, 0x31, 0x24, 0xd9, 0xf0, 0x2a, 0xfb, + 0xf2, 0x32, 0xf3, 0x07, 0x25, 0xd6, 0x09, 0x29, 0x2d, 0x22, 0xe2, 0x1a, 0x08, + 0x62, 0x1d, 0x7f, 0x18, 0x0e, 0x0a, 0x40, 0x0b, 0xd2, 0xac, 0x31, 0x47, 0xe9, + 0xf1, 0xf6, 0xff, 0x25, 0x06, 0x17, 0xce, 0xd9, 0xc2, 0xfe, 0xf8, 0x26, 0x23, + 0xc0, 0xfd, 0xca, 0xd1, 0xbf, 0x02, 0xe4, 0x15, 0xf1, 0xc7, 0xf9, 0xeb, 0x60, + 0xdc, 0x47, 0xe0, 0xdf, 0xe2, 0x16, 0xf5, 0xe4, 0xda, 0x42, 0x51, 0x37, 0xf0, + 0xeb, 0xdc, 0x27, 0xb1, 0x1a, 0xf8, 0xeb, 0xb9, 0xee, 0x33, 0xef, 0xdd, 0x90, + 0xd3, 0x22, 0xc8, 0xb8, 0xe5, 0xf5, 0x13, 0x06, 0x07, 0xda, 0xfa, 0x04, 0xf0, + 0xaf, 0x35, 0xd0, 0xd0, 0x14, 0x08, 0x2d, 0xf6, 0xed, 0x27, 0x27, 0xf8, 0xcb, + 0x23, 0xfb, 0x07, 0x2a, 0x27, 0x0c, 0xfc, 0xd9, 0xd4, 0x1f, 0xde, 0x0b, 0x0d, + 0x12, 0xd1, 0x08, 0x2b, 0xd1, 0x11, 0x03, 0xf3, 0x04, 0x45, 0xff, 0xd9, 0xef, + 0x19, 0x01, 0xec, 0x3d, 0xf3, 0x1a, 0xb7, 0xd8, 0xc2, 0xca, 0x18, 0x27, 0x01, + 0x29, 0x09, 0xd8, 0x14, 0xda, 0x11, 0x2d, 0x63, 0x40, 0xd6, 0xd0, 0xd4, 0xf7, + 0x1d, 0xde, 0xe1, 0xdc, 0xa6, 0x24, 0x13, 0xbb, 0xe4, 0x27, 0x3d, 0xf1, 0xd4, + 0x44, 0xd6, 0x17, 0xc4, 0xc5, 0xf8, 0xda, 0xc9, 0x4f, 0xe2, 0x13, 0x10, 0xf8, + 0xd0, 0x23, 0xdc, 0xf2, 0x26, 0x61, 0x1f, 0x02, 0xd1, 0xe0, 0xe6, 0xfb, 0xfe, + 0x1d, 0xac, 0xfb, 0xbd, 0x0d, 0x08, 0xe0, 0xb6, 0x2f, 0x11, 0xb5, 0x04, 0x4d, + 0xc0, 0xc9, 0xdf, 0xd8, 0xfe, 0xd5, 0xbb, 0xbf, 0x15, 0x0f, 0xf4, 0xf8, 0xd5, + 0xa2, 0xda, 0xbb, 0xd0, 0xae, 0xb9, 0xec, 0x07, 0xe2, 0x23, 0x16, 0x21, 0x0a, + 0x42, 0xae, 0xba, 0xb1, 0xea, 0x1b, 0x6b, 0x31, 0xb1, 0x0a, 0x17, 0x3a, 0xdc, + 0xae, 0x12, 0x03, 0xcf, 0xd2, 0xf6, 0xd4, 0xdf, 0x3a, 0xb6, 0xf8, 0x2d, 0xe2, + 0xa4, 0xe3, 0xf7, 0xfb, 0xd7, 0x0b, 0x9d, 0xde, 0xd7, 0xc9, 0x56, 0xee, 0x98, + 0x1c, 0x08, 0xab, 0xc2, 0x59, 0xa3, 0x30, 0x3f, 0x2d, 0xd0, 0x08, 0x1e, 0xed, + 0xdc, 0x1e, 0xc0, 0x64, 0xc9, 0x4e, 0xd7, 0xe7, 0xeb, 0xe2, 0xe8, 0x20, 0xe2, + 0xcd, 0xfc, 0x37, 0xc9, 0x5a, 0x1f, 0x23, 0x14, 0x0c, 0xee, 0xe7, 0x06, 0xc8, + 0xc7, 0x12, 0x9a, 0xfa, 0xd9, 0xff, 0xe9, 0x3c, 0xff, 0xff, 0x7f, 0xc3, 0xe8, + 0xe3, 0x01, 0xa0, 0x19, 0x3e, 0x16, 0xce, 0x1b, 0xe8, 0x27, 0x52, 0xec, 0x49, + 0xf5, 0xe9, 0x3c, 0xc3, 0xab, 0x3f, 0xfc, 0x02, 0x05, 0xbe, 0x49, 0x08, 0xd7, + 0x20, 0xea, 0x0f, 0x43, 0xd3, 0xf6, 0x03, 0x43, 0x2f, 0x07, 0x0e, 0xdb, 0xb5, + 0x1c, 0x3e, 0x19, 0xbe, 0xe8, 0xe9, 0x12, 0xed, 0xd5, 0x08, 0x02, 0xf6, 0xf9, + 0x01, 0xde, 0x01, 0xcf, 0xe6, 0x83, 0x35, 0x9d, 0xc9, 0xbf, 0x8a, 0xbe, 0xf2, + 0xf4, 0x11, 0xd1, 0x0e, 0xa4, 0xdd, 0x0d, 0xb4, 0xd2, 0x95, 0xf4, 0xb4, 0x2a, + 0xa3, 0xc9, 0xe0, 0x25, 0xbd, 0xf9, 0xaf, 0xba, 0x2f, 0xf4, 0xeb, 0x03, 0xf3, + 0x37, 0xd9, 0xaf, 0xd7, 0x0c, 0xcb, 0x19, 0xd1, 0x0c, 0xeb, 0x1e, 0x0a, 0x2b, + 0xf1, 0x16, 0x0f, 0x11, 0xea, 0x00, 0x81, 0xfe, 0xc5, 0x31, 0xe8, 0x8c, 0xb9, + 0x21, 0xfe, 0xd8, 0xfa, 0x9e, 0xf9, 0x23, 0x16, 0x15, 0x1c, 0x10, 0xe3, 0xf2, + 0x23, 0x15, 0xe3, 0x0e, 0xdf, 0x47, 0x42, 0x2e, 0x28, 0x0d, 0xc1, 0x28, 0x25, + 0xe6, 0xd2, 0xe9, 0xe9, 0xe2, 0xf4, 0xef, 0x38, 0x04, 0xc6, 0x0d, 0x25, 0xff, + 0xc7, 0x15, 0xe2, 0x06, 0xe5, 0x0b, 0x99, 0xb8, 0x2c, 0xf6, 0x56, 0x19, 0x14, + 0x1b, 0x05, 0x07, 0xec, 0xed, 0xfe, 0x4a, 0x0b, 0x18, 0x29, 0xeb, 0xda, 0xd8, + 0x68, 0xe0, 0xfe, 0xec, 0xc1, 0x01, 0xd8, 0xe7, 0x48, 0x12, 0x1f, 0x1c, 0x33, + 0x05, 0xb5, 0x16, 0x08, 0x90, 0xc7, 0x3b, 0xc8, 0xf1, 0x16, 0x26, 0xa2, 0xb9, + 0xc0, 0x0b, 0xba, 0xe4, 0xd9, 0x0f, 0xb3, 0x17, 0xdc, 0xea, 0x2c, 0xf8, 0xe7, + 0x18, 0xec, 0x1b, 0xaa, 0xf3, 0x50, 0x0a, 0x34, 0x30, 0xca, 0xf0, 0xfe, 0xb3, + 0x3b, 0x22, 0xde, 0x20, 0x14, 0x0f, 0x41, 0xe9, 0x29, 0xf9, 0x2a, 0x0b, 0x05, + 0x34, 0x00, 0xa9, 0xff, 0x06, 0xdf, 0x3f, 0xed, 0x37, 0xfe, 0x07, 0xc9, 0x12, + 0xfd, 0x02, 0x42, 0xbc, 0xe7, 0xc7, 0x03, 0xdc, 0xe6, 0x1d, 0xd8, 0x34, 0x07, + 0xa0, 0xd9, 0xf6, 0xe6, 0xe5, 0xb0, 0xe7, 0xa4, 0xfc, 0x02, 0xed, 0xf0, 0xaa, + 0xed, 0xff, 0x05, 0xca, 0x3a, 0xc7, 0x10, 0xed, 0x1d, 0x48, 0xe8, 0x16, 0xe1, + 0xdc, 0x13, 0x24, 0xfa, 0x2a, 0x3d, 0xdd, 0x0a, 0xeb, 0xe0, 0x22, 0xe5, 0x03, + 0xe9, 0x2a, 0x06, 0x2e, 0x3d, 0x07, 0xd4, 0x05, 0x55, 0xea, 0x38, 0x12, 0xcd, + 0xff, 0xb7, 0x11, 0x06, 0xb2, 0x12, 0xb7, 0xc6, 0x09, 0x06, 0xc6, 0xfe, 0xdb, + 0xe5, 0xbc, 0xd3, 0xcc, 0x06, 0xe9, 0xd1, 0xdf, 0xda, 0x2f, 0x2f, 0xf8, 0x10, + 0xd8, 0xc4, 0x04, 0xf8, 0xe7, 0x40, 0xcc, 0xbe, 0xc6, 0xe7, 0xea, 0xd6, 0xd3, + 0xff, 0xed, 0x01, 0xec, 0x00, 0x05, 0x16, 0xfe, 0xc6, 0xe6, 0x14, 0xea, 0xd7, + 0xcc, 0xd4, 0xfc, 0x4e, 0xbf, 0xd6, 0xce, 0x35, 0xbc, 0x29, 0xed, 0x12, 0xcc, + 0xf5, 0x0f, 0xee, 0xc4, 0xd0, 0xaf, 0x0b, 0x1d, 0xfa, 0xbb, 0xfc, 0xde, 0x2f, + 0x11, 0xf7, 0x36, 0xe2, 0xdc, 0x02, 0xfd, 0x05, 0xfe, 0xf4, 0x1c, 0xd5, 0x24, + 0x28, 0xca, 0x14, 0xf7, 0xdf, 0x0a, 0xe0, 0x0f, 0x7f, 0xbe, 0x2e, 0xf7, 0x0f, + 0x0d, 0xd5, 0xf6, 0x12, 0xdc, 0x02, 0x16, 0x03, 0xc8, 0xe8, 0xfe, 0xe1, 0xf9, + 0xc7, 0xfa, 0xa9, 0x1c, 0x20, 0x18, 0xe2, 0xde, 0x11, 0xf6, 0xbf, 0xd3, 0xdc, + 0x09, 0x20, 0xe4, 0x06, 0xdb, 0x49, 0xd2, 0xcf, 0xd8, 0xf7, 0xea, 0xee, 0xdd, + 0xf6, 0x03, 0xc5, 0xd8, 0xf8, 0xd5, 0xf1, 0xbe, 0x0e, 0x14, 0xfb, 0x50, 0x28, + 0x17, 0xfa, 0x10, 0xc9, 0xda, 0xff, 0xdb, 0x14, 0x03, 0xf1, 0xd8, 0x4e, 0x1c, + 0x00, 0xfb, 0xef, 0xbb, 0x0b, 0xf9, 0xcd, 0xf9, 0xd9, 0xff, 0x12, 0xf1, 0x16, + 0xea, 0xf6, 0x5b, 0xd7, 0xf6, 0xe7, 0xd1, 0x9f, 0x97, 0x0f, 0x59, 0xfe, 0xb6, + 0xdc, 0x84, 0xa7, 0x1c, 0x19, 0x0a, 0xba, 0xe9, 0x05, 0xfd, 0x30, 0xc8, 0xc5, + 0xd1, 0x90, 0xc1, 0xda, 0x07, 0x09, 0x14, 0x40, 0xf7, 0xe3, 0xd6, 0x32, 0xe0, + 0x0d, 0xda, 0x59, 0xf9, 0xf5, 0xd1, 0xff, 0xf9, 0xb8, 0x88, 0xfe, 0x34, 0xff, + 0xdd, 0xf3, 0x14, 0x30, 0x25, 0x1a, 0x14, 0x23, 0x51, 0xc3, 0xfa, 0x0c, 0x81, + 0x29, 0x24, 0x89, 0x18, 0x52, 0x44, 0xa0, 0x1a, 0xfd, 0xf3, 0xfa, 0x66, 0x1a, + 0x27, 0xd1, 0xd6, 0xa8, 0xcf, 0xf5, 0xbb, 0xeb, 0xd7, 0x1c, 0xcb, 0x71, 0xd1, + 0x10, 0xd9, 0x38, 0x40, 0x24, 0x0c, 0x2f, 0xed, 0x22, 0x1f, 0xd8, 0xdb, 0x5b, + 0xf5, 0xe2, 0x87, 0xf1, 0x04, 0xcb, 0xd6, 0x05, 0x17, 0xef, 0x4e, 0xe0, 0x8b, + 0xa5, 0x3a, 0xf0, 0xfc, 0xff, 0x62, 0x14, 0x18, 0xcb, 0xa1, 0x03, 0x1a, 0x0f, + 0x2b, 0x0a, 0x06, 0x27, 0x23, 0x1f, 0xf0, 0x50, 0xd7, 0x09, 0xb2, 0x05, 0xeb, + 0x42, 0x16, 0x43, 0xea, 0xb0, 0x08, 0x0f, 0x5a, 0x91, 0xdc, 0xdc, 0x54, 0xa6, + 0xc4, 0xdc, 0xed, 0x1d, 0xa3, 0x33, 0xf4, 0xff, 0xd8, 0xef, 0x10, 0xf3, 0x35, + 0xd0, 0x24, 0xff, 0x25, 0xf3, 0x07, 0xe9, 0xf7, 0x44, 0xf3, 0x03, 0x20, 0x09, + 0xc4, 0x48, 0x36, 0x69, 0x31, 0x29, 0xb2, 0xea, 0x0c, 0xc5, 0xbe, 0x09, 0x10, + 0xfd, 0xb7, 0x93, 0x1d, 0x1d, 0x04, 0xf4, 0x47, 0xea, 0x19, 0xcf, 0xd0, 0x1d, + 0xd3, 0x04, 0x1c, 0xf0, 0x66, 0x12, 0x03, 0xad, 0xcf, 0xc1, 0xdf, 0xb0, 0x08, + 0xee, 0xf6, 0xf1, 0xef, 0xcf, 0xfe, 0xfb, 0xe0, 0x06, 0x28, 0xc8, 0x10, 0xe5, + 0xac, 0xa3, 0xd4, 0xce, 0x22, 0xe6, 0xa8, 0x1c, 0x3b, 0x3b, 0x14, 0xe8, 0x0c, + 0xf4, 0xb3, 0xee, 0x1d, 0x92, 0x27, 0x57, 0x04, 0x27, 0xf3, 0x4c, 0xdb, 0xfa, + 0xf5, 0xc4, 0xd5, 0xc7, 0xdf, 0xf5, 0xd3, 0x14, 0xd4, 0xd6, 0xf3, 0x42, 0xed, + 0x15, 0xf1, 0xee, 0xd3, 0x5d, 0xed, 0xc6, 0x6b, 0x08, 0xd3, 0xdc, 0x88, 0xd4, + 0xe2, 0xf6, 0xc7, 0xfb, 0xd9, 0xf7, 0xc5, 0x2d, 0xd4, 0xec, 0xf8, 0xd6, 0x4a, + 0xff, 0xc6, 0x0a, 0xf7, 0xdc, 0xc3, 0xcf, 0x13, 0x0f, 0x01, 0xe6, 0x08, 0xfa, + 0xfd, 0x03, 0x07, 0xf4, 0x0d, 0xf5, 0x37, 0xc2, 0xc1, 0xf4, 0xf7, 0x2d, 0x01, + 0x2d, 0x15, 0xfc, 0xc5, 0x09, 0x3b, 0xf1, 0xac, 0x3c, 0x05, 0xe2, 0xd3, 0x17, + 0xfd, 0xd5, 0xe1, 0x2f, 0x13, 0x17, 0x1a, 0xec, 0xf0, 0xfb, 0xf0, 0xc3, 0x2c, + 0x01, 0x5b, 0xf5, 0x05, 0x31, 0x53, 0xc1, 0xc9, 0xf4, 0x1c, 0xef, 0xef, 0xd1, + 0x19, 0xf7, 0x06, 0x1d, 0x11, 0xdb, 0x04, 0x1d, 0xbc, 0xd1, 0xfb, 0x0c, 0x09, + 0x25, 0xf8, 0x33, 0x3c, 0x0c, 0x27, 0xf1, 0x12, 0xbd, 0x1d, 0xdf, 0x2e, 0x7f, + 0xde, 0x17, 0x03, 0xcf, 0xfd, 0x06, 0xf0, 0xe3, 0xe7, 0xfd, 0xc5, 0xfa, 0x1e, + 0xd0, 0x23, 0x32, 0x10, 0x14, 0x2d, 0xe7, 0x14, 0xf6, 0x19, 0xdb, 0x31, 0x14, + 0xe0, 0x02, 0xdc, 0x05, 0xf8, 0xf3, 0x0a, 0xe3, 0xe5, 0xbe, 0x17, 0xcf, 0x3a, + 0xc8, 0xd4, 0xc5, 0xdf, 0x10, 0xc1, 0xf7, 0xf0, 0xbd, 0xf7, 0xf1, 0xc3, 0xd3, + 0xb7, 0x17, 0xe0, 0x22, 0xe6, 0x38, 0xcc, 0x00, 0xba, 0xd0, 0x23, 0xfe, 0xe4, + 0x17, 0x1a, 0xed, 0x28, 0xee, 0x09, 0xee, 0x4e, 0xc8, 0xfa, 0x34, 0xf5, 0x32, + 0xe9, 0x1d, 0x14, 0x02, 0xf7, 0x23, 0xfb, 0xf7, 0x0a, 0x04, 0xf6, 0xde, 0x8e, + 0xdb, 0xe8, 0x4d, 0x1c, 0xf8, 0xf6, 0x03, 0x53, 0xf2, 0x11, 0xc1, 0xd6, 0xe3, + 0x28, 0xba, 0xde, 0xff, 0xcc, 0xd1, 0x68, 0xfb, 0xd5, 0xd9, 0xe7, 0xf8, 0xfe, + 0xec, 0x3e, 0xea, 0xc5, 0x01, 0xed, 0xe4, 0x2d, 0xd8, 0xd7, 0xd5, 0xed, 0x17, + 0xe9, 0x25, 0xfe, 0xdf, 0xcc, 0x01, 0xe3, 0x0c, 0xf9, 0xb7, 0xb8, 0xfc, 0xf7, + 0x89, 0x1c, 0x13, 0xab, 0x14, 0xc6, 0xde, 0x1d, 0xb0, 0x3c, 0xb0, 0x05, 0x04, + 0x0a, 0x18, 0x16, 0xff, 0xda, 0xf7, 0xe1, 0xe6, 0x17, 0xee, 0x4e, 0x9d, 0x45, + 0xd0, 0xf4, 0x3b, 0xe9, 0x0a, 0x14, 0xbe, 0x04, 0x23, 0x38, 0x0d, 0x2a, 0xf9, + 0xe9, 0x29, 0xee, 0xc4, 0xf8, 0x0c, 0xaa, 0x13, 0xb4, 0x4c, 0xe2, 0xf5, 0x26, + 0xf6, 0x0c, 0x26, 0x06, 0xdc, 0xf0, 0xde, 0xf1, 0xff, 0x1b, 0xb3, 0xd6, 0xf5, + 0xf2, 0x2d, 0xdc, 0x28, 0x45, 0x0e, 0x18, 0xfb, 0x27, 0xd2, 0x39, 0x0e, 0x9d, + 0x48, 0x2c, 0xd0, 0x06, 0x3c, 0x3a, 0x5b, 0xa6, 0xcf, 0xea, 0x7f, 0xcd, 0x31, + 0xe4, 0x1a, 0x1a, 0xf9, 0x05, 0xaa, 0xca, 0x11, 0xee, 0x40, 0xaf, 0xce, 0xc8, + 0x3b, 0x1a, 0x4c, 0xd8, 0x32, 0x37, 0xc9, 0xfb, 0x95, 0xf6, 0x05, 0xdc, 0xb5, + 0x1b, 0xf2, 0x4b, 0xf1, 0x03, 0x0b, 0x3b, 0x29, 0xd0, 0x24, 0x40, 0x2e, 0xdd, + 0xca, 0xc5, 0xfe, 0x07, 0x0b, 0xe8, 0x99, 0xc8, 0x09, 0xd8, 0xdd, 0x63, 0x50, + 0xf5, 0x3e, 0x47, 0xb9, 0xea, 0xf0, 0xed, 0x40, 0xfe, 0x4d, 0x0e, 0xce, 0xfc, + 0xed, 0xbf, 0xde, 0xeb, 0x01, 0x13, 0x01, 0xcd, 0x44, 0xdb, 0x3e, 0xc0, 0x07, + 0xc0, 0x39, 0x0d, 0xfb, 0xf2, 0x04, 0xa8, 0xbc, 0xf3, 0x2d, 0xc3, 0x3c, 0x01, + 0x41, 0x1b, 0x1a, 0xf0, 0x65, 0x14, 0x0c, 0xf5, 0x01, 0x5e, 0x04, 0xb4, 0xf8, + 0x3b, 0x19, 0x13, 0x19, 0xbe, 0xa0, 0x12, 0xe2, 0x0f, 0xab, 0xcf, 0xb0, 0xd5, + 0xf2, 0x12, 0xf0, 0x18, 0x1d, 0xa0, 0x07, 0xe1, 0xf6, 0x08, 0x08, 0x0a, 0x0f, + 0x57, 0x00, 0xd9, 0x1f, 0x88, 0xf5, 0x1f, 0xd7, 0x07, 0x1e, 0xe3, 0xe3, 0x00, + 0x12, 0xe4, 0x08, 0xf2, 0x11, 0x29, 0xd3, 0x98, 0xd0, 0xed, 0xd9, 0xe1, 0x24, + 0x43, 0xfa, 0xd3, 0x0e, 0xed, 0xc2, 0x20, 0xaf, 0xfc, 0xaf, 0x1b, 0xf9, 0xb8, + 0xbd, 0xb2, 0xac, 0xf1, 0x05, 0xf6, 0xc5, 0x2a, 0x16, 0xa0, 0x2d, 0xc9, 0x20, + 0xff, 0x16, 0x22, 0x06, 0xd5, 0xea, 0xf9, 0xa2, 0x1e, 0xe8, 0xb1, 0x1f, 0xd8, + 0xca, 0xc7, 0xf4, 0xa3, 0x24, 0x0b, 0xff, 0xdf, 0x03, 0x10, 0xd6, 0xf3, 0xcf, + 0xbe, 0x25, 0x18, 0x17, 0x41, 0x04, 0x01, 0x41, 0x40, 0xdf, 0xe8, 0xb3, 0x29, + 0x0f, 0x15, 0x64, 0xca, 0x1b, 0x2f, 0xf2, 0x04, 0xe4, 0xd3, 0x51, 0xf2, 0x48, + 0x33, 0x06, 0x27, 0xbc, 0x1e, 0x26, 0x0f, 0x10, 0xc5, 0xd3, 0x0a, 0xe2, 0xc1, + 0x3b, 0xd1, 0x9f, 0xed, 0xc4, 0xec, 0x45, 0xd4, 0x08, 0x1b, 0xf3, 0xf9, 0xf6, + 0xa4, 0xd0, 0xf8, 0xdd, 0xd7, 0x24, 0xf2, 0xc4, 0xf8, 0xe0, 0xe8, 0x1a, 0x13, + 0x3d, 0x07, 0x34, 0x1e, 0x98, 0x0b, 0x1a, 0xb8, 0xdc, 0xf3, 0x10, 0x79, 0xca, + 0xfe, 0x04, 0xf7, 0x44, 0xb0, 0x27, 0x31, 0x23, 0xf2, 0xed, 0x14, 0xd2, 0xe1, + 0xf8, 0xfe, 0xf7, 0xf6, 0x9e, 0xf8, 0xe5, 0xe4, 0x35, 0xe4, 0x24, 0xc7, 0x84, + 0xf4, 0xe6, 0x3a, 0x01, 0xcc, 0xc5, 0xe5, 0xd5, 0xd9, 0x02, 0x3f, 0x05, 0xef, + 0x42, 0xba, 0x23, 0xdd, 0x13, 0x37, 0x42, 0xce, 0xff, 0xd1, 0xfe, 0xe8, 0x28, + 0xd5, 0xc2, 0x14, 0xe2, 0x17, 0xbf, 0x10, 0x0a, 0xe9, 0x0f, 0xdd, 0x7f, 0x44, + 0x58, 0xe3, 0x28, 0xdf, 0x49, 0x3f, 0xe2, 0xd4, 0x2d, 0x2f, 0x07, 0xc1, 0x22, + 0xf3, 0xc2, 0x00, 0xda, 0x99, 0xff, 0xea, 0xb5, 0xf4, 0x35, 0xbe, 0xf1, 0xf3, + 0x12, 0xf2, 0x1e, 0x2e, 0xfd, 0xf0, 0xb2, 0xcf, 0xf7, 0xb4, 0x3f, 0x8a, 0xd8, + 0xd4, 0xe8, 0xf4, 0x14, 0xc6, 0x08, 0xf8, 0xf4, 0x0b, 0xdd, 0xf1, 0xef, 0x07, + 0x07, 0xf5, 0x08, 0x15, 0xe0, 0xdd, 0x37, 0x01, 0xf8, 0xcd, 0xac, 0x19, 0x2e, + 0xd5, 0x14, 0x1f, 0xaa, 0x15, 0x0d, 0x29, 0x1b, 0x28, 0xd2, 0xe0, 0xe6, 0x19, + 0x29, 0xd7, 0x16, 0x1e, 0x1c, 0x5b, 0x40, 0x2e, 0x18, 0x36, 0x02, 0x07, 0x58, + 0x31, 0x81, 0xb7, 0x20, 0xd4, 0x01, 0xe2, 0xaf, 0x44, 0xfd, 0x38, 0x98, 0x46, + 0xa7, 0x50, 0xf4, 0xe0, 0x31, 0xf4, 0xd9, 0x24, 0x26, 0x17, 0x59, 0x30, 0xaa, + 0xc3, 0xf5, 0xf2, 0xf2, 0xe6, 0x32, 0xfe, 0x45, 0x38, 0xa1, 0xc8, 0xee, 0xf2, + 0xce, 0x10, 0xc5, 0x0f, 0xc1, 0xcf, 0x08, 0xd9, 0x3b, 0x2a, 0xb8, 0x3b, 0x0d, + 0xff, 0x3d, 0x08, 0x12, 0x37, 0xed, 0xae, 0x1d, 0x0d, 0xd3, 0xa8, 0x0c, 0x19, + 0xa6, 0x1a, 0x07, 0xe5, 0xdc, 0xf2, 0xd6, 0x67, 0x1d, 0xed, 0x44, 0xe3, 0x1e, + 0xf5, 0xcf, 0x06, 0xfa, 0xff, 0xc3, 0x26, 0xe0, 0xe2, 0xd2, 0xf5, 0x01, 0x38, + 0xf8, 0x20, 0x47, 0xc9, 0xfe, 0x2f, 0xb0, 0xcc, 0xf2, 0x22, 0x60, 0x95, 0x0f, + 0x26, 0xa1, 0x00, 0xdd, 0xfc, 0xf2, 0xff, 0xd1, 0x0e, 0xe5, 0x08, 0xc6, 0xdc, + 0x1a, 0xec, 0x35, 0xdc, 0xe5, 0x01, 0xba, 0xdb, 0xf3, 0xde, 0x07, 0x26, 0x0b, + 0xf0, 0x02, 0x10, 0x08, 0xe1, 0x1b, 0x0c, 0xac, 0xc9, 0xfb, 0xef, 0xd8, 0x92, + 0x07, 0x1b, 0x38, 0xf3, 0xdc, 0xb6, 0xc4, 0xe5, 0x13, 0xc0, 0xc4, 0x3e, 0xd3, + 0xdd, 0xf0, 0xdd, 0xdc, 0x01, 0x1a, 0xd6, 0x15, 0x9a, 0x19, 0x19, 0xe7, 0x32, + 0xb3, 0x0a, 0xe4, 0x04, 0xc9, 0x1b, 0x05, 0xf9, 0xdd, 0xd7, 0xf0, 0x09, 0x02, + 0xb1, 0xaf, 0xad, 0xca, 0xfd, 0x10, 0x90, 0x1b, 0xc8, 0x37, 0x05, 0xcf, 0xb2, + 0x97, 0xec, 0xf4, 0x38, 0xd6, 0xeb, 0xe2, 0xf0, 0x0c, 0x53, 0x1e, 0xec, 0xbc, + 0x2d, 0x27, 0xa9, 0xec, 0xe1, 0xff, 0x8a, 0xe0, 0xf9, 0x07, 0xcc, 0xda, 0xd6, + 0xdf, 0x00, 0xec, 0xef, 0x01, 0x0d, 0x00, 0xed, 0xe8, 0xe6, 0xd4, 0x12, 0x0f, + 0xfa, 0xcb, 0xfe, 0x31, 0xdc, 0x30, 0xce, 0x17, 0x02, 0xd0, 0xf1, 0xe2, 0xfb, + 0xff, 0xe3, 0x14, 0xf7, 0x0c, 0x07, 0x1f, 0xf4, 0xd4, 0xd2, 0xf4, 0x11, 0x06, + 0x1d, 0x05, 0xd6, 0x37, 0xeb, 0x10, 0xd9, 0xfa, 0xd4, 0xfe, 0x6d, 0x18, 0xf8, + 0xf9, 0x23, 0xcc, 0x35, 0xce, 0x07, 0xeb, 0xf2, 0xf6, 0x1e, 0x12, 0x06, 0x0e, + 0x07, 0x05, 0xe9, 0x01, 0x06, 0x36, 0xfb, 0x4c, 0xd9, 0x07, 0xd7, 0x22, 0xc9, + 0xcd, 0xff, 0x0a, 0x07, 0xfa, 0x3d, 0xd4, 0x08, 0xbd, 0xf1, 0x01, 0x06, 0xd8, + 0xdf, 0x07, 0x0f, 0xeb, 0xe7, 0x7b, 0xf2, 0xd7, 0xdd, 0xf0, 0xf3, 0x1e, 0x15, + 0x1d, 0xf9, 0xf1, 0xf1, 0x1f, 0xd1, 0xc5, 0xe7, 0xea, 0xcb, 0xe9, 0xd1, 0xed, + 0xf3, 0x14, 0x05, 0xee, 0x1f, 0x46, 0xf9, 0xeb, 0x1e, 0xc3, 0xea, 0x03, 0x10, + 0xc2, 0xe0, 0xbe, 0x13, 0xe3, 0x0e, 0xe4, 0xdd, 0x54, 0x12, 0x16, 0x07, 0x1e, + 0x04, 0x2d, 0x19, 0xf7, 0xf2, 0x12, 0xed, 0x1a, 0xda, 0x21, 0xf6, 0xfd, 0x11, + 0xeb, 0x02, 0xfe, 0x04, 0xef, 0xe3, 0x07, 0xf9, 0x33, 0xf0, 0xe6, 0xfc, 0x1f, + 0x0d, 0x2f, 0x02, 0x12, 0x2c, 0x22, 0x00, 0x1e, 0x01, 0x1c, 0xf7, 0x00, 0xdd, + 0xf3, 0x03, 0xf3, 0x0b, 0x02, 0xf3, 0xc5, 0x13, 0xd8, 0x1f, 0xf7, 0xe2, 0xf5, + 0x13, 0xfe, 0xd3, 0x22, 0xfa, 0x16, 0x07, 0x01, 0x05, 0x1e, 0xf3, 0xfd, 0xcd, + 0x14, 0x7f, 0x25, 0xf8, 0x50, 0xec, 0xcc, 0xef, 0xea, 0xda, 0xeb, 0x1f, 0xfa, + 0xe5, 0x12, 0xd1, 0x0f, 0xec, 0xc6, 0xd8, 0x36, 0x14, 0x16, 0x13, 0x03, 0xf8, + 0x04, 0xf8, 0xf6, 0xae, 0xe3, 0xeb, 0x05, 0xd3, 0x01, 0xf4, 0xf0, 0x07, 0xf7, + 0x2a, 0xd2, 0xf4, 0xe7, 0xee, 0x0a, 0xf9, 0x38, 0x47, 0xab, 0xc3, 0xad, 0xd0, + 0xc9, 0xb8, 0xc6, 0xd7, 0xdd, 0xfb, 0xe3, 0x28, 0xcf, 0xb6, 0xfb, 0x0d, 0x11, + 0x05, 0xd1, 0xdb, 0xf2, 0xe9, 0xf1, 0x1f, 0xf4, 0xe4, 0xfa, 0xe3, 0xeb, 0xc2, + 0x87, 0xef, 0xf8, 0x1d, 0xec, 0x08, 0x41, 0xaf, 0xff, 0xee, 0x1a, 0x13, 0x00, + 0xed, 0x2b, 0x1f, 0x00, 0x3a, 0xd1, 0x12, 0x0b, 0xfe, 0xff, 0xf8, 0x13, 0x77, + 0x17, 0x35, 0x90, 0xe0, 0x0c, 0x06, 0x62, 0x11, 0x68, 0xad, 0x17, 0xd2, 0x1e, + 0x06, 0xd8, 0xe8, 0x11, 0xf5, 0x14, 0xf1, 0xd0, 0xbd, 0xcb, 0xfd, 0x17, 0x81, + 0xeb, 0xcd, 0xc1, 0x01, 0xda, 0xae, 0x15, 0xd1, 0x58, 0xe3, 0x5e, 0x07, 0xa0, + 0xf1, 0xf6, 0x05, 0x03, 0xd9, 0xc2, 0xe5, 0xb7, 0xeb, 0xfc, 0xc1, 0xe5, 0x0e, + 0x0e, 0xc0, 0xd4, 0xc1, 0x0e, 0x1b, 0x1d, 0xf7, 0xe8, 0x07, 0xca, 0xd9, 0xf7, + 0xcb, 0x1a, 0xea, 0xd5, 0xec, 0x0f, 0xe1, 0xfb, 0xc0, 0xd5, 0xe7, 0xe8, 0x2f, + 0x06, 0xc2, 0xc8, 0x0d, 0xd6, 0xe9, 0xb3, 0x11, 0x14, 0xd4, 0x2a, 0xb6, 0x00, + 0x11, 0xbf, 0x1a, 0xb4, 0xfc, 0x37, 0xc8, 0xc4, 0xba, 0xab, 0x4f, 0x24, 0xcd, + 0x17, 0x29, 0xca, 0xc4, 0xcf, 0x31, 0xe7, 0xe7, 0x24, 0xe4, 0x19, 0xe6, 0xdf, + 0xe1, 0xeb, 0x2d, 0x09, 0xfa, 0xe4, 0xbd, 0xea, 0x03, 0x51, 0xff, 0x13, 0xbd, + 0xb2, 0x1e, 0x2b, 0xd0, 0xcd, 0xe9, 0x1e, 0x0b, 0x09, 0x1f, 0xd0, 0x2f, 0x0e, + 0x07, 0x1a, 0xd5, 0x09, 0x17, 0xbf, 0xc6, 0x23, 0xcf, 0x0d, 0x21, 0x90, 0x25, + 0x0b, 0x06, 0x12, 0xbd, 0xaf, 0x24, 0xd8, 0x1c, 0x08, 0x1f, 0x27, 0x0f, 0xf5, + 0x1d, 0xfa, 0xcc, 0x30, 0x27, 0xdf, 0xe2, 0x35, 0x0d, 0xce, 0xfb, 0x0f, 0x2f, + 0xf7, 0x9e, 0x38, 0xec, 0xf8, 0xde, 0xed, 0xf7, 0xfa, 0xf8, 0x51, 0xdc, 0x10, + 0x07, 0xe0, 0x16, 0xf1, 0xc8, 0xfa, 0x18, 0x29, 0x14, 0xce, 0xeb, 0xff, 0x04, + 0xde, 0xf0, 0x03, 0x9d, 0xf5, 0x92, 0x2a, 0x29, 0xe5, 0xe0, 0x1c, 0xf5, 0x21, + 0x67, 0x0a, 0x23, 0xed, 0x13, 0xd2, 0x28, 0x23, 0xe7, 0xbd, 0xf9, 0xfd, 0x10, + 0x3b, 0x14, 0xe5, 0x0d, 0x07, 0x31, 0x8c, 0x13, 0xfa, 0x49, 0x9a, 0xf8, 0x0e, + 0x22, 0xd3, 0xd6, 0xe4, 0x46, 0x01, 0x18, 0xfe, 0x0d, 0xd9, 0x21, 0x14, 0x1f, + 0xde, 0x90, 0xce, 0xfb, 0xe9, 0xf0, 0x18, 0xfb, 0xdc, 0x28, 0x02, 0xfc, 0x0b, + 0x06, 0xf6, 0xf1, 0x96, 0x15, 0x45, 0xc6, 0xd6, 0x12, 0x3f, 0xf6, 0xeb, 0xd8, + 0xda, 0xf4, 0x35, 0x18, 0xce, 0xc3, 0xeb, 0xa1, 0x93, 0x34, 0xf9, 0x14, 0x81, + 0x25, 0xdf, 0x2a, 0xe5, 0xd2, 0x1c, 0x24, 0xe4, 0x29, 0x28, 0xe8, 0xdc, 0x11, + 0xc3, 0xe8, 0x10, 0xee, 0xb8, 0xf8, 0xd0, 0x2d, 0xf0, 0x4a, 0x92, 0x2d, 0x01, + 0xf0, 0xd0, 0xf2, 0xce, 0x0f, 0x18, 0xe5, 0xbc, 0xbc, 0x2e, 0x48, 0xf9, 0xeb, + 0x35, 0x95, 0x2f, 0xef, 0xd9, 0x1e, 0xe3, 0x22, 0xca, 0xd5, 0x13, 0x31, 0xcc, + 0xa5, 0xbf, 0xaf, 0xf4, 0xdb, 0x2f, 0x50, 0x0b, 0x2d, 0x07, 0x3f, 0x54, 0x1a, + 0x31, 0xf5, 0x1a, 0xf8, 0xdc, 0xee, 0xe2, 0x20, 0xcb, 0x08, 0x01, 0xfe, 0xae, + 0xd5, 0x30, 0xec, 0xc2, 0xbd, 0xd0, 0x3f, 0xdd, 0x29, 0x14, 0xf2, 0x3d, 0xf0, + 0xe2, 0x1e, 0xfe, 0xaa, 0x20, 0x05, 0x09, 0xea, 0x2a, 0xfb, 0xee, 0xd8, 0x07, + 0xe8, 0x3a, 0xf0, 0x36, 0xed, 0xda, 0x1a, 0x17, 0x0c, 0x90, 0x0b, 0x07, 0x17, + 0xcc, 0xaa, 0x57, 0xda, 0xff, 0x37, 0x14, 0xf6, 0x4a, 0xd8, 0xe8, 0x3d, 0xef, + 0x0c, 0x87, 0x35, 0xb3, 0x01, 0x43, 0xfb, 0x19, 0x02, 0xd6, 0x4e, 0x02, 0x37, + 0x01, 0x04, 0x23, 0xb9, 0xcc, 0x83, 0x4d, 0xe6, 0xe4, 0xf1, 0x4d, 0xd1, 0xf5, + 0xd1, 0xcf, 0xe3, 0x0f, 0xd5, 0x05, 0x1c, 0xd8, 0x03, 0x2e, 0xf3, 0xd6, 0xfb, + 0x15, 0x09, 0xdd, 0xc2, 0xd6, 0x0b, 0x24, 0xe2, 0x1d, 0xc1, 0xdd, 0xfa, 0xee, + 0xc5, 0x30, 0xda, 0x15, 0xe3, 0xf5, 0x28, 0x12, 0xeb, 0xce, 0x96, 0xd4, 0x47, + 0x1d, 0x10, 0xc3, 0xd6, 0x00, 0xf5, 0xf7, 0xd5, 0x10, 0xe3, 0x0d, 0xd8, 0x08, + 0xee, 0x28, 0x0a, 0x23, 0xa6, 0x0f, 0xdf, 0x11, 0x3a, 0x1d, 0x25, 0x17, 0x4a, + 0x43, 0xea, 0xef, 0xfd, 0xcb, 0xfb, 0xce, 0x16, 0x19, 0x03, 0xf6, 0x47, 0xdf, + 0xd5, 0xd1, 0x08, 0x0a, 0xe8, 0x06, 0x11, 0x30, 0xdf, 0xdb, 0x14, 0x19, 0x1e, + 0x7f, 0xb2, 0xe7, 0x11, 0xe1, 0xfc, 0xf4, 0xf9, 0xdd, 0x09, 0x1e, 0xfa, 0xf0, + 0xee, 0xd4, 0xec, 0x0e, 0xb4, 0xe0, 0xea, 0x32, 0xbc, 0xff, 0xcb, 0x15, 0x4d, + 0x3e, 0xd5, 0x05, 0x12, 0x0c, 0x37, 0x91, 0xe3, 0x2d, 0x10, 0xdb, 0xe1, 0x40, + 0xf7, 0xf2, 0xf3, 0x11, 0x70, 0x07, 0x10, 0xe7, 0xcd, 0xd1, 0x05, 0x0e, 0x9f, + 0xc9, 0x1d, 0xf5, 0xf6, 0xe6, 0xfb, 0xe7, 0x2a, 0xde, 0x08, 0xff, 0xc5, 0xd0, + 0xd4, 0x1e, 0xe8, 0xe1, 0xd7, 0x9e, 0x0a, 0xd7, 0x5f, 0xf5, 0xec, 0xd7, 0xe5, + 0x2e, 0xea, 0xd6, 0x0f, 0xea, 0xe7, 0xd9, 0xf3, 0x0f, 0xbe, 0x1a, 0xea, 0xdf, + 0xce, 0xe0, 0xe3, 0xe7, 0x12, 0x02, 0x16, 0xff, 0x2e, 0xe2, 0x39, 0x56, 0xb8, + 0xdb, 0x24, 0xfe, 0x0f, 0x26, 0xda, 0x33, 0xe9, 0x19, 0xee, 0x0f, 0x2a, 0xe8, + 0xdf, 0x1e, 0xff, 0xb6, 0xed, 0x24, 0xa7, 0x54, 0x05, 0xfe, 0x0f, 0xc1, 0xfe, + 0x09, 0xc7, 0x10, 0x1c, 0xe5, 0xfb, 0x24, 0xf9, 0x1d, 0x31, 0xe0, 0xca, 0x16, + 0xec, 0xe9, 0x09, 0x55, 0xc1, 0xbf, 0xfc, 0x05, 0xf4, 0xf2, 0xe1, 0xe9, 0x01, + 0xf7, 0x47, 0x3d, 0x1f, 0xcc, 0x28, 0x00, 0xc9, 0xfc, 0xec, 0x41, 0xce, 0x41, + 0xf7, 0xc9, 0xd0, 0x12, 0x0a, 0x14, 0xff, 0x34, 0xd9, 0xe7, 0xe2, 0xea, 0x1b, + 0x24, 0x0f, 0xdc, 0x2b, 0x0b, 0xbb, 0xb4, 0x02, 0x18, 0x2c, 0xef, 0xe6, 0x0b, + 0xfd, 0xe1, 0xa6, 0x21, 0x81, 0xcd, 0x1a, 0xfc, 0xe1, 0x51, 0xfb, 0xf8, 0xbd, + 0x25, 0xcc, 0xce, 0x48, 0xdd, 0x27, 0xe4, 0xfc, 0x1a, 0xc0, 0xd5, 0x1b, 0x26, + 0x40, 0x24, 0xf0, 0xcf, 0x45, 0xe7, 0x0d, 0xbf, 0xae, 0xbc, 0xa9, 0xc1, 0xba, + 0xea, 0xdc, 0xdc, 0xca, 0xd3, 0x2e, 0xae, 0x68, 0x3a, 0x07, 0xe6, 0x1a, 0x10, + 0xe8, 0xd4, 0xc0, 0xbf, 0x70, 0xee, 0x2a, 0x1a, 0xd7, 0x4c, 0xb9, 0xdb, 0xa5, + 0x16, 0xee, 0x01, 0x07, 0xe9, 0x14, 0xd0, 0xc1, 0xff, 0xd4, 0x11, 0x46, 0xf5, + 0xe7, 0x06, 0x9c, 0xb3, 0x85, 0xcd, 0x14, 0xc3, 0xf2, 0xca, 0x35, 0xaa, 0xd5, + 0x66, 0xcf, 0xe6, 0xf1, 0xc7, 0xf2, 0x13, 0x28, 0xf3, 0x04, 0x27, 0x13, 0xff, + 0xef, 0x24, 0x10, 0xaa, 0x62, 0x0a, 0x9b, 0x11, 0x23, 0x04, 0xca, 0xdc, 0xf0, + 0xf3, 0xd0, 0x0c, 0x1f, 0xd0, 0x47, 0x03, 0xd6, 0xd3, 0x9b, 0x33, 0x1f, 0x1a, + 0xcf, 0xa9, 0x06, 0xe9, 0x3e, 0xf8, 0xf4, 0xf9, 0x38, 0x20, 0xff, 0x30, 0xdd, + 0xc5, 0xcb, 0xfe, 0x22, 0xe4, 0xfa, 0x13, 0x07, 0x2b, 0xfa, 0x38, 0x38, 0x32, + 0xb8, 0x0e, 0x33, 0x12, 0x06, 0x83, 0x02, 0x15, 0x16, 0xb3, 0xbe, 0xa6, 0xd4, + 0x11, 0x11, 0x42, 0xce, 0x06, 0xad, 0x13, 0xec, 0xf3, 0xd6, 0xf3, 0xf6, 0xe0, + 0xb5, 0xc2, 0xcf, 0xeb, 0xc0, 0x2b, 0xde, 0xcd, 0xff, 0xda, 0xfd, 0xed, 0x01, + 0xc6, 0xd1, 0x02, 0x83, 0xef, 0xeb, 0xdb, 0x00, 0xe2, 0xa6, 0x1e, 0xb9, 0xd1, + 0xe6, 0xe4, 0xd2, 0xa5, 0xea, 0xf6, 0xc5, 0x07, 0x26, 0x09, 0xfb, 0xef, 0xbc, + 0xb8, 0xcf, 0x19, 0xc1, 0x37, 0xf9, 0xb6, 0xd2, 0xa6, 0x24, 0xdf, 0xcf, 0xfc, + 0xac, 0xf6, 0xd5, 0x2d, 0x09, 0x1a, 0x1b, 0x10, 0xed, 0x09, 0xf4, 0xee, 0xfc, + 0xb0, 0x1b, 0xe4, 0x28, 0xed, 0xec, 0xcb, 0xc7, 0xf0, 0xd7, 0x4b, 0xda, 0x02, + 0x1e, 0x31, 0x03, 0xb7, 0xe7, 0xe6, 0xcf, 0xf1, 0x13, 0xf9, 0x9c, 0x0d, 0x20, + 0xe1, 0x6c, 0xf6, 0xe8, 0x53, 0x6e, 0x03, 0xf9, 0x04, 0x17, 0x1d, 0x01, 0xe7, + 0xee, 0xcb, 0xc1, 0x09, 0x0c, 0x19, 0xf1, 0x21, 0xe3, 0xdd, 0x1f, 0xea, 0xef, + 0x15, 0xdb, 0x1b, 0xf4, 0x38, 0x3d, 0x04, 0x3e, 0x21, 0xf4, 0xff, 0xe3, 0xe1, + 0xed, 0x4b, 0x07, 0xfc, 0x00, 0xfe, 0x22, 0x2f, 0x07, 0x32, 0xea, 0xd9, 0xcb, + 0xf7, 0xfd, 0xf7, 0xb0, 0x09, 0xed, 0xe1, 0xfc, 0x2b, 0x35, 0xf2, 0x08, 0xfd, + 0x0c, 0x4b, 0x07, 0xd1, 0x39, 0xdf, 0xf0, 0x2b, 0xd3, 0x06, 0xd0, 0xd6, 0xde, + 0xef, 0x08, 0x0f, 0x18, 0xa1, 0xed, 0xe9, 0xff, 0xf5, 0xf4, 0xd0, 0xba, 0x57, + 0xc5, 0xe9, 0xd1, 0xe9, 0x22, 0x14, 0xfd, 0x04, 0xec, 0x0f, 0xfb, 0xe9, 0xdd, + 0xd2, 0xc4, 0xe2, 0xde, 0xfd, 0x0d, 0xf8, 0x6f, 0xf9, 0xf8, 0x02, 0xd6, 0xb6, + 0xf1, 0xeb, 0xe5, 0xf9, 0x0b, 0xe7, 0x48, 0x11, 0x02, 0x3d, 0xf4, 0x2c, 0xf4, + 0xf8, 0x49, 0xf3, 0xf1, 0x06, 0xf6, 0x3b, 0xe1, 0xd3, 0xdb, 0xc5, 0xb3, 0xee, + 0x54, 0x33, 0x04, 0xdf, 0x4f, 0x5e, 0xfe, 0x49, 0xf0, 0x17, 0xa7, 0xe8, 0x0b, + 0xe3, 0x3c, 0xed, 0x25, 0x03, 0xfc, 0x17, 0x09, 0xf0, 0xe3, 0x12, 0xf5, 0xe1, + 0xd7, 0x1a, 0x1d, 0xfe, 0x11, 0xf2, 0x11, 0x06, 0xca, 0x13, 0xdb, 0xed, 0xe7, + 0x22, 0x24, 0x1d, 0xed, 0xdb, 0x11, 0x13, 0xfe, 0x15, 0x0c, 0xf8, 0xc6, 0xf5, + 0x16, 0x99, 0xe5, 0xf3, 0x09, 0x22, 0x42, 0x3d, 0x0c, 0x7f, 0xe2, 0xfc, 0x14, + 0xda, 0xeb, 0x01, 0xf4, 0x0c, 0x0d, 0x03, 0x22, 0x04, 0x04, 0xed, 0xef, 0xda, + 0x1c, 0xd4, 0xe2, 0xd9, 0xf2, 0x24, 0xde, 0x11, 0xef, 0x11, 0xf9, 0xf4, 0xff, + 0xd3, 0xee, 0x0e, 0xe5, 0x08, 0x0e, 0xe3, 0x17, 0x05, 0xfd, 0xde, 0xf9, 0xfc, + 0x09, 0xe5, 0x21, 0xce, 0xe2, 0x26, 0xfa, 0x23, 0xec, 0x04, 0x02, 0x09, 0x41, + 0x20, 0x0e, 0x1e, 0xf2, 0xf0, 0x12, 0x08, 0x08, 0x04, 0x00, 0xf8, 0xe0, 0x0b, + 0xe3, 0xf5, 0x15, 0xfa, 0xf9, 0x1d, 0x1e, 0x02, 0xf6, 0x44, 0xe6, 0xe3, 0xce, + 0xf6, 0xd4, 0xc8, 0xf5, 0x27, 0x29, 0xfd, 0x3f, 0x08, 0x0b, 0xe4, 0x17, 0xf9, + 0x11, 0xd5, 0xee, 0x2f, 0x13, 0xce, 0xd2, 0x34, 0x00, 0xed, 0xe0, 0xf5, 0xf8, + 0x38, 0x0a, 0x15, 0xf6, 0xde, 0xfd, 0x0d, 0xe5, 0xe0, 0xe4, 0x0f, 0xe1, 0xe7, + 0xd8, 0xfd, 0xf6, 0x15, 0x0f, 0xf9, 0x00, 0x49, 0x06, 0xd2, 0x04, 0xc8, 0xed, + 0xfc, 0x18, 0xf1, 0xef, 0xf6, 0x2a, 0xe7, 0x04, 0xeb, 0xe5, 0x51, 0x20, 0x1c, + 0x08, 0xed, 0xfb, 0xfd, 0x33, 0xf8, 0xfb, 0xf9, 0x15, 0xfa, 0xf6, 0xf6, 0x04, + 0xdf, 0x1d, 0xfd, 0xf0, 0x19, 0xf0, 0xfa, 0x0f, 0x0e, 0x1b, 0x22, 0x12, 0xeb, + 0x02, 0xf5, 0xde, 0x12, 0x07, 0x07, 0x24, 0x38, 0xf6, 0xef, 0xe5, 0x21, 0xe8, + 0xe6, 0xce, 0xe1, 0xf8, 0x00, 0x24, 0xe5, 0xe5, 0xdf, 0x0d, 0xf6, 0xfc, 0x19, + 0xfb, 0x15, 0xe8, 0xf9, 0xfa, 0x32, 0x04, 0x0e, 0x02, 0x06, 0x07, 0xf6, 0xfc, + 0xef, 0x01, 0x1f, 0x7f, 0x1f, 0xe8, 0xfd, 0x0e, 0xe6, 0x0c, 0xf9, 0xe0, 0xe4, + 0xef, 0xe7, 0xeb, 0xed, 0xf4, 0x08, 0xe8, 0xda, 0xd1, 0x16, 0x11, 0x04, 0x00, + 0x16, 0xf6, 0x19, 0xf9, 0xf0, 0xc6, 0xf0, 0xff, 0xff, 0xf1, 0x17, 0xf1, 0xf6, + 0xde, 0xf5, 0x10, 0xbc, 0xe7, 0xdc, 0x21, 0x09, 0xec, 0xc0, 0xea, 0x93, 0xaf, + 0xc2, 0x0a, 0x9c, 0xdf, 0xe9, 0x15, 0x93, 0xbc, 0x1f, 0x94, 0xaf, 0x0c, 0xe2, + 0x4d, 0xe1, 0x1a, 0x0d, 0xd9, 0xd2, 0xf8, 0xd1, 0xe5, 0xf1, 0x1c, 0xc5, 0xc3, + 0x96, 0xc2, 0x05, 0xbe, 0x1f, 0xee, 0xee, 0x02, 0xac, 0xd3, 0x3c, 0x10, 0xe0, + 0x51, 0x08, 0xdd, 0x19, 0x3e, 0xde, 0xd5, 0xb6, 0xf2, 0xf3, 0xf1, 0xf1, 0x92, + 0x1c, 0x12, 0x59, 0x63, 0x3e, 0x34, 0xc6, 0xc6, 0xaf, 0x24, 0xf8, 0x23, 0x45, + 0x22, 0x30, 0xde, 0x2b, 0xeb, 0xea, 0xe5, 0x13, 0x0d, 0xbd, 0xac, 0xb4, 0xc3, + 0x4a, 0x58, 0xd7, 0x6c, 0xd3, 0xcd, 0x0a, 0xb8, 0xe7, 0x33, 0xd8, 0xce, 0xfa, + 0xc1, 0x05, 0xe8, 0x3d, 0xf4, 0xa1, 0x14, 0xe0, 0xf3, 0xb4, 0xf8, 0x12, 0xf3, + 0xa3, 0x26, 0x50, 0xd4, 0xf5, 0xb4, 0xed, 0x09, 0xda, 0xfc, 0xbc, 0xd0, 0xa8, + 0x0a, 0x11, 0xe6, 0xed, 0xfb, 0xf7, 0x30, 0xab, 0x00, 0x81, 0x33, 0x16, 0x47, + 0xee, 0x01, 0x0d, 0x14, 0x14, 0x17, 0xe7, 0xc0, 0xd0, 0xc8, 0x1c, 0x2c, 0x15, + 0xab, 0x4b, 0xb3, 0xdf, 0xd5, 0x6d, 0xe1, 0xb7, 0xa5, 0x56, 0xfa, 0x2a, 0xb3, + 0x06, 0xae, 0x33, 0xf5, 0xde, 0xe1, 0x03, 0x25, 0x13, 0xb8, 0xda, 0xcf, 0xfe, + 0x4c, 0x85, 0x97, 0x1d, 0xd1, 0xd6, 0xba, 0xd2, 0x11, 0xe2, 0x20, 0xe2, 0xb1, + 0xf9, 0x15, 0x08, 0xfa, 0x27, 0xfc, 0x9e, 0xc0, 0xb6, 0x3a, 0xdf, 0x60, 0xcd, + 0x16, 0xec, 0x3c, 0xb4, 0xda, 0xd3, 0x64, 0xca, 0xf7, 0x3d, 0x10, 0x9a, 0x46, + 0xdd, 0x52, 0x38, 0xda, 0xe0, 0xd6, 0xc7, 0xeb, 0xf6, 0x11, 0x1a, 0x57, 0x37, + 0x1e, 0x4e, 0xf9, 0xdd, 0xea, 0xc1, 0x25, 0xd9, 0xf1, 0x04, 0x12, 0x30, 0xed, + 0x08, 0x01, 0x0f, 0xa7, 0x00, 0xe3, 0x93, 0x5a, 0x10, 0xca, 0xd3, 0xca, 0x0f, + 0x1f, 0xc8, 0xe9, 0x1b, 0x95, 0xd3, 0xe3, 0x04, 0xed, 0x06, 0xf7, 0x03, 0x22, + 0x06, 0x0e, 0xda, 0xee, 0xed, 0x49, 0xca, 0xe0, 0xa3, 0xf4, 0xfb, 0xe2, 0x35, + 0xa2, 0x11, 0xca, 0x14, 0xf2, 0xec, 0x23, 0x31, 0xba, 0x01, 0x10, 0x0e, 0x66, + 0x15, 0x0f, 0x18, 0x20, 0xe0, 0x20, 0x07, 0x0e, 0xb4, 0xf3, 0x1f, 0xd4, 0x12, + 0xb1, 0x2f, 0xaa, 0xed, 0xf9, 0x2c, 0xdb, 0x1f, 0x26, 0xe4, 0x48, 0xf2, 0x0c, + 0x3b, 0xd1, 0x20, 0xb8, 0x15, 0xc5, 0xda, 0x11, 0xf4, 0xfd, 0x04, 0xef, 0x2f, + 0x26, 0x25, 0xd7, 0xfe, 0xd6, 0x02, 0xd4, 0xdd, 0xd5, 0x37, 0x08, 0x07, 0xb6, + 0x01, 0x16, 0xe7, 0x16, 0x10, 0x1c, 0xf2, 0xbb, 0xfc, 0x77, 0x01, 0xc2, 0x31, + 0xe8, 0xdb, 0xfb, 0xd8, 0xe0, 0x50, 0x1e, 0x47, 0xe4, 0x02, 0x1c, 0x15, 0x10, + 0xba, 0xf0, 0xcc, 0x22, 0xc3, 0xb8, 0xd0, 0xd3, 0x0e, 0x00, 0xb7, 0x13, 0x7b, + 0xf8, 0xf7, 0xfe, 0xf4, 0x0d, 0xd1, 0x25, 0xec, 0xd2, 0xbc, 0x2c, 0xe5, 0x43, + 0x22, 0x09, 0x0e, 0xce, 0xe1, 0xfe, 0x08, 0xf3, 0x0c, 0x09, 0x22, 0x03, 0xce, + 0x0e, 0xd9, 0x2e, 0x2c, 0xfb, 0xf4, 0x16, 0xe9, 0xfa, 0xd5, 0xeb, 0xe6, 0x22, + 0x38, 0x02, 0x59, 0x23, 0xd9, 0x17, 0xf9, 0xe1, 0x2d, 0x2b, 0xef, 0x37, 0x01, + 0xe8, 0x07, 0xf3, 0x17, 0x21, 0x07, 0x93, 0xe7, 0xe4, 0xff, 0x0c, 0xeb, 0xf6, + 0x96, 0x11, 0x0c, 0x49, 0xf7, 0xed, 0xfd, 0xeb, 0xd9, 0xbc, 0x24, 0xeb, 0xe3, + 0xb1, 0xf7, 0x67, 0xd0, 0xfa, 0x25, 0xc1, 0x28, 0x5b, 0x7f, 0xd1, 0xfa, 0xd8, + 0xc7, 0xe9, 0x42, 0xb6, 0xde, 0x23, 0xe6, 0xe5, 0x24, 0xe2, 0x11, 0xe7, 0xda, + 0x09, 0x3b, 0xed, 0x00, 0x38, 0xe6, 0xc3, 0xdc, 0xe3, 0xd9, 0xb5, 0xfd, 0x06, + 0x03, 0xde, 0x04, 0x0e, 0xf2, 0x1d, 0xe6, 0xfc, 0x98, 0xfc, 0xd8, 0x36, 0x16, + 0x00, 0x13, 0xd8, 0xf0, 0x10, 0x23, 0x3a, 0xf4, 0xe9, 0x02, 0xdc, 0xf8, 0x13, + 0xba, 0x1c, 0xd7, 0x19, 0x2e, 0x13, 0x09, 0x11, 0xeb, 0xce, 0xd0, 0xf5, 0x9e, + 0xf3, 0xfc, 0x3d, 0x2b, 0xf5, 0xdf, 0xf8, 0xcf, 0xd4, 0xf9, 0xea, 0xc8, 0x39, + 0x0d, 0xf8, 0x00, 0x4a, 0x13, 0xbe, 0x29, 0x1b, 0xb0, 0x14, 0x0e, 0xfd, 0xfc, + 0xd9, 0x03, 0xa4, 0xed, 0xf3, 0x03, 0x01, 0xda, 0x13, 0xf2, 0xd4, 0xf8, 0x1b, + 0x32, 0x18, 0xe1, 0x3d, 0xc7, 0xdd, 0xd3, 0x2f, 0x07, 0xa9, 0xe8, 0x19, 0xd4, + 0xf5, 0xfd, 0xf2, 0xe1, 0xbc, 0x0b, 0xa7, 0x06, 0xd7, 0x0a, 0xe9, 0x20, 0xfc, + 0x0f, 0x04, 0xfb, 0xbd, 0xdb, 0xf5, 0x05, 0x03, 0x51, 0x62, 0xee, 0xe4, 0x23, + 0xfb, 0xf6, 0x03, 0xfb, 0x4a, 0x2a, 0xde, 0xe2, 0xb3, 0xfc, 0xcf, 0xfa, 0xfc, + 0xc3, 0xea, 0xf9, 0xf5, 0xfc, 0xf1, 0xf1, 0x21, 0x38, 0x08, 0xbd, 0xf6, 0x55, + 0x09, 0xd2, 0xf7, 0xde, 0xe7, 0x1e, 0xf7, 0x56, 0x15, 0xda, 0x81, 0x30, 0xef, + 0x9f, 0xe8, 0xdf, 0xbc, 0x03, 0x08, 0x08, 0xfb, 0x10, 0xdd, 0xf9, 0x27, 0xd5, + 0xc0, 0xbc, 0xda, 0x04, 0xff, 0x2a, 0x2b, 0xe4, 0x20, 0xd4, 0x4e, 0xf3, 0xf2, + 0x53, 0xf7, 0xde, 0xea, 0x01, 0xe9, 0xe9, 0x08, 0xee, 0xd0, 0x11, 0x17, 0x23, + 0xcf, 0xf8, 0xd2, 0x00, 0xdb, 0xe1, 0xf7, 0x06, 0x0c, 0xf1, 0xdf, 0xe7, 0xfc, + 0xb6, 0xe3, 0xef, 0xe0, 0x41, 0xd9, 0x13, 0xcc, 0xda, 0xe9, 0xf8, 0x1f, 0xdc, + 0x03, 0xf3, 0xb3, 0xe9, 0xb8, 0xca, 0xe0, 0x1c, 0xaf, 0x1b, 0x21, 0x23, 0x1b, + 0xf0, 0xfa, 0x06, 0xec, 0x0f, 0x12, 0x18, 0xd4, 0xfe, 0xf8, 0x29, 0xdc, 0xed, + 0xf8, 0xf7, 0xdc, 0x32, 0x07, 0x22, 0xe8, 0xf3, 0xc4, 0xef, 0xe9, 0x34, 0xfe, + 0xe8, 0x4d, 0x0b, 0xf7, 0x14, 0xda, 0xef, 0xb3, 0x11, 0x24, 0xf0, 0xa9, 0xba, + 0xf9, 0xf6, 0x0a, 0xd5, 0x13, 0xf4, 0x2a, 0x2c, 0x1c, 0x05, 0xe7, 0x30, 0xd6, + 0x3f, 0xe2, 0xe6, 0x78, 0x4d, 0xd0, 0xd9, 0x2b, 0x1a, 0xd7, 0x14, 0x17, 0xe9, + 0x81, 0x13, 0x2e, 0xf9, 0xcb, 0xd2, 0xe6, 0x0b, 0xb2, 0x0a, 0xc8, 0xb1, 0xf2, + 0xb2, 0xd8, 0xe6, 0xf8, 0x0f, 0xad, 0xcb, 0xc6, 0xc6, 0xad, 0x56, 0x3b, 0x27, + 0xdc, 0xd6, 0x39, 0xf5, 0xf8, 0x34, 0x1d, 0xdd, 0x3b, 0xd4, 0xeb, 0x15, 0xbe, + 0xf4, 0x1b, 0x08, 0xf0, 0xe6, 0xc7, 0x29, 0x1e, 0x18, 0xc0, 0x10, 0xac, 0xf2, + 0xae, 0x24, 0xeb, 0xfc, 0xfd, 0x06, 0xfa, 0xe1, 0x08, 0xae, 0x26, 0xd4, 0xf9, + 0x41, 0xd4, 0xcd, 0xff, 0x64, 0xff, 0xce, 0xdd, 0xe4, 0xeb, 0xde, 0xf5, 0x4c, + 0x28, 0x02, 0xe2, 0x7a, 0x0d, 0xa5, 0x35, 0x46, 0xa5, 0xfa, 0x07, 0x11, 0x07, + 0x54, 0x0c, 0x05, 0x00, 0x11, 0x01, 0xfa, 0x0b, 0x09, 0xa1, 0x16, 0xfc, 0xa9, + 0xf4, 0x01, 0x35, 0xee, 0x05, 0x3d, 0xec, 0x0e, 0x0c, 0xf6, 0x1b, 0x3a, 0x1c, + 0x17, 0x58, 0xf2, 0x1a, 0x16, 0xea, 0x08, 0x20, 0xfa, 0x3c, 0xef, 0x0d, 0x0b, + 0xf9, 0x0a, 0xef, 0x87, 0xff, 0xeb, 0x07, 0xfd, 0x24, 0x0b, 0xc2, 0xfd, 0x1d, + 0xc0, 0x0f, 0xe7, 0x5d, 0x08, 0x00, 0xc9, 0x1a, 0xea, 0xe8, 0xda, 0xca, 0xe5, + 0x24, 0x3b, 0x18, 0xf8, 0xa4, 0xd0, 0x15, 0x0c, 0xeb, 0x11, 0xfc, 0xfc, 0x11, + 0xf2, 0x28, 0x0c, 0xd6, 0x40, 0x2b, 0xf8, 0x0d, 0x66, 0x1c, 0x0a, 0xf1, 0xf7, + 0x29, 0xf6, 0x05, 0x32, 0xd2, 0xec, 0x07, 0xff, 0xa3, 0x1b, 0x36, 0x5b, 0xd3, + 0x36, 0xd1, 0x07, 0xdd, 0xde, 0x29, 0x1e, 0x22, 0x18, 0xb5, 0xd7, 0xd9, 0x08, + 0xe8, 0x15, 0x90, 0xc3, 0x18, 0x11, 0xcc, 0x1f, 0x29, 0xd5, 0xf7, 0xbd, 0x22, + 0xcc, 0xbd, 0xc2, 0x0e, 0x09, 0x47, 0xcd, 0xa6, 0xc6, 0xbf, 0xd2, 0x1d, 0xee, + 0x36, 0xf7, 0xd4, 0xc2, 0x0d, 0x1b, 0x1f, 0x05, 0xfe, 0x0e, 0xb9, 0xe3, 0x1b, + 0x34, 0x44, 0xe1, 0xeb, 0xbc, 0x3c, 0xec, 0x25, 0x1b, 0xb4, 0x26, 0xc3, 0xdf, + 0x27, 0x1d, 0xed, 0xfc, 0xf9, 0x31, 0x2c, 0xee, 0x09, 0xea, 0xef, 0x02, 0xeb, + 0x0e, 0xe2, 0xc0, 0x09, 0xf0, 0x0f, 0xff, 0xf1, 0x50, 0x11, 0xf7, 0x54, 0xe9, + 0xc5, 0x34, 0xbf, 0x21, 0x01, 0xc5, 0x99, 0x14, 0xe1, 0x0a, 0xeb, 0x03, 0xbb, + 0xe7, 0xd1, 0xf7, 0xe7, 0x03, 0xd9, 0xff, 0x9e, 0x33, 0x17, 0x05, 0x1a, 0x30, + 0xfd, 0x3f, 0x0d, 0xdf, 0xe6, 0x18, 0x15, 0x21, 0xcb, 0x0f, 0x06, 0xcf, 0x9f, + 0x5b, 0x0f, 0x13, 0xf9, 0xcf, 0x67, 0x45, 0x0d, 0xf8, 0xc0, 0xd6, 0x02, 0x19, + 0x03, 0xa6, 0xbc, 0xfe, 0xe7, 0xea, 0x03, 0xb7, 0xba, 0x63, 0x16, 0xcb, 0x06, + 0x50, 0x1a, 0x09, 0x1a, 0x0d, 0x0d, 0xf0, 0xc5, 0xce, 0xfd, 0x9f, 0xbb, 0x12, + 0xfb, 0x08, 0xfe, 0x11, 0x08, 0xe5, 0x7f, 0x5c, 0x1e, 0x29, 0x20, 0x05, 0x21, + 0xfb, 0xcd, 0xe8, 0x2e, 0x24, 0xe7, 0x1b, 0x32, 0xd1, 0x05, 0xeb, 0xce, 0xdc, + 0x0e, 0xfb, 0xec, 0xf0, 0x15, 0xc2, 0xe6, 0xdc, 0xe0, 0x33, 0x2a, 0xd1, 0x37, + 0x0b, 0x4a, 0x01, 0xb8, 0xb0, 0xe6, 0xd6, 0xf5, 0x05, 0x0c, 0x11, 0xcd, 0xcc, + 0xd1, 0xb0, 0xfa, 0x14, 0x2e, 0x2e, 0x02, 0xe4, 0x01, 0xd0, 0xf7, 0xca, 0x60, + 0xa9, 0xe4, 0x1f, 0xe3, 0x4f, 0x2c, 0xfe, 0xfc, 0xbb, 0xe6, 0xcb, 0x00, 0xf4, + 0xe6, 0xdd, 0x21, 0xf0, 0xcb, 0xa5, 0x10, 0x3f, 0xe3, 0xf8, 0xaa, 0x26, 0x06, + 0xd1, 0xee, 0xda, 0xfd, 0x3b, 0xf4, 0xb9, 0xe0, 0xf4, 0xbd, 0xf0, 0xe5, 0xdd, + 0xb2, 0xf9, 0xfb, 0xce, 0xfa, 0x2a, 0xe3, 0x13, 0xd3, 0x07, 0xe1, 0xcb, 0xf8, + 0xd9, 0xed, 0xff, 0xb0, 0xc4, 0xc6, 0x1e, 0xdf, 0xe5, 0x14, 0xbf, 0xe0, 0xe4, + 0xf6, 0x04, 0xbd, 0xd4, 0x1f, 0xc9, 0xd0, 0xdd, 0xf3, 0xe9, 0x32, 0x23, 0x20, + 0xd3, 0x15, 0x25, 0x11, 0xa9, 0x2a, 0xcb, 0x29, 0xde, 0xfe, 0x03, 0xe2, 0x1c, + 0x24, 0xbe, 0xfb, 0x2f, 0x26, 0x06, 0xb9, 0x28, 0x3a, 0xd8, 0x3b, 0x1c, 0xe7, + 0x05, 0x06, 0xf9, 0xd7, 0x0c, 0xf9, 0xe5, 0x17, 0xf7, 0x36, 0x48, 0xfc, 0x12, + 0xe9, 0x9e, 0x09, 0xb8, 0x01, 0xf5, 0x1f, 0xd4, 0x3b, 0x12, 0x00, 0xd1, 0x09, + 0xeb, 0x32, 0xfb, 0xb0, 0x3c, 0x81, 0x17, 0x4c, 0x15, 0xfd, 0x0c, 0x2e, 0xcd, + 0x1f, 0x0f, 0x48, 0x20, 0x48, 0xda, 0xd0, 0xeb, 0xe6, 0x1a, 0xf6, 0xb2, 0xfd, + 0xc3, 0xd4, 0x01, 0x2c, 0xe2, 0xeb, 0xbc, 0x3c, 0xc7, 0xee, 0x0d, 0x21, 0xbb, + 0x0d, 0xf6, 0xda, 0x0a, 0xc5, 0x0d, 0x21, 0x10, 0xeb, 0xdc, 0x06, 0xf0, 0xd8, + 0xc5, 0x1a, 0x1a, 0xc5, 0x1f, 0xf4, 0xe3, 0x24, 0x9c, 0xb1, 0xcb, 0xc3, 0xe4, + 0xcd, 0xe4, 0xe7, 0x2c, 0x23, 0x30, 0xcb, 0xba, 0xc1, 0xf6, 0xab, 0x0b, 0xdc, + 0xaf, 0xd1, 0x13, 0x1f, 0x2c, 0x22, 0x22, 0xb9, 0xfd, 0x0b, 0x10, 0x22, 0x42, + 0xf9, 0x22, 0x02, 0xcf, 0xea, 0xe1, 0x35, 0x6a, 0x05, 0xd9, 0xb7, 0xfa, 0xb2, + 0xff, 0xf0, 0xd2, 0xcf, 0x12, 0xe9, 0xf8, 0x59, 0xd7, 0xcc, 0xbf, 0xc2, 0x82, + 0xc8, 0xd7, 0xe7, 0xa6, 0x3a, 0x22, 0xc4, 0x0e, 0x23, 0xf1, 0xd6, 0x29, 0xf4, + 0xda, 0xd6, 0xfe, 0x08, 0x00, 0x17, 0x06, 0x2a, 0x17, 0xca, 0xe2, 0x37, 0xde, + 0x10, 0x19, 0xe4, 0x38, 0x06, 0x07, 0xce, 0xfc, 0x1b, 0x43, 0xe0, 0xcf, 0xb9, + 0xa3, 0x20, 0x4d, 0xd8, 0x4a, 0xcc, 0x19, 0xe2, 0xb7, 0x18, 0xce, 0xd5, 0xeb, + 0xda, 0x11, 0x9c, 0xdc, 0xe9, 0x29, 0xca, 0xa6, 0xf5, 0x14, 0xe1, 0x1d, 0x1c, + 0xcb, 0xe3, 0x59, 0xf8, 0xcc, 0x4f, 0xd1, 0x4b, 0x16, 0xad, 0x14, 0xaf, 0x95, + 0xcf, 0x39, 0xfc, 0x1e, 0xb2, 0x1f, 0xeb, 0xfb, 0x3d, 0xff, 0xf8, 0xfd, 0xec, + 0x8b, 0x40, 0x2b, 0x10, 0xbf, 0xf6, 0xf5, 0xcc, 0x2f, 0xca, 0x2a, 0xf8, 0x9b, + 0x1a, 0xf5, 0xce, 0x1e, 0xf6, 0x25, 0xc5, 0x25, 0xe7, 0x84, 0xda, 0xc3, 0x1b, + 0xb5, 0xd6, 0x29, 0x36, 0x23, 0xaf, 0x00, 0x30, 0xe6, 0xa3, 0xd4, 0xbb, 0xc6, + 0xb5, 0xd3, 0x14, 0x14, 0x18, 0x1f, 0x30, 0x16, 0x37, 0xcf, 0xd9, 0xe6, 0xf8, + 0xda, 0xa2, 0x39, 0x14, 0x09, 0x33, 0x08, 0xeb, 0xac, 0xcd, 0x04, 0xcd, 0x49, + 0x89, 0xf9, 0xc1, 0xc2, 0xc6, 0x37, 0xdf, 0xdd, 0x01, 0xbf, 0x27, 0xec, 0x1f, + 0xe4, 0x05, 0xed, 0xe7, 0xec, 0x0d, 0x03, 0x4e, 0x2d, 0xc3, 0xe6, 0xf4, 0x07, + 0xeb, 0x23, 0xc8, 0xa5, 0xfc, 0xc4, 0x09, 0xda, 0xf0, 0x3e, 0xbb, 0xf9, 0x06, + 0x05, 0xd6, 0x1c, 0xd0, 0x20, 0xf3, 0x34, 0x00, 0xab, 0xff, 0xfe, 0xdb, 0xdb, + 0xd1, 0xd5, 0xe7, 0xed, 0xf5, 0xec, 0xf2, 0x2b, 0x32, 0xa4, 0xf3, 0x4c, 0x21, + 0xca, 0x2c, 0xb5, 0xe7, 0xd4, 0xc3, 0xfa, 0x56, 0x52, 0x0c, 0x0b, 0xd0, 0xd1, + 0xf5, 0x14, 0xf7, 0xc3, 0xdd, 0x20, 0x05, 0xac, 0x13, 0x56, 0x08, 0xc2, 0xd1, + 0xe1, 0x11, 0x00, 0xfa, 0xe8, 0x84, 0xff, 0x06, 0xf8, 0x09, 0xf8, 0xf3, 0xc1, + 0xde, 0xef, 0xec, 0x26, 0xf2, 0xfe, 0x24, 0xf2, 0x0c, 0xd5, 0xd7, 0x05, 0x01, + 0xce, 0x2d, 0x0c, 0x03, 0x23, 0xf7, 0xeb, 0x01, 0x08, 0x32, 0x81, 0xcb, 0xc2, + 0xd0, 0x2b, 0xda, 0xf1, 0x63, 0x03, 0xde, 0xf4, 0x20, 0xcc, 0xe2, 0x28, 0xdf, + 0x6d, 0xf9, 0xb6, 0x19, 0x9d, 0xfc, 0xf6, 0xe4, 0xc5, 0xdb, 0x06, 0xa6, 0x08, + 0xf0, 0x48, 0xf4, 0xfd, 0x20, 0xf7, 0x08, 0xb2, 0xc2, 0x00, 0xe8, 0xec, 0xbe, + 0xad, 0xf2, 0x4e, 0xf4, 0xf8, 0xe0, 0x17, 0xd8, 0xa7, 0x0f, 0x01, 0x00, 0xe8, + 0xe7, 0x0e, 0xe9, 0xff, 0x2e, 0x17, 0xa4, 0x15, 0xdd, 0xfe, 0x25, 0xf1, 0x1b, + 0xe0, 0xf9, 0xb7, 0xdd, 0x11, 0xd5, 0xb8, 0xe5, 0xfb, 0x0a, 0xb1, 0xe2, 0x48, + 0x3d, 0xa4, 0x1e, 0xc9, 0x48, 0xbb, 0xe0, 0xd7, 0x28, 0xe5, 0x00, 0xca, 0x24, + 0x2c, 0xe1, 0xb2, 0x49, 0x17, 0xe3, 0xc7, 0x05, 0xf1, 0xcd, 0x5e, 0xf5, 0xf1, + 0xc2, 0xf2, 0x2a, 0xd6, 0x03, 0xd9, 0x2b, 0xf8, 0xe0, 0xbb, 0x04, 0xc5, 0xd8, + 0x1f, 0x0a, 0xf8, 0x34, 0x46, 0x19, 0x14, 0xc4, 0xde, 0xfb, 0xeb, 0xe7, 0x4b, + 0xe7, 0xd9, 0x07, 0xc3, 0x1f, 0xe7, 0xe2, 0xe8, 0x7b, 0x07, 0x0d, 0xf2, 0x20, + 0xfc, 0x24, 0xe8, 0xde, 0xfe, 0xe5, 0xf1, 0xe9, 0xdb, 0xcd, 0xbc, 0x00, 0x03, + 0xfd, 0xf5, 0xb2, 0xe6, 0xe6, 0xf5, 0x02, 0x93, 0xc8, 0x2f, 0x0d, 0xfb, 0x25, + 0xe7, 0xc2, 0x24, 0x40, 0xce, 0x95, 0xd3, 0xeb, 0xc8, 0x03, 0x0f, 0x5d, 0xdf, + 0xd8, 0xf3, 0xa6, 0x59, 0x08, 0xde, 0xd2, 0xfc, 0xc9, 0xe5, 0x07, 0x09, 0xe1, + 0xff, 0xf0, 0x0f, 0xf0, 0xc6, 0xe1, 0xb9, 0xe3, 0x1a, 0x01, 0xde, 0x3d, 0x96, + 0xc3, 0x57, 0xb8, 0xc1, 0xa8, 0x14, 0x51, 0x16, 0x0e, 0xfc, 0x17, 0xd8, 0xd0, + 0x27, 0x02, 0x17, 0x36, 0xd0, 0x95, 0xc8, 0xc4, 0xe7, 0x06, 0x2a, 0x14, 0xfc, + 0x36, 0xfa, 0x3c, 0x21, 0x59, 0xd7, 0x10, 0x0b, 0x1e, 0xde, 0x22, 0x19, 0xc9, + 0xd5, 0xf2, 0xe5, 0xd6, 0xeb, 0x06, 0xdd, 0xf1, 0xfc, 0x06, 0xdb, 0x81, 0xeb, + 0xd5, 0xdc, 0x12, 0xd4, 0xee, 0xfd, 0x96, 0xc9, 0x4e, 0xef, 0xf2, 0x9e, 0x20, + 0xe6, 0xbd, 0x04, 0xdc, 0xe3, 0x0b, 0x3c, 0xa8, 0x37, 0xd7, 0xe9, 0xc8, 0x48, + 0xb9, 0xf7, 0xd5, 0x32, 0x02, 0x15, 0xad, 0x30, 0xc2, 0xbf, 0x51, 0xe8, 0x40, + 0x1c, 0xf2, 0x47, 0xe9, 0xbd, 0xb0, 0xc9, 0xfc, 0x36, 0x00, 0x06, 0x1d, 0xe7, + 0xcb, 0xdb, 0x1c, 0x2a, 0xfd, 0xb3, 0x1e, 0x0c, 0x92, 0xef, 0xe8, 0x1a, 0x22, + 0x05, 0xdb, 0x0c, 0x06, 0xf3, 0x22, 0xe8, 0x3c, 0xfc, 0x4d, 0x02, 0x2b, 0x17, + 0x09, 0xde, 0xe8, 0x41, 0x01, 0x2a, 0xb9, 0x0e, 0xc4, 0xc5, 0xdf, 0x0c, 0xcc, + 0xaf, 0xd9, 0xb6, 0xf3, 0x4f, 0xe0, 0xf0, 0xd0, 0xef, 0xc5, 0x15, 0xb3, 0x2e, + 0xd9, 0xd7, 0x54, 0x08, 0x49, 0xff, 0x2a, 0x0d, 0xe7, 0xd2, 0xfd, 0xe0, 0x0b, + 0xbd, 0xea, 0xbc, 0x13, 0xde, 0xad, 0x14, 0x2a, 0xa6, 0x81, 0x32, 0x29, 0x25, + 0xed, 0x49, 0xa3, 0x04, 0x0e, 0x06, 0x1d, 0x08, 0x22, 0x24, 0x01, 0xd0, 0xb5, + 0xe7, 0xe3, 0x2e, 0xf4, 0x1f, 0x25, 0x03, 0xc7, 0xe3, 0x2e, 0x00, 0x36, 0xf8, + 0xf5, 0x28, 0xdb, 0x40, 0xda, 0x0b, 0x2e, 0xe8, 0xfb, 0xf9, 0xca, 0x45, 0xcf, + 0xc9, 0x0e, 0xea, 0xf1, 0x25, 0xd7, 0x1d, 0xe2, 0x0a, 0xf3, 0xfe, 0x3c, 0xe7, + 0x00, 0xf4, 0x17, 0x35, 0xe4, 0x2d, 0xf8, 0x45, 0x10, 0xe2, 0xfd, 0xe6, 0x0a, + 0xaf, 0x05, 0x35, 0xc6, 0xdc, 0xf7, 0xb4, 0x97, 0x0b, 0x26, 0x01, 0xfb, 0xb5, + 0xfc, 0xbf, 0xc2, 0x29, 0xe0, 0x16, 0x54, 0xbf, 0x1a, 0xeb, 0x26, 0xd2, 0xf6, + 0xb2, 0xed, 0x31, 0x4b, 0x35, 0xd1, 0x0e, 0xc5, 0xeb, 0xf8, 0x09, 0x04, 0x62, + 0x1c, 0x07, 0xec, 0xf5, 0xd3, 0xbc, 0xdd, 0x17, 0xed, 0x92, 0xe9, 0xe5, 0x23, + 0xf0, 0xe9, 0xa0, 0xe0, 0x53, 0x33, 0xc8, 0xe6, 0x9e, 0x01, 0xf7, 0xfb, 0xd4, + 0x10, 0x35, 0xc3, 0xf9, 0xf1, 0xf4, 0xf1, 0xeb, 0x2f, 0xbe, 0x1d, 0x14, 0xd5, + 0xd6, 0x13, 0x1d, 0xe6, 0x2e, 0xe1, 0x3c, 0xe4, 0x12, 0xe0, 0xc7, 0x27, 0xec, + 0xfb, 0xda, 0xdc, 0xe7, 0xf8, 0x11, 0x1b, 0xe7, 0xea, 0xef, 0x0c, 0xee, 0xf4, + 0x05, 0x20, 0x81, 0xb3, 0x36, 0x12, 0xf5, 0xe3, 0x00, 0x1d, 0xb5, 0x15, 0xd0, + 0x04, 0x1b, 0xf8, 0xe6, 0xf7, 0x32, 0x0f, 0x27, 0xf9, 0xfe, 0x1b, 0xe8, 0x21, + 0xda, 0x29, 0xf3, 0x0d, 0x45, 0xc8, 0xee, 0xf9, 0x02, 0xfc, 0x04, 0x1c, 0xe2, + 0xf8, 0xfe, 0xf3, 0xfe, 0xfb, 0xc0, 0xd8, 0xd6, 0xd1, 0x12, 0x13, 0xfb, 0x19, + 0x26, 0x1b, 0x00, 0x31, 0xb1, 0xd4, 0x17, 0x36, 0x1f, 0x0c, 0x18, 0xe0, 0xf6, + 0xdb, 0xd0, 0x04, 0x14, 0x0c, 0x1c, 0x0e, 0x0c, 0x17, 0xe9, 0x02, 0xe7, 0x47, + 0x26, 0xc7, 0xd4, 0x1a, 0x0e, 0xff, 0x52, 0xf6, 0xb2, 0xcb, 0x22, 0xf7, 0x22, + 0xea, 0xd7, 0xec, 0xdf, 0xca, 0xe0, 0xbb, 0xc1, 0xf1, 0xd8, 0x0d, 0x39, 0x01, + 0x13, 0xeb, 0xd8, 0xd0, 0xf1, 0xf0, 0x3f, 0x17, 0xee, 0x07, 0xf5, 0xb8, 0x27, + 0xe9, 0xef, 0x06, 0xce, 0x2b, 0xf3, 0xe4, 0x3b, 0x04, 0x3a, 0xc7, 0x08, 0xc4, + 0x14, 0xc0, 0x47, 0x0d, 0x00, 0x24, 0x43, 0xd0, 0xaa, 0xa4, 0xb0, 0xe9, 0x1f, + 0x2d, 0x1a, 0xda, 0xf1, 0xd9, 0x13, 0xd1, 0xa9, 0x4c, 0x0d, 0xcf, 0x0c, 0x3b, + 0xfa, 0xef, 0x0f, 0x32, 0x31, 0xfa, 0x27, 0xe7, 0xed, 0x56, 0xd7, 0x05, 0x23, + 0xe1, 0x2a, 0x2b, 0xeb, 0xf3, 0x02, 0x0d, 0x1d, 0xc9, 0xde, 0x06, 0x26, 0xfa, + 0x13, 0xf6, 0xed, 0xec, 0x1e, 0xea, 0x4a, 0x2f, 0xf0, 0xda, 0x45, 0xf6, 0x1c, + 0xc4, 0x25, 0x18, 0xed, 0xfc, 0x44, 0xbd, 0x1d, 0xe0, 0xff, 0x00, 0xde, 0x33, + 0x31, 0xe6, 0x11, 0xe0, 0xcd, 0x37, 0xde, 0xe0, 0xf9, 0xfe, 0x01, 0xfe, 0xed, + 0x12, 0xf1, 0xf3, 0xe0, 0xa8, 0xeb, 0xc8, 0xe2, 0xf5, 0x0a, 0x22, 0x1f, 0x12, + 0xdd, 0x1b, 0xd8, 0xcd, 0xa4, 0xde, 0xe2, 0x18, 0xf3, 0x5a, 0xb7, 0xde, 0xb1, + 0x00, 0xd4, 0xf4, 0x1f, 0xe5, 0xc7, 0x2a, 0xf8, 0x22, 0x36, 0xb9, 0x0c, 0xf4, + 0x1f, 0xfa, 0xf5, 0xbc, 0xb4, 0x1b, 0xe6, 0x41, 0xdc, 0x32, 0x04, 0x11, 0xf5, + 0xe7, 0xcc, 0x1d, 0x72, 0x50, 0xd3, 0x16, 0x24, 0x8f, 0x29, 0xf3, 0xf9, 0xcc, + 0xdc, 0xdd, 0x4e, 0xff, 0xe1, 0xc9, 0xe0, 0x41, 0x22, 0x4d, 0xee, 0xc9, 0xc0, + 0x14, 0x23, 0xf9, 0xe6, 0xf9, 0x08, 0x10, 0xdb, 0x0a, 0x37, 0x02, 0x3a, 0xd0, + 0x04, 0xff, 0xa4, 0xcf, 0xda, 0x18, 0x1d, 0xe5, 0xe9, 0xfb, 0x22, 0xf8, 0x44, + 0x83, 0xd7, 0xfd, 0xf0, 0xf9, 0xc6, 0x09, 0xdb, 0xee, 0x11, 0xe2, 0x3d, 0xfc, + 0xdf, 0xd0, 0x1c, 0xe0, 0xf5, 0x13, 0x25, 0xcb, 0x07, 0x13, 0xcf, 0xff, 0xc5, + 0x35, 0x2a, 0xf7, 0xe9, 0xff, 0x0d, 0x4d, 0x12, 0xf9, 0x1f, 0x10, 0x16, 0x00, + 0x1d, 0xde, 0x15, 0x15, 0xa3, 0x03, 0xd5, 0xfc, 0x21, 0x01, 0xdb, 0xbf, 0xbf, + 0x09, 0xe0, 0xfc, 0x00, 0x10, 0xd2, 0xc8, 0xae, 0x08, 0x22, 0xf2, 0x51, 0x05, + 0x24, 0xfa, 0xe4, 0x10, 0xb5, 0xcb, 0x3f, 0xfc, 0xf9, 0x01, 0xf1, 0x64, 0xdd, + 0xf3, 0x20, 0xe8, 0xa5, 0xf1, 0x28, 0x44, 0xed, 0x28, 0x28, 0xa6, 0xe0, 0xff, + 0x41, 0xf1, 0x19, 0x0d, 0xfb, 0x0a, 0xe7, 0x15, 0x2c, 0x2b, 0x32, 0x0f, 0x4f, + 0x08, 0xf0, 0xd0, 0x2b, 0xea, 0xb0, 0xfc, 0xec, 0xd9, 0x43, 0x7e, 0xce, 0x0c, + 0xfa, 0x0b, 0x44, 0xc2, 0xc5, 0x18, 0xca, 0xe2, 0x01, 0xea, 0xa7, 0x36, 0xbd, + 0x24, 0xc8, 0xcd, 0xea, 0x1f, 0xd0, 0x14, 0xc0, 0xd3, 0xdc, 0x2b, 0xc9, 0xee, + 0xdd, 0xee, 0xfd, 0xb9, 0x0d, 0x26, 0x18, 0x25, 0xf7, 0x2f, 0xf8, 0xf1, 0x0e, + 0x16, 0xbd, 0xeb, 0xd2, 0x32, 0xc8, 0x10, 0xee, 0xa8, 0x07, 0x1e, 0x7f, 0xbc, + 0xf8, 0x0b, 0x0a, 0x24, 0x13, 0xd4, 0x1f, 0x02, 0xee, 0xd8, 0x1a, 0x00, 0xdb, + 0xc3, 0xe3, 0xf8, 0x09, 0x13, 0xdf, 0x08, 0xb4, 0x01, 0x2b, 0xc5, 0x0e, 0x04, + 0xdc, 0xe4, 0x05, 0x14, 0xc2, 0x0e, 0xf1, 0xda, 0x0c, 0xcf, 0x3e, 0x2d, 0x0b, + 0xf0, 0x0f, 0xea, 0xb3, 0xb6, 0xed, 0x1c, 0xe6, 0xe3, 0x43, 0xf0, 0x1b, 0xc2, + 0xd3, 0xfe, 0xb2, 0x30, 0x0d, 0xe9, 0x3c, 0x11, 0xd9, 0x20, 0xf7, 0xf8, 0x1a, + 0xf9, 0x16, 0xbf, 0xfb, 0xc9, 0x20, 0x1b, 0xc1, 0xd5, 0x92, 0x0e, 0x07, 0x04, + 0x4c, 0xbe, 0xe9, 0xc4, 0x05, 0xfc, 0x0d, 0xea, 0x6a, 0xd6, 0xea, 0xcc, 0x11, + 0xf9, 0xd8, 0x1f, 0xe9, 0x37, 0xcb, 0xb5, 0xf8, 0x69, 0xfd, 0xcb, 0x7f, 0xe7, + 0x20, 0xff, 0x00, 0xe1, 0x1a, 0x11, 0xe3, 0xc6, 0xf2, 0x02, 0x20, 0xd4, 0xe3, + 0xeb, 0xfe, 0xcd, 0xd1, 0x03, 0xdc, 0xfb, 0x05, 0xd9, 0xe7, 0x0c, 0x3f, 0xe7, + 0x22, 0x09, 0xbb, 0xe3, 0xfd, 0xe3, 0xd7, 0xda, 0xaa, 0x1e, 0xdc, 0xc4, 0xd0, + 0xc9, 0x64, 0xca, 0x3f, 0xe8, 0x18, 0xe2, 0x38, 0x28, 0xf1, 0x06, 0x0f, 0x18, + 0xd3, 0xf3, 0xff, 0xe1, 0xbe, 0x41, 0x02, 0x1e, 0x38, 0x15, 0xa3, 0x19, 0xe4, + 0x2c, 0x10, 0x31, 0xe6, 0xf9, 0xd6, 0xcb, 0xf2, 0xde, 0x03, 0x2a, 0x39, 0xf4, + 0xcf, 0x05, 0xf8, 0x51, 0xe2, 0xdc, 0xd8, 0xd3, 0xe5, 0x01, 0xdc, 0x0f, 0xc3, + 0xfb, 0xb8, 0x11, 0xfc, 0x10, 0x04, 0xd0, 0xfa, 0xea, 0x30, 0xa8, 0x13, 0xd9, + 0x2d, 0x00, 0xe0, 0xff, 0x3a, 0xf8, 0x39, 0x7d, 0x2a, 0x92, 0x16, 0xdc, 0xe3, + 0x1e, 0xe1, 0xde, 0xf1, 0x0b, 0xc8, 0xdf, 0xc7, 0xf1, 0xdd, 0xa4, 0xe6, 0xe0, + 0xee, 0x02, 0x0e, 0xfe, 0xcf, 0xb8, 0xe5, 0xde, 0x1f, 0x91, 0xf6, 0xd9, 0xf2, + 0xe0, 0xcb, 0xfe, 0xf5, 0x01, 0xf3, 0x43, 0x99, 0x1b, 0xd1, 0xbd, 0x35, 0xe4, + 0xd0, 0x87, 0xa8, 0xb8, 0x59, 0xf0, 0xa9, 0xd0, 0x88, 0x2e, 0x37, 0xb5, 0x02, + 0x42, 0xbb, 0x57, 0x5e, 0x07, 0xd3, 0x19, 0x4e, 0x1e, 0xe9, 0x20, 0xf9, 0xb5, + 0x27, 0xd6, 0xfe, 0xf6, 0x4b, 0xf7, 0xf1, 0xba, 0x43, 0xe2, 0x2f, 0x09, 0x91, + 0xf6, 0x14, 0xb5, 0x19, 0xa5, 0xe3, 0xda, 0xf4, 0x26, 0xe0, 0xdb, 0x1e, 0xbd, + 0x12, 0xbb, 0x16, 0xec, 0xc7, 0xa5, 0xd1, 0xea, 0xcf, 0x46, 0xb1, 0xc9, 0xde, + 0xdf, 0xd3, 0x07, 0x31, 0x4c, 0xdf, 0x2a, 0xe0, 0x3b, 0xbd, 0x1b, 0xec, 0x35, + 0x94, 0xe1, 0x20, 0xa8, 0x1b, 0x00, 0xd0, 0x1e, 0x29, 0xe8, 0xe7, 0x35, 0x0a, + 0x29, 0x47, 0xbe, 0x14, 0x48, 0xbc, 0x26, 0xdb, 0xdf, 0xec, 0x03, 0x5f, 0x0a, + 0x28, 0xf8, 0x4b, 0xe7, 0x8e, 0xfe, 0x91, 0xc5, 0x9f, 0x49, 0xed, 0xbc, 0x41, + 0x20, 0x9d, 0xc9, 0xcd, 0xf2, 0xf7, 0x34, 0x0e, 0xda, 0x2a, 0x98, 0xe0, 0x81, + 0x9e, 0x5c, 0x29, 0xd0, 0xcb, 0x3b, 0xef, 0x5c, 0x1c, 0xbc, 0xef, 0x03, 0xfe, + 0x42, 0x3f, 0xc2, 0xd6, 0xea, 0xd1, 0x8a, 0xe3, 0x04, 0xc0, 0x15, 0x38, 0x0d, + 0xfa, 0xb9, 0xb4, 0x1a, 0xd1, 0x47, 0xa0, 0x20, 0x40, 0xf1, 0xd0, 0xbb, 0x06, + 0x19, 0x2a, 0x48, 0xd3, 0x27, 0xf0, 0xf2, 0x1e, 0x0f, 0x19, 0x09, 0x3c, 0xe2, + 0xc2, 0xba, 0x31, 0xf3, 0xf6, 0x30, 0xb5, 0xd6, 0xe4, 0x30, 0x50, 0x14, 0x13, + 0x5a, 0x0e, 0x44, 0xfe, 0xd5, 0xf2, 0xb6, 0xde, 0x28, 0x55, 0x10, 0xfd, 0x0e, + 0xc0, 0xf4, 0xfd, 0x2a, 0x11, 0xae, 0xbe, 0x05, 0xd3, 0x33, 0xc2, 0xcd, 0xc5, + 0xc3, 0xad, 0x26, 0xea, 0x29, 0x6d, 0x17, 0xed, 0x4d, 0xe7, 0xed, 0xdc, 0xcf, + 0xc8, 0x49, 0xfb, 0xe5, 0x07, 0x20, 0xbf, 0x28, 0xd9, 0xef, 0xca, 0xe9, 0xc4, + 0x8f, 0xd7, 0xc3, 0xde, 0xb5, 0xf3, 0xeb, 0x99, 0xac, 0xf4, 0xf3, 0xe4, 0xfd, + 0xfc, 0x15, 0xf6, 0x09, 0xc4, 0xf0, 0xf5, 0xd0, 0xf8, 0xf7, 0xb1, 0xf9, 0x0a, + 0xf8, 0x2e, 0xe6, 0xf9, 0xfb, 0x15, 0x15, 0x0c, 0x1b, 0xf7, 0xe8, 0x08, 0xd5, + 0x1b, 0xfd, 0xeb, 0xfb, 0xf4, 0xe0, 0xeb, 0x10, 0x00, 0xf5, 0xcf, 0x1e, 0xfb, + 0xd8, 0x5a, 0xf1, 0x08, 0xe0, 0xd9, 0x95, 0xd4, 0x47, 0x0d, 0x06, 0x18, 0xde, + 0x03, 0xfd, 0xfb, 0xd3, 0xed, 0xe7, 0x0c, 0xeb, 0x2c, 0xe4, 0x2f, 0xfd, 0xf0, + 0xf0, 0xf9, 0x08, 0xdf, 0xec, 0x38, 0xff, 0xe9, 0xc7, 0xe0, 0xc8, 0xd1, 0xcc, + 0x14, 0x0e, 0x03, 0x78, 0xd6, 0xfc, 0xf9, 0xf1, 0xed, 0xf7, 0xda, 0x07, 0x04, + 0x07, 0xf0, 0xee, 0x26, 0xef, 0xd1, 0xff, 0x23, 0x13, 0xdf, 0xfa, 0x18, 0xf4, + 0xe2, 0xe5, 0x17, 0xfe, 0xc6, 0x25, 0xf6, 0xd2, 0xe4, 0xd0, 0x19, 0xf1, 0x11, + 0xfe, 0x02, 0x09, 0x3b, 0x04, 0xf1, 0x13, 0xbe, 0xb8, 0xf2, 0xfb, 0xf8, 0x24, + 0x12, 0x1b, 0xfb, 0x10, 0xe1, 0xf2, 0x60, 0xfd, 0xed, 0x30, 0x2b, 0x27, 0x08, + 0x20, 0xae, 0xf7, 0x06, 0x13, 0xee, 0x00, 0xfe, 0x11, 0x06, 0x1b, 0xe0, 0xfb, + 0x0e, 0x1a, 0xc4, 0xdf, 0x1a, 0xff, 0xfd, 0x15, 0xfe, 0xf3, 0xfe, 0x0b, 0xea, + 0xfa, 0x0e, 0x0e, 0x27, 0xff, 0x03, 0xf4, 0x22, 0xff, 0x02, 0xf0, 0xf9, 0xf5, + 0xf4, 0x39, 0xf2, 0xd4, 0x07, 0x00, 0xf1, 0xff, 0xe8, 0xf4, 0xea, 0x15, 0x18, + 0xe1, 0x25, 0x05, 0x2b, 0xd3, 0x05, 0xf6, 0x01, 0xff, 0x34, 0x05, 0x0e, 0x7f, + 0x1d, 0x02, 0xee, 0x0e, 0xf8, 0x16, 0xdc, 0xc7, 0x12, 0xbc, 0xda, 0xda, 0x16, + 0x02, 0xdd, 0xd8, 0xc7, 0x10, 0xe2, 0x34, 0x03, 0xfc, 0xfe, 0xf1, 0x15, 0xe7, + 0xca, 0xe0, 0x10, 0x07, 0x02, 0x16, 0xfa, 0xf9, 0x05, 0xb5, 0xed, 0xc8, 0xc5, + 0xe5, 0xe4, 0x14, 0xf9, 0x0b, 0x30, 0xee, 0xf5, 0xbf, 0x17, 0xe2, 0x19, 0xc7, + 0xa5, 0xc7, 0xd5, 0x3d, 0xbe, 0x1b, 0xaa, 0xc8, 0x44, 0x09, 0xdb, 0xf2, 0x31, + 0xec, 0xca, 0x11, 0xfb, 0x5d, 0xfe, 0x0d, 0x58, 0x3c, 0xb8, 0xe9, 0x3f, 0xde, + 0xbb, 0xeb, 0x28, 0xd5, 0xff, 0xce, 0x06, 0xb4, 0xbb, 0x81, 0xdf, 0x5e, 0xff, + 0xe6, 0xed, 0x5f, 0xae, 0xe1, 0x0a, 0x23, 0xcd, 0x37, 0x40, 0x32, 0x44, 0x47, + 0xc2, 0x9e, 0x18, 0xdb, 0x49, 0x4f, 0x21, 0xd3, 0x10, 0xd1, 0x08, 0xec, 0xe8, + 0xa6, 0x39, 0x9e, 0xad, 0x23, 0x37, 0x88, 0x16, 0xc7, 0x3e, 0xa6, 0xf4, 0x10, + 0xe6, 0xbc, 0xf3, 0x1d, 0xc7, 0x13, 0x34, 0xaa, 0xc6, 0xec, 0xd4, 0xb6, 0x27, + 0xfa, 0xf0, 0x8e, 0xe4, 0xdb, 0x0d, 0x30, 0xd3, 0x3f, 0xe3, 0xef, 0x2c, 0xd6, + 0xa9, 0xca, 0xaa, 0x27, 0x55, 0x21, 0x1e, 0xb4, 0xf0, 0xf0, 0x00, 0x08, 0x0a, + 0xff, 0xef, 0xd7, 0x36, 0xd5, 0xe2, 0xee, 0xca, 0xf1, 0x42, 0xe6, 0xfd, 0x37, + 0xe8, 0xde, 0xe8, 0xdf, 0x21, 0x17, 0x4c, 0x21, 0xee, 0x12, 0xca, 0x12, 0xab, + 0xde, 0xf4, 0xe2, 0xbd, 0x8b, 0x12, 0xf2, 0x21, 0x28, 0xd5, 0x55, 0xdb, 0x41, + 0xad, 0x48, 0x33, 0x21, 0x4a, 0x20, 0xfb, 0xf4, 0x31, 0x38, 0x1c, 0x08, 0x5d, + 0x43, 0x98, 0xa6, 0x3f, 0xc6, 0xe5, 0xf9, 0x3e, 0x07, 0xef, 0x2e, 0xed, 0x1d, + 0x0d, 0xe9, 0xf1, 0x26, 0x16, 0x12, 0x10, 0x01, 0x3b, 0x32, 0xdf, 0xc9, 0x69, + 0x98, 0x33, 0x25, 0x81, 0xe2, 0x02, 0xff, 0xc7, 0x1f, 0xe6, 0x03, 0xe1, 0xc8, + 0x2d, 0xe6, 0x38, 0xec, 0x12, 0x56, 0x16, 0xea, 0x54, 0xf4, 0xd0, 0x03, 0x1e, + 0xf6, 0xe8, 0xe3, 0x11, 0xed, 0x14, 0xcb, 0xf7, 0xb8, 0xcf, 0xfb, 0xa9, 0xe9, + 0x00, 0xdd, 0xdd, 0xfc, 0xb6, 0xae, 0x0a, 0x12, 0xcd, 0x06, 0xa2, 0xb9, 0x0a, + 0x04, 0xb1, 0x4b, 0xd5, 0xe9, 0x39, 0x23, 0x6e, 0xa5, 0xc3, 0xd5, 0xf4, 0xb3, + 0xf1, 0x08, 0x16, 0x64, 0x3f, 0xde, 0xe2, 0xba, 0x09, 0xe6, 0xee, 0xce, 0xf5, + 0xab, 0xd9, 0x35, 0xcc, 0x0e, 0xfe, 0xe4, 0x21, 0x21, 0x39, 0x04, 0x26, 0x44, + 0xa5, 0x2d, 0x39, 0xe0, 0xfb, 0x25, 0x09, 0x09, 0xb7, 0xf6, 0xde, 0x14, 0x04, + 0x4a, 0xcc, 0x38, 0xfc, 0x12, 0x36, 0x93, 0x36, 0xd3, 0xea, 0xfe, 0xf8, 0xa2, + 0xd0, 0x1e, 0x03, 0xc5, 0xba, 0xe8, 0xf5, 0x28, 0xe8, 0x18, 0x2f, 0xfe, 0xf0, + 0xdc, 0x4d, 0x3b, 0xdf, 0x31, 0x07, 0x0e, 0xd0, 0xfd, 0x24, 0x1a, 0xd9, 0x26, + 0xcc, 0x4a, 0xd2, 0xbf, 0xdb, 0xfc, 0xe4, 0x34, 0x12, 0xf4, 0x26, 0x59, 0x15, + 0xce, 0x3b, 0xbe, 0xe3, 0xdf, 0xf5, 0x03, 0xbc, 0x20, 0x73, 0xfe, 0xc9, 0xe0, + 0x08, 0xeb, 0xc0, 0x31, 0xd1, 0xab, 0x08, 0xd9, 0xa5, 0xda, 0x3d, 0xfc, 0x39, + 0x28, 0xdd, 0xff, 0xc0, 0xd8, 0x6c, 0xf5, 0xff, 0x2d, 0xd7, 0x9e, 0x1e, 0xbc, + 0x1f, 0xc6, 0xf0, 0x28, 0xf2, 0xad, 0x25, 0xbf, 0x8a, 0x37, 0x34, 0xf0, 0x56, + 0xf2, 0x4f, 0x0d, 0x30, 0x0e, 0x1d, 0x17, 0xf2, 0xaa, 0xea, 0x18, 0x29, 0x06, + 0x06, 0xf2, 0x26, 0x64, 0x1c, 0x01, 0xcc, 0x0d, 0x0d, 0x09, 0x02, 0xa4, 0x08, + 0xdd, 0x02, 0xd2, 0x36, 0xe6, 0x8c, 0x2f, 0x0d, 0xdb, 0xfe, 0x3d, 0x10, 0x20, + 0x07, 0xd6, 0x0e, 0x47, 0x34, 0x05, 0xd3, 0x8f, 0x1d, 0x12, 0x29, 0xcf, 0xf8, + 0x1e, 0xbd, 0x50, 0x4d, 0xbf, 0xdc, 0xef, 0xf2, 0xeb, 0x21, 0x1c, 0x08, 0x02, + 0x0f, 0xb3, 0xce, 0xcb, 0xd8, 0x04, 0x2f, 0x02, 0x02, 0xe4, 0xa2, 0xfa, 0xed, + 0xca, 0x81, 0x08, 0xd6, 0xfb, 0xd1, 0x4f, 0xd9, 0x21, 0x4b, 0xe6, 0x2d, 0xeb, + 0xe0, 0xb1, 0x34, 0xfb, 0x2f, 0x46, 0xdd, 0x39, 0xed, 0xd5, 0xfb, 0xe0, 0x11, + 0xe9, 0x0e, 0xc2, 0x39, 0x22, 0xce, 0xd5, 0xdd, 0x28, 0x99, 0xe2, 0xc0, 0x99, + 0xea, 0x0b, 0x4a, 0x0a, 0x20, 0xc2, 0xb5, 0xed, 0xb2, 0x52, 0xba, 0xe5, 0xf9, + 0x1f, 0xcd, 0xc2, 0xca, 0xd5, 0x18, 0xd1, 0xe7, 0x44, 0x25, 0xaa, 0xde, 0x3c, + 0x8e, 0xc6, 0xf0, 0x1a, 0xe5, 0x02, 0xfd, 0xf7, 0x1a, 0xf6, 0x5f, 0xc8, 0xd8, + 0xf9, 0x1d, 0x06, 0x8d, 0xbd, 0x5c, 0xc7, 0xb4, 0xc6, 0x25, 0xd4, 0x5a, 0x34, + 0x11, 0x9f, 0x87, 0xdd, 0x1a, 0x9b, 0xe8, 0x24, 0xdf, 0x1d, 0x2d, 0xce, 0xf8, + 0x40, 0x3a, 0x16, 0xd5, 0xf8, 0xcb, 0xe6, 0x09, 0xf6, 0xce, 0x2f, 0x06, 0xd2, + 0x1b, 0x25, 0xaa, 0xeb, 0xd6, 0xbc, 0xf5, 0x05, 0x57, 0x05, 0x07, 0xf8, 0xbb, + 0x0a, 0xab, 0xe1, 0x4a, 0xb9, 0xf4, 0xc0, 0xea, 0xe0, 0xc3, 0xee, 0x2c, 0xe7, + 0xf9, 0xdd, 0x03, 0xdd, 0x58, 0xf0, 0xf0, 0xd3, 0xda, 0x54, 0x09, 0xe0, 0xc4, + 0xdc, 0xc7, 0xc7, 0x3a, 0x0a, 0xb0, 0xc6, 0x06, 0xe7, 0x1b, 0x00, 0xc2, 0x25, + 0xc5, 0x0f, 0xe9, 0x2f, 0xe0, 0x16, 0x17, 0x16, 0x14, 0x25, 0xd2, 0x12, 0xef, + 0x27, 0x19, 0xc5, 0x0a, 0xe7, 0x10, 0x08, 0x96, 0x41, 0xfe, 0x06, 0x16, 0x0c, + 0x20, 0x3b, 0xb2, 0x0b, 0xd9, 0xe7, 0xe5, 0x09, 0xf8, 0xb8, 0xec, 0xe4, 0x59, + 0xbf, 0x2d, 0x0c, 0x49, 0xff, 0x58, 0xca, 0x00, 0x05, 0x2a, 0x36, 0xa7, 0xf1, + 0x07, 0xa0, 0xb6, 0x17, 0x19, 0xc6, 0x1f, 0x3b, 0xe8, 0x12, 0x46, 0xf9, 0x29, + 0xeb, 0x47, 0x81, 0x07, 0x1a, 0xfc, 0x44, 0x5f, 0xe1, 0xf0, 0xba, 0x40, 0xeb, + 0x42, 0xfa, 0x1b, 0xe8, 0xe7, 0xee, 0xe9, 0xf8, 0x38, 0xf9, 0x4b, 0x11, 0x0e, + 0x03, 0x26, 0x06, 0x19, 0x0e, 0xdc, 0xc3, 0x10, 0x12, 0x01, 0xf1, 0x3e, 0xcd, + 0x06, 0xdf, 0xf3, 0xb4, 0x15, 0x00, 0x13, 0xbf, 0x56, 0x9a, 0xdb, 0xf8, 0xd8, + 0x37, 0xcf, 0xf5, 0x22, 0xd0, 0x21, 0x3f, 0xd8, 0x31, 0xdd, 0xfd, 0xf7, 0xe5, + 0x0a, 0xc3, 0xdd, 0xe9, 0xe9, 0x1f, 0x10, 0x3f, 0x81, 0xfb, 0x27, 0xb4, 0xa3, + 0xd7, 0xf1, 0xfc, 0x12, 0x61, 0xff, 0xfb, 0x37, 0x08, 0xd7, 0x32, 0xf8, 0xa0, + 0xfe, 0x0d, 0xeb, 0xff, 0xef, 0xec, 0xdf, 0xc0, 0x1a, 0x3c, 0xd1, 0xe3, 0xf4, + 0x3c, 0xbe, 0x1c, 0xf2, 0xed, 0x0f, 0xf2, 0x36, 0xd7, 0x1d, 0xfd, 0x12, 0x0a, + 0xf1, 0x06, 0xf9, 0xb8, 0xa5, 0xf8, 0xf5, 0xbd, 0x36, 0x99, 0xc6, 0xf4, 0x0b, + 0x56, 0x17, 0x61, 0x21, 0xa4, 0xc0, 0x43, 0xe9, 0x01, 0xe6, 0xcf, 0xb2, 0xe4, + 0x14, 0x03, 0xde, 0xcc, 0xf5, 0x03, 0xd5, 0xa6, 0x10, 0xc0, 0xe0, 0xfa, 0x19, + 0xbd, 0xe2, 0x29, 0xd2, 0xfa, 0x4c, 0x19, 0xc4, 0x3f, 0x1d, 0xf2, 0x2a, 0xde, + 0xd5, 0x37, 0xde, 0xc8, 0xbc, 0x22, 0x5c, 0xf2, 0x15, 0xd2, 0xde, 0x32, 0x24, + 0xbe, 0xc9, 0x23, 0xe7, 0x90, 0x34, 0x1b, 0xf4, 0xa4, 0x45, 0xe6, 0x11, 0x09, + 0xe7, 0x22, 0xf5, 0x53, 0x4e, 0xc9, 0xe3, 0x26, 0xe4, 0x49, 0x3a, 0xd2, 0x26, + 0xc1, 0xff, 0xd8, 0x23, 0x23, 0x30, 0xc4, 0x04, 0xc8, 0xa0, 0x3b, 0x9b, 0xfb, + 0x4a, 0xdf, 0x17, 0x11, 0xa9, 0x08, 0x0d, 0x21, 0x63, 0x0e, 0x3e, 0x53, 0x28, + 0xdc, 0x1d, 0x06, 0xc6, 0xb1, 0xd3, 0x22, 0xf8, 0x2c, 0x03, 0xcb, 0x28, 0xf7, + 0x0b, 0x00, 0xff, 0xba, 0xfb, 0xf3, 0x0e, 0x2e, 0xaa, 0xe1, 0x29, 0x2c, 0xd6, + 0xfc, 0xc9, 0xd9, 0x23, 0x27, 0x04, 0xeb, 0x45, 0x26, 0xfc, 0x11, 0x81, 0x3c, + 0x2b, 0xf4, 0x54, 0xf9, 0xd4, 0x20, 0x1c, 0xf3, 0xcd, 0x0a, 0x24, 0xda, 0x11, + 0xfb, 0xfa, 0xec, 0xc3, 0x69, 0x17, 0xff, 0xcb, 0xec, 0x2b, 0xde, 0x3b, 0x2a, + 0x2c, 0x32, 0xe5, 0xa7, 0x01, 0xdf, 0xe8, 0xfe, 0x2a, 0x3f, 0x50, 0xe3, 0xf1, + 0xfd, 0x1b, 0xb6, 0xc8, 0xd5, 0x07, 0x07, 0xf9, 0xeb, 0x44, 0xb8, 0xf2, 0x3a, + 0xe0, 0x0e, 0xb9, 0xee, 0xe2, 0x08, 0xdc, 0xd3, 0xd7, 0xdd, 0xf1, 0xea, 0xc9, + 0x24, 0xe0, 0x37, 0xb8, 0x39, 0x3d, 0x28, 0x2d, 0xcf, 0xe9, 0xad, 0xbf, 0x0b, + 0xf8, 0xf0, 0x20, 0x0c, 0xe5, 0xa8, 0xae, 0x14, 0x0c, 0xe0, 0x2e, 0x24, 0x18, + 0xa5, 0x5f, 0xca, 0x24, 0x12, 0xdf, 0x09, 0xf2, 0x1e, 0xde, 0xcc, 0xe8, 0xfc, + 0xe0, 0xdf, 0xa5, 0xad, 0xdd, 0x3a, 0x14, 0x07, 0x25, 0x2c, 0xf5, 0x41, 0xcd, + 0xdf, 0x20, 0x1e, 0x04, 0xe0, 0x53, 0x4d, 0xf2, 0x82, 0xde, 0xfc, 0xca, 0xf4, + 0xd8, 0x3c, 0x36, 0xd6, 0xb3, 0x1e, 0xff, 0x07, 0x2a, 0xdc, 0xb3, 0xe3, 0x17, + 0x13, 0xdf, 0x25, 0xa7, 0xd5, 0x16, 0x23, 0x1b, 0x1c, 0x53, 0xa1, 0xb7, 0x05, + 0x81, 0xec, 0xf7, 0x5d, 0xa0, 0x5b, 0x04, 0x3e, 0xbd, 0x2d, 0xaa, 0xd3, 0x00, + 0xa5, 0x11, 0x2e, 0xe1, 0x0a, 0x83, 0x27, 0x37, 0xb5, 0xce, 0x0d, 0xd4, 0x49, + 0xfe, 0x3f, 0xeb, 0x17, 0xfc, 0x2e, 0x0b, 0x03, 0xfd, 0xc0, 0x91, 0xf1, 0x51, + 0xc6, 0xfb, 0xd5, 0xf6, 0x02, 0x05, 0xd0, 0x08, 0xee, 0x3a, 0x05, 0xaa, 0x42, + 0xbb, 0x09, 0x22, 0x13, 0xd6, 0xd0, 0x57, 0x2e, 0x02, 0x4a, 0xc0, 0xef, 0x1b, + 0xdd, 0xf1, 0xe8, 0x15, 0x18, 0xe6, 0x35, 0x17, 0xad, 0xf5, 0x05, 0x14, 0x03, + 0x02, 0x4a, 0xda, 0x09, 0xea, 0xfc, 0x46, 0x86, 0xe8, 0xcd, 0xc9, 0x1a, 0x42, + 0xbb, 0xca, 0xd6, 0xaf, 0x34, 0x3f, 0xc3, 0xd4, 0xeb, 0x1b, 0x2e, 0xdf, 0x08, + 0x4c, 0x03, 0xed, 0xd5, 0xd5, 0xe7, 0x00, 0x13, 0x1c, 0x04, 0xe0, 0x23, 0x27, + 0xaf, 0x36, 0x86, 0xa3, 0xa3, 0xed, 0x2a, 0x22, 0x4a, 0x07, 0x15, 0xe5, 0xb4, + 0xef, 0xe1, 0x4c, 0x26, 0xfb, 0x15, 0x7d, 0xdb, 0xde, 0x12, 0x11, 0xe8, 0xbf, + 0xf3, 0xa7, 0x56, 0xfb, 0xbc, 0x32, 0xd0, 0x05, 0xfe, 0xfd, 0xca, 0xef, 0x0a, + 0x0f, 0xc3, 0xf7, 0xfd, 0xf8, 0x13, 0x16, 0x1b, 0x0d, 0xc9, 0xc0, 0xeb, 0xbb, + 0x43, 0xd1, 0xef, 0x48, 0xe9, 0xd5, 0xeb, 0xee, 0xd8, 0x24, 0x2c, 0xfe, 0x01, + 0x19, 0xd7, 0x05, 0xe8, 0x2c, 0xcb, 0x01, 0x1b, 0xf7, 0xe1, 0x0a, 0xea, 0x4f, + 0x27, 0xdc, 0xca, 0x1d, 0x41, 0xdb, 0x01, 0x5d, 0xd5, 0xda, 0x14, 0xfd, 0xf5, + 0xe0, 0xdf, 0x13, 0x08, 0x38, 0x4b, 0xef, 0xd3, 0xc7, 0x14, 0x00, 0x24, 0xe4, + 0xb3, 0x38, 0x3e, 0xe7, 0x11, 0x1e, 0x20, 0x13, 0x15, 0xd7, 0x06, 0xf1, 0xb7, + 0xfc, 0xda, 0xd8, 0x02, 0x09, 0xc7, 0xfa, 0xc2, 0xfe, 0x1b, 0xfd, 0xe3, 0xba, + 0x15, 0xf6, 0x02, 0x08, 0x03, 0x7f, 0x01, 0xf7, 0x1c, 0xc2, 0x05, 0xe8, 0xfe, + 0xf9, 0x0e, 0xd1, 0x50, 0xe4, 0xe1, 0x02, 0xc8, 0x3d, 0xec, 0x56, 0x0b, 0x16, + 0x09, 0x19, 0x19, 0x33, 0x10, 0x0f, 0xee, 0xcb, 0xe9, 0xd5, 0x07, 0xe3, 0x3b, + 0xef, 0x05, 0x1f, 0x2f, 0x19, 0x44, 0x2d, 0xee, 0x25, 0x06, 0x0e, 0x00, 0x11, + 0x1a, 0x46, 0x07, 0x26, 0x1b, 0x1f, 0xbe, 0xf2, 0x25, 0xcb, 0xe2, 0xee, 0xeb, + 0xe2, 0x08, 0x0b, 0x17, 0xfc, 0xe5, 0xc6, 0xfe, 0xd3, 0x1b, 0xc2, 0x19, 0x19, + 0x14, 0x3a, 0x10, 0x35, 0x1a, 0x7a, 0xfe, 0x1d, 0xfe, 0xfb, 0x09, 0x0f, 0xca, + 0x25, 0x49, 0x2c, 0xb0, 0xf9, 0xd3, 0xcb, 0xdb, 0x19, 0x4e, 0xd5, 0xed, 0xe0, + 0xec, 0x4a, 0xfe, 0xee, 0xcf, 0xec, 0x03, 0xf6, 0x2b, 0xcc, 0x18, 0x1a, 0xe6, + 0xf2, 0x09, 0xdc, 0xcf, 0xe2, 0x07, 0x01, 0xf6, 0xe7, 0x00, 0xdb, 0xb4, 0xc0, + 0x19, 0xdf, 0x07, 0x59, 0xd0, 0x43, 0xea, 0xc8, 0xd2, 0x81, 0xf3, 0xec, 0x08, + 0xed, 0x0f, 0xd9, 0xe4, 0xf5, 0xd7, 0xcd, 0x3d, 0x0d, 0xe6, 0x60, 0xf6, 0xd7, + 0x60, 0xf6, 0x04, 0x0b, 0xfb, 0xfb, 0x17, 0xf5, 0xec, 0xef, 0xe6, 0x10, 0xe0, + 0xc2, 0x00, 0x2a, 0xd4, 0xfe, 0x11, 0x20, 0xd9, 0xe8, 0xf5, 0x0c, 0xde, 0x22, + 0x05, 0x36, 0xb1, 0xd5, 0x0e, 0xcd, 0x1d, 0xda, 0x02, 0xfc, 0x03, 0xdd, 0x51, + 0xdd, 0x0a, 0xf9, 0xe9, 0x0e, 0xf9, 0xf3, 0xcd, 0xcc, 0xf4, 0x24, 0x1a, 0x08, + 0xf2, 0x23, 0xeb, 0xed, 0xce, 0xff, 0xdf, 0x0f, 0xf3, 0xc4, 0xeb, 0x12, 0xef, + 0x1b, 0x47, 0xca, 0xc6, 0xd0, 0x01, 0xfd, 0x32, 0xea, 0x1e, 0xfc, 0xba, 0xdd, + 0x14, 0x0f, 0xe3, 0xef, 0xe8, 0xca, 0x19, 0xfb, 0xdd, 0x12, 0x15, 0xf6, 0x02, + 0x1f, 0x20, 0x0e, 0xe5, 0x0e, 0x03, 0xf7, 0xe9, 0x06, 0xf4, 0xde, 0x22, 0xee, + 0x50, 0x50, 0x14, 0xef, 0x16, 0xd7, 0xce, 0x15, 0xf3, 0xfe, 0x2d, 0xe2, 0xf8, + 0xdf, 0x1d, 0xfa, 0x0a, 0x5d, 0xf1, 0x0c, 0x1f, 0x3e, 0xfe, 0x4b, 0x00, 0xc0, + 0xbf, 0x02, 0x04, 0x10, 0x1f, 0x37, 0xd9, 0x2a, 0x08, 0xe4, 0xfb, 0x27, 0x1b, + 0xe9, 0xdc, 0xde, 0x33, 0xf7, 0x10, 0xd9, 0xf0, 0xff, 0x50, 0x27, 0xf1, 0x1e, + 0x24, 0x40, 0xd2, 0x06, 0x17, 0x11, 0x17, 0xf3, 0xdf, 0x11, 0xe6, 0x18, 0x29, + 0xff, 0xe3, 0xd2, 0xd6, 0xcd, 0xf4, 0x0a, 0xf1, 0x0d, 0x6d, 0x08, 0x11, 0xfc, + 0x07, 0xd6, 0xc8, 0x25, 0xbe, 0x04, 0x02, 0x1c, 0xf5, 0x01, 0x2f, 0x0a, 0x0e, + 0xd9, 0xf4, 0xdf, 0x1d, 0xe6, 0xd2, 0x02, 0xda, 0x2c, 0xc4, 0x00, 0xed, 0x21, + 0xeb, 0xcf, 0x2a, 0xf4, 0xb5, 0xfc, 0xb4, 0xc9, 0x03, 0xeb, 0xf4, 0xdd, 0x04, + 0xf4, 0x07, 0xdd, 0x10, 0xf8, 0xea, 0xdd, 0xf5, 0x06, 0xad, 0xce, 0xd6, 0xf7, + 0x1a, 0x21, 0xdc, 0x3d, 0xd7, 0x29, 0xf8, 0xed, 0x1b, 0x0d, 0xc7, 0x08, 0xcf, + 0xc4, 0x2a, 0xe3, 0x2c, 0xec, 0x27, 0x1f, 0xbe, 0x28, 0xd8, 0xe0, 0xab, 0xb5, + 0xf0, 0xd1, 0xd0, 0xeb, 0x41, 0xeb, 0x11, 0x06, 0xd8, 0xb9, 0xd4, 0x37, 0xce, + 0x09, 0x1b, 0x07, 0xf0, 0x0b, 0xde, 0xe4, 0xf4, 0x04, 0xd9, 0x2d, 0x1d, 0xf0, + 0xf9, 0x03, 0xf1, 0xb5, 0xe2, 0xd1, 0xf2, 0x38, 0xf0, 0x04, 0xc8, 0xb4, 0xf8, + 0x18, 0xc7, 0x56, 0xfe, 0x0a, 0xe3, 0x16, 0xfd, 0x26, 0xfd, 0xeb, 0xdf, 0x09, + 0xf5, 0xdc, 0x15, 0x04, 0xd6, 0xd1, 0x22, 0x18, 0x81, 0x0c, 0xdd, 0xb7, 0x05, + 0xda, 0xec, 0x25, 0xed, 0x12, 0x18, 0x56, 0xc9, 0xab, 0xd2, 0x06, 0xe2, 0xeb, + 0xe5, 0xb3, 0xc6, 0xec, 0xf3, 0x22, 0xaa, 0xfb, 0x09, 0x10, 0xe8, 0xd9, 0xfe, + 0xdc, 0x03, 0x45, 0xed, 0x18, 0x0f, 0xab, 0xfd, 0xdf, 0xeb, 0xe1, 0x19, 0xb3, + 0xd1, 0xfc, 0xd5, 0x3f, 0x1a, 0x04, 0x9e, 0xfc, 0x1c, 0x28, 0xb4, 0xd7, 0xf4, + 0xe2, 0xcc, 0xf3, 0x48, 0x24, 0xcb, 0x41, 0xf1, 0x02, 0xf1, 0xbf, 0x07, 0xf3, + 0x5c, 0xff, 0xcb, 0xd0, 0xe8, 0xc6, 0x65, 0xf3, 0xb2, 0x27, 0x2a, 0xe7, 0xc4, + 0xd0, 0x0d, 0x93, 0x06, 0xdc, 0xe7, 0x0d, 0x30, 0x34, 0xf8, 0x03, 0x23, 0xf5, + 0x07, 0xc1, 0xfa, 0x2f, 0xe8, 0x05, 0x10, 0xd0, 0x36, 0x31, 0xe6, 0xfa, 0x9a, + 0x99, 0xd7, 0x01, 0x0b, 0x23, 0xee, 0xea, 0x1f, 0x02, 0xd3, 0x40, 0xb5, 0xb6, + 0x9f, 0xfb, 0xd8, 0x11, 0xce, 0x01, 0xf9, 0xe4, 0xf3, 0xcb, 0xb2, 0xfb, 0xd6, + 0xf0, 0x1b, 0x25, 0xe4, 0x14, 0xea, 0xa6, 0x2b, 0xee, 0xe5, 0x08, 0xff, 0x54, + 0x13, 0xc7, 0xd9, 0xda, 0x31, 0xeb, 0x18, 0x0a, 0x01, 0xca, 0x0d, 0x57, 0x2d, + 0x05, 0x02, 0xe8, 0x06, 0xfc, 0xee, 0x22, 0xcc, 0xfd, 0x5e, 0x18, 0xfe, 0xf8, + 0xef, 0x3a, 0x9d, 0x09, 0x1e, 0xd5, 0xa7, 0xce, 0x4d, 0x0e, 0xf7, 0xd0, 0xfc, + 0xd0, 0xcf, 0xb5, 0xf6, 0x3d, 0x15, 0x18, 0xe1, 0x9a, 0xe1, 0xdc, 0x09, 0x15, + 0x21, 0x4e, 0xf5, 0x50, 0x30, 0xce, 0xc2, 0x11, 0xe2, 0xe1, 0x2e, 0xe1, 0x2d, + 0xd7, 0x11, 0xd4, 0xf3, 0x3f, 0x17, 0xa1, 0xc1, 0xce, 0xf4, 0x47, 0xdc, 0x4e, + 0xf6, 0xf3, 0x30, 0x61, 0xd6, 0xc4, 0x11, 0xe2, 0xe7, 0x9e, 0x07, 0xee, 0xda, + 0x4c, 0x41, 0xb8, 0x22, 0x47, 0xa9, 0xea, 0x10, 0xc4, 0x59, 0x91, 0xed, 0x8e, + 0x38, 0xe5, 0x5a, 0x22, 0xe6, 0x3b, 0x7f, 0x34, 0xeb, 0xbf, 0x08, 0xb4, 0x05, + 0x46, 0xa8, 0xe8, 0xc5, 0x1d, 0x23, 0xed, 0xcc, 0x4f, 0xf0, 0x11, 0x20, 0x20, + 0x33, 0xeb, 0xf6, 0x77, 0xf6, 0x0d, 0xa0, 0xfa, 0x8d, 0x49, 0xcc, 0x15, 0x09, + 0x0a, 0x35, 0xdc, 0xb3, 0x4e, 0xdc, 0x31, 0x0b, 0xd6, 0xb0, 0x0c, 0xff, 0x64, + 0xf9, 0xc8, 0xe8, 0x3c, 0xea, 0x46, 0x11, 0x26, 0xf6, 0x9a, 0x1f, 0xe5, 0x36, + 0x32, 0xf5, 0x0f, 0x4f, 0xdb, 0x0d, 0xd2, 0x0e, 0xff, 0x2b, 0xda, 0xca, 0xa8, + 0x26, 0xeb, 0xdd, 0x05, 0x1b, 0xa0, 0x07, 0x8a, 0x38, 0x27, 0x3a, 0x18, 0x01, + 0xbe, 0xbe, 0x3e, 0xd9, 0x01, 0xc6, 0x44, 0xb4, 0xdf, 0x1f, 0x16, 0xb9, 0x21, + 0xfb, 0xd8, 0xf2, 0xa3, 0xd5, 0xf5, 0xf2, 0x06, 0xc5, 0xc5, 0xf7, 0x3f, 0xd3, + 0x41, 0xf8, 0xd1, 0xf9, 0xe0, 0xbf, 0x0e, 0xdb, 0x94, 0xe5, 0x05, 0x03, 0xfe, + 0xd2, 0x3b, 0xf0, 0x01, 0xcc, 0x04, 0x98, 0x15, 0x09, 0xae, 0xa4, 0x22, 0x2b, + 0xab, 0x03, 0x21, 0x2c, 0x30, 0x38, 0x44, 0xee, 0x12, 0xf9, 0xfe, 0x15, 0xb1, + 0x49, 0x5d, 0x01, 0x9c, 0x31, 0x91, 0x3d, 0xeb, 0x1d, 0xa9, 0xe0, 0xe7, 0xcf, + 0xde, 0x26, 0xcf, 0xef, 0x14, 0x0f, 0xbc, 0x0d, 0xe9, 0x96, 0xe0, 0xec, 0xe8, + 0xc7, 0x1c, 0x06, 0xe1, 0xc2, 0xe0, 0xff, 0xdc, 0xfc, 0xf3, 0xe2, 0xe2, 0x01, + 0x21, 0xd3, 0x3b, 0xf3, 0x18, 0x19, 0xff, 0xe4, 0xcf, 0xbf, 0xe9, 0xd0, 0x39, + 0xe2, 0x12, 0xe6, 0xf2, 0xf3, 0xf9, 0xe8, 0xe2, 0xf5, 0xf6, 0x29, 0x9b, 0xa9, + 0x74, 0xb8, 0xef, 0xb4, 0xef, 0xc4, 0xfe, 0x35, 0x27, 0x0a, 0x05, 0xf9, 0x03, + 0x15, 0x15, 0xd9, 0x12, 0x29, 0xf6, 0xeb, 0x2d, 0x0c, 0x16, 0xf7, 0xee, 0xc2, + 0xb9, 0x1d, 0xd5, 0xef, 0x46, 0xf1, 0x0f, 0xe0, 0x07, 0xcf, 0xc6, 0x1d, 0xec, + 0x07, 0x11, 0x26, 0xf4, 0xde, 0xc1, 0xf0, 0xea, 0x1a, 0xda, 0xe5, 0x3b, 0x34, + 0xd4, 0xd6, 0x0a, 0xf9, 0xc6, 0xe0, 0x0b, 0xdf, 0x1b, 0xb4, 0xfa, 0xf0, 0xf7, + 0x0a, 0x0e, 0xcc, 0xcd, 0x01, 0xd6, 0x9f, 0xbf, 0xdc, 0xe0, 0xee, 0xe8, 0xf7, + 0xd9, 0x50, 0x25, 0x13, 0xfb, 0xe9, 0xb0, 0xe5, 0xfb, 0x4a, 0xd3, 0x02, 0xad, + 0x34, 0xc4, 0xf8, 0xf9, 0xe3, 0x5f, 0xfa, 0x01, 0xf0, 0xff, 0xf7, 0x0e, 0xf2, + 0xca, 0xe6, 0xfb, 0x0f, 0x08, 0xf2, 0xfb, 0x11, 0xe2, 0x15, 0xcc, 0xd5, 0x19, + 0x08, 0xad, 0xeb, 0x1a, 0xe5, 0x14, 0xd4, 0xf0, 0xf3, 0x0a, 0x1f, 0x1a, 0xf0, + 0xf7, 0x17, 0x19, 0xda, 0x1e, 0xf4, 0x20, 0x07, 0xdb, 0xe0, 0xb4, 0xef, 0x3c, + 0x03, 0xe2, 0xf0, 0xca, 0x44, 0xfa, 0xea, 0xf2, 0xec, 0xef, 0xfa, 0x14, 0xc5, + 0x3e, 0x1b, 0x2f, 0xfc, 0x07, 0xe3, 0x05, 0x24, 0xf3, 0xec, 0x10, 0x7f, 0xfe, + 0xed, 0x28, 0xee, 0x98, 0x1e, 0xe1, 0xb4, 0xee, 0x0d, 0xbe, 0x04, 0x3a, 0xcf, + 0xdb, 0xa5, 0xda, 0xd9, 0xed, 0x2a, 0x31, 0x00, 0xfe, 0xfb, 0xf9, 0xe7, 0xfa, + 0xa4, 0xc6, 0xe2, 0x02, 0xea, 0xfc, 0xeb, 0x14, 0xed, 0x11, 0x28, 0xd6, 0xd7, + 0xed, 0xef, 0xf1, 0xef, 0xc9, 0xe4, 0xf6, 0xe5, 0x47, 0x21, 0x0e, 0xcf, 0xa0, + 0x40, 0xce, 0xe1, 0x3c, 0xe9, 0xd9, 0xbd, 0x13, 0x14, 0x01, 0xe0, 0xc7, 0xef, + 0x39, 0xf1, 0x06, 0x09, 0x32, 0x30, 0x95, 0x10, 0xf4, 0x45, 0xd0, 0x1c, 0xe1, + 0xaa, 0x2f, 0x18, 0xeb, 0xc9, 0xf3, 0xa4, 0x1f, 0xd4, 0xda, 0x0e, 0xd0, 0x3a, + 0xfc, 0xf6, 0xa3, 0x20, 0xe2, 0xfa, 0x09, 0x5b, 0x17, 0x26, 0x25, 0x08, 0xf7, + 0xed, 0x2d, 0x18, 0xc9, 0xfb, 0xc0, 0xe0, 0x09, 0xdb, 0x02, 0x0f, 0xf1, 0xdd, + 0xbd, 0xba, 0xd8, 0xbd, 0x12, 0xca, 0xbb, 0xcf, 0xf5, 0x3a, 0x34, 0xf9, 0xfe, + 0xd7, 0x10, 0xfa, 0x0c, 0xfa, 0xe5, 0x23, 0x04, 0xf7, 0xf1, 0x0f, 0xde, 0xcf, + 0x90, 0x31, 0x05, 0x4b, 0xfa, 0xe6, 0xef, 0xf4, 0xd9, 0x01, 0x03, 0x39, 0x02, + 0xa8, 0xe7, 0xf5, 0x13, 0x36, 0xd9, 0xff, 0x90, 0xbe, 0xf0, 0x02, 0x45, 0xb4, + 0xc2, 0x22, 0x28, 0x9f, 0xed, 0xf5, 0x13, 0x15, 0xfd, 0x18, 0xeb, 0x3b, 0x22, + 0x00, 0xfa, 0xdd, 0xe4, 0xcc, 0xd1, 0x25, 0x28, 0xf2, 0xb8, 0xde, 0x16, 0x25, + 0x0f, 0x0e, 0xe5, 0xcd, 0xf1, 0x1e, 0x29, 0xe1, 0xfb, 0x2b, 0xb6, 0xe4, 0x02, + 0x00, 0xe3, 0x29, 0xe1, 0xda, 0x4d, 0xf2, 0xf7, 0x03, 0xc3, 0xed, 0xc8, 0x28, + 0xf8, 0xdd, 0xfe, 0x45, 0xf2, 0xb0, 0xe7, 0x31, 0xd0, 0xf7, 0xf5, 0xdd, 0x2e, + 0x18, 0xc7, 0x03, 0xeb, 0xbb, 0xd4, 0xb9, 0x2c, 0xd6, 0xef, 0xea, 0x29, 0xf2, + 0xfb, 0x0f, 0xa6, 0xcd, 0x32, 0xe9, 0xf5, 0xed, 0x2c, 0xe3, 0xe6, 0x10, 0xb0, + 0xd0, 0x49, 0xef, 0xfb, 0xab, 0xeb, 0xf7, 0xfd, 0x31, 0xef, 0xdf, 0xec, 0x08, + 0xd9, 0x35, 0x81, 0xc6, 0x24, 0xf0, 0x5a, 0xb0, 0x30, 0x3d, 0xe9, 0xbc, 0xdc, + 0xd8, 0x1b, 0xf2, 0xcc, 0x1c, 0xaf, 0x98, 0x09, 0xac, 0x38, 0xda, 0x05, 0x0a, + 0x3b, 0xcf, 0x28, 0xff, 0x35, 0xdc, 0x07, 0x20, 0x27, 0x57, 0xe3, 0xc4, 0x08, + 0x16, 0x0d, 0x30, 0x81, 0xab, 0x15, 0xe1, 0x10, 0x27, 0xa8, 0xd1, 0xcd, 0x42, + 0x0a, 0xf0, 0xed, 0x0d, 0x08, 0xc7, 0x30, 0xe3, 0x38, 0x0b, 0x24, 0xe6, 0x26, + 0x30, 0x59, 0x1b, 0xac, 0xf4, 0xc6, 0xb0, 0xdd, 0x52, 0x15, 0xb3, 0x2f, 0x8b, + 0x0a, 0xb8, 0xc2, 0x53, 0x1f, 0xae, 0x05, 0xf7, 0x45, 0x9e, 0xb9, 0xb4, 0x2d, + 0xe0, 0x10, 0xe3, 0x07, 0x1e, 0xef, 0xd1, 0x39, 0x9b, 0x34, 0xe6, 0x17, 0x5c, + 0xec, 0xc4, 0xe4, 0xf8, 0x42, 0xf9, 0xdd, 0x2a, 0x10, 0xb8, 0xa4, 0x24, 0xf8, + 0x00, 0x53, 0xd0, 0x0e, 0xdc, 0x9b, 0x26, 0x7d, 0xfa, 0x1f, 0x3d, 0xe7, 0xeb, + 0xc5, 0xf1, 0xc3, 0x0d, 0xeb, 0xc6, 0x27, 0x11, 0x4b, 0xd0, 0x13, 0xf3, 0xc5, + 0x05, 0x35, 0x2f, 0x06, 0xcc, 0xb9, 0x2a, 0xc4, 0x24, 0xef, 0x39, 0xf7, 0xa9, + 0xcf, 0xdf, 0xb0, 0xfd, 0xa3, 0x16, 0x23, 0x16, 0x00, 0xe5, 0xbd, 0xc8, 0xed, + 0xdf, 0x84, 0x03, 0xc2, 0x03, 0x27, 0xee, 0xf5, 0xf0, 0xde, 0x2a, 0x16, 0x01, + 0xba, 0xd6, 0xe0, 0x08, 0xf6, 0x10, 0xd0, 0x13, 0xeb, 0x31, 0x17, 0x2b, 0xc1, + 0x20, 0xfa, 0xeb, 0xf1, 0x21, 0x11, 0xe4, 0xc4, 0xf8, 0xfd, 0xf3, 0x46, 0x25, + 0x17, 0xfd, 0xe0, 0xfb, 0x00, 0xd9, 0xdb, 0xa4, 0xdc, 0x02, 0xae, 0xfa, 0xe0, + 0xd8, 0xe2, 0xf0, 0x11, 0xf2, 0x1d, 0x2f, 0x44, 0x0d, 0x28, 0x14, 0xb4, 0x06, + 0xe0, 0xe2, 0x36, 0x41, 0xf0, 0xc9, 0xf5, 0xd5, 0x47, 0x54, 0xda, 0xdd, 0x8a, + 0x04, 0xed, 0xae, 0x08, 0x64, 0xba, 0x60, 0xfc, 0x11, 0xe2, 0x05, 0x01, 0x6b, + 0x07, 0xf5, 0xc9, 0x14, 0xd5, 0xfd, 0x18, 0xf0, 0x2f, 0x06, 0xf9, 0x19, 0xf2, + 0x2c, 0x52, 0xa9, 0x76, 0xe0, 0xd4, 0xae, 0xc2, 0xdb, 0xd4, 0xef, 0xb9, 0xee, + 0x44, 0x1c, 0x13, 0xf2, 0xdc, 0xfb, 0xfc, 0xb2, 0xed, 0xed, 0xf4, 0x0a, 0xbd, + 0xee, 0xfa, 0xdd, 0xf6, 0xec, 0xfb, 0xda, 0xb2, 0xf9, 0x0e, 0xf1, 0x2c, 0x1d, + 0x08, 0xde, 0xcd, 0xf0, 0x0d, 0x0a, 0xfe, 0xbc, 0xdd, 0xfa, 0x30, 0x18, 0xd7, + 0x08, 0xcc, 0xd3, 0xf7, 0x03, 0x09, 0x15, 0x00, 0xfe, 0x0e, 0xd0, 0xed, 0x35, + 0x0c, 0xb6, 0xf3, 0xbb, 0x3d, 0xec, 0xf5, 0x23, 0xfe, 0x26, 0x5c, 0xed, 0x06, + 0xd1, 0xaf, 0xe7, 0x21, 0x37, 0xde, 0xd9, 0x28, 0x7f, 0x0d, 0x17, 0x16, 0x13, + 0xa0, 0xfc, 0xf2, 0xd5, 0x26, 0xbb, 0xdc, 0x19, 0x1d, 0x3f, 0x43, 0xd7, 0xed, + 0xfa, 0xcd, 0x0f, 0x94, 0x22, 0xfd, 0x1c, 0xfd, 0xe2, 0xf6, 0xde, 0x03, 0x04, + 0x20, 0xcd, 0xc7, 0x9d, 0x29, 0x0b, 0xf5, 0xec, 0xfc, 0x48, 0xfb, 0x70, 0xef, + 0xbc, 0xd8, 0x13, 0xc8, 0x48, 0xfc, 0xdf, 0x31, 0xeb, 0x42, 0xcd, 0xee, 0xcf, + 0x28, 0x1f, 0xf7, 0xaa, 0x0f, 0xd6, 0xd9, 0xd0, 0xfa, 0xda, 0xb7, 0xfc, 0x01, + 0xbb, 0x22, 0xe5, 0xe2, 0x1e, 0xf0, 0x00, 0x0d, 0x06, 0xc9, 0xd7, 0xea, 0xef, + 0x20, 0x02, 0xbd, 0x0e, 0xec, 0x19, 0xed, 0x12, 0xff, 0xdb, 0x00, 0x40, 0xed, + 0xec, 0xb7, 0xd5, 0xd5, 0x02, 0xd2, 0xdc, 0x17, 0xcb, 0x0c, 0xed, 0xe7, 0x01, + 0x0c, 0xe0, 0xd5, 0xf0, 0x23, 0xdb, 0xe0, 0xfc, 0x0f, 0xf6, 0x25, 0x21, 0xfd, + 0xf3, 0x45, 0x05, 0x19, 0x10, 0x12, 0xcb, 0xf6, 0x2d, 0x99, 0xdf, 0x36, 0xfd, + 0xb5, 0xee, 0xe3, 0xdf, 0x41, 0xf3, 0x03, 0xea, 0xd0, 0x03, 0xdb, 0x20, 0x1f, + 0x30, 0xf8, 0x3b, 0x15, 0x08, 0xc0, 0xe1, 0xff, 0xf2, 0xf0, 0x0b, 0xf0, 0x19, + 0x71, 0x0d, 0xe8, 0xcb, 0xd2, 0xf1, 0x27, 0xed, 0xeb, 0x12, 0xd6, 0xfd, 0x5a, + 0xf4, 0x37, 0x17, 0xd6, 0xb9, 0x23, 0xdc, 0x02, 0xad, 0x0d, 0xf7, 0xcb, 0xc4, + 0xb8, 0x3e, 0x15, 0xf8, 0xec, 0xfd, 0x06, 0xd1, 0xa0, 0xe0, 0x4c, 0x34, 0xef, + 0xb7, 0xef, 0xdc, 0x27, 0xbd, 0x01, 0xc3, 0x3e, 0xf1, 0xda, 0xd7, 0xa1, 0xde, + 0xfe, 0x39, 0xee, 0xaa, 0x09, 0xdd, 0xf4, 0xc8, 0x00, 0xaa, 0xc7, 0xc3, 0x19, + 0x08, 0x33, 0xf0, 0xe5, 0x24, 0x3b, 0x14, 0xf1, 0xc2, 0xcc, 0xcd, 0xea, 0xe0, + 0x44, 0xdd, 0xca, 0xbd, 0xf3, 0xd1, 0x01, 0xfe, 0x45, 0x26, 0x0c, 0xe3, 0x10, + 0x2d, 0x0e, 0x24, 0xd0, 0xd7, 0x32, 0xcf, 0x25, 0xf3, 0x2b, 0xe1, 0x04, 0xfe, + 0xf7, 0x2b, 0xdb, 0x02, 0x37, 0x11, 0xce, 0xcb, 0x39, 0x12, 0xbc, 0xf1, 0x0d, + 0x1e, 0xf8, 0x04, 0x49, 0x00, 0xd7, 0xe3, 0xd6, 0xf8, 0xe5, 0xf2, 0x38, 0x16, + 0x11, 0xde, 0xd4, 0xee, 0x29, 0xee, 0x14, 0x1a, 0xfc, 0x1f, 0xc2, 0xfc, 0x51, + 0xaf, 0xe2, 0x1f, 0xbf, 0xf5, 0xdf, 0x23, 0xcd, 0xc7, 0x05, 0xce, 0xd3, 0xf8, + 0x0e, 0xfa, 0x56, 0xef, 0xcf, 0x4d, 0xfb, 0xa6, 0xd2, 0x08, 0xe2, 0xe6, 0xde, + 0x2c, 0xe8, 0xc7, 0x27, 0xa8, 0xf1, 0xd2, 0xe6, 0x15, 0x0d, 0xf9, 0xfc, 0xd8, + 0x49, 0x2c, 0x2a, 0xd5, 0x0d, 0xf6, 0x13, 0x1c, 0x14, 0xe3, 0x15, 0x0a, 0x06, + 0xf1, 0x2e, 0x08, 0xfd, 0x2b, 0xf2, 0x81, 0x02, 0xcd, 0x3e, 0xd5, 0xe3, 0xb0, + 0xd3, 0x22, 0x13, 0x09, 0xd5, 0xc8, 0x25, 0xe0, 0x20, 0x21, 0xde, 0xf8, 0xf1, + 0xc1, 0x0b, 0xf8, 0xbd, 0xd7, 0x0b, 0x2e, 0xeb, 0xe5, 0xeb, 0xa5, 0xee, 0x01, + 0x17, 0xe7, 0xe7, 0xbd, 0xcf, 0xdd, 0xff, 0x19, 0xea, 0xec, 0xe7, 0xf3, 0x35, + 0xd0, 0x11, 0xb8, 0xae, 0x19, 0xef, 0x4e, 0xd7, 0xaf, 0xde, 0xf9, 0xa7, 0x14, + 0xf3, 0xed, 0xe8, 0x14, 0xeb, 0xd1, 0xad, 0xce, 0xff, 0xd3, 0xff, 0x2d, 0x56, + 0xbe, 0xee, 0xba, 0xc1, 0xae, 0x44, 0xe9, 0xe5, 0xc0, 0x21, 0xf2, 0xc6, 0xf7, + 0xce, 0x02, 0xfb, 0xa6, 0x47, 0x1f, 0x30, 0x05, 0x03, 0xf6, 0xd9, 0xdf, 0xc0, + 0xdb, 0x11, 0xf3, 0xa8, 0xd9, 0x12, 0xcc, 0x93, 0xe3, 0x37, 0xff, 0xd1, 0xe0, + 0xeb, 0xdf, 0xdb, 0x11, 0xcf, 0xdf, 0x36, 0xe9, 0xb7, 0x00, 0xf7, 0x1b, 0xad, + 0xd6, 0xe6, 0x24, 0x31, 0x19, 0x06, 0x03, 0xcd, 0xe7, 0x01, 0x19, 0xf6, 0xf9, + 0xf9, 0x2b, 0xfc, 0xed, 0x18, 0xb6, 0x5a, 0xe3, 0x0c, 0xd8, 0x07, 0x32, 0x15, + 0x1b, 0xf5, 0xc1, 0xe0, 0x37, 0xcd, 0x25, 0xd2, 0xcb, 0x43, 0x4d, 0xd6, 0x0f, + 0x17, 0xcc, 0xe4, 0x1f, 0xcd, 0x9a, 0x3e, 0x1b, 0x0a, 0x30, 0xed, 0xcd, 0x2a, + 0x44, 0xc7, 0xfa, 0xf9, 0x0f, 0xd0, 0xe3, 0xf5, 0x8b, 0xf6, 0xa7, 0xc4, 0x9f, + 0xdf, 0xe4, 0x12, 0x22, 0xd2, 0x26, 0x12, 0xfa, 0x19, 0xdc, 0xb9, 0x1b, 0x2b, + 0x09, 0x09, 0x57, 0x93, 0x95, 0x02, 0xea, 0xef, 0x16, 0xf3, 0x3e, 0x04, 0xf1, + 0xe3, 0xf2, 0x32, 0xc4, 0x43, 0x29, 0xd1, 0x33, 0xfa, 0xcd, 0x05, 0x4d, 0x24, + 0xe0, 0xd1, 0x1e, 0x28, 0x14, 0x50, 0xfb, 0x1e, 0x0e, 0xe7, 0x09, 0xc4, 0x0c, + 0xed, 0x08, 0x09, 0xbc, 0xf7, 0xe4, 0x00, 0xf4, 0xeb, 0x0e, 0x08, 0xf2, 0xfd, + 0x05, 0x07, 0x19, 0xba, 0x3e, 0xcc, 0xcb, 0x40, 0xea, 0x01, 0xf4, 0xb8, 0xee, + 0x21, 0xa5, 0xf6, 0x25, 0xf8, 0xe0, 0xeb, 0xe9, 0x34, 0xf3, 0x0f, 0xb2, 0x1e, + 0xca, 0xf1, 0xb1, 0xd4, 0xed, 0x04, 0x1c, 0xff, 0xe0, 0x2f, 0xa0, 0xe4, 0x03, + 0xa0, 0xf3, 0xd8, 0xf3, 0xfe, 0x23, 0xcf, 0xe7, 0x1a, 0x07, 0x0a, 0xdb, 0x81, + 0x75, 0x3f, 0xf1, 0x3f, 0x00, 0x0d, 0x0e, 0xaf, 0xf7, 0x2e, 0xfc, 0x01, 0x01, + 0xe5, 0x30, 0x21, 0xfd, 0xd3, 0xd8, 0xf0, 0xfc, 0x27, 0x00, 0x04, 0xfc, 0x3b, + 0xef, 0x10, 0xe8, 0x16, 0xfd, 0x15, 0xef, 0x07, 0x03, 0x06, 0x18, 0xe2, 0xd4, + 0xf1, 0x2d, 0x0f, 0xe1, 0xd6, 0xc2, 0xeb, 0xf7, 0xae, 0xcd, 0xfa, 0xf1, 0x11, + 0xed, 0x00, 0xf3, 0xd2, 0xe0, 0xf8, 0xbe, 0x00, 0x15, 0x23, 0x03, 0x1d, 0xbb, + 0xeb, 0x03, 0x05, 0x12, 0x26, 0x0e, 0xdc, 0xef, 0xce, 0xe4, 0xe3, 0x06, 0xef, + 0x35, 0x3c, 0x11, 0xeb, 0xfc, 0x0c, 0xf9, 0xde, 0xec, 0x3f, 0xf2, 0x1a, 0xc1, + 0xed, 0x06, 0x2d, 0xef, 0xc8, 0xe2, 0xf3, 0xb4, 0xf6, 0x23, 0x03, 0xdd, 0xd0, + 0x28, 0x10, 0xca, 0xed, 0xe9, 0x1d, 0x0a, 0xed, 0xd9, 0xfe, 0xd7, 0xe6, 0x21, + 0x02, 0xca, 0xda, 0xe2, 0xed, 0x07, 0x3a, 0xf5, 0xd3, 0xe7, 0xd9, 0xed, 0xcf, + 0xca, 0x0b, 0x07, 0xee, 0xfe, 0xe6, 0xf2, 0xff, 0xfb, 0x08, 0x0b, 0xe9, 0xf2, + 0xf5, 0xda, 0x02, 0xce, 0x33, 0xf4, 0xd1, 0xd7, 0xe1, 0x1b, 0x43, 0xfb, 0xfd, + 0xb3, 0xec, 0x19, 0xe5, 0xe1, 0xfc, 0x02, 0xf4, 0x1a, 0xbb, 0x28, 0x06, 0xcc, + 0x41, 0x22, 0xd2, 0xf5, 0xf4, 0x0a, 0x02, 0x7f, 0x16, 0xb8, 0xbd, 0xe6, 0xea, + 0xf0, 0x0e, 0xf5, 0xf8, 0x01, 0xc0, 0x15, 0xd1, 0xfb, 0xd3, 0xed, 0x13, 0xce, + 0xd2, 0xe8, 0x07, 0xf6, 0x00, 0x2c, 0xe3, 0x09, 0xf6, 0xf4, 0x09, 0x11, 0x1e, + 0x0d, 0x09, 0x35, 0xf5, 0x18, 0x13, 0xd2, 0xc0, 0xd4, 0x0e, 0xf1, 0x00, 0x17, + 0x2d, 0xce, 0xf2, 0x37, 0x33, 0xfe, 0x0f, 0x99, 0xe5, 0xe9, 0x10, 0xd6, 0x05, + 0xf9, 0xd5, 0xd8, 0xc6, 0xce, 0x07, 0xd1, 0xbc, 0x15, 0xf9, 0x0c, 0x1c, 0x2a, + 0xf1, 0x3d, 0xb9, 0x12, 0x76, 0xba, 0xf4, 0xe8, 0x27, 0x19, 0x1d, 0xf4, 0x15, + 0x37, 0x10, 0x06, 0xf3, 0xc3, 0x06, 0xfb, 0x39, 0xdb, 0xee, 0x11, 0xeb, 0x18, + 0xf9, 0xe4, 0xe7, 0x55, 0xec, 0xff, 0xd4, 0x14, 0xe4, 0xd3, 0xfa, 0xea, 0xdf, + 0x0d, 0xbd, 0xe4, 0xf2, 0x3b, 0x00, 0x06, 0xc7, 0x33, 0xbc, 0xde, 0xf8, 0xe6, + 0x01, 0xe6, 0xd7, 0xd7, 0xd8, 0x3c, 0xd7, 0xf8, 0xd0, 0xd5, 0xe7, 0xf3, 0xfe, + 0x16, 0xfc, 0xfa, 0xf4, 0x02, 0xd3, 0xfd, 0x37, 0x04, 0xc2, 0x0d, 0xde, 0xed, + 0x11, 0x24, 0x0d, 0x1c, 0xf7, 0x01, 0xfd, 0xed, 0xda, 0xd6, 0x3a, 0xb1, 0xda, + 0x04, 0xf9, 0xeb, 0xd8, 0xf0, 0xe5, 0x00, 0xe4, 0x0a, 0x3b, 0x05, 0xdc, 0xc9, + 0x40, 0xae, 0xdf, 0x12, 0x04, 0x52, 0xf8, 0x3c, 0x29, 0xfe, 0xe3, 0x28, 0xff, + 0x03, 0x10, 0xe4, 0x0e, 0x14, 0xec, 0x0c, 0xd0, 0xc5, 0x09, 0xfe, 0xb9, 0xf8, + 0xf6, 0x19, 0xdf, 0x29, 0x0d, 0xf4, 0x31, 0xf0, 0xfa, 0x32, 0x0e, 0xd0, 0xd4, + 0xf6, 0xfb, 0xf3, 0x2a, 0x08, 0xfe, 0xc4, 0x0e, 0x32, 0xc7, 0xd4, 0xf3, 0x0a, + 0xdc, 0xf6, 0xec, 0x10, 0x7f, 0xfa, 0x11, 0xd2, 0xe0, 0x3f, 0x1b, 0xb4, 0x2b, + 0x01, 0xd5, 0xeb, 0xe1, 0xef, 0x0c, 0xc1, 0xd0, 0xd3, 0xfe, 0xe8, 0xee, 0x29, + 0x11, 0x05, 0xe0, 0x17, 0xc7, 0xf0, 0xe3, 0xe9, 0xd6, 0x05, 0xeb, 0xeb, 0xa2, + 0xdc, 0xfd, 0x04, 0x18, 0x03, 0xe8, 0xd1, 0x3a, 0xd0, 0x08, 0xea, 0x11, 0x1b, + 0x1e, 0x1c, 0x23, 0xf2, 0xf5, 0x00, 0xf2, 0x1d, 0xf0, 0x01, 0xf5, 0xf0, 0xe2, + 0xfe, 0xfc, 0xf7, 0x0b, 0x03, 0xf3, 0x28, 0x04, 0xfc, 0xb4, 0xf6, 0xf5, 0x1f, + 0xe3, 0xd9, 0x23, 0x11, 0xb0, 0xe3, 0xe8, 0xe0, 0xe3, 0x0e, 0x23, 0xf0, 0x07, + 0x08, 0xc8, 0x0b, 0x1c, 0xe1, 0xd8, 0x0f, 0x1d, 0xf1, 0xf0, 0x24, 0xdb, 0x4d, + 0x06, 0x1e, 0x1e, 0xd5, 0x0d, 0x01, 0x0b, 0x03, 0xff, 0xc7, 0xf9, 0x25, 0x04, + 0xd5, 0x20, 0x0c, 0x0c, 0xee, 0x26, 0xfc, 0x23, 0x11, 0xfc, 0xd3, 0x06, 0x3c, + 0xc4, 0xaf, 0xed, 0xd5, 0xfc, 0xe7, 0x2e, 0xea, 0xf1, 0xf9, 0xfb, 0x03, 0x30, + 0xfb, 0xe4, 0xf7, 0xe3, 0x0e, 0xfd, 0xe0, 0xf9, 0x07, 0xf7, 0xcc, 0xfc, 0xe3, + 0xe6, 0xd4, 0xe8, 0x1c, 0xff, 0xb3, 0x28, 0xf5, 0xe6, 0xfc, 0x08, 0xd8, 0xe2, + 0x0c, 0x0c, 0x4c, 0x10, 0x19, 0x0a, 0xc7, 0x12, 0x14, 0x04, 0x22, 0x0d, 0xdb, + 0xe0, 0xe5, 0x26, 0xe5, 0x0e, 0x1b, 0xed, 0x16, 0xc3, 0xd1, 0x7f, 0x07, 0xc1, + 0x02, 0x0c, 0x13, 0x2d, 0x11, 0xcc, 0x15, 0xf3, 0x02, 0xed, 0xc4, 0x10, 0xce, + 0xc8, 0x1a, 0xeb, 0xf7, 0x19, 0x25, 0xe5, 0x12, 0x20, 0xfe, 0x22, 0xfa, 0xb5, + 0xd6, 0xed, 0x1b, 0x0b, 0xd7, 0xfb, 0xb1, 0xdc, 0xff, 0xef, 0x40, 0x2f, 0xf9, + 0xf0, 0xd1, 0xd7, 0xe6, 0xe9, 0xf6, 0xe1, 0xeb, 0xe2, 0xea, 0xf0, 0xe0, 0xce, + 0xbf, 0x0d, 0xdd, 0xd2, 0x07, 0x09, 0xd0, 0xa1, 0x18, 0x11, 0xdf, 0x0f, 0xcc, + 0x2f, 0xe1, 0x3e, 0xf2, 0xfe, 0xbd, 0x05, 0x00, 0xbc, 0xba, 0xb9, 0xf4, 0x03, + 0xd4, 0xc6, 0x01, 0xfa, 0xfb, 0x27, 0xfd, 0xef, 0x25, 0xe2, 0x03, 0xf7, 0x30, + 0x06, 0xc4, 0x94, 0xf7, 0xe2, 0x0c, 0xeb, 0xd9, 0xf5, 0x14, 0xc6, 0x0b, 0xff, + 0x0b, 0x2b, 0xf3, 0x11, 0x24, 0xe5, 0xd8, 0xf6, 0x04, 0x2d, 0x19, 0x1a, 0x0e, + 0x18, 0xcd, 0xf8, 0x11, 0x0f, 0x08, 0x2e, 0xdb, 0xe1, 0x3d, 0x05, 0xbd, 0xde, + 0x13, 0xf4, 0xd4, 0x0e, 0xd6, 0xe1, 0xcd, 0xfd, 0xde, 0x3a, 0xd0, 0x34, 0xf2, + 0xe1, 0xd8, 0x34, 0xc4, 0xdd, 0x11, 0xd2, 0xff, 0xda, 0xf6, 0xec, 0xd1, 0xbd, + 0xe4, 0xdd, 0xfc, 0x22, 0x13, 0x1f, 0x38, 0xd0, 0x24, 0x0f, 0xfe, 0x1a, 0xdf, + 0xde, 0x2b, 0x35, 0xe8, 0x34, 0x1e, 0x13, 0xf2, 0xfb, 0xac, 0xf1, 0xe6, 0x3d, + 0xe7, 0x20, 0xf6, 0x14, 0x0f, 0xe8, 0xfe, 0x26, 0x21, 0xf2, 0xc9, 0x20, 0xc4, + 0x2f, 0xc4, 0x33, 0xc9, 0xed, 0xfa, 0xcf, 0x10, 0xe1, 0xd0, 0xa9, 0xcd, 0xe1, + 0xfb, 0xf3, 0xfc, 0x4e, 0xcc, 0x2f, 0x19, 0x10, 0x84, 0x18, 0xdf, 0x44, 0x19, + 0xf7, 0xb5, 0xc7, 0xdb, 0xca, 0xef, 0x0d, 0x08, 0xf7, 0x81, 0xb1, 0xef, 0xd4, + 0x3c, 0xab, 0xc6, 0xbc, 0xef, 0xfd, 0x0c, 0x1e, 0xd6, 0x0a, 0xfa, 0x4f, 0x09, + 0xec, 0x39, 0x2c, 0x25, 0xe0, 0xca, 0xf2, 0xff, 0xd1, 0xf8, 0xf7, 0x2e, 0xfd, + 0x13, 0x14, 0x09, 0xef, 0x04, 0x01, 0xa9, 0x39, 0x1b, 0xd1, 0x14, 0xdb, 0xc2, + 0x08, 0x01, 0x40, 0xd3, 0xff, 0x2b, 0x09, 0xb2, 0xeb, 0x03, 0x01, 0x0c, 0x2b, + 0x25, 0xf3, 0xe1, 0xe5, 0xe2, 0x71, 0xf0, 0xfc, 0x0d, 0x04, 0xe7, 0xaf, 0x11, + 0xb7, 0x16, 0xf0, 0xf1, 0x40, 0xaf, 0xe5, 0xf0, 0x0d, 0xf7, 0xd3, 0xff, 0x2b, + 0xa6, 0x2c, 0xc8, 0x1b, 0xff, 0xb5, 0x03, 0xe1, 0x10, 0xd2, 0xf8, 0x00, 0x15, + 0xe0, 0xfd, 0xed, 0x5a, 0xeb, 0x16, 0xed, 0x0b, 0xc2, 0xf6, 0x03, 0x0a, 0xf1, + 0xd5, 0x01, 0x24, 0x0e, 0xbe, 0xfa, 0xf1, 0x01, 0x02, 0x28, 0x19, 0xee, 0x1d, + 0x15, 0x0e, 0xf2, 0x12, 0xa8, 0x01, 0xee, 0xff, 0x34, 0x11, 0xf0, 0x2f, 0x27, + 0xee, 0xf6, 0xeb, 0xfb, 0x09, 0xcb, 0x21, 0x1c, 0x2b, 0x29, 0x10, 0x1e, 0x06, + 0x07, 0x20, 0x3c, 0xfa, 0xd9, 0xb6, 0x04, 0x42, 0x30, 0xdd, 0x2d, 0xe8, 0xf6, + 0xcd, 0xfb, 0x0a, 0x1d, 0xf2, 0x5f, 0xe6, 0x05, 0x2c, 0x0d, 0xdc, 0x28, 0xec, + 0xe6, 0x08, 0xf9, 0x28, 0xca, 0x1b, 0x0e, 0xdd, 0x12, 0xc1, 0xdf, 0x06, 0xe8, + 0xeb, 0x3e, 0x25, 0xea, 0xf7, 0xbd, 0xf5, 0xdb, 0xdf, 0xdc, 0x4a, 0x27, 0xff, + 0xff, 0x08, 0x19, 0x90, 0x1c, 0xe5, 0x3d, 0xe6, 0xf8, 0xf8, 0xcc, 0x0e, 0xd7, + 0xf3, 0x1e, 0xd7, 0xae, 0xd1, 0x14, 0xd2, 0xfa, 0xa2, 0xe6, 0x25, 0x41, 0x39, + 0xff, 0x17, 0xef, 0x0e, 0x19, 0xac, 0x11, 0xd1, 0x08, 0x08, 0xc5, 0xf3, 0x27, + 0xbb, 0xfd, 0xe9, 0xd5, 0x8e, 0xdf, 0x15, 0xcf, 0xe0, 0xd9, 0xfd, 0x10, 0xe6, + 0x28, 0xee, 0x1a, 0xe9, 0xed, 0x81, 0xca, 0x0d, 0xba, 0x0a, 0xc4, 0xd5, 0xe4, + 0xe9, 0xd0, 0xdc, 0xf7, 0xa9, 0xe7, 0xbc, 0x40, 0x0b, 0x09, 0xe4, 0xf6, 0xb2, + 0x12, 0xf0, 0x69, 0x44, 0x06, 0xef, 0x11, 0x16, 0x54, 0x2f, 0xe8, 0xb4, 0x9d, + 0x25, 0xdb, 0x0e, 0x0f, 0xee, 0x17, 0x18, 0x14, 0xbc, 0xfc, 0x0b, 0x27, 0xd5, + 0xef, 0xbb, 0x19, 0xd9, 0x01, 0x07, 0xf4, 0x13, 0x45, 0xb3, 0x0d, 0x0b, 0xb2, + 0xbb, 0x25, 0x0a, 0x25, 0x00, 0xe2, 0x13, 0xfb, 0xff, 0xb8, 0xe4, 0xf5, 0xdd, + 0xbb, 0xff, 0x3a, 0xcb, 0xd6, 0xf5, 0x09, 0x41, 0x10, 0xd5, 0xef, 0xca, 0xf2, + 0x31, 0x90, 0x0e, 0x28, 0xed, 0x00, 0xd8, 0x3f, 0xc5, 0xe5, 0xf8, 0x42, 0x3a, + 0x30, 0x2a, 0xee, 0xff, 0xd0, 0x2f, 0x0d, 0xb1, 0xe2, 0x07, 0xe3, 0x3a, 0xdb, + 0xa2, 0xe7, 0x3d, 0xf5, 0xcf, 0xf7, 0xec, 0x08, 0x3d, 0x29, 0x0d, 0x04, 0xe8, + 0x8a, 0xe8, 0xd4, 0x40, 0xdc, 0xf6, 0xeb, 0xc9, 0xd0, 0xdf, 0xeb, 0xec, 0xf9, + 0xff, 0xcb, 0x43, 0xef, 0xe3, 0x25, 0x03, 0x19, 0x01, 0x01, 0xd3, 0x21, 0x36, + 0x1f, 0x2d, 0x08, 0x2d, 0xce, 0xff, 0xf3, 0xe3, 0x08, 0xeb, 0xf1, 0x02, 0x35, + 0x19, 0x62, 0x26, 0xd6, 0xd3, 0x18, 0x37, 0xd9, 0xc5, 0x36, 0x32, 0xf1, 0xb8, + 0x59, 0xe3, 0x48, 0xf7, 0xdf, 0xd6, 0xea, 0xd4, 0x30, 0xfb, 0x33, 0x5f, 0xbc, + 0xc1, 0xf6, 0xe5, 0xb5, 0x31, 0x02, 0x1f, 0x24, 0xee, 0xe8, 0xe5, 0x6a, 0x9b, + 0x02, 0xdd, 0x2f, 0xf5, 0x21, 0x2d, 0x1e, 0xc9, 0x2c, 0x15, 0x08, 0xc5, 0xbe, + 0xd5, 0x2d, 0xfc, 0xe3, 0x8b, 0x13, 0xd0, 0xee, 0x0d, 0x1e, 0x66, 0xec, 0x10, + 0xe8, 0x1e, 0x2e, 0xeb, 0xdd, 0x45, 0xca, 0xc1, 0xfe, 0xcc, 0xfe, 0xb7, 0xbd, + 0xc9, 0xc3, 0x1f, 0xc2, 0xb1, 0x14, 0xae, 0x31, 0xe1, 0xd1, 0x30, 0x07, 0xf3, + 0xa8, 0x3e, 0x93, 0x45, 0x2c, 0xed, 0x8f, 0xd1, 0xb8, 0xd0, 0x1a, 0x27, 0xc4, + 0xa3, 0xdd, 0x0d, 0x7f, 0x2b, 0x07, 0xde, 0xf9, 0x3b, 0x2f, 0xc2, 0xfd, 0xa0, + 0xcb, 0xbb, 0x3a, 0xf7, 0xe7, 0xe0, 0x03, 0x04, 0x06, 0xbc, 0xbc, 0xbf, 0x11, + 0x05, 0xda, 0xd6, 0x4e, 0xb7, 0x35, 0xd2, 0x68, 0x1b, 0x39, 0xe1, 0xd0, 0x0d, + 0x11, 0x26, 0xcf, 0xeb, 0xef, 0xc7, 0xfd, 0x19, 0xdf, 0xca, 0x43, 0xd1, 0xa5, + 0x2c, 0x55, 0x0b, 0x17, 0x31, 0xd7, 0xc9, 0xe7, 0xf3, 0xe2, 0xfe, 0xc4, 0xdd, + 0x5c, 0xd5, 0xfe, 0xc6, 0xce, 0x5a, 0x06, 0xbc, 0xa7, 0x55, 0xf4, 0xbf, 0xf0, + 0x44, 0x29, 0xe6, 0x2c, 0xd2, 0xa4, 0x27, 0xbb, 0x24, 0xc4, 0xd1, 0xd9, 0xaa, + 0xb7, 0xbc, 0xaf, 0xe1, 0x30, 0xa9, 0x9b, 0x13, 0xf1, 0x54, 0x45, 0x21, 0xe8, + 0x0d, 0xf0, 0xf3, 0xc5, 0x56, 0x01, 0xf4, 0xee, 0xfa, 0x11, 0x0d, 0x1b, 0xb8, + 0xe2, 0xc1, 0xf7, 0xc7, 0xb0, 0xd0, 0x23, 0xfa, 0xec, 0xe2, 0xfb, 0x23, 0xd3, + 0x02, 0x44, 0x2f, 0x4b, 0x95, 0x0c, 0x03, 0x41, 0xed, 0x35, 0x14, 0xfb, 0x45, + 0xd4, 0xf0, 0xf0, 0xf2, 0x13, 0xc5, 0x25, 0xb4, 0xdb, 0x1b, 0xc2, 0xda, 0xf0, + 0x18, 0xd7, 0xdc, 0xcb, 0xac, 0xe2, 0xc8, 0xfe, 0xff, 0x14, 0xee, 0xb4, 0x12, + 0xf0, 0xd8, 0xd3, 0xc6, 0xd2, 0xbd, 0x9f, 0xbb, 0x6b, 0xe9, 0x39, 0xbf, 0x14, + 0xe5, 0xed, 0x0d, 0xcd, 0xfb, 0xee, 0x57, 0x94, 0xbf, 0x0f, 0x0a, 0xcf, 0x00, + 0xf1, 0xdb, 0x0e, 0x2b, 0x05, 0xc0, 0xeb, 0x07, 0xe6, 0x5e, 0x56, 0x11, 0xd9, + 0x29, 0x1a, 0x17, 0x0f, 0x3a, 0x04, 0xb4, 0x22, 0x06, 0xf9, 0x0c, 0xe8, 0x33, + 0xe1, 0x8c, 0x30, 0xf4, 0xcf, 0x50, 0x32, 0xa6, 0xb1, 0x2c, 0xb1, 0x0a, 0xc0, + 0x2f, 0xe4, 0x08, 0xbf, 0xea, 0xff, 0xda, 0xf5, 0x81, 0xc7, 0x0f, 0xeb, 0xe2, + 0x53, 0x56, 0xd8, 0xb2, 0xe0, 0xdf, 0x2d, 0x20, 0xf2, 0xec, 0xf0, 0x22, 0xe6, + 0x3d, 0x0d, 0x2c, 0x34, 0x05, 0x0c, 0x1b, 0xe7, 0x35, 0x25, 0x41, 0x3e, 0xeb, + 0x08, 0x21, 0xc5, 0x22, 0xd8, 0x1a, 0xc0, 0xce, 0x9e, 0x05, 0xc4, 0xf4, 0xa5, + 0x23, 0x40, 0x0f, 0xce, 0xc4, 0xf2, 0x49, 0x01, 0xd8, 0x07, 0x27, 0x36, 0xcf, + 0x15, 0xf7, 0x02, 0xbf, 0x96, 0xe5, 0xd7, 0x17, 0x59, 0x49, 0x1f, 0x97, 0xe7, + 0xdb, 0xd3, 0xea, 0xdb, 0xf7, 0x0a, 0x09, 0x0e, 0xa9, 0xc6, 0x0c, 0xb9, 0xcc, + 0x31, 0xd1, 0xd5, 0xc9, 0x01, 0x6d, 0x2d, 0xc6, 0xed, 0xc3, 0xa5, 0xca, 0xdc, + 0xdd, 0x97, 0xc1, 0xf8, 0x28, 0xc5, 0x06, 0x1b, 0x3b, 0xdd, 0xc0, 0xf3, 0xc4, + 0x2e, 0xf7, 0xf1, 0xeb, 0x20, 0xe8, 0xfe, 0xb6, 0x6b, 0xcf, 0x2c, 0x03, 0xb4, + 0xdb, 0x54, 0x05, 0xe3, 0xae, 0x1b, 0x32, 0xc8, 0x0d, 0xa1, 0x15, 0xdf, 0x32, + 0x29, 0x17, 0xfc, 0xf5, 0x0b, 0x18, 0x2a, 0x1f, 0x13, 0xbe, 0x09, 0xf5, 0xb8, + 0xac, 0xf2, 0x55, 0xd9, 0xbd, 0xca, 0x27, 0x4d, 0xdd, 0xc3, 0x1c, 0xdb, 0x09, + 0xe9, 0xd4, 0x0a, 0xae, 0xf3, 0x61, 0x19, 0xb7, 0xff, 0x00, 0xec, 0xfe, 0xf7, + 0xbe, 0xf8, 0x61, 0xda, 0xf8, 0x27, 0x2c, 0xd4, 0xfc, 0xf5, 0x42, 0xde, 0xdc, + 0x47, 0x65, 0x40, 0xbc, 0xf6, 0xdb, 0xf3, 0xc6, 0xa4, 0x00, 0xea, 0x21, 0x00, + 0x15, 0x48, 0x09, 0xbf, 0x2f, 0xec, 0xd9, 0xb9, 0xde, 0x9e, 0x28, 0xe1, 0xec, + 0x5d, 0xea, 0x27, 0x35, 0xc3, 0x46, 0xfd, 0xef, 0x1d, 0xf2, 0x9c, 0xd4, 0xf0, + 0x04, 0xe1, 0xcf, 0xb5, 0xd8, 0xf9, 0xef, 0xed, 0xf8, 0x21, 0xdc, 0x17, 0xd8, + 0x20, 0xf0, 0xeb, 0xbc, 0x06, 0x0d, 0xe6, 0xe6, 0xc2, 0x0c, 0x03, 0xc8, 0xf6, + 0xcb, 0xc3, 0xf8, 0xfd, 0x14, 0x17, 0xf3, 0x11, 0x13, 0xfe, 0xea, 0xf8, 0xd9, + 0xcd, 0xfa, 0x22, 0xf6, 0x03, 0x25, 0x02, 0x14, 0x20, 0x02, 0xfe, 0xad, 0xe2, + 0x3c, 0x07, 0xfb, 0x40, 0x13, 0xef, 0xea, 0x08, 0x1a, 0x1f, 0x36, 0xe6, 0xe0, + 0xde, 0xf9, 0xfa, 0xcd, 0x04, 0xce, 0x1c, 0xe3, 0xf3, 0x1d, 0x31, 0xdf, 0x15, + 0xe7, 0xfd, 0xcd, 0x03, 0xf2, 0xfb, 0xa8, 0xf4, 0x0b, 0x26, 0xff, 0x23, 0xb5, + 0x9d, 0xee, 0xf6, 0xeb, 0x23, 0xcd, 0xe8, 0xeb, 0xfe, 0x1b, 0xde, 0x00, 0xe0, + 0x28, 0x00, 0xca, 0x22, 0xdf, 0xfa, 0x05, 0xe5, 0x3e, 0xf9, 0xfc, 0x2b, 0xe4, + 0xf5, 0xee, 0xed, 0xdf, 0xb5, 0xd2, 0x00, 0xe0, 0xd6, 0x03, 0xfb, 0xe0, 0xe1, + 0xf7, 0xc2, 0xc2, 0x1b, 0xcd, 0xcd, 0xb8, 0x07, 0xe6, 0x00, 0xf1, 0x02, 0xd2, + 0xea, 0x3b, 0x04, 0x08, 0xba, 0xe2, 0xc1, 0xb9, 0xc0, 0xf8, 0x19, 0x65, 0x2c, + 0xd9, 0xf2, 0xfe, 0xd2, 0xdd, 0xd4, 0x17, 0x2e, 0x2c, 0x0a, 0x59, 0x4c, 0x14, + 0xf3, 0xd7, 0x40, 0xc7, 0x36, 0x3c, 0x01, 0xdd, 0x24, 0xf6, 0x1d, 0xdd, 0x31, + 0xf9, 0xdb, 0xd7, 0xfa, 0xd9, 0xf9, 0xf7, 0xbb, 0x25, 0x1a, 0xea, 0x21, 0xe4, + 0xf3, 0xfb, 0xef, 0x81, 0xf6, 0x55, 0xd7, 0xf4, 0x4d, 0xf2, 0x09, 0x1e, 0x36, + 0xfa, 0xec, 0xdc, 0xdd, 0xe6, 0xe1, 0x11, 0xca, 0x18, 0xe0, 0xff, 0xf0, 0xd0, + 0xe1, 0x12, 0xaa, 0xba, 0x22, 0x34, 0x0c, 0x05, 0x1a, 0x00, 0xd2, 0xec, 0x2b, + 0x37, 0xe8, 0xdd, 0x0b, 0x1f, 0xb9, 0xdd, 0xd3, 0x08, 0x22, 0xd7, 0x4e, 0xeb, + 0x14, 0x26, 0x0e, 0xfc, 0xdc, 0xe7, 0x2b, 0xf2, 0x3c, 0x12, 0xdd, 0xf9, 0xe9, + 0xf7, 0xdb, 0xff, 0xee, 0xda, 0xe5, 0x15, 0xe7, 0xe4, 0xdf, 0x0f, 0x0a, 0x1b, + 0xf2, 0x04, 0x04, 0xfa, 0x0d, 0xeb, 0xe7, 0xd2, 0x31, 0xfa, 0xf1, 0xca, 0x15, + 0xf7, 0xf8, 0xf2, 0xf4, 0x19, 0x10, 0x38, 0xef, 0x14, 0xf4, 0xe6, 0x10, 0x04, + 0xeb, 0x10, 0xdc, 0xfb, 0x07, 0xf1, 0x0f, 0xd7, 0xf4, 0xeb, 0xfd, 0x02, 0x7f, + 0x26, 0xe8, 0xf3, 0xcf, 0x21, 0x0d, 0xf9, 0xeb, 0xe4, 0xd5, 0x14, 0xda, 0xe0, + 0xe9, 0xf8, 0xcf, 0x04, 0xd1, 0xc8, 0xe4, 0xe5, 0x29, 0x5c, 0xcc, 0x19, 0xf9, + 0xe0, 0x0d, 0x09, 0x04, 0x2e, 0x0b, 0x04, 0xfd, 0xda, 0x09, 0xf0, 0xcd, 0x1f, + 0xd7, 0xdb, 0x05, 0x1d, 0xe0, 0x0f, 0x02, 0x04, 0xf7, 0xee, 0xde, 0xd5, 0x0f, + 0x05, 0xeb, 0xe1, 0xed, 0x13, 0xdc, 0x10, 0xe9, 0x14, 0xd1, 0xf8, 0xfe, 0xed, + 0xf3, 0xec, 0xfb, 0xfd, 0xd6, 0x19, 0x21, 0x04, 0xfc, 0xe2, 0xf2, 0xeb, 0xd0, + 0xf9, 0x23, 0x02, 0x38, 0x05, 0x0d, 0xfe, 0xf6, 0xde, 0xca, 0xc3, 0x28, 0x0a, + 0xfa, 0xed, 0x07, 0xdb, 0xf3, 0x12, 0x30, 0x2a, 0xf9, 0xe1, 0xe6, 0x09, 0xd5, + 0xff, 0x30, 0x09, 0x3e, 0xfa, 0xfe, 0x2d, 0xf0, 0xf8, 0xfd, 0xda, 0x27, 0xfd, + 0xf1, 0xc7, 0xff, 0xd6, 0xe9, 0x02, 0xf2, 0xfc, 0xfa, 0x08, 0xde, 0xd4, 0x00, + 0xe4, 0xc7, 0x2d, 0xf4, 0x16, 0x05, 0x01, 0xf9, 0xd4, 0x01, 0x07, 0xcd, 0xf0, + 0x32, 0xde, 0xc8, 0xfe, 0x08, 0x16, 0xe2, 0x1e, 0xfd, 0xf6, 0xeb, 0x00, 0x13, + 0x31, 0xfa, 0x08, 0x14, 0xb7, 0x13, 0xff, 0x1b, 0xcf, 0x16, 0x0d, 0xe6, 0x08, + 0xf7, 0xf6, 0xc8, 0x24, 0xdf, 0xf0, 0x0a, 0x01, 0xfc, 0xf3, 0x04, 0xdc, 0xc0, + 0xc3, 0xe8, 0x14, 0x23, 0xd2, 0xe4, 0xe7, 0x08, 0xc6, 0xfe, 0xe8, 0x0d, 0xea, + 0x07, 0x03, 0xdb, 0x03, 0xf4, 0xf9, 0xb8, 0x1d, 0xea, 0x35, 0xc7, 0x41, 0x27, + 0xcf, 0xea, 0xf3, 0xd4, 0xd5, 0x22, 0xd4, 0xe5, 0x07, 0xb6, 0xe7, 0xe6, 0xe9, + 0xd7, 0x04, 0xbd, 0xf7, 0xed, 0xf9, 0xcf, 0x00, 0xc9, 0x18, 0x3b, 0xf5, 0xd5, + 0x43, 0xea, 0x37, 0x02, 0xe4, 0xf8, 0xd2, 0x17, 0x07, 0xfe, 0x0d, 0xe4, 0x0e, + 0xa1, 0xff, 0x3b, 0xf9, 0xf3, 0xdd, 0x2f, 0x1e, 0x7f, 0x00, 0xdd, 0xf1, 0xb5, + 0x17, 0xd3, 0x5b, 0xdd, 0xc9, 0xe5, 0x33, 0x0b, 0xe2, 0x31, 0xa1, 0x09, 0xf5, + 0xb7, 0xf7, 0xd5, 0x9f, 0x4a, 0x3e, 0xd0, 0xd4, 0xe6, 0xb9, 0xef, 0xed, 0xd0, + 0x61, 0xf2, 0x34, 0x2f, 0x0a, 0xff, 0x19, 0xf1, 0x36, 0xc0, 0xf0, 0xce, 0x6c, + 0x08, 0xb9, 0xce, 0xd8, 0xbb, 0x63, 0xe2, 0x20, 0x3f, 0x24, 0xcb, 0xdb, 0xd2, + 0xf9, 0x0a, 0xea, 0xdf, 0x2d, 0xca, 0x13, 0x14, 0xb0, 0xea, 0xff, 0x22, 0xcf, + 0x06, 0x07, 0xf7, 0xef, 0x32, 0xf3, 0x0b, 0x0d, 0xa1, 0x98, 0xfb, 0xd9, 0x29, + 0xec, 0x40, 0x01, 0x20, 0xc8, 0xfe, 0xf1, 0x2b, 0x07, 0xff, 0x06, 0xe6, 0x05, + 0xce, 0x1d, 0x56, 0xe1, 0xe1, 0x00, 0x13, 0xe0, 0xfd, 0x0e, 0xff, 0xfc, 0x51, + 0x0b, 0x25, 0x01, 0xef, 0x39, 0x34, 0x38, 0xe6, 0xf3, 0xdc, 0xf3, 0x42, 0xe3, + 0x13, 0x04, 0x07, 0xef, 0xd1, 0xea, 0xfe, 0xe1, 0xd0, 0xd8, 0xf4, 0x2f, 0xee, + 0xef, 0xeb, 0x14, 0xfe, 0xf2, 0x0d, 0xb1, 0x17, 0x00, 0x24, 0xad, 0xb8, 0xb8, + 0x0f, 0xd9, 0x09, 0xf6, 0xbf, 0x19, 0xf4, 0x0e, 0xf4, 0x2a, 0x1a, 0xfe, 0x22, + 0xf5, 0xfa, 0x3b, 0x22, 0xb9, 0x67, 0x10, 0x10, 0xc4, 0x0b, 0x00, 0xcf, 0x45, + 0xdd, 0xbc, 0x4c, 0xf2, 0x43, 0xb9, 0x07, 0xe2, 0xc9, 0xf9, 0x0b, 0xf0, 0xee, + 0xd4, 0xe0, 0xe7, 0x2b, 0xe2, 0xc6, 0xd8, 0xeb, 0xc7, 0x1d, 0xd9, 0xf9, 0x00, + 0x15, 0xfe, 0xdf, 0x06, 0xd8, 0x04, 0x05, 0xeb, 0x1c, 0xdb, 0xcf, 0x35, 0xe2, + 0x0a, 0xf4, 0xf7, 0x09, 0x13, 0xfd, 0xfe, 0xe0, 0xe9, 0xf8, 0xfd, 0xc0, 0xdd, + 0xf4, 0x1a, 0xff, 0xf1, 0xcf, 0x15, 0x34, 0xf5, 0xea, 0x14, 0x11, 0x04, 0xf9, + 0xeb, 0x0d, 0xe2, 0xc8, 0x0c, 0x09, 0x04, 0xc5, 0xe4, 0xfd, 0x0b, 0x15, 0x2f, + 0xf5, 0x11, 0x18, 0x08, 0x7f, 0x01, 0x05, 0xfc, 0xf9, 0xf9, 0x0d, 0x0b, 0xe1, + 0xd0, 0xef, 0x14, 0x23, 0xf6, 0x0d, 0xba, 0xe8, 0x0f, 0xd8, 0xe3, 0x09, 0xd9, + 0x06, 0x3d, 0x08, 0x05, 0xfa, 0xf7, 0x02, 0xf5, 0xd1, 0x4e, 0xf1, 0x14, 0xfd, + 0xc8, 0xec, 0xe5, 0xf3, 0x15, 0xd2, 0xd8, 0xda, 0x08, 0xeb, 0xe9, 0xdf, 0xdf, + 0xec, 0xf2, 0x09, 0x04, 0x07, 0x1f, 0xec, 0x0c, 0xcf, 0x10, 0x06, 0xf7, 0xfb, + 0xe8, 0xcb, 0xff, 0x15, 0xc3, 0xf4, 0xe6, 0xf3, 0xf5, 0xef, 0xea, 0x0c, 0x19, + 0xe9, 0x1f, 0xed, 0xc9, 0xef, 0xde, 0xec, 0x07, 0x27, 0xd5, 0x08, 0xec, 0xec, + 0xe8, 0xcc, 0xe0, 0xfc, 0xca, 0xf4, 0xc4, 0xf2, 0xdd, 0x13, 0x20, 0x20, 0x2a, + 0xf4, 0xea, 0xfb, 0xe8, 0x19, 0x16, 0xfc, 0xe2, 0x1d, 0xea, 0xfb, 0x35, 0x14, + 0x14, 0xbe, 0x0a, 0x2c, 0x0f, 0xe1, 0xe5, 0xf8, 0xcd, 0xf4, 0x03, 0xff, 0xeb, + 0x09, 0x09, 0xbd, 0xdf, 0xf9, 0xea, 0xf2, 0x0b, 0x06, 0xf1, 0xf8, 0xec, 0xf7, + 0xf3, 0xe5, 0xf3, 0xf6, 0xf8, 0x25, 0xe9, 0xe9, 0xc7, 0x1a, 0x05, 0x05, 0x0e, + 0x0c, 0x05, 0xec, 0x19, 0xfa, 0x28, 0xe2, 0x06, 0x13, 0xe1, 0x18, 0xe9, 0x06, + 0xf9, 0xfe, 0x09, 0x06, 0x00, 0xe9, 0xef, 0xf1, 0xf8, 0xf5, 0xed, 0x2c, 0x15, + 0xef, 0xdd, 0x08, 0xcd, 0xd0, 0xdf, 0xfc, 0xf5, 0xf9, 0xdc, 0xdc, 0xdb, 0xff, + 0xe0, 0x2e, 0xed, 0x02, 0xfb, 0xfd, 0xeb, 0xf5, 0xe3, 0x2d, 0xc6, 0xd6, 0x1b, + 0xe9, 0xfb, 0x16, 0x09, 0x0b, 0xc1, 0xea, 0xe6, 0x09, 0xff, 0xf5, 0xfc, 0x34, + 0xf6, 0x1c, 0xfd, 0x0a, 0x02, 0x04, 0x12, 0xf5, 0x12, 0xe0, 0xf5, 0xc2, 0xf2, + 0xf0, 0x0d, 0x0f, 0xf7, 0xe8, 0xec, 0x2e, 0x34, 0xe2, 0xe1, 0x18, 0xfd, 0xba, + 0x08, 0x14, 0xf2, 0xea, 0x15, 0x1d, 0xda, 0x0c, 0x1a, 0xfe, 0xe6, 0x0b, 0x01, + 0x32, 0x25, 0x22, 0xec, 0xca, 0x11, 0xed, 0x22, 0xde, 0xf9, 0xf8, 0x0f, 0xd1, + 0x03, 0xfc, 0x04, 0xf5, 0x0d, 0xb3, 0xe6, 0x2e, 0xe9, 0xf0, 0x22, 0x15, 0x52, + 0x14, 0xf0, 0xe6, 0x27, 0xfb, 0x19, 0xe9, 0x28, 0xe6, 0xff, 0xba, 0xf5, 0x07, + 0x04, 0xbd, 0x07, 0xe1, 0x05, 0xea, 0x08, 0xec, 0xda, 0xb9, 0x32, 0xe7, 0xec, + 0x0e, 0x05, 0xad, 0xef, 0xf0, 0xe7, 0xe9, 0x27, 0xd6, 0xe4, 0x26, 0x05, 0x07, + 0xc4, 0xd5, 0xf7, 0xfd, 0xcb, 0xf4, 0x21, 0xe6, 0x0c, 0x25, 0x0b, 0xcc, 0x1f, + 0xc1, 0x2d, 0x04, 0x1e, 0x49, 0x1f, 0x3c, 0x19, 0x00, 0xe5, 0xaa, 0xcf, 0xd5, + 0xc9, 0x03, 0xd6, 0xcf, 0xe4, 0xf0, 0x05, 0x2f, 0x07, 0xf1, 0xc5, 0x2a, 0x25, + 0xfd, 0x30, 0x42, 0xf2, 0x01, 0xfd, 0xe1, 0x0c, 0xf7, 0x1e, 0x7f, 0x04, 0x16, + 0xc3, 0xde, 0xd8, 0x00, 0xc9, 0xe0, 0x35, 0xfc, 0xf0, 0x06, 0x31, 0xec, 0x0d, + 0xd6, 0xe0, 0xd1, 0x2c, 0xcd, 0xc8, 0xf9, 0xf9, 0xfd, 0xe9, 0xf4, 0x0d, 0xc5, + 0xe2, 0x29, 0xce, 0xdf, 0xe4, 0xf3, 0x07, 0x1c, 0x0b, 0xf6, 0x13, 0xe3, 0x06, + 0x00, 0x36, 0x09, 0xd7, 0xce, 0xdc, 0x19, 0xff, 0x14, 0xe2, 0x09, 0xdd, 0x09, + 0xf6, 0xc6, 0xf7, 0x9f, 0x0b, 0xeb, 0xd4, 0x0a, 0x22, 0x28, 0xd8, 0xcc, 0xcf, + 0xdc, 0xd6, 0xc1, 0x02, 0xf8, 0xdd, 0x0c, 0xef, 0x40, 0xd9, 0xd1, 0xc9, 0x07, + 0xee, 0xea, 0xda, 0xac, 0xeb, 0x37, 0xe1, 0xd7, 0x07, 0xc3, 0x1f, 0xfe, 0x12, + 0xe6, 0xe1, 0xf7, 0x1d, 0xb7, 0x29, 0x18, 0xd1, 0x3f, 0x00, 0xb6, 0x1a, 0xd5, + 0xf4, 0x0d, 0xeb, 0xab, 0xe4, 0xe1, 0x14, 0xf1, 0xdd, 0xcb, 0xf2, 0x0e, 0x03, + 0xe6, 0xd5, 0x21, 0x4e, 0xe0, 0xcc, 0x07, 0x20, 0xce, 0x12, 0xb1, 0xe5, 0xd8, + 0x13, 0xb8, 0x0c, 0xeb, 0xda, 0xfb, 0x0a, 0xd5, 0xe8, 0x66, 0x28, 0xfb, 0xee, + 0x94, 0x35, 0xc4, 0x24, 0xc8, 0x29, 0x12, 0x0c, 0xf3, 0xee, 0x28, 0x96, 0x03, + 0x22, 0xf2, 0xf2, 0xe3, 0x95, 0xf2, 0x7f, 0xf6, 0xeb, 0x03, 0x29, 0xe9, 0xd7, + 0xe4, 0x33, 0xeb, 0x49, 0xfd, 0xdc, 0xc5, 0x1b, 0xf0, 0x2c, 0x87, 0xf4, 0x04, + 0x10, 0xe9, 0xf5, 0xc8, 0xef, 0x06, 0x13, 0xfe, 0x26, 0xf0, 0x32, 0x11, 0xf0, + 0x05, 0x21, 0xfc, 0xe8, 0xcf, 0xf8, 0x9c, 0x31, 0xf4, 0xc6, 0xf0, 0x13, 0x0e, + 0xe8, 0xe0, 0x2e, 0x32, 0xfe, 0xf6, 0x17, 0xce, 0xe9, 0xcd, 0x06, 0x06, 0xcf, + 0x33, 0x09, 0x1d, 0x07, 0xd9, 0xcb, 0xcc, 0xd9, 0x4d, 0xf5, 0xd1, 0xba, 0xe7, + 0xc2, 0xe1, 0x03, 0x20, 0x0a, 0x0e, 0xc4, 0x00, 0xb1, 0x5a, 0xf0, 0x3e, 0xcf, + 0x26, 0x0a, 0x33, 0x0e, 0xee, 0xfe, 0xbb, 0xe0, 0x21, 0xd9, 0xa1, 0xb4, 0x58, + 0xc8, 0xd4, 0xff, 0xed, 0xaf, 0x1a, 0x0f, 0xca, 0xd2, 0xfd, 0x09, 0xc4, 0x1b, + 0x97, 0xdf, 0xf3, 0x32, 0xe3, 0xc2, 0xf1, 0x1d, 0xf1, 0xc3, 0xf4, 0x9d, 0x00, + 0xeb, 0x0b, 0x0f, 0x03, 0x17, 0xc4, 0x09, 0xe5, 0x14, 0xfb, 0x1a, 0xc8, 0xfe, + 0x11, 0xb6, 0x21, 0xeb, 0x19, 0xb6, 0x0c, 0xfd, 0xca, 0xc8, 0xde, 0x00, 0xa4, + 0xc4, 0xe6, 0xeb, 0x03, 0x0b, 0x10, 0xe5, 0xf6, 0xc6, 0xd0, 0xb9, 0xd2, 0xd0, + 0x23, 0xb3, 0xa0, 0xdf, 0x32, 0xd7, 0x17, 0x95, 0xe2, 0x01, 0x06, 0xa7, 0xec, + 0xa0, 0x33, 0x0f, 0xca, 0xfc, 0xc1, 0xd9, 0xa2, 0x14, 0xf4, 0xc9, 0xff, 0x21, + 0x03, 0x84, 0xf7, 0xfd, 0x2d, 0xc4, 0x08, 0xce, 0xa9, 0xf7, 0x35, 0xcc, 0x24, + 0x44, 0xe4, 0xbf, 0xbb, 0xe6, 0x22, 0x0a, 0xf3, 0xe2, 0xdb, 0x1d, 0xea, 0xd9, + 0xac, 0xff, 0x25, 0xfb, 0x3c, 0x05, 0xe8, 0xb0, 0xf0, 0x01, 0x05, 0x01, 0x31, + 0x1f, 0x34, 0xab, 0xde, 0x8d, 0x18, 0xe8, 0xb9, 0xe2, 0x01, 0x24, 0x06, 0xde, + 0xef, 0xf4, 0xa2, 0xc0, 0xec, 0x2d, 0xf4, 0xa5, 0xda, 0x0a, 0x37, 0x0f, 0x18, + 0x18, 0xbc, 0xe5, 0xed, 0x0b, 0xf5, 0xed, 0xf3, 0x28, 0x11, 0x3e, 0x2f, 0x99, + 0xd0, 0x00, 0xb7, 0x18, 0xb9, 0x3b, 0x31, 0x16, 0xf2, 0xb3, 0x5f, 0xf9, 0x06, + 0x18, 0xd3, 0xfb, 0x81, 0xae, 0xcf, 0xe0, 0xe5, 0xe4, 0xee, 0x09, 0x24, 0xac, + 0xf9, 0xcf, 0xa3, 0x53, 0xe2, 0x1d, 0x4e, 0xb9, 0xc1, 0xcb, 0x41, 0xdf, 0x09, + 0x22, 0xf1, 0xe7, 0xe6, 0x20, 0xdb, 0x49, 0xbf, 0x00, 0xee, 0xd5, 0xd2, 0xdf, + 0x2a, 0xe9, 0x3b, 0xd1, 0xdf, 0xf8, 0xdb, 0x05, 0x31, 0xef, 0xd4, 0x0d, 0x03, + 0x2f, 0x1f, 0xd4, 0xa2, 0xfc, 0xf2, 0x2b, 0x0d, 0x22, 0x1b, 0x07, 0xf0, 0x3f, + 0xf5, 0x13, 0x07, 0x01, 0xd4, 0x41, 0xd0, 0xc4, 0xfa, 0x1d, 0x26, 0xe8, 0xa7, + 0x0c, 0x0e, 0xc6, 0x0b, 0x3a, 0x55, 0x13, 0x2f, 0x10, 0x60, 0xf7, 0x11, 0xcf, + 0x12, 0xf2, 0x0d, 0x2c, 0xf9, 0xd8, 0x15, 0x21, 0xf5, 0x00, 0x0e, 0xd1, 0xcc, + 0xfb, 0xaa, 0xe6, 0xd3, 0x33, 0x5b, 0x24, 0xfc, 0xc2, 0xcc, 0x31, 0xda, 0x40, + 0x57, 0xf2, 0xfb, 0xf6, 0xdd, 0x27, 0x32, 0xc9, 0x44, 0xdc, 0xd4, 0xe3, 0xed, + 0xc3, 0x32, 0xd2, 0xd2, 0x42, 0x10, 0x27, 0x0a, 0xd7, 0x10, 0x37, 0xe4, 0x3b, + 0x44, 0xd1, 0xd6, 0xe3, 0xdd, 0xf8, 0xcf, 0x0f, 0x02, 0xed, 0xca, 0xb0, 0xf4, + 0xd8, 0xd4, 0xf8, 0x11, 0x0c, 0xfc, 0x19, 0xd2, 0xe7, 0xdc, 0xed, 0x14, 0xfc, + 0xda, 0xb0, 0xc6, 0x03, 0xce, 0xb3, 0x26, 0x0e, 0x21, 0xfa, 0xe4, 0xeb, 0x07, + 0xb6, 0x2d, 0xa3, 0xcc, 0x33, 0x14, 0xe1, 0x12, 0xb9, 0xfb, 0xe9, 0x27, 0xbb, + 0x3d, 0x06, 0xbe, 0xe3, 0x03, 0xf8, 0xe1, 0xf5, 0x2d, 0x07, 0x56, 0x1b, 0x05, + 0x1d, 0xc8, 0x01, 0xfc, 0xcf, 0xf6, 0xb4, 0x24, 0xea, 0x0d, 0xd6, 0xfe, 0xf0, + 0xf0, 0xef, 0xd2, 0xe4, 0xe2, 0x1c, 0x06, 0xfd, 0xd1, 0x24, 0xf5, 0x81, 0x09, + 0xee, 0xd9, 0x33, 0x03, 0xeb, 0x13, 0xe7, 0x22, 0xe9, 0x21, 0xbf, 0xee, 0x1c, + 0xe3, 0xd8, 0x0d, 0xe0, 0xcb, 0xac, 0xbf, 0xe2, 0xfc, 0xba, 0x2f, 0x35, 0x17, + 0xf2, 0xce, 0x11, 0xd8, 0xed, 0xf6, 0xd6, 0x0e, 0xfb, 0xe8, 0xe8, 0xf6, 0xb8, + 0xe4, 0xfd, 0xf0, 0xe2, 0xf5, 0xc7, 0x14, 0xe3, 0x03, 0xc0, 0xe4, 0x11, 0xef, + 0xf2, 0xe1, 0xf6, 0xe6, 0xef, 0xed, 0x22, 0x18, 0xe0, 0xf5, 0x34, 0x1b, 0x1b, + 0xb7, 0x0c, 0xfe, 0x2d, 0x0e, 0xad, 0xc8, 0xd6, 0xc9, 0x0c, 0x06, 0xe6, 0xf3, + 0x14, 0xc6, 0xf9, 0xc0, 0x1b, 0xd3, 0x23, 0x22, 0xe9, 0x15, 0xf1, 0xff, 0xee, + 0x18, 0x14, 0xcb, 0xe6, 0xd6, 0xea, 0x08, 0xf0, 0x39, 0xe7, 0x06, 0x2e, 0x13, + 0x0f, 0x0c, 0xd4, 0xc9, 0xe5, 0xdf, 0x0f, 0x0e, 0xf4, 0x0c, 0xf5, 0xff, 0x1e, + 0x27, 0xf0, 0x0a, 0xa0, 0xfe, 0xd7, 0x29, 0xd4, 0xea, 0x18, 0xfb, 0x00, 0xb8, + 0xb0, 0xf6, 0x93, 0x0c, 0xde, 0x25, 0x08, 0x0d, 0xe9, 0xdd, 0x30, 0xc3, 0xff, + 0x1c, 0xae, 0xdc, 0xee, 0x1c, 0x03, 0x15, 0xea, 0x1d, 0xf1, 0x15, 0x1e, 0xf5, + 0x9c, 0x12, 0xec, 0x12, 0xd9, 0xea, 0x13, 0xfe, 0xea, 0x20, 0xf9, 0x0b, 0x6e, + 0x08, 0xe7, 0x11, 0xc1, 0x0d, 0xdd, 0x1a, 0x1a, 0xd7, 0x2a, 0xfe, 0xe0, 0x2e, + 0xdb, 0xdf, 0xea, 0xfc, 0xe6, 0xb0, 0xdf, 0xbb, 0x07, 0xeb, 0xac, 0x09, 0xf1, + 0x3c, 0x07, 0xe2, 0xcd, 0x0c, 0xed, 0x02, 0xee, 0x01, 0x93, 0x44, 0xda, 0x06, + 0xe3, 0x12, 0x05, 0xf1, 0x49, 0x1a, 0xe0, 0xfd, 0x02, 0xd8, 0xed, 0xfe, 0x36, + 0xda, 0xd0, 0x15, 0x24, 0x01, 0x0b, 0x07, 0x44, 0x23, 0x31, 0xef, 0x46, 0x24, + 0x9e, 0xe4, 0xd1, 0xf9, 0xb6, 0x34, 0x3f, 0xf3, 0xe7, 0xe9, 0x9d, 0xf3, 0xd7, + 0xcf, 0xf0, 0x36, 0xe4, 0x1c, 0x0b, 0xc9, 0xe4, 0x04, 0x28, 0xf3, 0x22, 0xf7, + 0xe3, 0xe1, 0x15, 0xef, 0xab, 0x0d, 0xbd, 0x99, 0xb1, 0xdc, 0xc6, 0xd1, 0x16, + 0xf8, 0x41, 0x13, 0x2a, 0x2e, 0xce, 0xe0, 0x32, 0x34, 0x04, 0xdf, 0xff, 0x1f, + 0xba, 0xe6, 0xfc, 0xc5, 0x22, 0x08, 0xe8, 0xff, 0xf4, 0xcf, 0x04, 0x16, 0xe8, + 0x32, 0xe5, 0x34, 0xe7, 0xcc, 0xd4, 0xdf, 0x1c, 0xf4, 0xf5, 0xf4, 0x0f, 0x36, + 0xb1, 0xd5, 0xd5, 0xcd, 0xfa, 0xec, 0x12, 0xef, 0xa2, 0xfc, 0xdd, 0xd6, 0xf3, + 0x06, 0xd0, 0xaf, 0xd2, 0xfc, 0xf4, 0x21, 0x08, 0xd3, 0x3c, 0xbb, 0xfe, 0x3c, + 0x3b, 0xf6, 0xfc, 0xc7, 0x0a, 0xe2, 0xbf, 0xcb, 0x03, 0xf9, 0x29, 0x9f, 0xf6, + 0xfc, 0x3e, 0x00, 0x10, 0x44, 0x29, 0x2f, 0xc8, 0xf5, 0xc2, 0x2f, 0xe5, 0x0c, + 0x20, 0xff, 0x14, 0xe4, 0xff, 0xc3, 0x07, 0xf1, 0xda, 0x2b, 0x02, 0xb9, 0xe9, + 0xfe, 0xd8, 0x01, 0x96, 0x19, 0x02, 0x06, 0xc9, 0xd4, 0xe8, 0xfc, 0x17, 0xb7, + 0xd7, 0x22, 0x18, 0x0a, 0x1b, 0x47, 0xff, 0x23, 0x0a, 0x2c, 0x14, 0x0f, 0x32, + 0xea, 0x0c, 0xa1, 0x1d, 0xf5, 0xff, 0xf3, 0x11, 0x2d, 0xf5, 0x2f, 0x29, 0xcf, + 0x11, 0x20, 0x81, 0xd2, 0x81, 0x13, 0xad, 0xd2, 0xf8, 0x60, 0x1f, 0x12, 0xbc, + 0xe3, 0xad, 0x2c, 0x22, 0x9e, 0xfd, 0xc5, 0x12, 0xc0, 0xd5, 0x03, 0xea, 0xc8, + 0xc5, 0xe7, 0xd6, 0xdf, 0x33, 0x06, 0x3f, 0x28, 0x21, 0xfb, 0xce, 0x2f, 0xcf, + 0xc3, 0xc8, 0xe7, 0xd1, 0xef, 0xc6, 0xff, 0xdb, 0x38, 0xeb, 0x02, 0x1c, 0x01, + 0x12, 0x1a, 0x0e, 0x25, 0xe8, 0xf0, 0xfb, 0x97, 0xf6, 0xb5, 0xc0, 0xf4, 0xff, + 0xfd, 0xe2, 0xf3, 0xd2, 0xbe, 0xfe, 0x49, 0xe8, 0x2c, 0xf3, 0xe4, 0x16, 0xd7, + 0x02, 0x0f, 0x46, 0x1f, 0xf4, 0x01, 0xc4, 0x0d, 0xd5, 0xed, 0xec, 0xe3, 0xc7, + 0xec, 0xb8, 0xe9, 0x70, 0xd5, 0x10, 0x1c, 0x15, 0xcf, 0x21, 0xb1, 0x45, 0xf6, + 0xe9, 0xd2, 0xf8, 0xa8, 0xfd, 0xec, 0x16, 0x81, 0xd6, 0xe4, 0xfd, 0xf2, 0x1b, + 0x01, 0x0d, 0xf6, 0xb9, 0x12, 0x00, 0x33, 0x29, 0xac, 0xd6, 0xcd, 0x11, 0xfb, + 0xfc, 0xe7, 0xd8, 0xf1, 0x40, 0x29, 0x38, 0xee, 0x12, 0x34, 0xe3, 0xd7, 0x28, + 0xf0, 0xf1, 0x06, 0x23, 0xd4, 0xe0, 0xbe, 0x13, 0x10, 0xf4, 0x29, 0xd8, 0xe9, + 0xe3, 0xe6, 0xf6, 0xe2, 0x17, 0x29, 0x06, 0xc4, 0x1a, 0x45, 0xd4, 0x15, 0x17, + 0x63, 0x3d, 0xff, 0xcd, 0x16, 0x17, 0x2b, 0x14, 0x39, 0x09, 0xd5, 0xf4, 0xfb, + 0xff, 0xeb, 0xed, 0xd1, 0xd1, 0x07, 0xf9, 0xdc, 0xac, 0xef, 0x00, 0xd4, 0xc9, + 0x11, 0x22, 0xf0, 0xe3, 0x00, 0xe1, 0x19, 0xd7, 0xf3, 0x67, 0xa5, 0xc7, 0xd4, + 0x0a, 0x10, 0x06, 0xe4, 0x87, 0xe5, 0xe6, 0x1b, 0xda, 0xe3, 0xe5, 0xe1, 0xe7, + 0xcf, 0xf9, 0x03, 0xf3, 0x1a, 0xc5, 0xfc, 0x23, 0x1f, 0x05, 0x15, 0xca, 0xd3, + 0xcb, 0x62, 0xb0, 0x5f, 0x17, 0xd5, 0x1f, 0xc6, 0xfe, 0xcc, 0x31, 0xd2, 0x0b, + 0x20, 0x01, 0xe2, 0xf7, 0x25, 0xc9, 0xad, 0xfa, 0xb7, 0xd7, 0x5d, 0xfe, 0xc1, + 0x04, 0xe6, 0xea, 0xda, 0xad, 0x1b, 0xf4, 0xe7, 0xdc, 0xfb, 0x1a, 0xf3, 0x2e, + 0x1e, 0x23, 0x1c, 0xea, 0xeb, 0xe6, 0xce, 0xef, 0xf1, 0xfa, 0xc9, 0x21, 0x27, + 0xf0, 0xfe, 0x08, 0xe3, 0xc7, 0xfd, 0x20, 0x2c, 0x1b, 0x07, 0xc3, 0xe0, 0xce, + 0xe6, 0x04, 0xd4, 0xef, 0xf4, 0xb1, 0x46, 0xf7, 0x06, 0xd3, 0x34, 0x0b, 0x49, + 0xcd, 0xea, 0xea, 0x1e, 0xd5, 0x1b, 0xc9, 0x02, 0xe7, 0x01, 0xed, 0x2b, 0xdd, + 0x06, 0xb6, 0xe2, 0x0a, 0x2f, 0x0c, 0x25, 0x20, 0xda, 0x24, 0xf2, 0xfc, 0x01, + 0x17, 0xf5, 0xf4, 0x3c, 0xfd, 0x18, 0xd6, 0xe2, 0x34, 0xf4, 0xdf, 0xf0, 0x31, + 0xea, 0xf7, 0x20, 0xf4, 0x81, 0x0d, 0xe9, 0x12, 0xf5, 0xb4, 0xd8, 0xaf, 0xbc, + 0xd2, 0x12, 0x1e, 0xf0, 0xa6, 0xd0, 0xea, 0x01, 0x1b, 0xf1, 0x3a, 0xd7, 0xf8, + 0x3e, 0x93, 0xee, 0xbd, 0x1e, 0xcb, 0x14, 0xf4, 0x03, 0xeb, 0x00, 0xb8, 0xee, + 0x04, 0xe5, 0x2d, 0xb8, 0x0c, 0xaf, 0x26, 0xdc, 0x31, 0xb6, 0xf4, 0x1f, 0x31, + 0xa7, 0xeb, 0x22, 0xf6, 0xfc, 0xfc, 0xc0, 0x24, 0xec, 0xf6, 0xe6, 0x1e, 0xb4, + 0xef, 0x18, 0xe7, 0xf1, 0xfb, 0xcf, 0xdf, 0xcd, 0x0b, 0xee, 0x26, 0x10, 0xd1, + 0x11, 0xf3, 0x0f, 0x1c, 0x42, 0xed, 0x34, 0xf8, 0xf7, 0xff, 0xdc, 0xf4, 0x2e, + 0x23, 0x18, 0xf4, 0xc1, 0x18, 0x19, 0xfc, 0xbb, 0xad, 0x10, 0x02, 0xfd, 0xe8, + 0x09, 0xf2, 0x2b, 0x07, 0x2d, 0xd8, 0x23, 0x2e, 0x31, 0x0a, 0x1a, 0x1f, 0x10, + 0x20, 0x10, 0xa5, 0xf8, 0xdd, 0x32, 0xf0, 0xda, 0xb7, 0x20, 0x13, 0x0e, 0xfc, + 0xfb, 0xc6, 0x00, 0x0d, 0xc9, 0xbf, 0x95, 0xe5, 0x03, 0xd4, 0xf3, 0xf2, 0xf2, + 0x3c, 0xf5, 0x99, 0xbc, 0x0b, 0xf1, 0x1a, 0xd2, 0x1d, 0xba, 0xbb, 0xdf, 0xf6, + 0xbd, 0x2e, 0x29, 0x20, 0x01, 0x0b, 0xeb, 0xa8, 0xed, 0x40, 0xe6, 0x23, 0xc6, + 0x0c, 0x3a, 0xf8, 0xff, 0xf4, 0xed, 0x05, 0xea, 0x0e, 0xfb, 0xbf, 0xeb, 0xd7, + 0xf0, 0x09, 0xea, 0x26, 0x11, 0xd9, 0xfc, 0xc0, 0x14, 0xfc, 0xff, 0xf9, 0xd8, + 0x03, 0xb8, 0xf1, 0xf4, 0xf2, 0xfc, 0xd3, 0xd0, 0xf7, 0xed, 0xf1, 0x28, 0xfc, + 0x22, 0x07, 0x36, 0xef, 0x07, 0x04, 0x0b, 0xec, 0x01, 0xee, 0x25, 0xe5, 0xf0, + 0x1f, 0x01, 0xea, 0x10, 0x1d, 0x0e, 0xde, 0xed, 0x24, 0x11, 0x06, 0xd7, 0xdd, + 0x01, 0xc2, 0x48, 0x28, 0x4f, 0xe3, 0x3c, 0xd7, 0xe4, 0xe1, 0xcd, 0xf9, 0xf4, + 0xe9, 0xc2, 0xf5, 0x07, 0xef, 0x05, 0x1d, 0x0e, 0xdf, 0x04, 0xd9, 0xf0, 0x17, + 0x01, 0xeb, 0xe8, 0xd0, 0x2f, 0x2c, 0x52, 0xf9, 0xc3, 0xfe, 0xf7, 0xf5, 0x3a, + 0xb5, 0xed, 0xd1, 0x0a, 0xec, 0xfa, 0xd4, 0xfd, 0x35, 0x14, 0xf3, 0xba, 0xe5, + 0xff, 0x29, 0xe8, 0x45, 0xf7, 0x09, 0xe5, 0xcf, 0xd9, 0xd7, 0x01, 0xf2, 0xf6, + 0xf6, 0x1d, 0xd2, 0xfe, 0xeb, 0xdd, 0xdb, 0x1b, 0x2b, 0xe4, 0xd9, 0x43, 0xed, + 0xd6, 0x0f, 0xc2, 0x1d, 0x21, 0xc1, 0xd5, 0x0d, 0x28, 0x27, 0xee, 0xce, 0xbb, + 0xe4, 0x36, 0xe8, 0xd1, 0xe3, 0xf4, 0x7f, 0xd4, 0xf5, 0x0a, 0xf9, 0xc0, 0xef, + 0xe3, 0xff, 0xe5, 0x11, 0xf3, 0x3f, 0x2b, 0x03, 0xe3, 0xcd, 0x2a, 0xe9, 0xfb, + 0xfe, 0xfb, 0xeb, 0x34, 0xdf, 0x2f, 0xe7, 0xd3, 0xe7, 0xe9, 0x16, 0x1f, 0xd6, + 0xc2, 0xeb, 0x0b, 0x1f, 0x02, 0xf8, 0xea, 0xfa, 0xd9, 0xf6, 0xf4, 0xf3, 0xaa, + 0x10, 0xc6, 0xd2, 0x25, 0xf4, 0x02, 0x31, 0xf5, 0x04, 0xcd, 0xd9, 0xf2, 0xed, + 0xf5, 0x19, 0x30, 0x13, 0x11, 0x14, 0xed, 0x1c, 0x1d, 0xf7, 0xbc, 0xcc, 0x24, + 0x3b, 0x0d, 0xd4, 0xf6, 0xf5, 0xe4, 0xe0, 0xf5, 0x0c, 0xe0, 0xcf, 0xf4, 0x0d, + 0xb7, 0xe2, 0x00, 0xfd, 0x10, 0x13, 0x43, 0x22, 0x2d, 0x36, 0x0f, 0x06, 0x08, + 0xca, 0xd9, 0xf0, 0x2e, 0x04, 0xbd, 0xe5, 0xbd, 0x0e, 0xde, 0x02, 0xee, 0xdc, + 0xc6, 0x0e, 0xe5, 0xcd, 0xff, 0xf6, 0x13, 0x0f, 0xf8, 0xf0, 0xf5, 0xf0, 0xea, + 0x27, 0xa5, 0xe1, 0xf9, 0x0c, 0xd7, 0x07, 0xab, 0xe0, 0x36, 0x12, 0xdb, 0x32, + 0xf6, 0x16, 0xf6, 0x10, 0xfd, 0x12, 0xd1, 0xfb, 0xf4, 0xf9, 0xdb, 0xe4, 0xcf, + 0x02, 0x09, 0x3b, 0xe7, 0x15, 0xfe, 0x19, 0x7f, 0x29, 0xfa, 0xfd, 0xcd, 0x13, + 0xea, 0x0b, 0xdf, 0x17, 0xfa, 0x18, 0x03, 0xeb, 0xed, 0x01, 0xc6, 0x15, 0xd0, + 0xb5, 0x16, 0xbe, 0x1c, 0x1a, 0x0f, 0x0b, 0x07, 0xe8, 0x19, 0x07, 0x12, 0x3d, + 0xf0, 0xf1, 0xf2, 0xb5, 0xc3, 0xe3, 0xfa, 0xff, 0xd8, 0xd3, 0xb4, 0x00, 0xc5, + 0xd3, 0xea, 0xc4, 0xd5, 0xfd, 0xe3, 0x44, 0x0d, 0x1e, 0xee, 0xf7, 0xbc, 0xdd, + 0xe5, 0xde, 0xda, 0x12, 0xd3, 0xc9, 0x05, 0xc3, 0xed, 0xd5, 0xf5, 0xbf, 0xc8, + 0x01, 0x0a, 0x00, 0x25, 0x28, 0x03, 0xc6, 0x00, 0xe4, 0xd3, 0xf2, 0xfd, 0xf3, + 0x0c, 0xfb, 0x0f, 0x17, 0xb0, 0xdc, 0x02, 0xb7, 0xef, 0xd3, 0xf7, 0xce, 0xf6, + 0x27, 0x23, 0x0d, 0x11, 0xcc, 0xfb, 0xf9, 0xf2, 0x22, 0xd8, 0xc4, 0x33, 0xf0, + 0x14, 0x42, 0x05, 0xe4, 0xed, 0xf7, 0x1e, 0xbe, 0xc2, 0xea, 0x11, 0xeb, 0xdf, + 0x0c, 0xf9, 0xc6, 0x07, 0x13, 0xb1, 0xd6, 0xf9, 0xb8, 0xd1, 0xf5, 0xd2, 0xcf, + 0x02, 0xba, 0x10, 0x02, 0xe4, 0x16, 0xeb, 0xd0, 0x3f, 0xda, 0xec, 0xe1, 0x1a, + 0x39, 0x1a, 0x06, 0x2e, 0x17, 0xdb, 0x09, 0xf8, 0xe9, 0xf7, 0x18, 0x12, 0xb1, + 0x0a, 0xf2, 0xef, 0xfd, 0xe6, 0x24, 0xfd, 0x1b, 0xe1, 0x07, 0xb9, 0xf8, 0xf2, + 0xcb, 0x49, 0xec, 0xe2, 0x04, 0x1d, 0xd1, 0xd5, 0xe8, 0x09, 0xec, 0xe0, 0xb8, + 0xc8, 0xfc, 0xf4, 0xf5, 0x08, 0xe9, 0xfb, 0xf5, 0x13, 0xad, 0x14, 0xdb, 0x01, + 0x09, 0xbe, 0x10, 0xe8, 0x19, 0xfc, 0xec, 0x1e, 0xbe, 0xb1, 0x2d, 0xbb, 0x01, + 0xf8, 0x0a, 0x4c, 0x1e, 0x17, 0xec, 0xf0, 0xc8, 0x1f, 0x18, 0x9b, 0xe9, 0xf1, + 0x0c, 0xf2, 0xca, 0xa2, 0xd0, 0xef, 0xee, 0xcb, 0xee, 0x09, 0xff, 0xce, 0xf0, + 0xff, 0x1e, 0xd0, 0x0b, 0xd2, 0xe4, 0xa4, 0xd8, 0xfc, 0xd8, 0xe3, 0x36, 0xfc, + 0x12, 0x2d, 0x22, 0x74, 0x14, 0xed, 0xdb, 0xbc, 0x08, 0xd3, 0x2a, 0xd0, 0x96, + 0x17, 0xf2, 0x26, 0xfd, 0x05, 0xd3, 0xd7, 0x56, 0xbc, 0xdc, 0x14, 0xe4, 0xf7, + 0x6c, 0x05, 0x21, 0x30, 0x25, 0x11, 0x00, 0xb5, 0x50, 0xcb, 0x05, 0xea, 0xf1, + 0x27, 0x32, 0xf7, 0x22, 0xc5, 0xd5, 0xcd, 0xf0, 0xed, 0x37, 0xc3, 0x1b, 0xe7, + 0x48, 0xee, 0xc9, 0xf3, 0xf4, 0xdb, 0xc7, 0xbc, 0xfe, 0xdd, 0xe9, 0x87, 0x01, + 0xf6, 0x1d, 0xf0, 0xba, 0xe4, 0xf6, 0xcd, 0x21, 0xf6, 0xbf, 0x1f, 0xf4, 0x0b, + 0xe4, 0xc1, 0xe7, 0xdd, 0x45, 0x03, 0x06, 0x09, 0x04, 0x1e, 0x1a, 0x0a, 0x19, + 0xcc, 0x93, 0x06, 0xc6, 0x1c, 0xbe, 0xef, 0xa5, 0x19, 0x2e, 0x41, 0x3a, 0xf2, + 0xcb, 0xf3, 0xc5, 0x17, 0x36, 0x4d, 0xbf, 0xdc, 0x02, 0x04, 0xfb, 0xe5, 0x36, + 0xf9, 0xdd, 0x0a, 0x9b, 0xa5, 0xb4, 0x57, 0xce, 0xea, 0xfe, 0xd4, 0x4c, 0xd3, + 0xce, 0x0d, 0xdb, 0xf7, 0xf0, 0x97, 0x3a, 0xbc, 0xe0, 0xab, 0xe8, 0x1d, 0xe1, + 0xfa, 0xea, 0xec, 0xe0, 0x1d, 0xa9, 0xe8, 0xcd, 0xc8, 0x11, 0x01, 0x0d, 0x28, + 0x0f, 0xbc, 0x20, 0xec, 0x13, 0x01, 0xfd, 0x44, 0xd3, 0x24, 0xe6, 0x26, 0xb3, + 0x04, 0x23, 0x11, 0x0b, 0xca, 0x04, 0xc4, 0x08, 0x02, 0xe7, 0x7f, 0x25, 0x26, + 0xf1, 0xc7, 0xe2, 0xf1, 0x0c, 0xe6, 0xac, 0x38, 0xbe, 0xd0, 0xda, 0xe7, 0xbd, + 0x13, 0xc4, 0x03, 0x14, 0x12, 0x9c, 0xc5, 0xdf, 0xea, 0xfe, 0xdc, 0xcc, 0xc2, + 0x96, 0x2a, 0xe3, 0x28, 0xbe, 0xba, 0x38, 0xc1, 0x95, 0x2e, 0x1f, 0xda, 0xaf, + 0x08, 0x39, 0xa8, 0x51, 0x11, 0xe6, 0x28, 0x16, 0x32, 0xe9, 0x2b, 0xeb, 0xdd, + 0x17, 0x39, 0xd1, 0x3e, 0x07, 0x3c, 0x05, 0xbe, 0xfe, 0x32, 0xb0, 0x0f, 0xda, + 0xee, 0x26, 0xd4, 0x14, 0xeb, 0xf6, 0x06, 0x2f, 0x19, 0xdd, 0xe7, 0xbe, 0x2a, + 0xd3, 0xcb, 0xff, 0x35, 0xf0, 0xb4, 0x23, 0x05, 0xd5, 0xaa, 0x2a, 0x16, 0xfe, + 0xd1, 0xd7, 0x29, 0xa9, 0x17, 0xfa, 0x2b, 0x02, 0xbf, 0x3a, 0xaa, 0xe4, 0x0d, + 0xed, 0xdc, 0xcc, 0xee, 0x2b, 0xd3, 0xcf, 0xd4, 0xfe, 0xcc, 0xe4, 0x10, 0xbb, + 0x30, 0xc2, 0xe9, 0xd3, 0x2e, 0xaf, 0x10, 0xf5, 0xef, 0x30, 0xf3, 0x01, 0xfb, + 0xa9, 0xe8, 0x05, 0x50, 0x10, 0xe2, 0xe2, 0x30, 0x19, 0xed, 0x67, 0xea, 0x1f, + 0x3b, 0x5b, 0x10, 0xf8, 0x04, 0x57, 0x0e, 0x01, 0x81, 0xd6, 0x2e, 0xe4, 0xe8, + 0x9a, 0xfc, 0xa1, 0xe1, 0x3f, 0xc7, 0xfe, 0x2d, 0x50, 0x40, 0x2a, 0x54, 0xcf, + 0xd6, 0xac, 0xec, 0x12, 0xfc, 0x23, 0x0b, 0xb0, 0xee, 0xee, 0x07, 0x17, 0xee, + 0xd3, 0xdb, 0xf3, 0x04, 0xbf, 0xef, 0xf9, 0xc2, 0x2b, 0x0b, 0x0f, 0x4e, 0x44, + 0x97, 0x35, 0x26, 0x03, 0xe2, 0x03, 0x33, 0xd1, 0xd7, 0x2f, 0x2b, 0x06, 0x1a, + 0xf5, 0xe7, 0xe7, 0xf0, 0xfe, 0xfb, 0x1b, 0xcf, 0x44, 0xd0, 0x16, 0x9f, 0xb7, + 0xd2, 0xd1, 0xe4, 0xa8, 0xf0, 0xe8, 0xed, 0xd6, 0xb5, 0xb0, 0xb8, 0x96, 0xd8, + 0xc8, 0x02, 0x9d, 0xeb, 0x27, 0x08, 0xf1, 0xeb, 0xe9, 0xbf, 0xbf, 0x2e, 0xe8, + 0xae, 0xc7, 0xd6, 0xbe, 0xd8, 0xd5, 0xf8, 0x27, 0xb1, 0xdf, 0xd3, 0xfb, 0xca, + 0x20, 0xee, 0xf6, 0xa2, 0xe6, 0xf3, 0x4b, 0xd9, 0xb9, 0x23, 0x47, 0x19, 0x50, + 0xc3, 0xd7, 0xbe, 0x28, 0xf1, 0xf7, 0xf9, 0xd9, 0x0c, 0xc2, 0xe2, 0x21, 0xd3, + 0xf2, 0xde, 0x0b, 0xad, 0xbd, 0x17, 0xd8, 0xfa, 0xb8, 0xe5, 0x25, 0xd2, 0xe5, + 0xb1, 0xe7, 0x24, 0xbd, 0x4b, 0xa7, 0x08, 0x25, 0x11, 0xbc, 0xce, 0x0e, 0xb8, + 0xcf, 0xda, 0x05, 0xff, 0xd1, 0x48, 0xd8, 0xca, 0xf2, 0x9c, 0xfe, 0x14, 0x16, + 0xcb, 0x0e, 0x2c, 0xf3, 0xcc, 0x57, 0xb2, 0xf9, 0xf5, 0xd0, 0x1a, 0xc7, 0x1c, + 0x0c, 0x34, 0x05, 0x0a, 0xd9, 0xbe, 0x44, 0x05, 0x23, 0x35, 0xeb, 0x00, 0xa4, + 0x07, 0xb5, 0xd1, 0xda, 0x2b, 0x1c, 0x16, 0x27, 0xec, 0xf9, 0xcf, 0x33, 0xa7, + 0x1b, 0xee, 0xbc, 0x14, 0x25, 0xcb, 0xa0, 0xfe, 0xf0, 0xe4, 0xa3, 0xed, 0xf7, + 0xfd, 0x05, 0x2e, 0xe6, 0xe6, 0xb4, 0x40, 0xb2, 0xc5, 0xc6, 0xde, 0xad, 0xfd, + 0xac, 0xd6, 0xe5, 0xce, 0xbc, 0xee, 0x39, 0x4f, 0x10, 0xda, 0x3c, 0xae, 0xea, + 0x12, 0x21, 0xca, 0x1d, 0x97, 0xfc, 0xc9, 0xe7, 0xe9, 0xf3, 0x7d, 0xec, 0x11, + 0x59, 0x53, 0x06, 0x2b, 0x4c, 0xbc, 0x06, 0xf3, 0x09, 0xd9, 0xd5, 0xbd, 0x0e, + 0xf0, 0x02, 0x21, 0xda, 0x17, 0x13, 0xb9, 0xfa, 0xfe, 0x20, 0x01, 0xf9, 0xf3, + 0x08, 0xbf, 0xaf, 0x16, 0xf6, 0x2d, 0x4e, 0xfb, 0x1b, 0x47, 0xea, 0x13, 0x35, + 0x03, 0x11, 0x03, 0xe5, 0x15, 0xf7, 0xfe, 0xc6, 0xe2, 0x2f, 0xd5, 0x04, 0xcb, + 0x1e, 0x3a, 0x0e, 0x23, 0xe2, 0x48, 0xf6, 0x1f, 0xe0, 0xfd, 0xc6, 0x48, 0xd1, + 0x45, 0xf4, 0x2b, 0x35, 0x41, 0xc9, 0x51, 0xf6, 0xbd, 0xb4, 0xf9, 0xda, 0xae, + 0x20, 0xeb, 0xbe, 0xe0, 0x81, 0x28, 0xaf, 0x0f, 0xd6, 0x16, 0xf6, 0xf9, 0xc8, + 0xf5, 0xfc, 0xe9, 0xb6, 0xe2, 0xdd, 0xfa, 0x15, 0xdc, 0xcc, 0xe2, 0xc1, 0xd5, + 0x2c, 0xde, 0x1d, 0xb2, 0xe6, 0xf7, 0xf7, 0xf2, 0xfe, 0xff, 0xa6, 0xb1, 0x0d, + 0x08, 0xf8, 0xb8, 0x03, 0xcc, 0x0f, 0x10, 0x17, 0x1b, 0xcd, 0xec, 0x46, 0xd9, + 0xe5, 0xed, 0xd6, 0xf2, 0xe2, 0xf4, 0xe4, 0xdf, 0xda, 0xe8, 0xee, 0xb9, 0xe3, + 0xf9, 0x2c, 0xe7, 0x2d, 0xf9, 0xec, 0x14, 0xe2, 0xd5, 0xeb, 0x17, 0x50, 0x11, + 0xee, 0xfb, 0x25, 0xc0, 0xf2, 0xfe, 0x1f, 0xe2, 0xf1, 0xc7, 0xf3, 0x02, 0xeb, + 0xd2, 0xfe, 0x14, 0x2b, 0x56, 0x20, 0x29, 0x29, 0xca, 0xf2, 0xb3, 0x5e, 0xf3, + 0xcb, 0xdc, 0xf5, 0x4f, 0xf2, 0x4b, 0xe3, 0xd1, 0xe5, 0xbe, 0xce, 0xef, 0x0a, + 0x34, 0x5a, 0xd7, 0x00, 0x08, 0xeb, 0xe0, 0x07, 0xf6, 0x30, 0xe8, 0x11, 0xe1, + 0xc7, 0x07, 0xf1, 0xf6, 0xb4, 0x81, 0xe1, 0xeb, 0x1d, 0xde, 0xdd, 0xdc, 0xf5, + 0xfa, 0xaa, 0x09, 0xdf, 0x09, 0x30, 0xc3, 0xdc, 0xe3, 0xee, 0xf2, 0xfe, 0x17, + 0xe7, 0xbf, 0x3b, 0xfb, 0xe3, 0xff, 0xda, 0xf8, 0x15, 0x94, 0x0e, 0xf5, 0x02, + 0xed, 0x02, 0xee, 0xf2, 0xc6, 0xcc, 0xfd, 0xfc, 0x2d, 0xf9, 0x51, 0x46, 0xc6, + 0xcc, 0xce, 0xc7, 0x23, 0xa1, 0x06, 0xb9, 0xfe, 0xee, 0x13, 0x4e, 0x49, 0x01, + 0xea, 0xc5, 0x3c, 0xc4, 0x25, 0xf0, 0x5e, 0xf6, 0x18, 0x12, 0x34, 0xe7, 0xf2, + 0x0b, 0xc9, 0xdc, 0x33, 0xb5, 0xc1, 0xb2, 0x26, 0xdc, 0x15, 0xd6, 0xf9, 0xe3, + 0x42, 0xe7, 0xe6, 0x12, 0xf7, 0xef, 0xcb, 0x39, 0xdb, 0xb5, 0xf7, 0x18, 0xfb, + 0x0a, 0xae, 0xda, 0xfc, 0xdd, 0x04, 0xc3, 0xff, 0x10, 0xdb, 0x02, 0x06, 0x11, + 0x04, 0x1a, 0xfe, 0x13, 0x07, 0x57, 0x07, 0x25, 0xb6, 0xc2, 0xe5, 0xf1, 0x5a, + 0xa1, 0x35, 0x2a, 0xde, 0x2e, 0xd6, 0xe9, 0xc4, 0x03, 0xdf, 0xc2, 0x1a, 0x2f, + 0x23, 0xc8, 0xa8, 0xf6, 0xd6, 0xb6, 0xa1, 0x09, 0x1c, 0xa9, 0xb7, 0xe3, 0xed, + 0xf8, 0x03, 0xb1, 0x40, 0x02, 0xe7, 0xc1, 0x9c, 0xc5, 0xda, 0xf5, 0xed, 0xe4, + 0x04, 0x36, 0xf0, 0xe0, 0xd5, 0x07, 0xf3, 0x08, 0x5c, 0xa4, 0x07, 0x37, 0xc8, + 0xcd, 0x12, 0x1c, 0x3c, 0xf9, 0xed, 0xe5, 0x0d, 0xea, 0x15, 0xdc, 0x15, 0xf6, + 0xf2, 0x37, 0x15, 0x1a, 0x27, 0xd1, 0x2a, 0xfa, 0xe2, 0xba, 0x22, 0xd6, 0x19, + 0xd0, 0xd0, 0x0e, 0x08, 0x0e, 0x02, 0x30, 0x04, 0xee, 0xff, 0x33, 0xc2, 0xdd, + 0xea, 0xca, 0xe9, 0xdf, 0x06, 0xca, 0xe5, 0xfb, 0x39, 0x0e, 0xb8, 0xc2, 0x02, + 0x0c, 0x05, 0xe7, 0x37, 0xd8, 0x1b, 0xe6, 0x07, 0x02, 0xff, 0x03, 0x09, 0xec, + 0xf3, 0x01, 0xdb, 0xde, 0xf4, 0x50, 0xee, 0x21, 0xf4, 0xdc, 0x9f, 0xf1, 0xf7, + 0xf4, 0xc6, 0xd2, 0xf1, 0x30, 0x42, 0xed, 0x25, 0x2f, 0xf5, 0x08, 0x27, 0xc1, + 0xdb, 0x22, 0x23, 0xd6, 0x27, 0xeb, 0x0f, 0xf1, 0x28, 0x06, 0x20, 0x21, 0x55, + 0xf9, 0xed, 0x20, 0xbb, 0xf4, 0x29, 0x16, 0xea, 0xfc, 0xed, 0x0f, 0x0d, 0xce, + 0xfa, 0xf3, 0x38, 0x09, 0xca, 0x56, 0x7f, 0xf4, 0x26, 0x27, 0xef, 0x04, 0xf6, + 0xf5, 0xe3, 0xea, 0x16, 0xf5, 0x00, 0x35, 0x16, 0xc9, 0xff, 0x36, 0xfe, 0xbe, + 0xfc, 0x37, 0xef, 0xd5, 0xf8, 0x0a, 0x20, 0x1a, 0xfa, 0xd6, 0x01, 0x3e, 0x3f, + 0xc8, 0x16, 0x27, 0xdc, 0xc9, 0xdd, 0xb1, 0x38, 0x17, 0x0f, 0xde, 0xf7, 0xc0, + 0xfe, 0x09, 0xcb, 0xf3, 0x13, 0x21, 0x19, 0x46, 0xf5, 0x1b, 0xf4, 0x2b, 0xe7, + 0xb6, 0x0f, 0xec, 0x59, 0xec, 0xfa, 0x12, 0x1d, 0x09, 0xee, 0xee, 0x25, 0xef, + 0x07, 0xf1, 0xfa, 0xcf, 0xfc, 0x32, 0x2a, 0xf6, 0xf7, 0xe4, 0xf6, 0xac, 0xff, + 0x27, 0x03, 0xc8, 0xf2, 0xb3, 0xc7, 0xdf, 0xe5, 0xec, 0xde, 0x2c, 0x03, 0xf8, + 0xda, 0x00, 0xde, 0x23, 0xfb, 0xf8, 0xb7, 0x04, 0xdc, 0xfa, 0xe3, 0xe9, 0x29, + 0x16, 0x1c, 0x05, 0xd2, 0xbe, 0xcb, 0x10, 0xd4, 0x41, 0x2f, 0xdf, 0xc5, 0x2d, + 0xfc, 0x29, 0x1d, 0xa5, 0x21, 0x2b, 0xde, 0x12, 0x10, 0xbd, 0x0d, 0xf9, 0xb9, + 0x0d, 0xf2, 0x2c, 0xf1, 0x50, 0x36, 0x36, 0xe9, 0xb0, 0x48, 0x23, 0xef, 0xfe, + 0x1c, 0xf3, 0xe5, 0x0e, 0x46, 0x0d, 0x12, 0xfd, 0xe1, 0x0d, 0xef, 0x32, 0x1d, + 0xe7, 0x00, 0x23, 0x0c, 0xca, 0x25, 0x24, 0x00, 0xf5, 0xad, 0xcb, 0x0b, 0x09, + 0x1e, 0xd0, 0xfb, 0xd3, 0xdc, 0xee, 0xed, 0x36, 0xe3, 0xdb, 0x02, 0x6f, 0xda, + 0xc7, 0xd0, 0xd2, 0xd8, 0xa1, 0xc1, 0x04, 0x5d, 0xbd, 0x0d, 0x35, 0xf5, 0x09, + 0x59, 0xad, 0xe0, 0x00, 0xe7, 0xa3, 0x13, 0xa0, 0xfc, 0x27, 0xf1, 0x10, 0x06, + 0xd1, 0x22, 0x21, 0x43, 0x0e, 0xd8, 0xbc, 0x1d, 0xad, 0x05, 0xc2, 0xe7, 0x23, + 0xed, 0xfd, 0x0c, 0x0c, 0x08, 0xf9, 0x2f, 0x3b, 0x10, 0xf1, 0xd3, 0x10, 0xfa, + 0xe0, 0xe4, 0xb0, 0xc4, 0xf1, 0xd5, 0xd5, 0x2f, 0x14, 0xca, 0xf3, 0xea, 0xd9, + 0xde, 0xe6, 0x01, 0xec, 0xee, 0x0b, 0x1f, 0x28, 0x81, 0xfe, 0x02, 0xc0, 0xcc, + 0xce, 0xb1, 0xfd, 0x04, 0xdd, 0x18, 0xfa, 0x26, 0xe3, 0xe9, 0xca, 0xdc, 0xc6, + 0xef, 0xf6, 0x12, 0x08, 0xf0, 0x5f, 0xe6, 0xfd, 0xf8, 0x15, 0x2e, 0x0b, 0xcb, + 0x1b, 0x14, 0x43, 0x17, 0x58, 0xee, 0xb7, 0x5d, 0xd6, 0x15, 0x05, 0xa4, 0x10, + 0xe1, 0xd6, 0x12, 0x24, 0x2c, 0x33, 0x29, 0xce, 0xf4, 0x01, 0xb1, 0x48, 0xf2, + 0x29, 0x14, 0xc3, 0x1f, 0xf2, 0xd1, 0xd4, 0x46, 0xd3, 0x16, 0xef, 0xfe, 0xed, + 0xe5, 0x1d, 0x07, 0x2f, 0x29, 0xf0, 0x17, 0x18, 0xd0, 0x18, 0xdd, 0x53, 0xcb, + 0x0b, 0xd4, 0x09, 0x54, 0x08, 0xf4, 0x30, 0xd8, 0x3f, 0x44, 0x2c, 0xf2, 0x08, + 0x2c, 0x15, 0xe7, 0xe0, 0xdd, 0xe8, 0xcc, 0xce, 0xea, 0x2c, 0x06, 0xd3, 0x25, + 0x09, 0x2e, 0xb9, 0xa7, 0xe9, 0xcf, 0x11, 0xc5, 0xe9, 0x17, 0xc0, 0x01, 0xe2, + 0xe8, 0xe4, 0xef, 0xee, 0xd5, 0x55, 0x20, 0xf6, 0x17, 0xad, 0x15, 0xdc, 0x81, + 0xed, 0xcc, 0xe2, 0x20, 0x1c, 0xd0, 0xe6, 0x22, 0x02, 0x95, 0xf4, 0xd7, 0xd6, + 0x38, 0x2f, 0x0f, 0xc5, 0xa9, 0x0b, 0xd6, 0xef, 0x02, 0xde, 0x98, 0xaa, 0x29, + 0x4c, 0x2a, 0x3c, 0xca, 0x5f, 0x39, 0x06, 0x2e, 0xc6, 0xde, 0xf0, 0x0d, 0x9d, + 0xe1, 0x16, 0xe7, 0x1e, 0xdc, 0xd3, 0xf9, 0x09, 0xb4, 0x31, 0x9a, 0x87, 0xfe, + 0xb5, 0xc2, 0xeb, 0x0f, 0xe7, 0xf6, 0x47, 0x23, 0x12, 0xc0, 0xc9, 0x23, 0x17, + 0xec, 0xd6, 0xb1, 0xca, 0xee, 0x2c, 0xed, 0xf2, 0xc9, 0xf4, 0x1b, 0xc7, 0xcb, + 0xd4, 0xff, 0xe8, 0x08, 0xfc, 0xe9, 0x62, 0xe2, 0xe6, 0x0e, 0xf2, 0xbc, 0xe2, + 0xc1, 0xd9, 0x16, 0x12, 0x43, 0xb9, 0xee, 0xc0, 0xef, 0xfc, 0x37, 0xf5, 0xf0, + 0xca, 0xe9, 0x63, 0x18, 0xe9, 0x12, 0xcd, 0x0b, 0xdc, 0xf1, 0xc3, 0x05, 0x25, + 0x31, 0x10, 0x99, 0xcb, 0x24, 0xff, 0x4a, 0x0d, 0x2b, 0x02, 0xf9, 0x3e, 0x03, + 0x0b, 0x62, 0xdb, 0xf5, 0xd8, 0xf1, 0xd1, 0xf8, 0xe2, 0xdb, 0xf4, 0x21, 0xe6, + 0xac, 0x18, 0xdf, 0x21, 0xf4, 0x1b, 0xcd, 0xa9, 0x10, 0x6e, 0xe9, 0xfb, 0x17, + 0xd2, 0xf4, 0x0d, 0xf8, 0xf9, 0x30, 0x0a, 0x96, 0x00, 0xf9, 0xbf, 0xcf, 0xf4, + 0x3f, 0xf5, 0xec, 0x1d, 0x16, 0xa9, 0x0c, 0xe2, 0xb5, 0xf3, 0x1f, 0x3f, 0xf5, + 0x11, 0xf3, 0x17, 0x04, 0x0c, 0xd2, 0x9d, 0xb4, 0xdd, 0xec, 0xc4, 0x37, 0x13, + 0x06, 0x0c, 0xba, 0x2a, 0x15, 0xf7, 0xd4, 0xd0, 0xe6, 0x10, 0x19, 0xfa, 0x6d, + 0x49, 0xd8, 0xde, 0xcd, 0x00, 0xf9, 0xbf, 0xf6, 0xd5, 0x16, 0xb5, 0xbd, 0xde, + 0x21, 0xcb, 0x43, 0xf7, 0x1e, 0xdf, 0x2f, 0x0f, 0x23, 0xa7, 0x55, 0xe7, 0xf5, + 0xe4, 0xe0, 0x0e, 0xba, 0x41, 0xdb, 0xfc, 0xe8, 0x05, 0xcc, 0x0f, 0xb6, 0xf5, + 0xe3, 0xad, 0xeb, 0xf3, 0xba, 0x19, 0xfe, 0xe2, 0xf8, 0xaa, 0xd1, 0xfd, 0x9f, + 0xb3, 0x1f, 0xbb, 0xdf, 0xd2, 0x0b, 0x00, 0x2f, 0xd6, 0x03, 0xf4, 0xf1, 0x14, + 0xf6, 0x47, 0xfa, 0xca, 0xff, 0x08, 0xe2, 0xdc, 0x49, 0x44, 0x37, 0x2d, 0xfd, + 0xdc, 0xf8, 0xe3, 0x00, 0xd3, 0x78, 0xee, 0xf5, 0xe9, 0x07, 0xda, 0xd4, 0x34, + 0xca, 0xdc, 0x2a, 0x04, 0xe2, 0x08, 0x2e, 0x0c, 0xbb, 0x0c, 0xdf, 0x8b, 0xf6, + 0xe1, 0xf8, 0xfa, 0xdb, 0xe2, 0xfa, 0xc4, 0x09, 0x17, 0xf5, 0xed, 0xcd, 0x1b, + 0xda, 0x0b, 0x2c, 0x0c, 0xee, 0xf4, 0x09, 0xc9, 0xc9, 0xd8, 0xe3, 0x34, 0x49, + 0xef, 0x04, 0xc7, 0xfc, 0xf4, 0x01, 0xe0, 0xc6, 0x27, 0xdf, 0xf2, 0xe6, 0xf8, + 0x58, 0xd8, 0xf1, 0xb7, 0x14, 0xbd, 0x07, 0xfd, 0xd1, 0x8d, 0xdc, 0x25, 0x06, + 0xd5, 0xf1, 0xbb, 0xcd, 0x20, 0xb1, 0xd7, 0xec, 0x9d, 0x09, 0xdd, 0x07, 0xf5, + 0xfe, 0x35, 0xea, 0x6b, 0x3f, 0xce, 0xca, 0xf3, 0xd1, 0xe4, 0x19, 0x03, 0x0f, + 0x0e, 0xda, 0xdf, 0xe2, 0x18, 0xd2, 0x2f, 0x49, 0xe1, 0xe3, 0xa7, 0xf4, 0x11, + 0x03, 0xf1, 0xe2, 0x25, 0xf5, 0x03, 0xf3, 0xe2, 0xfe, 0xf9, 0x01, 0xed, 0xe6, + 0x2b, 0x02, 0xc0, 0xe4, 0xe0, 0x21, 0xda, 0xb7, 0xe0, 0x18, 0xe2, 0x01, 0xfe, + 0x0b, 0xe9, 0x3d, 0x8f, 0xaf, 0xf9, 0x0d, 0xdc, 0xf6, 0xff, 0xc5, 0xc7, 0xe7, + 0xe0, 0x15, 0xba, 0xd2, 0x16, 0xe4, 0x02, 0x1e, 0xf5, 0x0c, 0x56, 0xe0, 0x27, + 0x4b, 0xc0, 0x13, 0x05, 0x08, 0x2e, 0x02, 0x06, 0x19, 0xff, 0x21, 0x2b, 0xf6, + 0xfe, 0x38, 0xff, 0x7f, 0xda, 0xc2, 0x43, 0x07, 0xdf, 0xdb, 0xb6, 0x03, 0x0a, + 0xd3, 0x1e, 0xe6, 0xeb, 0xe6, 0xdf, 0xd7, 0x05, 0xda, 0xe2, 0x2e, 0xf9, 0xe6, + 0x24, 0x28, 0xfa, 0xfd, 0x09, 0x0a, 0xfb, 0xe3, 0x18, 0x0f, 0xcf, 0x15, 0x13, + 0xe5, 0xf2, 0x00, 0xef, 0xee, 0xd6, 0x0b, 0xd7, 0xf1, 0xfc, 0xf5, 0x1c, 0xcf, + 0x10, 0xfa, 0x2c, 0xcf, 0x35, 0x0a, 0xe6, 0xf8, 0xe7, 0x0f, 0xd6, 0xd6, 0x39, + 0xe4, 0xfb, 0x04, 0x1c, 0x1f, 0xc3, 0x1f, 0x23, 0x07, 0xee, 0x1e, 0x21, 0x20, + 0xec, 0xf9, 0xfb, 0x0d, 0xf5, 0xef, 0xdf, 0x26, 0x07, 0x00, 0xc8, 0x26, 0x2e, + 0x00, 0x0e, 0xb5, 0xe3, 0x4a, 0xdb, 0xfd, 0xb0, 0x2a, 0x0b, 0xe7, 0x23, 0xee, + 0xf9, 0xe5, 0xfe, 0x0c, 0xd3, 0xc1, 0xf5, 0xe7, 0xf7, 0x00, 0xf1, 0xde, 0x1d, + 0xec, 0x05, 0xd0, 0x0c, 0xde, 0x28, 0x04, 0x26, 0xee, 0xe4, 0xfd, 0xfb, 0x0e, + 0xe4, 0xfd, 0x14, 0x0d, 0x0d, 0x27, 0x29, 0xfa, 0xfd, 0xda, 0x0b, 0xe2, 0x12, + 0x04, 0x28, 0xeb, 0xee, 0xf7, 0xbf, 0xfa, 0xc2, 0x1c, 0xf8, 0xd8, 0xc5, 0xfd, + 0xe8, 0x12, 0xef, 0xfe, 0xe9, 0x0a, 0x11, 0x1b, 0xf2, 0xe2, 0xc4, 0xaa, 0xd5, + 0xce, 0x23, 0xf2, 0xe4, 0x1f, 0xcf, 0x07, 0x06, 0x17, 0x28, 0xd6, 0x24, 0x1b, + 0xc5, 0x07, 0x05, 0xf2, 0x52, 0x41, 0xe6, 0x7f, 0xfb, 0xd9, 0xec, 0xfb, 0x1b, + 0xe5, 0xf3, 0x02, 0xdc, 0x1b, 0x16, 0x16, 0x03, 0xf5, 0x12, 0x0c, 0xee, 0xef, + 0x05, 0x0f, 0xed, 0x21, 0xc2, 0xfb, 0x31, 0x04, 0xe4, 0xfb, 0xe7, 0xbd, 0x37, + 0xff, 0x07, 0x21, 0xd8, 0x0d, 0x39, 0x0a, 0xf3, 0x02, 0xe7, 0x0c, 0x13, 0xd0, + 0x0e, 0x1f, 0x15, 0xff, 0x06, 0xfc, 0x22, 0xfa, 0x1d, 0x08, 0xc5, 0xeb, 0xfa, + 0xe1, 0xd3, 0xfa, 0xf2, 0xf2, 0xd7, 0x2b, 0xf8, 0x13, 0xe6, 0xfe, 0xd2, 0xfc, + 0xe9, 0x11, 0x4e, 0x14, 0xe8, 0x36, 0xed, 0xdb, 0x12, 0x14, 0x23, 0x0f, 0xb5, + 0xdf, 0x3f, 0x0c, 0xee, 0xf3, 0xcb, 0xcb, 0xec, 0x2f, 0xad, 0x18, 0xeb, 0xc3, + 0xfd, 0x64, 0x08, 0x20, 0x2c, 0x27, 0xfb, 0xcf, 0xd3, 0xfe, 0x49, 0xeb, 0xcc, + 0xe9, 0xc6, 0x27, 0xfc, 0xac, 0xe0, 0xe0, 0xb7, 0x4c, 0xd0, 0xdd, 0xfa, 0x43, + 0xee, 0xa0, 0xa1, 0xb5, 0x0c, 0xd5, 0xd7, 0xa6, 0x06, 0xe8, 0xf4, 0xce, 0x1e, + 0xd5, 0xfb, 0xc5, 0x0f, 0xb3, 0xc2, 0x1a, 0x08, 0xb8, 0xff, 0x44, 0x23, 0x0c, + 0x14, 0xe9, 0x2d, 0xe7, 0x97, 0xd7, 0x2b, 0xe7, 0xac, 0xdc, 0xcb, 0x94, 0xee, + 0x0b, 0x1e, 0x00, 0x50, 0x26, 0x17, 0xf1, 0x2c, 0x38, 0xda, 0x0a, 0x6f, 0xd8, + 0xc9, 0x10, 0x26, 0xe3, 0x0d, 0x19, 0x1a, 0xf1, 0x15, 0xe6, 0xf9, 0xdd, 0xee, + 0xab, 0x20, 0xee, 0xfc, 0xde, 0xdd, 0x16, 0x23, 0x1f, 0x9f, 0x25, 0x2e, 0xe6, + 0x21, 0x0d, 0xc9, 0xfa, 0xcf, 0xe3, 0x01, 0xcf, 0x24, 0x71, 0xa5, 0xf5, 0x2e, + 0xdf, 0x35, 0x17, 0x30, 0xe3, 0xeb, 0x1e, 0x29, 0x16, 0xfb, 0x23, 0xe5, 0x20, + 0xf8, 0x1e, 0xf4, 0xb1, 0xe9, 0xbc, 0x08, 0x20, 0x00, 0x17, 0xcf, 0x03, 0x20, + 0xde, 0xbb, 0xd4, 0xf4, 0xc3, 0xe7, 0x2b, 0xe1, 0xb0, 0x38, 0x01, 0xdf, 0x9d, + 0x73, 0x16, 0x17, 0xc2, 0xe8, 0x47, 0x15, 0xfb, 0xc7, 0x07, 0xfb, 0x49, 0xd3, + 0x09, 0xbb, 0xaa, 0x38, 0x29, 0xef, 0xe6, 0xc9, 0xbf, 0x0c, 0x4b, 0xe0, 0x09, + 0x52, 0x15, 0x0a, 0x94, 0x89, 0xa6, 0xd5, 0xe4, 0xf6, 0x18, 0x04, 0xe1, 0x2a, + 0xda, 0xe6, 0xb4, 0xd1, 0x0b, 0x59, 0xf7, 0xb6, 0xc2, 0x91, 0xec, 0xaf, 0xbb, + 0x3b, 0xcb, 0x22, 0xfc, 0xf8, 0x18, 0xc4, 0xbd, 0x12, 0x81, 0xc0, 0xcd, 0xdf, + 0x09, 0xaa, 0x0d, 0x50, 0xe7, 0xe3, 0x10, 0x28, 0x25, 0x9f, 0xd7, 0xbc, 0xac, + 0x02, 0x3b, 0x00, 0xcd, 0x21, 0xee, 0xf3, 0xdc, 0x16, 0x10, 0xbb, 0x25, 0xae, + 0xe1, 0x22, 0xca, 0xfa, 0x95, 0xf1, 0xd6, 0x38, 0xd7, 0x9e, 0xd8, 0xc9, 0xe8, + 0xd9, 0x10, 0xd9, 0xdb, 0xd7, 0xeb, 0xa2, 0x59, 0x39, 0xd7, 0x08, 0xd7, 0xf1, + 0x9e, 0xef, 0x0c, 0xc6, 0xda, 0x17, 0xef, 0xd9, 0xec, 0xc0, 0x03, 0x09, 0x1e, + 0xea, 0xef, 0x63, 0xfb, 0xdd, 0x89, 0xdf, 0xaa, 0xf6, 0xec, 0x0a, 0x2e, 0x31, + 0xee, 0x2e, 0x90, 0xe8, 0x17, 0xd5, 0x52, 0xde, 0x29, 0xac, 0x0b, 0xfa, 0xf1, + 0xff, 0xb3, 0xb0, 0x01, 0xdf, 0x0f, 0x53, 0xa4, 0xea, 0xd0, 0xe0, 0xb0, 0xc7, + 0x22, 0xf4, 0x1b, 0x7f, 0xbd, 0xe5, 0xe4, 0x93, 0x16, 0xca, 0xf8, 0xb6, 0xee, + 0x01, 0x04, 0x07, 0xf7, 0x07, 0xfc, 0xe4, 0xd1, 0x00, 0xf8, 0xc2, 0xca, 0xfa, + 0x33, 0x03, 0xec, 0xd3, 0xd6, 0x03, 0x0c, 0xce, 0x0a, 0x15, 0xb8, 0xf1, 0x05, + 0xe9, 0x32, 0x95, 0xf0, 0x0c, 0xd8, 0x10, 0x00, 0xcd, 0xe0, 0xbe, 0xf9, 0x11, + 0xac, 0xba, 0xfc, 0x75, 0xe7, 0x27, 0xa8, 0x36, 0xbb, 0xf4, 0x35, 0x32, 0xfc, + 0xb4, 0xdc, 0x0b, 0x1c, 0x50, 0x0e, 0xad, 0xd4, 0xc1, 0xc7, 0xde, 0x05, 0xdc, + 0x41, 0x0e, 0xae, 0xfa, 0x09, 0xf0, 0x96, 0xe0, 0xc1, 0xd7, 0xc6, 0x00, 0x9d, + 0x05, 0xff, 0xec, 0x14, 0xce, 0xe4, 0x09, 0x17, 0x02, 0x04, 0xeb, 0x58, 0xee, + 0x0c, 0x15, 0x19, 0xd7, 0xb1, 0xcd, 0xea, 0x89, 0x8a, 0x12, 0xf5, 0x3c, 0x02, + 0x5b, 0xf8, 0xca, 0x06, 0xa6, 0xc5, 0xec, 0x11, 0xcd, 0x30, 0xe0, 0x04, 0x1e, + 0xf9, 0xc4, 0xe1, 0xae, 0xbe, 0x12, 0x1c, 0x03, 0xfc, 0xf0, 0xa2, 0x3a, 0xae, + 0x0c, 0x6e, 0x0a, 0xe1, 0xe5, 0xeb, 0xba, 0x31, 0xbe, 0x42, 0x27, 0xd5, 0x00, + 0xaa, 0xcc, 0x28, 0xcd, 0x05, 0x09, 0xd3, 0xd0, 0xf4, 0x07, 0xbe, 0x14, 0xf3, + 0x10, 0xf2, 0x18, 0x35, 0x1f, 0x42, 0xe0, 0xf1, 0xeb, 0xd2, 0x24, 0xfc, 0x01, + 0xc7, 0x47, 0x9e, 0x04, 0x17, 0x03, 0xf4, 0xab, 0xe6, 0x96, 0x78, 0xbb, 0xbd, + 0x16, 0xb3, 0x03, 0xca, 0xda, 0x07, 0x09, 0xc9, 0x13, 0xf7, 0x00, 0x14, 0xb8, + 0xc7, 0xee, 0x02, 0x1f, 0x1e, 0xc6, 0x88, 0xe2, 0x3c, 0xd9, 0xf9, 0xb5, 0xfe, + 0x9e, 0x04, 0xe4, 0x01, 0xf4, 0x46, 0x55, 0x0d, 0xe3, 0x22, 0x45, 0xf7, 0xb7, + 0xae, 0x0b, 0x49, 0xe7, 0x43, 0x24, 0x49, 0x3a, 0xd8, 0xd7, 0x49, 0x11, 0x06, + 0x15, 0x12, 0xec, 0x02, 0x4e, 0x61, 0x45, 0xf9, 0xe9, 0x1a, 0x0f, 0x0b, 0x98, + 0xf8, 0x4f, 0x22, 0x2d, 0x1b, 0xc7, 0xf4, 0x21, 0xa2, 0xe0, 0x7f, 0xda, 0xdc, + 0xa3, 0x2b, 0x33, 0xf9, 0x10, 0x1d, 0xe4, 0xc4, 0xd6, 0xb1, 0xd7, 0x05, 0xd7, + 0xa4, 0x1e, 0x42, 0xcc, 0xf2, 0xc6, 0xd4, 0xf3, 0xc2, 0x39, 0x91, 0x21, 0xf9, + 0xd4, 0x24, 0xe1, 0x16, 0xc4, 0xf3, 0xd4, 0xbc, 0xfe, 0x15, 0x11, 0x99, 0xee, + 0xd1, 0x0c, 0x17, 0xe0, 0x29, 0xe0, 0x2e, 0x5f, 0x4f, 0x27, 0xe7, 0x06, 0x36, + 0xcd, 0x41, 0xe4, 0x97, 0x18, 0x31, 0xf7, 0x23, 0x0a, 0x05, 0xfd, 0x9e, 0x17, + 0x27, 0x15, 0x03, 0x0d, 0x19, 0x1a, 0xe6, 0xf1, 0x0e, 0x2b, 0xce, 0xda, 0xc7, + 0xc2, 0xf8, 0xdc, 0xc0, 0xaa, 0x35, 0xb9, 0xba, 0xe4, 0xc2, 0x16, 0x1c, 0x38, + 0xc2, 0xc1, 0x09, 0x23, 0xf5, 0x0a, 0x0d, 0xf3, 0x0b, 0x05, 0x49, 0xdf, 0x05, + 0x0b, 0x22, 0x1d, 0x3f, 0xdd, 0x39, 0x61, 0xc8, 0xc5, 0x70, 0x18, 0xdb, 0x26, + 0x24, 0x8f, 0xbb, 0x5e, 0x47, 0x19, 0x0e, 0xbf, 0xe0, 0x1d, 0xc8, 0xdf, 0x1f, + 0xaf, 0x40, 0x3d, 0x42, 0x46, 0xfb, 0xb2, 0xfb, 0xe5, 0x90, 0x26, 0xe0, 0x19, + 0x3b, 0x13, 0x32, 0x15, 0x54, 0x15, 0xe5, 0xa6, 0x9d, 0xd3, 0xab, 0xc2, 0xf8, + 0xb4, 0x25, 0x10, 0x3a, 0xce, 0x23, 0xf4, 0xa1, 0xcf, 0xff, 0x0f, 0xf8, 0x10, + 0xd8, 0x72, 0x0e, 0xe5, 0xde, 0xd6, 0x0a, 0x32, 0xb8, 0x11, 0xec, 0x9f, 0x19, + 0x12, 0x07, 0xc1, 0x2a, 0xf6, 0x33, 0xc8, 0xfc, 0x0f, 0xf6, 0xf8, 0x19, 0x13, + 0x12, 0xfa, 0x01, 0xce, 0x26, 0xdb, 0x11, 0x1e, 0xbe, 0xe5, 0xd6, 0xdb, 0xfb, + 0xf8, 0x2b, 0x2a, 0x32, 0x34, 0xf4, 0xc5, 0x43, 0x18, 0x06, 0xcb, 0xd5, 0x13, + 0xe1, 0x1b, 0xff, 0x2d, 0x17, 0x0c, 0xee, 0xc0, 0xe0, 0x9c, 0xbe, 0x1d, 0x0c, + 0xff, 0x25, 0x52, 0xed, 0xf3, 0x3d, 0xec, 0xd3, 0x35, 0xe2, 0x0f, 0xcb, 0x52, + 0x0f, 0x1b, 0xd5, 0xee, 0x12, 0x41, 0xdf, 0xf7, 0x1d, 0xdc, 0xd9, 0xd5, 0xf8, + 0xfa, 0xfc, 0xe2, 0x26, 0xf8, 0xd1, 0x3b, 0xd1, 0xf0, 0x18, 0xe9, 0x2f, 0x37, + 0x07, 0xd8, 0xe2, 0xd9, 0x99, 0xdc, 0xf1, 0xec, 0xfc, 0xe3, 0x1b, 0xb5, 0x0c, + 0x2c, 0x34, 0xfb, 0x38, 0x26, 0xe6, 0xa7, 0xd8, 0xbd, 0xd9, 0xe8, 0xe6, 0x21, + 0x08, 0xfd, 0x18, 0x44, 0xf1, 0x0a, 0xae, 0xfd, 0xd6, 0x45, 0x0b, 0xcf, 0x12, + 0xf8, 0xdd, 0xf1, 0x28, 0xd5, 0x0c, 0xec, 0x19, 0x3d, 0xe7, 0xec, 0xf2, 0xf6, + 0xb0, 0x53, 0x1a, 0xe4, 0x20, 0x21, 0x35, 0xf0, 0xd6, 0xcb, 0x15, 0xdc, 0xd7, + 0xff, 0xf9, 0xe1, 0x9e, 0xf6, 0xbd, 0x08, 0xfe, 0xdb, 0xed, 0xd9, 0x10, 0x37, + 0xf1, 0xbf, 0xf6, 0x9a, 0xf0, 0xeb, 0x3a, 0xf8, 0x04, 0xc5, 0xe2, 0xb9, 0x05, + 0x2f, 0x29, 0x11, 0x1f, 0x15, 0xe8, 0x19, 0x0f, 0xd2, 0x18, 0xde, 0x7f, 0x03, + 0x0d, 0xf8, 0xdb, 0xe7, 0xe1, 0xe6, 0xd8, 0x08, 0xcc, 0xd9, 0x29, 0xef, 0xb4, + 0x03, 0x48, 0x29, 0x00, 0x05, 0x0c, 0xf0, 0x26, 0xfa, 0xfd, 0xcf, 0x0f, 0x19, + 0xeb, 0xb6, 0xdd, 0xd6, 0x27, 0x53, 0x13, 0xfa, 0x0a, 0xf4, 0xf8, 0x0b, 0x5f, + 0xfb, 0xcc, 0xe7, 0xb3, 0x21, 0xf9, 0x68, 0x08, 0x63, 0xb5, 0x2d, 0xd1, 0xea, + 0x22, 0xdd, 0x1b, 0x03, 0xe3, 0xcf, 0xa6, 0xe9, 0xd7, 0x1e, 0x0a, 0x1e, 0x3f, + 0xb8, 0x08, 0xca, 0xdb, 0x14, 0x06, 0x3b, 0x64, 0x27, 0x21, 0xcd, 0xb9, 0xf1, + 0x1f, 0xc4, 0x08, 0x05, 0xcf, 0xce, 0xbb, 0xf8, 0x8d, 0xb9, 0xec, 0x5b, 0x56, + 0x6f, 0x0b, 0xe0, 0xcd, 0x21, 0xb8, 0xe0, 0x10, 0xf8, 0xc7, 0x39, 0xea, 0x56, + 0xde, 0x36, 0xb3, 0xf7, 0xeb, 0xde, 0xde, 0x1d, 0xf2, 0x39, 0xd1, 0xb7, 0xf6, + 0xaa, 0x50, 0x01, 0xc8, 0x20, 0xcf, 0xd5, 0x98, 0xca, 0x08, 0xa1, 0xf0, 0x1a, + 0xc5, 0x1b, 0xdc, 0xde, 0x10, 0xce, 0x09, 0x05, 0xba, 0xa8, 0xf2, 0xdf, 0xd9, + 0xed, 0xc2, 0x1d, 0x17, 0xf3, 0xff, 0xca, 0x56, 0x5c, 0xf9, 0x14, 0x95, 0xdc, + 0x14, 0x02, 0x5f, 0x01, 0xc3, 0xf4, 0x42, 0xb1, 0x44, 0xc4, 0x9b, 0xb2, 0xfd, + 0xff, 0x01, 0x2c, 0x01, 0xbc, 0xb7, 0xa1, 0xd1, 0xee, 0x16, 0x2b, 0xe6, 0x50, + 0xef, 0xc8, 0x3b, 0xaa, 0xbb, 0x15, 0xfd, 0xde, 0xfc, 0xe0, 0xee, 0x0a, 0xed, + 0xf2, 0x44, 0x06, 0xab, 0x11, 0xee, 0xe8, 0x05, 0xdb, 0xeb, 0x27, 0xf9, 0xa9, + 0xd3, 0x08, 0xf7, 0x60, 0x3b, 0xf8, 0xe2, 0xe4, 0x07, 0xf4, 0xf7, 0x08, 0xf4, + 0x0c, 0x49, 0x1f, 0xb9, 0xef, 0xd0, 0xc4, 0x6f, 0x05, 0xc1, 0xbc, 0x0f, 0xc0, + 0xbe, 0x33, 0x3f, 0x81, 0xbf, 0xcf, 0xe3, 0x34, 0xd1, 0xfb, 0x2f, 0xe9, 0x28, + 0xe0, 0xf9, 0xba, 0x2c, 0x18, 0xe3, 0x23, 0xfc, 0xf2, 0xa8, 0x16, 0x90, 0x29, + 0xcd, 0x66, 0x0d, 0xd8, 0x21, 0xeb, 0xb5, 0xed, 0x1b, 0xad, 0xfa, 0x33, 0x1b, + 0x3b, 0x9c, 0xbd, 0x0e, 0x9f, 0x11, 0x06, 0xd0, 0xd8, 0xa2, 0x0d, 0xb3, 0x92, + 0xc8, 0x08, 0x22, 0xc4, 0x0a, 0xf9, 0x12, 0xe6, 0x25, 0xd3, 0x2b, 0xeb, 0xea, + 0xfa, 0xbe, 0x09, 0xf6, 0x30, 0x0f, 0xf3, 0x05, 0x18, 0x04, 0xee, 0xef, 0xee, + 0xbc, 0xf1, 0xc4, 0xe0, 0x0c, 0xf5, 0xfe, 0xf5, 0xee, 0xed, 0x05, 0xcd, 0x3e, + 0xd5, 0xd3, 0x15, 0xf1, 0xd7, 0x18, 0xb1, 0x0b, 0xe8, 0xff, 0xc4, 0x37, 0x10, + 0xd7, 0xba, 0xf2, 0x0d, 0xbb, 0xe8, 0x03, 0x36, 0x2e, 0x0d, 0xf0, 0xf3, 0x05, + 0xd8, 0xd1, 0xf0, 0x0f, 0xe4, 0x03, 0xc8, 0xf3, 0x06, 0xe8, 0xf3, 0x06, 0xf8, + 0x0a, 0xdf, 0xc8, 0xf9, 0xfb, 0xd3, 0xd6, 0xfa, 0xf0, 0xd4, 0x16, 0xcd, 0xf8, + 0x2d, 0xfd, 0xe0, 0xfa, 0xab, 0x14, 0xe6, 0x1e, 0xd6, 0x12, 0x32, 0xef, 0x04, + 0xf9, 0xd7, 0xec, 0xce, 0xf7, 0xc8, 0xfa, 0x01, 0x1e, 0x0b, 0x0e, 0xfc, 0xd5, + 0xe5, 0xf4, 0xd5, 0x0e, 0x06, 0xf4, 0xeb, 0xe2, 0xb8, 0xe4, 0xee, 0x0c, 0xd4, + 0xfe, 0xd0, 0xff, 0xe8, 0x10, 0x13, 0xc4, 0xad, 0xed, 0xf7, 0xea, 0xfc, 0xf2, + 0xf8, 0xfa, 0xf4, 0xd7, 0xf4, 0xea, 0xed, 0x22, 0x2c, 0xf8, 0xe9, 0xe5, 0x2e, + 0xda, 0x7f, 0x03, 0xf3, 0xef, 0xf3, 0xc2, 0xe4, 0x39, 0xf3, 0x07, 0x11, 0xc4, + 0xe0, 0xdd, 0x11, 0xe3, 0xf7, 0xe7, 0xf0, 0x1d, 0xf7, 0x11, 0xfb, 0x07, 0x1a, + 0x11, 0x05, 0x07, 0xf3, 0xd5, 0xdc, 0x2c, 0xfe, 0xe6, 0x23, 0xcb, 0x15, 0x09, + 0xc0, 0xc2, 0xdb, 0xe7, 0x1c, 0xea, 0xe0, 0x34, 0xfc, 0x11, 0x04, 0xfd, 0xf2, + 0x0e, 0xaa, 0xce, 0x10, 0x19, 0xe6, 0xff, 0xd4, 0xe1, 0xca, 0xdc, 0xcf, 0x2c, + 0xbc, 0x0d, 0xfe, 0xf6, 0xf1, 0x05, 0xfe, 0xed, 0x35, 0xd6, 0x13, 0x48, 0xdd, + 0x27, 0x0b, 0xdc, 0xfd, 0x0a, 0x23, 0x26, 0xfa, 0xfb, 0x13, 0xe9, 0xd2, 0x18, + 0xe4, 0x4f, 0xbb, 0xcc, 0x21, 0xe6, 0xf3, 0x22, 0x01, 0x04, 0x37, 0x04, 0x09, + 0x51, 0xc9, 0xb5, 0xe3, 0x0b, 0x30, 0xf2, 0x13, 0xf4, 0xe8, 0x13, 0x01, 0xc4, + 0xfe, 0xfc, 0x43, 0x52, 0xcf, 0x20, 0xde, 0xfd, 0xc4, 0xc4, 0xf6, 0xb3, 0x3a, + 0xd9, 0xd7, 0xea, 0xf0, 0xef, 0xed, 0x0b, 0x1c, 0xcf, 0x7f, 0x43, 0x30, 0x25, + 0x3e, 0xce, 0x11, 0xf7, 0xda, 0xce, 0xf5, 0x0d, 0x15, 0x10, 0x0e, 0x1f, 0xfe, + 0x45, 0xd3, 0x26, 0xfb, 0x1f, 0xfc, 0x29, 0x31, 0xf3, 0x17, 0xf9, 0xe4, 0xce, + 0x37, 0x15, 0x07, 0xf0, 0xe2, 0x2e, 0x0a, 0x4f, 0xc7, 0x51, 0xcf, 0xe9, 0xc3, + 0xe2, 0xea, 0x12, 0xea, 0x27, 0xb1, 0xe6, 0x30, 0xe6, 0xd8, 0x09, 0xd9, 0xf5, + 0x07, 0x13, 0xf7, 0xf8, 0xfc, 0xc7, 0x19, 0xf8, 0xe6, 0xd2, 0x00, 0xe0, 0x33, + 0x09, 0x05, 0x13, 0xfa, 0x00, 0xfc, 0x06, 0xad, 0xcc, 0xf8, 0x38, 0x05, 0x05, + 0x35, 0xed, 0x1a, 0x1c, 0xea, 0x15, 0xec, 0xec, 0x04, 0xee, 0xca, 0x17, 0xe9, + 0xf6, 0x3f, 0xf6, 0xde, 0xd5, 0x25, 0x1a, 0x0c, 0x1a, 0xea, 0xd7, 0xd7, 0xdd, + 0x23, 0xf8, 0xaf, 0x07, 0xfa, 0xbb, 0x29, 0x35, 0xd5, 0x02, 0xd0, 0x02, 0xff, + 0xd2, 0x14, 0xc5, 0x4d, 0x1e, 0xe7, 0xe0, 0x1d, 0xc0, 0xfd, 0xd3, 0xcd, 0x4d, + 0x23, 0xca, 0x49, 0x07, 0xff, 0x6f, 0x06, 0x39, 0xdf, 0x17, 0x1d, 0xc5, 0x04, + 0xf1, 0xee, 0xe4, 0xee, 0xfd, 0x05, 0xe9, 0x19, 0x26, 0x17, 0x13, 0xc5, 0xf9, + 0x2c, 0x06, 0x26, 0xea, 0x0c, 0xea, 0x13, 0xb3, 0xb2, 0xdb, 0x0e, 0x09, 0x19, + 0xf7, 0xff, 0x0a, 0xe9, 0x30, 0xdf, 0x20, 0xca, 0xd9, 0xf8, 0x02, 0x0d, 0xd1, + 0xec, 0xf0, 0x11, 0xf3, 0xf8, 0xd6, 0xe6, 0xf6, 0xd4, 0x08, 0x0a, 0xfa, 0xdb, + 0x00, 0x59, 0xdf, 0xef, 0x0a, 0xf8, 0x00, 0xee, 0xea, 0xfe, 0xc0, 0xed, 0x01, + 0xd9, 0x1e, 0x0e, 0x41, 0x20, 0x23, 0x18, 0xfb, 0x1f, 0xf1, 0x11, 0xf4, 0xf2, + 0x34, 0xed, 0xdf, 0xf4, 0xe0, 0xfc, 0xde, 0xff, 0x26, 0xd6, 0xc3, 0x14, 0xdf, + 0xfa, 0xcc, 0xda, 0xdd, 0x12, 0xee, 0x03, 0x02, 0xd0, 0xdb, 0x2d, 0xdb, 0xda, + 0xf3, 0xf8, 0xd4, 0x27, 0xbc, 0xdf, 0x06, 0xf6, 0xff, 0x1b, 0x00, 0xd2, 0x06, + 0x10, 0xfd, 0xfd, 0xeb, 0xff, 0xe9, 0xe5, 0xdd, 0x03, 0xdc, 0x06, 0x3f, 0x45, + 0xfe, 0x08, 0x20, 0x24, 0x2f, 0x1e, 0xf3, 0xf3, 0xc2, 0x20, 0xd0, 0xfc, 0xed, + 0xbf, 0x03, 0xfb, 0xee, 0x04, 0x18, 0xd9, 0xd2, 0x1b, 0xe2, 0xdd, 0xfe, 0xdb, + 0x21, 0x2a, 0xe6, 0xf7, 0x07, 0xd4, 0x04, 0xe3, 0x27, 0x27, 0xdc, 0x03, 0xc8, + 0xed, 0xe0, 0x1b, 0xf7, 0x34, 0xc8, 0xe5, 0xc3, 0x1d, 0xfb, 0x08, 0xeb, 0xd5, + 0xe6, 0x21, 0x11, 0x21, 0xed, 0x2a, 0xc7, 0xd8, 0xe1, 0xfe, 0x0a, 0xe5, 0xb9, + 0x10, 0xff, 0x23, 0x1b, 0xb1, 0xf4, 0xe3, 0xf2, 0x11, 0xe7, 0xd4, 0x0d, 0xfe, + 0x00, 0x21, 0xd6, 0xdd, 0x03, 0xe5, 0xf0, 0x11, 0xf7, 0xed, 0xe1, 0xfc, 0x0c, + 0x09, 0xa9, 0xdf, 0xed, 0xdc, 0xf2, 0xb8, 0xfc, 0xf2, 0x06, 0x3a, 0x32, 0x1f, + 0xfb, 0xac, 0xe0, 0xec, 0x01, 0x2f, 0xdd, 0xcd, 0x0e, 0xcc, 0x16, 0x2f, 0x20, + 0x2e, 0x03, 0xf4, 0x1f, 0xdf, 0xbf, 0xd8, 0x14, 0x0a, 0x0b, 0xe4, 0xf8, 0xec, + 0xd7, 0xe2, 0xe0, 0xe6, 0xfa, 0xf6, 0xcd, 0xf9, 0xd5, 0xcc, 0xe2, 0xfd, 0x16, + 0xf9, 0xea, 0x0c, 0xc6, 0xcc, 0x26, 0xd3, 0xec, 0xea, 0xed, 0x08, 0xe2, 0xee, + 0xe4, 0x00, 0xe2, 0xfa, 0xe1, 0x0e, 0x0d, 0xfe, 0x29, 0xc9, 0x1d, 0x1d, 0x0d, + 0xfb, 0x26, 0xfd, 0x0e, 0x22, 0xf4, 0xe8, 0xc3, 0x5d, 0xe4, 0xff, 0x7f, 0x2f, + 0x20, 0xee, 0xc8, 0xe7, 0xf7, 0xcc, 0x0b, 0xe3, 0x0f, 0xa5, 0xd0, 0xcd, 0x08, + 0xe6, 0xff, 0xc7, 0x01, 0x12, 0xe8, 0xe2, 0xd6, 0xf2, 0xfc, 0xf2, 0x06, 0xf1, + 0xa2, 0xfa, 0xc7, 0xd5, 0xdd, 0xc9, 0xcb, 0xe5, 0xe5, 0xd2, 0xfb, 0xf0, 0x00, + 0xe0, 0xfc, 0x04, 0xf4, 0xd6, 0x40, 0x1a, 0xa2, 0xee, 0xe7, 0x15, 0xd4, 0x16, + 0xdd, 0xf8, 0x00, 0xd0, 0xe2, 0x3c, 0xec, 0xe4, 0xe3, 0xde, 0xf4, 0x04, 0xc3, + 0xd7, 0x11, 0x28, 0xed, 0xd2, 0xa6, 0xe1, 0x21, 0xe7, 0xf3, 0x3a, 0x07, 0x1e, + 0x72, 0x38, 0x09, 0xea, 0xf0, 0xf4, 0x08, 0xf2, 0xd4, 0x01, 0xcf, 0x1a, 0xd1, + 0xfb, 0x3e, 0xc6, 0xf1, 0x30, 0xe4, 0xeb, 0x38, 0xb3, 0xf7, 0x18, 0xd7, 0xe6, + 0xf6, 0x19, 0xfe, 0x04, 0xc5, 0x2f, 0xf6, 0xf2, 0xe5, 0xe4, 0xca, 0x08, 0xfd, + 0x5f, 0xbf, 0x09, 0xb3, 0xfc, 0xea, 0xcf, 0xc7, 0xe0, 0xac, 0x2f, 0x1c, 0x36, + 0x20, 0xf6, 0xb2, 0xc2, 0xa2, 0x0d, 0x05, 0xdf, 0xc3, 0x1f, 0xc9, 0xf3, 0xfa, + 0xb7, 0x3b, 0x05, 0x19, 0xb1, 0xf2, 0xe6, 0xf5, 0x07, 0x1d, 0xeb, 0xc0, 0xa6, + 0xb5, 0xea, 0xd9, 0xf7, 0xf0, 0xf9, 0x05, 0xf6, 0xff, 0x2d, 0xf2, 0xc9, 0x02, + 0xd3, 0x03, 0xbb, 0xb2, 0xe2, 0xe0, 0x38, 0x40, 0xcd, 0xf7, 0xda, 0x20, 0xd4, + 0x26, 0x0d, 0x32, 0xb4, 0x13, 0xbb, 0x19, 0x6f, 0xf6, 0xe7, 0xbf, 0xe1, 0x19, + 0xaf, 0x14, 0xc5, 0x3c, 0xfd, 0xdd, 0xf7, 0xef, 0xcc, 0x08, 0xce, 0xd4, 0xf5, + 0x04, 0xc2, 0xc9, 0x02, 0xaa, 0xc3, 0xb3, 0xc6, 0x19, 0xfe, 0x0f, 0x28, 0xe4, + 0x81, 0x13, 0x17, 0xf8, 0xbd, 0x14, 0x08, 0x2d, 0xfb, 0x3d, 0xf7, 0x07, 0x0f, + 0x12, 0xe5, 0xda, 0xcb, 0x41, 0xda, 0x2b, 0xf4, 0x19, 0xcd, 0x2d, 0x38, 0x10, + 0x19, 0x2a, 0x16, 0xd1, 0xdd, 0xda, 0xd7, 0x23, 0x13, 0x0c, 0xe6, 0xda, 0x93, + 0xe3, 0xc2, 0xcd, 0xe1, 0xe4, 0xe8, 0xe8, 0x07, 0xf6, 0x19, 0x0c, 0xd1, 0x14, + 0x09, 0xd8, 0xc4, 0x20, 0x0d, 0xc6, 0x0b, 0xcf, 0x00, 0x00, 0xfc, 0xea, 0xde, + 0xaa, 0x0f, 0x0d, 0x19, 0x95, 0xe7, 0x44, 0xb3, 0x2c, 0xcc, 0x38, 0x39, 0xdc, + 0xc1, 0xe0, 0x1f, 0xd7, 0xd0, 0x07, 0xbc, 0x30, 0x3f, 0x0a, 0xde, 0xea, 0xe7, + 0xf1, 0xc2, 0xf2, 0x1c, 0xb2, 0xee, 0xee, 0xb0, 0xea, 0xdc, 0xcf, 0x95, 0x17, + 0xe8, 0x4f, 0xce, 0x49, 0xb9, 0xdd, 0x0f, 0xe9, 0x02, 0x32, 0xa9, 0xf0, 0xe8, + 0x19, 0x32, 0x10, 0xfa, 0x09, 0xbd, 0xd4, 0x01, 0x1d, 0xf8, 0x23, 0xec, 0xde, + 0xae, 0xe8, 0xd3, 0x14, 0xe4, 0x31, 0xfd, 0x56, 0xeb, 0xb9, 0x03, 0x06, 0xeb, + 0x32, 0xd8, 0xe5, 0x1f, 0x35, 0x53, 0xfe, 0xda, 0x0c, 0xb1, 0xdb, 0xc1, 0xcd, + 0x53, 0xe6, 0x16, 0xfb, 0xf3, 0xd7, 0xde, 0x01, 0xc8, 0xef, 0x23, 0x2e, 0xda, + 0xdf, 0xc0, 0xc9, 0xe4, 0xf0, 0xe1, 0xcb, 0xe7, 0x7f, 0xf5, 0xe8, 0xe2, 0x14, + 0x17, 0x2f, 0xe1, 0xda, 0xcb, 0xa2, 0x2d, 0x0b, 0xfb, 0xee, 0x10, 0x20, 0xf6, + 0x0f, 0x15, 0xfd, 0x11, 0xd4, 0x50, 0xec, 0xfb, 0xf7, 0xd8, 0xb3, 0xe6, 0xe2, + 0xbe, 0x3a, 0x32, 0xf1, 0xf2, 0x36, 0xc3, 0xaa, 0x27, 0xf9, 0x31, 0x41, 0xf6, + 0xd7, 0x0d, 0x07, 0xc8, 0xee, 0xfc, 0x13, 0x00, 0xeb, 0x1c, 0xe5, 0x08, 0x1f, + 0x17, 0xf7, 0xf1, 0xee, 0xe2, 0x1a, 0xf9, 0xcc, 0xec, 0x95, 0x26, 0xee, 0x03, + 0xf1, 0xbf, 0x0e, 0x1c, 0x46, 0xf6, 0x16, 0x1c, 0xf6, 0xd4, 0x1a, 0xfa, 0xef, + 0x0d, 0x44, 0xe4, 0x3e, 0x6d, 0x3f, 0x1c, 0x43, 0xd8, 0xfd, 0x3a, 0xcb, 0xe8, + 0x06, 0xfc, 0xf6, 0x07, 0x3f, 0xfa, 0xef, 0xc1, 0xb7, 0xfd, 0x0b, 0x3c, 0x0f, + 0xe1, 0x0b, 0xe1, 0xef, 0x9b, 0xd3, 0x95, 0x1d, 0xf3, 0xf5, 0xf1, 0xff, 0x16, + 0x02, 0xf4, 0x15, 0xf5, 0xa6, 0xd5, 0xf6, 0x03, 0x1c, 0x3a, 0xfd, 0xe0, 0x05, + 0xff, 0x0e, 0xda, 0xce, 0xc0, 0xdd, 0xcd, 0xe2, 0xdf, 0xba, 0x14, 0xc7, 0xf9, + 0xf8, 0x12, 0xfd, 0xe3, 0x31, 0xe5, 0x8e, 0xfb, 0x07, 0xf0, 0xf9, 0xf3, 0xd5, + 0xd5, 0x08, 0xa6, 0x01, 0x11, 0x33, 0x23, 0x24, 0x45, 0x4e, 0x3a, 0x0d, 0x20, + 0xd7, 0x1e, 0x39, 0x19, 0xd7, 0xfd, 0xa0, 0xc6, 0xe5, 0xe7, 0xd3, 0xba, 0x11, + 0xfc, 0x2a, 0xfe, 0x19, 0xf0, 0xcb, 0xce, 0xe1, 0xdd, 0x35, 0x0c, 0x3c, 0xf2, + 0xf9, 0x07, 0x17, 0xc1, 0xf9, 0xd5, 0x06, 0x11, 0x87, 0xf1, 0x0d, 0x0d, 0xee, + 0xf1, 0xdb, 0xa5, 0x12, 0xe6, 0xd2, 0x29, 0x37, 0xd9, 0xe4, 0xcb, 0x38, 0xc4, + 0x2a, 0x14, 0xbf, 0xc2, 0x2b, 0x0e, 0xe6, 0xda, 0xd7, 0xce, 0xf6, 0xf7, 0x39, + 0x1d, 0xfb, 0x01, 0xfe, 0xe9, 0xb2, 0xde, 0x99, 0xfb, 0x38, 0x24, 0xbc, 0xe9, + 0xd6, 0xc8, 0x1f, 0xbb, 0x55, 0xfc, 0xe2, 0xdc, 0x33, 0xde, 0x01, 0x08, 0x0e, + 0x19, 0xe9, 0x20, 0x33, 0xfb, 0x9b, 0xdd, 0x0c, 0xbb, 0xf2, 0xc6, 0x1d, 0xbc, + 0x16, 0x1a, 0xd9, 0xc6, 0x81, 0x35, 0xfd, 0xe8, 0x1e, 0x25, 0xbb, 0x27, 0xd0, + 0x16, 0xe4, 0xd9, 0x39, 0xad, 0xa0, 0xd3, 0xe1, 0x20, 0xfa, 0x01, 0xee, 0x08, + 0xdb, 0xdc, 0x6a, 0x2f, 0xc1, 0x43, 0xf0, 0x01, 0x07, 0xb1, 0xc6, 0xa7, 0x32, + 0x02, 0xcf, 0x20, 0x06, 0x48, 0x28, 0x11, 0xc4, 0xec, 0x6b, 0xd0, 0x14, 0xee, + 0x6a, 0x26, 0xd7, 0xf2, 0x46, 0xff, 0x29, 0xa5, 0xdf, 0xe1, 0xdc, 0xd6, 0x11, + 0xd8, 0x08, 0xe9, 0xf2, 0x0e, 0xdc, 0x89, 0xdf, 0xe6, 0x14, 0xec, 0x3a, 0x10, + 0x3e, 0xed, 0xe2, 0x20, 0x3e, 0x13, 0xf9, 0xba, 0xfe, 0xd7, 0xca, 0xf2, 0x44, + 0x1f, 0x04, 0x14, 0xc1, 0xfb, 0x0b, 0xf2, 0x66, 0xc8, 0xf8, 0x45, 0x0b, 0x36, + 0x1b, 0xd1, 0x28, 0x1c, 0x00, 0x0b, 0x14, 0xb5, 0xfa, 0xd3, 0xf6, 0x2a, 0xd4, + 0xcc, 0xc9, 0xaf, 0xd8, 0xca, 0x06, 0x26, 0x02, 0xd1, 0xde, 0xc5, 0x02, 0xc0, + 0xf0, 0x1d, 0x32, 0x31, 0xd4, 0x2f, 0xf9, 0xf3, 0xe2, 0x1f, 0x97, 0xb8, 0x1d, + 0xc4, 0x2d, 0xfe, 0xbe, 0xfa, 0xce, 0xd8, 0x15, 0xea, 0xbd, 0xda, 0x56, 0xd7, + 0x09, 0xca, 0x23, 0x14, 0xbf, 0x5c, 0x52, 0x1b, 0x3b, 0xe4, 0x19, 0xf1, 0xec, + 0x15, 0xfb, 0xa7, 0xb7, 0xe2, 0xdf, 0xd8, 0xe8, 0x23, 0x2a, 0x1d, 0x04, 0x1b, + 0x20, 0xf0, 0xf3, 0x83, 0x2e, 0xdb, 0xf6, 0x99, 0xfd, 0x33, 0x09, 0xf1, 0x3b, + 0xfd, 0x20, 0xd7, 0x96, 0x04, 0x01, 0x2b, 0xd1, 0x0b, 0x32, 0x4b, 0x29, 0x20, + 0xfa, 0x0e, 0xcd, 0xdd, 0x4c, 0xae, 0x00, 0xaf, 0x0b, 0xf5, 0xe5, 0x03, 0xdb, + 0x99, 0xc5, 0xe6, 0xf5, 0x81, 0xe7, 0x0b, 0x11, 0xc2, 0x1f, 0xf6, 0xfb, 0x2f, + 0x47, 0x40, 0xff, 0x1f, 0xfe, 0xdc, 0xc6, 0xc5, 0xed, 0x04, 0x1e, 0x27, 0x12, + 0xc3, 0x2f, 0x1d, 0x23, 0xfe, 0xed, 0x41, 0x3f, 0xfb, 0x09, 0xf8, 0xf1, 0xf4, + 0xff, 0xc7, 0xc5, 0x1b, 0xdb, 0x01, 0x8c, 0x0e, 0xf2, 0x36, 0xf3, 0xfc, 0xcd, + 0xd2, 0xfb, 0x0a, 0x15, 0x46, 0x25, 0x03, 0xfe, 0xeb, 0xca, 0xba, 0x11, 0x19, + 0xec, 0xba, 0x04, 0xba, 0x25, 0xef, 0x1c, 0xfb, 0x09, 0x0e, 0x22, 0x1e, 0xda, + 0x01, 0xf9, 0x36, 0xec, 0x24, 0xbd, 0xed, 0x10, 0xee, 0x19, 0xb7, 0xa8, 0xf2, + 0xe0, 0x9a, 0x12, 0xdb, 0xb9, 0xf9, 0xbd, 0xc8, 0x10, 0x24, 0x06, 0x8f, 0xeb, + 0x0c, 0x19, 0xd9, 0x0a, 0x8f, 0xd7, 0xc1, 0x0a, 0xd9, 0x43, 0x0d, 0xb6, 0x03, + 0xe5, 0x09, 0x2e, 0xfd, 0xdc, 0xd1, 0xf9, 0xa1, 0xd7, 0x10, 0xc0, 0xf8, 0x0f, + 0xe2, 0x15, 0x30, 0x15, 0x25, 0xed, 0xf7, 0x1e, 0x2a, 0xb3, 0xdb, 0x48, 0x21, + 0x01, 0xf0, 0x04, 0xc1, 0x05, 0xfd, 0x20, 0xd4, 0xe4, 0x04, 0xc3, 0x01, 0xde, + 0xe2, 0xe0, 0x03, 0xef, 0xd2, 0x22, 0x0d, 0x29, 0xfb, 0xca, 0xf1, 0xe5, 0x11, + 0x07, 0xe3, 0xe3, 0xe9, 0x3a, 0xad, 0x06, 0x13, 0xfc, 0xca, 0x39, 0xd0, 0xf2, + 0xf4, 0x0f, 0x0f, 0x1d, 0xd4, 0xf5, 0xd4, 0x1c, 0xc5, 0x2f, 0x0f, 0xdd, 0x01, + 0x0b, 0xc7, 0xfd, 0xfe, 0x20, 0x24, 0x24, 0x2d, 0xe8, 0x13, 0x1f, 0x1a, 0xfa, + 0xfc, 0x11, 0xe9, 0x25, 0x07, 0x05, 0xf9, 0xea, 0x11, 0xd4, 0xac, 0x17, 0x07, + 0x26, 0x04, 0xf9, 0xc0, 0xe1, 0xf9, 0x00, 0xc3, 0x04, 0xc1, 0xfb, 0x25, 0xe3, + 0xf6, 0x1b, 0xf0, 0x12, 0xf1, 0xf8, 0xd0, 0xf1, 0x1b, 0xe2, 0x08, 0x32, 0xf1, + 0x15, 0xf2, 0xb8, 0xe4, 0xe3, 0x12, 0xef, 0xd2, 0xd9, 0xdc, 0xf4, 0xbe, 0x1d, + 0x08, 0x19, 0x13, 0xdc, 0xd0, 0x20, 0xf5, 0xdc, 0xd9, 0x29, 0xeb, 0xee, 0xc8, + 0x1b, 0xb3, 0x0b, 0x0c, 0xda, 0xd8, 0x20, 0xfa, 0xc8, 0xeb, 0x0e, 0x1d, 0xe8, + 0xd8, 0xd0, 0x20, 0x2b, 0xf4, 0x31, 0x19, 0x22, 0xce, 0x1d, 0x23, 0xed, 0xe7, + 0x1a, 0xcb, 0xd6, 0xe0, 0xea, 0x09, 0x0b, 0xbd, 0xf3, 0x09, 0xd0, 0x07, 0xd5, + 0x16, 0xf1, 0xfa, 0xfa, 0x09, 0xce, 0xf0, 0x1b, 0xe9, 0x43, 0xf8, 0xe5, 0xfd, + 0x05, 0xdd, 0x31, 0xfa, 0x0d, 0x16, 0x08, 0xfa, 0xd0, 0x06, 0x49, 0xcd, 0xf3, + 0xd1, 0x06, 0xf4, 0xf5, 0xf2, 0x25, 0xef, 0x03, 0x32, 0x45, 0x96, 0x22, 0x24, + 0x08, 0xe8, 0x37, 0xb6, 0x06, 0x1f, 0xda, 0xf3, 0xd8, 0xc9, 0x0d, 0xd5, 0xcb, + 0xac, 0xdd, 0x01, 0x09, 0x09, 0x12, 0x19, 0xba, 0xfa, 0x09, 0xd8, 0x11, 0x04, + 0x16, 0xec, 0x25, 0xf0, 0xe2, 0x30, 0x04, 0xeb, 0x0b, 0xfc, 0xd8, 0xec, 0x05, + 0x10, 0xf4, 0x01, 0x0f, 0x08, 0x06, 0xfd, 0xf6, 0x7f, 0x10, 0xf2, 0xf8, 0xd9, + 0x0e, 0x04, 0x1b, 0x1c, 0xfa, 0x1e, 0xc6, 0xf0, 0xa6, 0x0f, 0x2d, 0xdb, 0xc3, + 0x5c, 0xb3, 0xf0, 0xcd, 0x31, 0x68, 0x04, 0xee, 0x1b, 0xe0, 0x01, 0xfc, 0x16, + 0xe6, 0xf7, 0xf8, 0x2d, 0xaa, 0xfa, 0xe2, 0x07, 0x02, 0xc3, 0xdf, 0xd1, 0xe6, + 0x23, 0xe4, 0x01, 0x00, 0x36, 0xa5, 0x03, 0xdc, 0xd2, 0xc5, 0xda, 0xe0, 0xca, + 0xf3, 0xba, 0xee, 0xf9, 0xec, 0x41, 0x55, 0x38, 0x00, 0x01, 0x9b, 0x17, 0xbd, + 0x41, 0x08, 0xde, 0xbc, 0x26, 0x31, 0xef, 0xf9, 0xda, 0x0b, 0x32, 0xcf, 0xd9, + 0x08, 0xd6, 0x0e, 0x56, 0x21, 0x2d, 0x28, 0xec, 0x01, 0x0a, 0xc1, 0x71, 0xf6, + 0x23, 0xf7, 0xe3, 0x04, 0xe2, 0xf7, 0x23, 0x81, 0xd4, 0x0b, 0xf5, 0x0e, 0x33, + 0xae, 0xed, 0x0e, 0xe5, 0xfd, 0x2d, 0x2f, 0x26, 0xb3, 0xe8, 0xd0, 0xf6, 0xd2, + 0xf9, 0xc8, 0xe5, 0xec, 0x12, 0xd3, 0xe9, 0x09, 0xf0, 0x16, 0x02, 0x9f, 0xee, + 0x05, 0xe2, 0x08, 0x03, 0xbe, 0xce, 0xc6, 0x61, 0x0b, 0x0e, 0x0e, 0x07, 0x13, + 0x2b, 0x13, 0xdf, 0xe8, 0x9d, 0x07, 0xb8, 0x0d, 0x9b, 0xec, 0xbe, 0xd4, 0x51, + 0x21, 0x15, 0xb9, 0xec, 0x08, 0xa3, 0xfc, 0x54, 0x2b, 0xed, 0xed, 0x0f, 0xec, + 0x13, 0xfe, 0x03, 0xe9, 0xdb, 0x3a, 0xaf, 0xad, 0xde, 0x42, 0xfb, 0xff, 0xe6, + 0x07, 0x48, 0xf8, 0xeb, 0xdb, 0xd1, 0x20, 0xe8, 0xaf, 0x3e, 0xad, 0xe4, 0xed, + 0xe8, 0xf1, 0xea, 0xf8, 0x06, 0xfe, 0xb4, 0x2b, 0xb9, 0xe6, 0x06, 0xf8, 0xd6, + 0xd7, 0xf7, 0xf4, 0xf0, 0x11, 0x0a, 0xf5, 0x1c, 0xe4, 0xd4, 0xde, 0x9a, 0x1e, + 0xf5, 0x30, 0xca, 0x26, 0xec, 0xd1, 0x07, 0x05, 0xdf, 0xb8, 0x0f, 0xd5, 0xc2, + 0x1d, 0x26, 0xe2, 0xc9, 0xbc, 0xc9, 0x89, 0xe3, 0xb5, 0xfb, 0x16, 0x98, 0xdb, + 0xc8, 0xd1, 0xf0, 0x06, 0x97, 0x27, 0x0d, 0x0b, 0x1d, 0xfb, 0xfd, 0x1f, 0x11, + 0x44, 0xd7, 0xce, 0x00, 0x39, 0xe4, 0xf3, 0x15, 0x13, 0xf8, 0x1c, 0xd7, 0x0b, + 0xf0, 0xf2, 0x25, 0x0b, 0xe6, 0x07, 0xf1, 0xe6, 0xf3, 0x02, 0x00, 0x25, 0xe5, + 0xfd, 0x23, 0x14, 0xd3, 0x0a, 0xe5, 0x05, 0x13, 0x43, 0xe3, 0xee, 0xe2, 0xe6, + 0xf5, 0xf9, 0xfd, 0x24, 0xd2, 0x20, 0x29, 0xde, 0x0b, 0xfa, 0x10, 0xd8, 0xe4, + 0xfa, 0xd3, 0x05, 0xf3, 0x24, 0xdc, 0x02, 0xe8, 0xe8, 0xf0, 0xf0, 0x2c, 0xdb, + 0xd9, 0x1c, 0xf2, 0xfc, 0xf0, 0x08, 0x17, 0xf4, 0xe0, 0xeb, 0x0f, 0xe9, 0xff, + 0x0a, 0xfb, 0xf7, 0xe7, 0x05, 0x0e, 0x10, 0x05, 0x2c, 0x06, 0xd9, 0x08, 0x02, + 0x0c, 0x35, 0x08, 0x17, 0xf6, 0xf8, 0x08, 0x17, 0xdf, 0xef, 0xfb, 0x0d, 0xb6, + 0xc1, 0x01, 0x35, 0xf5, 0xd2, 0xfe, 0xe2, 0x1c, 0xfb, 0xe1, 0xe7, 0x16, 0x0b, + 0x0b, 0xeb, 0x1a, 0x15, 0xd0, 0x00, 0xdd, 0x24, 0xf4, 0xf8, 0xed, 0x29, 0xf5, + 0x19, 0x09, 0x0e, 0xe8, 0xef, 0x1d, 0xf1, 0xdd, 0xe3, 0xd1, 0x6b, 0xf1, 0xf4, + 0x09, 0xf5, 0x1d, 0x57, 0xd9, 0x7f, 0x04, 0x15, 0xf9, 0x0a, 0xdb, 0xd4, 0xea, + 0xc7, 0xf6, 0x07, 0x06, 0xde, 0xfe, 0xed, 0x12, 0xf2, 0x6f, 0x14, 0xf6, 0xca, + 0x05, 0xdf, 0x1e, 0x17, 0x07, 0xe7, 0xf8, 0xd6, 0xf3, 0xed, 0x11, 0xd2, 0x22, + 0x1a, 0x1f, 0xf2, 0xf3, 0xe2, 0x0f, 0x11, 0xea, 0xfa, 0x6f, 0xeb, 0xec, 0xf5, + 0xee, 0x02, 0xd7, 0xfe, 0xc7, 0x19, 0xf1, 0x0e, 0x03, 0x05, 0xfc, 0xd7, 0xc6, + 0xf5, 0x07, 0x44, 0xf7, 0x02, 0x0e, 0xfc, 0x17, 0xe2, 0xf0, 0x1b, 0xf9, 0xf5, + 0xe6, 0xf8, 0xea, 0xf2, 0x0d, 0x19, 0x04, 0x1a, 0xed, 0x0f, 0xe8, 0xdc, 0xd9, + 0xfc, 0x0c, 0xf6, 0xf7, 0x19, 0x5d, 0xf0, 0x1d, 0x4e, 0x1f, 0x18, 0xe4, 0xd5, + 0x14, 0xf9, 0xf7, 0xf1, 0xab, 0x6b, 0xd7, 0x0c, 0xfe, 0xfa, 0xc0, 0x9d, 0xca, + 0x07, 0xd8, 0x1f, 0xf3, 0xfa, 0x09, 0xba, 0xdd, 0x09, 0x1e, 0x18, 0x0d, 0xf4, + 0x30, 0x39, 0xef, 0xf6, 0xf8, 0xd6, 0x2b, 0xd5, 0xf6, 0xb8, 0xdb, 0x0e, 0xd2, + 0xf6, 0x4a, 0xf9, 0x19, 0x06, 0xf1, 0xaa, 0xee, 0xc6, 0xdc, 0x21, 0x13, 0x5b, + 0x3d, 0x23, 0xc4, 0x30, 0x1f, 0x3d, 0x41, 0x06, 0xea, 0xe2, 0x17, 0x20, 0xd6, + 0xef, 0x81, 0x13, 0x1d, 0x1b, 0x01, 0xce, 0xf7, 0xf1, 0x43, 0x2d, 0x00, 0xe6, + 0x1d, 0xc3, 0xed, 0x07, 0xd3, 0x0b, 0x2d, 0xef, 0xed, 0x1b, 0xe7, 0x30, 0xc8, + 0xd3, 0xf2, 0x08, 0x03, 0xb7, 0xec, 0xdc, 0x1c, 0xb0, 0xcc, 0x56, 0x22, 0x48, + 0xaa, 0x07, 0xe5, 0xe2, 0x0a, 0x07, 0xf8, 0xbe, 0x3c, 0xe1, 0x25, 0xc4, 0x34, + 0xef, 0xa6, 0x1e, 0xfd, 0xba, 0xaf, 0x05, 0xda, 0x3b, 0xef, 0xba, 0x02, 0xd8, + 0x14, 0x31, 0x15, 0x00, 0x08, 0xba, 0xf6, 0xe7, 0xff, 0x32, 0x31, 0xd4, 0x1b, + 0xf0, 0x08, 0x1f, 0x9c, 0xf9, 0x1c, 0xde, 0xdf, 0x0d, 0xe0, 0xe8, 0x47, 0xd8, + 0x22, 0x04, 0x09, 0xec, 0xfc, 0x0b, 0x14, 0xc8, 0xed, 0xe8, 0xd2, 0xb2, 0xa9, + 0x15, 0xea, 0xf0, 0x13, 0xfd, 0xff, 0xf0, 0xda, 0xf9, 0xf2, 0x0f, 0x10, 0xfc, + 0x11, 0xf5, 0x16, 0x3f, 0x01, 0x01, 0x19, 0x22, 0x38, 0x02, 0xbb, 0xf6, 0x13, + 0x4a, 0x23, 0x17, 0x11, 0x40, 0xd2, 0xcb, 0x19, 0x0b, 0xfb, 0xf0, 0xef, 0x30, + 0x1d, 0x1b, 0xca, 0xde, 0x22, 0xeb, 0x02, 0x17, 0xc0, 0xb0, 0x21, 0x07, 0x2f, + 0x00, 0xe5, 0xb2, 0xed, 0x83, 0x20, 0xdb, 0x41, 0x04, 0x0a, 0xee, 0xc8, 0xe7, + 0x09, 0xf8, 0xf4, 0x10, 0x30, 0xda, 0x0a, 0x14, 0xfa, 0xbf, 0xf9, 0xce, 0x15, + 0xf1, 0xfc, 0xbd, 0x1e, 0x17, 0xf4, 0xe0, 0xe6, 0xcd, 0xfd, 0x29, 0x25, 0x02, + 0xcd, 0xc7, 0xb6, 0xe5, 0x06, 0x01, 0xd6, 0x1c, 0xfd, 0xfa, 0x18, 0xfd, 0xc8, + 0xc3, 0x17, 0xe2, 0x1f, 0xc8, 0xe7, 0x36, 0xc4, 0xef, 0xf2, 0xd4, 0xd2, 0x14, + 0x21, 0x06, 0x07, 0xfc, 0x06, 0x04, 0xf0, 0xc5, 0x11, 0xc6, 0x19, 0x09, 0x30, + 0xf9, 0x12, 0xfe, 0xf4, 0xfd, 0xf7, 0xf5, 0x13, 0x1c, 0xfe, 0xd4, 0xd8, 0x08, + 0x28, 0x23, 0xf5, 0x05, 0x13, 0xfb, 0x01, 0x6a, 0x1c, 0xe0, 0xea, 0xfb, 0x23, + 0xf9, 0x0a, 0x04, 0x3d, 0xf2, 0x19, 0x0a, 0xcf, 0x0b, 0x00, 0xd5, 0x12, 0xdd, + 0x12, 0x2c, 0xe1, 0x18, 0x29, 0x02, 0x1b, 0x08, 0x08, 0xee, 0xda, 0xd6, 0x1c, + 0xf6, 0x1d, 0xb8, 0xaa, 0xd9, 0xf3, 0x0e, 0xf6, 0xef, 0xd1, 0xf6, 0xf4, 0xb5, + 0xfd, 0xd9, 0xdd, 0xf8, 0x38, 0x0b, 0xeb, 0xe5, 0xfe, 0x00, 0xf9, 0xcb, 0xec, + 0x0c, 0xf0, 0xf2, 0x0f, 0xf9, 0xcd, 0xd1, 0x31, 0xd0, 0xcc, 0xe7, 0x2a, 0xd4, + 0xee, 0xf4, 0xaa, 0xe9, 0x06, 0xe7, 0xea, 0xee, 0xe8, 0xff, 0xf3, 0xe3, 0xf8, + 0x10, 0xc8, 0xed, 0x01, 0xd0, 0xee, 0x02, 0xe7, 0x03, 0xc1, 0xe4, 0xd3, 0xba, + 0x1c, 0x25, 0x49, 0xe4, 0xf1, 0xdf, 0xf6, 0xbd, 0x49, 0x0b, 0xbb, 0x03, 0xe9, + 0xfb, 0x4b, 0x1b, 0xf4, 0x7f, 0xe0, 0x27, 0xd2, 0x04, 0x0d, 0x08, 0xcc, 0xbf, + 0xf9, 0xed, 0xee, 0xed, 0x54, 0xc1, 0xf3, 0x04, 0xb5, 0xce, 0xe7, 0xc5, 0xf6, + 0xea, 0xcd, 0x09, 0x0f, 0xfe, 0x37, 0xdd, 0x0e, 0x0b, 0xf8, 0x09, 0xbf, 0xf8, + 0xcc, 0xe7, 0xf8, 0x43, 0xfe, 0x0d, 0xfb, 0xe7, 0xdf, 0xf5, 0x3a, 0xc6, 0x29, + 0x29, 0xfc, 0x31, 0xf3, 0xf0, 0x10, 0xd9, 0xd8, 0x05, 0xcb, 0x02, 0xee, 0x08, + 0x1d, 0x53, 0x06, 0x1c, 0xe3, 0xe4, 0xed, 0xd8, 0xcf, 0xeb, 0x3b, 0xeb, 0x3b, + 0x0b, 0xdb, 0x46, 0xc8, 0x05, 0x2a, 0xe5, 0x04, 0x0f, 0x99, 0x43, 0xba, 0x3a, + 0xfd, 0xf5, 0xd5, 0xee, 0x44, 0x30, 0xe8, 0x18, 0xf6, 0xe3, 0xf1, 0xf6, 0x25, + 0xe3, 0x0e, 0x43, 0x35, 0xfd, 0xc0, 0x0c, 0xf8, 0x59, 0xe3, 0x00, 0xf7, 0x11, + 0xcd, 0x1b, 0xd1, 0xef, 0x34, 0xd4, 0x93, 0x07, 0x2f, 0xf0, 0xe6, 0xda, 0xc7, + 0xf4, 0xc7, 0xd2, 0xeb, 0x15, 0xef, 0xf1, 0xe1, 0x5e, 0xce, 0x29, 0x12, 0x3f, + 0xde, 0xef, 0x2a, 0x19, 0x25, 0xe6, 0xf8, 0x07, 0x0a, 0x54, 0x3f, 0xf4, 0xf3, + 0xcf, 0xeb, 0xed, 0xd3, 0x1d, 0xc7, 0xcf, 0x24, 0xe6, 0xdb, 0x17, 0x0d, 0x56, + 0xd4, 0xc6, 0xeb, 0x23, 0xaf, 0xb2, 0x19, 0xea, 0x3e, 0x31, 0xe7, 0x17, 0x05, + 0xcb, 0xcf, 0x5d, 0x05, 0x05, 0x32, 0xfc, 0xeb, 0xd2, 0x0c, 0xd5, 0xf6, 0x15, + 0xda, 0xd4, 0x15, 0xd9, 0xba, 0xcd, 0x07, 0xd1, 0xf7, 0x30, 0xe0, 0x12, 0x1c, + 0xd5, 0xcf, 0xc1, 0x2a, 0xe1, 0x00, 0x9f, 0xb1, 0x10, 0xf2, 0xf6, 0x27, 0x03, + 0x7f, 0x10, 0x1f, 0x2e, 0x0b, 0xea, 0x22, 0xd4, 0xc9, 0xa9, 0xdb, 0x0b, 0x13, + 0xad, 0xa9, 0xe8, 0x30, 0x15, 0xda, 0xf3, 0xe8, 0xd0, 0x19, 0xfc, 0x03, 0xf1, + 0xe2, 0xbb, 0x08, 0xd0, 0x3b, 0x27, 0x22, 0xd9, 0x0d, 0x4e, 0xee, 0xe6, 0x16, + 0x1e, 0x14, 0xb4, 0xe9, 0xde, 0xf9, 0x27, 0x01, 0x0e, 0xf2, 0xf2, 0xf1, 0xe6, + 0x00, 0xc4, 0xd9, 0xe8, 0x33, 0xf0, 0x34, 0x10, 0xd0, 0x02, 0xf1, 0xeb, 0x28, + 0x26, 0xff, 0x49, 0xe5, 0x01, 0x37, 0x4e, 0x29, 0xf8, 0xc1, 0xe3, 0x22, 0xb9, + 0x1f, 0x02, 0xfd, 0x0e, 0xb7, 0xd6, 0xc7, 0xf9, 0xcd, 0xcd, 0x1a, 0x17, 0xe6, + 0xee, 0x05, 0xd1, 0xe5, 0xed, 0xf9, 0xe1, 0x32, 0x27, 0xe6, 0xf0, 0xd0, 0x31, + 0xe1, 0xea, 0xd4, 0x30, 0x06, 0x43, 0xec, 0xf6, 0xf3, 0x22, 0xf2, 0xf6, 0xd0, + 0xda, 0xfd, 0x0f, 0xad, 0x01, 0xda, 0x0a, 0xc3, 0x10, 0xf8, 0x9f, 0xfe, 0xe4, + 0xf4, 0xb0, 0x2f, 0x13, 0xd7, 0x8b, 0x13, 0xf6, 0xce, 0xd9, 0x05, 0x9e, 0x13, + 0xfb, 0x12, 0xfe, 0x9b, 0xf2, 0xf5, 0xbc, 0x18, 0xf5, 0x10, 0xd1, 0x18, 0xd8, + 0x0a, 0x49, 0xea, 0xd2, 0x0d, 0x02, 0xfd, 0xf7, 0xe1, 0x19, 0xee, 0xb4, 0x14, + 0xe1, 0xf5, 0xb3, 0xcc, 0xe2, 0xf2, 0x15, 0x52, 0xdd, 0xd9, 0x10, 0x22, 0x41, + 0x44, 0x01, 0x21, 0xb8, 0x1c, 0xdc, 0xd9, 0xd9, 0x0e, 0x0f, 0x30, 0xd1, 0xd2, + 0xe8, 0xc4, 0xdf, 0xed, 0xec, 0xc6, 0x36, 0xdb, 0xfb, 0x0f, 0x10, 0x2e, 0xbd, + 0xb5, 0x22, 0x23, 0xf8, 0x22, 0x0d, 0xde, 0xc7, 0xe6, 0xed, 0xfb, 0xe1, 0x4a, + 0x9a, 0x24, 0xd0, 0xf6, 0xe6, 0x30, 0xdc, 0xce, 0xca, 0xe5, 0xfb, 0xe9, 0xfc, + 0x24, 0xd1, 0x0b, 0xe2, 0xce, 0x07, 0xdb, 0xae, 0x34, 0x08, 0xd3, 0x2c, 0xb5, + 0xfc, 0xfa, 0xf4, 0x05, 0xfe, 0x15, 0x2b, 0xfb, 0xe8, 0x2f, 0x30, 0xa3, 0x04, + 0xad, 0x0c, 0xe7, 0xe3, 0x04, 0xea, 0x41, 0x3c, 0xfc, 0xe0, 0x9e, 0xb8, 0xf8, + 0x54, 0xdd, 0xed, 0xfd, 0xcb, 0x2b, 0x4b, 0xf8, 0x00, 0xc6, 0xe7, 0xff, 0x24, + 0x1f, 0xee, 0xc2, 0x53, 0xf0, 0x0a, 0xf7, 0xcd, 0x27, 0x1e, 0x06, 0xe4, 0x12, + 0xcc, 0xb4, 0x2e, 0x08, 0xfd, 0xfa, 0x1a, 0xf1, 0x03, 0xeb, 0xbe, 0x0b, 0xc1, + 0xea, 0x81, 0x29, 0xe9, 0xb9, 0xc0, 0xde, 0x23, 0xf7, 0xdd, 0xe8, 0xd2, 0xdc, + 0x1c, 0xec, 0xd1, 0x04, 0xe0, 0x1f, 0xf7, 0x0c, 0x26, 0xe5, 0x01, 0xe6, 0xe9, + 0x08, 0xce, 0x1f, 0xee, 0xbd, 0x06, 0x13, 0x08, 0xf0, 0xf7, 0xf3, 0x26, 0x1f, + 0x12, 0x14, 0xbe, 0x44, 0xfe, 0xdc, 0x55, 0x47, 0x24, 0x0d, 0xd7, 0xdb, 0xc0, + 0xd0, 0x1f, 0x28, 0x03, 0x92, 0xde, 0xe7, 0x15, 0xf4, 0x32, 0xaf, 0x3a, 0x2c, + 0x13, 0xd1, 0x18, 0x24, 0xb8, 0x5a, 0x47, 0x33, 0x01, 0xca, 0x19, 0xeb, 0x05, + 0xda, 0xb7, 0x81, 0xf4, 0xde, 0xde, 0x06, 0x3d, 0x90, 0xeb, 0x1a, 0xe7, 0xde, + 0xe2, 0xd0, 0x0f, 0x0a, 0x08, 0xeb, 0x21, 0xad, 0x06, 0x0e, 0xae, 0x00, 0x18, + 0x1e, 0x2f, 0x4b, 0xc0, 0xda, 0xf3, 0x42, 0x27, 0x41, 0x36, 0x55, 0xce, 0x1a, + 0xce, 0xc7, 0x12, 0x4f, 0xc9, 0x22, 0xae, 0x17, 0x2d, 0x09, 0xea, 0xc5, 0xb0, + 0xd4, 0xe8, 0x17, 0x2e, 0xdd, 0x34, 0x40, 0xdb, 0x06, 0xea, 0x13, 0xa4, 0x27, + 0xf1, 0x02, 0x34, 0xdb, 0x14, 0xfe, 0xfd, 0x26, 0x3c, 0x15, 0xc6, 0x12, 0xa2, + 0xb5, 0x03, 0x2a, 0xf0, 0xd8, 0xc1, 0xf6, 0xfa, 0x26, 0xaa, 0xc9, 0xdd, 0x21, + 0x39, 0x55, 0x32, 0x2c, 0xcb, 0x20, 0xcc, 0x02, 0x25, 0xa9, 0xed, 0x05, 0x50, + 0xc6, 0x48, 0x37, 0x14, 0xbf, 0xa6, 0x39, 0x1f, 0x44, 0xed, 0x2d, 0x0d, 0xde, + 0x1f, 0x37, 0x99, 0x99, 0x09, 0x15, 0xeb, 0x12, 0xe2, 0xfe, 0xdc, 0x91, 0xc7, + 0xe4, 0x05, 0xd9, 0xf0, 0xf1, 0xe7, 0xe3, 0x1d, 0x14, 0x10, 0xca, 0xcc, 0xaf, + 0xe1, 0x04, 0x43, 0xdc, 0xe2, 0xfc, 0x31, 0xd3, 0xe3, 0x21, 0x13, 0xd9, 0xd9, + 0xa0, 0x46, 0x16, 0x21, 0x24, 0x10, 0x1e, 0xe2, 0x06, 0x19, 0xeb, 0xdc, 0xde, + 0xc6, 0x2e, 0xba, 0xfc, 0x2b, 0xce, 0x16, 0xd2, 0x10, 0xe2, 0xb8, 0xde, 0x20, + 0xc3, 0xf5, 0x29, 0xb5, 0xea, 0x08, 0xf5, 0xd9, 0xb2, 0xca, 0x1c, 0x15, 0xf0, + 0x4c, 0xd5, 0xc1, 0x01, 0x08, 0xf8, 0xe5, 0xab, 0x19, 0xc5, 0xc8, 0xa9, 0xeb, + 0xfd, 0xeb, 0x11, 0x04, 0xd2, 0xa0, 0x25, 0x18, 0xbb, 0xb3, 0x26, 0xef, 0x01, + 0xd6, 0x4a, 0xfd, 0x0c, 0x33, 0x26, 0x12, 0x12, 0xdb, 0xf2, 0x03, 0xfa, 0xc4, + 0x33, 0x3f, 0x0b, 0x12, 0xe6, 0xa1, 0x57, 0x3a, 0x39, 0x06, 0xff, 0x3d, 0xfa, + 0x1f, 0xd1, 0x05, 0x1f, 0x00, 0x0e, 0xf7, 0xf5, 0x14, 0x17, 0xf1, 0xc9, 0xe4, + 0xff, 0x05, 0xec, 0xd3, 0xb1, 0xdc, 0x12, 0xe0, 0xfa, 0xe4, 0xf3, 0x2f, 0xec, + 0xfd, 0xfe, 0xde, 0xe0, 0xe7, 0xf0, 0x01, 0x17, 0xf3, 0x07, 0x12, 0xb1, 0xee, + 0xd4, 0x12, 0x05, 0xd6, 0x3f, 0xdd, 0xbd, 0xbb, 0xfb, 0xd7, 0x00, 0x24, 0x0b, + 0x36, 0xed, 0xee, 0x20, 0x4d, 0xf2, 0xf1, 0xeb, 0x26, 0xf0, 0xe9, 0xac, 0xd7, + 0xe7, 0x2d, 0x2a, 0xe7, 0xcf, 0xf3, 0xc3, 0xd0, 0x1c, 0xe4, 0xec, 0xff, 0x06, + 0xd3, 0xc4, 0x1e, 0xee, 0xfb, 0x08, 0xb9, 0xde, 0xd6, 0xfe, 0x18, 0x28, 0x00, + 0xd5, 0xc6, 0xe0, 0xd4, 0x32, 0x3d, 0xd9, 0x0f, 0xf9, 0xe9, 0xfd, 0xe7, 0xe5, + 0xf2, 0xe7, 0xf7, 0xd9, 0x2d, 0xcd, 0x0f, 0x07, 0x21, 0xdb, 0xce, 0xcf, 0xc5, + 0x05, 0xe1, 0xcd, 0x19, 0xb6, 0xf1, 0xed, 0x12, 0xf6, 0x0e, 0xff, 0xd8, 0xa4, + 0x1d, 0x42, 0xf0, 0xb1, 0xce, 0x02, 0xef, 0xf7, 0xba, 0x0f, 0x01, 0xd2, 0x02, + 0x31, 0xd7, 0xf1, 0xd8, 0x00, 0xfc, 0x45, 0x1a, 0xc2, 0xb8, 0x08, 0xec, 0x07, + 0x0e, 0xb7, 0x0f, 0xc6, 0xd6, 0x3a, 0xad, 0xeb, 0xca, 0xda, 0x0e, 0x2b, 0xc1, + 0x02, 0xfc, 0xef, 0x3f, 0x31, 0xe8, 0x04, 0x15, 0xef, 0xff, 0x25, 0x00, 0x04, + 0x01, 0xc9, 0xdd, 0xff, 0xe4, 0x0c, 0xd8, 0xbc, 0xd9, 0xe0, 0xc4, 0xe8, 0x1e, + 0xd9, 0x34, 0x0d, 0x25, 0xe5, 0x3b, 0xc9, 0x02, 0x1d, 0xf9, 0xce, 0x17, 0xf6, + 0x06, 0x04, 0xe1, 0xea, 0x0d, 0xcf, 0xd2, 0x15, 0xf4, 0xd2, 0x34, 0x09, 0xe0, + 0x7f, 0xa7, 0x22, 0x58, 0xdb, 0xef, 0xfd, 0xf0, 0x3a, 0x3b, 0xf5, 0x52, 0x30, + 0x18, 0xff, 0xfa, 0xa1, 0x06, 0xdc, 0x7b, 0x0a, 0x08, 0x1d, 0xef, 0x13, 0xfe, + 0xdf, 0x18, 0x67, 0x1c, 0xdd, 0xe9, 0xd9, 0xf1, 0xb0, 0xdd, 0x09, 0x14, 0x09, + 0xe0, 0x03, 0x12, 0xf5, 0xd6, 0x37, 0xe3, 0x06, 0xe0, 0xde, 0x4a, 0xcd, 0x0e, + 0xee, 0xf1, 0x1f, 0xfc, 0xf3, 0xf0, 0xd2, 0xf2, 0xfb, 0xfc, 0xd6, 0xe7, 0x34, + 0x0b, 0xfc, 0xf1, 0xd0, 0x09, 0xda, 0xef, 0x27, 0xac, 0xb8, 0x57, 0xdf, 0x00, + 0xb1, 0xf4, 0xca, 0xe3, 0x7e, 0x1d, 0x07, 0x09, 0x1d, 0xcd, 0x45, 0xcb, 0xfa, + 0xf1, 0xd3, 0xd7, 0xc8, 0xef, 0xdc, 0xf2, 0xe5, 0x01, 0x06, 0xf2, 0x12, 0xf5, + 0xda, 0x32, 0xbb, 0x15, 0xb5, 0x04, 0xb4, 0xca, 0xf2, 0x0b, 0x0c, 0x24, 0x62, + 0xdf, 0xe5, 0x95, 0x16, 0x04, 0x46, 0xe1, 0x00, 0xee, 0x4d, 0xcc, 0xdc, 0x4e, + 0xda, 0xcd, 0xc9, 0xe9, 0x0b, 0x51, 0x0e, 0x30, 0xfa, 0xf5, 0xe2, 0x0f, 0xb8, + 0xa7, 0xba, 0xe5, 0xee, 0xd0, 0xd7, 0xc3, 0xd0, 0xf6, 0x36, 0x00, 0x25, 0x48, + 0x1b, 0xc6, 0xe6, 0xb0, 0xba, 0xfb, 0x2e, 0xe9, 0xf2, 0xc6, 0x30, 0xc2, 0xef, + 0xf4, 0xde, 0x75, 0x0c, 0x06, 0x2f, 0x1c, 0x2f, 0x18, 0x03, 0xe6, 0xfa, 0x0b, + 0xf5, 0x13, 0xda, 0x51, 0xf7, 0xf0, 0x16, 0xe9, 0xe3, 0xee, 0xe3, 0xc0, 0xce, + 0x11, 0x13, 0x39, 0xf5, 0xf0, 0xd8, 0x02, 0x35, 0x11, 0xe1, 0x04, 0x1c, 0x24, + 0xda, 0xf5, 0xf8, 0x10, 0xd4, 0xd6, 0xf3, 0xe1, 0x09, 0xf7, 0xff, 0xdd, 0x02, + 0xe1, 0xdb, 0xf3, 0x0b, 0x15, 0x1d, 0xea, 0x2f, 0x08, 0xb0, 0x38, 0x0f, 0xfe, + 0xd3, 0x19, 0xde, 0x27, 0x02, 0x09, 0xd9, 0xe8, 0x7f, 0xfd, 0x04, 0xfd, 0xeb, + 0xc6, 0xff, 0xf7, 0xe0, 0xc9, 0x1d, 0xa1, 0x0c, 0x17, 0xd9, 0xdd, 0xa3, 0xdb, + 0xe1, 0x10, 0x28, 0xed, 0x07, 0xe5, 0x06, 0xf0, 0xf9, 0xd8, 0xb9, 0xc3, 0xfc, + 0x25, 0xf0, 0xfc, 0xfe, 0xe5, 0x03, 0x0f, 0xf3, 0xd9, 0xb5, 0xe5, 0xeb, 0xf3, + 0xdc, 0x2d, 0xd2, 0xc8, 0xcf, 0xef, 0xdd, 0xe5, 0xf8, 0x0a, 0x1f, 0xfc, 0xd0, + 0x11, 0xdc, 0xcb, 0x31, 0x01, 0xdf, 0xfb, 0xee, 0x2a, 0xe1, 0xf5, 0x37, 0xdd, + 0x0d, 0xcd, 0x10, 0xcc, 0xf8, 0x01, 0xff, 0xdd, 0xfc, 0xd6, 0x20, 0x43, 0xd2, + 0xec, 0x11, 0xf8, 0x03, 0xdc, 0x15, 0xfc, 0xf2, 0xca, 0xf9, 0x07, 0x08, 0xe0, + 0xfd, 0x23, 0x2b, 0x22, 0xe1, 0xcb, 0xe6, 0x10, 0x03, 0x46, 0x24, 0x00, 0xf9, + 0xdf, 0xfe, 0x27, 0x0b, 0x1e, 0xc0, 0x0e, 0x15, 0x06, 0xd3, 0x11, 0xd2, 0xd0, + 0x0d, 0xda, 0xda, 0x29, 0xc3, 0x0f, 0x5c, 0x13, 0x03, 0xf7, 0xd3, 0x14, 0xf7, + 0xf6, 0x12, 0x11, 0x13, 0x05, 0xda, 0xf3, 0xe6, 0xf0, 0xde, 0xc3, 0xcd, 0xd4, + 0xfc, 0xe5, 0xda, 0xe2, 0xe2, 0xe5, 0x1e, 0xfc, 0xfc, 0xf3, 0x08, 0xe4, 0xf2, + 0xec, 0x07, 0x01, 0xff, 0xec, 0xf5, 0x0a, 0x00, 0xe5, 0xe9, 0xe6, 0xf6, 0xfc, + 0xef, 0xe2, 0xde, 0xdd, 0xee, 0xfe, 0x06, 0xf0, 0xc2, 0xe4, 0x04, 0xf6, 0xe2, + 0x0f, 0xef, 0x09, 0xf0, 0x0b, 0xe4, 0xde, 0xde, 0x13, 0xe9, 0xd8, 0xd2, 0xf8, + 0xf6, 0xef, 0x12, 0x24, 0x7f, 0xf7, 0xc4, 0xf7, 0xd5, 0x1b, 0x02, 0x43, 0x07, + 0x04, 0x11, 0x05, 0xf9, 0x17, 0x1a, 0x4a, 0x01, 0x2d, 0xc1, 0xbf, 0xdb, 0xf7, + 0xf4, 0x05, 0x18, 0x27, 0xda, 0x22, 0x07, 0xec, 0xe5, 0x0c, 0x04, 0xb4, 0x01, + 0xba, 0xf4, 0xe8, 0x26, 0xf6, 0xee, 0xfa, 0x0e, 0xf9, 0xf6, 0xfc, 0xf8, 0xe0, + 0xd1, 0x0c, 0x08, 0xd8, 0xfa, 0x06, 0x17, 0xd8, 0x1b, 0xf9, 0x41, 0xec, 0x1f, + 0xd8, 0x04, 0xe9, 0x00, 0x35, 0xf8, 0x0f, 0x15, 0xc8, 0xf9, 0xd4, 0xfa, 0xdd, + 0x15, 0xdd, 0x0f, 0x33, 0x06, 0x19, 0xdc, 0xfd, 0xd3, 0xb3, 0xca, 0xbc, 0xfc, + 0x01, 0xb4, 0xed, 0xc6, 0x2f, 0xd8, 0x37, 0xe7, 0xe8, 0xf8, 0xeb, 0xe5, 0xde, + 0xd4, 0xe6, 0xde, 0xc3, 0xd8, 0xf4, 0xf0, 0x0c, 0xc0, 0x1c, 0xe8, 0xc0, 0x0d, + 0x16, 0x03, 0xf0, 0xd6, 0x19, 0x0c, 0xf6, 0x38, 0x3b, 0x1c, 0x0c, 0xfb, 0xa6, + 0xee, 0xdb, 0x10, 0xa1, 0x0b, 0x17, 0xe6, 0x19, 0x15, 0xb9, 0xfa, 0x03, 0xc5, + 0xf6, 0xe5, 0xe0, 0xdb, 0x4e, 0x05, 0x2e, 0xf9, 0xda, 0xf9, 0x1f, 0x26, 0xf6, + 0xcd, 0x28, 0x33, 0xee, 0x17, 0xb9, 0xe4, 0x29, 0x08, 0x16, 0xe5, 0x09, 0xca, + 0x18, 0xf5, 0xfe, 0x00, 0xfb, 0xe2, 0xef, 0x0f, 0x06, 0x19, 0xed, 0xf2, 0xf1, + 0xa6, 0x10, 0x57, 0xf1, 0xdc, 0xe2, 0x43, 0x2b, 0x24, 0xf0, 0xe7, 0x06, 0x11, + 0x23, 0xc8, 0x21, 0x0f, 0xf7, 0xd7, 0xf4, 0xd5, 0xca, 0xf5, 0xff, 0xf0, 0xf0, + 0xd2, 0xd9, 0x13, 0x0c, 0x15, 0x06, 0xdb, 0x09, 0xd1, 0x00, 0x37, 0x08, 0x0d, + 0xce, 0x16, 0xc4, 0xd5, 0xe4, 0xd9, 0xe9, 0x04, 0xaf, 0xc5, 0xde, 0xe4, 0x26, + 0xdd, 0x39, 0x08, 0xd6, 0xc9, 0x09, 0x1a, 0xe5, 0xc4, 0x3c, 0xfc, 0x2a, 0x1b, + 0xee, 0x0b, 0x0b, 0x9c, 0x2d, 0xcf, 0xad, 0xc5, 0x1e, 0xb5, 0xfa, 0x05, 0xe6, + 0x7f, 0xf2, 0xfa, 0x08, 0xd9, 0x0e, 0x03, 0x3c, 0xdf, 0xbb, 0x16, 0xe1, 0x42, + 0xfa, 0x11, 0x95, 0xb9, 0x3d, 0xbd, 0xe4, 0xd2, 0x01, 0xfe, 0xbc, 0xed, 0x0b, + 0xd3, 0x04, 0xc1, 0xd4, 0xf7, 0x2d, 0xe4, 0x08, 0xbe, 0xe5, 0x05, 0xea, 0xee, + 0xe5, 0x1a, 0xf0, 0x59, 0x03, 0xc8, 0xd6, 0x18, 0xe2, 0xe9, 0x07, 0x18, 0x1a, + 0x20, 0x24, 0xfc, 0x06, 0x1a, 0xfe, 0x03, 0xa1, 0xc7, 0xd5, 0xe3, 0x08, 0x06, + 0xf2, 0xcc, 0xb1, 0xef, 0xdf, 0x1e, 0xe3, 0x1e, 0xbb, 0xc5, 0xf1, 0x14, 0xe2, + 0xe2, 0x0e, 0x1a, 0x00, 0xb9, 0x09, 0xfe, 0xac, 0x13, 0x0e, 0xcc, 0xc6, 0xf5, + 0x34, 0xea, 0x2f, 0x5c, 0x19, 0xeb, 0x33, 0xbd, 0x9d, 0x12, 0x9a, 0x19, 0xa4, + 0xd7, 0xd3, 0xea, 0xd2, 0x1a, 0xde, 0x16, 0x1d, 0x18, 0xf0, 0x98, 0x40, 0xe9, + 0x00, 0xd8, 0xe0, 0x13, 0x03, 0x08, 0xe2, 0xf3, 0xcd, 0x1c, 0xe8, 0xcd, 0x38, + 0xfb, 0x34, 0x18, 0xf4, 0x12, 0x13, 0xfc, 0xc3, 0xf6, 0x0b, 0xfe, 0xd4, 0xee, + 0x10, 0xf8, 0xd6, 0x6f, 0x21, 0x05, 0xff, 0x07, 0xd6, 0xe0, 0x90, 0xf7, 0x2a, + 0x2b, 0xa2, 0xef, 0xdf, 0x0a, 0x06, 0x1b, 0x2a, 0x08, 0x4a, 0xc4, 0x11, 0xfa, + 0xf4, 0xae, 0x01, 0xb5, 0xf5, 0xf9, 0x26, 0x54, 0x0d, 0x43, 0x55, 0xc5, 0xe9, + 0xff, 0xe1, 0xc1, 0xf3, 0x22, 0x2b, 0xc4, 0x15, 0xe8, 0x57, 0xee, 0xfa, 0xeb, + 0xfc, 0xda, 0xd8, 0xc1, 0x0d, 0xf0, 0x1b, 0xfc, 0x0d, 0xd9, 0x2c, 0x3d, 0x12, + 0x1c, 0x1c, 0xd2, 0x3d, 0xfa, 0xf6, 0x1b, 0xf0, 0x0f, 0x40, 0x9b, 0xa7, 0xf9, + 0xb2, 0xe1, 0xf8, 0xf2, 0xf4, 0x14, 0xd6, 0xe7, 0x0f, 0xc9, 0x00, 0xe2, 0x08, + 0xdb, 0x7f, 0xb8, 0xe5, 0xe4, 0xab, 0x24, 0xfb, 0xee, 0xf5, 0xe3, 0x36, 0x2a, + 0xad, 0xfc, 0xf9, 0xbe, 0xe3, 0x01, 0xd3, 0xdb, 0xe1, 0x60, 0x0a, 0xbf, 0x0a, + 0xc0, 0xac, 0xe0, 0xd0, 0x41, 0xd6, 0x0b, 0xdc, 0x3e, 0x09, 0xf7, 0xc5, 0xe1, + 0xe6, 0xff, 0xe3, 0x22, 0xca, 0xdf, 0x24, 0xfa, 0x60, 0xe1, 0xb6, 0x97, 0xeb, + 0xe2, 0x2a, 0x39, 0x21, 0xc6, 0xdf, 0x3c, 0x1f, 0x3b, 0x16, 0xf9, 0x1f, 0x9a, + 0xda, 0xda, 0xbf, 0x4e, 0xd7, 0x03, 0x1f, 0xdd, 0xeb, 0x03, 0x33, 0x19, 0xed, + 0xfd, 0xe5, 0xcb, 0x14, 0xde, 0xf5, 0x17, 0x00, 0x59, 0xc3, 0xd7, 0xe7, 0xf0, + 0xb1, 0xce, 0x42, 0x35, 0xe5, 0xc0, 0xf1, 0x58, 0xf3, 0xd5, 0xe7, 0x13, 0xd6, + 0x0c, 0x24, 0x05, 0xcb, 0x00, 0xb6, 0xec, 0xff, 0x1e, 0x39, 0xf1, 0x1a, 0xb9, + 0xf8, 0x01, 0xff, 0xe2, 0x68, 0xde, 0x28, 0xcf, 0xcc, 0xe7, 0xd6, 0x0d, 0xa9, + 0x20, 0xf1, 0xe3, 0xeb, 0xec, 0xf0, 0xd2, 0x13, 0xf8, 0x08, 0x0c, 0xf2, 0xe5, + 0x1e, 0xc6, 0x06, 0x1f, 0xc0, 0xfd, 0xac, 0xfa, 0xb6, 0xf9, 0xff, 0xd1, 0xf0, + 0xe8, 0xbc, 0xed, 0x23, 0xa5, 0xd9, 0x0b, 0xfe, 0xf8, 0xac, 0x5c, 0xca, 0xd9, + 0xe0, 0xcf, 0x81, 0xf5, 0xfb, 0x26, 0x0b, 0x09, 0x10, 0x2d, 0x9b, 0x20, 0x01, + 0xfb, 0x0c, 0x09, 0x0d, 0xd0, 0x0c, 0x24, 0x11, 0x10, 0xb5, 0x07, 0xd3, 0xe4, + 0x17, 0x16, 0xd6, 0xdc, 0xfe, 0xcb, 0xb6, 0xc8, 0xf8, 0xde, 0xe8, 0x3c, 0xd9, + 0x47, 0xfd, 0xa0, 0x22, 0xd5, 0xde, 0xea, 0xc2, 0xea, 0xe7, 0x43, 0xde, 0x09, + 0xab, 0xd6, 0xcd, 0x1c, 0xf9, 0xc0, 0xcc, 0x03, 0xfe, 0x31, 0x18, 0x22, 0xe5, + 0xdc, 0xfb, 0xd8, 0xbb, 0xfa, 0x9d, 0x06, 0x32, 0x09, 0x0d, 0xaa, 0x1a, 0x01, + 0xbe, 0xd0, 0xcf, 0xea, 0x0e, 0x16, 0x21, 0x13, 0xef, 0xd4, 0xdc, 0x49, 0x0e, + 0xef, 0xd1, 0x1e, 0x13, 0x42, 0x2f, 0x28, 0xc9, 0xbe, 0xe5, 0x11, 0x3d, 0xf5, + 0xf0, 0xca, 0x16, 0x1c, 0xd8, 0x18, 0xfd, 0xd2, 0x19, 0xe3, 0xea, 0xbf, 0xdd, + 0xcb, 0x87, 0xff, 0x1e, 0xb7, 0xe6, 0x25, 0xcc, 0xe5, 0xf9, 0xe5, 0xe9, 0xac, + 0xfa, 0x50, 0xfa, 0xea, 0x04, 0x06, 0xa1, 0xc9, 0x07, 0x0b, 0xf3, 0xde, 0xa0, + 0xdd, 0xe8, 0x90, 0x96, 0x0b, 0xeb, 0x0d, 0x21, 0x07, 0x2f, 0x99, 0xeb, 0x9b, + 0x0a, 0x0d, 0xe4, 0xf8, 0x4e, 0xe2, 0xdf, 0x15, 0xe0, 0xe4, 0xd7, 0xc3, 0xf5, + 0xd9, 0x1e, 0xd3, 0x07, 0xfe, 0xd7, 0xf5, 0xcf, 0x29, 0x34, 0x20, 0x20, 0xd9, + 0xcd, 0x14, 0xfe, 0xe5, 0x2f, 0x1b, 0x08, 0x3f, 0x9d, 0xc4, 0x03, 0x04, 0x09, + 0xf5, 0xcb, 0xd2, 0xfa, 0xfa, 0xcf, 0x01, 0xc5, 0x07, 0x06, 0x03, 0xfa, 0xdd, + 0xc0, 0xda, 0xf1, 0xc6, 0xef, 0xf1, 0x14, 0xf6, 0xcd, 0x48, 0x9d, 0xb3, 0xb4, + 0xac, 0xff, 0xe6, 0xed, 0x04, 0xf3, 0xf8, 0xdd, 0xe7, 0x08, 0xe3, 0x37, 0xf5, + 0xd9, 0xfe, 0x08, 0xd8, 0x01, 0xf1, 0xc6, 0xd8, 0xd4, 0x38, 0x15, 0x1b, 0xe1, + 0x9c, 0x04, 0xe6, 0xe1, 0xfd, 0x03, 0xcd, 0x86, 0x0e, 0x0c, 0xe4, 0x81, 0x04, + 0xf4, 0xfc, 0xd7, 0x26, 0x37, 0x0a, 0xae, 0x0e, 0xe5, 0x33, 0xfa, 0xd8, 0xeb, + 0x01, 0xc0, 0x50, 0xf8, 0xf5, 0x24, 0x1e, 0x28, 0x06, 0xc3, 0x13, 0xf8, 0xae, + 0x03, 0xfb, 0xce, 0xbc, 0x2c, 0x17, 0x0a, 0xf3, 0xcf, 0xee, 0x1a, 0xb0, 0x1f, + 0xba, 0xbc, 0xee, 0xae, 0x00, 0x05, 0xbe, 0xd6, 0xf5, 0x12, 0xe8, 0xb5, 0x2c, + 0xd4, 0xf2, 0x20, 0x2a, 0xfd, 0x1b, 0x30, 0xf7, 0xaf, 0xc2, 0xde, 0xcb, 0x30, + 0x20, 0xdc, 0x0f, 0xfe, 0xeb, 0x1e, 0xca, 0xc7, 0xf3, 0x22, 0xce, 0xeb, 0xf1, + 0x14, 0xfb, 0xe5, 0xfe, 0xd4, 0xcd, 0xd5, 0xfb, 0xea, 0xc6, 0xd8, 0xde, 0xe3, + 0x33, 0x29, 0x61, 0x32, 0x1e, 0xfb, 0x2d, 0xcb, 0xc5, 0xef, 0x06, 0xe9, 0xeb, + 0x0d, 0x20, 0x38, 0xfb, 0xdc, 0xdd, 0xbd, 0xe7, 0xd3, 0xec, 0xcb, 0x5a, 0xe0, + 0x4e, 0x2f, 0x22, 0xc6, 0x06, 0xca, 0xe3, 0x09, 0x2c, 0x3d, 0x17, 0x08, 0xef, + 0xe6, 0xed, 0xd1, 0x33, 0x1f, 0x28, 0xd6, 0xb9, 0x88, 0xe9, 0x1b, 0xe5, 0xe1, + 0xd3, 0x6e, 0x0c, 0x09, 0xb9, 0x1e, 0xcc, 0xf1, 0x40, 0xce, 0x33, 0x0e, 0xff, + 0x2a, 0x18, 0x13, 0xf0, 0xe5, 0xa6, 0xd9, 0xe1, 0x2b, 0x11, 0xec, 0x1b, 0x23, + 0x0a, 0x18, 0xdf, 0x13, 0xfc, 0x41, 0xcc, 0x00, 0xc6, 0xf4, 0x25, 0xf3, 0x21, + 0x36, 0x04, 0x51, 0xfe, 0xbb, 0xf4, 0xf7, 0x05, 0x46, 0x0b, 0xea, 0x3d, 0xf6, + 0xaf, 0x03, 0x4b, 0xe8, 0x13, 0xf7, 0x14, 0x10, 0xf8, 0x08, 0xd0, 0xb7, 0x05, + 0xcd, 0x13, 0xda, 0x9f, 0xe8, 0x14, 0xc8, 0x02, 0x09, 0xc1, 0x2e, 0xa6, 0x07, + 0x13, 0xfd, 0xdd, 0xde, 0x43, 0x17, 0x45, 0xe4, 0xe5, 0xed, 0x1b, 0xfe, 0xf1, + 0xed, 0xf8, 0x15, 0x4d, 0x0d, 0x0e, 0x37, 0x1d, 0x09, 0xfc, 0xc5, 0xb8, 0xe9, + 0xf0, 0xef, 0xf7, 0x0a, 0x19, 0x22, 0x14, 0x11, 0x44, 0xd7, 0xe3, 0x03, 0xe6, + 0x26, 0x00, 0xb2, 0x0a, 0xe2, 0xec, 0xe4, 0x3e, 0x24, 0xe4, 0x30, 0xbe, 0x12, + 0xf4, 0x02, 0xfd, 0x1b, 0x05, 0xda, 0xde, 0x02, 0xe1, 0x33, 0xfb, 0x0f, 0xe0, + 0x03, 0x18, 0xed, 0xe6, 0xe1, 0x10, 0x2d, 0xc9, 0x19, 0xee, 0x13, 0x3b, 0xef, + 0xda, 0xe7, 0xb5, 0xc1, 0xdb, 0xee, 0xfa, 0x03, 0x2c, 0x57, 0xec, 0x02, 0x18, + 0xf3, 0xf2, 0xfe, 0x2d, 0xeb, 0x02, 0xf7, 0x1f, 0xeb, 0xef, 0x43, 0xe7, 0x2c, + 0x00, 0xa3, 0x2f, 0xf9, 0xd2, 0xec, 0xc6, 0xbe, 0x11, 0xc9, 0xce, 0xf2, 0xf2, + 0xe5, 0xf8, 0x24, 0x09, 0x25, 0x02, 0x30, 0x68, 0x2f, 0x1c, 0x1e, 0x10, 0xf9, + 0x10, 0xe5, 0xdf, 0xc2, 0xdf, 0xf3, 0x2d, 0xf5, 0xbf, 0xdd, 0x1d, 0x02, 0x06, + 0x03, 0xd1, 0x20, 0x2f, 0x2b, 0xeb, 0xda, 0x20, 0xe0, 0x40, 0x17, 0xe7, 0x47, + 0x0a, 0xf5, 0xe0, 0x1f, 0x00, 0x13, 0x23, 0x0c, 0x06, 0x46, 0xc7, 0xf7, 0x22, + 0x2b, 0xfa, 0xe5, 0x15, 0xf8, 0xe5, 0xe8, 0x43, 0x29, 0x07, 0x0d, 0xe5, 0xee, + 0x04, 0xfc, 0xd2, 0xae, 0x7f, 0xd0, 0x07, 0xe5, 0xfb, 0xf5, 0xe4, 0x1b, 0xfd, + 0xd6, 0xc3, 0xd2, 0xe4, 0xb9, 0xdc, 0xe1, 0xf4, 0x25, 0xf2, 0xf1, 0xcd, 0xee, + 0x16, 0x14, 0x01, 0x33, 0x33, 0x04, 0xf5, 0xd0, 0xfc, 0xf0, 0x1e, 0x10, 0xfc, + 0xda, 0x30, 0xe7, 0x06, 0xc5, 0xdc, 0xdd, 0xf2, 0x18, 0xe4, 0x6d, 0xe7, 0x19, + 0xe7, 0x04, 0xf7, 0x1f, 0xde, 0x0d, 0xd5, 0x0b, 0xc8, 0xbf, 0x00, 0x0e, 0xcb, + 0xff, 0xd4, 0x18, 0x9e, 0xcb, 0xf1, 0xf7, 0xed, 0xfc, 0x2f, 0x56, 0xcb, 0xec, + 0x4f, 0x1b, 0x2b, 0xcc, 0xee, 0xdc, 0x24, 0xdb, 0x1d, 0xbe, 0x32, 0xfc, 0x3d, + 0x61, 0xf4, 0xcc, 0x05, 0xe6, 0xf7, 0xc7, 0xfc, 0xd4, 0xf4, 0x91, 0xec, 0xeb, + 0x1f, 0xdd, 0xfa, 0x37, 0x0b, 0xba, 0xd9, 0x20, 0xca, 0x41, 0x5a, 0x31, 0x02, + 0xf4, 0x14, 0xae, 0x45, 0x0d, 0xf0, 0x1c, 0xb2, 0x03, 0xff, 0x17, 0xe6, 0x17, + 0xd8, 0xc2, 0xe9, 0xc3, 0xc0, 0x78, 0xcb, 0x0a, 0x40, 0xe9, 0x43, 0xbb, 0xe2, + 0xe0, 0x15, 0x2e, 0xd6, 0x21, 0xb0, 0xc6, 0xe0, 0xba, 0x20, 0x02, 0xe2, 0x00, + 0xcf, 0xce, 0xef, 0x1d, 0x35, 0x10, 0xf7, 0xd9, 0xd6, 0xed, 0xe6, 0x2a, 0x1e, + 0xe8, 0x1f, 0x0c, 0x19, 0xc5, 0x0e, 0xe9, 0x0f, 0xe0, 0x22, 0xb9, 0xc9, 0x03, + 0xf2, 0xe5, 0xde, 0xb8, 0xd0, 0xfb, 0xf9, 0xcf, 0x16, 0xf5, 0xf7, 0xe0, 0xe3, + 0x17, 0xf1, 0xe2, 0x50, 0x15, 0x3c, 0xec, 0xfb, 0xdb, 0xe7, 0x2d, 0xbc, 0xe6, + 0xbf, 0x19, 0xed, 0xe7, 0x61, 0xb8, 0x71, 0xd1, 0x08, 0x03, 0xdb, 0x05, 0x40, + 0x4c, 0x01, 0xf1, 0x09, 0xef, 0x3a, 0x02, 0x2a, 0x37, 0xc0, 0x55, 0xd1, 0x8c, + 0x14, 0x09, 0xfd, 0xea, 0x22, 0xee, 0x0b, 0x23, 0xec, 0xa9, 0x81, 0xff, 0xd3, + 0xf2, 0xe3, 0xcd, 0xc2, 0x09, 0x13, 0xdb, 0xbb, 0x0f, 0x16, 0x04, 0xa7, 0x15, + 0x4e, 0xe9, 0x16, 0xd2, 0xe4, 0xd2, 0xe2, 0xe2, 0x2c, 0xbc, 0x1b, 0xf6, 0xfc, + 0xd9, 0x60, 0x86, 0x1c, 0x29, 0xc4, 0x40, 0xe6, 0xf1, 0x25, 0xc9, 0x44, 0x20, + 0x2e, 0xd4, 0x05, 0xc8, 0x0b, 0x30, 0x1e, 0xda, 0xe7, 0xdc, 0xeb, 0xe3, 0xef, + 0xa9, 0xe0, 0x2f, 0xbc, 0xb7, 0xaf, 0x50, 0xd6, 0x59, 0xf5, 0xf0, 0x0c, 0x11, + 0xbb, 0xf8, 0xd1, 0x1c, 0x0b, 0xee, 0x28, 0xa3, 0x28, 0x21, 0xc1, 0xb9, 0xc0, + 0xe0, 0xed, 0xaa, 0xf0, 0xf9, 0xca, 0xc7, 0x0f, 0x07, 0xc4, 0x04, 0x36, 0xdf, + 0xeb, 0xf4, 0xf6, 0xde, 0xf9, 0x2a, 0x18, 0xed, 0xf0, 0x07, 0xed, 0x25, 0xdf, + 0x0f, 0xf5, 0x81, 0xd1, 0x13, 0x19, 0x15, 0xdc, 0xfe, 0xf7, 0xfe, 0x30, 0x1d, + 0xdb, 0x1f, 0x17, 0x3a, 0xeb, 0xf6, 0xd0, 0x37, 0x0c, 0xed, 0xd9, 0xb3, 0x26, + 0xfb, 0xd5, 0xfb, 0xb5, 0x07, 0xe9, 0xea, 0xe0, 0xe1, 0xc8, 0xe0, 0xd9, 0xe4, + 0xcf, 0xe2, 0xda, 0xe0, 0x04, 0xbe, 0xac, 0x1a, 0x02, 0xd6, 0x04, 0xe0, 0x18, + 0xd7, 0xff, 0x27, 0x0b, 0x24, 0x98, 0x2c, 0xfc, 0xd1, 0xd5, 0x48, 0xfb, 0x0b, + 0x02, 0xec, 0xd8, 0xfa, 0xe3, 0x9c, 0xf4, 0xfd, 0xcf, 0x5b, 0x11, 0xf2, 0xdc, + 0x03, 0xd7, 0xf9, 0xa7, 0x0d, 0xf7, 0xb8, 0xc3, 0x0f, 0xe7, 0x28, 0xa5, 0xee, + 0xf1, 0x10, 0x43, 0xde, 0x04, 0xe9, 0x10, 0x02, 0x00, 0xc7, 0x2a, 0x3d, 0xe4, + 0xac, 0xdb, 0x0a, 0xdb, 0xd8, 0xee, 0x21, 0x2c, 0x0e, 0x21, 0x2e, 0xdd, 0x30, + 0x1b, 0xde, 0x11, 0xe7, 0x46, 0xfc, 0x0f, 0x2e, 0xe8, 0x31, 0x59, 0x09, 0xe3, + 0xaa, 0x50, 0xd5, 0xd2, 0x1a, 0xfd, 0xfe, 0x29, 0xc4, 0xdc, 0xc7, 0xf5, 0xdb, + 0xa6, 0xdd, 0x25, 0xee, 0xf9, 0xb3, 0x12, 0xf9, 0xf4, 0x31, 0x13, 0x03, 0x20, + 0xff, 0xca, 0x01, 0xbe, 0xef, 0xca, 0xb9, 0xc9, 0xd4, 0x04, 0xb9, 0xd8, 0x25, + 0xb0, 0xf5, 0xbb, 0xa4, 0xd9, 0xc3, 0xfd, 0xa6, 0x16, 0x2f, 0xeb, 0xe2, 0x01, + 0x1f, 0x06, 0xf7, 0xe5, 0xbf, 0xcc, 0xbf, 0xf4, 0x0e, 0xf4, 0x25, 0x45, 0x1a, + 0xf8, 0x06, 0xd0, 0x18, 0xea, 0x03, 0xd3, 0x32, 0xf8, 0xe5, 0x24, 0x3e, 0x23, + 0xdb, 0xf2, 0xea, 0xd1, 0x04, 0x1b, 0x18, 0xe5, 0x06, 0x5f, 0xab, 0x34, 0xb9, + 0x42, 0xe8, 0xfc, 0x20, 0x20, 0x1e, 0x16, 0xed, 0x34, 0xdc, 0x27, 0x08, 0x0f, + 0xf3, 0xf2, 0xf6, 0xdd, 0xd9, 0x15, 0xd1, 0xd4, 0xb5, 0x00, 0xc4, 0xc9, 0xdb, + 0xc9, 0xd1, 0xfe, 0xdd, 0xa8, 0xe5, 0x2c, 0xcd, 0xce, 0x22, 0xdd, 0xf6, 0xe4, + 0x21, 0xda, 0x28, 0x0c, 0x93, 0xef, 0xf5, 0x4a, 0x31, 0x9e, 0xca, 0x2b, 0x13, + 0x02, 0xef, 0xeb, 0xca, 0x07, 0xc8, 0xe7, 0x5f, 0xfd, 0x7d, 0xef, 0x20, 0x45, + 0x20, 0xc6, 0x15, 0x8c, 0xd7, 0xf8, 0xcf, 0x13, 0xd2, 0x0d, 0x28, 0x46, 0x58, + 0xeb, 0x34, 0x59, 0x11, 0xb7, 0xc8, 0xe4, 0x47, 0x45, 0xf1, 0xf7, 0x34, 0x07, + 0xd3, 0x0f, 0x75, 0xdb, 0x34, 0xfb, 0xd2, 0xb7, 0x23, 0xe2, 0xf8, 0x40, 0xd6, + 0x11, 0x03, 0xd0, 0xe5, 0xac, 0xb5, 0xde, 0x36, 0x15, 0xf1, 0xd2, 0x36, 0xea, + 0xcd, 0x45, 0x59, 0xf6, 0x1e, 0xca, 0x0e, 0xf2, 0x2c, 0x25, 0xde, 0xd7, 0x66, + 0x33, 0x23, 0xd5, 0x9b, 0x1c, 0xd4, 0xab, 0x13, 0xea, 0x03, 0xb2, 0x59, 0x01, + 0x19, 0x08, 0x16, 0x64, 0xd3, 0x33, 0xd5, 0x95, 0xd5, 0x3c, 0xca, 0xdc, 0xe8, + 0x19, 0x08, 0xcb, 0xe1, 0x81, 0xdb, 0xe2, 0xde, 0x19, 0x12, 0xd6, 0x1f, 0xcf, + 0x14, 0xfb, 0xd8, 0x30, 0xf8, 0x0d, 0x3d, 0xdb, 0xbb, 0x14, 0xdc, 0x0e, 0xbe, + 0xf0, 0xe7, 0x12, 0x4d, 0xd2, 0x20, 0xb5, 0x4c, 0xb1, 0xd6, 0x4b, 0x95, 0xe1, + 0x0a, 0xa9, 0x06, 0x15, 0xf7, 0x8b, 0xb8, 0x06, 0xce, 0xc9, 0xe1, 0xdf, 0x8d, + 0x0b, 0xd4, 0xcc, 0xf8, 0xa2, 0xdb, 0x96, 0xfe, 0x45, 0x11, 0x28, 0xed, 0x1e, + 0x94, 0x07, 0x21, 0xe5, 0x2d, 0x2e, 0xc2, 0x0a, 0xf2, 0xf9, 0x0c, 0xe6, 0xe1, + 0x12, 0xd5, 0xd6, 0x4c, 0xe1, 0x30, 0x04, 0xda, 0xfb, 0x34, 0x11, 0x3d, 0xf7, + 0x02, 0xb2, 0x62, 0x13, 0xdf, 0xf5, 0x03, 0xea, 0x02, 0x89, 0xc5, 0x16, 0x1e, + 0x12, 0xd4, 0xe4, 0x20, 0xd9, 0xf1, 0xa7, 0x02, 0x51, 0xcd, 0xd9, 0xc9, 0x97, + 0x07, 0xe2, 0xab, 0xc5, 0x53, 0x45, 0xe5, 0xdf, 0xb2, 0xbc, 0xc9, 0xf5, 0x3f, + 0xae, 0xc4, 0x1f, 0xb8, 0x27, 0x05, 0xb6, 0xc4, 0xf8, 0x26, 0xd1, 0x01, 0x0e, + 0xc4, 0xfd, 0xa2, 0x05, 0x9e, 0xbf, 0x33, 0x21, 0xfa, 0xe9, 0x09, 0x07, 0x9c, + 0xf1, 0x20, 0xe2, 0x2e, 0xcb, 0xd8, 0x85, 0x1e, 0xea, 0x34, 0xf6, 0xcf, 0xd2, + 0x38, 0xf7, 0xd8, 0x2b, 0xea, 0xe9, 0x02, 0xc3, 0xc4, 0x93, 0x09, 0xa4, 0xf6, + 0x1c, 0xe2, 0xe7, 0xea, 0xbd, 0x2f, 0xfa, 0x16, 0xca, 0xcb, 0xe0, 0xc7, 0xf2, + 0x22, 0x43, 0xbe, 0x00, 0xb9, 0xf5, 0xf5, 0xf8, 0x05, 0x7d, 0x20, 0x19, 0xed, + 0xc6, 0x03, 0xf2, 0x32, 0x18, 0xc0, 0x1c, 0x93, 0x1c, 0x0f, 0x04, 0x27, 0x81, + 0xdc, 0xcf, 0xbb, 0x00, 0xda, 0xbb, 0xe6, 0xac, 0xe9, 0x36, 0x05, 0x12, 0xfd, + 0x1e, 0xf1, 0xb4, 0xa2, 0x33, 0x10, 0xbf, 0x1f, 0xe8, 0x18, 0xc9, 0x29, 0x07, + 0x0b, 0x2e, 0xfa, 0xa7, 0x02, 0xd8, 0xca, 0xf3, 0xf0, 0xe3, 0x1e, 0xfd, 0xd8, + 0xf0, 0xe5, 0x04, 0x9b, 0xec, 0x11, 0xe5, 0xfa, 0x0e, 0x93, 0xe6, 0xdb, 0x06, + 0xe8, 0xf1, 0xe3, 0x36, 0xd8, 0xe5, 0x0b, 0x02, 0xb4, 0xeb, 0x06, 0xdb, 0x0e, + 0xf0, 0xd9, 0xb6, 0xb9, 0xcc, 0xbe, 0x09, 0x42, 0x13, 0xfd, 0x3e, 0x08, 0xf2, + 0xf1, 0x8f, 0xb2, 0xe7, 0xd1, 0xa4, 0xd8, 0x35, 0xf5, 0xef, 0xf7, 0xc9, 0xef, + 0x95, 0xc2, 0x03, 0xf0, 0xce, 0x2b, 0x20, 0xed, 0x2d, 0xfe, 0xe5, 0x4f, 0xb2, + 0xd0, 0xd9, 0xdc, 0x06, 0xe7, 0x0c, 0x22, 0x08, 0xf0, 0x2d, 0xf4, 0xbd, 0x23, + 0x24, 0x4b, 0xec, 0xe0, 0xde, 0xeb, 0xf2, 0x24, 0xcd, 0xf8, 0x23, 0xfa, 0x13, + 0xf8, 0xeb, 0x49, 0x06, 0xed, 0xca, 0xde, 0xb3, 0x65, 0x3c, 0xe1, 0x27, 0xf7, + 0x32, 0xd0, 0x21, 0x8b, 0x20, 0xec, 0xf4, 0x2e, 0xf3, 0xf6, 0x02, 0xc4, 0x23, + 0x06, 0x2d, 0x3a, 0xdc, 0x1e, 0xcd, 0x0c, 0xeb, 0xa6, 0xf9, 0xe1, 0x12, 0x2a, + 0x37, 0x57, 0x0b, 0xdc, 0xa2, 0xc4, 0x01, 0xbc, 0x4b, 0x45, 0x3d, 0x4f, 0x0a, + 0x5b, 0x26, 0x40, 0x33, 0x3a, 0x95, 0xa6, 0xda, 0x5f, 0xd6, 0xd9, 0xe3, 0xe5, + 0x37, 0xbe, 0xe4, 0x00, 0xe5, 0xba, 0x07, 0x53, 0x1d, 0x27, 0x1d, 0x0b, 0x38, + 0xcf, 0xc4, 0xf5, 0x21, 0x4e, 0xf2, 0x52, 0xdf, 0xf2, 0xc2, 0xf1, 0x14, 0x17, + 0xba, 0xb3, 0x95, 0x00, 0xee, 0xd2, 0xd6, 0x1f, 0x18, 0x03, 0x88, 0x25, 0xdb, + 0xf5, 0x13, 0x00, 0x2e, 0x04, 0xb3, 0x1e, 0xee, 0xd1, 0x12, 0x17, 0xd8, 0x2d, + 0xbf, 0xfe, 0x37, 0xf1, 0xe5, 0x1b, 0xeb, 0xe4, 0xe4, 0x59, 0xf7, 0x7b, 0x0d, + 0xd9, 0x9a, 0x18, 0x22, 0xdb, 0xb8, 0xf1, 0xe4, 0x32, 0xd8, 0xdd, 0xc0, 0xf5, + 0xef, 0xc6, 0x44, 0xca, 0x02, 0x4a, 0xf0, 0x11, 0x0e, 0x90, 0xf8, 0xf5, 0x08, + 0xfe, 0xad, 0xd5, 0x17, 0xe6, 0xd0, 0x8b, 0x65, 0xf9, 0xde, 0xfc, 0x32, 0x0f, + 0xc1, 0xd0, 0xb6, 0xd6, 0x21, 0x12, 0x13, 0xcc, 0xeb, 0x10, 0x2a, 0x4e, 0xd6, + 0x4c, 0x18, 0xbc, 0xe3, 0x2a, 0x06, 0xbe, 0xe8, 0xbb, 0x0c, 0xfe, 0xef, 0xc0, + 0xf4, 0xc0, 0xdc, 0x36, 0x14, 0x35, 0x10, 0x7f, 0xf2, 0x13, 0x15, 0xe1, 0x33, + 0x26, 0xd7, 0xf2, 0x30, 0xfd, 0xe0, 0x61, 0xd5, 0xc0, 0xea, 0x35, 0xb9, 0x9d, + 0x3f, 0x15, 0x14, 0xe7, 0xd6, 0xc1, 0x08, 0xc2, 0xd7, 0xeb, 0xd5, 0xe1, 0x2a, + 0xfe, 0xab, 0xf8, 0xee, 0xf8, 0x06, 0x24, 0xe8, 0x27, 0x0c, 0x26, 0x08, 0x0f, + 0xaf, 0x04, 0xbe, 0xf3, 0xe2, 0xdd, 0xdd, 0x58, 0xc8, 0x33, 0xf1, 0xeb, 0x1a, + 0xbc, 0x4c, 0xd9, 0xc7, 0xf7, 0xd0, 0xfb, 0xc6, 0xcf, 0x2d, 0xf9, 0xe4, 0xe9, + 0xe2, 0x40, 0xf3, 0x3e, 0xe6, 0xe5, 0x19, 0xda, 0x1c, 0x05, 0x00, 0xf7, 0xba, + 0x08, 0xf7, 0xd4, 0xd4, 0x5b, 0xf1, 0x25, 0xca, 0x0a, 0xd5, 0x00, 0xe6, 0xe9, + 0x13, 0x00, 0xa5, 0x38, 0xf8, 0xe1, 0x1c, 0xe0, 0x02, 0x42, 0x6a, 0xce, 0x08, + 0xe2, 0x30, 0x33, 0xf9, 0xdd, 0xe2, 0xcf, 0xf0, 0x51, 0x22, 0x0e, 0x29, 0x62, + 0xb8, 0xcb, 0x14, 0xd1, 0x98, 0xff, 0xd0, 0xb7, 0xc0, 0xdc, 0x0b, 0xfb, 0x52, + 0x47, 0xf8, 0x05, 0xe3, 0xd5, 0x19, 0x14, 0xf1, 0xeb, 0x04, 0x2f, 0xc7, 0x58, + 0xc6, 0xc3, 0xb7, 0xeb, 0xa0, 0x22, 0xd2, 0xe7, 0xb0, 0xe7, 0x0f, 0xfb, 0xbb, + 0x15, 0x29, 0xc9, 0xd5, 0x00, 0xf0, 0x16, 0xeb, 0xfe, 0x37, 0xdd, 0xf1, 0xc8, + 0xee, 0xdb, 0xfc, 0xe0, 0xbe, 0xfa, 0x05, 0xf3, 0xf8, 0xe0, 0x13, 0xf6, 0xd6, + 0x19, 0x30, 0xd0, 0xe9, 0x33, 0xd3, 0xe3, 0xb9, 0xc4, 0x45, 0xf5, 0xa5, 0x55, + 0xfe, 0xca, 0x02, 0xc2, 0x10, 0xd4, 0x15, 0x1e, 0xe0, 0xe6, 0x07, 0xed, 0x73, + 0x06, 0xf5, 0x1d, 0xda, 0x81, 0xd9, 0xfb, 0xfe, 0xf9, 0x16, 0x28, 0xde, 0x10, + 0xf0, 0xce, 0xf8, 0x2e, 0xe2, 0x34, 0x2d, 0x1c, 0x0a, 0xf4, 0x29, 0x1d, 0xe6, + 0x98, 0xc6, 0xb8, 0x38, 0x14, 0x11, 0xe7, 0xf9, 0x01, 0x2a, 0xee, 0x5e, 0xf9, + 0xfd, 0xf7, 0xc8, 0xfe, 0xf0, 0xbf, 0x2f, 0x9d, 0xc0, 0x1b, 0xd7, 0x1f, 0xd1, + 0xd7, 0xa3, 0xa9, 0x14, 0xdd, 0xe7, 0xe4, 0x03, 0x28, 0x52, 0x34, 0x1f, 0xbc, + 0xdd, 0xfb, 0x26, 0xc3, 0xef, 0x22, 0x4f, 0x24, 0xb3, 0xaf, 0x04, 0x01, 0x04, + 0x08, 0x22, 0xce, 0xf0, 0x24, 0x3d, 0xc0, 0xa1, 0x06, 0x01, 0x16, 0x18, 0x5a, + 0xdb, 0x42, 0x10, 0xc9, 0xf3, 0xf5, 0xfb, 0xfc, 0x00, 0x0c, 0xff, 0x05, 0xf0, + 0x1e, 0xdd, 0xd4, 0x53, 0xca, 0x09, 0xf7, 0x1c, 0xb1, 0x18, 0xbc, 0x13, 0x1b, + 0x02, 0x14, 0x52, 0x24, 0xf7, 0x36, 0xb4, 0x15, 0xde, 0x1d, 0xfe, 0xf7, 0x40, + 0xe9, 0xd4, 0x25, 0x47, 0x13, 0x39, 0x46, 0x37, 0xb0, 0xfc, 0x34, 0xf1, 0x0d, + 0x04, 0x1e, 0x77, 0xcd, 0x34, 0xbe, 0x03, 0xf1, 0x1a, 0x1f, 0xc3, 0xdc, 0x96, + 0xf2, 0x21, 0xef, 0x9f, 0xe6, 0xf9, 0xfd, 0x26, 0xf8, 0x07, 0xc9, 0xf2, 0xe3, + 0xbe, 0xb7, 0x27, 0xb8, 0x39, 0xfc, 0x50, 0x16, 0xe6, 0xd8, 0xf2, 0xcc, 0xb0, + 0x48, 0x26, 0xcc, 0xf7, 0xd5, 0x4f, 0xe4, 0xc5, 0x03, 0x1b, 0xfa, 0xa1, 0xd6, + 0x09, 0x1e, 0x0e, 0xfd, 0xb4, 0x1a, 0xce, 0xce, 0x0a, 0x37, 0x12, 0xce, 0xd9, + 0xd2, 0xfc, 0x30, 0xaf, 0x05, 0x19, 0x1c, 0x46, 0xdc, 0xc9, 0x3c, 0x13, 0xed, + 0x05, 0xe6, 0x08, 0x7f, 0x56, 0xc7, 0xeb, 0x98, 0x05, 0x3e, 0xf8, 0xe9, 0x32, + 0xfd, 0xb8, 0x31, 0xd7, 0xe9, 0x18, 0x1f, 0x2f, 0xf3, 0xc5, 0xe7, 0x07, 0xc7, + 0x2e, 0x8a, 0x12, 0xd9, 0x2e, 0xf7, 0x14, 0x36, 0xe5, 0x10, 0x37, 0xd0, 0x0b, + 0xe0, 0xb6, 0xfc, 0xd7, 0x07, 0xad, 0xe6, 0x05, 0xf0, 0xcc, 0x1f, 0xe7, 0x4d, + 0xef, 0x17, 0xe0, 0xee, 0xef, 0xe9, 0xa6, 0x13, 0xc9, 0xaf, 0xf6, 0x21, 0xce, + 0x2e, 0x30, 0x1a, 0xba, 0xfb, 0x57, 0x01, 0x8c, 0xe0, 0x13, 0x09, 0x20, 0xe1, + 0x3b, 0xfb, 0xec, 0xf7, 0x27, 0xe8, 0x16, 0xc1, 0xe7, 0x0f, 0xb2, 0xd8, 0x16, + 0x0f, 0x3d, 0xe6, 0x49, 0xe4, 0x0c, 0x3a, 0x0e, 0xcf, 0x34, 0xf4, 0x2c, 0xf8, + 0xdd, 0x08, 0xd5, 0xf6, 0xf0, 0xdc, 0xfa, 0xe5, 0x17, 0xce, 0x4f, 0xb6, 0xdc, + 0x36, 0xde, 0x20, 0x32, 0xe4, 0xc0, 0x0d, 0x39, 0xf6, 0xf3, 0x0d, 0x14, 0xf9, + 0x0b, 0x2d, 0x5d, 0x42, 0xd1, 0x45, 0x14, 0xc7, 0x0c, 0xae, 0xeb, 0xbb, 0x32, + 0x0b, 0x04, 0xf5, 0x9c, 0xf2, 0xef, 0xc0, 0x4b, 0xf1, 0xb3, 0x2e, 0x13, 0x35, + 0xf4, 0xf3, 0x12, 0xfc, 0xcd, 0xed, 0xf4, 0xac, 0xd1, 0x04, 0xe9, 0xa9, 0x07, + 0xda, 0x50, 0xc7, 0xd4, 0x1e, 0xe8, 0xeb, 0x1e, 0x08, 0x4c, 0xe7, 0x57, 0xec, + 0xff, 0x04, 0xd6, 0x15, 0xcc, 0x56, 0x00, 0x0b, 0xeb, 0xe5, 0x50, 0x09, 0x16, + 0xf2, 0xd9, 0xdc, 0xf0, 0xee, 0x37, 0x26, 0x06, 0x0c, 0x20, 0xec, 0x1c, 0x0f, + 0x3c, 0xdc, 0xe6, 0x25, 0xdb, 0x04, 0x0d, 0x1c, 0x43, 0xf3, 0x23, 0x1b, 0x3a, + 0x11, 0x25, 0x02, 0xa6, 0x07, 0x06, 0xfb, 0xc9, 0xed, 0x59, 0x05, 0x1c, 0x03, + 0xde, 0x03, 0x45, 0x0d, 0xd0, 0x01, 0x33, 0x22, 0x0c, 0xfb, 0xc2, 0xf1, 0xd8, + 0xc3, 0xf0, 0x4b, 0xc3, 0x05, 0x20, 0x41, 0xcf, 0xde, 0xd7, 0x17, 0x12, 0x34, + 0xff, 0xfb, 0xe2, 0x10, 0xeb, 0xdb, 0xcd, 0x07, 0xdb, 0xed, 0xd9, 0x1e, 0x4a, + 0x2b, 0xf4, 0xab, 0xfd, 0x31, 0x04, 0xed, 0x02, 0x1c, 0xc5, 0x7e, 0xde, 0xb9, + 0x16, 0xb1, 0x05, 0x0a, 0xf2, 0xc6, 0x20, 0x1b, 0x14, 0xce, 0x4d, 0xe7, 0xf2, + 0x1b, 0xe0, 0xf8, 0x03, 0x15, 0x07, 0x19, 0x14, 0xfb, 0xeb, 0xb9, 0xbc, 0x25, + 0x0c, 0xd1, 0xfc, 0xe4, 0x34, 0xd0, 0x81, 0x0c, 0xe7, 0x07, 0x04, 0xd3, 0x34, + 0xe2, 0xc1, 0xdc, 0xd7, 0xd6, 0xe3, 0x34, 0x9d, 0xd9, 0xbc, 0x26, 0xb0, 0xbb, + 0x25, 0xdd, 0xe6, 0xdb, 0xf2, 0xe7, 0x00, 0x23, 0x06, 0x4c, 0xd9, 0x04, 0xc9, + 0x3b, 0x19, 0x0c, 0x06, 0x23, 0x1e, 0xf7, 0xe8, 0xf1, 0x32, 0x34, 0xe3, 0xd2, + 0xe5, 0xf5, 0x24, 0xf3, 0x31, 0x18, 0xef, 0xf4, 0x10, 0x0d, 0xc3, 0xed, 0x0d, + 0x3d, 0x0d, 0xfb, 0xc0, 0xda, 0x2a, 0xde, 0xee, 0x2d, 0x15, 0xfc, 0x03, 0xef, + 0x01, 0xe0, 0x2c, 0xee, 0xe4, 0x4b, 0x35, 0xcb, 0x2d, 0x1f, 0xb8, 0xdd, 0xc8, + 0xdc, 0x24, 0xdd, 0x16, 0x02, 0xd0, 0xe1, 0xd1, 0xbf, 0xea, 0x35, 0xe6, 0x8d, + 0x1b, 0xef, 0x5e, 0x0e, 0xd0, 0xe0, 0x16, 0x66, 0x18, 0x81, 0xce, 0x2c, 0x30, + 0xbd, 0xc9, 0x1a, 0x44, 0x0c, 0xfd, 0xdc, 0x04, 0xc4, 0xfa, 0xfd, 0x1b, 0x2f, + 0x04, 0xee, 0x0c, 0x0d, 0x04, 0xd4, 0x21, 0x2b, 0xd7, 0xb5, 0x33, 0x11, 0xc7, + 0xe2, 0xb2, 0x03, 0xf7, 0x00, 0x05, 0xd8, 0x5f, 0xb2, 0x27, 0x81, 0xdb, 0xa8, + 0xe5, 0xdf, 0x32, 0xf3, 0xb8, 0x13, 0xf7, 0xf2, 0xf3, 0x0f, 0x24, 0xb3, 0x1e, + 0x2e, 0xc0, 0xdc, 0xdf, 0xff, 0x36, 0x89, 0x3e, 0x30, 0xf5, 0xe2, 0x21, 0xf0, + 0x2b, 0x19, 0x10, 0xfa, 0x05, 0x3a, 0x06, 0xff, 0x1c, 0xb4, 0xff, 0xcd, 0xd9, + 0xe6, 0xf1, 0x37, 0x04, 0x19, 0xfe, 0xf2, 0xfa, 0xfb, 0x5a, 0x9d, 0xd3, 0x1e, + 0xa7, 0xb0, 0x27, 0xb0, 0xd9, 0x47, 0x3b, 0xfb, 0xf6, 0xcc, 0xf8, 0xd5, 0xdc, + 0xd9, 0xc2, 0xee, 0xc0, 0x0d, 0xf7, 0xd9, 0xc7, 0x1f, 0xd5, 0xee, 0xfd, 0xe4, + 0xea, 0x01, 0xef, 0x23, 0xfa, 0xee, 0xcf, 0xee, 0xab, 0xbb, 0x1a, 0x21, 0xdf, + 0x3f, 0x06, 0xd3, 0xd8, 0xf8, 0x2f, 0x99, 0xad, 0x06, 0xb8, 0xd7, 0x0b, 0x23, + 0x19, 0x1a, 0xc5, 0x28, 0xa5, 0x54, 0x4a, 0x14, 0x53, 0x9a, 0xd2, 0x12, 0xda, + 0x13, 0x3b, 0xf2, 0x2d, 0x0c, 0xca, 0x13, 0xe7, 0xd2, 0x07, 0xe8, 0xde, 0xb1, + 0x43, 0xcd, 0x37, 0xd6, 0xfe, 0xe9, 0xf7, 0xc0, 0x56, 0xfe, 0xc6, 0xdd, 0xf9, + 0x0b, 0xd8, 0x12, 0xe6, 0x02, 0x2b, 0x8c, 0x41, 0xb1, 0xd6, 0xaf, 0xf9, 0x26, + 0xd5, 0xc9, 0xff, 0xd8, 0x37, 0xcc, 0xf4, 0x03, 0x22, 0x40, 0x08, 0xcb, 0xcd, + 0xb1, 0xb6, 0x1c, 0xe4, 0xe1, 0xaf, 0xf8, 0xf8, 0xc2, 0xd5, 0xec, 0x29, 0xf1, + 0xe3, 0x27, 0xef, 0xf9, 0xc7, 0x08, 0x1f, 0xf0, 0xb3, 0x0a, 0x28, 0x4a, 0xea, + 0xb9, 0x08, 0x13, 0xff, 0x03, 0x52, 0x1c, 0xfb, 0x0a, 0xec, 0x02, 0x05, 0xcb, + 0x0c, 0xe0, 0x08, 0xf2, 0xf3, 0xd6, 0xe1, 0x2e, 0xf8, 0xc6, 0x0a, 0xf7, 0xc3, + 0x4a, 0x2f, 0xdd, 0x0a, 0xef, 0x1b, 0xfd, 0x10, 0xd7, 0xd1, 0xcb, 0x11, 0xfa, + 0x41, 0xc4, 0xdc, 0xf3, 0xfb, 0x3a, 0xee, 0xde, 0x12, 0x22, 0xef, 0x04, 0x24, + 0xb7, 0xd5, 0xe1, 0x07, 0x10, 0x1f, 0xb2, 0xc4, 0xd5, 0xc0, 0x30, 0xdf, 0xe9, + 0x28, 0x14, 0xe1, 0x02, 0x24, 0x27, 0x08, 0x25, 0x2f, 0x23, 0x05, 0x24, 0x00, + 0x26, 0xac, 0xb8, 0x02, 0xd5, 0x3d, 0xf0, 0x35, 0xd8, 0xe9, 0xeb, 0x6d, 0xe1, + 0xee, 0xf5, 0xfa, 0x4c, 0x27, 0x0d, 0x1d, 0xf2, 0xfb, 0xd6, 0x17, 0xf1, 0x1d, + 0xc9, 0x1a, 0x08, 0x30, 0x29, 0x17, 0xda, 0x18, 0x28, 0xea, 0x12, 0xf2, 0xf7, + 0x10, 0x3f, 0xe2, 0xe2, 0xe7, 0xfc, 0xcf, 0x1d, 0x1a, 0x07, 0xe3, 0x0e, 0xd8, + 0x1a, 0xde, 0x11, 0xf9, 0x0d, 0xa7, 0x1e, 0x37, 0x04, 0x4e, 0xcb, 0xe9, 0x28, + 0xee, 0xc5, 0xd4, 0xe9, 0xe6, 0x16, 0x16, 0x0e, 0xe8, 0x51, 0x07, 0xe6, 0xf5, + 0x00, 0xbd, 0xce, 0xc7, 0xb8, 0xed, 0x0b, 0xe2, 0x0e, 0xc0, 0x1a, 0xfc, 0xc4, + 0xc1, 0x0f, 0xe9, 0x0d, 0xcc, 0xd3, 0x28, 0x0c, 0x7f, 0xb2, 0x00, 0x22, 0xcb, + 0xe1, 0x26, 0xdb, 0x14, 0xec, 0x11, 0x27, 0x06, 0xb4, 0xff, 0xbf, 0x0b, 0x27, + 0xcb, 0xf5, 0xf8, 0x02, 0x23, 0x06, 0xc7, 0xcb, 0xfa, 0xef, 0x9a, 0x03, 0x13, + 0xce, 0x04, 0x09, 0x13, 0xe5, 0x24, 0x2a, 0x32, 0x10, 0xb8, 0xeb, 0xff, 0xe2, + 0x24, 0x14, 0xfb, 0xa5, 0xfe, 0x26, 0xc7, 0x9c, 0xe2, 0x6e, 0xd6, 0xe5, 0xd1, + 0x1d, 0xee, 0xd1, 0xf2, 0x02, 0xa7, 0x81, 0x7b, 0xe1, 0x13, 0x20, 0x1d, 0xc7, + 0x2f, 0xcf, 0x9a, 0x4f, 0xb3, 0x53, 0xc7, 0xcb, 0x05, 0x77, 0xc2, 0xa3, 0x67, + 0x98, 0x32, 0xc4, 0xe4, 0x19, 0xf6, 0x46, 0x39, 0x8d, 0xc1, 0x26, 0x37, 0xc2, + 0xf2, 0x53, 0xc6, 0x1f, 0x74, 0xf2, 0x0f, 0xc0, 0x5e, 0xf5, 0xcd, 0x49, 0x01, + 0x13, 0xfa, 0xd3, 0xe4, 0xce, 0xd8, 0xea, 0x1e, 0x21, 0xd2, 0xf9, 0x07, 0xaa, + 0x16, 0x2d, 0x25, 0xe7, 0x47, 0x0e, 0x0f, 0x24, 0xb3, 0xd6, 0xc4, 0x4b, 0x61, + 0xc4, 0xf4, 0xda, 0x06, 0xca, 0xc8, 0x15, 0x3d, 0x40, 0xfd, 0x1b, 0xdc, 0x9b, + 0x20, 0x07, 0xfc, 0x37, 0xc9, 0xc0, 0xa2, 0x95, 0xad, 0x41, 0x36, 0xd9, 0xac, + 0xfe, 0x13, 0xe5, 0x45, 0x2b, 0x1e, 0xec, 0x4c, 0x33, 0xdd, 0xf3, 0xd7, 0x1f, + 0xde, 0xf2, 0x2e, 0xf1, 0x12, 0xc3, 0xdf, 0xcf, 0x01, 0xda, 0xbd, 0xc5, 0x1a, + 0x29, 0x1b, 0x33, 0xec, 0xc3, 0xd7, 0xbe, 0x52, 0xe3, 0x25, 0x35, 0x16, 0x0a, + 0x3f, 0xae, 0x31, 0xd1, 0xef, 0xc5, 0xb7, 0xfa, 0x2e, 0x15, 0xbf, 0x3c, 0xb7, + 0x10, 0xba, 0xdc, 0x4a, 0x52, 0x68, 0x15, 0x50, 0x53, 0x2d, 0x95, 0x04, 0x0a, + 0x1f, 0x67, 0x2d, 0xbd, 0x28, 0xc6, 0xe9, 0x1d, 0xf1, 0xf8, 0xf2, 0xfd, 0x2c, + 0xec, 0xbf, 0x2d, 0xd4, 0xde, 0xdb, 0x5f, 0xdf, 0xff, 0xea, 0x15, 0xe6, 0xd6, + 0x15, 0x07, 0xf3, 0xed, 0xf1, 0xe4, 0xf0, 0x37, 0xd7, 0x90, 0xb8, 0xd3, 0x4a, + 0xd6, 0x14, 0x3b, 0xea, 0xf9, 0x32, 0x07, 0xe0, 0x15, 0x10, 0x2a, 0x16, 0xbb, + 0x10, 0xc8, 0x08, 0xca, 0x11, 0xfb, 0xb2, 0x17, 0xf1, 0x13, 0x18, 0xfe, 0xc9, + 0xe5, 0xa5, 0x2b, 0x05, 0x07, 0xef, 0x07, 0x13, 0xcd, 0x4e, 0xdc, 0x32, 0xef, + 0x1f, 0x24, 0x0d, 0x37, 0xfc, 0xf2, 0xbe, 0xea, 0xfa, 0x27, 0xa7, 0xd4, 0xe9, + 0xc8, 0x01, 0x0c, 0xf0, 0xc9, 0xeb, 0xcf, 0x51, 0x26, 0xd9, 0x0f, 0xfc, 0xcf, + 0xf2, 0x16, 0x0a, 0x0c, 0x1a, 0xe9, 0xef, 0x48, 0xf0, 0x56, 0xf0, 0xd8, 0xb2, + 0xfa, 0xa6, 0x2c, 0xb9, 0xb1, 0x15, 0x00, 0xd3, 0xf7, 0xf8, 0x27, 0xe3, 0xfd, + 0x1d, 0xff, 0xb6, 0x40, 0xef, 0x2a, 0xca, 0xdd, 0x02, 0x98, 0x12, 0x34, 0x1a, + 0x30, 0xcb, 0xf9, 0x3a, 0xd8, 0x30, 0xfb, 0x97, 0x2d, 0xb0, 0x1a, 0xa4, 0xc1, + 0xcc, 0x0c, 0xf0, 0x1b, 0x3e, 0xf1, 0x05, 0xff, 0xdb, 0x11, 0xac, 0xcd, 0xad, + 0x05, 0x0c, 0x0b, 0xf5, 0x12, 0x15, 0xf9, 0x32, 0xf0, 0xbc, 0xa9, 0x32, 0x0d, + 0xe9, 0xfc, 0xcc, 0xeb, 0x36, 0x7a, 0xf6, 0xc4, 0xff, 0xff, 0x24, 0xb2, 0xcc, + 0x47, 0xd5, 0x04, 0xe1, 0x7f, 0x21, 0xea, 0x16, 0xe2, 0x3e, 0x22, 0xcb, 0xf4, + 0xc9, 0x32, 0x36, 0xf4, 0xe8, 0x54, 0x34, 0x22, 0x3f, 0x26, 0xe2, 0xc4, 0xf8, + 0xcd, 0x29, 0xdc, 0x0f, 0xc8, 0xec, 0xc5, 0x29, 0x66, 0xe1, 0xf5, 0x54, 0xd0, + 0x00, 0x2a, 0xe2, 0x99, 0xc6, 0x11, 0xf8, 0x28, 0xf5, 0xdc, 0x2f, 0x06, 0x06, + 0x1c, 0x12, 0xd8, 0x3e, 0xba, 0xd9, 0x2f, 0x4c, 0xb6, 0x0d, 0x00, 0x25, 0x38, + 0x31, 0xe2, 0xdc, 0xd9, 0x3d, 0x65, 0x00, 0x40, 0x2f, 0xd2, 0x5d, 0xb4, 0xd7, + 0x45, 0x2b, 0x51, 0x39, 0x03, 0xf6, 0x2a, 0x06, 0x98, 0x07, 0xf5, 0x0f, 0xf5, + 0x69, 0x31, 0x2a, 0x06, 0x01, 0x38, 0xc3, 0xe0, 0xf9, 0x07, 0xfa, 0xd7, 0x15, + 0x10, 0x20, 0xf2, 0xf0, 0xc8, 0x02, 0xf2, 0x59, 0xd7, 0xcb, 0x10, 0xf9, 0x2a, + 0x1a, 0x09, 0xfc, 0xce, 0x2c, 0xe9, 0xc3, 0xd4, 0xe0, 0xb6, 0x02, 0xe4, 0xdb, + 0x29, 0xff, 0xc0, 0x3e, 0xc2, 0xfd, 0xf4, 0xeb, 0xfa, 0xf9, 0x11, 0x3b, 0x06, + 0xb6, 0x2c, 0x1d, 0xa9, 0x0c, 0xe0, 0x25, 0x00, 0xf0, 0xef, 0x29, 0xdd, 0xe1, + 0xdc, 0x17, 0xda, 0xf9, 0xe9, 0x3d, 0xff, 0x0a, 0xbe, 0xe4, 0x1e, 0x03, 0xd8, + 0x3e, 0x21, 0xb8, 0x01, 0x41, 0x0c, 0xb8, 0xe7, 0x42, 0x82, 0x28, 0x2a, 0xd4, + 0xe4, 0xee, 0xe1, 0xd4, 0x3e, 0xc5, 0xd5, 0xca, 0x41, 0x34, 0xdb, 0x20, 0x05, + 0x1b, 0x3b, 0x20, 0xd4, 0x1d, 0xa4, 0xe4, 0x00, 0xac, 0x67, 0xc5, 0xe4, 0x35, + 0x36, 0x04, 0x37, 0x13, 0xf0, 0xcc, 0xbb, 0xd5, 0xe2, 0x42, 0xac, 0x16, 0xfd, + 0xca, 0xfe, 0xc8, 0x42, 0x38, 0x29, 0x3a, 0xb5, 0xbc, 0xd6, 0x9a, 0x34, 0x08, + 0xd7, 0x9a, 0x36, 0x2e, 0x0e, 0x33, 0xb8, 0xfc, 0xda, 0x94, 0x06, 0xb7, 0xaa, + 0x33, 0xf2, 0xec, 0x9d, 0x10, 0xb7, 0x29, 0xc4, 0x73, 0x26, 0x4c, 0x09, 0x79, + 0x01, 0xfd, 0x34, 0xe3, 0xdd, 0xe5, 0x9f, 0xd2, 0x1d, 0x25, 0xa3, 0xfe, 0xf7, + 0xf2, 0x16, 0xf4, 0x33, 0x23, 0xf3, 0xca, 0x0d, 0x20, 0xe5, 0x37, 0xf2, 0xe6, + 0x38, 0x39, 0xf4, 0xf7, 0xf2, 0x53, 0xfe, 0xd5, 0xe9, 0x33, 0x17, 0xdb, 0x06, + 0xf4, 0xe9, 0xec, 0xca, 0x83, 0xb4, 0xf8, 0x15, 0x4f, 0x7a, 0xea, 0x0f, 0xfc, + 0xe5, 0x95, 0x36, 0x37, 0xe1, 0xf4, 0x51, 0xde, 0x0d, 0x04, 0x27, 0x3e, 0x32, + 0x10, 0xf2, 0xf1, 0xa1, 0xa8, 0x1f, 0xe4, 0x15, 0xee, 0xd7, 0x2b, 0xd0, 0xdd, + 0xd9, 0xdc, 0x08, 0xe6, 0xc2, 0xe8, 0xae, 0xe9, 0xd0, 0x04, 0xc3, 0xeb, 0x32, + 0x8f, 0x02, 0xa4, 0x2f, 0x97, 0xed, 0xd0, 0x00, 0xc1, 0xdd, 0x00, 0xf5, 0x1e, + 0x34, 0xed, 0x22, 0xfd, 0x0e, 0xe2, 0x48, 0x81, 0x15, 0x42, 0x3e, 0xe0, 0x59, + 0xe6, 0xf7, 0x5f, 0xe5, 0xcf, 0xaf, 0x3f, 0xfb, 0xfc, 0x17, 0x34, 0x1d, 0xe4, + 0x06, 0xb6, 0xe9, 0x20, 0xeb, 0xbc, 0xe5, 0xdb, 0xbd, 0xc4, 0x3f, 0xce, 0xe6, + 0x88, 0x20, 0xd3, 0xf3, 0xcf, 0x1c, 0xba, 0xe9, 0x13, 0xd3, 0xc3, 0xfd, 0xf1, + 0xdd, 0x53, 0xe6, 0x43, 0xf7, 0xaa, 0xdd, 0xde, 0xf9, 0xfb, 0xe6, 0xd9, 0xc3, + 0x16, 0xb1, 0xdd, 0xe3, 0x11, 0x36, 0xf4, 0xf9, 0xb7, 0xbd, 0xaa, 0x2f, 0xa0, + 0xd8, 0xfc, 0x1e, 0xb7, 0x47, 0x00, 0x32, 0x10, 0x16, 0xf4, 0x6e, 0x16, 0xce, + 0xde, 0x00, 0xea, 0xdf, 0x25, 0x32, 0xfa, 0x2e, 0x57, 0x2b, 0x0d, 0xb2, 0xde, + 0xf6, 0xd6, 0x4b, 0xe4, 0x22, 0xe5, 0x11, 0xd8, 0xdd, 0xcc, 0xd3, 0xc2, 0xc7, + 0x30, 0xc8, 0x22, 0xac, 0xe5, 0xd5, 0xf8, 0xf7, 0xf9, 0x24, 0xab, 0x24, 0xdc, + 0x15, 0xf2, 0xb3, 0x02, 0x19, 0xfa, 0x31, 0xc5, 0xd1, 0xf3, 0xea, 0xd6, 0xca, + 0x05, 0xe8, 0xdf, 0xe4, 0x09, 0x1a, 0xd4, 0xe4, 0x7f, 0x49, 0xb3, 0xdf, 0xaa, + 0xf2, 0x07, 0xdb, 0x16, 0x21, 0x21, 0x1e, 0xfb, 0xd9, 0xda, 0x0b, 0x15, 0xab, + 0x1d, 0xf7, 0x33, 0x37, 0xe3, 0x07, 0xd3, 0xe6, 0xb3, 0xf1, 0x19, 0xfe, 0xf0, + 0xd3, 0xba, 0xff, 0xe1, 0xfd, 0xcc, 0x26, 0xdd, 0x3c, 0x31, 0xef, 0xd8, 0xbe, + 0x36, 0xf3, 0xd5, 0xd5, 0xe8, 0xf5, 0x09, 0x28, 0x43, 0x1b, 0x10, 0xbd, 0x9a, + 0xdb, 0x2c, 0xdf, 0xc5, 0xe0, 0xc7, 0x1f, 0xda, 0x00, 0xd1, 0x0b, 0xba, 0xfd, + 0x0c, 0x2f, 0xc0, 0xf5, 0xf1, 0x09, 0xef, 0x06, 0x1c, 0xee, 0xfa, 0xf9, 0xf5, + 0xea, 0x9a, 0xec, 0x30, 0xf6, 0x0c, 0xbe, 0xe4, 0x06, 0xed, 0x62, 0xa9, 0xd2, + 0xc8, 0xf0, 0xfb, 0x4a, 0xf9, 0xee, 0x4d, 0xca, 0xd0, 0xdf, 0x04, 0xf5, 0x06, + 0x17, 0x3e, 0x69, 0x0b, 0x3d, 0x46, 0x9f, 0xef, 0x05, 0xb3, 0xe6, 0xc9, 0xaa, + 0x19, 0xd9, 0x1d, 0xc8, 0x0d, 0x0e, 0xd0, 0x56, 0x2a, 0xef, 0x3b, 0x6a, 0x45, + 0xad, 0x9b, 0x0d, 0xcb, 0x39, 0xd5, 0x2b, 0xf2, 0xe9, 0x20, 0xfc, 0x19, 0xd9, + 0xb7, 0xd6, 0xf0, 0xd4, 0x0a, 0xfc, 0x14, 0x11, 0xfe, 0xdb, 0x02, 0x0b, 0x11, + 0x01, 0xea, 0xa8, 0x15, 0xc9, 0x9f, 0xf0, 0xdf, 0xdf, 0xdb, 0x06, 0xee, 0xda, + 0xe1, 0xf9, 0xc2, 0x13, 0xff, 0x1b, 0x27, 0xe8, 0xf7, 0xe2, 0xf2, 0xc0, 0x13, + 0xb3, 0xf7, 0xd5, 0xdb, 0x41, 0xf4, 0xd6, 0xe5, 0xf9, 0xa2, 0xf3, 0x1a, 0x61, + 0xd6, 0x18, 0xf2, 0xf7, 0x05, 0xec, 0xdf, 0xe1, 0x44, 0xe6, 0x1d, 0x2e, 0xdf, + 0x1a, 0x42, 0xf3, 0xe0, 0x11, 0x02, 0xf0, 0xec, 0x55, 0xef, 0x01, 0xe9, 0xcd, + 0xfc, 0x0a, 0x28, 0x32, 0x38, 0x28, 0x4e, 0x57, 0x13, 0xd5, 0xf2, 0xd2, 0xda, + 0x00, 0xe6, 0x28, 0x03, 0xf3, 0xbd, 0x4c, 0x54, 0xd6, 0x01, 0xf9, 0x2e, 0x54, + 0xde, 0x25, 0x05, 0xe3, 0xbc, 0x0e, 0xa7, 0xa6, 0xd2, 0xf2, 0xc8, 0x0a, 0xcc, + 0xf1, 0xd8, 0x0f, 0x07, 0xf2, 0xf6, 0x4b, 0xf5, 0xb6, 0x08, 0xd4, 0xf9, 0x23, + 0xd4, 0xc6, 0x11, 0xd3, 0x78, 0x06, 0x3a, 0x03, 0xfc, 0x25, 0xee, 0x2b, 0xd0, + 0x27, 0x37, 0x04, 0x4c, 0xc7, 0xe2, 0xe9, 0xc3, 0xd3, 0xd4, 0xf0, 0xed, 0xe4, + 0x12, 0x45, 0xdb, 0x01, 0xf1, 0xf7, 0xd3, 0x43, 0x04, 0x3c, 0x1c, 0xfd, 0x40, + 0x10, 0x84, 0x4e, 0xe4, 0x1b, 0x03, 0x15, 0xae, 0xde, 0x05, 0xfb, 0x00, 0x26, + 0xd5, 0xc3, 0x20, 0x32, 0x21, 0xf1, 0xd9, 0xb2, 0x23, 0xf8, 0xf8, 0xf7, 0xe7, + 0x2b, 0xf4, 0xc8, 0xfe, 0x78, 0x22, 0x72, 0xdc, 0xf0, 0x2d, 0x1d, 0xc1, 0x22, + 0x10, 0x60, 0x45, 0x45, 0xc1, 0x60, 0xcc, 0x81, 0x16, 0xd3, 0xc6, 0xcd, 0xfe, + 0xc7, 0xcd, 0x07, 0xe8, 0xbf, 0xfb, 0xfb, 0xd5, 0x0b, 0x1f, 0xeb, 0x1c, 0x24, + 0xef, 0x19, 0xde, 0xc6, 0xbf, 0x00, 0xc9, 0x08, 0x11, 0xed, 0xf0, 0xf8, 0xf3, + 0xd3, 0x2f, 0xe9, 0xe8, 0xc0, 0xdf, 0xf4, 0x30, 0xe6, 0x1d, 0xff, 0xe6, 0xed, + 0x2d, 0xb2, 0xb9, 0xfd, 0xd0, 0x95, 0x2b, 0xd2, 0x38, 0x1f, 0xc2, 0x0f, 0x14, + 0xb8, 0x09, 0x07, 0xff, 0x02, 0xe7, 0xe2, 0xcc, 0x29, 0x12, 0xf1, 0x09, 0x01, + 0xc4, 0x01, 0xb7, 0xd6, 0xc5, 0xdf, 0xd8, 0xff, 0x12, 0x14, 0x1f, 0xb9, 0x1b, + 0x1b, 0x53, 0xc4, 0x02, 0xee, 0xd9, 0xcf, 0xeb, 0xc2, 0xd9, 0x0a, 0x35, 0x09, + 0xf2, 0x0e, 0x04, 0x65, 0xee, 0xad, 0x10, 0x05, 0x2c, 0x14, 0x19, 0xf3, 0x12, + 0xb7, 0x1e, 0x24, 0xe7, 0xc9, 0x24, 0xec, 0xf7, 0x24, 0x07, 0x2d, 0xce, 0x3c, + 0xf0, 0xef, 0x1b, 0xe6, 0x05, 0xb0, 0xf7, 0xe9, 0x13, 0xdb, 0xea, 0xdb, 0xff, + 0x06, 0xd8, 0x25, 0x2c, 0xc5, 0x03, 0xe0, 0xec, 0xef, 0x02, 0x04, 0xdd, 0xd7, + 0x02, 0xd3, 0xed, 0x0b, 0x1e, 0x01, 0xe7, 0xdf, 0xcb, 0xf9, 0xba, 0x02, 0xde, + 0x3b, 0x14, 0xee, 0x28, 0x2f, 0xf6, 0x1b, 0x0b, 0x20, 0x30, 0xfe, 0xf8, 0xed, + 0x1b, 0x04, 0x02, 0xef, 0xc3, 0xf5, 0x06, 0xe3, 0xe8, 0xe8, 0x24, 0x19, 0x1a, + 0xc7, 0x0c, 0x83, 0xe1, 0x7f, 0xe3, 0xc4, 0xf0, 0x00, 0xfc, 0xff, 0xfa, 0x0a, + 0xf9, 0xf7, 0x12, 0x09, 0x2f, 0xf1, 0xef, 0x6b, 0xd0, 0x1c, 0x3a, 0x02, 0xc1, + 0xde, 0x05, 0x23, 0xe8, 0xf2, 0xc9, 0xf2, 0xf0, 0x30, 0xf8, 0x02, 0xae, 0xac, + 0xcc, 0xc9, 0x20, 0x02, 0x14, 0xec, 0xd9, 0xb3, 0xf7, 0xcb, 0x03, 0x09, 0xd3, + 0x13, 0x93, 0xe0, 0xa5, 0xf1, 0xe2, 0xe1, 0xe1, 0x02, 0xd0, 0xeb, 0x05, 0x1e, + 0xdb, 0xc0, 0xf7, 0x3f, 0x2e, 0xbc, 0xfb, 0x33, 0xf7, 0x1f, 0x48, 0x11, 0x18, + 0x2a, 0x31, 0x3a, 0x01, 0x2f, 0xd6, 0xce, 0x05, 0xfd, 0xc2, 0x40, 0xf5, 0xef, + 0x06, 0x9d, 0x1a, 0xe2, 0xae, 0xe4, 0x0a, 0xb7, 0xd3, 0x07, 0x33, 0x01, 0x16, + 0x0d, 0xeb, 0xe7, 0xfc, 0x09, 0xda, 0xd9, 0xc5, 0x01, 0xfa, 0xce, 0xf3, 0xe2, + 0xd5, 0xe7, 0xc1, 0xdc, 0x1f, 0x1d, 0xc3, 0xfa, 0xc0, 0xe8, 0xf4, 0xe3, 0xba, + 0xe5, 0xe5, 0x06, 0x06, 0x3b, 0xff, 0x18, 0xac, 0xdc, 0x25, 0xd5, 0xe3, 0x32, + 0xc3, 0xb8, 0x13, 0x28, 0xed, 0x1f, 0xc9, 0xf2, 0xe7, 0x0a, 0xfa, 0xbc, 0x66, + 0xfa, 0xf6, 0xeb, 0xfa, 0xca, 0xe0, 0x17, 0x1d, 0xf7, 0x11, 0xfc, 0xf6, 0xd4, + 0x08, 0xde, 0xe6, 0x38, 0x0d, 0x25, 0xa9, 0xd9, 0xe0, 0x2f, 0x0b, 0xd0, 0x08, + 0xd6, 0xfa, 0x1f, 0x3e, 0xcf, 0xed, 0xfd, 0xaf, 0xb7, 0xc0, 0xf6, 0xf3, 0x0f, + 0x44, 0x8b, 0xd8, 0xf3, 0xc8, 0xf4, 0x1e, 0xf2, 0xe3, 0x97, 0xac, 0x0c, 0x15, + 0xee, 0x16, 0xed, 0xef, 0xe5, 0x15, 0xdb, 0x4c, 0xad, 0xdc, 0x20, 0xbe, 0xcb, + 0xf2, 0xb7, 0x00, 0x1f, 0xd7, 0xc2, 0x0e, 0xb1, 0x2a, 0x24, 0xdb, 0x2f, 0xd6, + 0x09, 0xe7, 0xe5, 0xf5, 0x36, 0x2d, 0xc0, 0xea, 0x38, 0x28, 0x15, 0x0a, 0xb5, + 0x26, 0x05, 0x05, 0x8b, 0xef, 0xf8, 0x1d, 0xfb, 0xdb, 0xef, 0x08, 0xec, 0x29, + 0xe5, 0x0c, 0x56, 0xbf, 0xf7, 0xfd, 0x08, 0xf6, 0x50, 0xed, 0x00, 0x0b, 0xc9, + 0xe0, 0x0f, 0xf2, 0xdc, 0xef, 0x1c, 0xb0, 0xe6, 0xc6, 0x00, 0x1e, 0xbf, 0x44, + 0xe4, 0xed, 0x07, 0x09, 0xfa, 0x01, 0xfd, 0xf6, 0x25, 0xe1, 0xdf, 0x72, 0xbb, + 0xfb, 0xb5, 0xe9, 0xb8, 0xbb, 0xb6, 0x7f, 0xdd, 0xe6, 0x0a, 0xda, 0x72, 0xd2, + 0x18, 0xc4, 0xc2, 0x03, 0x12, 0x09, 0xee, 0x16, 0x8b, 0x15, 0x11, 0x16, 0xfe, + 0xe7, 0xef, 0x26, 0x32, 0xdd, 0x08, 0xf9, 0x08, 0x2a, 0xb3, 0xd9, 0x5f, 0xe4, + 0x0f, 0xe6, 0xbc, 0x41, 0x1b, 0x02, 0xd9, 0xf0, 0x00, 0x45, 0xed, 0xe6, 0x16, + 0xc5, 0x12, 0x20, 0xf9, 0x08, 0x19, 0x2b, 0xd1, 0x02, 0xda, 0xf6, 0x1a, 0xff, + 0x08, 0x03, 0xdb, 0xed, 0xf9, 0xc9, 0x1b, 0xe3, 0x13, 0x17, 0x13, 0x3b, 0x2d, + 0x1d, 0xe5, 0xfb, 0xfd, 0xef, 0x28, 0x06, 0xc8, 0xc2, 0xd3, 0xcc, 0xaa, 0xd6, + 0xf8, 0xf8, 0x37, 0xf0, 0xf5, 0xd9, 0xf4, 0xf7, 0x10, 0xc7, 0xd4, 0xef, 0x02, + 0xe7, 0xf6, 0xda, 0xf8, 0xeb, 0x21, 0xc3, 0x37, 0x02, 0xbf, 0x03, 0xc7, 0xd9, + 0xd7, 0x0a, 0xfd, 0x30, 0x2b, 0x0d, 0x28, 0x18, 0x03, 0xd0, 0xcb, 0xbb, 0x36, + 0xe4, 0xed, 0xba, 0x2d, 0xf8, 0x14, 0x13, 0xaa, 0xbf, 0x22, 0xe8, 0xea, 0x11, + 0x12, 0xe6, 0xcc, 0x0b, 0xef, 0x9b, 0x15, 0xbd, 0xfa, 0xd5, 0xf2, 0xef, 0xd9, + 0xef, 0x1a, 0xec, 0x31, 0xc2, 0xd0, 0xd8, 0xf1, 0xcf, 0x2f, 0xdf, 0xf8, 0xdc, + 0xbc, 0xb8, 0xde, 0xe2, 0xfa, 0x3c, 0xf7, 0xc5, 0xcd, 0xfc, 0x0b, 0x14, 0x1e, + 0xff, 0x01, 0xfe, 0xfc, 0xe0, 0xdf, 0x07, 0x0a, 0xda, 0xf4, 0xea, 0x0e, 0xfd, + 0x3e, 0xf0, 0xce, 0x9d, 0xe5, 0xdf, 0x23, 0xc7, 0xf5, 0xec, 0x0e, 0xec, 0xea, + 0x19, 0x31, 0xb2, 0x2d, 0xfe, 0xd6, 0xe9, 0x0a, 0x00, 0xe5, 0x7f, 0x15, 0xc3, + 0xd7, 0xc7, 0xb9, 0x03, 0xf5, 0xd6, 0x30, 0xfe, 0xd1, 0x07, 0xb8, 0x4e, 0xc6, + 0xf3, 0xfe, 0xd6, 0xf8, 0x0f, 0x2f, 0xf2, 0xf0, 0x2b, 0x07, 0xe5, 0xe1, 0xd5, + 0xf7, 0xf0, 0x1b, 0xd7, 0x21, 0x42, 0xc0, 0x40, 0x13, 0xb3, 0xd1, 0xd9, 0x43, + 0x0e, 0x04, 0xfd, 0x32, 0xd6, 0x18, 0x09, 0x11, 0xda, 0x21, 0x94, 0xe3, 0xf5, + 0x16, 0xb2, 0xe0, 0xf9, 0x93, 0xf9, 0xcd, 0xfb, 0x0d, 0xc9, 0xef, 0xfa, 0x04, + 0x2c, 0x06, 0x07, 0xdd, 0x42, 0xcc, 0x15, 0x11, 0xca, 0x18, 0x2e, 0xf2, 0x4d, + 0x19, 0x1b, 0x44, 0x33, 0x30, 0xf8, 0x03, 0xd9, 0x2f, 0xdb, 0x37, 0xdb, 0x06, + 0x16, 0x0b, 0xcc, 0x09, 0xba, 0xd4, 0x6e, 0xee, 0xe8, 0x05, 0xcc, 0x21, 0xe8, + 0xec, 0xd8, 0xc5, 0xf6, 0xb0, 0x18, 0xb1, 0x24, 0xfa, 0x22, 0xc4, 0x02, 0x3a, + 0x2a, 0x26, 0xa3, 0xf8, 0x26, 0xb7, 0x07, 0xee, 0x03, 0x0d, 0x10, 0xe2, 0x38, + 0x02, 0xf9, 0xdf, 0x2e, 0x3c, 0xae, 0x37, 0x19, 0xd8, 0x00, 0x20, 0xd3, 0xdb, + 0xe0, 0x38, 0x04, 0x4b, 0x01, 0x3a, 0x60, 0xe7, 0xe2, 0xd7, 0xc4, 0xf5, 0xb8, + 0x35, 0x25, 0xc9, 0x57, 0xf3, 0x3b, 0x3b, 0xd4, 0x23, 0xd3, 0x0d, 0x09, 0x00, + 0xec, 0x00, 0x63, 0xec, 0x2e, 0x21, 0x1e, 0x81, 0xed, 0xd2, 0xc5, 0x12, 0xf9, + 0x2f, 0xf6, 0x04, 0xd6, 0xf5, 0x29, 0x0b, 0xcc, 0x09, 0x90, 0x32, 0xc8, 0x27, + 0xf6, 0xd7, 0xe6, 0xe2, 0xee, 0x1c, 0x2f, 0x0e, 0xfe, 0x03, 0xbf, 0xbb, 0x1d, + 0x27, 0x6c, 0x25, 0x10, 0x27, 0xee, 0x59, 0xc5, 0xd1, 0xd1, 0x2a, 0x50, 0xd0, + 0xe6, 0xd9, 0x33, 0xd1, 0xed, 0x1c, 0xe2, 0xea, 0x57, 0x14, 0xe3, 0xe8, 0x08, + 0x00, 0x52, 0xe8, 0x06, 0xdf, 0xb6, 0xee, 0xe0, 0x3d, 0x04, 0xdc, 0xf2, 0x0a, + 0x0a, 0xd8, 0xb9, 0xfd, 0x9a, 0xe3, 0x0a, 0x19, 0x0f, 0x1b, 0xf5, 0xd2, 0xc6, + 0x13, 0xff, 0xee, 0xb7, 0x25, 0x0e, 0x46, 0xfc, 0xe4, 0xe5, 0xdc, 0xf2, 0xd2, + 0x51, 0x2a, 0xf8, 0xf3, 0xc8, 0xc2, 0xe8, 0xe4, 0x53, 0x43, 0x15, 0x30, 0xd6, + 0x43, 0xf7, 0xd4, 0x24, 0xfa, 0x18, 0xe1, 0x23, 0xc3, 0xb5, 0x2e, 0x65, 0x4c, + 0x2a, 0x01, 0xf1, 0xce, 0xd0, 0x92, 0xab, 0xbf, 0xc5, 0x30, 0xe2, 0xa8, 0xe7, + 0x0d, 0x26, 0xba, 0x09, 0x0a, 0x4c, 0x03, 0xf9, 0xab, 0x1c, 0x05, 0x33, 0x0f, + 0x90, 0x32, 0x0d, 0xe1, 0x10, 0xa1, 0x47, 0xbf, 0x0b, 0xc5, 0xe0, 0x22, 0xd2, + 0xe7, 0xd3, 0xf1, 0xdc, 0x02, 0x25, 0x13, 0xc9, 0xf5, 0x89, 0xb2, 0x87, 0x06, + 0xce, 0xed, 0xa9, 0xd8, 0x45, 0x21, 0x20, 0xd2, 0xec, 0xfe, 0xcf, 0x2d, 0xa7, + 0xfb, 0x1a, 0x25, 0xb8, 0xe0, 0x08, 0xbb, 0xed, 0x0d, 0x1d, 0xf4, 0x91, 0xb7, + 0x55, 0xe8, 0xe6, 0x1a, 0xf9, 0x36, 0xb0, 0xba, 0xe0, 0x3b, 0xd2, 0x3b, 0xfd, + 0x03, 0xce, 0x51, 0x29, 0xf5, 0xd7, 0x30, 0x32, 0x19, 0xa2, 0xee, 0xf7, 0x5e, + 0x39, 0x25, 0xda, 0xd7, 0x26, 0x1e, 0xf0, 0x0b, 0xf5, 0xdb, 0xd9, 0x16, 0xbf, + 0x3d, 0xf9, 0xc4, 0xaa, 0xdc, 0x1f, 0x35, 0x06, 0x09, 0xca, 0xad, 0xf1, 0xdf, + 0xd6, 0x27, 0x13, 0xa2, 0xe3, 0x0c, 0xe1, 0x3c, 0x1f, 0xd3, 0x27, 0xcb, 0xf7, + 0x36, 0xef, 0x02, 0xdb, 0x0d, 0x07, 0x1b, 0xcb, 0xf1, 0xd6, 0x0c, 0x34, 0xe3, + 0xd4, 0x02, 0xf6, 0x21, 0xcd, 0xcb, 0xfd, 0xc5, 0x04, 0xda, 0x13, 0xa0, 0xa9, + 0x13, 0xca, 0x1c, 0x23, 0x23, 0x27, 0xe5, 0x5a, 0xd1, 0xef, 0x43, 0x04, 0xd3, + 0xe6, 0x45, 0xf3, 0x44, 0xbb, 0x00, 0xf1, 0x39, 0xcc, 0xba, 0xf8, 0x1d, 0x06, + 0x30, 0xf6, 0xd0, 0xb2, 0x0c, 0xdc, 0xdf, 0x1d, 0xd0, 0x45, 0xb2, 0xde, 0xe0, + 0x00, 0xd5, 0x7f, 0xfe, 0xe5, 0x1e, 0x58, 0x2e, 0x01, 0xf1, 0x1d, 0xd5, 0xeb, + 0xc6, 0x09, 0x0f, 0x14, 0xd5, 0x12, 0xe8, 0xb8, 0xda, 0x1b, 0xd5, 0x1f, 0xe7, + 0x39, 0xda, 0xd3, 0x18, 0xf6, 0xfb, 0x1f, 0x11, 0xfe, 0xff, 0x67, 0xdc, 0xe0, + 0x41, 0xf4, 0xe8, 0xe8, 0xf2, 0xed, 0x27, 0xdc, 0xa9, 0xf1, 0xc3, 0x9a, 0xb5, + 0xd7, 0xe3, 0xf5, 0xfb, 0x28, 0xb9, 0xf5, 0xd7, 0x12, 0x25, 0xd7, 0xe5, 0xf6, + 0x4c, 0x29, 0xfd, 0xdc, 0xc3, 0xe6, 0x3c, 0x12, 0x09, 0xe9, 0xfe, 0xf8, 0x05, + 0x4f, 0xbb, 0x25, 0x02, 0xd8, 0xb3, 0xd6, 0xbe, 0x1e, 0xd6, 0xdb, 0xf2, 0xe7, + 0x23, 0x04, 0x13, 0xe7, 0x09, 0x3a, 0xfa, 0xa8, 0x1e, 0xf9, 0x0b, 0x2e, 0xdb, + 0xc1, 0xe0, 0x06, 0xb5, 0xc3, 0x01, 0xf7, 0x34, 0xe6, 0xb9, 0x01, 0xf1, 0x02, + 0xe2, 0x13, 0xc7, 0x05, 0x08, 0x02, 0x4c, 0x54, 0x1d, 0xf6, 0x04, 0x25, 0x29, + 0xb1, 0xe6, 0xe9, 0xd9, 0x06, 0x26, 0xe9, 0xed, 0xfc, 0xdf, 0x2a, 0xb2, 0x0a, + 0xc9, 0x1c, 0x2a, 0xf9, 0x17, 0xf3, 0x08, 0xe9, 0xff, 0xe8, 0xba, 0x17, 0x08, + 0x09, 0xea, 0x1f, 0x07, 0xf3, 0x13, 0xea, 0xe4, 0xd7, 0x29, 0xf3, 0xe8, 0xce, + 0xf6, 0x16, 0xda, 0xfb, 0x07, 0xb7, 0x08, 0xd3, 0xe4, 0x36, 0xc7, 0xc4, 0x34, + 0x23, 0x36, 0x00, 0xe8, 0xf4, 0xbd, 0xfa, 0xf7, 0x98, 0xdd, 0xe9, 0xf9, 0x2b, + 0xb2, 0x37, 0xfe, 0xcd, 0x0b, 0x0f, 0xe8, 0x03, 0xb2, 0xdb, 0x15, 0xb7, 0xf7, + 0xc6, 0xeb, 0xf9, 0xc5, 0xf3, 0xe2, 0x23, 0x35, 0xb9, 0xb6, 0xcc, 0xfd, 0xb0, + 0x18, 0xb9, 0x1e, 0xf2, 0xf2, 0xeb, 0xe8, 0x33, 0xde, 0x02, 0xe1, 0x1e, 0xce, + 0x30, 0xfb, 0x7f, 0xec, 0xfd, 0xb4, 0x0b, 0x15, 0x1a, 0x59, 0xe6, 0xe1, 0xe3, + 0x25, 0x01, 0x07, 0x3c, 0x15, 0xae, 0xf5, 0xe9, 0x35, 0x19, 0xe8, 0xfe, 0x06, + 0x0f, 0x27, 0x0e, 0xdc, 0x17, 0x1c, 0x37, 0xaa, 0x3c, 0xe7, 0x37, 0x07, 0x18, + 0xc3, 0xc8, 0xf1, 0x53, 0xcc, 0xdc, 0xb3, 0xe0, 0xe2, 0x2d, 0xe9, 0xe4, 0xdd, + 0xf7, 0x13, 0x27, 0xc9, 0x52, 0x03, 0x0a, 0x9f, 0x06, 0x2e, 0x40, 0xf0, 0x03, + 0x22, 0x46, 0xf3, 0x0d, 0xb4, 0xfb, 0xf7, 0xd1, 0xbd, 0xd8, 0x11, 0xf8, 0xc5, + 0xcd, 0xfa, 0xf8, 0xc6, 0xbe, 0xb5, 0xc9, 0x27, 0xbb, 0xb6, 0xfe, 0x0b, 0x95, + 0xd1, 0xbf, 0xb2, 0xc4, 0x0b, 0xc8, 0x3d, 0x15, 0x2d, 0x04, 0x2e, 0xe9, 0xfd, + 0xd3, 0xc1, 0xfa, 0xe6, 0x17, 0x03, 0xc8, 0xc0, 0xeb, 0x14, 0xb3, 0x13, 0x19, + 0xda, 0x1e, 0x09, 0xa8, 0xd0, 0xf3, 0xc9, 0x23, 0xbf, 0x3f, 0xf2, 0xac, 0x26, + 0xfc, 0x17, 0xbd, 0xf9, 0xf8, 0x32, 0xe6, 0x4b, 0xd9, 0xc4, 0x58, 0xff, 0xe5, + 0xe0, 0xec, 0x19, 0xe7, 0xff, 0xf1, 0x0f, 0x99, 0xe8, 0x1c, 0xe9, 0x1c, 0x4d, + 0x27, 0xe7, 0xbd, 0xdb, 0x0b, 0x49, 0x3b, 0xf6, 0x11, 0x1a, 0x20, 0xe2, 0x0a, + 0xc8, 0xc1, 0xcf, 0xe7, 0x0a, 0x20, 0xc9, 0x9e, 0xe3, 0xe3, 0x55, 0xcc, 0x00, + 0x15, 0xfb, 0x4d, 0xc4, 0x1c, 0xfe, 0x93, 0xaa, 0xe3, 0x0e, 0xce, 0xdc, 0x1a, + 0x57, 0x16, 0x2c, 0x15, 0x45, 0xd0, 0x17, 0x17, 0xe8, 0xe6, 0x4b, 0xc4, 0x36, + 0xf7, 0x51, 0x0a, 0x32, 0x07, 0x28, 0xcb, 0xba, 0xe2, 0xea, 0x09, 0x08, 0xe1, + 0x1d, 0x41, 0xb9, 0x14, 0x7b, 0xc1, 0xd4, 0x06, 0xfd, 0x07, 0x3c, 0x11, 0x4a, + 0xf1, 0xe2, 0x29, 0xf9, 0xf1, 0xb7, 0xe3, 0x1e, 0xf9, 0x03, 0xce, 0x18, 0x27, + 0xf9, 0xd9, 0x05, 0x07, 0x6c, 0xfc, 0xbe, 0x17, 0xcf, 0xfd, 0xf1, 0xd3, 0xf4, + 0xf7, 0xc9, 0xdf, 0xaa, 0x3d, 0xfb, 0x25, 0x04, 0x2b, 0xe5, 0xf9, 0x1e, 0xfe, + 0xfa, 0x53, 0xeb, 0xca, 0xfb, 0xf3, 0xfd, 0xc8, 0x2d, 0xb8, 0x16, 0x11, 0x56, + 0x0c, 0xe0, 0xfb, 0xd2, 0x26, 0x14, 0x33, 0x5d, 0x13, 0xfd, 0x35, 0x29, 0xaa, + 0x39, 0xed, 0x14, 0x27, 0xd3, 0xf1, 0x17, 0x11, 0x39, 0xeb, 0x1d, 0xdc, 0x37, + 0x0c, 0xe0, 0xeb, 0x04, 0x0a, 0xb2, 0x06, 0x25, 0x32, 0xfe, 0x24, 0xe2, 0xf3, + 0xd2, 0xeb, 0xf6, 0x01, 0x3a, 0xe2, 0xed, 0x5b, 0xbf, 0x0f, 0x2b, 0xde, 0x00, + 0x7f, 0x56, 0x0b, 0xc4, 0xcb, 0x1a, 0x21, 0x1f, 0xd8, 0xc0, 0x25, 0xde, 0xce, + 0x1e, 0xe0, 0xd0, 0x45, 0xf6, 0x1c, 0x14, 0x32, 0x1e, 0x3a, 0x2d, 0xcf, 0xdc, + 0xa6, 0xab, 0xb4, 0x3b, 0xe0, 0xef, 0xaf, 0x0e, 0xce, 0x0b, 0xc9, 0x28, 0x2b, + 0xc7, 0x0a, 0x2a, 0xde, 0xc4, 0xc7, 0xba, 0x81, 0x29, 0xf2, 0x19, 0xd9, 0xdf, + 0x36, 0xee, 0xb1, 0xf7, 0xbf, 0xc7, 0x01, 0xe8, 0x2a, 0x92, 0xf3, 0x10, 0xe8, + 0x0a, 0x0a, 0xea, 0xb5, 0xe5, 0xc9, 0x38, 0x34, 0xde, 0xe6, 0x12, 0xcb, 0xeb, + 0x14, 0xc9, 0x3d, 0xc6, 0xb6, 0xc0, 0xca, 0xd9, 0x4e, 0xc3, 0xb0, 0x41, 0xca, + 0x0c, 0xaa, 0xd2, 0xc8, 0xec, 0xe0, 0xea, 0xd4, 0x1c, 0xf4, 0x3c, 0xff, 0x0a, + 0xe5, 0x2f, 0x3e, 0xce, 0xdd, 0x1a, 0x08, 0x24, 0xfc, 0x1b, 0x2f, 0xac, 0x00, + 0x10, 0xfe, 0x3b, 0xed, 0xee, 0xe4, 0x18, 0xde, 0xde, 0x25, 0x33, 0x5d, 0xf8, + 0x3f, 0xec, 0xfd, 0xdd, 0x0a, 0xeb, 0x07, 0xdd, 0xe9, 0x2a, 0x3a, 0x02, 0xe1, + 0x09, 0x00, 0xbe, 0x1f, 0xdd, 0x0f, 0x33, 0x49, 0x13, 0xf5, 0xec, 0xbd, 0x11, + 0xb5, 0xf0, 0xd5, 0x03, 0xca, 0xde, 0xd6, 0x73, 0xf9, 0x09, 0xdb, 0xf0, 0x28, + 0x4b, 0xfe, 0xf1, 0xf1, 0xfc, 0xa9, 0x07, 0xf3, 0x06, 0x25, 0xc6, 0x60, 0xca, + 0x29, 0xfe, 0x05, 0xf2, 0xd1, 0xe7, 0x00, 0x2c, 0x31, 0xf7, 0x0c, 0x30, 0xe3, + 0x0d, 0xe2, 0x07, 0xdf, 0xae, 0xd9, 0xc1, 0xf3, 0x1a, 0xf2, 0xd4, 0x0e, 0xc3, + 0x16, 0xf2, 0x44, 0x22, 0x00, 0xe5, 0x24, 0xef, 0xa2, 0x62, 0x13, 0x07, 0x44, + 0xdf, 0xb3, 0x03, 0xfa, 0x23, 0xfe, 0xf6, 0xd8, 0xaa, 0xf1, 0x12, 0x18, 0xee, + 0x1f, 0xd8, 0x5a, 0x14, 0x3a, 0x38, 0xe2, 0xf5, 0x22, 0xc9, 0xc5, 0x6c, 0x15, + 0x76, 0xea, 0xf6, 0x52, 0xe6, 0x12, 0x3a, 0x06, 0x27, 0x7b, 0x09, 0xde, 0x68, + 0xf0, 0xef, 0xe4, 0xc7, 0xc3, 0xd1, 0x2e, 0xdb, 0xeb, 0x47, 0xb8, 0xcc, 0xf3, + 0x0a, 0xeb, 0x19, 0x0e, 0x27, 0xed, 0x19, 0xde, 0x21, 0xdc, 0xf3, 0xcd, 0xe2, + 0xf9, 0x02, 0xe8, 0x27, 0xfe, 0x06, 0x03, 0xd2, 0x37, 0xa2, 0xde, 0xdc, 0xda, + 0x5c, 0xc7, 0xbd, 0xf4, 0x06, 0x05, 0xf5, 0xf0, 0x06, 0xab, 0x08, 0xda, 0x3f, + 0xf8, 0x17, 0x37, 0xfd, 0x25, 0xe2, 0x3c, 0xf6, 0x22, 0x16, 0x11, 0xce, 0xf8, + 0xdb, 0xc2, 0x1d, 0x16, 0x0e, 0xe5, 0xd9, 0x00, 0x32, 0xca, 0x3a, 0xa5, 0x0c, + 0x06, 0x02, 0xb2, 0x2d, 0xdb, 0x0d, 0xde, 0x24, 0xf5, 0x59, 0x0e, 0xaf, 0xe2, + 0xf3, 0xfa, 0xb3, 0xd8, 0x03, 0x3d, 0x1a, 0x1a, 0x16, 0xea, 0xf5, 0xe5, 0xfe, + 0xda, 0x3a, 0xf7, 0x15, 0xe1, 0xfe, 0xf4, 0x0f, 0xde, 0xbb, 0xf5, 0xef, 0xfe, + 0xdb, 0x32, 0xe0, 0xd7, 0xfa, 0x3f, 0xf9, 0xf9, 0xf7, 0xf5, 0xe0, 0x14, 0x35, + 0xc8, 0xe1, 0xcf, 0x15, 0x0e, 0x3a, 0xed, 0x13, 0x3b, 0xeb, 0xc2, 0x34, 0xec, + 0xa9, 0x9d, 0x01, 0x9f, 0x0b, 0xaa, 0x3d, 0x1a, 0x13, 0x0f, 0xea, 0x31, 0x02, + 0xde, 0x0b, 0x1c, 0x37, 0xf9, 0xf5, 0xbd, 0xf4, 0x04, 0xe5, 0x08, 0xf5, 0xcd, + 0xe7, 0xe3, 0x10, 0x0e, 0x13, 0x27, 0x07, 0x14, 0xd9, 0xad, 0xd5, 0xbf, 0xc5, + 0x2b, 0x1f, 0xf9, 0x24, 0x08, 0x34, 0x03, 0x14, 0x02, 0x91, 0x13, 0x0c, 0x55, + 0x1d, 0xeb, 0x09, 0x16, 0xe6, 0xf2, 0x23, 0xd3, 0x3b, 0xcd, 0xeb, 0xeb, 0xc8, + 0xf2, 0xc0, 0xf9, 0xb6, 0xe9, 0xfd, 0xe3, 0x1e, 0x18, 0x33, 0x1f, 0xf6, 0xe9, + 0xc0, 0xf3, 0xf7, 0xee, 0x29, 0xdc, 0x94, 0x5e, 0xf4, 0xeb, 0xf6, 0xf8, 0xd0, + 0xde, 0x00, 0x17, 0xfd, 0x0b, 0x56, 0xfe, 0x01, 0xae, 0x2c, 0xf9, 0x0d, 0xa4, + 0xcf, 0x07, 0x2a, 0x0e, 0x19, 0x20, 0x81, 0x08, 0xc5, 0xdf, 0x21, 0xde, 0xe6, + 0xe0, 0x24, 0xd9, 0x21, 0x1b, 0xc6, 0x28, 0x0e, 0x00, 0x13, 0x0b, 0xf6, 0x2b, + 0x13, 0x13, 0xad, 0x2e, 0x63, 0xfc, 0xfe, 0x09, 0x18, 0xaf, 0x3b, 0xdb, 0x0a, + 0xd9, 0xdc, 0x0f, 0x19, 0xc1, 0xe4, 0x02, 0x23, 0x74, 0x05, 0xdd, 0xf5, 0x43, + 0x08, 0xdd, 0xf4, 0xeb, 0x01, 0x09, 0xfb, 0xc3, 0x2f, 0xc1, 0xc9, 0x35, 0x18, + 0x28, 0xf3, 0xe4, 0xd1, 0x1c, 0xfe, 0xed, 0xae, 0xbf, 0xd5, 0xf5, 0x34, 0x23, + 0xcf, 0x08, 0x14, 0x3b, 0xd5, 0xa0, 0x3c, 0xec, 0xc8, 0xf1, 0x3a, 0xbd, 0xe4, + 0xfd, 0x1d, 0xed, 0x27, 0x13, 0xb1, 0x0c, 0xdd, 0xd5, 0xdf, 0x00, 0xe9, 0xec, + 0xcb, 0xf7, 0x3c, 0x44, 0x06, 0xea, 0xa6, 0xe2, 0x0a, 0x08, 0xd2, 0x01, 0xe1, + 0xf6, 0xc9, 0x1a, 0x43, 0xdb, 0x45, 0xb9, 0x2c, 0x1a, 0xe4, 0x1c, 0xe1, 0xfe, + 0xe8, 0xd2, 0x03, 0xb6, 0xbc, 0x43, 0x16, 0xfe, 0xad, 0xf0, 0xdc, 0xf7, 0xfe, + 0x0b, 0x33, 0xc9, 0xaa, 0xb9, 0x15, 0xfb, 0xda, 0x99, 0x2a, 0xea, 0x02, 0x3c, + 0x2a, 0x62, 0x03, 0x08, 0x1a, 0x20, 0xdd, 0x2c, 0xde, 0x05, 0x39, 0xb3, 0xc8, + 0xba, 0xc9, 0x03, 0x07, 0xd8, 0x00, 0x06, 0xc5, 0x3c, 0x16, 0xf4, 0xb5, 0xf0, + 0xc5, 0xe2, 0xe7, 0xfe, 0x05, 0x0c, 0x0b, 0x1f, 0xd6, 0xdb, 0xd1, 0xf7, 0xe5, + 0xfb, 0xb1, 0xcc, 0x1a, 0xcf, 0xa7, 0x34, 0xfa, 0xc1, 0x30, 0xa1, 0xe2, 0x16, + 0xdf, 0xed, 0x2a, 0x1a, 0x9f, 0x0e, 0xf7, 0x0d, 0xd9, 0xf6, 0x02, 0x0f, 0xb1, + 0xe8, 0xb1, 0x10, 0x14, 0xee, 0x04, 0xec, 0x9c, 0xb2, 0xa5, 0xd1, 0xde, 0x11, + 0x1a, 0x46, 0xfb, 0xa3, 0x4c, 0x10, 0xef, 0x16, 0xeb, 0x06, 0x14, 0x19, 0x48, + 0x1c, 0xe5, 0xf9, 0xe1, 0x14, 0x04, 0x20, 0xbf, 0xc0, 0xa2, 0x07, 0xd0, 0x01, + 0xd9, 0xf8, 0x93, 0xe3, 0xe7, 0xd9, 0x1b, 0xa3, 0xf9, 0xc0, 0xc0, 0xc7, 0xe2, + 0xd1, 0xff, 0x4c, 0xee, 0xfc, 0x31, 0xef, 0x3a, 0xef, 0xd5, 0xd7, 0xce, 0xf3, + 0xe5, 0xba, 0xe8, 0x15, 0x15, 0x7f, 0xf8, 0x07, 0x38, 0x17, 0x10, 0x3d, 0x0f, + 0x1b, 0xe3, 0xd3, 0xcc, 0xc5, 0x41, 0x3f, 0x35, 0xed, 0xd1, 0xe2, 0xc6, 0x1d, + 0xcf, 0xdf, 0xd4, 0xbf, 0xf9, 0xe7, 0x10, 0x0b, 0x07, 0xce, 0x19, 0xca, 0xfb, + 0xee, 0xfb, 0xf8, 0xc8, 0x10, 0xcf, 0xfa, 0xba, 0xd1, 0xe7, 0xd7, 0xdb, 0xce, + 0xcd, 0x03, 0xff, 0xd2, 0x33, 0xed, 0x25, 0x06, 0x30, 0xf0, 0x01, 0xe8, 0x25, + 0x10, 0x00, 0x15, 0x2c, 0xe8, 0x0e, 0xdd, 0x03, 0x0e, 0xd6, 0xc7, 0xd7, 0x16, + 0xf5, 0x34, 0x54, 0x12, 0xc1, 0xfe, 0x4c, 0xe8, 0x08, 0x19, 0x01, 0xf9, 0x9e, + 0x0a, 0xb7, 0xbc, 0x02, 0xcc, 0xed, 0x15, 0xea, 0xc7, 0x32, 0x33, 0x1c, 0xf9, + 0xbf, 0xbb, 0x20, 0x1e, 0x08, 0xe7, 0xea, 0x22, 0x02, 0xfc, 0x0a, 0xc1, 0xd0, + 0xec, 0x07, 0x0c, 0x38, 0xed, 0xfe, 0xd3, 0xe5, 0x13, 0xb9, 0xd5, 0xeb, 0xd2, + 0xf8, 0xdc, 0x1f, 0xbf, 0xf3, 0xf9, 0x18, 0x13, 0x09, 0xe6, 0xea, 0x14, 0x81, + 0xfc, 0xea, 0xcf, 0xfc, 0xdd, 0x08, 0xcd, 0x1f, 0x05, 0xb6, 0xce, 0x23, 0x23, + 0xce, 0xc6, 0x0e, 0xb6, 0xf3, 0xdf, 0xe9, 0x16, 0x18, 0xcc, 0x13, 0x19, 0x19, + 0xef, 0x19, 0x2a, 0xfb, 0xcc, 0x18, 0xb9, 0xca, 0xd9, 0xe2, 0x56, 0xc9, 0xc5, + 0x0b, 0x12, 0xcf, 0x12, 0xfc, 0x21, 0x5b, 0xb9, 0x0e, 0x13, 0x19, 0xeb, 0x01, + 0x0f, 0x47, 0x25, 0xed, 0xe1, 0x12, 0xf9, 0xfe, 0xf6, 0x27, 0xe9, 0x05, 0xb8, + 0xae, 0xec, 0x2d, 0x00, 0xf7, 0xde, 0xf2, 0xe7, 0xfe, 0x04, 0xc7, 0xda, 0x1e, + 0xef, 0x32, 0x9c, 0xe2, 0x15, 0xbe, 0xcc, 0x26, 0xe0, 0x02, 0xfd, 0x0c, 0xe9, + 0xf5, 0xf9, 0xfe, 0xf8, 0xe4, 0xf1, 0xd7, 0x02, 0xcf, 0x28, 0x20, 0x12, 0xde, + 0x39, 0xfa, 0xda, 0x06, 0xed, 0xc8, 0xeb, 0x03, 0x27, 0x1a, 0x1b, 0xf8, 0xf6, + 0xd6, 0xb2, 0xfc, 0xd8, 0xb5, 0xf3, 0xeb, 0xf6, 0x00, 0x18, 0x45, 0x13, 0xfd, + 0x62, 0xfb, 0xd0, 0xf0, 0xa6, 0x35, 0xdc, 0x75, 0xac, 0x9c, 0xe9, 0xd5, 0xea, + 0xbe, 0xbe, 0xf8, 0x1a, 0x05, 0x85, 0x0a, 0x1e, 0x01, 0xda, 0xd3, 0x81, 0xe1, + 0xcc, 0xd4, 0xdf, 0xd1, 0xfb, 0x13, 0xd6, 0xde, 0x1f, 0xa0, 0xd6, 0x1e, 0xe9, + 0x3d, 0xd4, 0x13, 0xce, 0x41, 0x2f, 0x40, 0xdd, 0x03, 0x61, 0xa5, 0x34, 0xc8, + 0x16, 0xdb, 0xc6, 0xbe, 0xaf, 0xe3, 0x52, 0x6e, 0xdb, 0xec, 0x49, 0xe0, 0xfb, + 0x24, 0xf9, 0x24, 0xe8, 0x29, 0xc6, 0xb9, 0x03, 0x26, 0x2c, 0xda, 0x01, 0xe9, + 0xa7, 0xde, 0x05, 0xbf, 0xa8, 0x1f, 0xbd, 0xb3, 0x84, 0xe2, 0x1f, 0x29, 0x12, + 0xcd, 0xe7, 0x1f, 0x05, 0x4f, 0x1a, 0x2a, 0xe2, 0x92, 0xc0, 0xfc, 0x1e, 0xf7, + 0xbd, 0xa7, 0xe0, 0xc1, 0xe2, 0xc9, 0x88, 0x19, 0xcf, 0xc5, 0xfa, 0x12, 0xad, + 0xd8, 0x0e, 0x20, 0x98, 0x9e, 0x04, 0x17, 0xc1, 0xf6, 0x02, 0x60, 0xf2, 0xdc, + 0x09, 0x42, 0x29, 0x26, 0x0a, 0x8a, 0xec, 0xe9, 0x12, 0x03, 0xb2, 0xb4, 0xf6, + 0x10, 0xf3, 0x87, 0x12, 0xfd, 0xda, 0xde, 0xf2, 0xdd, 0xa8, 0x44, 0x5d, 0xff, + 0x69, 0x40, 0xc0, 0x86, 0x0b, 0x4a, 0x5d, 0xef, 0x04, 0x14, 0xf9, 0x9b, 0x11, + 0xa1, 0xde, 0x3d, 0xe7, 0x5a, 0xf9, 0xbb, 0xce, 0xf9, 0xa2, 0xf8, 0x2c, 0x05, + 0xd4, 0xf7, 0x1d, 0xdf, 0xdf, 0xda, 0x34, 0xd8, 0xf5, 0xcb, 0x0a, 0xe0, 0xe0, + 0xc6, 0xdf, 0xe4, 0xd1, 0xd8, 0xf8, 0x28, 0xea, 0x01, 0xfc, 0x4b, 0xcb, 0x46, + 0xc1, 0xf7, 0x1f, 0xe7, 0xe9, 0x21, 0x09, 0xd5, 0x18, 0xdf, 0xe1, 0xfc, 0xdb, + 0xfd, 0x3e, 0xa1, 0xa8, 0xed, 0x2f, 0x4e, 0x4a, 0xba, 0xe1, 0x50, 0xff, 0x56, + 0xcb, 0xcd, 0x10, 0xe4, 0xe5, 0x77, 0x68, 0xfa, 0xd6, 0xb3, 0xd2, 0xba, 0xcb, + 0x55, 0x15, 0xf4, 0x26, 0x0c, 0x28, 0x3b, 0xdc, 0xe7, 0x2b, 0xe1, 0x06, 0xe9, + 0x83, 0x24, 0xf6, 0x0f, 0x11, 0x18, 0xf0, 0x04, 0xf7, 0x15, 0xd7, 0xe4, 0xdf, + 0x15, 0xf5, 0x81, 0xcd, 0x02, 0x45, 0x0a, 0xfc, 0xb1, 0xf3, 0xd4, 0x0b, 0xc4, + 0xdf, 0x09, 0xca, 0x05, 0xc7, 0xe9, 0x0f, 0xf7, 0xeb, 0xda, 0x7c, 0x12, 0xf6, + 0xc8, 0x04, 0xdf, 0xd3, 0x8d, 0x23, 0x64, 0x22, 0xff, 0x45, 0x23, 0xf1, 0xfa, + 0xf0, 0x15, 0xa7, 0xf2, 0xba, 0xe4, 0xbb, 0x2f, 0x85, 0x96, 0xef, 0x07, 0xa8, + 0x9c, 0xf2, 0x4a, 0xe0, 0xd3, 0xdb, 0xe6, 0x8d, 0xc0, 0xb8, 0xd2, 0xf0, 0x09, + 0xbf, 0x3b, 0xeb, 0x12, 0x56, 0xa5, 0x9f, 0x46, 0xef, 0xd6, 0x26, 0x1f, 0xf4, + 0xd8, 0xb5, 0x24, 0xdf, 0xa7, 0x02, 0xc6, 0x01, 0x4c, 0x3b, 0xef, 0xdf, 0x07, + 0xad, 0x19, 0x42, 0x0a, 0x02, 0xb1, 0xce, 0x56, 0xec, 0x0b, 0xd7, 0x4f, 0xb6, + 0xbd, 0x06, 0xf9, 0xb4, 0x21, 0x4e, 0xfd, 0x04, 0xd5, 0x46, 0x38, 0x91, 0x11, + 0xbe, 0x3d, 0x08, 0xc8, 0xee, 0x2f, 0xfd, 0x1a, 0xac, 0xcd, 0xfe, 0x29, 0x0f, + 0xda, 0xf8, 0x96, 0x21, 0xfd, 0xd9, 0x33, 0x19, 0xc1, 0x57, 0xf8, 0x10, 0xd3, + 0xe9, 0xdc, 0xfc, 0x0c, 0xf0, 0xcd, 0x19, 0xc6, 0xd7, 0x1c, 0x01, 0xe9, 0x4b, + 0xba, 0xf6, 0xb2, 0xe7, 0xf4, 0xbc, 0xfc, 0x14, 0xf3, 0xc9, 0x06, 0xf8, 0x26, + 0x26, 0x04, 0xe9, 0x52, 0xdc, 0x18, 0x11, 0xd4, 0x52, 0xf6, 0xf6, 0xf0, 0x51, + 0xde, 0xde, 0x1e, 0xdd, 0xf5, 0x40, 0xb0, 0x00, 0x03, 0xea, 0x17, 0xe3, 0x09, + 0xfd, 0x0b, 0xf0, 0x3e, 0xa3, 0xba, 0x12, 0x3f, 0x15, 0xf0, 0xef, 0x17, 0xb0, + 0x1f, 0xf3, 0xa9, 0x5f, 0xe0, 0x57, 0x06, 0x03, 0x12, 0xa0, 0x15, 0x1b, 0xe3, + 0xf0, 0xdb, 0x57, 0x0b, 0x44, 0x48, 0xd8, 0x05, 0xd6, 0xfb, 0x4e, 0xdf, 0x09, + 0xbf, 0xde, 0x27, 0x05, 0x21, 0xe0, 0xd5, 0xcf, 0x24, 0x08, 0xe4, 0xc1, 0xfc, + 0xf2, 0x33, 0xe1, 0xec, 0x15, 0x09, 0x03, 0xf4, 0x05, 0xf0, 0x11, 0xf8, 0x9b, + 0xea, 0xcc, 0xfb, 0xa7, 0xf9, 0x07, 0xdf, 0xe3, 0xa2, 0x00, 0x0c, 0xc1, 0x1e, + 0x18, 0xd4, 0xea, 0x02, 0x3f, 0xef, 0x17, 0x03, 0x24, 0x1d, 0x44, 0x15, 0xc3, + 0xe0, 0x03, 0x08, 0x10, 0xf8, 0x09, 0x16, 0x21, 0x14, 0x29, 0x02, 0xc8, 0x09, + 0x17, 0x33, 0xfe, 0x62, 0x25, 0xfc, 0xfb, 0xc3, 0x48, 0x5d, 0x1d, 0xeb, 0x00, + 0x1c, 0xd0, 0x18, 0xa5, 0x18, 0xd3, 0x2e, 0x1e, 0xc0, 0xee, 0x12, 0xee, 0x57, + 0xf6, 0xf2, 0x0e, 0xe1, 0x07, 0xb0, 0xea, 0xe9, 0x2a, 0x11, 0x3d, 0xf0, 0xf3, + 0xd4, 0xe8, 0x08, 0xd2, 0xf2, 0xe9, 0x00, 0x0b, 0xf4, 0xa2, 0xbe, 0xf9, 0xbf, + 0x5d, 0x3c, 0xb9, 0xe1, 0xc6, 0xf5, 0x00, 0xd5, 0x13, 0x05, 0x05, 0x10, 0xff, + 0xe4, 0x1d, 0xb4, 0xfa, 0xd6, 0xe9, 0xec, 0x0a, 0xf8, 0x01, 0xec, 0xe4, 0xec, + 0x3c, 0xd0, 0xcd, 0xf5, 0xc0, 0xcc, 0xda, 0xcf, 0xf5, 0x3f, 0xe0, 0xe4, 0xc0, + 0x08, 0x27, 0x53, 0xdf, 0x08, 0xa9, 0x24, 0x0c, 0xb7, 0x2c, 0x21, 0x7f, 0xd0, + 0xe2, 0x28, 0xe9, 0xbc, 0x1b, 0xca, 0xec, 0x1f, 0x00, 0x0e, 0x17, 0xfe, 0x1b, + 0x05, 0xf0, 0x5d, 0xf1, 0x0e, 0x24, 0x09, 0xe8, 0xf6, 0x13, 0x05, 0xc3, 0x2a, + 0x09, 0xc5, 0xe5, 0x26, 0xeb, 0xdc, 0xfa, 0x05, 0x09, 0xe8, 0xf3, 0xca, 0xf2, + 0x01, 0xed, 0xdf, 0xb6, 0x04, 0xdd, 0xe3, 0xb2, 0xf2, 0xbf, 0xfa, 0x4a, 0x28, + 0x01, 0x0e, 0xb4, 0x01, 0x13, 0xc6, 0x3a, 0x05, 0xe8, 0xf4, 0x02, 0x0d, 0x16, + 0x08, 0xea, 0xdd, 0xfe, 0x13, 0xe1, 0xfd, 0x38, 0xef, 0x00, 0xdb, 0x1a, 0x1f, + 0xe9, 0xe5, 0xcf, 0xe4, 0xf4, 0xfa, 0x32, 0xc5, 0x04, 0x1c, 0x0b, 0x50, 0xeb, + 0xff, 0x2c, 0xe6, 0xde, 0xf7, 0xfa, 0xa5, 0xb8, 0xc4, 0xc9, 0xe8, 0x06, 0x02, + 0xfb, 0xb5, 0xfb, 0xee, 0x1a, 0x13, 0xf7, 0xd2, 0xea, 0x2c, 0xec, 0xe4, 0x07, + 0xf4, 0x2c, 0xc1, 0x2b, 0x04, 0x13, 0x24, 0x06, 0xdd, 0xfe, 0x8f, 0xe1, 0x43, + 0xb9, 0xdf, 0xbd, 0x47, 0xac, 0x2e, 0xe2, 0x16, 0xe2, 0xfb, 0xc1, 0x48, 0x08, + 0xf2, 0x61, 0xd4, 0xf0, 0xe4, 0x4b, 0x0a, 0xd2, 0xe1, 0x3a, 0x24, 0x2f, 0xa9, + 0xea, 0xfc, 0xcd, 0x32, 0xf7, 0x03, 0x1a, 0x6a, 0xbb, 0x28, 0xea, 0xa3, 0xe4, + 0xb8, 0xbf, 0x1b, 0xce, 0xfe, 0xd1, 0xc3, 0x21, 0x0d, 0x9e, 0xf3, 0xdb, 0xdc, + 0x1b, 0xf6, 0xdf, 0xc2, 0xbf, 0x12, 0x30, 0x63, 0xc4, 0xe6, 0xf8, 0x05, 0xcc, + 0x16, 0xf7, 0x0a, 0xe4, 0xca, 0xea, 0xea, 0x0a, 0xe8, 0x2e, 0x1c, 0xc1, 0xfc, + 0xac, 0x20, 0x02, 0xfb, 0x42, 0x0b, 0xf7, 0xe2, 0xf9, 0xe1, 0xe5, 0xcb, 0xb4, + 0xb3, 0x02, 0x17, 0xd2, 0xd9, 0xca, 0xe9, 0xbe, 0xfa, 0x17, 0xd3, 0xda, 0x48, + 0xfa, 0xd1, 0x07, 0xbd, 0x10, 0x19, 0xa5, 0xe8, 0x0b, 0x3c, 0x3a, 0x0f, 0xf0, + 0xe4, 0xe2, 0x0e, 0x9e, 0xc5, 0xd5, 0xba, 0x77, 0xd6, 0xc4, 0x4d, 0x06, 0xd2, + 0xf1, 0x03, 0x5b, 0xce, 0x00, 0x35, 0x2a, 0x08, 0xf1, 0x87, 0xbb, 0x3a, 0xb3, + 0x08, 0x0c, 0xa5, 0xcf, 0x2a, 0xe4, 0x4c, 0x04, 0x41, 0xd7, 0xd7, 0xd2, 0x13, + 0xee, 0xe6, 0x9d, 0xdc, 0x09, 0xf1, 0xec, 0xd8, 0x34, 0xfe, 0x56, 0x07, 0xaf, + 0xd6, 0x37, 0xd9, 0xdf, 0x4c, 0xb6, 0x16, 0x1a, 0xa6, 0x07, 0xc7, 0x9d, 0xe6, + 0x07, 0xf8, 0x31, 0xee, 0x3a, 0xd1, 0x38, 0xb7, 0xac, 0xc2, 0x19, 0xeb, 0xba, + 0x05, 0x54, 0xe1, 0xbe, 0xf1, 0x3a, 0xc1, 0xfb, 0xe8, 0x5b, 0xd2, 0xa6, 0x30, + 0xd9, 0x81, 0xa0, 0x07, 0x1b, 0x00, 0x01, 0x6e, 0xcc, 0x24, 0x0f, 0xf4, 0x16, + 0x0b, 0xd4, 0xd1, 0x3c, 0xcc, 0xb5, 0xd6, 0xa9, 0x2c, 0xf3, 0xea, 0xe3, 0xfd, + 0xf9, 0x81, 0x21, 0x4d, 0x3e, 0xd5, 0xfe, 0xb7, 0x0f, 0xc1, 0x1c, 0x1d, 0x16, + 0xf7, 0x03, 0xf9, 0xfe, 0xd6, 0xf3, 0x11, 0xab, 0xd3, 0xfb, 0x58, 0xf3, 0xae, + 0xcc, 0xde, 0xfb, 0xc4, 0xb8, 0x0b, 0x05, 0xde, 0x30, 0x1f, 0xc9, 0x83, 0x0d, + 0xd7, 0xec, 0x03, 0x18, 0x15, 0xf6, 0x0e, 0x4a, 0xcc, 0x14, 0x31, 0xac, 0x25, + 0x2a, 0x1e, 0xb5, 0xd8, 0x6d, 0xd2, 0x1c, 0xec, 0xdb, 0xc8, 0xc7, 0xec, 0x1d, + 0xbe, 0xf1, 0x10, 0xeb, 0x0b, 0xc6, 0xca, 0xed, 0xe4, 0xdc, 0xbc, 0x09, 0x58, + 0xe2, 0xed, 0xc8, 0xdb, 0xd2, 0xec, 0xf6, 0x15, 0xeb, 0xda, 0xd4, 0x2e, 0xf0, + 0xc7, 0xdb, 0xff, 0x3b, 0xb3, 0x60, 0x15, 0xdb, 0xff, 0x06, 0x05, 0x1d, 0x00, + 0xae, 0xe6, 0xcb, 0x09, 0x50, 0x1e, 0xec, 0x36, 0x08, 0xcc, 0xa3, 0xf3, 0x54, + 0x06, 0x54, 0xeb, 0xc4, 0xf0, 0x43, 0xc1, 0xfd, 0xe5, 0xf0, 0xd5, 0xdb, 0xe4, + 0xe3, 0xfd, 0x44, 0x1c, 0x0f, 0xf0, 0xe0, 0x03, 0x2a, 0x65, 0xe3, 0xc8, 0xe9, + 0xfd, 0xef, 0xdb, 0x42, 0x05, 0x06, 0xe2, 0xd1, 0xa9, 0xdc, 0x10, 0x9d, 0x38, + 0x0d, 0x1f, 0xc0, 0x0d, 0xf1, 0xd7, 0x31, 0xc9, 0x21, 0x87, 0xf7, 0xed, 0xf7, + 0xa1, 0x08, 0xf3, 0xbf, 0xcf, 0x2a, 0xd6, 0xe9, 0xfd, 0x03, 0xf9, 0xdc, 0x22, + 0x00, 0xff, 0x15, 0xeb, 0x09, 0xfb, 0x2a, 0x29, 0xf7, 0x09, 0xfa, 0xb5, 0xf0, + 0x13, 0xe6, 0xf8, 0x46, 0x07, 0x29, 0x8d, 0xfd, 0xfe, 0x0a, 0x1b, 0x18, 0xf3, + 0xa4, 0xec, 0xc3, 0x26, 0xa0, 0xe4, 0xd8, 0x0a, 0xd8, 0xf0, 0x96, 0x86, 0x2d, + 0xc9, 0x02, 0x21, 0xf4, 0x2e, 0x40, 0x1f, 0x0e, 0x3e, 0xd7, 0x51, 0x3f, 0x0d, + 0xc9, 0x9c, 0xb7, 0x27, 0xd8, 0x23, 0x02, 0xc7, 0x0f, 0xd5, 0x90, 0x38, 0xc9, + 0x1e, 0x02, 0xaa, 0x3c, 0xbe, 0x88, 0x29, 0xdd, 0x39, 0xe7, 0x98, 0x09, 0xd9, + 0x84, 0x38, 0xe9, 0x4b, 0xb3, 0xbb, 0x2e, 0x29, 0xfd, 0x1a, 0x1f, 0x08, 0xe4, + 0x3d, 0x1e, 0xfb, 0xc2, 0x32, 0x13, 0x4b, 0x40, 0xdd, 0xfc, 0xe4, 0xff, 0xf7, + 0x28, 0xde, 0xbb, 0xf3, 0x09, 0xe5, 0x06, 0xc9, 0x34, 0xe5, 0x93, 0xde, 0xd8, + 0x2e, 0xb4, 0xfe, 0xc6, 0x41, 0xa6, 0xdc, 0xfc, 0x0c, 0x2d, 0x33, 0xd4, 0x62, + 0xe7, 0xc8, 0xcc, 0x4a, 0x28, 0xc7, 0x31, 0x93, 0x1b, 0x4c, 0x33, 0x2d, 0x3f, + 0xc1, 0x58, 0xe2, 0xcc, 0xef, 0xf1, 0xf9, 0xce, 0x09, 0x24, 0xb9, 0x09, 0xd9, + 0x23, 0xef, 0xfc, 0xd1, 0x15, 0x41, 0xfd, 0x21, 0xe6, 0x49, 0xbd, 0xd0, 0xd8, + 0xcc, 0x2c, 0xd1, 0xfe, 0xb8, 0xca, 0xd4, 0xec, 0xdb, 0x14, 0xd5, 0x61, 0xfa, + 0xbc, 0x27, 0xf8, 0x91, 0xa3, 0x3f, 0x23, 0x48, 0xcd, 0x1d, 0xf3, 0x2c, 0xfc, + 0xaa, 0xb0, 0xf0, 0x0b, 0xd9, 0xe5, 0x0c, 0xb8, 0x0f, 0xdb, 0x95, 0xf6, 0xef, + 0x1e, 0xda, 0xe5, 0xf4, 0x6f, 0x42, 0xf2, 0x35, 0xba, 0x11, 0xc9, 0x0b, 0xf2, + 0xb7, 0x16, 0xbd, 0xa0, 0x24, 0x36, 0xe5, 0x3d, 0xe7, 0xfb, 0xa0, 0xd6, 0x05, + 0xb7, 0xd8, 0x16, 0xf2, 0x1d, 0xac, 0x81, 0x04, 0xb5, 0xdd, 0xe9, 0x21, 0x99, + 0x3c, 0x16, 0xf6, 0x1a, 0xa6, 0xb8, 0x4c, 0xd1, 0x24, 0xd9, 0xeb, 0xe8, 0x03, + 0xc1, 0xe4, 0xe4, 0xab, 0x92, 0xf5, 0x11, 0xd6, 0x45, 0x35, 0xf4, 0x05, 0xe5, + 0xe5, 0xe2, 0xc4, 0x5a, 0xf9, 0xf3, 0xe7, 0xd6, 0xd0, 0x0a, 0xb0, 0x23, 0xdf, + 0x3d, 0xea, 0x29, 0xde, 0x0d, 0xb3, 0x12, 0x0a, 0xee, 0xb1, 0x36, 0x3a, 0xb6, + 0x07, 0x1b, 0xf4, 0xc1, 0x08, 0x2f, 0xc7, 0x03, 0xf6, 0xf1, 0xf8, 0x16, 0x36, + 0xe1, 0x1a, 0x02, 0x08, 0xfd, 0xe9, 0x9b, 0xd2, 0xb8, 0xfc, 0x32, 0xb2, 0xe2, + 0x37, 0xd9, 0xaf, 0x05, 0xfb, 0x52, 0x1c, 0x09, 0x03, 0xe1, 0x2e, 0xd7, 0x2c, + 0x22, 0xf6, 0x04, 0x03, 0x11, 0x26, 0xd9, 0x1e, 0xb1, 0xe4, 0xa7, 0x33, 0xf2, + 0x1a, 0x10, 0xf8, 0xe1, 0x29, 0x0b, 0xe2, 0x1b, 0xf8, 0x1c, 0xd3, 0xc9, 0x17, + 0xec, 0x00, 0x61, 0xbf, 0x01, 0x3c, 0x9c, 0x06, 0x54, 0x10, 0xd4, 0xe9, 0xa2, + 0x3f, 0xba, 0xd3, 0xe5, 0xaa, 0x05, 0x03, 0x50, 0x07, 0x38, 0x17, 0xf9, 0x44, + 0x03, 0xc5, 0xfd, 0xc3, 0xb4, 0xdc, 0xf5, 0x0c, 0x07, 0xf5, 0xcd, 0x31, 0x44, + 0x62, 0x08, 0xbe, 0xa5, 0x34, 0x2a, 0xe7, 0xfa, 0x07, 0xca, 0xd8, 0xad, 0xce, + 0x00, 0xee, 0xdb, 0x1f, 0xb7, 0x38, 0xde, 0xc2, 0x3c, 0xf3, 0xeb, 0xb7, 0x99, + 0xb2, 0x1b, 0x0f, 0xd8, 0x14, 0x17, 0x15, 0x46, 0x19, 0x29, 0x25, 0xae, 0x3a, + 0xce, 0x41, 0x43, 0xdb, 0xd7, 0x1a, 0x1b, 0x91, 0x17, 0xa4, 0x0b, 0xeb, 0x0d, + 0xde, 0xe8, 0xde, 0x81, 0xfd, 0xf2, 0x14, 0xc3, 0xa7, 0x0b, 0xc9, 0xe9, 0x30, + 0xbb, 0x23, 0xef, 0xf0, 0xe4, 0x12, 0xc9, 0xcf, 0xfb, 0x1b, 0xcb, 0xe9, 0xad, + 0xf5, 0x56, 0x03, 0x4d, 0xdb, 0xe6, 0x15, 0x07, 0x5f, 0x34, 0xfa, 0xcb, 0xf5, + 0x2d, 0xd9, 0xc9, 0x19, 0xfe, 0x23, 0xfa, 0xda, 0xdd, 0xd3, 0xac, 0xca, 0x31, + 0xd6, 0x08, 0x1d, 0xef, 0xfe, 0x18, 0xef, 0xfd, 0xee, 0xe9, 0x32, 0x4f, 0xee, + 0x02, 0xf1, 0xf3, 0xb3, 0x61, 0x0b, 0xe7, 0xbe, 0xe6, 0xa2, 0xc3, 0xdd, 0x09, + 0xe6, 0x01, 0xaf, 0xc0, 0x2b, 0xca, 0xf1, 0x3a, 0x2d, 0x2e, 0x31, 0x0c, 0xd1, + 0x88, 0xdf, 0xb5, 0xf1, 0x17, 0x23, 0xf2, 0x3b, 0x08, 0x60, 0xee, 0xd5, 0xfe, + 0x12, 0x18, 0xdc, 0x02, 0x02, 0xa9, 0xdd, 0xde, 0xca, 0xed, 0xd3, 0x11, 0x14, + 0x0f, 0x46, 0xfe, 0x02, 0xc3, 0x1c, 0x18, 0xcd, 0xdc, 0xdd, 0x58, 0xd7, 0xee, + 0x43, 0x1d, 0xce, 0xd9, 0x09, 0xf5, 0x09, 0xe4, 0x58, 0x13, 0xd2, 0x08, 0xe1, + 0xda, 0xee, 0x36, 0xa1, 0xf3, 0x00, 0x43, 0xa5, 0x06, 0xf9, 0x0b, 0xf3, 0xda, + 0x8e, 0xd5, 0xe8, 0xd7, 0xd2, 0x2b, 0x21, 0x00, 0xc0, 0x17, 0xd1, 0x09, 0xd3, + 0xda, 0xfc, 0xba, 0x15, 0x08, 0xee, 0xd8, 0xd6, 0xc4, 0xab, 0x43, 0x03, 0xfa, + 0x10, 0x22, 0xe4, 0xf5, 0xe6, 0x18, 0x18, 0x3a, 0xd2, 0xf4, 0x08, 0xfa, 0xd4, + 0x0d, 0xdc, 0xd9, 0x23, 0xa7, 0xe9, 0x3c, 0xff, 0x1d, 0xf2, 0xef, 0x39, 0x07, + 0x17, 0xc2, 0x30, 0x2f, 0xf3, 0xca, 0x55, 0x15, 0xff, 0xff, 0x99, 0x2d, 0xe0, + 0x44, 0x0d, 0x6e, 0xc6, 0xf1, 0x20, 0x0f, 0xc1, 0xf1, 0x0a, 0xf5, 0xec, 0x11, + 0x24, 0xf8, 0xe8, 0x02, 0xd2, 0xe6, 0x12, 0x1e, 0xff, 0xc9, 0x17, 0xcf, 0xd7, + 0x07, 0xd8, 0x0d, 0x04, 0x0d, 0x2a, 0xfe, 0x09, 0x3b, 0xcd, 0x56, 0x26, 0xcd, + 0x03, 0x2a, 0x0f, 0xdc, 0x3c, 0x01, 0xaa, 0xd8, 0x3f, 0x37, 0x01, 0xde, 0xf3, + 0xe8, 0xdd, 0xf8, 0xe3, 0x01, 0x39, 0xe9, 0xbc, 0x16, 0xfa, 0xe1, 0xd3, 0xf4, + 0xd1, 0x15, 0x22, 0x17, 0xdd, 0x0f, 0xef, 0xd4, 0xd2, 0x15, 0x81, 0xd2, 0x19, + 0xe6, 0xd6, 0x1d, 0x06, 0x08, 0xb7, 0xe2, 0xde, 0xed, 0xe0, 0x0e, 0xed, 0x09, + 0x38, 0xcb, 0xef, 0xea, 0x2f, 0xd9, 0xdf, 0xfb, 0x05, 0xe3, 0x11, 0xce, 0xe7, + 0xf4, 0x15, 0x45, 0xf5, 0xf4, 0x09, 0x16, 0xcc, 0x44, 0xce, 0x1b, 0xe5, 0x0e, + 0xfa, 0xc1, 0x2d, 0x44, 0xed, 0xe6, 0x27, 0xfe, 0x00, 0x23, 0xdb, 0x1a, 0xc1, + 0x2d, 0xad, 0xbe, 0x2b, 0x22, 0xe7, 0x07, 0xe1, 0xd8, 0xf6, 0xe7, 0x53, 0xbb, + 0xd1, 0x85, 0xe7, 0xdd, 0x32, 0xe2, 0xf3, 0xe0, 0x05, 0x09, 0xfa, 0xd7, 0xf4, + 0x15, 0x3b, 0xea, 0x16, 0x0f, 0xe8, 0xd4, 0x44, 0xf8, 0xb0, 0xe4, 0xe9, 0xe4, + 0xe1, 0xb7, 0x52, 0xb5, 0x65, 0x03, 0x11, 0xab, 0xbe, 0x3f, 0xc8, 0x21, 0xf7, + 0x09, 0x0f, 0x31, 0xf4, 0x47, 0xfc, 0xfb, 0xdb, 0x81, 0x2a, 0x37, 0xd4, 0xc4, + 0x08, 0xb7, 0xff, 0xfc, 0x27, 0x1c, 0xf0, 0x00, 0x07, 0x16, 0x07, 0xaf, 0xe4, + 0xda, 0x26, 0xcc, 0xf1, 0xd8, 0x37, 0x35, 0x18, 0x36, 0x0c, 0x0b, 0x4e, 0xfc, + 0xd7, 0x97, 0x15, 0xed, 0xdf, 0xf1, 0x00, 0xe7, 0x2b, 0xde, 0xf3, 0xb5, 0xc6, + 0x33, 0xd5, 0xf2, 0x0e, 0x1f, 0xf0, 0xcd, 0xbf, 0x40, 0xbe, 0x07, 0xd4, 0x8c, + 0xd4, 0xbe, 0x92, 0xdb, 0x3e, 0x1b, 0xfb, 0xd4, 0x1a, 0xe1, 0x0d, 0x0d, 0x1b, + 0xe6, 0x9f, 0xd9, 0xc0, 0xb9, 0x09, 0xd8, 0xa6, 0xdd, 0xfd, 0xf8, 0x0d, 0x01, + 0x3d, 0xb7, 0xe6, 0xe1, 0xca, 0xe0, 0x01, 0xe4, 0xa9, 0x0f, 0x18, 0x1d, 0xc2, + 0xf0, 0x08, 0x16, 0x11, 0x06, 0x14, 0xb4, 0x9a, 0xb5, 0xc1, 0x90, 0xc7, 0x00, + 0xfc, 0x0b, 0xd5, 0x95, 0xe6, 0x24, 0xf3, 0xfb, 0x01, 0xac, 0xc0, 0x13, 0xe2, + 0xff, 0xd0, 0xd2, 0x1a, 0x1c, 0xb5, 0x4d, 0x3b, 0xeb, 0x1f, 0xf0, 0xf8, 0xb5, + 0xcb, 0xff, 0xd9, 0x19, 0xd4, 0xf6, 0x16, 0x14, 0xdb, 0xfe, 0x26, 0xdb, 0x97, + 0x44, 0x21, 0x3a, 0xec, 0xda, 0xe3, 0x08, 0xa7, 0x4e, 0xd7, 0xf2, 0x34, 0xcb, + 0x40, 0xd0, 0x75, 0x1b, 0xf4, 0x2b, 0x26, 0xf3, 0x2c, 0xc8, 0xe5, 0xd6, 0x71, + 0x1d, 0xf3, 0xb9, 0x64, 0xc1, 0xee, 0x25, 0x27, 0xc0, 0x0c, 0x19, 0xf1, 0x11, + 0x61, 0x01, 0xea, 0x0c, 0xf7, 0xa1, 0x1a, 0x18, 0xe4, 0xc7, 0xf5, 0x23, 0xf5, + 0x3a, 0xfe, 0x87, 0xfb, 0x9f, 0x09, 0xd2, 0x24, 0x24, 0x27, 0xf5, 0xa1, 0x17, + 0x36, 0x0c, 0xe9, 0xf0, 0x28, 0xec, 0xe2, 0xe1, 0xb5, 0xcb, 0x07, 0xf7, 0xe0, + 0x15, 0x1c, 0xea, 0xde, 0x00, 0x0a, 0x20, 0xe8, 0xe8, 0x42, 0xde, 0xea, 0x01, + 0xff, 0xf1, 0x31, 0x2c, 0x2f, 0x11, 0xe7, 0xf1, 0xfd, 0xd4, 0xed, 0x03, 0xf1, + 0xdd, 0xf6, 0xcf, 0xca, 0x01, 0x40, 0xf4, 0xff, 0xe4, 0xe0, 0x0b, 0x3d, 0xe8, + 0x2c, 0xca, 0xf4, 0xe0, 0xf6, 0x55, 0xef, 0x27, 0xff, 0xd2, 0xd6, 0x5f, 0x07, + 0xe4, 0xfa, 0xf1, 0x32, 0xf4, 0x36, 0xca, 0xea, 0x26, 0x1a, 0x13, 0x26, 0x19, + 0xde, 0x10, 0x13, 0xe2, 0xc0, 0x00, 0xc2, 0xd2, 0x03, 0x02, 0x3e, 0xed, 0x02, + 0x54, 0xcd, 0x10, 0x06, 0x18, 0xd4, 0x60, 0x05, 0x2f, 0x07, 0xd7, 0xd7, 0x14, + 0x28, 0xf8, 0xf5, 0xec, 0xd3, 0x03, 0xe5, 0xf9, 0x4f, 0x04, 0x17, 0xec, 0x55, + 0x00, 0x13, 0x04, 0xea, 0x27, 0xf4, 0xb2, 0x07, 0xf2, 0xd7, 0x32, 0xfa, 0x31, + 0x48, 0x09, 0xfa, 0x40, 0xca, 0xff, 0xf9, 0x44, 0xf6, 0x26, 0x11, 0x11, 0xd5, + 0x20, 0xd1, 0xcf, 0x7f, 0x39, 0x25, 0x2c, 0x2c, 0xc4, 0x1c, 0x20, 0xd9, 0xa5, + 0x11, 0x0b, 0xcb, 0xfa, 0xed, 0xd9, 0xe5, 0x13, 0xd0, 0xcf, 0x26, 0xe4, 0xf7, + 0xd7, 0x16, 0x51, 0xc4, 0xea, 0xec, 0x0a, 0xfe, 0x1a, 0x11, 0x15, 0x18, 0x27, + 0x6a, 0xf1, 0x29, 0xed, 0xfd, 0xe2, 0xe3, 0xe6, 0x16, 0x1b, 0x17, 0x2a, 0x13, + 0x16, 0x01, 0xd9, 0xd2, 0x07, 0xe4, 0x04, 0xd6, 0x4a, 0xfd, 0x24, 0x09, 0xde, + 0x33, 0xb7, 0xfe, 0xc1, 0x02, 0xdc, 0x25, 0xf1, 0xe0, 0x5d, 0x19, 0xf6, 0xee, + 0xe6, 0xc8, 0x31, 0xe1, 0xe5, 0xed, 0x00, 0xf9, 0xf2, 0xf8, 0xc7, 0x02, 0x02, + 0xc1, 0xd9, 0xdd, 0x37, 0xc9, 0xbe, 0xe8, 0xf9, 0x2b, 0xe3, 0xdf, 0x14, 0xa8, + 0x31, 0xc8, 0xcf, 0xfd, 0xec, 0x2a, 0xf6, 0xb3, 0x96, 0xdb, 0xc9, 0xd5, 0x01, + 0xee, 0xec, 0x02, 0x3a, 0x03, 0xb3, 0x56, 0x21, 0xcf, 0xd3, 0x28, 0x2d, 0xb4, + 0xd0, 0x0b, 0xd6, 0xf1, 0xac, 0xf8, 0xdb, 0x12, 0x40, 0x19, 0x9e, 0xfa, 0x27, + 0xe5, 0x1d, 0xf5, 0xeb, 0xea, 0xbe, 0xb9, 0xc6, 0xde, 0xd7, 0xf9, 0xd9, 0xe4, + 0x35, 0xca, 0xce, 0x2a, 0x56, 0xbe, 0x0d, 0x06, 0xff, 0xcc, 0xe7, 0xba, 0x17, + 0x22, 0xea, 0xc2, 0x3d, 0x15, 0xe4, 0x2c, 0x0b, 0x0c, 0xf4, 0xf8, 0x56, 0x43, + 0x4c, 0xfd, 0xf4, 0xb6, 0xd5, 0xf9, 0xd5, 0x05, 0x1c, 0xdf, 0xfe, 0x00, 0x35, + 0xec, 0xe6, 0xa9, 0x06, 0x17, 0xdc, 0xcf, 0x06, 0xf1, 0x42, 0x25, 0xd2, 0xc6, + 0x1a, 0xfc, 0xe6, 0xf0, 0xd5, 0xdd, 0xde, 0xf2, 0xd3, 0xfe, 0x06, 0x81, 0x23, + 0x20, 0x3a, 0x1f, 0x24, 0xe7, 0x17, 0x09, 0x21, 0xff, 0xb7, 0xeb, 0xb4, 0xc7, + 0xf0, 0xb0, 0xb3, 0xfa, 0x0c, 0xc3, 0x22, 0xf4, 0x1b, 0xdd, 0xd3, 0x17, 0x3b, + 0x33, 0xa2, 0xd1, 0x18, 0x1f, 0x2a, 0xce, 0x0d, 0xbe, 0xc4, 0x0f, 0x3f, 0xff, + 0xe9, 0xdc, 0xaf, 0x01, 0xec, 0xeb, 0xf1, 0xc8, 0xc1, 0x22, 0xc8, 0x2d, 0xa7, + 0xc6, 0xbe, 0x44, 0xd5, 0xea, 0x1a, 0x1d, 0x0d, 0x1e, 0x0f, 0x21, 0x03, 0x45, + 0xd5, 0x39, 0xfa, 0x0e, 0xf4, 0xdf, 0xf9, 0x0d, 0xdf, 0x17, 0x23, 0x8a, 0x14, + 0x20, 0xcc, 0x08, 0x09, 0xe1, 0x25, 0xe3, 0xb9, 0x1e, 0xf4, 0x1e, 0xcf, 0xe2, + 0xef, 0xca, 0xf0, 0x2d, 0x1c, 0x00, 0xf9, 0xdd, 0x88, 0x1f, 0x0c, 0xdd, 0x2e, + 0x03, 0xd2, 0x05, 0x0a, 0xe4, 0x35, 0x0a, 0x2b, 0xbb, 0xb6, 0x09, 0xbc, 0xe5, + 0xfd, 0xeb, 0xd3, 0xe6, 0xdc, 0x08, 0xd8, 0x39, 0x1d, 0xf0, 0x3b, 0xe1, 0x04, + 0xfa, 0x0a, 0xf5, 0xe4, 0x13, 0xd6, 0x2e, 0x08, 0x05, 0x18, 0xa6, 0xd3, 0xd9, + 0x3f, 0x31, 0xb7, 0x08, 0x8e, 0x10, 0x21, 0xda, 0x1d, 0xe8, 0xe7, 0xf2, 0x1a, + 0x06, 0xba, 0xd7, 0x09, 0x01, 0xcd, 0xf7, 0xb1, 0xe6, 0x01, 0xfe, 0xf6, 0xe8, + 0xe0, 0xc5, 0xd5, 0xdc, 0xbc, 0xff, 0xb1, 0x1e, 0x2c, 0xd5, 0xf6, 0xed, 0x42, + 0xb0, 0x07, 0x08, 0x1c, 0xe9, 0x30, 0xf3, 0xde, 0xcf, 0x16, 0x2d, 0xf1, 0x28, + 0xe1, 0xd2, 0x20, 0x1c, 0xe8, 0xfb, 0x17, 0xe1, 0x23, 0xe5, 0xd1, 0xfc, 0xee, + 0x0e, 0x20, 0x0e, 0x15, 0x11, 0xc7, 0x1a, 0x00, 0x17, 0xc6, 0x24, 0xd6, 0x05, + 0x1f, 0x08, 0xfc, 0x08, 0xef, 0xf7, 0xf4, 0xc6, 0xd1, 0xe1, 0x29, 0xe6, 0xed, + 0x0b, 0xb6, 0x19, 0xf5, 0xea, 0x2a, 0x25, 0xfc, 0xa5, 0xd9, 0x1f, 0x3f, 0x30, + 0x00, 0x01, 0x29, 0xdb, 0x06, 0xf3, 0x24, 0xa9, 0x21, 0x1f, 0x16, 0x13, 0x03, + 0x1d, 0x2c, 0x04, 0xea, 0xf7, 0xe3, 0xee, 0x43, 0x20, 0x40, 0xfc, 0x38, 0xcd, + 0x5c, 0xfb, 0x36, 0xd6, 0xd5, 0x30, 0xbd, 0xeb, 0xe3, 0x0a, 0xd4, 0xec, 0xef, + 0xfb, 0xd2, 0xf5, 0x08, 0xe8, 0x0a, 0xfb, 0xe1, 0x32, 0x81, 0x2f, 0xc8, 0x38, + 0xf4, 0x1a, 0xd2, 0xac, 0xd2, 0x02, 0x1c, 0xd1, 0xef, 0xf9, 0xad, 0xe8, 0xee, + 0xf3, 0x13, 0xff, 0x16, 0xa1, 0xa7, 0xd4, 0xf2, 0xee, 0x21, 0x00, 0x19, 0x30, + 0x40, 0xd8, 0x0f, 0x19, 0x16, 0x4d, 0x3a, 0x1c, 0xb3, 0xea, 0x00, 0xff, 0x88, + 0xfd, 0xfe, 0xc6, 0x38, 0x02, 0xe9, 0x06, 0xfe, 0x2a, 0x3a, 0x11, 0x10, 0xf4, + 0x11, 0xef, 0xf7, 0xea, 0xf9, 0x28, 0xd1, 0x17, 0xdb, 0xbe, 0x07, 0x46, 0xe6, + 0x94, 0x02, 0xe8, 0x12, 0x06, 0x09, 0x06, 0xf5, 0xbd, 0xb4, 0xda, 0xd2, 0x32, + 0xd9, 0x2a, 0xa1, 0x3a, 0x3c, 0xe1, 0xe2, 0x26, 0x2a, 0x12, 0xc2, 0xeb, 0x01, + 0xbe, 0xf6, 0x1f, 0x5d, 0x36, 0xff, 0x04, 0x09, 0xcb, 0x19, 0x23, 0x10, 0xfc, + 0xc8, 0xce, 0x10, 0x18, 0x0c, 0x08, 0xc7, 0xe6, 0x0f, 0xe5, 0xd1, 0xf0, 0xda, + 0xd5, 0xe0, 0xc2, 0x24, 0xda, 0xe2, 0x0a, 0xf9, 0xec, 0x4d, 0x8c, 0xdf, 0xde, + 0xfe, 0x1a, 0xf0, 0xc1, 0xc3, 0xcd, 0x2b, 0xe9, 0x0e, 0xc9, 0xa6, 0x35, 0xee, + 0x2c, 0xe2, 0x4d, 0xfd, 0x1e, 0xfc, 0xf7, 0xc9, 0x4d, 0x27, 0xaf, 0xde, 0xd3, + 0xb2, 0xd9, 0xfb, 0xef, 0x27, 0xfd, 0x0f, 0x1a, 0xef, 0x96, 0xc4, 0x23, 0xf1, + 0xdc, 0x0c, 0x07, 0x0f, 0xeb, 0x34, 0xf7, 0x2a, 0x17, 0xf5, 0xdf, 0x09, 0x9f, + 0xdb, 0xf2, 0xb5, 0xe4, 0xf0, 0x1e, 0x3e, 0xe4, 0x4b, 0x15, 0x0b, 0xb3, 0x11, + 0xdb, 0xf4, 0xef, 0x50, 0x1f, 0x3f, 0x24, 0x46, 0xda, 0xdf, 0x0b, 0x30, 0x82, + 0xf8, 0xbd, 0xff, 0xdb, 0xdd, 0x15, 0xe8, 0x3f, 0xba, 0x3c, 0xc9, 0x3e, 0x19, + 0xb7, 0xcc, 0xee, 0xf3, 0xf2, 0xb9, 0x36, 0x25, 0x1e, 0x2c, 0x0c, 0xbf, 0x07, + 0xf1, 0xc7, 0x12, 0xfb, 0xda, 0x49, 0x2d, 0xb1, 0xbf, 0xe7, 0xce, 0x0e, 0xf9, + 0x2f, 0xe4, 0x09, 0x1c, 0xe3, 0xd2, 0x47, 0xc7, 0xf0, 0xe3, 0x3a, 0xab, 0xd1, + 0xf2, 0xf3, 0xf2, 0xb5, 0x21, 0xe5, 0xe0, 0xde, 0x13, 0xfc, 0xb6, 0x04, 0xf0, + 0xd5, 0x99, 0xe3, 0xfb, 0xbb, 0x04, 0xe3, 0xfa, 0xc8, 0xf2, 0x15, 0xdd, 0xc8, + 0xb1, 0x28, 0x0b, 0xad, 0x1d, 0x21, 0xe9, 0x23, 0xd4, 0xd0, 0xe8, 0xc0, 0xc8, + 0xe5, 0x12, 0x11, 0x14, 0xda, 0x09, 0xf8, 0xcc, 0x0f, 0xe2, 0x22, 0xcc, 0xfd, + 0x03, 0xb1, 0x9e, 0xde, 0xbc, 0x3a, 0x14, 0x2d, 0xe1, 0xe5, 0xc6, 0xd9, 0x9b, + 0xec, 0x05, 0xa3, 0x20, 0x30, 0xc1, 0xfc, 0x26, 0xe3, 0x3f, 0x1e, 0xff, 0xe3, + 0x0d, 0x50, 0x01, 0x9e, 0xd6, 0xff, 0xae, 0x18, 0x01, 0x2b, 0x49, 0x0b, 0x5d, + 0x0b, 0xf0, 0xed, 0x06, 0x2f, 0x4c, 0x3d, 0x0d, 0xd2, 0xd4, 0x7f, 0xfc, 0xf1, + 0x49, 0x10, 0xe1, 0xf6, 0xf4, 0x92, 0x2e, 0xdf, 0xed, 0x1a, 0x01, 0x17, 0x08, + 0xe2, 0xee, 0x49, 0x10, 0x8f, 0x0b, 0xde, 0x2c, 0xe8, 0x1b, 0x07, 0xbf, 0xce, + 0xc3, 0xee, 0xfa, 0x2b, 0xe7, 0xd4, 0x25, 0x05, 0xd0, 0x1d, 0xbd, 0xb1, 0xbd, + 0xfa, 0x0d, 0xd8, 0xff, 0xe2, 0x14, 0xfc, 0xf8, 0x16, 0xca, 0xf9, 0x33, 0xef, + 0x17, 0xd3, 0x2a, 0xed, 0xa4, 0x50, 0xda, 0x3b, 0x51, 0xe0, 0x5f, 0xf8, 0x03, + 0x35, 0xb8, 0xdc, 0xc5, 0xe4, 0x1c, 0x10, 0x9e, 0xe2, 0xe2, 0xba, 0xd7, 0xdb, + 0x42, 0xb5, 0xe3, 0xd4, 0xf1, 0x07, 0xeb, 0xfe, 0xe7, 0xfa, 0xa1, 0xfa, 0x38, + 0x1a, 0xc8, 0xe9, 0x41, 0xed, 0xe6, 0x9a, 0xac, 0xf1, 0x26, 0xff, 0x25, 0xc5, + 0xf4, 0xe8, 0xb6, 0xfe, 0x4e, 0xff, 0x24, 0xda, 0x21, 0xfb, 0xa5, 0x22, 0xf2, + 0xbc, 0xd2, 0xef, 0x02, 0xfd, 0xf1, 0xb2, 0xf0, 0x6a, 0xbd, 0x10, 0xe5, 0x53, + 0xe6, 0x3a, 0x18, 0x8b, 0xfb, 0x0e, 0x32, 0x24, 0xe9, 0x7f, 0x0e, 0xd2, 0x1f, + 0x32, 0xc6, 0xf0, 0xb3, 0xa1, 0xf7, 0x14, 0x3f, 0x13, 0xdf, 0xb5, 0xe9, 0xb8, + 0xc8, 0xe6, 0xe4, 0x09, 0xf6, 0x2d, 0x29, 0xf3, 0x67, 0x10, 0x0e, 0xdd, 0x27, + 0x1e, 0x0d, 0xc3, 0xd7, 0x0b, 0x38, 0x55, 0xc8, 0xee, 0xb1, 0xce, 0xf7, 0xd0, + 0xe2, 0xf4, 0xc2, 0xee, 0xd2, 0xe1, 0xf0, 0x39, 0x91, 0x4a, 0xfa, 0x9c, 0xfe, + 0x33, 0xcc, 0x15, 0xba, 0xe4, 0x9d, 0x00, 0x1e, 0xe6, 0xe8, 0x74, 0x25, 0x50, + 0xdd, 0xd3, 0x58, 0xf8, 0xed, 0xf2, 0xda, 0x67, 0xc5, 0xf9, 0x30, 0x21, 0xf7, + 0xfa, 0xdf, 0x75, 0x1d, 0xf3, 0xf9, 0xb1, 0xb3, 0xc8, 0x52, 0x2c, 0x95, 0xdb, + 0xfd, 0xe0, 0xb7, 0xde, 0x52, 0xf1, 0x50, 0xf3, 0xf9, 0xe1, 0xec, 0x1d, 0x12, + 0xe4, 0xbd, 0x23, 0x0b, 0xf0, 0xbb, 0x49, 0x38, 0xd0, 0xcc, 0x20, 0xff, 0x14, + 0xf9, 0xe3, 0xd8, 0xcb, 0xf8, 0xf7, 0xf9, 0xe9, 0xe4, 0xdb, 0xd0, 0xcc, 0xea, + 0x3c, 0x1c, 0xf2, 0xbc, 0x26, 0xf6, 0x06, 0xe3, 0x00, 0x0c, 0xf4, 0xff, 0xfb, + 0x15, 0xf8, 0x01, 0x2c, 0x05, 0xbb, 0xc6, 0x07, 0xc6, 0xf5, 0x3b, 0x2d, 0x1a, + 0xf2, 0x2f, 0xcd, 0xc9, 0xfa, 0xf3, 0x03, 0x35, 0xe8, 0x19, 0xde, 0xcc, 0xef, + 0x31, 0xf1, 0xee, 0x2e, 0x5e, 0xc9, 0x05, 0x7b, 0x1c, 0xb9, 0xbc, 0x09, 0x4a, + 0x30, 0x08, 0x01, 0xea, 0xd6, 0xe7, 0xb6, 0xcb, 0x0a, 0xd8, 0xe0, 0x0c, 0x11, + 0x09, 0x0c, 0x22, 0xe1, 0xe9, 0x13, 0xc4, 0x01, 0x18, 0xe3, 0xd0, 0xf3, 0x28, + 0x0b, 0xc1, 0xc2, 0xd4, 0xff, 0xf0, 0x16, 0x5f, 0x33, 0x16, 0xcb, 0xd4, 0xb7, + 0xde, 0xd2, 0x16, 0xde, 0xf2, 0xfe, 0xb4, 0xdf, 0xb2, 0x1b, 0xb6, 0x9e, 0xf7, + 0xfe, 0xbf, 0xaf, 0x21, 0xae, 0x2a, 0x23, 0xdb, 0xe7, 0xe9, 0x1b, 0xcd, 0x1d, + 0x17, 0xae, 0xdb, 0x32, 0x42, 0xb9, 0xc8, 0xf2, 0x0a, 0xfc, 0xe1, 0xb2, 0xd7, + 0xd6, 0xe5, 0xeb, 0x4b, 0xd0, 0x45, 0xcb, 0xa7, 0x12, 0xd0, 0x31, 0xe4, 0x8b, + 0x03, 0x38, 0x00, 0xbd, 0x28, 0xea, 0xf4, 0xf3, 0x2c, 0xfa, 0xad, 0x27, 0xf4, + 0xdd, 0x63, 0xdc, 0xf3, 0xd7, 0xd1, 0x7f, 0xfa, 0x34, 0x1b, 0x23, 0xbc, 0xf7, + 0xe0, 0x20, 0x26, 0x24, 0xd2, 0xa3, 0x16, 0xe7, 0xf0, 0xd2, 0xf9, 0xa7, 0xbe, + 0xd7, 0xec, 0x12, 0x07, 0x13, 0x00, 0x0f, 0xdc, 0x50, 0x10, 0xf3, 0xad, 0x38, + 0x93, 0x13, 0xf5, 0x01, 0xb5, 0xbd, 0xe4, 0xd3, 0x0a, 0xe2, 0x28, 0x3e, 0x2d, + 0x20, 0x1c, 0xea, 0xd8, 0xb6, 0x53, 0xe6, 0xca, 0x0b, 0xf1, 0x0e, 0xa9, 0x1e, + 0x07, 0x2f, 0x4f, 0xf1, 0xe0, 0xc3, 0xc6, 0xce, 0x01, 0x09, 0xd0, 0x0d, 0x18, + 0x25, 0x30, 0x17, 0x9d, 0x33, 0x60, 0xfa, 0x07, 0x40, 0xd6, 0x0a, 0x0a, 0x21, + 0xfe, 0xb5, 0x0d, 0x12, 0xe5, 0xe2, 0xce, 0xdf, 0x01, 0xdf, 0xd0, 0x0c, 0x27, + 0x22, 0x28, 0x21, 0x2c, 0xf2, 0x51, 0x2d, 0x1b, 0xc3, 0x2c, 0xb5, 0x07, 0xd1, + 0xd4, 0x30, 0xee, 0xd9, 0x24, 0xf5, 0x13, 0xe2, 0xc9, 0x14, 0x10, 0x19, 0xbc, + 0x00, 0xfd, 0xd1, 0xe4, 0xd8, 0x13, 0xb3, 0xdc, 0xef, 0xcd, 0xe1, 0x40, 0x1c, + 0xd7, 0xdf, 0x17, 0x1c, 0xf5, 0xe4, 0xf0, 0xcc, 0xe8, 0xd4, 0x11, 0xdd, 0xbb, + 0x34, 0xf3, 0x38, 0x09, 0x3f, 0x1a, 0xef, 0xf8, 0xee, 0xd2, 0x35, 0xe9, 0x22, + 0xd1, 0xd0, 0x36, 0x07, 0xfe, 0x1b, 0xfe, 0xd1, 0x06, 0xee, 0xd8, 0x9c, 0xee, + 0xe9, 0x24, 0x27, 0x09, 0xd1, 0x02, 0xcc, 0x34, 0xf7, 0x7f, 0x2f, 0x02, 0x09, + 0xc1, 0xea, 0xd3, 0x1c, 0x3c, 0xe8, 0xe6, 0x09, 0xda, 0xf9, 0xda, 0xe1, 0xf3, + 0x38, 0x20, 0xb9, 0x0d, 0x14, 0xeb, 0xef, 0xfd, 0xb3, 0xe6, 0x07, 0x1a, 0xff, + 0xf0, 0x1a, 0x2f, 0xc3, 0x12, 0x31, 0xf0, 0xed, 0x3c, 0xd1, 0x03, 0x2b, 0xb3, + 0x18, 0xc0, 0x9b, 0xed, 0x23, 0x1d, 0xd9, 0xc2, 0x07, 0xf9, 0x28, 0x15, 0x08, + 0x1a, 0xc5, 0x04, 0xc6, 0x19, 0xe5, 0x0c, 0x4c, 0x05, 0x09, 0xda, 0xff, 0x02, + 0x2f, 0xe9, 0x0a, 0xdf, 0xa0, 0x03, 0x21, 0x31, 0x11, 0xff, 0x07, 0x4d, 0xd7, + 0x07, 0x46, 0xdc, 0xcf, 0x08, 0xe9, 0xf8, 0xef, 0xa3, 0x38, 0x02, 0x28, 0x1b, + 0x27, 0x95, 0xe5, 0x1d, 0x99, 0x94, 0xc4, 0x23, 0xeb, 0x0e, 0xb9, 0xaf, 0xcd, + 0x39, 0xfe, 0xfb, 0xeb, 0x01, 0x2e, 0xea, 0xd9, 0xf6, 0xf3, 0x0a, 0x19, 0xc4, + 0x21, 0x2e, 0xe4, 0x03, 0xdf, 0xfc, 0xec, 0xe9, 0xc3, 0x02, 0x2b, 0x4b, 0x0b, + 0xca, 0x0a, 0x4a, 0xbe, 0x14, 0x0a, 0xe9, 0x37, 0xa3, 0xbb, 0xb6, 0x3a, 0xd7, + 0x27, 0xb0, 0x05, 0xfe, 0xff, 0xe4, 0x0f, 0x8f, 0xf8, 0x19, 0x9e, 0xcc, 0xe9, + 0x46, 0xf8, 0xb9, 0xf7, 0xc5, 0xab, 0xfa, 0x09, 0x60, 0x24, 0xc8, 0x15, 0xa0, + 0x25, 0x07, 0xc6, 0xd3, 0xda, 0xf1, 0x3a, 0x2b, 0xd7, 0xe4, 0x18, 0xee, 0x54, + 0x1a, 0x03, 0x16, 0x18, 0xb6, 0xfb, 0xd9, 0x3f, 0x00, 0x09, 0x28, 0xe3, 0xdf, + 0xc9, 0x2c, 0x85, 0xf3, 0xf6, 0x16, 0xdc, 0xee, 0x0d, 0xfa, 0x2f, 0xf4, 0xde, + 0x1d, 0xd9, 0xd9, 0x36, 0x23, 0xd5, 0xec, 0x0f, 0x05, 0x00, 0x30, 0x3a, 0xdc, + 0x20, 0xcd, 0xb6, 0x45, 0x99, 0xca, 0x0c, 0x4a, 0x31, 0x12, 0xd8, 0xfa, 0xfd, + 0x17, 0x82, 0xbd, 0x06, 0xe3, 0x25, 0xbc, 0x37, 0xdc, 0xdf, 0xc2, 0xcb, 0x34, + 0xe4, 0xf9, 0xb7, 0xf4, 0x0d, 0x9b, 0xe3, 0xd2, 0x81, 0xd9, 0x46, 0xce, 0xae, + 0xb0, 0x68, 0xe0, 0x06, 0xec, 0xfd, 0x0e, 0x37, 0x0a, 0x24, 0x18, 0x0d, 0x13, + 0xa7, 0xdb, 0x02, 0x86, 0xb0, 0x25, 0xed, 0xcf, 0x01, 0xf5, 0xd2, 0xd5, 0xf1, + 0xf1, 0xf6, 0xc6, 0xd9, 0xda, 0xc8, 0x11, 0x28, 0x22, 0xae, 0xf9, 0x07, 0xe1, + 0xdb, 0xfc, 0x0b, 0x88, 0xd0, 0x02, 0xca, 0xe7, 0xfc, 0xd1, 0xb1, 0x10, 0x03, + 0x48, 0x08, 0xfd, 0x44, 0x35, 0x0b, 0xd7, 0x23, 0xf6, 0x19, 0xfe, 0x01, 0xf3, + 0x2e, 0xd5, 0x30, 0x45, 0x3e, 0x48, 0xb6, 0x19, 0x09, 0xf7, 0x07, 0x14, 0x20, + 0xfd, 0xd6, 0xd9, 0x23, 0x0f, 0x11, 0x02, 0x3f, 0xc6, 0xec, 0x24, 0x07, 0xe2, + 0xd9, 0xeb, 0xfd, 0xf9, 0xd4, 0x12, 0x14, 0x1d, 0x29, 0x1e, 0x29, 0x0b, 0xad, + 0x1e, 0x2d, 0x0a, 0xd6, 0xd7, 0xfb, 0x33, 0x30, 0xd0, 0xc7, 0xf3, 0x3f, 0xf4, + 0xf0, 0xe1, 0x46, 0x16, 0x55, 0xf9, 0x3e, 0xc9, 0x19, 0x1c, 0xec, 0xf2, 0xeb, + 0x9a, 0xc4, 0xf1, 0x05, 0xce, 0xe6, 0xea, 0xf5, 0xd0, 0x08, 0x25, 0x22, 0xdf, + 0xf7, 0xcd, 0xb2, 0x02, 0xfc, 0xce, 0xc8, 0xd1, 0xa6, 0x33, 0x02, 0x07, 0x21, + 0xf2, 0xb1, 0xd8, 0xef, 0xe0, 0xc2, 0xd6, 0xf7, 0xfd, 0xce, 0xc4, 0x08, 0xce, + 0x2d, 0x0e, 0x98, 0xff, 0xcb, 0xf3, 0xda, 0x40, 0x15, 0xf3, 0x10, 0xf7, 0xe1, + 0xc4, 0xe0, 0xc8, 0x10, 0xf3, 0xfc, 0x27, 0xc2, 0x1a, 0xc3, 0x18, 0xdf, 0xce, + 0xa5, 0xd0, 0x42, 0x24, 0xd5, 0x0f, 0xe6, 0xf8, 0xf8, 0xf1, 0x15, 0xf1, 0xbb, + 0x1b, 0xc1, 0x05, 0xfb, 0x41, 0xba, 0xf0, 0xce, 0x01, 0x43, 0xe6, 0xf2, 0x2d, + 0xea, 0xba, 0xde, 0xd4, 0x09, 0x04, 0xfc, 0xff, 0xdd, 0xcd, 0x21, 0x09, 0xfd, + 0x2b, 0xfa, 0xf5, 0xf7, 0x2b, 0xfe, 0x13, 0xd6, 0x07, 0x86, 0x33, 0xe8, 0x13, + 0x0f, 0x03, 0xcf, 0xa3, 0xc1, 0x0d, 0x08, 0x2b, 0xd6, 0xe0, 0xce, 0x0a, 0xf5, + 0xf3, 0x04, 0xdf, 0xb0, 0xe9, 0xf4, 0x13, 0xfb, 0xa8, 0xd9, 0xd9, 0xfe, 0x0f, + 0xbe, 0xc9, 0x25, 0x35, 0x03, 0xcf, 0xe3, 0xe0, 0xf0, 0x56, 0x0e, 0xf1, 0x2b, + 0x1e, 0xf0, 0x07, 0xf0, 0x15, 0x9e, 0xc6, 0xf2, 0xfc, 0x1e, 0xa6, 0xb1, 0xed, + 0x2a, 0x25, 0x22, 0x32, 0x13, 0xbf, 0xc3, 0x0d, 0x18, 0xd3, 0xf6, 0x02, 0x02, + 0xe3, 0x22, 0x76, 0xfd, 0xdd, 0xdd, 0xed, 0xde, 0xe4, 0xd9, 0xa0, 0x26, 0xdb, + 0xbd, 0xf1, 0x1a, 0xae, 0xf7, 0xd3, 0xc0, 0xf1, 0xc7, 0xf3, 0xc9, 0xfe, 0x31, + 0x84, 0xb1, 0xc5, 0x46, 0xf4, 0xfc, 0x49, 0xf5, 0xcf, 0x16, 0xe8, 0xef, 0xe1, + 0x0a, 0xfd, 0xcd, 0xd1, 0xff, 0xf3, 0xf1, 0xf7, 0xf5, 0xec, 0xc5, 0x11, 0xd7, + 0xd4, 0x15, 0x13, 0xae, 0xe5, 0xe7, 0x34, 0xdb, 0x0f, 0x1b, 0x23, 0x9b, 0xc9, + 0xbf, 0xdd, 0x7f, 0xfa, 0x00, 0x04, 0xbc, 0xa6, 0xcb, 0xf2, 0x0e, 0xbc, 0xec, + 0x96, 0xeb, 0xf9, 0xe8, 0xe0, 0x1d, 0x97, 0xfa, 0xf0, 0xfc, 0xf3, 0x19, 0xd1, + 0x1c, 0x1b, 0xd9, 0xf0, 0xb2, 0x1f, 0xd0, 0x1e, 0x2b, 0xfc, 0x00, 0xe1, 0x0d, + 0x19, 0xf1, 0xf9, 0x08, 0xeb, 0xcd, 0xca, 0xed, 0xbf, 0xdb, 0x08, 0x2f, 0x0e, + 0xeb, 0x9f, 0xc9, 0xc4, 0x1c, 0x0b, 0xce, 0xbf, 0x28, 0x09, 0x0d, 0x3e, 0x29, + 0xc5, 0x18, 0x30, 0xf1, 0x4b, 0xed, 0xff, 0xe2, 0xec, 0xf0, 0x09, 0xd4, 0x6c, + 0x39, 0xcd, 0x21, 0xd3, 0x5b, 0x0f, 0x0c, 0xd1, 0xf2, 0x2d, 0xe3, 0x0d, 0xdd, + 0x07, 0xb1, 0x33, 0xe5, 0xb9, 0x1b, 0xc7, 0x04, 0x10, 0xf4, 0xc2, 0x4d, 0x16, + 0x98, 0xe1, 0x1c, 0xe4, 0x31, 0xfb, 0xe0, 0x00, 0x07, 0x43, 0x0e, 0xe2, 0xde, + 0xd4, 0xb1, 0x14, 0xec, 0x7f, 0xdc, 0xf2, 0xee, 0xc4, 0xd4, 0x53, 0x19, 0xe3, + 0xfb, 0xf1, 0xdb, 0xb4, 0x06, 0xb9, 0xc3, 0x16, 0x06, 0xfb, 0x00, 0xd0, 0xc9, + 0xee, 0x04, 0x50, 0x42, 0xaa, 0xbd, 0xbb, 0xe1, 0xde, 0x1c, 0xfc, 0xe2, 0xcf, + 0xb4, 0x0f, 0xeb, 0xff, 0x88, 0x4f, 0x0f, 0x9c, 0xd3, 0xe2, 0xd7, 0xdb, 0x18, + 0x1d, 0xfc, 0xef, 0xca, 0x31, 0xfc, 0x1b, 0x1b, 0xa6, 0xdd, 0xfd, 0xfc, 0x0b, + 0x4a, 0x0f, 0x1c, 0xda, 0x8d, 0x3b, 0x1b, 0xe7, 0x0d, 0xde, 0xd1, 0x15, 0x11, + 0xcf, 0x0b, 0x29, 0x19, 0x03, 0x31, 0xf0, 0x5a, 0xf0, 0xc4, 0xdd, 0x3e, 0x25, + 0xfd, 0xd3, 0xdc, 0xe8, 0xda, 0xb8, 0xc7, 0xff, 0xe6, 0xf2, 0xc7, 0x07, 0xd5, + 0x1f, 0xfa, 0xc4, 0x36, 0xb4, 0x2f, 0xe1, 0xd5, 0xfb, 0x15, 0x1b, 0x08, 0xee, + 0xda, 0xd2, 0xec, 0xbc, 0x0f, 0x1a, 0xc3, 0xeb, 0xec, 0xfa, 0x0f, 0xc9, 0x3c, + 0x5b, 0x00, 0x33, 0xfd, 0x01, 0x1d, 0xcc, 0xe2, 0x3b, 0x43, 0xcd, 0x56, 0x39, + 0x09, 0x0e, 0xc3, 0xd1, 0xfd, 0xbb, 0x30, 0xdb, 0x53, 0x1a, 0xb4, 0x2f, 0x11, + 0xfc, 0x13, 0x2f, 0xeb, 0xc8, 0xd3, 0x26, 0xf7, 0x24, 0x1f, 0xd0, 0xe5, 0xdc, + 0x36, 0xec, 0xd1, 0x2f, 0xc8, 0x28, 0xe4, 0xd1, 0x52, 0x24, 0x24, 0xe5, 0xf2, + 0x0b, 0xc4, 0xf5, 0xcf, 0x38, 0xdc, 0x2a, 0x26, 0xe6, 0xdc, 0xc0, 0xec, 0xd8, + 0xda, 0xf7, 0xd1, 0xf7, 0xfb, 0x06, 0xf7, 0xd7, 0x19, 0x2b, 0xf4, 0xff, 0xf8, + 0x19, 0xd2, 0xe4, 0xba, 0x1b, 0xd7, 0x1b, 0x22, 0xfc, 0x53, 0xef, 0xee, 0x21, + 0x9d, 0xe3, 0xf0, 0x14, 0xe7, 0xa4, 0x0e, 0x0a, 0xd5, 0x23, 0x1a, 0x2b, 0xe5, + 0x1a, 0x14, 0x0b, 0xf1, 0xe7, 0xe6, 0xdd, 0x09, 0x0f, 0x03, 0xeb, 0x09, 0x18, + 0x19, 0x31, 0xae, 0xf0, 0x29, 0x09, 0x0a, 0xe2, 0xe5, 0xe3, 0xcc, 0xfb, 0x02, + 0x03, 0xa9, 0xee, 0x18, 0xf0, 0xfe, 0xca, 0xed, 0xd2, 0xfb, 0xf4, 0xe2, 0xf7, + 0x05, 0x07, 0xdc, 0xf0, 0xf1, 0xe5, 0x11, 0x26, 0xc3, 0xaf, 0x0f, 0xf6, 0x0f, + 0x25, 0xc2, 0xd8, 0x10, 0x11, 0x1f, 0x19, 0x05, 0xfa, 0xfb, 0xd2, 0xe9, 0xf8, + 0xcc, 0xb5, 0xf3, 0xdb, 0xc8, 0x4a, 0xe7, 0xf7, 0x1b, 0x1a, 0x2c, 0xfa, 0xcd, + 0x00, 0x23, 0x33, 0xce, 0xb3, 0x13, 0xa8, 0x01, 0xc5, 0x0d, 0x32, 0xee, 0xe2, + 0xef, 0x25, 0xcd, 0xe8, 0xf3, 0x18, 0xe0, 0xf0, 0x2a, 0xde, 0x7f, 0x4a, 0xac, + 0x1a, 0x04, 0x17, 0x01, 0xe8, 0xdb, 0xdc, 0x2a, 0xf0, 0xe4, 0x11, 0x01, 0x2c, + 0x09, 0x16, 0x0f, 0xda, 0x40, 0xd8, 0x1d, 0x12, 0x0c, 0x10, 0x3a, 0xe6, 0xef, + 0x22, 0xd6, 0xad, 0xda, 0x53, 0x0b, 0x20, 0x26, 0x15, 0xb9, 0x1b, 0xe0, 0x37, + 0x09, 0xd2, 0xf3, 0xf9, 0xd7, 0xc4, 0x16, 0xcf, 0xdc, 0x16, 0xec, 0x1c, 0x23, + 0xc5, 0xe9, 0xe5, 0xca, 0x20, 0xb9, 0x10, 0xe7, 0x10, 0x51, 0x0f, 0xdd, 0x4f, + 0x21, 0x16, 0x28, 0xc1, 0xb8, 0xe3, 0x06, 0xe0, 0x12, 0x0a, 0xb5, 0x0c, 0x39, + 0x27, 0xe2, 0x02, 0x00, 0xbb, 0x4b, 0x0b, 0xaa, 0xc7, 0xf6, 0x47, 0x2d, 0xdf, + 0x0d, 0xfd, 0xf8, 0xba, 0xf0, 0xe9, 0x08, 0xdd, 0x00, 0xe4, 0xf2, 0xf6, 0xec, + 0x04, 0xc0, 0x36, 0x19, 0xd0, 0x03, 0xf9, 0xaf, 0xbc, 0xf0, 0xda, 0x21, 0xe7, + 0xc9, 0xba, 0x4f, 0xa7, 0xcc, 0xf8, 0x2f, 0xe5, 0x71, 0xe8, 0x0a, 0x38, 0xc5, + 0x15, 0xdb, 0x0f, 0x10, 0xff, 0x30, 0x02, 0xe3, 0x35, 0x0e, 0xf5, 0x24, 0xfa, + 0x32, 0xc9, 0x49, 0xf0, 0xf7, 0x1a, 0xf5, 0x0a, 0xd3, 0xb4, 0xe9, 0x0a, 0xcc, + 0x0e, 0xc0, 0xd7, 0xf4, 0x0e, 0x35, 0x1b, 0xcd, 0xf0, 0xc6, 0x01, 0x26, 0xba, + 0x10, 0xe3, 0x4b, 0x39, 0x2e, 0xbe, 0xfc, 0xd3, 0xfb, 0xf0, 0x10, 0x3a, 0xbf, + 0x09, 0xc3, 0xb3, 0xd0, 0xcb, 0xf6, 0x42, 0x06, 0x0a, 0xea, 0xca, 0x1c, 0x19, + 0x35, 0x2c, 0xdf, 0xed, 0x0e, 0x09, 0xfe, 0x08, 0x03, 0xde, 0xbb, 0xe3, 0xe6, + 0xc6, 0x2e, 0xff, 0xe2, 0xe7, 0x0c, 0x1f, 0xce, 0xf2, 0x05, 0xbc, 0xdc, 0xfe, + 0xed, 0x1b, 0x24, 0xa3, 0xe9, 0xd6, 0x0f, 0x20, 0x7f, 0x01, 0xed, 0x03, 0x3e, + 0xd9, 0xdd, 0x0a, 0xf8, 0x3e, 0xe6, 0xd5, 0xf6, 0xfc, 0xe4, 0xc9, 0xf3, 0xdd, + 0xba, 0x04, 0x1a, 0x04, 0x30, 0x26, 0xe1, 0xda, 0x49, 0xe1, 0xab, 0xfa, 0x22, + 0xe6, 0xc6, 0x0e, 0xe3, 0xd8, 0x1a, 0x1b, 0xd4, 0xd7, 0xfa, 0x20, 0xee, 0xf5, + 0xf9, 0x16, 0x0b, 0xdd, 0xd2, 0x12, 0xff, 0x51, 0xec, 0xf7, 0xdd, 0xb1, 0xec, + 0xe2, 0xfe, 0xfb, 0xd3, 0x38, 0xd2, 0xfc, 0xb7, 0xee, 0x0d, 0xf0, 0xe7, 0xed, + 0xce, 0x1b, 0x2e, 0x2a, 0x24, 0xe3, 0xeb, 0x30, 0x03, 0x0e, 0xd0, 0x04, 0xdd, + 0x3b, 0xdf, 0x49, 0x1d, 0xe5, 0x05, 0xeb, 0x07, 0xcb, 0x24, 0x23, 0xc2, 0xed, + 0xf4, 0xeb, 0xc6, 0xb7, 0x5c, 0xf0, 0xe7, 0x69, 0xf7, 0x05, 0x16, 0xc1, 0xdb, + 0xfa, 0x2b, 0xe1, 0x19, 0xe2, 0xa7, 0x0a, 0xb7, 0xf0, 0x40, 0xd2, 0xc1, 0xb8, + 0x2f, 0xc3, 0xeb, 0xcd, 0xf9, 0xe2, 0xfd, 0x0f, 0x0a, 0xe3, 0x18, 0x19, 0xa5, + 0x0d, 0xed, 0xf0, 0xcc, 0xe8, 0xed, 0xf3, 0x2a, 0x09, 0xb1, 0xf7, 0xd9, 0x3d, + 0xf6, 0x42, 0xff, 0x31, 0xdf, 0x09, 0xd0, 0x1b, 0xb8, 0xd6, 0xeb, 0x48, 0xfd, + 0x00, 0xb7, 0x05, 0xf7, 0x12, 0x01, 0x1a, 0x05, 0xcc, 0xf3, 0xe6, 0xeb, 0xcf, + 0x1f, 0xc5, 0x23, 0x00, 0x33, 0xbd, 0xf7, 0xd9, 0xb7, 0x18, 0xec, 0xa7, 0xee, + 0xf4, 0xb4, 0xf2, 0x01, 0xc7, 0x1e, 0x1b, 0xf2, 0xc7, 0x0a, 0x07, 0x17, 0x1c, + 0xbf, 0xc8, 0x32, 0x1a, 0x1c, 0xe7, 0x96, 0xf6, 0xfd, 0x34, 0x0e, 0xf8, 0xf2, + 0x10, 0x14, 0xdb, 0x02, 0x2c, 0xed, 0xef, 0x18, 0xe4, 0x16, 0xdd, 0xd9, 0xea, + 0xf2, 0x1c, 0x24, 0x13, 0x07, 0x17, 0xe1, 0x1d, 0xe9, 0xd2, 0xbe, 0xe6, 0xfe, + 0x30, 0x3e, 0x1a, 0x2f, 0x0a, 0x06, 0xdb, 0x01, 0xe0, 0x16, 0xb3, 0x1a, 0x1f, + 0xd4, 0x05, 0xea, 0xfd, 0xcb, 0x13, 0x08, 0xb8, 0x2a, 0xb6, 0xf8, 0xeb, 0x29, + 0x22, 0x3b, 0x2e, 0xf2, 0xe7, 0x10, 0xea, 0xd3, 0xf2, 0xf5, 0x14, 0x17, 0x03, + 0x29, 0x17, 0xe5, 0xfb, 0xf1, 0xc7, 0xd3, 0xb9, 0x10, 0x06, 0xcf, 0x96, 0xeb, + 0x13, 0x02, 0xd7, 0x42, 0xfd, 0xb8, 0xf0, 0xf3, 0xf9, 0x07, 0xc3, 0xe9, 0xf4, + 0x1a, 0xd5, 0xf0, 0xbf, 0x24, 0xd6, 0x17, 0xe4, 0xd6, 0x0e, 0x0d, 0xe8, 0x0e, + 0x0a, 0x44, 0xef, 0xad, 0x0f, 0xeb, 0x3b, 0xd2, 0x33, 0x32, 0xc8, 0xf5, 0x2c, + 0x47, 0xcb, 0x1c, 0x2a, 0xee, 0x31, 0x81, 0xd0, 0xe2, 0xdb, 0x10, 0xdb, 0x31, + 0xfd, 0xe6, 0x16, 0xc6, 0x40, 0xdb, 0x26, 0xf4, 0xfe, 0x2e, 0xe8, 0xc0, 0xf7, + 0x1a, 0xbb, 0xd5, 0x0f, 0x35, 0xfd, 0xf8, 0xee, 0xbc, 0x06, 0xd0, 0x0e, 0xd5, + 0xc6, 0xf9, 0xbe, 0xf5, 0xbe, 0xc8, 0xf0, 0x11, 0xfc, 0xe6, 0x01, 0xf9, 0xe7, + 0x1e, 0x27, 0xdb, 0xdb, 0xdd, 0x10, 0x1c, 0xee, 0x0f, 0x06, 0xdc, 0x2b, 0x1d, + 0xfc, 0x35, 0xf8, 0x43, 0x07, 0x05, 0xc2, 0x17, 0x36, 0xe8, 0x12, 0x13, 0x08, + 0xfd, 0xf0, 0xb3, 0xcf, 0x4f, 0xe5, 0xea, 0x2e, 0xfd, 0xfa, 0xe7, 0x26, 0x1f, + 0xee, 0xe7, 0x2f, 0xe0, 0x0c, 0x1c, 0x29, 0x11, 0x16, 0x25, 0xe4, 0x1e, 0x14, + 0x00, 0xfe, 0xd5, 0xf7, 0xe3, 0xe7, 0x13, 0xc0, 0xf5, 0xc0, 0x24, 0x0a, 0xed, + 0xf9, 0xe0, 0xc6, 0xe5, 0x10, 0x0e, 0xe6, 0xda, 0x16, 0x1b, 0x11, 0xf9, 0xf5, + 0xf1, 0xd2, 0xe8, 0xd3, 0x02, 0xd6, 0xde, 0x07, 0x1f, 0x07, 0xdc, 0xc8, 0x00, + 0x07, 0xe9, 0x40, 0x16, 0xef, 0xfa, 0xfa, 0xe3, 0x0d, 0xef, 0xdc, 0x2e, 0x03, + 0xf5, 0xc9, 0xc5, 0xda, 0xbb, 0xea, 0xb0, 0xd3, 0xfd, 0x0e, 0x02, 0x05, 0xf2, + 0xdf, 0x18, 0x94, 0xe5, 0xf1, 0xea, 0x0a, 0x08, 0x3e, 0xdf, 0xe5, 0xd2, 0x1a, + 0xb9, 0xea, 0xe4, 0x25, 0x33, 0x24, 0x2c, 0x05, 0x14, 0x7f, 0xef, 0xef, 0x2d, + 0xf1, 0xe5, 0x15, 0xdf, 0xf7, 0xa0, 0x2f, 0xf4, 0xfb, 0x10, 0x0d, 0xd4, 0x00, + 0x07, 0xde, 0x33, 0xed, 0x14, 0xff, 0xfa, 0xe2, 0x51, 0xea, 0xa5, 0x2c, 0x16, + 0x0c, 0x1d, 0x01, 0xcf, 0xdd, 0xf6, 0xef, 0x1f, 0x12, 0x5a, 0x19, 0xc4, 0xee, + 0x07, 0xdf, 0xc3, 0x6a, 0xed, 0xdf, 0x49, 0x30, 0x2d, 0x08, 0x02, 0x0b, 0xf1, + 0xdd, 0xfc, 0x15, 0xd0, 0xbd, 0x03, 0x1c, 0xef, 0xdd, 0xe7, 0xba, 0x47, 0x45, + 0xb9, 0xbe, 0xd6, 0x2e, 0xcc, 0xab, 0xbc, 0x06, 0xe8, 0x07, 0xdf, 0x0f, 0xd9, + 0x07, 0x06, 0x1a, 0xb2, 0xe2, 0x25, 0xfd, 0xfa, 0x0d, 0x16, 0x04, 0xfa, 0x2b, + 0xda, 0x1a, 0x0e, 0xb7, 0xc5, 0xef, 0xbd, 0xe0, 0x85, 0xdb, 0x03, 0xf3, 0xd5, + 0xf7, 0x91, 0xc6, 0xad, 0x0e, 0xc6, 0xed, 0xea, 0x0f, 0xfb, 0xd1, 0xaf, 0x03, + 0x24, 0x26, 0x3e, 0xe2, 0x55, 0xe7, 0xd2, 0xe7, 0xbb, 0x01, 0xc2, 0x42, 0x23, + 0xe0, 0x24, 0x11, 0xb8, 0x55, 0xf8, 0x9d, 0xf4, 0xe4, 0x2d, 0x04, 0x8b, 0x29, + 0xca, 0xff, 0x1c, 0xfe, 0xd3, 0x3f, 0x30, 0x07, 0x4b, 0xfe, 0x2e, 0xb9, 0xff, + 0x2a, 0x59, 0x4e, 0xed, 0xcb, 0x01, 0xcc, 0x09, 0x2e, 0x42, 0x1c, 0xaf, 0x46, + 0xc9, 0xee, 0x9f, 0xc6, 0xbb, 0xeb, 0xbd, 0x11, 0x3e, 0xef, 0xef, 0x36, 0xa7, + 0xde, 0xc4, 0xc8, 0xee, 0x8d, 0xbc, 0x3b, 0xdd, 0x49, 0xe1, 0xb5, 0xc0, 0xe2, + 0xe3, 0x29, 0xd1, 0xfe, 0x1a, 0x03, 0x95, 0xe6, 0xe6, 0xca, 0xfd, 0xe6, 0x1b, + 0xf1, 0x14, 0x12, 0xed, 0xf0, 0x00, 0xc6, 0x2f, 0x02, 0xb7, 0x26, 0xf7, 0x9d, + 0x27, 0x91, 0xf7, 0x54, 0x38, 0xba, 0xea, 0xf8, 0xfc, 0xd9, 0xab, 0x37, 0x07, + 0x8e, 0xf2, 0x31, 0x0c, 0x1e, 0xd6, 0x0a, 0x09, 0xef, 0x81, 0x1c, 0xbc, 0x08, + 0x13, 0xe6, 0xf8, 0xb2, 0xdd, 0x11, 0x51, 0xe4, 0x50, 0xcc, 0xa9, 0x35, 0xf8, + 0x3c, 0x97, 0xd4, 0xce, 0xea, 0xf6, 0xe2, 0xd4, 0x58, 0xf4, 0xb6, 0x42, 0xe5, + 0x33, 0x4a, 0xfc, 0xdd, 0x35, 0x2a, 0xa3, 0x28, 0xe9, 0x5a, 0xa5, 0xe0, 0xf2, + 0xe5, 0x06, 0x23, 0x2e, 0x59, 0xdc, 0x3a, 0xec, 0x26, 0x2f, 0x32, 0xc9, 0xec, + 0xc4, 0x08, 0x0c, 0xcd, 0xe6, 0x5d, 0x39, 0x95, 0xd7, 0xc7, 0x34, 0x29, 0xcb, + 0xf3, 0xe6, 0xfc, 0x0c, 0xf2, 0xd6, 0xd8, 0x3f, 0x2b, 0x1e, 0x15, 0xf4, 0x0c, + 0x51, 0x05, 0x2b, 0x26, 0xd3, 0x08, 0x28, 0x07, 0xf5, 0xff, 0x24, 0x42, 0x0a, + 0xb4, 0x1e, 0xab, 0x2a, 0x18, 0x53, 0x94, 0xd3, 0xf6, 0xfa, 0x59, 0x47, 0xbb, + 0xd7, 0xd5, 0xbb, 0x53, 0xfd, 0xf3, 0xd7, 0xf8, 0xe0, 0x09, 0x37, 0x03, 0xc4, + 0x41, 0x5b, 0xc4, 0xdf, 0xef, 0xbf, 0x35, 0xbf, 0x29, 0xb8, 0xec, 0xac, 0xf9, + 0x9c, 0xc6, 0x29, 0xf4, 0xb1, 0xd4, 0x14, 0x79, 0x56, 0xdf, 0xf2, 0x2e, 0xfe, + 0x6c, 0xc2, 0xdc, 0xc7, 0x2e, 0x08, 0xca, 0xbf, 0x02, 0xc3, 0x2f, 0xdf, 0x1f, + 0xf1, 0xa6, 0xfb, 0xf7, 0x25, 0x04, 0x72, 0xe5, 0x00, 0x1c, 0xe0, 0x32, 0xd1, + 0x6b, 0xe4, 0xb7, 0xbe, 0x06, 0x52, 0xc4, 0x5a, 0x4c, 0x15, 0x15, 0xd5, 0xe0, + 0x35, 0x8c, 0x30, 0xcd, 0xc5, 0xfb, 0xdb, 0xd0, 0x2e, 0xc6, 0x23, 0x32, 0x06, + 0xd5, 0xbc, 0xad, 0x13, 0xc6, 0x41, 0x29, 0xe2, 0x29, 0xe3, 0x25, 0x00, 0x24, + 0x01, 0x3a, 0xe9, 0xdf, 0xd8, 0x16, 0x37, 0xcf, 0xff, 0x03, 0xe9, 0x06, 0x20, + 0xe2, 0x3c, 0xd1, 0xcc, 0x26, 0xe8, 0xc2, 0xd6, 0x0d, 0x35, 0x08, 0xae, 0x13, + 0x47, 0x1b, 0xe6, 0x46, 0x49, 0x34, 0x36, 0x9a, 0xf9, 0x56, 0xdb, 0xc1, 0x36, + 0x3a, 0xd6, 0xcd, 0xca, 0xad, 0xb7, 0xa3, 0x2c, 0xa3, 0xe2, 0x0a, 0xe8, 0xf4, + 0x38, 0x47, 0xca, 0xf7, 0x0e, 0xb1, 0x15, 0x2a, 0xe8, 0xe5, 0x65, 0x3a, 0x01, + 0x54, 0x4a, 0x2d, 0xfc, 0x33, 0x23, 0x07, 0x81, 0xc3, 0xa2, 0xda, 0x05, 0x08, + 0x02, 0x57, 0x0d, 0xe4, 0xd4, 0xc8, 0xce, 0x2b, 0xc2, 0x38, 0x04, 0xd4, 0xdf, + 0xbb, 0x07, 0x0b, 0xce, 0xb6, 0xf5, 0x01, 0xd6, 0x4a, 0x01, 0x41, 0x4b, 0xd3, + 0xf4, 0x3d, 0x3f, 0x0d, 0x1c, 0xeb, 0xe6, 0x68, 0x07, 0x04, 0x19, 0x9b, 0xbb, + 0xfb, 0xfc, 0xd0, 0x03, 0x01, 0xbd, 0xf3, 0xa3, 0xcf, 0xc5, 0x2c, 0x15, 0xf3, + 0x6c, 0x34, 0xfa, 0xed, 0x17, 0x0f, 0x1b, 0xe7, 0xe1, 0x11, 0x34, 0xad, 0xfd, + 0x90, 0x00, 0x12, 0x50, 0x06, 0xf0, 0xa3, 0x12, 0xbf, 0xbe, 0x00, 0x20, 0x49, + 0xed, 0xe7, 0xde, 0x07, 0xd0, 0x12, 0x1b, 0xba, 0xab, 0x26, 0x34, 0xaa, 0x27, + 0xb2, 0x37, 0x02, 0xf8, 0x07, 0x07, 0xf3, 0x02, 0xf8, 0xd5, 0x27, 0xdb, 0x2b, + 0xc8, 0x2a, 0xd4, 0x36, 0x0d, 0xd6, 0xe5, 0x37, 0xec, 0x6b, 0x2a, 0x0f, 0xb4, + 0x58, 0xdc, 0xc7, 0x30, 0xea, 0xc5, 0x06, 0xcb, 0x22, 0x16, 0xd2, 0xf7, 0x14, + 0xff, 0xe5, 0x3b, 0x01, 0xee, 0x2e, 0xcf, 0x06, 0xcd, 0x7f, 0x11, 0xf8, 0xc6, + 0x04, 0x3e, 0xd8, 0x22, 0xd0, 0x02, 0xe1, 0xa0, 0xcf, 0x2f, 0xbb, 0x3f, 0x2c, + 0xe8, 0x34, 0x17, 0xbc, 0x21, 0xf6, 0xc7, 0x49, 0xf2, 0x0d, 0xb5, 0xed, 0xbb, + 0xce, 0x00, 0xbf, 0xb1, 0xfb, 0xc5, 0x53, 0x06, 0x13, 0xb2, 0xfb, 0x06, 0xd7, + 0xee, 0x5a, 0x0f, 0xeb, 0xa8, 0xe7, 0xfd, 0x0f, 0x16, 0xf1, 0xe1, 0x37, 0x9f, + 0x38, 0xed, 0xf0, 0xd3, 0x24, 0x2f, 0xaa, 0xef, 0xf8, 0x01, 0xfe, 0x47, 0xfb, + 0x27, 0x0a, 0xdf, 0xa2, 0xf7, 0xd2, 0x20, 0xac, 0x2e, 0x0e, 0xea, 0xc7, 0xfb, + 0xcf, 0x43, 0xed, 0x93, 0xc5, 0x00, 0x22, 0x2d, 0x57, 0x61, 0x02, 0xfc, 0xda, + 0x23, 0xec, 0xf1, 0x13, 0x44, 0xef, 0x2b, 0xeb, 0x12, 0x73, 0xcd, 0xe4, 0x00, + 0xe9, 0x5d, 0xe6, 0xcb, 0xc5, 0xd6, 0xec, 0xe4, 0x20, 0xec, 0xb0, 0x52, 0xb4, + 0xb7, 0xd1, 0xd1, 0xc8, 0xb7, 0x14, 0xd9, 0xba, 0xfe, 0xbc, 0x14, 0x1c, 0xe1, + 0xa5, 0xf1, 0xb1, 0xe0, 0xd8, 0xe7, 0xbe, 0xfc, 0xf2, 0xcf, 0x09, 0x27, 0xdd, + 0x02, 0xe4, 0x12, 0x4d, 0xcd, 0x21, 0x12, 0xac, 0xe8, 0x06, 0xee, 0xce, 0x46, + 0xdc, 0xde, 0x0f, 0xf4, 0xf2, 0xf1, 0xba, 0xd1, 0xe6, 0x36, 0xda, 0x3c, 0xfb, + 0xdb, 0xc9, 0x00, 0xdd, 0xfe, 0xc3, 0xe7, 0xa6, 0xc5, 0xba, 0x22, 0xee, 0xe3, + 0xa6, 0x43, 0x00, 0xdd, 0xd8, 0xe4, 0x24, 0x13, 0xfc, 0x0d, 0x09, 0xde, 0xcd, + 0xca, 0xfe, 0xff, 0x07, 0xe7, 0xd6, 0xaa, 0x06, 0xdd, 0xd9, 0x34, 0xcc, 0x1a, + 0x45, 0xd9, 0xe9, 0xec, 0xef, 0xfb, 0xdd, 0xee, 0xf6, 0x1d, 0x08, 0xfc, 0xdd, + 0xd4, 0x25, 0xaa, 0x0c, 0xee, 0x03, 0xaf, 0x02, 0x52, 0xcf, 0x01, 0xb8, 0xed, + 0xb6, 0x17, 0x4a, 0x1e, 0x25, 0x13, 0xba, 0xc9, 0xfa, 0xec, 0x0c, 0x16, 0xcf, + 0xcc, 0xe4, 0x02, 0xf8, 0xf0, 0x45, 0xea, 0x04, 0xee, 0xeb, 0x09, 0x3b, 0x35, + 0xc5, 0x06, 0xc0, 0x0b, 0xd1, 0xd2, 0xf7, 0x28, 0x10, 0x14, 0x2c, 0xe6, 0x19, + 0xd1, 0xf6, 0xec, 0x17, 0xd3, 0xda, 0x44, 0x47, 0x00, 0xdc, 0x15, 0x0e, 0xf5, + 0xdd, 0xdd, 0xed, 0x55, 0xa2, 0x06, 0xf5, 0xff, 0x07, 0x3f, 0xc8, 0xbb, 0xf7, + 0xe9, 0xe9, 0xcd, 0xba, 0x04, 0xd7, 0x00, 0x25, 0x15, 0x23, 0x77, 0x06, 0xbd, + 0x50, 0xc3, 0xd9, 0xcf, 0x30, 0xe2, 0xaf, 0xc0, 0x2b, 0xbd, 0x17, 0x05, 0xe9, + 0x51, 0xfe, 0x08, 0x26, 0x25, 0xdf, 0xe7, 0xfc, 0xb6, 0x02, 0xd8, 0x0c, 0xd3, + 0xe1, 0xf5, 0x20, 0xd7, 0x40, 0x11, 0x02, 0x14, 0xe9, 0xe2, 0xbe, 0xe6, 0x1e, + 0x14, 0xdc, 0xfa, 0x03, 0x27, 0xcb, 0xf9, 0x21, 0x08, 0x17, 0x1b, 0x04, 0x26, + 0xf4, 0xf1, 0xd6, 0xc2, 0xca, 0xfa, 0xfe, 0x2d, 0xf7, 0xdd, 0xd9, 0xe4, 0x3a, + 0x00, 0x35, 0x0f, 0xfc, 0xf4, 0x18, 0x08, 0xdf, 0x1d, 0x10, 0x48, 0xb3, 0xdf, + 0x1e, 0x0d, 0x00, 0x19, 0xb3, 0x3f, 0x7f, 0x1f, 0xc2, 0x1c, 0xc9, 0xd4, 0x36, + 0xf1, 0xd1, 0xeb, 0x03, 0xe6, 0x18, 0x18, 0xe7, 0xe2, 0xe6, 0xf8, 0xdd, 0x0a, + 0x23, 0xf0, 0xc5, 0x1c, 0xf0, 0x10, 0xcd, 0xf0, 0x9f, 0xc2, 0xd8, 0x1d, 0xe4, + 0x20, 0xfa, 0x1f, 0xf2, 0xcc, 0x0a, 0xc7, 0x00, 0xf5, 0x07, 0x19, 0x1a, 0x64, + 0xdb, 0xe7, 0xf3, 0xc1, 0x14, 0xe5, 0xd3, 0xe7, 0x17, 0xf4, 0xbb, 0x17, 0xcd, + 0x2d, 0x1d, 0x27, 0xb0, 0x16, 0xe3, 0xf7, 0xe2, 0xfa, 0x42, 0x20, 0x24, 0xe6, + 0xdb, 0xd9, 0x12, 0x0d, 0xee, 0xe6, 0xff, 0x28, 0x07, 0x44, 0xfc, 0xd5, 0xff, + 0x05, 0xe5, 0xd4, 0xfb, 0xc1, 0xd3, 0xf8, 0x2c, 0x0a, 0x22, 0x0e, 0xe5, 0x1d, + 0x09, 0x25, 0xf7, 0x20, 0x26, 0x2f, 0x24, 0xda, 0x1e, 0xff, 0xb1, 0x10, 0x47, + 0x46, 0xe1, 0x25, 0xd3, 0xf6, 0xfe, 0x2c, 0xc8, 0x45, 0x20, 0xd1, 0x13, 0xdf, + 0xf9, 0x04, 0xd2, 0x2a, 0xfb, 0xf1, 0x15, 0xf4, 0xd5, 0xdb, 0x08, 0x03, 0xff, + 0x1a, 0x1a, 0x0c, 0xf7, 0xd5, 0xf6, 0xfd, 0xe1, 0xaa, 0xfc, 0x45, 0x4a, 0x14, + 0xea, 0xfc, 0x07, 0xf2, 0x28, 0xfa, 0x24, 0x1e, 0xc3, 0xda, 0x3d, 0xf6, 0x01, + 0xfd, 0x1f, 0x04, 0xe3, 0x2a, 0xda, 0xfc, 0xfb, 0xdd, 0xe1, 0xf6, 0xda, 0xe5, + 0x14, 0xf8, 0xf1, 0x2e, 0x08, 0x1f, 0xfc, 0xf8, 0xff, 0xe5, 0xf5, 0x35, 0xf2, + 0x16, 0xf4, 0xfb, 0xe3, 0xf9, 0xfb, 0xf8, 0xf9, 0xe3, 0xdc, 0xfc, 0xf6, 0x13, + 0x11, 0x11, 0x7f, 0xfc, 0x16, 0xee, 0xe8, 0x21, 0x06, 0x4c, 0xec, 0x10, 0xf8, + 0xff, 0xfd, 0xff, 0x27, 0xb0, 0x17, 0x5d, 0xdd, 0xe5, 0xc0, 0xf1, 0xed, 0x38, + 0xd8, 0x04, 0xf7, 0x03, 0xd6, 0x09, 0xe9, 0x0d, 0x41, 0xea, 0x01, 0xea, 0xf4, + 0x21, 0x26, 0xe2, 0x1a, 0x00, 0x05, 0xf3, 0xe3, 0xc2, 0x0c, 0xef, 0x0c, 0xf6, + 0xd3, 0xce, 0x06, 0x08, 0x0b, 0xd2, 0x01, 0xf1, 0xf5, 0xfe, 0x38, 0x06, 0x2d, + 0x16, 0x0c, 0xf9, 0x05, 0xd4, 0x08, 0xc8, 0x24, 0xe1, 0x2a, 0xdd, 0x0c, 0x23, + 0x1c, 0x38, 0x04, 0xce, 0x0e, 0x11, 0x16, 0xf1, 0xf3, 0xd7, 0xdf, 0x0e, 0xb8, + 0xd9, 0xdb, 0x2d, 0x1e, 0x07, 0xdf, 0x06, 0xf8, 0xf7, 0x8a, 0xbe, 0xe2, 0xf6, + 0xfd, 0x09, 0xf2, 0x01, 0xc0, 0xee, 0xc7, 0x1b, 0xf3, 0x03, 0xfa, 0x97, 0xbc, + 0xd7, 0xe4, 0xb7, 0x0a, 0x0f, 0xd4, 0xc2, 0x45, 0x01, 0x07, 0x11, 0xd5, 0x03, + 0xde, 0xfa, 0xdd, 0xe2, 0xd6, 0xae, 0x41, 0xc1, 0x22, 0x0e, 0x2b, 0x81, 0xa2, + 0xf9, 0xfa, 0xed, 0x3a, 0xce, 0xe7, 0x21, 0x01, 0xf6, 0x17, 0xec, 0x17, 0x5e, + 0xb2, 0x0e, 0xe7, 0x33, 0xf7, 0xec, 0x05, 0x27, 0x08, 0x0d, 0x0e, 0xf6, 0xdb, + 0x82, 0x00, 0xd4, 0xe3, 0xed, 0xf5, 0xe8, 0x01, 0xba, 0xe6, 0xe2, 0xed, 0x17, + 0x3e, 0x1a, 0xc9, 0x46, 0xe6, 0xf1, 0x07, 0xe9, 0x04, 0x05, 0x20, 0xf7, 0x3a, + 0xf0, 0xad, 0xd4, 0xfe, 0x39, 0xd7, 0xf1, 0xdc, 0x60, 0xd8, 0xe4, 0xdf, 0x3e, + 0x01, 0xbc, 0xfa, 0x3f, 0xba, 0x58, 0x0b, 0x42, 0x42, 0xe6, 0x06, 0x0d, 0xf6, + 0x08, 0x0b, 0xd3, 0x25, 0xbe, 0x1d, 0x3e, 0xcc, 0xcd, 0xc2, 0xfe, 0xfd, 0xeb, + 0xf4, 0xff, 0xf7, 0xd6, 0xf1, 0xf6, 0xc5, 0x08, 0x39, 0xb5, 0x04, 0xae, 0xff, + 0x59, 0x32, 0x31, 0xc6, 0xc1, 0xd2, 0xd6, 0xa2, 0xa3, 0xf7, 0x17, 0xde, 0x1e, + 0x51, 0xca, 0x99, 0xa1, 0xd7, 0x2b, 0x1e, 0x14, 0xba, 0xf5, 0x08, 0xca, 0x1a, + 0x0e, 0x36, 0x07, 0x11, 0xa4, 0x07, 0xb8, 0xd5, 0x27, 0x3a, 0x9e, 0xfa, 0xd4, + 0x0e, 0xec, 0xf6, 0x01, 0x23, 0x02, 0xf6, 0x2f, 0xe5, 0x3a, 0xbd, 0x26, 0xf5, + 0xd9, 0x2e, 0xdc, 0xc8, 0xe6, 0xd0, 0xc4, 0x07, 0xfe, 0x14, 0xc2, 0xeb, 0x1b, + 0xbf, 0xc1, 0xc5, 0x4f, 0x27, 0xeb, 0xcb, 0xed, 0xfb, 0x35, 0x11, 0x07, 0x4d, + 0xbc, 0x38, 0x14, 0x2b, 0x1e, 0xff, 0xfe, 0xdf, 0xb2, 0xfb, 0xf9, 0x1d, 0xed, + 0xe8, 0xec, 0x0d, 0x10, 0xfe, 0xe0, 0x29, 0xe5, 0xe1, 0x1d, 0x8c, 0x20, 0x41, + 0xe8, 0xdd, 0xd5, 0xed, 0x0f, 0xd9, 0x62, 0xd9, 0x5e, 0x63, 0x8b, 0x0c, 0x08, + 0x04, 0xf1, 0x31, 0xbd, 0x2e, 0xf0, 0x95, 0x3e, 0xe6, 0xfd, 0x04, 0x21, 0xe9, + 0x0e, 0x30, 0xe1, 0x0f, 0x47, 0x43, 0xed, 0xbc, 0xd4, 0x95, 0x99, 0x81, 0x78, + 0x1f, 0x04, 0x08, 0xc6, 0x0e, 0x09, 0xe2, 0x31, 0xec, 0x1a, 0xc9, 0x2c, 0xf9, + 0x17, 0x2f, 0xd8, 0xd9, 0xa0, 0xff, 0x32, 0x00, 0x26, 0xf5, 0xce, 0x25, 0xe3, + 0xe5, 0xbd, 0x0d, 0x74, 0xaf, 0xb5, 0xfd, 0x67, 0xc7, 0xc8, 0x4c, 0xa4, 0xfa, + 0xf6, 0xd2, 0x03, 0xf0, 0xc5, 0xf2, 0x2d, 0x2a, 0xb3, 0xd4, 0x26, 0xcd, 0x21, + 0x32, 0xe0, 0xfc, 0xb7, 0x96, 0x13, 0xfb, 0x1f, 0xdf, 0xb2, 0xd4, 0x0c, 0xf6, + 0x33, 0x26, 0xf7, 0xd7, 0xf0, 0x02, 0xc2, 0x52, 0x90, 0xe5, 0x16, 0xc0, 0x0e, + 0x09, 0x5f, 0x1b, 0x38, 0x2b, 0xd9, 0xba, 0xe4, 0xdc, 0xcb, 0x26, 0xdc, 0xfb, + 0xdb, 0xef, 0x27, 0xce, 0x01, 0xaf, 0xbd, 0x05, 0xf6, 0xd9, 0xcf, 0xea, 0x14, + 0xe6, 0xf9, 0x48, 0xc2, 0x40, 0xff, 0xf8, 0xc0, 0x24, 0x51, 0xda, 0x23, 0xc6, + 0xe5, 0xe9, 0xdc, 0x07, 0xa0, 0xdf, 0xa0, 0x13, 0xca, 0x23, 0x5b, 0xcb, 0xf5, + 0x0a, 0x04, 0x45, 0xbe, 0x29, 0xf5, 0x21, 0xb8, 0x20, 0x21, 0xfc, 0x14, 0x2b, + 0xf7, 0xee, 0x1c, 0xe6, 0x06, 0x2e, 0x29, 0x07, 0xf4, 0xf3, 0xd1, 0xe0, 0x21, + 0x28, 0xea, 0xe9, 0x1d, 0xd3, 0xc0, 0xed, 0xe1, 0x99, 0x42, 0x2a, 0x23, 0x92, + 0x2e, 0xe1, 0x04, 0xef, 0xec, 0x9e, 0x1b, 0xd7, 0xb8, 0x10, 0xe6, 0xed, 0x09, + 0xdd, 0xe5, 0x16, 0xf4, 0x10, 0xf5, 0xd2, 0x2b, 0x21, 0xae, 0xf2, 0x42, 0x2a, + 0x41, 0x42, 0xfb, 0xfb, 0x0a, 0xff, 0xbe, 0xfc, 0x1f, 0x29, 0xdb, 0x4e, 0x1d, + 0x08, 0xed, 0x01, 0x17, 0xa3, 0xd3, 0xd8, 0x0d, 0xe8, 0xf8, 0x78, 0xdb, 0xff, + 0x09, 0x31, 0xe5, 0x05, 0xec, 0x09, 0xc7, 0xc6, 0xeb, 0xd1, 0x05, 0x10, 0xef, + 0x16, 0xbb, 0xe1, 0xc3, 0xbe, 0x06, 0xb4, 0xd9, 0x02, 0xa0, 0xe5, 0xfe, 0x05, + 0x0e, 0xc7, 0xcc, 0x41, 0x29, 0x25, 0xfe, 0xf1, 0x24, 0xe7, 0xa9, 0x44, 0x00, + 0x12, 0x00, 0xb7, 0x25, 0xbf, 0x1d, 0x0f, 0x10, 0x4d, 0x8d, 0xe8, 0xfb, 0x0f, + 0xb0, 0x1f, 0xfe, 0x3a, 0xef, 0x16, 0x11, 0xcc, 0x03, 0xdb, 0xfe, 0x5b, 0xff, + 0x03, 0xb0, 0xed, 0xba, 0xf7, 0xc6, 0x2e, 0x1e, 0x1a, 0xe4, 0x27, 0xe3, 0xe2, + 0x0f, 0x0c, 0xb9, 0xa3, 0x01, 0xd3, 0xfb, 0x31, 0xc9, 0xfd, 0xcc, 0xbe, 0xed, + 0x0f, 0xe9, 0xe6, 0x10, 0xd3, 0x01, 0x00, 0x19, 0xcb, 0xfd, 0xac, 0xf9, 0xdb, + 0xd0, 0x9e, 0x3a, 0xde, 0x12, 0xcf, 0x0b, 0xb2, 0x0a, 0x15, 0xf2, 0xfc, 0x39, + 0x19, 0xe5, 0xf0, 0xf9, 0xcb, 0x4b, 0xd5, 0x02, 0x29, 0xce, 0xec, 0xfc, 0x20, + 0x1f, 0x13, 0xe8, 0xea, 0x41, 0xdb, 0x45, 0x4e, 0xe2, 0xb3, 0xf2, 0xd4, 0xad, + 0x0a, 0xfe, 0xe5, 0x06, 0x1a, 0x20, 0xce, 0xc0, 0x49, 0xf9, 0xfe, 0xdc, 0xcf, + 0xca, 0x00, 0xce, 0x40, 0x43, 0x1f, 0xb9, 0x30, 0xd7, 0xce, 0xa4, 0x0b, 0x0a, + 0x23, 0x12, 0x03, 0x16, 0xce, 0xdd, 0x10, 0xb1, 0x2f, 0xdc, 0x06, 0xd8, 0x1d, + 0xe4, 0x15, 0xfd, 0xc8, 0xe4, 0x09, 0xff, 0x13, 0xd3, 0x05, 0x40, 0xe7, 0x1c, + 0x39, 0xde, 0xe5, 0x50, 0xf1, 0xea, 0xfe, 0x0f, 0xc4, 0x35, 0x7f, 0xc6, 0x26, + 0x25, 0xb1, 0x01, 0xf3, 0x20, 0xbe, 0x44, 0xa8, 0x1b, 0xef, 0x0f, 0xc1, 0x00, + 0xf0, 0x2d, 0x02, 0xfe, 0x3b, 0x27, 0x03, 0x08, 0xfa, 0x38, 0x01, 0xd3, 0xfa, + 0xea, 0x32, 0xfa, 0xe3, 0x33, 0x0a, 0x0b, 0x59, 0x13, 0xb3, 0x17, 0xf6, 0x23, + 0xe8, 0x3c, 0x1b, 0xd6, 0xfe, 0x1e, 0x00, 0x05, 0xca, 0x12, 0xdd, 0x1e, 0xe0, + 0xfd, 0xc8, 0x12, 0xde, 0xc5, 0x09, 0xb3, 0xfc, 0xc4, 0x24, 0xbe, 0xc0, 0xfd, + 0xed, 0x13, 0xec, 0x0f, 0xa3, 0xbb, 0xe6, 0xeb, 0xd0, 0xf1, 0xe8, 0x26, 0x99, + 0x01, 0xca, 0xd7, 0xe6, 0xc8, 0xc4, 0xce, 0x3b, 0xee, 0xf8, 0x1b, 0x9a, 0x26, + 0xb1, 0x1a, 0xf5, 0xe5, 0x3e, 0x28, 0xe8, 0x10, 0xf0, 0x2a, 0xe0, 0xfa, 0x3e, + 0x2a, 0xd7, 0xde, 0x1d, 0x1b, 0x26, 0x0b, 0xcc, 0x4c, 0xef, 0x0c, 0xe6, 0xc1, + 0xdf, 0x06, 0xf6, 0x87, 0xbe, 0xd3, 0xc3, 0x28, 0x2f, 0x06, 0xb9, 0x5a, 0xff, + 0xa4, 0xe3, 0x06, 0x2d, 0x0f, 0x20, 0x9e, 0xb0, 0xbe, 0x1e, 0x20, 0xdb, 0xd3, + 0xda, 0x86, 0xd4, 0xe8, 0xed, 0x17, 0xef, 0xc9, 0xda, 0xbc, 0xbe, 0x06, 0xb1, + 0x24, 0xf1, 0x21, 0x01, 0xf3, 0xf0, 0x1c, 0x06, 0x19, 0x18, 0xef, 0xfc, 0x9e, + 0x0a, 0xd0, 0xdc, 0x78, 0x00, 0xfb, 0xe4, 0x05, 0xbc, 0x4a, 0x2c, 0xff, 0x81, + 0xf2, 0x32, 0x19, 0x05, 0xa6, 0x33, 0xf6, 0xda, 0xbe, 0xfd, 0xe8, 0xdd, 0x01, + 0x0f, 0xcb, 0xdc, 0x48, 0x52, 0x09, 0x7f, 0xf6, 0xa2, 0x02, 0xf7, 0x23, 0x03, + 0x4b, 0xf0, 0x44, 0x27, 0xaa, 0x01, 0xfb, 0xf5, 0xec, 0xfa, 0xea, 0xd6, 0xb1, + 0xc4, 0xde, 0xe0, 0x15, 0xf7, 0x0b, 0x05, 0xf0, 0xd7, 0x09, 0xef, 0xd1, 0x03, + 0xf5, 0x26, 0xd6, 0x18, 0xf1, 0xec, 0xd7, 0xea, 0xed, 0xf0, 0x18, 0x2b, 0x07, + 0xf5, 0xe6, 0xf3, 0x21, 0xe8, 0x31, 0xeb, 0xcd, 0xc8, 0xe7, 0x17, 0x2b, 0xff, + 0xd1, 0xed, 0xd5, 0xc2, 0x19, 0xe8, 0xff, 0xc2, 0x24, 0xf6, 0x2f, 0xf9, 0xcb, + 0x78, 0x01, 0xdd, 0xdc, 0xec, 0x10, 0x07, 0xec, 0x0f, 0x3f, 0xfd, 0x19, 0xd3, + 0xc7, 0xf3, 0xad, 0xae, 0x3c, 0xb8, 0x0a, 0xe5, 0xf7, 0xf2, 0x03, 0x08, 0x00, + 0xc9, 0x04, 0x4d, 0x29, 0xe2, 0x27, 0x0d, 0x08, 0xd4, 0xf6, 0x10, 0xc5, 0xf8, + 0xa3, 0xcf, 0x9d, 0x46, 0x0a, 0x25, 0x0a, 0xd2, 0xec, 0xd0, 0x18, 0x13, 0xf5, + 0xb7, 0x0b, 0xfd, 0x2a, 0x00, 0x37, 0x30, 0xc0, 0xf6, 0x12, 0xf3, 0xb1, 0x2c, + 0x14, 0x09, 0x30, 0xd9, 0xd9, 0xc4, 0xf5, 0x01, 0xc1, 0x2e, 0x2e, 0x04, 0xc6, + 0xf0, 0xab, 0xda, 0xce, 0xd8, 0x1e, 0xea, 0x3c, 0x1a, 0xd5, 0xe0, 0x01, 0xc1, + 0x1f, 0xe8, 0x04, 0x12, 0xe8, 0x10, 0xc6, 0x03, 0xe1, 0xda, 0xb6, 0xe8, 0xcb, + 0x8e, 0x43, 0xfb, 0xf3, 0x36, 0xd5, 0xd0, 0x53, 0xeb, 0xfa, 0xee, 0xd3, 0x39, + 0xd5, 0xf7, 0xa6, 0xba, 0x37, 0xd6, 0x10, 0x06, 0xbe, 0xbb, 0xc8, 0xb4, 0x15, + 0x02, 0xe4, 0x1c, 0xe7, 0xd9, 0x01, 0x2a, 0x0c, 0x16, 0x1c, 0x01, 0x11, 0xca, + 0xd6, 0xf8, 0x4a, 0xc1, 0xf5, 0x04, 0x09, 0xc3, 0xf0, 0x14, 0xca, 0xda, 0xf7, + 0xf6, 0x17, 0xfd, 0xde, 0x33, 0x39, 0xd8, 0x98, 0x0a, 0xe9, 0x2f, 0xf6, 0xe0, + 0x13, 0xd0, 0xfb, 0x01, 0xff, 0xd9, 0xea, 0xe6, 0xf9, 0x05, 0x37, 0xf5, 0x4c, + 0x06, 0xf7, 0x22, 0x06, 0xd9, 0x22, 0x18, 0x46, 0xfb, 0xe5, 0xfb, 0xde, 0xfc, + 0xc2, 0xee, 0x11, 0xec, 0xce, 0x0b, 0x2a, 0x09, 0x08, 0x3b, 0xd1, 0xe7, 0x1f, + 0x09, 0xe2, 0xfd, 0x0a, 0x15, 0xc7, 0xff, 0xca, 0x17, 0xab, 0xde, 0xdb, 0xfb, + 0xf6, 0x29, 0xd7, 0x21, 0xea, 0xc2, 0x08, 0x0f, 0xed, 0x1b, 0xf1, 0x0b, 0xfa, + 0x07, 0xde, 0xfc, 0xe1, 0x2c, 0x35, 0xf1, 0xe2, 0xc9, 0xf6, 0xd7, 0x1d, 0xad, + 0xea, 0x48, 0xfe, 0xe1, 0x05, 0x14, 0xf1, 0x0e, 0x1c, 0x0e, 0xb0, 0x3b, 0xf3, + 0x2a, 0x03, 0xef, 0x22, 0x3e, 0x0c, 0xdf, 0xba, 0x32, 0xca, 0xfe, 0xdf, 0x21, + 0x3d, 0x3e, 0x04, 0x09, 0x43, 0xf0, 0x3b, 0xc6, 0x4c, 0x81, 0x28, 0xfe, 0x09, + 0x3e, 0x1e, 0xe6, 0x21, 0xb3, 0x2b, 0xac, 0x1a, 0x09, 0xe3, 0x09, 0xe5, 0xf7, + 0xd8, 0xfb, 0xe4, 0xd3, 0xde, 0x15, 0x09, 0xe5, 0xb5, 0xc8, 0xe8, 0x20, 0xb2, + 0xe4, 0xf6, 0xeb, 0x23, 0xff, 0xd4, 0xcb, 0xdc, 0xeb, 0x1b, 0x8f, 0xf8, 0xf2, + 0x29, 0x41, 0x06, 0xc8, 0xe5, 0xcc, 0xff, 0x07, 0xf9, 0x33, 0xbe, 0xce, 0xf2, + 0x09, 0x9a, 0xd7, 0x08, 0x2a, 0x40, 0x1c, 0xef, 0x0c, 0xc8, 0xf3, 0xdb, 0xe9, + 0x2a, 0xd4, 0x1b, 0xb1, 0xd2, 0x3b, 0x33, 0xea, 0xfd, 0xf5, 0x0c, 0xd5, 0xe2, + 0x1c, 0x04, 0xef, 0xde, 0x0c, 0xf5, 0xad, 0x1f, 0xb0, 0xf9, 0xfc, 0xe4, 0xcf, + 0x0e, 0xaf, 0xe4, 0xe3, 0x16, 0xbe, 0xe7, 0xf1, 0xf8, 0xc8, 0x1f, 0xd8, 0xe9, + 0xbd, 0xb4, 0xb9, 0xe3, 0xbe, 0x17, 0x17, 0x28, 0xef, 0x03, 0xd9, 0xc5, 0xf6, + 0xf0, 0xff, 0x1b, 0xf2, 0xc3, 0xcc, 0xd8, 0xe6, 0x19, 0xaa, 0x06, 0xf0, 0x16, + 0xce, 0x0f, 0xd8, 0x18, 0xe9, 0x13, 0xfa, 0xf9, 0xb2, 0xb0, 0x24, 0x05, 0xe5, + 0xcd, 0x2d, 0xee, 0xd1, 0x13, 0x0d, 0xe8, 0xd2, 0xee, 0xdf, 0xf6, 0x65, 0xf9, + 0xc5, 0xa1, 0xe8, 0xce, 0xdd, 0xec, 0xdd, 0x1b, 0x15, 0x9b, 0x03, 0xcf, 0x33, + 0xce, 0x1e, 0xe2, 0x00, 0xe6, 0x03, 0xe0, 0xe5, 0x18, 0x1d, 0x01, 0x09, 0xe4, + 0xdb, 0xeb, 0x2c, 0x2b, 0xca, 0xc1, 0xe1, 0xdb, 0x01, 0xfa, 0xde, 0xc8, 0xe5, + 0x06, 0xd7, 0xda, 0xd7, 0x1e, 0xce, 0x37, 0x03, 0x13, 0xe3, 0xe6, 0x81, 0xe8, + 0x01, 0x19, 0xdb, 0x0f, 0xe8, 0xfe, 0xe5, 0xe6, 0xd6, 0x07, 0x85, 0xf8, 0x0c, + 0x1f, 0xd7, 0x25, 0x0b, 0xdd, 0x37, 0xd3, 0x17, 0x56, 0xd3, 0x03, 0x0a, 0x03, + 0xe8, 0x13, 0xbb, 0xff, 0xdc, 0x14, 0x0e, 0xe5, 0xae, 0x41, 0x16, 0x6c, 0x09, + 0xc6, 0xf8, 0xf8, 0x0d, 0xd8, 0xba, 0xdd, 0xf7, 0xfd, 0x18, 0x44, 0x8c, 0x3d, + 0xe3, 0x31, 0xd7, 0x1a, 0xef, 0x4e, 0x42, 0xc5, 0x1e, 0xcd, 0xe0, 0xfa, 0x03, + 0x2d, 0x4b, 0x0b, 0xfe, 0x2f, 0xea, 0x03, 0xfa, 0x0d, 0xe9, 0x1c, 0xe6, 0x0b, + 0x19, 0xe2, 0xf1, 0x15, 0xe2, 0x00, 0x33, 0xba, 0x33, 0xc4, 0xd5, 0xc2, 0x1b, + 0xd2, 0xee, 0xed, 0x1e, 0x13, 0xf9, 0xf1, 0xed, 0xee, 0x05, 0x13, 0x10, 0x15, + 0x5f, 0xcd, 0xe0, 0xdb, 0xd4, 0x28, 0xf9, 0x1e, 0xcc, 0xea, 0x23, 0x17, 0xcc, + 0x1f, 0xd7, 0x2e, 0xa8, 0x46, 0xec, 0xd0, 0xda, 0x12, 0xe2, 0xf1, 0x09, 0x2f, + 0xe6, 0x2f, 0xd9, 0xc4, 0xf0, 0xd8, 0x11, 0xbc, 0x0f, 0xf5, 0x34, 0x1d, 0x96, + 0x10, 0x01, 0xc4, 0xe9, 0x38, 0xe1, 0x2c, 0xf8, 0xcc, 0x0b, 0x33, 0xc6, 0xe5, + 0xf1, 0x23, 0x2f, 0x06, 0xdf, 0xb1, 0xb8, 0x13, 0x09, 0x11, 0xce, 0xc9, 0x4b, + 0x18, 0xce, 0x35, 0xfc, 0x3a, 0x12, 0xc3, 0x0d, 0x53, 0xc8, 0x0c, 0xd2, 0x2d, + 0xfd, 0xa1, 0xc3, 0xed, 0x35, 0x14, 0x0a, 0xfe, 0xf3, 0xdc, 0xb8, 0xcc, 0x1d, + 0x01, 0x0e, 0x3a, 0xe5, 0xd1, 0x12, 0x81, 0xdf, 0x09, 0xbd, 0x0c, 0xf0, 0x19, + 0x06, 0xe2, 0x11, 0xad, 0x07, 0xf1, 0x0e, 0xc3, 0x2b, 0x15, 0x1a, 0x31, 0xf1, + 0x13, 0xec, 0x10, 0x07, 0xde, 0x25, 0x1e, 0x1a, 0xe5, 0xd2, 0x25, 0xf4, 0x04, + 0x26, 0x20, 0x19, 0xff, 0x1a, 0x35, 0x26, 0xeb, 0x00, 0x00, 0x49, 0xca, 0xee, + 0xd0, 0xf0, 0xde, 0x27, 0x12, 0x0b, 0x0b, 0xf7, 0x12, 0x13, 0x05, 0xf3, 0x03, + 0x05, 0x3d, 0x12, 0xfe, 0xff, 0xd4, 0xfa, 0xf1, 0x3f, 0xfb, 0x17, 0x2e, 0x12, + 0xfb, 0x1a, 0xe7, 0x41, 0xc9, 0x01, 0xe1, 0xb8, 0x1d, 0x29, 0x37, 0xdd, 0xe9, + 0xda, 0xa9, 0x38, 0xbf, 0xef, 0xdb, 0xe7, 0xcd, 0xe5, 0x21, 0x1d, 0xc5, 0x08, + 0x33, 0xc3, 0xed, 0x19, 0x0c, 0x09, 0xf4, 0xcb, 0xef, 0xf2, 0x2c, 0x11, 0xfc, + 0xe0, 0x36, 0xdf, 0x29, 0x3f, 0xe5, 0x3b, 0xc7, 0xb6, 0xc8, 0xf9, 0x1c, 0xd5, + 0xfe, 0xed, 0xdb, 0xdb, 0xa4, 0xe1, 0xea, 0x0b, 0xf8, 0x1a, 0x4e, 0x19, 0xc7, + 0xec, 0x4e, 0xa6, 0x8f, 0xe1, 0xf8, 0xff, 0xe0, 0xe2, 0xd6, 0xdb, 0x04, 0x2e, + 0x42, 0x15, 0x16, 0xe0, 0xc3, 0xf3, 0x08, 0xd0, 0xfe, 0x11, 0x20, 0x52, 0xe5, + 0x1e, 0xe4, 0xd0, 0xf8, 0xf2, 0x17, 0xc6, 0x35, 0xaf, 0xcf, 0x1b, 0xfa, 0xc7, + 0xc7, 0xff, 0x13, 0x00, 0x2a, 0x4a, 0xd0, 0x3a, 0xd7, 0x38, 0xd0, 0xc4, 0x65, + 0xd6, 0x17, 0x2c, 0xe2, 0xfd, 0xfd, 0xf4, 0x3b, 0xe0, 0xf2, 0xba, 0x04, 0xe5, + 0x21, 0xad, 0x4f, 0x03, 0xf5, 0x1f, 0xa6, 0xb8, 0xe6, 0xd0, 0x37, 0xf5, 0xe4, + 0xd0, 0xf5, 0xfe, 0x03, 0x11, 0x4c, 0xea, 0xf5, 0x1c, 0xc0, 0xd2, 0xd9, 0x1c, + 0x13, 0xd2, 0xf3, 0x05, 0x12, 0xfa, 0x18, 0xd7, 0xcd, 0xbf, 0xda, 0xc6, 0xb4, + 0x1d, 0xfe, 0x37, 0x12, 0x8f, 0xbc, 0x5b, 0xe7, 0xc8, 0x20, 0xfc, 0xcf, 0xfb, + 0xfe, 0x32, 0x1d, 0x5e, 0x15, 0xea, 0xbe, 0xc8, 0xd3, 0x81, 0xc4, 0x04, 0xea, + 0xdd, 0xca, 0x32, 0x1d, 0x37, 0xb8, 0x00, 0x25, 0xe3, 0x0d, 0xf5, 0x3b, 0x16, + 0x04, 0x0a, 0x06, 0x28, 0xb1, 0x07, 0x18, 0xcd, 0x4c, 0xf2, 0xf6, 0x07, 0xc4, + 0x19, 0x22, 0xe0, 0x28, 0xd2, 0x2d, 0xf4, 0x1a, 0x0c, 0xf4, 0x44, 0x04, 0x2b, + 0x42, 0x03, 0x15, 0xb2, 0x96, 0x27, 0x17, 0x0b, 0x21, 0xe8, 0xab, 0x41, 0xd9, + 0x15, 0xd4, 0xdf, 0xf9, 0x30, 0x10, 0xb7, 0xe0, 0xe0, 0x09, 0x35, 0x00, 0x19, + 0xf7, 0xb7, 0xcb, 0x05, 0x1b, 0x0e, 0xf2, 0xd0, 0xde, 0x2f, 0x0e, 0x19, 0xd1, + 0x17, 0x1d, 0xe0, 0xeb, 0xf6, 0xc0, 0x6a, 0x10, 0xf8, 0xd2, 0x02, 0x04, 0xdb, + 0xe0, 0x07, 0x37, 0xe7, 0x1d, 0x02, 0x07, 0xec, 0xcf, 0xe7, 0xf5, 0xef, 0xbc, + 0xf4, 0x3f, 0xa6, 0x12, 0xff, 0x1b, 0x08, 0xb5, 0xf5, 0xd3, 0xbe, 0xf6, 0xda, + 0xd5, 0xda, 0x01, 0xef, 0xcf, 0x1a, 0x3e, 0xe6, 0xb7, 0xdc, 0xfe, 0xdf, 0xd4, + 0xee, 0x16, 0x21, 0xcb, 0x19, 0x27, 0x27, 0xe0, 0xf1, 0x06, 0x2c, 0x20, 0xcc, + 0x9d, 0xb4, 0x09, 0xf5, 0x1e, 0xd2, 0x09, 0x13, 0xfa, 0xca, 0x56, 0xe5, 0xd6, + 0xde, 0xfe, 0x12, 0xe5, 0x3c, 0xe4, 0xed, 0xfa, 0xfb, 0x21, 0xdc, 0x1a, 0x06, + 0xf7, 0x3f, 0xa3, 0xfa, 0x62, 0xe4, 0xed, 0x29, 0x11, 0x35, 0x0f, 0x78, 0xd0, + 0xf6, 0xf2, 0x51, 0x2e, 0xbb, 0xa3, 0xc6, 0x81, 0xec, 0x13, 0x4a, 0xcf, 0xe7, + 0x2a, 0xfa, 0xe6, 0x16, 0xcb, 0xf2, 0x95, 0x04, 0xde, 0xd3, 0x37, 0xcf, 0x9b, + 0x14, 0xf1, 0xfd, 0xfc, 0x12, 0x16, 0x16, 0xed, 0x22, 0xd3, 0xd5, 0xba, 0xd7, + 0xec, 0xe1, 0xdf, 0x2b, 0xd2, 0xc2, 0x08, 0xd7, 0xdd, 0xab, 0xd7, 0xe4, 0x0a, + 0xf4, 0xc5, 0xb2, 0x19, 0xdf, 0xe9, 0x24, 0xc2, 0xc2, 0xfd, 0xcb, 0xbd, 0xe7, + 0xaf, 0x8d, 0xad, 0x19, 0x27, 0x04, 0xe0, 0xea, 0x2f, 0xf4, 0xe8, 0x40, 0x2e, + 0xde, 0x2c, 0xcd, 0xfa, 0x53, 0x23, 0xdf, 0x5f, 0xdd, 0xe1, 0xb5, 0xea, 0x01, + 0x1f, 0xac, 0xff, 0xfe, 0x27, 0xdb, 0x1d, 0xc3, 0x90, 0xf1, 0xe3, 0xaa, 0x01, + 0x04, 0xe5, 0x07, 0xb7, 0xbf, 0xc4, 0xc9, 0x11, 0xc9, 0xb5, 0xe0, 0x1e, 0xdf, + 0x14, 0x03, 0x1a, 0xcc, 0x28, 0x02, 0xee, 0x1b, 0x13, 0xed, 0xef, 0x58, 0xa8, + 0x09, 0x10, 0x15, 0xed, 0x00, 0x66, 0x06, 0xeb, 0xe9, 0xe5, 0xed, 0xfe, 0x28, + 0xd9, 0xaa, 0xe9, 0x99, 0x46, 0x17, 0xd1, 0xe6, 0x0a, 0xdf, 0xdc, 0xbe, 0x32, + 0xb5, 0xfa, 0xf6, 0xf2, 0xd0, 0xf7, 0xca, 0x03, 0xe6, 0xfc, 0x07, 0xcf, 0xef, + 0x93, 0xe5, 0x05, 0xf1, 0xe1, 0xdc, 0x10, 0x15, 0x25, 0x18, 0x17, 0xba, 0xb1, + 0xeb, 0x9d, 0xdc, 0x04, 0xbe, 0x27, 0x2d, 0xf2, 0x15, 0xdb, 0x25, 0xe6, 0xe4, + 0xe9, 0x1e, 0x27, 0xe9, 0xff, 0x26, 0x39, 0xca, 0x12, 0xa0, 0xd3, 0xcc, 0xfc, + 0x1c, 0x9d, 0xc0, 0xd0, 0xfc, 0xe0, 0xd2, 0x11, 0x23, 0xf6, 0x3b, 0xfe, 0xfc, + 0x3a, 0x25, 0x48, 0xd5, 0xdf, 0xc5, 0x29, 0x0e, 0xfd, 0x5b, 0xe1, 0x09, 0x4d, + 0x19, 0x31, 0xc9, 0xb1, 0xfd, 0x12, 0x32, 0xb5, 0x00, 0xf4, 0x43, 0x2c, 0xfb, + 0x1b, 0xeb, 0xd8, 0xe8, 0x11, 0xb6, 0x2b, 0xff, 0xef, 0x26, 0xcd, 0x5c, 0xf6, + 0xe9, 0xf0, 0xf3, 0xfd, 0xea, 0x00, 0xc3, 0xce, 0x1f, 0x44, 0xcf, 0xe0, 0xd2, + 0x12, 0xc1, 0x16, 0xdd, 0xe7, 0x9e, 0x3a, 0x10, 0x05, 0xfe, 0x0d, 0x04, 0xaf, + 0xdc, 0xc1, 0xc5, 0xd2, 0xdc, 0xa0, 0xd9, 0x00, 0x01, 0x71, 0xe2, 0x15, 0x1c, + 0xd3, 0x11, 0xcb, 0x0b, 0xd5, 0x86, 0x14, 0xa7, 0x0c, 0xe3, 0x3b, 0xb9, 0xb5, + 0xd7, 0x34, 0xdf, 0x37, 0xf3, 0xf6, 0xf2, 0xe1, 0x38, 0x35, 0x01, 0x00, 0xe9, + 0xad, 0xe8, 0x07, 0x2a, 0x96, 0x23, 0x2e, 0xff, 0xe0, 0xd9, 0x26, 0xeb, 0xe2, + 0x58, 0xcb, 0xe7, 0x01, 0xc8, 0x13, 0x1f, 0xca, 0xe5, 0xde, 0xfc, 0x0a, 0xe4, + 0x04, 0xd2, 0xef, 0x20, 0xd7, 0x03, 0x0a, 0xff, 0x27, 0x19, 0xf0, 0xc6, 0x01, + 0x19, 0xfa, 0xbb, 0xde, 0x13, 0xf0, 0xfd, 0x03, 0x9c, 0x07, 0xdd, 0xc3, 0x27, + 0xe1, 0xb6, 0xb4, 0xe7, 0xde, 0xe4, 0x81, 0x07, 0xef, 0x12, 0xe3, 0x19, 0x27, + 0x17, 0xca, 0xbb, 0x08, 0xc7, 0xd6, 0x20, 0x99, 0xf1, 0xe6, 0x1f, 0xcd, 0x03, + 0x05, 0x43, 0x17, 0xcc, 0x08, 0xec, 0xc3, 0x23, 0x28, 0x15, 0x07, 0xd7, 0x21, + 0xf2, 0xfc, 0x02, 0xf2, 0xc3, 0xe7, 0x20, 0x1c, 0xde, 0xa1, 0x0b, 0xcb, 0x1c, + 0xed, 0x8b, 0xcb, 0xd6, 0x23, 0x18, 0xe6, 0xfe, 0xde, 0x2a, 0xfd, 0xca, 0x2b, + 0x28, 0xf4, 0xf9, 0xd2, 0xc1, 0xe1, 0x14, 0xc8, 0x17, 0x01, 0xe4, 0xdf, 0x28, + 0x25, 0x0c, 0xfe, 0xf8, 0x15, 0x39, 0xfe, 0xd4, 0xeb, 0x1d, 0xf0, 0xeb, 0x16, + 0x92, 0x45, 0xf6, 0xbc, 0x35, 0x0c, 0xff, 0x29, 0x41, 0xf4, 0xe4, 0x46, 0x2a, + 0x0a, 0xfe, 0xc6, 0xe7, 0xe6, 0xa9, 0x0e, 0x0a, 0x01, 0x12, 0x4f, 0x21, 0xe6, + 0x14, 0xab, 0x09, 0xe0, 0xd5, 0xba, 0xfc, 0xf4, 0x02, 0xf4, 0x2b, 0x39, 0xef, + 0x1c, 0xb6, 0xed, 0xe6, 0x0c, 0x03, 0xda, 0xd4, 0xe9, 0xf7, 0x48, 0xf2, 0xe5, + 0x2f, 0xc5, 0xad, 0x31, 0xcc, 0xfd, 0xb3, 0xf2, 0xc4, 0x39, 0xee, 0x0a, 0xfe, + 0xe9, 0x1e, 0xec, 0x14, 0x14, 0xe3, 0xfb, 0x02, 0xfc, 0xf1, 0xf9, 0xb5, 0xd0, + 0xc4, 0x08, 0xe1, 0xf4, 0x15, 0xec, 0xc1, 0xd8, 0x0d, 0xff, 0x2f, 0xf9, 0x18, + 0xc1, 0xcc, 0x5d, 0xa1, 0xf2, 0x29, 0xf7, 0xf7, 0x30, 0xe3, 0x21, 0xe1, 0x11, + 0x1e, 0x89, 0xf2, 0xfd, 0xdc, 0x27, 0xd1, 0x17, 0xee, 0xcd, 0x7d, 0x12, 0xc2, + 0x14, 0xb5, 0xdf, 0x1f, 0xcd, 0x42, 0xcc, 0x0f, 0xd2, 0x13, 0x63, 0x13, 0x40, + 0xef, 0x16, 0x12, 0x04, 0x4e, 0xc5, 0xd4, 0x0c, 0x14, 0x1e, 0xda, 0xa1, 0x48, + 0xcc, 0xfd, 0x1a, 0xac, 0x18, 0xe6, 0xfc, 0x3b, 0x31, 0x0f, 0x7f, 0xf8, 0xf4, + 0x87, 0x14, 0xb8, 0xe1, 0x14, 0xec, 0xa9, 0x31, 0x20, 0x45, 0x06, 0xed, 0xf0, + 0xda, 0xe5, 0xe4, 0xcc, 0xdb, 0xff, 0xe7, 0xd3, 0x12, 0xf6, 0xe7, 0x06, 0x16, + 0xf2, 0xb6, 0xdf, 0x0b, 0x2b, 0x15, 0xe5, 0xca, 0x0f, 0x1d, 0xd2, 0x41, 0x07, + 0xea, 0xd8, 0x16, 0x0a, 0xaf, 0xad, 0xee, 0x02, 0x01, 0x04, 0x60, 0xe9, 0x31, + 0x5d, 0x04, 0x0e, 0xcb, 0xc3, 0xaa, 0x0b, 0xda, 0xbe, 0x16, 0x12, 0xed, 0xf5, + 0x1d, 0xd4, 0xd6, 0x29, 0x21, 0xfa, 0x99, 0x16, 0x06, 0xaa, 0x15, 0xd4, 0x1c, + 0x10, 0xec, 0xe9, 0xe7, 0x14, 0xe9, 0xf0, 0x34, 0xbe, 0xf5, 0x53, 0xf5, 0x08, + 0xe4, 0xd2, 0xe3, 0x1b, 0xec, 0xf7, 0xb4, 0xf2, 0x0b, 0x15, 0xcb, 0xaf, 0xe8, + 0xc3, 0xe1, 0x1d, 0x24, 0xe9, 0x23, 0xfc, 0xce, 0xd0, 0xd1, 0xac, 0x20, 0x0a, + 0x09, 0xda, 0xd3, 0xf3, 0x25, 0x12, 0xee, 0xd1, 0xc6, 0x11, 0xac, 0xf2, 0x1c, + 0xe6, 0xec, 0xf4, 0x1a, 0xc0, 0xb3, 0x08, 0x0a, 0x2b, 0x30, 0x63, 0xdb, 0xfa, + 0xd3, 0x19, 0xdd, 0xf6, 0x58, 0xcf, 0xe9, 0x25, 0xee, 0xe5, 0xcd, 0x11, 0x08, + 0xe3, 0xdc, 0xec, 0x43, 0xdc, 0x04, 0xfd, 0x11, 0xbd, 0x16, 0xda, 0xea, 0xf8, + 0xdc, 0xee, 0xe9, 0xe3, 0x42, 0xb7, 0x32, 0xc9, 0xc1, 0x4b, 0xff, 0x16, 0x1c, + 0x1d, 0x99, 0xbd, 0x5c, 0x30, 0xd3, 0x0f, 0xe4, 0x74, 0xc7, 0x02, 0x0f, 0xc7, + 0x2d, 0xec, 0x2a, 0xe2, 0x0d, 0x1d, 0xec, 0x0e, 0xe8, 0xdb, 0x22, 0xc9, 0xb3, + 0xd1, 0xfe, 0xe2, 0xe9, 0x20, 0xda, 0xd4, 0x19, 0x21, 0xa4, 0xf1, 0xe1, 0x39, + 0x2f, 0x05, 0x23, 0xe4, 0xf4, 0x01, 0x12, 0x00, 0xec, 0x25, 0x1e, 0xa8, 0xf6, + 0xf8, 0xff, 0x0e, 0xd5, 0xc0, 0xcb, 0xc1, 0x33, 0x22, 0xc4, 0x1f, 0x0e, 0x05, + 0xed, 0xe1, 0x01, 0xe0, 0x11, 0xeb, 0x0a, 0xe0, 0x32, 0xd0, 0x70, 0xaf, 0x1b, + 0xf1, 0x07, 0x10, 0xf6, 0x02, 0xed, 0x3e, 0xd6, 0xa9, 0x11, 0xee, 0x1e, 0xe0, + 0xd1, 0xbc, 0xe8, 0x01, 0xe2, 0x1c, 0x3e, 0xa3, 0xd6, 0x8a, 0x0d, 0xdd, 0xe1, + 0x30, 0xed, 0x04, 0x15, 0xff, 0x24, 0xff, 0x1b, 0x81, 0xcd, 0xd5, 0x19, 0xe1, + 0x14, 0x33, 0x29, 0xdb, 0xdc, 0x38, 0xce, 0xf7, 0xd6, 0xd9, 0x23, 0xbb, 0x01, + 0xd4, 0xfc, 0xda, 0x48, 0xde, 0xd8, 0x37, 0xd4, 0x2b, 0xcd, 0x36, 0xe9, 0x14, + 0xf7, 0xfc, 0xcc, 0xe4, 0x25, 0xe8, 0xf3, 0x22, 0x3b, 0x0a, 0xc5, 0xce, 0xfb, + 0xef, 0x1c, 0x06, 0x19, 0x19, 0x0d, 0xfd, 0xe0, 0xf4, 0xed, 0x01, 0xef, 0x30, + 0xfe, 0xed, 0xe5, 0xfa, 0xe8, 0x1b, 0x0d, 0x2f, 0x04, 0xcd, 0xda, 0xca, 0xd8, + 0xed, 0x1a, 0x1a, 0x0f, 0x00, 0x04, 0xef, 0x7f, 0xff, 0xd3, 0xf8, 0xf4, 0x14, + 0xf0, 0x1f, 0xec, 0xcf, 0xff, 0xe9, 0x03, 0xa9, 0x17, 0x98, 0x24, 0x46, 0xcf, + 0xed, 0x14, 0xc9, 0x00, 0xd0, 0xd5, 0x36, 0xec, 0x3d, 0xd0, 0xff, 0xdd, 0x0d, + 0x30, 0x01, 0xd8, 0xd2, 0xbe, 0xee, 0xe6, 0x0a, 0xe7, 0xfb, 0x17, 0x1a, 0xe4, + 0xe6, 0x03, 0xb3, 0x25, 0x10, 0x27, 0xe3, 0x11, 0xd1, 0xc3, 0xc8, 0xda, 0xe5, + 0xf0, 0x0c, 0xf1, 0x13, 0xb3, 0xeb, 0xd5, 0xce, 0xb0, 0x18, 0x16, 0xe5, 0xf1, + 0xfa, 0xcf, 0xd0, 0xd1, 0xe4, 0xd5, 0xeb, 0xea, 0x14, 0x09, 0x29, 0xbf, 0x30, + 0xd5, 0xd7, 0x2a, 0x1a, 0xed, 0x1e, 0xe7, 0x19, 0x31, 0x2f, 0xce, 0xbe, 0xd9, + 0xeb, 0xf9, 0xd1, 0x0e, 0xe5, 0xdf, 0xfb, 0xc7, 0x02, 0xea, 0xf6, 0x29, 0x11, + 0xdd, 0x03, 0xdf, 0x21, 0x12, 0xf6, 0xe9, 0xf3, 0xfb, 0x16, 0x2d, 0xdd, 0xf8, + 0xdf, 0xe8, 0xd3, 0xfe, 0x24, 0xd1, 0xf7, 0xbf, 0xe5, 0xff, 0x1f, 0x27, 0xe1, + 0x00, 0xff, 0xd5, 0xb0, 0x1b, 0x17, 0xdc, 0xef, 0x1f, 0xd2, 0xf4, 0x0c, 0xf0, + 0xaf, 0xda, 0xf4, 0x0e, 0x22, 0x1f, 0x05, 0xe5, 0x19, 0x19, 0x22, 0x00, 0x13, + 0xde, 0x1c, 0xe8, 0x41, 0x17, 0xee, 0x48, 0xe4, 0xf3, 0xf1, 0xad, 0x1a, 0x1a, + 0xeb, 0x41, 0x35, 0x14, 0x0f, 0xd6, 0xe6, 0xde, 0xd2, 0x39, 0xc9, 0xf7, 0x0b, + 0xe4, 0xf0, 0x00, 0xd7, 0x09, 0xf1, 0xff, 0xca, 0xfa, 0xfb, 0x19, 0x0e, 0xf1, + 0x09, 0x24, 0xce, 0xe4, 0x1c, 0x10, 0xfb, 0xf7, 0xf0, 0xf2, 0x2b, 0xd7, 0xfc, + 0xe8, 0xe4, 0x07, 0xfe, 0xdc, 0xe8, 0x19, 0xef, 0xed, 0xff, 0x0d, 0xe1, 0xf7, + 0xd6, 0xf9, 0xed, 0x1b, 0x17, 0x0d, 0xf6, 0xeb, 0xf5, 0x0d, 0x0b, 0xe1, 0x0f, + 0xf8, 0xfc, 0xf7, 0xf7, 0xef, 0xdf, 0x12, 0x1b, 0x03, 0x06, 0xf8, 0x03, 0xf0, + 0xe0, 0xf2, 0xe7, 0x3b, 0xc8, 0x05, 0xef, 0x0c, 0xf8, 0x15, 0xe0, 0x2e, 0xe1, + 0xb6, 0xfa, 0xf0, 0x20, 0x08, 0xe2, 0xe5, 0x02, 0xe3, 0x0a, 0x00, 0x18, 0xd1, + 0x14, 0xe5, 0x00, 0x17, 0x13, 0xfa, 0x1b, 0xee, 0x19, 0xfd, 0xd9, 0xf5, 0xcc, + 0x03, 0xe6, 0x0b, 0xe2, 0x16, 0x1a, 0x15, 0xea, 0x0f, 0xdd, 0xd3, 0xf0, 0xf4, + 0x00, 0xc5, 0x04, 0x0b, 0x0e, 0xde, 0xdc, 0x1e, 0xe8, 0xe9, 0x43, 0x00, 0x11, + 0x0b, 0x25, 0xe0, 0xfc, 0x1f, 0xd7, 0x7f, 0xf7, 0x06, 0x15, 0x0c, 0x24, 0x41, + 0xf1, 0x1c, 0xf1, 0xfb, 0xe5, 0xcc, 0xcf, 0xf7, 0xd7, 0xe6, 0x05, 0xee, 0xee, + 0x2e, 0x1b, 0x1b, 0x0a, 0x28, 0x20, 0x0d, 0x06, 0xf5, 0x0a, 0x13, 0xed, 0x00, + 0x23, 0xc6, 0xd9, 0xf8, 0x1d, 0xe1, 0x11, 0xcc, 0xe9, 0xe3, 0xfe, 0x18, 0x0a, + 0xdf, 0xfb, 0xdc, 0x02, 0xed, 0xe8, 0x00, 0x19, 0x23, 0xda, 0x14, 0x0c, 0xe9, + 0x3e, 0xf1, 0x1c, 0x05, 0x1c, 0xdd, 0xf3, 0x19, 0x11, 0x05, 0x02, 0x04, 0xf0, + 0x02, 0xf7, 0xf9, 0xf4, 0x03, 0x00, 0xe2, 0xf7, 0x16, 0x07, 0x37, 0xdd, 0x09, + 0xfe, 0x1e, 0x27, 0xef, 0x14, 0xfa, 0xdf, 0xf0, 0xd4, 0xe5, 0x08, 0xeb, 0x26, + 0x33, 0x36, 0xe7, 0x18, 0xfa, 0xfc, 0x10, 0x13, 0x0c, 0xf5, 0xe5, 0xfb, 0xfe, + 0x1b, 0xc4, 0xe8, 0x04, 0xd1, 0x0e, 0x33, 0xee, 0x15, 0x0b, 0x12, 0xf3, 0xe8, + 0xd1, 0x00, 0x01, 0xe6, 0xd8, 0xd7, 0x01, 0xe5, 0x13, 0xfe, 0xf7, 0x0f, 0xee, + 0x18, 0x06, 0x07, 0xe8, 0xdf, 0x12, 0x17, 0xd3, 0xff, 0xfe, 0xe7, 0x15, 0x13, + 0xd1, 0xa8, 0xd0, 0xf2, 0x0a, 0xce, 0xfe, 0xfb, 0xf9, 0xd8, 0xcd, 0xf2, 0xf1, + 0x25, 0x0e, 0x1d, 0xc9, 0xeb, 0x2b, 0xf9, 0xf5, 0xf2, 0xf7, 0x32, 0xf9, 0x2b, + 0xef, 0x2b, 0x04, 0xf7, 0x21, 0x11, 0x1e, 0xf5, 0x3c, 0xfc, 0xc9, 0xb8, 0x3b, + 0x03, 0xb9, 0xb2, 0xec, 0xe8, 0xe9, 0x04, 0x18, 0xdf, 0xde, 0xc2, 0x26, 0x0e, + 0x0e, 0xf7, 0xd8, 0x40, 0x0d, 0xf1, 0x4e, 0xf2, 0xe9, 0xef, 0xf1, 0x13, 0x1d, + 0xf9, 0xe0, 0x1a, 0x10, 0x18, 0x12, 0xdd, 0x35, 0x35, 0xf9, 0x02, 0xde, 0xd2, + 0x2a, 0xf9, 0xdf, 0x01, 0xd5, 0xf3, 0xf5, 0x05, 0x08, 0xe5, 0x9e, 0x19, 0x0a, + 0x0c, 0x44, 0xeb, 0x32, 0xf1, 0x06, 0x51, 0xd6, 0xdd, 0xea, 0xf1, 0xd5, 0xd8, + 0xed, 0xfe, 0x7f, 0xd2, 0x07, 0x03, 0xd6, 0x14, 0x13, 0xd7, 0x0c, 0xdd, 0xe0, + 0xff, 0xaf, 0x1a, 0xfc, 0xd5, 0xca, 0xd0, 0xe7, 0xf3, 0xf6, 0xeb, 0xea, 0x10, + 0xf0, 0xfe, 0x10, 0xfb, 0xe9, 0x1a, 0xf8, 0xde, 0x0b, 0xf9, 0xb3, 0xc6, 0xf4, + 0xe8, 0x10, 0x1c, 0xd5, 0xee, 0xcf, 0x09, 0x01, 0xfc, 0xe9, 0xf0, 0xcd, 0x20, + 0xe5, 0x04, 0x0c, 0x04, 0x11, 0xec, 0xc2, 0x10, 0x1f, 0x17, 0xd1, 0xd6, 0x08, + 0x22, 0xf3, 0xf0, 0x34, 0x1e, 0x13, 0xfd, 0xdd, 0x18, 0xfb, 0x1f, 0xe0, 0x06, + 0x0c, 0xf3, 0x05, 0x03, 0xf3, 0x0e, 0x17, 0xfe, 0xde, 0x02, 0xea, 0x0e, 0xf0, + 0x22, 0xdc, 0xef, 0xc5, 0xeb, 0xf9, 0x0a, 0xf1, 0x05, 0xe9, 0x18, 0x12, 0xf2, + 0xf7, 0xea, 0x12, 0x2a, 0x33, 0xe0, 0xfd, 0xf1, 0x08, 0x24, 0xf7, 0xe5, 0xde, + 0xe1, 0x11, 0x35, 0x16, 0x16, 0x13, 0xf9, 0x1b, 0xda, 0xbb, 0xfd, 0xfe, 0xdf, + 0x0f, 0x0a, 0x40, 0xf8, 0xed, 0xea, 0xbb, 0xbe, 0xec, 0x05, 0xd7, 0x0f, 0x1b, + 0x24, 0xd5, 0x2b, 0xf2, 0x1b, 0xe4, 0xdc, 0x5e, 0xeb, 0xdb, 0x48, 0x3e, 0x0d, + 0xad, 0x26, 0xdc, 0xf2, 0xc6, 0xb5, 0x22, 0xa5, 0xc5, 0x2d, 0xc9, 0xcb, 0xe9, + 0x2e, 0x1f, 0xba, 0x81, 0xc7, 0xcd, 0xbb, 0x0c, 0xe5, 0xd6, 0xdd, 0xf5, 0xe7, + 0x17, 0x05, 0x0d, 0xf6, 0xd8, 0xf1, 0xc0, 0xff, 0xfc, 0xf2, 0xe5, 0xeb, 0xda, + 0x03, 0x0a, 0xfb, 0x48, 0xf9, 0xa7, 0xf5, 0xe7, 0xe8, 0x31, 0xd6, 0xd2, 0x2c, + 0xba, 0x4c, 0x19, 0xb7, 0x4d, 0x08, 0x0e, 0x1c, 0xce, 0xd6, 0xa6, 0xbe, 0xc2, + 0x07, 0xed, 0x32, 0xd7, 0xfc, 0xc9, 0xa6, 0x40, 0x1c, 0x05, 0xdb, 0x40, 0xd7, + 0x0a, 0x2a, 0xaf, 0x04, 0xf8, 0xff, 0x22, 0x27, 0xa1, 0xd8, 0xeb, 0xe4, 0xf0, + 0x04, 0xa8, 0xb2, 0x3d, 0xe3, 0x12, 0xe0, 0xb5, 0x2c, 0x0d, 0xe9, 0x30, 0xb4, + 0x26, 0x1d, 0xcc, 0x0c, 0xf8, 0xe2, 0x04, 0xa9, 0xee, 0xc3, 0xb6, 0xe7, 0xfa, + 0x3d, 0xb4, 0xe7, 0xcb, 0x35, 0x02, 0xde, 0x34, 0x3c, 0xea, 0xe6, 0x0a, 0xcc, + 0xfa, 0x00, 0x44, 0x03, 0xf6, 0xf2, 0xfb, 0xec, 0xce, 0x1a, 0x45, 0x35, 0xc4, + 0xd4, 0x26, 0xdf, 0xfe, 0xeb, 0x20, 0xe8, 0xfb, 0xd5, 0xc4, 0x3a, 0xf4, 0xfc, + 0x09, 0xe8, 0x3d, 0xe7, 0xd4, 0x22, 0xc2, 0xde, 0x16, 0xf8, 0x38, 0xf8, 0x1d, + 0x36, 0x31, 0x35, 0xfc, 0xc6, 0xfa, 0xda, 0x0e, 0xcf, 0xe8, 0xe4, 0xb9, 0xed, + 0xfa, 0x37, 0x18, 0x05, 0xbb, 0xd8, 0xee, 0x14, 0x0b, 0xe5, 0xec, 0xcc, 0xc9, + 0xf6, 0xd6, 0x08, 0xfc, 0x09, 0x2a, 0x08, 0xfd, 0xcd, 0xa2, 0x13, 0x36, 0x32, + 0x31, 0xf5, 0x0a, 0xef, 0xfb, 0x09, 0x17, 0x03, 0xd8, 0x2a, 0x05, 0xe7, 0x2a, + 0xdd, 0xef, 0xe8, 0xab, 0x0d, 0xd4, 0xcb, 0x29, 0x0d, 0xf9, 0xbf, 0x85, 0xfb, + 0x2a, 0xf8, 0x44, 0xdb, 0xa1, 0x24, 0xe2, 0xfe, 0xe0, 0x3a, 0x09, 0xf0, 0x08, + 0xa1, 0xf9, 0x2c, 0x10, 0xdc, 0xf0, 0xec, 0xe8, 0xf8, 0x54, 0x01, 0x1e, 0xb0, + 0x44, 0xf9, 0x0a, 0x3a, 0x29, 0xea, 0xe3, 0xee, 0x5f, 0x22, 0x5b, 0xfe, 0xdd, + 0x89, 0x0c, 0xb2, 0xda, 0x96, 0x99, 0xf4, 0xec, 0x05, 0xc8, 0xf9, 0xdf, 0xf8, + 0xd0, 0x0e, 0xca, 0x9d, 0x38, 0x0b, 0x20, 0x35, 0xf5, 0xf9, 0x2b, 0xcb, 0xef, + 0x26, 0xe3, 0xea, 0x45, 0x23, 0xa2, 0xb7, 0xe1, 0x1c, 0x1d, 0xe1, 0xda, 0x33, + 0xc6, 0x09, 0x1b, 0x4c, 0xc7, 0xd1, 0xb7, 0xf3, 0xa5, 0x36, 0x5a, 0xef, 0x05, + 0xfb, 0x9f, 0xbf, 0x5f, 0x17, 0x84, 0xde, 0xf7, 0xf3, 0x4f, 0xc6, 0x31, 0x25, + 0x27, 0xe3, 0x04, 0xe3, 0x15, 0xa5, 0xeb, 0xbe, 0xe7, 0x0b, 0x3d, 0xcc, 0xe3, + 0x18, 0xb5, 0x21, 0x5f, 0x09, 0xf8, 0xd2, 0xc6, 0xc4, 0x29, 0x18, 0xc2, 0x3c, + 0x32, 0x26, 0xe6, 0x18, 0x36, 0xf5, 0x31, 0xcd, 0xe0, 0x21, 0x6b, 0xef, 0x5c, + 0xca, 0xfd, 0xca, 0x28, 0xc4, 0x01, 0xf7, 0x40, 0xe1, 0xe7, 0xee, 0xdd, 0x11, + 0xc6, 0x08, 0x8d, 0xbe, 0xb8, 0x57, 0x3b, 0xc2, 0xf9, 0xe1, 0xec, 0x3d, 0x32, + 0xa9, 0xc1, 0x2f, 0x3c, 0x10, 0xc5, 0x0b, 0x0d, 0x0c, 0x08, 0xbe, 0xda, 0xf1, + 0xff, 0xcd, 0x00, 0x44, 0x03, 0x59, 0xae, 0x0d, 0x18, 0xdf, 0xf3, 0x7f, 0xf1, + 0x02, 0x5d, 0x05, 0xf9, 0xea, 0xfa, 0x91, 0x1e, 0x0d, 0xf9, 0xf3, 0x33, 0x46, + 0xfc, 0xfc, 0x5a, 0xcc, 0x42, 0x39, 0xe7, 0xc3, 0xb9, 0xec, 0xce, 0x9a, 0x38, + 0xb5, 0xea, 0xc2, 0xc8, 0x24, 0x2c, 0xcc, 0x14, 0xac, 0xe2, 0xc8, 0x33, 0xb5, + 0xf2, 0xa0, 0xee, 0xdd, 0x2a, 0x97, 0xef, 0x22, 0xda, 0x5d, 0x2d, 0x4e, 0x07, + 0xdb, 0xc6, 0xb9, 0xe9, 0xa7, 0x00, 0xf4, 0xc4, 0xd4, 0xb6, 0xef, 0xdd, 0xe8, + 0xef, 0xee, 0x9d, 0xeb, 0xde, 0xec, 0xc9, 0xe7, 0xf7, 0xcb, 0xb8, 0xc2, 0x0f, + 0xfc, 0xec, 0xfa, 0xda, 0x89, 0x05, 0x3e, 0xc0, 0x29, 0xf7, 0x14, 0xe2, 0xf1, + 0xda, 0xd3, 0xe5, 0xdd, 0x0a, 0xf6, 0x16, 0x03, 0xeb, 0xed, 0x39, 0x34, 0xb8, + 0xe7, 0xf2, 0x1f, 0xb9, 0xed, 0xb5, 0xe4, 0x18, 0x35, 0xf8, 0x1b, 0xd6, 0x20, + 0x48, 0x2f, 0x06, 0xaa, 0xd7, 0x1d, 0xd8, 0x06, 0x09, 0xca, 0xdf, 0x1d, 0x28, + 0x07, 0x11, 0xf5, 0x0c, 0xf5, 0x8a, 0xe9, 0x19, 0xc6, 0xcd, 0xf6, 0xc1, 0xe9, + 0x0a, 0xfd, 0x38, 0xe2, 0xde, 0x08, 0xd1, 0xd2, 0xe7, 0x10, 0xfd, 0x16, 0xdf, + 0x50, 0x81, 0x1f, 0xd4, 0x03, 0xbe, 0x50, 0x12, 0xd1, 0xe4, 0xdd, 0xe3, 0x1a, + 0x1a, 0xe0, 0xd1, 0xdb, 0xe1, 0xbe, 0x05, 0xf5, 0x9c, 0x10, 0x02, 0x0c, 0x1a, + 0xd4, 0x27, 0xf3, 0xd2, 0x32, 0x88, 0x0e, 0x23, 0x14, 0x58, 0xfa, 0xf8, 0xf3, + 0xe2, 0x32, 0xe1, 0xdd, 0xe5, 0x00, 0xb8, 0x24, 0xee, 0x39, 0xab, 0xf8, 0xd4, + 0xf4, 0x57, 0xd8, 0xc5, 0xf7, 0x49, 0x2f, 0x4a, 0xe5, 0xf7, 0xea, 0xfa, 0xec, + 0x39, 0x27, 0xc6, 0xc8, 0x1f, 0xeb, 0xd5, 0x53, 0xf7, 0x60, 0xe4, 0xe3, 0x39, + 0xbc, 0xd1, 0xab, 0x1f, 0x1e, 0x0d, 0xd7, 0x1c, 0x51, 0xc6, 0xc3, 0x21, 0xc2, + 0xd0, 0x14, 0xbd, 0xc8, 0xb0, 0xc4, 0x0e, 0xeb, 0x4b, 0x0b, 0xf0, 0xe7, 0xee, + 0xe9, 0x63, 0xda, 0xe8, 0x2a, 0xf8, 0xd6, 0xde, 0x19, 0x22, 0xe0, 0xb8, 0xfd, + 0xee, 0xd4, 0xfb, 0xda, 0x47, 0xc7, 0x50, 0x14, 0xe2, 0xd7, 0x18, 0x05, 0xd4, + 0xfd, 0x9f, 0x06, 0xee, 0xf1, 0xe1, 0xce, 0x40, 0x2f, 0xff, 0x0c, 0x19, 0xf1, + 0x29, 0xbb, 0xc6, 0xd7, 0xee, 0xb4, 0xe9, 0xc1, 0xe2, 0xfd, 0x08, 0xb4, 0x32, + 0xdd, 0x16, 0xe1, 0x21, 0x97, 0xd0, 0xf6, 0x03, 0xe0, 0xbc, 0xd7, 0x96, 0x48, + 0xe0, 0xfb, 0xd8, 0xe4, 0xe2, 0x06, 0xd6, 0x11, 0xe7, 0xd5, 0x92, 0x32, 0xfc, + 0xef, 0xd4, 0xe6, 0x42, 0x19, 0xce, 0x09, 0x16, 0xcb, 0xae, 0x0a, 0xe2, 0x33, + 0x0d, 0xa2, 0x33, 0x00, 0xe0, 0x0e, 0xd0, 0x4c, 0x15, 0xe7, 0x3f, 0xdb, 0x1a, + 0x33, 0x38, 0xc8, 0xfb, 0xc1, 0xfa, 0x04, 0x17, 0x27, 0x3f, 0x12, 0xb4, 0x18, + 0xf4, 0x05, 0xe8, 0x0b, 0x1c, 0xa8, 0xe7, 0xde, 0x04, 0xb8, 0xf0, 0x00, 0xc5, + 0x10, 0xd7, 0xd3, 0xb8, 0x28, 0x37, 0xf7, 0x2f, 0xde, 0x05, 0xa7, 0xe8, 0xa9, + 0x15, 0xf2, 0x06, 0xb7, 0xf3, 0xc3, 0xc1, 0x21, 0x0e, 0x0b, 0x2a, 0xeb, 0x05, + 0xfe, 0x11, 0xd0, 0xf5, 0x00, 0xc7, 0x30, 0xe4, 0x15, 0x2c, 0x00, 0x0f, 0x95, + 0xd8, 0x1e, 0xe8, 0x26, 0x13, 0xd8, 0xcf, 0xde, 0xcc, 0x3e, 0xcd, 0x9d, 0x15, + 0x4d, 0x54, 0x3f, 0xac, 0xed, 0x3f, 0xce, 0xb0, 0x21, 0x47, 0xdd, 0x31, 0x81, + 0xf0, 0x1e, 0x07, 0xc9, 0x29, 0x04, 0xd3, 0x3f, 0xff, 0xef, 0xb1, 0x1a, 0x05, + 0xfb, 0x32, 0xf2, 0xfe, 0xe2, 0x1b, 0x08, 0xaf, 0xb6, 0xa9, 0xeb, 0xba, 0x16, + 0x41, 0xbc, 0xaf, 0xdb, 0xdf, 0x16, 0x1c, 0x32, 0x2d, 0x19, 0xd4, 0xc4, 0x4c, + 0xb9, 0xba, 0xdf, 0x30, 0xc1, 0x93, 0xce, 0x03, 0xac, 0xdb, 0xef, 0xff, 0xf1, + 0x4a, 0x49, 0xca, 0xfc, 0xeb, 0xbd, 0x09, 0x20, 0x2f, 0x06, 0x3f, 0xfd, 0x3b, + 0x1c, 0x29, 0xf4, 0x11, 0x16, 0x0b, 0xd8, 0xef, 0x32, 0x08, 0xfa, 0x4d, 0xe1, + 0x3a, 0xbc, 0x50, 0xeb, 0x38, 0x07, 0xf2, 0x13, 0xbb, 0xd2, 0xac, 0x4f, 0x5f, + 0x09, 0x26, 0xfa, 0xee, 0xea, 0x3c, 0xda, 0x0f, 0x54, 0xe7, 0x07, 0x09, 0xed, + 0xda, 0x33, 0x20, 0x2c, 0x33, 0xcd, 0xf4, 0x3f, 0xbe, 0xf3, 0xbe, 0xa8, 0xc1, + 0xbb, 0x12, 0xfe, 0x00, 0x02, 0xc0, 0x25, 0x0a, 0xda, 0xa8, 0xdc, 0x24, 0x0a, + 0xc7, 0xef, 0xd1, 0xf2, 0xed, 0xc1, 0x0d, 0xe2, 0x8d, 0x02, 0xeb, 0x07, 0xf7, + 0xde, 0xf1, 0xcd, 0x20, 0x26, 0x1e, 0xd2, 0xf9, 0xa7, 0xb7, 0xef, 0x01, 0xce, + 0xb8, 0xaf, 0xbc, 0xd8, 0xf5, 0x4d, 0xe3, 0xd0, 0xa3, 0xc6, 0x1e, 0x02, 0xd4, + 0x00, 0x10, 0xde, 0xd5, 0xed, 0xfe, 0xdb, 0xd5, 0xfa, 0x0d, 0x23, 0x54, 0xf9, + 0xfe, 0xd0, 0xdb, 0xa8, 0x1f, 0x0a, 0xa1, 0x04, 0xef, 0x4e, 0x03, 0x19, 0xf2, + 0xec, 0xbd, 0x20, 0xbb, 0xe6, 0xf7, 0x1b, 0xbe, 0xe9, 0x14, 0xf9, 0xdc, 0xf2, + 0xe5, 0xf7, 0xf1, 0xe8, 0xb8, 0xe9, 0xe3, 0xee, 0xf4, 0x28, 0x0b, 0x9f, 0xe3, + 0xff, 0x22, 0xd2, 0x98, 0x81, 0x16, 0xed, 0xf3, 0x9f, 0x15, 0xfd, 0x11, 0x1a, + 0xda, 0xea, 0xb5, 0xf2, 0x9d, 0x08, 0x37, 0xb9, 0x22, 0xbc, 0x11, 0x21, 0xee, + 0x1a, 0x2c, 0xca, 0x01, 0xdd, 0xfe, 0xd8, 0xf6, 0xa5, 0x05, 0xc7, 0x9b, 0xf7, + 0xe2, 0xa9, 0xd6, 0x11, 0xc0, 0xf7, 0x11, 0xfa, 0x1e, 0xde, 0xc9, 0x27, 0x13, + 0xf4, 0xee, 0x1c, 0xbd, 0x06, 0xf5, 0xde, 0x27, 0xbf, 0x11, 0xcf, 0xc7, 0x53, + 0x1c, 0x17, 0xe1, 0xf4, 0xfa, 0x35, 0xce, 0xe0, 0x06, 0xeb, 0x27, 0xed, 0xc1, + 0xdc, 0x18, 0xf4, 0xa7, 0xde, 0x12, 0xd9, 0x09, 0xe0, 0x28, 0xcf, 0xdc, 0x11, + 0x12, 0x03, 0x2f, 0x30, 0xcf, 0xfa, 0x11, 0xc7, 0xe5, 0x40, 0x07, 0xeb, 0x37, + 0xde, 0xc0, 0x26, 0x10, 0xca, 0x3d, 0xe3, 0xe8, 0xe9, 0xf1, 0x04, 0xe2, 0xe9, + 0x09, 0x30, 0x20, 0x15, 0x11, 0xc7, 0xed, 0xe0, 0x06, 0x1c, 0xdf, 0x1d, 0xea, + 0xd7, 0x18, 0x01, 0xd8, 0x99, 0xf3, 0x05, 0x19, 0x0e, 0x1b, 0x3e, 0xbf, 0x29, + 0x6e, 0xcc, 0x0b, 0x2a, 0xf6, 0xa3, 0xee, 0x8f, 0x18, 0xbb, 0xfe, 0xb0, 0xce, + 0x28, 0xbf, 0x1e, 0x01, 0x0e, 0xeb, 0x24, 0xef, 0xfb, 0xb4, 0x11, 0x67, 0xd6, + 0xec, 0xa1, 0x01, 0x90, 0x41, 0x4f, 0xc0, 0x0a, 0x1f, 0xab, 0xe4, 0xf2, 0xdc, + 0xec, 0x09, 0x12, 0x97, 0x04, 0x22, 0xf2, 0x2d, 0x20, 0x15, 0x9f, 0xc4, 0x15, + 0x2f, 0xf5, 0x11, 0xfe, 0x1e, 0x05, 0x4e, 0x08, 0x0c, 0x19, 0x38, 0xf1, 0xce, + 0x1c, 0x20, 0xc2, 0xb7, 0xd2, 0xdc, 0xf6, 0x13, 0xfb, 0xaa, 0xde, 0x24, 0x2b, + 0x04, 0xb0, 0xc4, 0x23, 0x9b, 0xb3, 0xe6, 0x8d, 0xc3, 0xd6, 0xd7, 0x37, 0x2a, + 0xd2, 0x37, 0xda, 0x81, 0xea, 0x25, 0x2b, 0xce, 0x08, 0x07, 0xf0, 0x3a, 0xe3, + 0x1e, 0xa9, 0xe7, 0xf1, 0xed, 0x1a, 0xa8, 0x21, 0xe2, 0xe9, 0xd4, 0xc2, 0xd5, + 0x15, 0x45, 0xdf, 0x38, 0xcf, 0x3b, 0x1f, 0xe4, 0x24, 0x43, 0xe4, 0x07, 0xcc, + 0xca, 0xfe, 0xe8, 0x10, 0x30, 0xc0, 0xc0, 0x31, 0x9c, 0xf9, 0xdf, 0xd5, 0xd2, + 0x07, 0x2f, 0xfc, 0xff, 0x0e, 0xe0, 0x06, 0x20, 0xb3, 0x19, 0xf9, 0x20, 0xae, + 0xe3, 0xfa, 0xd5, 0x0b, 0x25, 0x2d, 0xc6, 0xe9, 0x06, 0x36, 0xce, 0xf6, 0x17, + 0xf5, 0xde, 0x25, 0xee, 0x25, 0xd1, 0xe4, 0xe1, 0x33, 0xfa, 0xeb, 0x05, 0x55, + 0xce, 0x0c, 0xf8, 0xb5, 0xeb, 0x00, 0x65, 0x0b, 0x0b, 0x32, 0xab, 0x02, 0xab, + 0x0f, 0xfb, 0xd6, 0xf3, 0xba, 0xd8, 0xf7, 0x25, 0xb2, 0x46, 0x3b, 0xff, 0xc6, + 0xbd, 0x0b, 0x16, 0xce, 0xf2, 0xed, 0xb2, 0xf4, 0xf3, 0xf9, 0xe8, 0xe9, 0xb5, + 0xe1, 0x9d, 0xff, 0xf0, 0xed, 0xd2, 0x18, 0xfd, 0xeb, 0xc7, 0xf6, 0x3f, 0x0c, + 0xdc, 0xe8, 0x0d, 0x2b, 0xd0, 0x64, 0x15, 0x10, 0xcf, 0x05, 0xdc, 0xe0, 0xcf, + 0xda, 0xdd, 0x24, 0xd2, 0x40, 0x07, 0xb1, 0x41, 0x02, 0xe4, 0xca, 0x07, 0x23, + 0x2f, 0xbf, 0xf0, 0xcb, 0xc0, 0x00, 0xba, 0xee, 0xe2, 0xc7, 0x14, 0xca, 0x3f, + 0xf5, 0xba, 0xdd, 0xf2, 0xfc, 0x28, 0xa4, 0x09, 0xbc, 0xe5, 0x2c, 0x22, 0x57, + 0x25, 0x40, 0x20, 0xab, 0xdf, 0x01, 0x2d, 0x08, 0xa4, 0xde, 0x1a, 0x0f, 0xe9, + 0xc3, 0x1a, 0x41, 0xc1, 0xe4, 0xb9, 0xeb, 0x0d, 0xd7, 0xb6, 0x04, 0x08, 0x47, + 0xed, 0x0d, 0x32, 0x2a, 0x25, 0xe3, 0x10, 0xe2, 0xb9, 0xb3, 0xd2, 0x0d, 0x3a, + 0x2c, 0xe4, 0xef, 0x39, 0x9c, 0xcb, 0xbe, 0xf1, 0x23, 0x60, 0x02, 0x4a, 0xd1, + 0xbe, 0xd9, 0xa9, 0x2a, 0x1e, 0x0f, 0xb4, 0x02, 0x03, 0xdf, 0xd2, 0x23, 0xa7, + 0xcf, 0x1e, 0x32, 0x16, 0x09, 0xfe, 0x1d, 0xe6, 0x19, 0xd7, 0xb9, 0xd1, 0xc4, + 0x51, 0xbc, 0x13, 0x16, 0xf4, 0x4e, 0xf0, 0xcb, 0xff, 0xeb, 0xdd, 0x03, 0xf4, + 0x12, 0x25, 0x40, 0xde, 0x47, 0xf7, 0xe1, 0xdf, 0x45, 0xf6, 0x26, 0xa7, 0xeb, + 0xe6, 0xee, 0x0a, 0xed, 0xed, 0xfb, 0x32, 0xc4, 0x45, 0x33, 0xd2, 0x26, 0xeb, + 0x1e, 0x09, 0x2a, 0xde, 0x3f, 0xcc, 0x44, 0xe5, 0x27, 0xb6, 0x50, 0xb2, 0x03, + 0xf4, 0x16, 0xc7, 0xc2, 0xdc, 0xd3, 0x05, 0x35, 0x14, 0x4e, 0xd6, 0xd5, 0x4f, + 0x0d, 0xcd, 0x1b, 0xfe, 0x68, 0xe5, 0xce, 0x0c, 0x1b, 0xe4, 0xea, 0xc0, 0xfd, + 0xcb, 0x79, 0x0a, 0x9b, 0x40, 0xe2, 0xfd, 0xa4, 0xbc, 0xc3, 0x21, 0x51, 0x48, + 0xa2, 0x06, 0x91, 0x00, 0xe1, 0xfa, 0x37, 0x09, 0xdc, 0x3d, 0x00, 0xcd, 0x7f, + 0xf7, 0x43, 0x1c, 0xe4, 0x1c, 0xfc, 0x4a, 0x21, 0xb2, 0xdb, 0x04, 0x21, 0xcf, + 0x00, 0xa6, 0xe4, 0x29, 0x17, 0x2a, 0xde, 0x22, 0x47, 0xf1, 0x17, 0xe5, 0x03, + 0xd3, 0xc5, 0xce, 0xfc, 0xd9, 0xe8, 0xd8, 0xf1, 0xc2, 0x2f, 0x08, 0x47, 0xf3, + 0xc4, 0x04, 0xea, 0xd3, 0xb4, 0x33, 0xe2, 0xee, 0xc5, 0xe5, 0x19, 0xf2, 0xff, + 0xc1, 0xfb, 0xd7, 0x1e, 0xe7, 0xd2, 0x03, 0xd8, 0xd9, 0xea, 0xb0, 0xfa, 0x1f, + 0x43, 0xe8, 0xe1, 0x2e, 0x15, 0x24, 0xe5, 0xc4, 0x1b, 0xd9, 0x0d, 0x1b, 0xe3, + 0xeb, 0x0c, 0xcc, 0xe1, 0x46, 0xfc, 0xde, 0x0e, 0x0a, 0x0b, 0xd2, 0x10, 0xda, + 0x0f, 0xec, 0x0a, 0xf9, 0xe1, 0xdf, 0x14, 0xea, 0x22, 0x45, 0xf0, 0x22, 0x15, + 0xc6, 0x04, 0xfd, 0x0c, 0x2e, 0x01, 0xdc, 0x05, 0xba, 0xf3, 0xe3, 0x04, 0x1c, + 0xde, 0xf7, 0xd8, 0x13, 0xfa, 0xd6, 0xec, 0x1b, 0x15, 0xfa, 0xcf, 0xe6, 0xdd, + 0x22, 0x03, 0xf4, 0xd7, 0x1f, 0xf3, 0xe2, 0xfe, 0x02, 0x2e, 0xf7, 0xdb, 0xf6, + 0xf9, 0xfb, 0x17, 0xed, 0x1a, 0xf0, 0xed, 0xc6, 0xf7, 0x18, 0xad, 0x29, 0xfb, + 0x04, 0xf0, 0x35, 0x0b, 0xd0, 0x0d, 0x02, 0x17, 0x09, 0xf6, 0xfd, 0x0d, 0xac, + 0xdf, 0x18, 0xd5, 0xcf, 0xd9, 0xce, 0x3d, 0xf8, 0xeb, 0xff, 0x12, 0xb1, 0x15, + 0x01, 0xf9, 0x1a, 0x10, 0xeb, 0xf5, 0x1f, 0x05, 0x0e, 0xfd, 0xfd, 0x12, 0x09, + 0x27, 0xcd, 0x11, 0x0d, 0x35, 0xa3, 0xda, 0xc4, 0xde, 0xee, 0x03, 0xf7, 0x1b, + 0x26, 0x0d, 0x18, 0x2c, 0x06, 0xb9, 0xef, 0x2b, 0xe6, 0x0a, 0xee, 0x0c, 0xed, + 0x79, 0xe3, 0x16, 0x47, 0xf1, 0xfe, 0xde, 0xf2, 0xe5, 0x05, 0xd4, 0xde, 0xec, + 0x44, 0xc9, 0xd1, 0x2f, 0x07, 0xf6, 0x17, 0x1b, 0xd9, 0xdd, 0xed, 0x3a, 0x35, + 0x2a, 0x3e, 0x08, 0x08, 0xaa, 0xef, 0xeb, 0xa6, 0x7f, 0xf1, 0x57, 0x26, 0x29, + 0xe0, 0x0e, 0x33, 0xcf, 0x29, 0xdf, 0xd8, 0xed, 0x18, 0xf2, 0x07, 0x08, 0x28, + 0xd4, 0xde, 0xd7, 0xd4, 0x0b, 0xc2, 0xcf, 0xf3, 0x2e, 0x0b, 0xb3, 0x95, 0x1f, + 0x1f, 0x23, 0x02, 0x0c, 0x19, 0xf5, 0xe6, 0xfd, 0xb9, 0x12, 0xe6, 0x13, 0x13, + 0x35, 0x38, 0x20, 0x1a, 0xe6, 0xf4, 0x32, 0x50, 0xc3, 0x04, 0xb5, 0xdf, 0xe1, + 0xf4, 0xf5, 0xdb, 0x42, 0xfb, 0xeb, 0xf2, 0xb8, 0x20, 0xe7, 0x25, 0x06, 0xee, + 0x33, 0x12, 0xdd, 0x01, 0xef, 0x0f, 0x1f, 0xf2, 0xcc, 0xf9, 0x10, 0xe7, 0xc3, + 0x9e, 0xe1, 0x19, 0x2a, 0xf5, 0x0c, 0xde, 0xc8, 0xda, 0xf4, 0xb0, 0xec, 0x09, + 0x1a, 0x02, 0xab, 0x5e, 0xce, 0x0e, 0x2d, 0xfb, 0xee, 0x1b, 0xf2, 0x3d, 0x51, + 0xde, 0xbf, 0x24, 0xe0, 0x3a, 0xa9, 0x27, 0xaa, 0xce, 0xb3, 0xf7, 0xcd, 0xf8, + 0xa7, 0xf6, 0xf3, 0xe1, 0x1e, 0x3a, 0x36, 0xc2, 0xb4, 0xfb, 0x41, 0x51, 0x0e, + 0x17, 0x27, 0x00, 0x14, 0xf0, 0xe2, 0xc9, 0xcc, 0xf6, 0xcd, 0xf0, 0xcb, 0x2f, + 0xb6, 0x06, 0x29, 0xe6, 0xba, 0xf5, 0xed, 0xe1, 0xdb, 0x49, 0xfa, 0xfd, 0xfe, + 0x03, 0xff, 0x07, 0xf9, 0x33, 0xc7, 0xfd, 0x1c, 0x4c, 0x93, 0x0b, 0xeb, 0xbd, + 0xda, 0xf3, 0x1a, 0xfb, 0x3d, 0x13, 0x2d, 0x3a, 0x2e, 0x3b, 0xc7, 0x9b, 0x1b, + 0xe5, 0xec, 0x0c, 0x11, 0xdf, 0xee, 0xef, 0xce, 0x20, 0x18, 0x3e, 0xe9, 0xf9, + 0x22, 0x15, 0x04, 0xfe, 0x09, 0x00, 0x10, 0xfe, 0xf1, 0x2e, 0xf6, 0xbe, 0x3c, + 0xb7, 0xd6, 0xe2, 0x08, 0x24, 0x36, 0xf3, 0x05, 0x17, 0x47, 0xdd, 0xf9, 0xf0, + 0xff, 0xf3, 0x4a, 0xea, 0xee, 0xe1, 0x03, 0x26, 0x95, 0xc4, 0x3c, 0x44, 0x2c, + 0xd3, 0xeb, 0xb8, 0x67, 0x0d, 0x25, 0x3d, 0xbc, 0x19, 0x3e, 0xfa, 0xdb, 0xd8, + 0x7f, 0x25, 0xa0, 0x28, 0x13, 0x34, 0xef, 0xd3, 0x23, 0xec, 0xbf, 0xc4, 0x09, + 0xcf, 0x3f, 0xca, 0x02, 0xf4, 0xc1, 0xde, 0xb7, 0xfd, 0xb9, 0x0e, 0xfd, 0xf8, + 0x09, 0xdd, 0xfb, 0xb3, 0xe8, 0x2d, 0x29, 0x27, 0xf3, 0xf6, 0xfc, 0xec, 0x13, + 0x08, 0xfe, 0xf1, 0x17, 0x06, 0xc5, 0x11, 0xf5, 0xf2, 0x1d, 0x25, 0xe0, 0xd6, + 0x01, 0x00, 0x1b, 0xbc, 0x05, 0x2f, 0xbf, 0x16, 0x16, 0x2e, 0xc6, 0xfa, 0xb4, + 0x5a, 0x43, 0xaa, 0xdd, 0xf2, 0xf2, 0xd6, 0xa1, 0xef, 0x0d, 0xcc, 0xca, 0xe0, + 0x57, 0xec, 0x9d, 0xd2, 0x3c, 0xd4, 0xf2, 0xc6, 0xfc, 0xbe, 0xb2, 0x11, 0xbc, + 0xdc, 0xef, 0x3b, 0xe1, 0x23, 0xc6, 0x0c, 0xd9, 0x15, 0x05, 0xf1, 0x54, 0x34, + 0xf9, 0xaa, 0xf3, 0xf4, 0x98, 0xda, 0x21, 0x22, 0xdd, 0xf7, 0x17, 0x11, 0x4b, + 0xed, 0x05, 0xf0, 0xf4, 0x41, 0xd1, 0xa8, 0x0f, 0x08, 0x1b, 0x16, 0x04, 0x9c, + 0xff, 0x18, 0xf1, 0xbe, 0x3d, 0x0b, 0xcd, 0xbf, 0xa7, 0xe2, 0x2c, 0xec, 0x0d, + 0xf5, 0xc9, 0xf3, 0x00, 0x07, 0x0b, 0xd1, 0x9f, 0x42, 0x21, 0xcf, 0xed, 0xfa, + 0xf7, 0x14, 0x0a, 0xcf, 0xc6, 0x31, 0x0e, 0xd1, 0xd0, 0x4d, 0xbb, 0xe9, 0xe0, + 0x3d, 0xd4, 0xcb, 0x21, 0xfa, 0xd9, 0x2f, 0xb4, 0xd3, 0xe5, 0x14, 0x03, 0xa4, + 0xda, 0x17, 0x18, 0x3a, 0xf1, 0xfc, 0xb6, 0x2b, 0x21, 0xde, 0x1b, 0xaf, 0xf0, + 0xe3, 0xd0, 0xdb, 0xf2, 0x15, 0xce, 0x24, 0x19, 0xc4, 0xf7, 0x0d, 0x11, 0xf7, + 0xff, 0xfa, 0xc8, 0xa5, 0x19, 0xde, 0xe8, 0xd6, 0x05, 0x0a, 0x1d, 0x12, 0xfd, + 0xed, 0xc5, 0x2a, 0xc1, 0xc6, 0xbc, 0xc8, 0x04, 0x81, 0x4c, 0x2a, 0xe9, 0xac, + 0xfa, 0x25, 0x40, 0xeb, 0xf2, 0xf4, 0xce, 0x1a, 0xd1, 0xcb, 0xee, 0xe0, 0xc3, + 0x1e, 0xd5, 0xca, 0x0d, 0xf6, 0x3b, 0x3b, 0xf5, 0x1f, 0xe2, 0x2e, 0x35, 0x3a, + 0x3c, 0xb7, 0xd6, 0x0a, 0xd3, 0xe4, 0x47, 0x13, 0x38, 0x09, 0xde, 0xd3, 0x0b, + 0x05, 0xe7, 0xe7, 0x25, 0x17, 0x27, 0x19, 0x17, 0xce, 0xf3, 0x22, 0xbd, 0xec, + 0xee, 0xca, 0x5a, 0xf8, 0xeb, 0x22, 0xeb, 0xe3, 0x34, 0xf9, 0x18, 0xcc, 0xbd, + 0x0b, 0x01, 0xfa, 0x15, 0xce, 0x08, 0x39, 0xaf, 0xe9, 0x2a, 0x22, 0x3d, 0xe7, + 0xd4, 0x23, 0xdc, 0xdd, 0x12, 0xdc, 0x28, 0xbd, 0xde, 0x09, 0xdd, 0xee, 0x52, + 0xff, 0x21, 0xc0, 0xcb, 0xd7, 0x34, 0xfa, 0xee, 0xf3, 0x2e, 0x0a, 0x1e, 0x0a, + 0xd5, 0x2b, 0xcd, 0xe6, 0x16, 0x34, 0x04, 0xf2, 0x36, 0xed, 0x1b, 0xce, 0xd2, + 0x42, 0x04, 0xd9, 0xe2, 0x71, 0xd2, 0x00, 0xf0, 0xfb, 0xd7, 0x2a, 0x40, 0x11, + 0xe0, 0x1e, 0xfe, 0x01, 0x09, 0x34, 0xb8, 0x26, 0xc1, 0xfc, 0x9d, 0x00, 0xf0, + 0xeb, 0x11, 0x04, 0xd9, 0x9b, 0x21, 0xf3, 0x02, 0xd6, 0x06, 0xeb, 0x3c, 0xea, + 0xbb, 0xfc, 0xde, 0x12, 0x0a, 0x0c, 0x62, 0xde, 0xe3, 0xe2, 0xda, 0x19, 0xfc, + 0xe0, 0xe7, 0x40, 0xe1, 0xd2, 0x8d, 0xa4, 0xf4, 0xe3, 0x02, 0xe0, 0xd1, 0x39, + 0xd0, 0x1d, 0xed, 0xca, 0xe0, 0x11, 0x87, 0xe2, 0xd1, 0xd9, 0xb5, 0xea, 0xa3, + 0x35, 0xfe, 0x12, 0xef, 0x09, 0x37, 0x33, 0xeb, 0xf5, 0xf7, 0xe2, 0xcc, 0xf5, + 0x2b, 0xc1, 0xfa, 0xd2, 0xe6, 0x02, 0xf7, 0xc8, 0xe9, 0x7f, 0xc4, 0x5f, 0x2c, + 0x0e, 0xfc, 0x2f, 0xea, 0xad, 0x1c, 0xdd, 0xf8, 0xd1, 0xfa, 0x09, 0xb0, 0xae, + 0xd9, 0xc6, 0xde, 0x04, 0xfc, 0xe4, 0x0d, 0xef, 0xce, 0x1b, 0x11, 0x21, 0xfa, + 0xca, 0x4b, 0x1e, 0x10, 0xf1, 0x1d, 0x3c, 0xbf, 0xd1, 0xe5, 0xd6, 0x0d, 0x18, + 0xdc, 0x13, 0x10, 0xee, 0x4f, 0x0b, 0x07, 0xf3, 0x08, 0xde, 0x30, 0xd4, 0x3a, + 0x4c, 0x19, 0xac, 0xfb, 0xe1, 0x2b, 0x23, 0xde, 0x1d, 0x1d, 0x27, 0x12, 0xe4, + 0x0e, 0xe8, 0x61, 0xcb, 0xa1, 0x03, 0xe6, 0x97, 0x44, 0xab, 0x07, 0xb4, 0xef, + 0xda, 0xdc, 0x0a, 0xe7, 0xec, 0xd8, 0x1e, 0xb6, 0x2f, 0xdf, 0x13, 0xcd, 0x37, + 0x03, 0x0c, 0x1e, 0xde, 0x9a, 0x0e, 0x11, 0x2b, 0xf5, 0xdd, 0xe0, 0xd2, 0x1d, + 0xbd, 0x01, 0x0e, 0xfd, 0xdc, 0xf5, 0x0a, 0xca, 0x33, 0xe1, 0x0b, 0xf1, 0xf8, + 0x2e, 0xa5, 0x1d, 0xe7, 0x4c, 0x01, 0x33, 0x18, 0x2a, 0xc9, 0xe8, 0x04, 0xd8, + 0x1f, 0xde, 0x00, 0x44, 0xbd, 0xd9, 0xc7, 0x11, 0xf0, 0xd6, 0x32, 0xcf, 0x13, + 0x9a, 0xdd, 0xd9, 0xc7, 0xf4, 0xf2, 0xbb, 0xc5, 0xf0, 0x01, 0x00, 0x81, 0xe7, + 0x27, 0xf4, 0x10, 0x08, 0x6a, 0xee, 0xb7, 0x13, 0x58, 0x5f, 0xd8, 0x16, 0xff, + 0x43, 0xe9, 0x31, 0x13, 0x51, 0xfc, 0xed, 0x01, 0x35, 0xb7, 0x02, 0x00, 0xf8, + 0xf1, 0x0f, 0x2a, 0xf7, 0xe7, 0xc8, 0xa8, 0xeb, 0xa8, 0x2c, 0x21, 0xf4, 0x2d, + 0x15, 0x41, 0x14, 0x28, 0x18, 0xf4, 0x0f, 0x21, 0xfe, 0xd7, 0x27, 0x43, 0xf2, + 0xa3, 0xe5, 0x52, 0xf4, 0xfd, 0xc4, 0x59, 0x0a, 0xbf, 0xe2, 0xcd, 0x39, 0x15, + 0x08, 0x10, 0x09, 0x97, 0x97, 0x23, 0x40, 0x28, 0x4a, 0x0e, 0xed, 0x1d, 0x32, + 0xf4, 0xc6, 0xe6, 0xae, 0xf1, 0x45, 0x4b, 0xd0, 0xfe, 0x33, 0x35, 0x1c, 0xda, + 0xaf, 0x17, 0x03, 0x37, 0x2c, 0x02, 0x1c, 0xda, 0x27, 0xf2, 0x36, 0xed, 0x2a, + 0x2a, 0x14, 0xcf, 0xee, 0x0d, 0xd7, 0x06, 0xe2, 0x05, 0x52, 0xee, 0x14, 0xe1, + 0xf3, 0xad, 0xea, 0xe3, 0xe7, 0xfd, 0xf1, 0xea, 0xeb, 0xc4, 0x1a, 0xff, 0x0e, + 0xdc, 0xce, 0xf2, 0xfd, 0xaf, 0xb1, 0xb1, 0xaf, 0x2e, 0xb9, 0x14, 0x31, 0x31, + 0xbd, 0xcb, 0xda, 0xc1, 0x37, 0xfd, 0x64, 0xe2, 0xba, 0xfb, 0x27, 0xef, 0x15, + 0xd0, 0x1d, 0xee, 0x0f, 0xc3, 0xea, 0x30, 0x31, 0xfb, 0xd5, 0x12, 0x0c, 0xf2, + 0x3a, 0x89, 0x30, 0x91, 0xc2, 0xda, 0xc1, 0x0b, 0xe1, 0x31, 0x4c, 0x30, 0xde, + 0xe8, 0x0a, 0x11, 0x0d, 0xeb, 0xef, 0x00, 0x05, 0xd9, 0xbf, 0x08, 0x39, 0x36, + 0xed, 0xbe, 0xc9, 0x1e, 0xf0, 0x3b, 0x44, 0xfa, 0xa4, 0x8f, 0xc7, 0xd1, 0xd5, + 0x0c, 0xe0, 0x14, 0xcf, 0x24, 0xcb, 0x1b, 0xf7, 0xd9, 0xdf, 0x10, 0xfa, 0xa9, + 0xa7, 0x03, 0xfd, 0xd4, 0x0b, 0xca, 0xd5, 0xe4, 0xb6, 0x23, 0xca, 0xed, 0x04, + 0xf1, 0x38, 0xf9, 0x01, 0xac, 0x4c, 0x0e, 0xd7, 0xcf, 0xad, 0xe4, 0x20, 0x0a, + 0xf8, 0xfc, 0x2f, 0xcc, 0xff, 0xdd, 0xe1, 0x81, 0x04, 0xac, 0xd6, 0xe6, 0xbd, + 0x2e, 0x47, 0xf1, 0x1f, 0x3a, 0xd0, 0x0f, 0xb9, 0x17, 0xac, 0x04, 0xcb, 0x20, + 0x32, 0x88, 0x20, 0x00, 0x34, 0xe4, 0xdc, 0xc6, 0x37, 0x0c, 0x22, 0x02, 0x1e, + 0xd6, 0xe0, 0x02, 0x06, 0xa2, 0xe9, 0xec, 0xe5, 0x03, 0xee, 0xe6, 0xca, 0x01, + 0xd1, 0xb8, 0x0d, 0x26, 0x2a, 0x12, 0xbc, 0xdb, 0xf3, 0xcb, 0xc2, 0x21, 0xcf, + 0x3c, 0xfc, 0x04, 0xc9, 0xc5, 0x13, 0xcd, 0x04, 0x2a, 0xe8, 0xee, 0xaf, 0xec, + 0x1b, 0xf9, 0xc1, 0x05, 0x33, 0x1f, 0x1f, 0x24, 0xdb, 0xb4, 0xea, 0x12, 0x54, + 0xf7, 0xee, 0x24, 0xe3, 0xe0, 0x09, 0xbe, 0xd5, 0x15, 0xdc, 0x2d, 0xea, 0x36, + 0x1e, 0xda, 0xdf, 0x21, 0x07, 0xbd, 0x31, 0xeb, 0xc3, 0xe6, 0xb1, 0xd9, 0x24, + 0xdc, 0x19, 0x0c, 0xa8, 0xff, 0x0a, 0x13, 0xf0, 0xbe, 0xea, 0xde, 0xba, 0xea, + 0x19, 0x2c, 0xe0, 0xdb, 0x48, 0x10, 0xfc, 0x05, 0x1a, 0x0f, 0xb9, 0x2c, 0x0d, + 0xd3, 0xb5, 0xea, 0xd3, 0x04, 0xdd, 0xdc, 0x1e, 0xd8, 0x19, 0xa7, 0x0b, 0xde, + 0x1a, 0xdd, 0x2d, 0xdc, 0xe8, 0x10, 0xf7, 0x19, 0xfb, 0xf6, 0xdb, 0xca, 0xd4, + 0x19, 0xe1, 0x2b, 0xd3, 0xd9, 0xe6, 0xc7, 0xf3, 0xec, 0xfa, 0x15, 0x06, 0xc2, + 0xf9, 0x0a, 0xb0, 0xf0, 0x16, 0xdd, 0xf6, 0xd7, 0x0c, 0x26, 0xfc, 0x31, 0x05, + 0x36, 0xff, 0x35, 0x07, 0x07, 0x2d, 0xef, 0x02, 0xfb, 0xa0, 0xf2, 0xea, 0x0b, + 0x20, 0x32, 0x13, 0x0f, 0x27, 0xb3, 0xf3, 0xbb, 0xe7, 0x14, 0xdc, 0x0b, 0x02, + 0x1d, 0xe2, 0xf7, 0xea, 0xff, 0xf6, 0x0f, 0xde, 0xed, 0xf3, 0x21, 0x0b, 0xee, + 0x18, 0xf3, 0x33, 0xf7, 0x25, 0xf0, 0xf8, 0xd3, 0xc5, 0xe0, 0xeb, 0xc9, 0xea, + 0xe2, 0x08, 0x10, 0xcd, 0xfc, 0xf1, 0x0e, 0x02, 0x15, 0xcd, 0xf9, 0x18, 0x14, + 0x08, 0x1f, 0x01, 0xfe, 0xcb, 0xf8, 0xed, 0xef, 0x05, 0x07, 0xf7, 0xdd, 0x07, + 0x17, 0xd0, 0x16, 0x20, 0x22, 0x06, 0x0d, 0x05, 0x7f, 0xfd, 0xdc, 0xf4, 0x18, + 0x16, 0x0c, 0xd8, 0x14, 0x05, 0x01, 0x17, 0xc5, 0xcf, 0xf1, 0xd9, 0x02, 0xed, + 0x04, 0x0d, 0x22, 0x1e, 0xf6, 0xbb, 0xfd, 0xed, 0x0a, 0xf8, 0xde, 0xde, 0xd8, + 0x34, 0xf4, 0xfc, 0xf9, 0xcc, 0xcf, 0xf2, 0xea, 0x41, 0x47, 0xd9, 0xd6, 0xe9, + 0xf5, 0xe9, 0xc9, 0x07, 0x09, 0xfc, 0xf6, 0xd6, 0x0a, 0xeb, 0xed, 0xf7, 0xf2, + 0xfc, 0xed, 0xf6, 0xfd, 0xe3, 0xf2, 0x25, 0x0d, 0xd9, 0xd7, 0xf3, 0x14, 0xe5, + 0x4d, 0x0a, 0xeb, 0xf8, 0xeb, 0x19, 0xd2, 0xbb, 0xe7, 0xcb, 0xfa, 0xf4, 0xd7, + 0xf4, 0x17, 0xb7, 0x0e, 0xe8, 0xf0, 0x13, 0xda, 0xf3, 0x0c, 0x0e, 0x0b, 0xe5, + 0xea, 0xf9, 0x0c, 0x58, 0x03, 0xfb, 0x0b, 0xf6, 0xeb, 0x0d, 0xf9, 0xde, 0x29, + 0xda, 0x18, 0xfc, 0xdb, 0xdb, 0xc8, 0x0c, 0x37, 0x1f, 0xf9, 0x14, 0x13, 0xdf, + 0x12, 0x22, 0xff, 0x17, 0xe9, 0xe1, 0xf6, 0x0d, 0x0a, 0xe5, 0xef, 0xd3, 0xd6, + 0xf2, 0xd6, 0xfb, 0xf7, 0xe1, 0x07, 0xff, 0x42, 0xdc, 0x2d, 0xb0, 0x07, 0xfb, + 0xf3, 0x12, 0x05, 0x0f, 0xdf, 0x0e, 0xdc, 0xf2, 0x00, 0xc8, 0xdf, 0x02, 0x0e, + 0x08, 0x22, 0x18, 0x13, 0x2b, 0xd9, 0x00, 0x0b, 0xc2, 0x12, 0xdf, 0xfe, 0x4a, + 0x3c, 0xcc, 0x47, 0x12, 0x20, 0xde, 0x1a, 0xca, 0xed, 0xed, 0x30, 0x0c, 0x04, + 0x38, 0x0f, 0xeb, 0x19, 0xb5, 0x20, 0x22, 0x07, 0xec, 0x09, 0xd4, 0xb4, 0xf3, + 0x11, 0xf6, 0xbb, 0xd9, 0x05, 0xf4, 0x0a, 0xed, 0x33, 0xc1, 0xe8, 0x43, 0xd4, + 0x07, 0xfc, 0xdc, 0x2e, 0x0f, 0x1d, 0x2e, 0xd2, 0xe5, 0xff, 0x1a, 0xc1, 0xea, + 0x26, 0x29, 0xb8, 0x17, 0xbe, 0x08, 0xdc, 0xe9, 0xd7, 0xeb, 0xe1, 0x31, 0xdf, + 0xef, 0x01, 0xd8, 0xa1, 0x3b, 0x20, 0x06, 0x9b, 0xf5, 0xfd, 0xee, 0x2e, 0xd7, + 0xec, 0x18, 0x25, 0x32, 0x7f, 0x0b, 0x08, 0xeb, 0xa0, 0x0d, 0xfd, 0x33, 0xfb, + 0xce, 0xdf, 0x0a, 0xf9, 0x00, 0x18, 0xd8, 0xe7, 0x25, 0xd8, 0xd5, 0x09, 0xeb, + 0x17, 0x74, 0x10, 0xed, 0x00, 0x12, 0x0c, 0xdf, 0xb9, 0x4b, 0x08, 0x16, 0xe1, + 0xf3, 0xdf, 0x1e, 0x05, 0xf9, 0xd4, 0xc7, 0xcf, 0xd9, 0xe1, 0xc5, 0xbb, 0xe0, + 0xce, 0xf5, 0x1d, 0xe5, 0x11, 0x06, 0xe1, 0x07, 0xf6, 0x26, 0xcd, 0x03, 0xc7, + 0x15, 0xd9, 0x23, 0xe8, 0xd0, 0x05, 0xf9, 0xf3, 0xc9, 0xe1, 0xe0, 0x05, 0xe6, + 0x11, 0xf3, 0xde, 0xe2, 0xfa, 0xc4, 0xfb, 0x05, 0x13, 0x01, 0x1c, 0xe9, 0x08, + 0xd8, 0xdd, 0xb9, 0x19, 0xb5, 0xea, 0xa8, 0x03, 0xde, 0xf2, 0x09, 0x45, 0x39, + 0x0f, 0xf1, 0xda, 0xe2, 0x13, 0x37, 0x16, 0xe2, 0x3f, 0xf7, 0xdf, 0x32, 0xe9, + 0x07, 0x4c, 0xeb, 0x40, 0xac, 0xe5, 0xb0, 0xfe, 0xc2, 0xe0, 0xf4, 0xd7, 0xc1, + 0x23, 0xf5, 0xdf, 0xe7, 0x0f, 0xff, 0xe3, 0x34, 0xbf, 0xd1, 0xdc, 0xfe, 0x0c, + 0xd1, 0xf0, 0xea, 0xd6, 0xbd, 0xf8, 0xc3, 0xcc, 0xc5, 0xf0, 0xf3, 0xdb, 0x03, + 0x17, 0x1d, 0x0d, 0x28, 0xe8, 0x16, 0xd3, 0x16, 0xcc, 0xf5, 0x17, 0xec, 0x36, + 0xe4, 0x2e, 0x07, 0xdc, 0xe2, 0xd3, 0x0a, 0xd7, 0x0a, 0x1f, 0xc0, 0x19, 0x16, + 0xeb, 0xd4, 0xd9, 0xfe, 0xd9, 0xd9, 0xb6, 0xf9, 0xf6, 0xdd, 0xd1, 0xe4, 0x25, + 0xc0, 0xf9, 0xda, 0x10, 0xe5, 0x25, 0x15, 0xb5, 0x1d, 0x9c, 0x10, 0x05, 0xd1, + 0xd2, 0x8d, 0xee, 0xde, 0xa7, 0xb7, 0x49, 0xe9, 0x26, 0x9c, 0x03, 0xec, 0x22, + 0xf9, 0xe3, 0x30, 0x04, 0x29, 0x10, 0xcd, 0xe2, 0xce, 0xf6, 0x18, 0xfd, 0xe5, + 0x21, 0x0b, 0x19, 0xf7, 0x19, 0xe7, 0xd1, 0xf2, 0xfc, 0xf8, 0x10, 0xbf, 0xdb, + 0x0f, 0xd7, 0x4b, 0x0c, 0x30, 0x1a, 0x49, 0xf7, 0xd0, 0xc8, 0x14, 0x2b, 0x13, + 0xa6, 0xe6, 0xf0, 0xcf, 0x09, 0x22, 0x30, 0xf5, 0x41, 0xc9, 0x06, 0xf7, 0x1f, + 0xe9, 0xf0, 0x04, 0x0d, 0xde, 0xed, 0x10, 0x1b, 0xc2, 0x29, 0xc0, 0xd3, 0x2a, + 0xcf, 0xfb, 0xc8, 0x17, 0xf9, 0xa6, 0x11, 0x06, 0xf5, 0x0d, 0xd3, 0xd1, 0xf9, + 0xc0, 0xa7, 0xe3, 0xff, 0xec, 0x15, 0xe0, 0xed, 0xba, 0xcf, 0xfe, 0xf9, 0xea, + 0x01, 0x43, 0x01, 0x08, 0xfd, 0x2a, 0xc0, 0x42, 0x15, 0xc7, 0xfb, 0xfa, 0xf7, + 0xcd, 0x24, 0xff, 0xf4, 0xc3, 0xde, 0xef, 0xe5, 0x03, 0x06, 0x15, 0xeb, 0xf5, + 0x27, 0xe3, 0xd7, 0x09, 0x10, 0x07, 0xe9, 0x1f, 0xdf, 0xdb, 0x24, 0x1f, 0xeb, + 0xcb, 0xf8, 0xc3, 0xda, 0x1f, 0x19, 0x0c, 0xe2, 0x6a, 0xce, 0xfa, 0xf9, 0xb8, + 0x18, 0xf7, 0xf7, 0xe6, 0xd0, 0x1d, 0xac, 0x2a, 0xfd, 0xf7, 0x0c, 0xf2, 0x18, + 0xb3, 0xc5, 0x33, 0xd9, 0x43, 0xfb, 0xf0, 0x46, 0xc7, 0xb7, 0x0a, 0xde, 0xf8, + 0x08, 0xed, 0x15, 0xd9, 0xd3, 0x15, 0x24, 0x34, 0x0a, 0x36, 0x03, 0xb4, 0xce, + 0x87, 0xc0, 0x7f, 0xc1, 0xec, 0xf6, 0xec, 0x16, 0x14, 0x01, 0x23, 0x00, 0xe3, + 0xcd, 0x94, 0xee, 0xe3, 0xec, 0xf9, 0x08, 0xf6, 0x0e, 0xf3, 0xec, 0x0f, 0xba, + 0xb5, 0x07, 0x08, 0xfb, 0xd1, 0xc8, 0x0d, 0xb5, 0xe7, 0xfb, 0x13, 0xb6, 0xfb, + 0x10, 0xf7, 0xbb, 0xdb, 0xdb, 0xe2, 0x09, 0x29, 0x4e, 0x36, 0x2a, 0xe4, 0xe1, + 0x27, 0xde, 0xe8, 0xdb, 0x01, 0x15, 0x03, 0xf1, 0x20, 0xef, 0xc2, 0xd8, 0xca, + 0xac, 0x0c, 0x34, 0x2d, 0xc9, 0xb3, 0xf2, 0xc4, 0x21, 0xf3, 0x04, 0x81, 0xa7, + 0xea, 0x45, 0xd3, 0x3b, 0x09, 0x28, 0xf4, 0xad, 0xf1, 0xfc, 0x13, 0xed, 0xaa, + 0xba, 0x10, 0xea, 0x37, 0x22, 0x24, 0xd3, 0xe1, 0x0d, 0xfa, 0x09, 0xec, 0x29, + 0x13, 0x10, 0x03, 0x28, 0xfa, 0x28, 0xda, 0xdb, 0xde, 0x6c, 0x60, 0xc2, 0x0a, + 0xf0, 0x37, 0x5f, 0x01, 0x00, 0xf8, 0xbe, 0xbf, 0xc6, 0x41, 0x01, 0xcd, 0xfd, + 0x3e, 0x0d, 0xfe, 0x05, 0xef, 0xed, 0x23, 0x09, 0xee, 0x45, 0xf2, 0xbe, 0x34, + 0x2d, 0x03, 0x6f, 0xb7, 0xd3, 0xf2, 0xf6, 0x01, 0xbe, 0x11, 0x0f, 0xcb, 0x38, + 0x09, 0x0c, 0xd9, 0xc3, 0x1d, 0xe3, 0xfc, 0xa9, 0xb3, 0x2a, 0xe5, 0xa6, 0xb2, + 0x2a, 0xff, 0xf3, 0x26, 0x09, 0xed, 0xb8, 0x0d, 0xa8, 0x13, 0xe5, 0xba, 0x4d, + 0x2d, 0x38, 0xf7, 0xbe, 0xc3, 0x28, 0x3a, 0x27, 0xdf, 0xe3, 0xca, 0xb2, 0x0d, + 0x05, 0xbb, 0xd9, 0xda, 0xfe, 0xb6, 0xbc, 0xaa, 0xff, 0x1c, 0xf1, 0xf3, 0x00, + 0x03, 0x1b, 0x13, 0x16, 0xe4, 0x1a, 0xf5, 0xd7, 0x2b, 0xf4, 0x28, 0x35, 0xfe, + 0xdb, 0xcd, 0xc6, 0xf7, 0xde, 0xf8, 0xd3, 0xfc, 0x07, 0x17, 0x00, 0xdf, 0x03, + 0x03, 0x17, 0xe3, 0xb0, 0x22, 0x00, 0xd2, 0xc9, 0x30, 0x18, 0x04, 0xf2, 0x0e, + 0x0e, 0x06, 0xc8, 0xe9, 0xd7, 0xe4, 0x3b, 0x06, 0x02, 0xf6, 0x1f, 0x02, 0xfd, + 0x07, 0x11, 0xc0, 0x49, 0xd8, 0xd6, 0xbb, 0x22, 0xaf, 0x51, 0xeb, 0x05, 0xaf, + 0xe0, 0xeb, 0x07, 0x14, 0x36, 0x2d, 0xaf, 0xf8, 0xf7, 0x1b, 0xec, 0xf0, 0x23, + 0xf4, 0xed, 0xdb, 0xf4, 0x0b, 0x5d, 0x0d, 0xb5, 0xcd, 0x09, 0xfb, 0xf9, 0xde, + 0x03, 0xe3, 0xf7, 0x4a, 0x5f, 0xb3, 0xda, 0x13, 0xfd, 0xbb, 0xee, 0xe6, 0x19, + 0xe7, 0x56, 0x9d, 0x30, 0xd9, 0x2e, 0x2b, 0xb6, 0xf5, 0xca, 0x30, 0x8a, 0xc4, + 0xf8, 0xfd, 0xc8, 0xf5, 0x20, 0xf5, 0x35, 0x14, 0xfa, 0x08, 0x06, 0xd7, 0xc3, + 0xfb, 0xff, 0xd3, 0xd6, 0xb8, 0x31, 0x0c, 0x46, 0x29, 0xe6, 0x07, 0xe5, 0x0d, + 0x25, 0xaa, 0xf4, 0xa7, 0x3a, 0xe9, 0xd1, 0x39, 0xcc, 0x48, 0xfc, 0x92, 0x27, + 0xa8, 0x3a, 0x32, 0xe9, 0x09, 0xc4, 0x16, 0x18, 0xea, 0xea, 0xb6, 0xa8, 0x2b, + 0x1f, 0xea, 0x01, 0x0d, 0xb8, 0xe1, 0x15, 0x59, 0xb0, 0x2d, 0xc3, 0xfd, 0x66, + 0xdc, 0x05, 0x1e, 0xd1, 0xcf, 0x26, 0xdc, 0x00, 0x42, 0x29, 0x16, 0x19, 0xc7, + 0x27, 0xe9, 0x89, 0xc5, 0x12, 0x49, 0xcc, 0x21, 0xfd, 0xef, 0xac, 0x4f, 0xeb, + 0x07, 0xf5, 0x22, 0x1a, 0x8a, 0x28, 0xac, 0x26, 0xa4, 0x2b, 0x55, 0xf3, 0x15, + 0xa8, 0xf6, 0x18, 0x3d, 0x33, 0x10, 0x0c, 0xea, 0x12, 0xca, 0xc9, 0xec, 0xa4, + 0xb9, 0xfb, 0xce, 0x31, 0x35, 0xf0, 0x02, 0x19, 0x32, 0x95, 0x09, 0xbb, 0xc4, + 0x2c, 0xf8, 0x1c, 0xd9, 0x0a, 0xcf, 0x8c, 0xf2, 0x15, 0x8d, 0xcb, 0xa3, 0x08, + 0x28, 0xdd, 0x1b, 0x08, 0xd7, 0xb1, 0x48, 0x07, 0x0b, 0xe5, 0xe8, 0xf0, 0x40, + 0x0e, 0x07, 0xec, 0xde, 0xc6, 0xce, 0xb4, 0xe6, 0x15, 0x21, 0x0b, 0xa7, 0xf6, + 0xf0, 0xf1, 0x11, 0x36, 0xda, 0x94, 0x0f, 0xeb, 0x1e, 0x54, 0xd9, 0x9d, 0xc2, + 0x0f, 0x22, 0xce, 0x00, 0xe5, 0x5a, 0x18, 0xb8, 0x01, 0x4c, 0xc6, 0xf8, 0xe5, + 0x99, 0x28, 0x04, 0xf4, 0xf4, 0x16, 0x25, 0xdd, 0x0d, 0x3e, 0xb0, 0x01, 0xfe, + 0xb6, 0xfe, 0xe7, 0x04, 0xbd, 0x26, 0xb5, 0x4b, 0xb0, 0xe9, 0xf0, 0xfe, 0x03, + 0x3d, 0xe6, 0xf3, 0x1e, 0x6e, 0x13, 0x4d, 0x4c, 0xc5, 0xb5, 0x81, 0xa0, 0xec, + 0xc0, 0xcf, 0x0b, 0x01, 0x1a, 0xcc, 0x1d, 0xac, 0x2d, 0xd1, 0x15, 0x05, 0x0a, + 0xff, 0x2b, 0xf0, 0xb9, 0xf6, 0xbf, 0x45, 0x00, 0xb5, 0x43, 0x1a, 0xd5, 0xe0, + 0x0e, 0x10, 0xe5, 0xc9, 0xed, 0xde, 0x2e, 0xd0, 0xe8, 0x2f, 0x08, 0xd4, 0xdf, + 0xc7, 0xf8, 0xf6, 0xb3, 0x22, 0xf9, 0xec, 0xe6, 0x14, 0xd8, 0x14, 0xee, 0xc1, + 0x00, 0x12, 0xe4, 0x12, 0x00, 0xec, 0xe1, 0xac, 0xcb, 0x0c, 0xd2, 0xe9, 0x11, + 0x2e, 0xd7, 0x18, 0xd1, 0x2b, 0x3a, 0x32, 0xee, 0x08, 0x00, 0xb2, 0x8a, 0x15, + 0xe6, 0xab, 0xf8, 0xfd, 0x93, 0xe3, 0xf6, 0xeb, 0xd8, 0x1f, 0xd7, 0x29, 0xfe, + 0x40, 0x57, 0xec, 0xa2, 0xe2, 0x0d, 0x0e, 0xe9, 0xf7, 0x1f, 0x92, 0xdd, 0xaf, + 0xec, 0x13, 0x10, 0xc9, 0xe6, 0x24, 0xcf, 0xeb, 0x0a, 0xfa, 0x25, 0xbc, 0xe0, + 0x8a, 0x18, 0x89, 0x05, 0xbd, 0x20, 0x13, 0xf3, 0x06, 0x19, 0xc4, 0xdd, 0xd3, + 0x2d, 0xd1, 0xd3, 0x33, 0x07, 0xf5, 0x26, 0x2a, 0x16, 0x05, 0xeb, 0x48, 0x3f, + 0x34, 0xe7, 0xff, 0xfa, 0x81, 0xdb, 0xe9, 0xf3, 0xc0, 0x25, 0x0c, 0xb5, 0xe8, + 0x00, 0x47, 0xf6, 0x42, 0xf8, 0xd7, 0xd1, 0xf7, 0xf8, 0x20, 0x07, 0x17, 0xf9, + 0x1b, 0x9e, 0xf2, 0x3a, 0xdc, 0x0e, 0x29, 0xb0, 0x1a, 0x04, 0x99, 0x43, 0x0a, + 0x07, 0xff, 0x52, 0x02, 0x14, 0x04, 0xac, 0xe7, 0xcf, 0x04, 0x07, 0xf3, 0xf4, + 0x26, 0x07, 0xe4, 0x47, 0xd6, 0xd7, 0x01, 0xd1, 0x17, 0x18, 0x37, 0xfc, 0xfc, + 0xd5, 0xf3, 0x08, 0xfc, 0x37, 0x28, 0xce, 0xfd, 0x24, 0xde, 0xf0, 0xe3, 0x1f, + 0xa0, 0xf0, 0x07, 0xfb, 0xdc, 0xfd, 0xd4, 0xf1, 0x2e, 0xe5, 0x1c, 0xd8, 0x19, + 0xe1, 0xe5, 0x5f, 0xe5, 0xc9, 0xf2, 0x25, 0xc1, 0x34, 0x42, 0xc4, 0xf1, 0xf7, + 0xe6, 0xf5, 0xcb, 0xf3, 0x2d, 0x00, 0xe6, 0xda, 0xff, 0xac, 0x37, 0xfa, 0xd7, + 0xc0, 0xf0, 0x2a, 0xd6, 0xc3, 0xdf, 0xc3, 0x30, 0xed, 0xb0, 0xff, 0xe5, 0xf9, + 0x07, 0xf3, 0xd8, 0x1c, 0x41, 0x17, 0xda, 0xf8, 0x03, 0xf0, 0x0c, 0xce, 0x14, + 0x08, 0x06, 0xf4, 0x11, 0xde, 0x14, 0xfc, 0x19, 0x28, 0xd8, 0x04, 0x4b, 0x27, + 0x21, 0xb7, 0xee, 0xdf, 0x02, 0xf7, 0x16, 0xf1, 0xd5, 0x12, 0xea, 0xf3, 0x1f, + 0x0a, 0xd0, 0x39, 0x53, 0xf6, 0xef, 0xed, 0x1a, 0x1e, 0xea, 0xd0, 0x1f, 0xd7, + 0xf9, 0xfd, 0x1b, 0xf4, 0xfb, 0x08, 0xd5, 0x1c, 0x25, 0x33, 0xd9, 0xf7, 0x16, + 0x07, 0xf5, 0x01, 0x29, 0x3e, 0x1a, 0x10, 0x05, 0xde, 0x14, 0xe2, 0xe2, 0x1f, + 0x03, 0x0b, 0xe9, 0xed, 0x0d, 0xfd, 0xf1, 0x09, 0x05, 0x06, 0xd7, 0xcb, 0xb7, + 0x00, 0xdc, 0xff, 0xde, 0x04, 0xc1, 0x2e, 0x13, 0xf0, 0x09, 0x19, 0x0c, 0x2a, + 0x1b, 0xf2, 0x26, 0xbc, 0xe5, 0x31, 0xc5, 0x00, 0xb8, 0xfa, 0x2b, 0xf1, 0xfb, + 0xda, 0xfd, 0xc5, 0x22, 0x12, 0x03, 0xf9, 0x20, 0xd2, 0xf2, 0x3b, 0xad, 0x16, + 0xe4, 0xed, 0xee, 0x24, 0xfb, 0x0d, 0xe9, 0x04, 0x0f, 0xd4, 0xfa, 0xf0, 0xe9, + 0xe9, 0xf7, 0xf9, 0xfd, 0xdf, 0x7f, 0x0c, 0x0b, 0x0a, 0xdf, 0xdc, 0x01, 0xfa, + 0xef, 0xf6, 0x08, 0xd7, 0x42, 0x10, 0xf6, 0x6a, 0x12, 0xf9, 0xef, 0xf3, 0x0f, + 0x01, 0xe5, 0xe8, 0x0a, 0x08, 0xd8, 0xb0, 0x23, 0xd9, 0xdd, 0x03, 0xee, 0xf1, + 0xed, 0xe1, 0x24, 0x52, 0xf3, 0x7d, 0x20, 0xe8, 0x9e, 0xe7, 0x07, 0xed, 0x73, + 0xe9, 0x1e, 0x0a, 0x08, 0xe1, 0xf3, 0x17, 0xe1, 0x07, 0xf9, 0xdd, 0xff, 0x17, + 0x0e, 0xd6, 0xf4, 0xfd, 0xf9, 0xed, 0xbb, 0xd0, 0xf7, 0xcd, 0xea, 0xdb, 0xe9, + 0x19, 0xcf, 0xbd, 0x35, 0x13, 0x07, 0x27, 0x2b, 0x03, 0xca, 0x0c, 0xfb, 0xc7, + 0x01, 0x07, 0x02, 0x24, 0x27, 0x1e, 0x22, 0x38, 0xf2, 0x1c, 0x2b, 0xa3, 0xc8, + 0x14, 0xfe, 0xfa, 0x01, 0xec, 0xde, 0xff, 0xeb, 0xda, 0xca, 0xdd, 0x25, 0xd1, + 0xb0, 0xf7, 0x14, 0xd1, 0x94, 0xba, 0x3d, 0xb9, 0x1c, 0xcc, 0xbe, 0x2d, 0xfb, + 0x2f, 0x08, 0xff, 0xee, 0xaf, 0x97, 0xfd, 0xa5, 0x10, 0x48, 0x25, 0x37, 0xd8, + 0x2d, 0xff, 0xc9, 0xff, 0xf1, 0x4c, 0xf1, 0x8f, 0xf0, 0xcb, 0xc3, 0x81, 0xf9, + 0x1e, 0x49, 0x33, 0x13, 0x14, 0xf1, 0xa2, 0x5e, 0xf7, 0x3a, 0xf9, 0xdc, 0xe9, + 0x0e, 0x49, 0x6f, 0xed, 0xd0, 0xe4, 0x0a, 0xb5, 0xde, 0xd6, 0xd4, 0xe7, 0xc4, + 0xf4, 0xee, 0x08, 0xee, 0x05, 0xe8, 0xb7, 0x5c, 0x9e, 0x3b, 0xbe, 0xcd, 0x31, + 0xdf, 0x42, 0x1a, 0xfb, 0xed, 0xe5, 0xda, 0xf6, 0xab, 0xc9, 0xe3, 0xbc, 0x13, + 0xf3, 0xc8, 0xed, 0x28, 0x2a, 0xc4, 0xeb, 0xe3, 0xc4, 0xf4, 0x2a, 0x22, 0x0b, + 0x13, 0xd5, 0xcc, 0xf5, 0xb1, 0x33, 0x10, 0xee, 0xb5, 0xc4, 0xdd, 0x02, 0xcf, + 0x1e, 0xc4, 0xc7, 0xe7, 0x15, 0xa1, 0x37, 0xcf, 0x01, 0x94, 0xa6, 0xdc, 0x28, + 0xec, 0x02, 0x3e, 0x09, 0x0c, 0xae, 0x0a, 0x40, 0x03, 0x32, 0xd2, 0x8f, 0xcb, + 0x99, 0xc8, 0x3d, 0xe7, 0xec, 0x36, 0xb6, 0xf0, 0xf8, 0xcc, 0xae, 0x0e, 0xec, + 0x0b, 0xed, 0x32, 0xe3, 0x0a, 0xb7, 0xc8, 0xba, 0x45, 0x30, 0x03, 0xc5, 0x1c, + 0xf9, 0x42, 0xbf, 0x44, 0x50, 0x28, 0x0a, 0xd4, 0x9f, 0xb0, 0xe6, 0x17, 0x04, + 0x06, 0x06, 0x32, 0xc8, 0x14, 0x46, 0xe2, 0x25, 0xee, 0x95, 0xeb, 0xe2, 0xe0, + 0x06, 0xf1, 0x09, 0xf6, 0xdf, 0x12, 0x1d, 0xd8, 0xbd, 0x16, 0x35, 0xc3, 0x3f, + 0x10, 0x12, 0xc5, 0xe0, 0xeb, 0x11, 0xfc, 0x20, 0xb1, 0xc6, 0xb6, 0xdd, 0xfd, + 0x34, 0x11, 0x11, 0x22, 0x1b, 0xe8, 0xdc, 0x0d, 0xdc, 0x45, 0xe4, 0xbb, 0x1e, + 0xfe, 0xeb, 0xed, 0xfb, 0x3a, 0x1a, 0x25, 0xa9, 0xfb, 0x66, 0xc6, 0xec, 0xba, + 0xcb, 0xc9, 0x28, 0x08, 0xc5, 0x21, 0xb8, 0x2f, 0x06, 0xb7, 0x16, 0xd5, 0xb3, + 0xce, 0xad, 0xc5, 0xa9, 0xbe, 0x9e, 0x9b, 0x0c, 0x39, 0x20, 0xe8, 0xcf, 0xc8, + 0xd9, 0xf0, 0x26, 0xb6, 0xc9, 0xf3, 0xf2, 0xdc, 0xec, 0xca, 0x1f, 0xf2, 0x13, + 0xaa, 0x32, 0x11, 0xf7, 0xd1, 0xb6, 0x10, 0xa5, 0xf4, 0xf6, 0x3e, 0x0c, 0xed, + 0xd6, 0xe8, 0x92, 0xf9, 0xfa, 0x1d, 0x56, 0xbe, 0xf1, 0xc6, 0x12, 0xe9, 0xf1, + 0x21, 0xcd, 0x07, 0xa3, 0xe0, 0xd5, 0x07, 0xe9, 0xfd, 0xc5, 0x2d, 0xfb, 0xa3, + 0xe5, 0xdd, 0xd0, 0x15, 0xdc, 0x10, 0x0f, 0x81, 0x13, 0xcb, 0x31, 0xa5, 0x1d, + 0xee, 0xbc, 0xb7, 0xeb, 0xd1, 0xb4, 0xcd, 0xcc, 0x9d, 0xe8, 0xf3, 0xf5, 0x2a, + 0x30, 0xe7, 0xdc, 0xe2, 0xcc, 0xef, 0x10, 0x11, 0xba, 0x08, 0xd6, 0xd2, 0xd1, + 0x9d, 0x1f, 0x1f, 0xdc, 0xe1, 0xf4, 0xb0, 0x0d, 0xf1, 0x99, 0x9c, 0x24, 0xfb, + 0x0a, 0xdc, 0xee, 0xa9, 0xd5, 0xd8, 0xcd, 0xf4, 0x19, 0xef, 0x1e, 0x2d, 0x17, + 0xed, 0xe7, 0xf1, 0x36, 0x55, 0x22, 0xba, 0xa3, 0xe1, 0xc3, 0xda, 0xfc, 0xbb, + 0x07, 0xe3, 0xa1, 0xed, 0xc3, 0xfb, 0xe2, 0xe6, 0xff, 0xa0, 0xef, 0x02, 0xb2, + 0xd9, 0xee, 0x60, 0x15, 0x39, 0x15, 0xec, 0xfc, 0xfd, 0x2e, 0xf4, 0xa9, 0x10, + 0xf0, 0x18, 0x17, 0xa3, 0xce, 0xe1, 0xdf, 0xc0, 0xaa, 0x2c, 0x52, 0xb3, 0xf4, + 0xeb, 0x44, 0x8e, 0x17, 0xa8, 0xed, 0xef, 0x06, 0xd6, 0xe8, 0x3f, 0xd0, 0xf2, + 0xb4, 0xc9, 0xe2, 0xab, 0x03, 0x25, 0x39, 0x07, 0x35, 0xe0, 0xa3, 0xdf, 0xba, + 0x04, 0x59, 0xb2, 0xc4, 0x9a, 0x06, 0x14, 0xde, 0xf2, 0x4d, 0xf3, 0x43, 0x01, + 0xcc, 0xaa, 0x3a, 0x11, 0x43, 0xa9, 0xb0, 0x35, 0x26, 0xfc, 0xf6, 0x92, 0x0b, + 0x2a, 0x19, 0xde, 0x0d, 0xd2, 0xea, 0xf0, 0xfd, 0x09, 0xd2, 0x6c, 0xb6, 0xb9, + 0x09, 0x9b, 0xee, 0x15, 0xdf, 0x81, 0x37, 0x1a, 0xf8, 0x44, 0x16, 0xf3, 0x35, + 0xc9, 0xdf, 0xe9, 0x1a, 0x17, 0x1a, 0x2c, 0x27, 0xa9, 0x27, 0x10, 0x03, 0xd1, + 0x2f, 0x1c, 0x99, 0xe1, 0x03, 0x08, 0xcb, 0xbc, 0xef, 0x05, 0xf9, 0xac, 0x9a, + 0x19, 0xac, 0x36, 0x99, 0x3c, 0xf9, 0xbc, 0xec, 0xd2, 0x09, 0x45, 0xc0, 0x09, + 0x59, 0xbf, 0xf9, 0xcc, 0xde, 0xd4, 0x27, 0x3f, 0xd0, 0xe5, 0x15, 0xcb, 0xca, + 0x00, 0xd3, 0xed, 0x16, 0x2f, 0x28, 0xe8, 0x50, 0xbf, 0x94, 0xc9, 0xb9, 0xc0, + 0x92, 0x8a, 0xdb, 0x3e, 0xbe, 0xf3, 0x07, 0xf7, 0x16, 0x96, 0x09, 0x29, 0xe8, + 0xca, 0x54, 0x26, 0xf4, 0x08, 0x18, 0x2c, 0x08, 0x01, 0xef, 0xcf, 0x5b, 0x41, + 0x18, 0x22, 0x3a, 0xf8, 0xc2, 0xc7, 0x0d, 0x07, 0x17, 0x1d, 0x57, 0x9d, 0xfb, + 0xb3, 0xdf, 0x8d, 0xfb, 0x01, 0xf7, 0xf6, 0xb9, 0x31, 0xf3, 0xf6, 0x1f, 0x42, + 0x04, 0x93, 0xb8, 0xd5, 0xfe, 0x9e, 0x02, 0xc4, 0x4d, 0x47, 0x27, 0xc5, 0xfa, + 0x5a, 0x2b, 0xa8, 0x9e, 0x18, 0xf0, 0xe1, 0x20, 0x03, 0x9c, 0x1d, 0xb4, 0xa8, + 0x2a, 0xce, 0xac, 0xe2, 0xdf, 0x05, 0xc3, 0x52, 0xec, 0x46, 0xe0, 0xc7, 0x5e, + 0xd4, 0x16, 0xd7, 0x61, 0xdc, 0x0d, 0x0b, 0x2b, 0xf9, 0xa1, 0xa1, 0x2a, 0x21, + 0x03, 0x13, 0xc9, 0x05, 0x3c, 0xfa, 0xd1, 0x05, 0x35, 0x11, 0x4f, 0xf1, 0x1c, + 0xf1, 0xee, 0x10, 0xe0, 0xd9, 0xa9, 0xda, 0x0d, 0xa3, 0x08, 0x07, 0x1a, 0x3b, + 0x50, 0xd6, 0x8c, 0x51, 0x30, 0xe3, 0xf8, 0x32, 0xc9, 0xfc, 0x02, 0xbe, 0x1d, + 0x4e, 0xd0, 0x5b, 0x05, 0xf5, 0xfd, 0x0a, 0xfd, 0xec, 0xdc, 0x37, 0xe4, 0x1f, + 0xda, 0x3a, 0x32, 0xbd, 0xa6, 0xd1, 0x02, 0xe8, 0x82, 0xd9, 0xfd, 0xe7, 0x56, + 0x02, 0x1b, 0xbf, 0x7c, 0xc5, 0xba, 0xfb, 0xde, 0x1c, 0x1e, 0x03, 0x36, 0x58, + 0x21, 0x86, 0xef, 0x31, 0xf4, 0xdb, 0xef, 0xb1, 0xcc, 0xec, 0xd9, 0xde, 0xf6, + 0x21, 0x00, 0x31, 0xd7, 0xf4, 0x89, 0x0a, 0xe7, 0x23, 0xea, 0xc3, 0x26, 0xbf, + 0x06, 0xfa, 0x01, 0x96, 0xe2, 0x19, 0xba, 0x3a, 0x23, 0xb4, 0xc1, 0x19, 0xb6, + 0xb1, 0x00, 0x45, 0x5a, 0x4a, 0xe5, 0xf0, 0x93, 0xe0, 0xd8, 0xff, 0x30, 0xd6, + 0x17, 0x01, 0xe0, 0xe0, 0xd7, 0x24, 0xab, 0x89, 0xa9, 0xbc, 0xf5, 0x11, 0x07, + 0xca, 0xd2, 0xb1, 0xb0, 0xbd, 0x52, 0x21, 0xd2, 0xfb, 0xa0, 0xd2, 0xce, 0xd3, + 0x09, 0xdf, 0xc9, 0x9b, 0x10, 0xde, 0x3a, 0x23, 0xcd, 0xf4, 0xcd, 0xe6, 0x11, + 0xce, 0xd8, 0x1a, 0xa2, 0x19, 0x18, 0xb9, 0x0c, 0xc3, 0xe9, 0xf8, 0x18, 0xf3, + 0xd8, 0xe4, 0xce, 0xb4, 0x12, 0xd9, 0x3c, 0xb1, 0xc6, 0xef, 0x02, 0xe9, 0x74, + 0x15, 0xe3, 0xda, 0x35, 0xc8, 0x2e, 0xea, 0xad, 0xae, 0xe9, 0xc5, 0xd6, 0xda, + 0xee, 0xb9, 0x04, 0x39, 0xc2, 0x1a, 0x25, 0x15, 0xf1, 0x57, 0x31, 0x9e, 0x84, + 0xee, 0xb3, 0x81, 0x31, 0xf2, 0xf4, 0xdc, 0x28, 0xf6, 0xd3, 0xe9, 0xf8, 0x15, + 0xf7, 0xcb, 0x06, 0x87, 0xe6, 0xb7, 0xd5, 0x64, 0xeb, 0xfd, 0xbf, 0xb1, 0xd4, + 0xdb, 0x46, 0x1c, 0xe6, 0x38, 0xc6, 0x52, 0x2e, 0xe1, 0xdb, 0x92, 0xef, 0xe9, + 0xea, 0xe7, 0xe0, 0xcb, 0x4b, 0x3d, 0x4c, 0xa0, 0xc0, 0xa1, 0x16, 0x31, 0xe4, + 0xc6, 0xef, 0x00, 0xa6, 0xce, 0x1f, 0xf0, 0x18, 0x9b, 0xd4, 0xf7, 0xf5, 0xf6, + 0x49, 0xae, 0xd7, 0x3d, 0xa3, 0x46, 0x5c, 0x3e, 0x6f, 0x9d, 0xd0, 0x24, 0x5b, + 0xc3, 0x9d, 0xec, 0xf6, 0x08, 0x86, 0xc5, 0xee, 0xc2, 0x0a, 0xf7, 0xf6, 0xdf, + 0xfd, 0xdd, 0xfb, 0x14, 0xb5, 0x22, 0xbd, 0xf6, 0xd3, 0xe9, 0xc3, 0xe8, 0x10, + 0x04, 0x0d, 0x11, 0xf2, 0x1c, 0xde, 0x17, 0xe0, 0x23, 0x08, 0xdf, 0xf7, 0x07, + 0xe0, 0xee, 0x21, 0xda, 0x2b, 0x0b, 0xe2, 0xee, 0x08, 0xfc, 0x28, 0xd0, 0x2b, + 0xfd, 0x07, 0x28, 0x03, 0x07, 0xeb, 0xf7, 0x05, 0x0f, 0x15, 0x21, 0xf9, 0xcb, + 0x46, 0xcf, 0x17, 0xd4, 0xe5, 0xcb, 0xfa, 0x30, 0x1c, 0xf0, 0x01, 0x02, 0xd0, + 0x20, 0xd7, 0xe2, 0x31, 0xe5, 0xeb, 0x2b, 0xf2, 0xf8, 0x27, 0x21, 0x1d, 0xf5, + 0x1c, 0x0e, 0x13, 0x08, 0x30, 0xcc, 0xe6, 0xcf, 0x16, 0xbd, 0xd3, 0xef, 0xfe, + 0x03, 0xe7, 0x7f, 0xdc, 0xf3, 0xd9, 0x1d, 0xd2, 0x2f, 0xf9, 0xde, 0x17, 0x26, + 0xd2, 0xed, 0x7e, 0xff, 0xcf, 0xd7, 0xf2, 0x2b, 0x38, 0x02, 0x34, 0x14, 0x18, + 0xbc, 0x3d, 0xda, 0xe2, 0xee, 0xda, 0xf8, 0xfd, 0xbf, 0xed, 0x0d, 0xf9, 0x19, + 0xe5, 0x01, 0x3a, 0x10, 0xbd, 0xda, 0xfe, 0xf2, 0x0e, 0x0d, 0xce, 0xf9, 0xc9, + 0x1e, 0xcf, 0xd4, 0xfd, 0xee, 0x65, 0xf8, 0x01, 0x40, 0x15, 0xe7, 0x52, 0xe7, + 0xe8, 0xe3, 0xef, 0x18, 0x13, 0xd1, 0xf1, 0xd2, 0xec, 0x18, 0xe9, 0x03, 0x0d, + 0x23, 0xf8, 0xf8, 0xe1, 0x3e, 0x12, 0xbb, 0xe5, 0xf9, 0x0b, 0x38, 0x2c, 0xf1, + 0xf7, 0x09, 0x27, 0xe7, 0x22, 0x01, 0xe2, 0xc7, 0xf9, 0xe0, 0xec, 0xfb, 0xf5, + 0x02, 0x02, 0xe2, 0xd1, 0x00, 0xf7, 0x22, 0xf0, 0x05, 0x00, 0x3c, 0x2a, 0xdb, + 0x43, 0x07, 0x48, 0x05, 0x0b, 0xd8, 0x37, 0x0d, 0x1c, 0xbe, 0x3f, 0x55, 0xf5, + 0x05, 0x31, 0xc5, 0xca, 0x03, 0x02, 0xcf, 0xf0, 0x15, 0x01, 0x20, 0x26, 0x0e, + 0x00, 0xd0, 0xc1, 0xcd, 0xf2, 0x09, 0xf8, 0xfa, 0x15, 0xf4, 0x0b, 0xd3, 0xed, + 0xd7, 0xd9, 0x0f, 0xf5, 0xde, 0xfb, 0xe7, 0xeb, 0x1d, 0x27, 0x30, 0x03, 0xd2, + 0xd9, 0xf7, 0x00, 0x11, 0x20, 0xf4, 0x26, 0xa6, 0x2d, 0xc0, 0xed, 0xf5, 0xb9, + 0x06, 0x19, 0x04, 0xc1, 0xfd, 0xce, 0x23, 0xcd, 0x27, 0x13, 0xaf, 0xd2, 0xda, + 0xe9, 0xdc, 0x17, 0x1b, 0x10, 0x38, 0x24, 0xcf, 0x42, 0xcf, 0xf6, 0x0d, 0x22, + 0xf7, 0x0a, 0xfa, 0xc1, 0x1d, 0xbf, 0x20, 0xaa, 0xe1, 0x1b, 0xc9, 0xd9, 0xbf, + 0xe0, 0xc0, 0xbb, 0x37, 0x2a, 0xcf, 0xf4, 0x0a, 0x33, 0xe5, 0x0d, 0xe7, 0x13, + 0x11, 0x1a, 0xf3, 0x13, 0xe8, 0xfc, 0x4a, 0xe8, 0x07, 0xf8, 0x3c, 0xbc, 0x04, + 0x73, 0xc6, 0xb6, 0x17, 0xf8, 0x95, 0xba, 0x02, 0x63, 0x3f, 0xf3, 0x48, 0x0f, + 0xcc, 0x23, 0x53, 0xf4, 0xe0, 0xaf, 0x0d, 0x2a, 0x3b, 0xd8, 0xd9, 0x7f, 0x29, + 0xdd, 0xe2, 0x28, 0x36, 0xea, 0x1d, 0xd3, 0xfc, 0xf9, 0xf1, 0x11, 0xea, 0xba, + 0x13, 0x4b, 0xef, 0xd1, 0x85, 0xe5, 0x09, 0x29, 0x04, 0x04, 0x1f, 0x41, 0xe6, + 0xf3, 0xf1, 0xc8, 0xd0, 0xfd, 0xce, 0x1e, 0xda, 0xfd, 0x09, 0xcf, 0xea, 0xf4, + 0xea, 0x16, 0xf5, 0xf9, 0xe4, 0x18, 0x1a, 0x02, 0x26, 0xef, 0x14, 0xf8, 0xd0, + 0xec, 0xc7, 0xd5, 0xb9, 0x08, 0x28, 0x5f, 0xed, 0x13, 0x2e, 0x92, 0xc1, 0xd9, + 0xbf, 0x02, 0x01, 0xf0, 0xe7, 0xfc, 0xab, 0x2b, 0xef, 0xfb, 0x03, 0xfd, 0xbe, + 0xe8, 0xff, 0xe3, 0x1c, 0xe0, 0xe2, 0xdc, 0x09, 0xf0, 0x60, 0xe1, 0xcc, 0x1a, + 0x43, 0x0e, 0xe8, 0xc6, 0x1f, 0xf5, 0x06, 0x28, 0xc6, 0x2c, 0x46, 0x5a, 0x0d, + 0xeb, 0x24, 0xfc, 0xcc, 0x0a, 0xd6, 0x19, 0x25, 0x4a, 0xd4, 0x1c, 0xf9, 0xf3, + 0xfa, 0x02, 0xd6, 0x0c, 0xe5, 0x2d, 0xf8, 0x22, 0xf9, 0xd4, 0xdb, 0xe3, 0x06, + 0xd6, 0x2b, 0xf3, 0xc8, 0x65, 0x22, 0x09, 0xc2, 0xb5, 0xd2, 0x35, 0xa1, 0xfd, + 0x19, 0x33, 0xe0, 0x56, 0xbd, 0x29, 0xe1, 0xe3, 0xb2, 0xdb, 0x25, 0xff, 0xe6, + 0xbc, 0xc5, 0xdc, 0xc8, 0xf1, 0xf1, 0x19, 0xea, 0xc5, 0xcd, 0xa8, 0xdc, 0xe2, + 0xeb, 0x0e, 0x44, 0x2c, 0xbe, 0xe9, 0x11, 0xf7, 0xba, 0x0a, 0x45, 0xe9, 0xe6, + 0x0a, 0x1c, 0xac, 0x10, 0xec, 0x23, 0x05, 0xd9, 0xd1, 0x13, 0x3b, 0xfe, 0xe5, + 0xe3, 0x05, 0xfe, 0xeb, 0xb3, 0xff, 0xd0, 0x16, 0xf9, 0xf6, 0x2c, 0x00, 0xfe, + 0xf3, 0x07, 0xca, 0x47, 0x0a, 0xda, 0xc1, 0xcd, 0x30, 0xf4, 0xf9, 0xfc, 0x00, + 0xa0, 0x26, 0x13, 0xda, 0xcb, 0x17, 0xb2, 0xee, 0x9a, 0xc4, 0xd3, 0x09, 0x45, + 0xc4, 0xab, 0xb2, 0x11, 0xf0, 0xee, 0x04, 0xfe, 0x21, 0xf2, 0x17, 0x36, 0x15, + 0xf3, 0x22, 0x0a, 0xe1, 0x0c, 0xea, 0xc0, 0xf0, 0xd7, 0x29, 0xee, 0xef, 0x18, + 0x0a, 0x92, 0x2e, 0xff, 0x0d, 0xf8, 0x14, 0xc1, 0x20, 0x99, 0xc0, 0xd9, 0xe8, + 0x04, 0xb2, 0xd4, 0x2e, 0x04, 0xcb, 0x09, 0x02, 0x1f, 0xdf, 0xc7, 0xf2, 0x1b, + 0x2d, 0x56, 0x16, 0xf5, 0x07, 0xf1, 0x2f, 0xea, 0xf3, 0xf7, 0x13, 0xb7, 0x1d, + 0x23, 0xdc, 0x38, 0xcb, 0xe5, 0xfb, 0x2a, 0x30, 0x32, 0x35, 0xe4, 0x20, 0x10, + 0xa7, 0x21, 0x0d, 0x02, 0xf1, 0x0c, 0xd2, 0x22, 0x0e, 0x02, 0x43, 0xea, 0xed, + 0xd1, 0xec, 0x7f, 0x00, 0xcd, 0x08, 0xef, 0x30, 0x04, 0xcd, 0xdb, 0xd5, 0x20, + 0x07, 0xdb, 0x00, 0xdf, 0x2e, 0xe6, 0xfb, 0xc3, 0xf7, 0xa6, 0xf4, 0x25, 0x24, + 0x17, 0x08, 0x50, 0x32, 0xe7, 0xfc, 0x15, 0x2b, 0xf8, 0x05, 0xc5, 0xb0, 0xd6, + 0xf0, 0xfe, 0x0d, 0xcb, 0xc2, 0xda, 0xef, 0xb8, 0x29, 0x15, 0x43, 0xc5, 0x21, + 0x20, 0x07, 0x04, 0xbe, 0xc4, 0x29, 0xc0, 0xd6, 0xac, 0xd6, 0xdc, 0x03, 0xe0, + 0xcc, 0xc0, 0xf7, 0xd0, 0x19, 0xc2, 0xd4, 0xc6, 0x2d, 0xee, 0xda, 0xd6, 0xa4, + 0xeb, 0xa2, 0xf3, 0x11, 0xa3, 0xf9, 0xc4, 0x3c, 0x3c, 0x0f, 0xc8, 0xcf, 0xe0, + 0x18, 0xe0, 0x33, 0xe5, 0xc8, 0xea, 0xf0, 0x16, 0xff, 0xd7, 0x0c, 0x1d, 0x11, + 0xf6, 0x12, 0x13, 0xf4, 0xf6, 0xac, 0xf8, 0xe7, 0x01, 0xd7, 0xf3, 0xfd, 0xdb, + 0xf8, 0xf5, 0xde, 0xd9, 0xd0, 0xfb, 0xfc, 0xf1, 0x2e, 0x02, 0x2c, 0xeb, 0xc7, + 0x0c, 0x0e, 0xfc, 0xda, 0x26, 0xd5, 0xf0, 0xd4, 0x14, 0xb9, 0x0d, 0xe6, 0x2a, + 0x03, 0xfa, 0x06, 0xd8, 0x7f, 0xff, 0xc7, 0x12, 0x21, 0xdc, 0x27, 0xe5, 0xeb, + 0x3e, 0xcb, 0x16, 0xd8, 0xd7, 0x33, 0xec, 0x1a, 0xf6, 0xec, 0xf3, 0x29, 0xd9, + 0xd2, 0xea, 0x16, 0xc0, 0x26, 0xf1, 0xdf, 0x0c, 0xdd, 0x41, 0xf2, 0xc8, 0xcd, + 0x09, 0xd6, 0x0f, 0xfb, 0x36, 0x1b, 0xeb, 0x02, 0x2f, 0xb7, 0x1a, 0xdb, 0xdc, + 0x2b, 0xfe, 0xdb, 0xe8, 0xd1, 0xca, 0x16, 0xff, 0x18, 0xf4, 0xf5, 0xd1, 0xdc, + 0xf8, 0xed, 0xda, 0x34, 0x02, 0xe9, 0x15, 0x1c, 0xc3, 0x16, 0x2c, 0x0f, 0xbd, + 0x13, 0x06, 0xfa, 0xe2, 0xda, 0xa4, 0xed, 0x18, 0xe4, 0xf6, 0xfb, 0xd6, 0x18, + 0x16, 0x02, 0xf9, 0xcb, 0xca, 0xf9, 0xfe, 0xf7, 0xe9, 0xd3, 0xe7, 0x3a, 0xe8, + 0xda, 0xf6, 0xf5, 0xe9, 0xdd, 0x32, 0xe0, 0xee, 0x2b, 0x1f, 0xea, 0xff, 0x1e, + 0xdb, 0xda, 0x09, 0x15, 0x2d, 0x0f, 0x0b, 0xfe, 0xf8, 0x1d, 0x07, 0x05, 0xf6, + 0x1b, 0xef, 0xbf, 0x22, 0x11, 0xd7, 0xee, 0xed, 0x0f, 0xb6, 0xdc, 0xfb, 0x33, + 0xea, 0x02, 0xe3, 0x16, 0xc6, 0x24, 0x02, 0xfa, 0x12, 0xfd, 0xc1, 0xf7, 0x1a, + 0xf6, 0xfb, 0xd3, 0x09, 0x25, 0xd9, 0x2f, 0xe8, 0xf9, 0x0a, 0xf0, 0xf6, 0x31, + 0x3d, 0x22, 0x31, 0xef, 0xdd, 0x12, 0x09, 0x02, 0xf5, 0xfd, 0xde, 0x11, 0x23, + 0x2c, 0x0d, 0xb9, 0x06, 0xf8, 0xe9, 0x1b, 0xe5, 0x04, 0x1b, 0xe7, 0x0f, 0xe4, + 0x06, 0xf9, 0x2e, 0x19, 0xd6, 0x20, 0x1c, 0xb9, 0xf7, 0xc0, 0x08, 0xe2, 0xdb, + 0xf6, 0x00, 0xed, 0xf9, 0x34, 0xec, 0xe7, 0xc5, 0x2c, 0x0d, 0x1d, 0xb8, 0xdc, + 0x19, 0xd3, 0x30, 0x08, 0x3a, 0xf4, 0x12, 0xd3, 0x12, 0x03, 0xdc, 0xb1, 0x06, + 0x18, 0x3a, 0x1f, 0xc5, 0xea, 0x19, 0xf1, 0xea, 0xfe, 0xef, 0xd1, 0xcf, 0x22, + 0xe8, 0x24, 0x28, 0xc9, 0x40, 0x02, 0x1e, 0x0f, 0xcb, 0x0c, 0x28, 0x35, 0xca, + 0xad, 0xe5, 0x35, 0x0d, 0x1b, 0xe6, 0x0c, 0x11, 0xe0, 0x28, 0x35, 0x13, 0x09, + 0xdd, 0x05, 0x3e, 0xf9, 0x0c, 0xd9, 0xdc, 0x0a, 0xb2, 0x11, 0xc7, 0xf7, 0x28, + 0xd4, 0xdc, 0xed, 0xd3, 0x18, 0xed, 0x14, 0x39, 0x0c, 0x1f, 0xfc, 0xf0, 0x1d, + 0xf5, 0xa4, 0x3a, 0x37, 0x3e, 0x26, 0xd4, 0x28, 0xe6, 0xdf, 0x5f, 0x15, 0x11, + 0xf5, 0x20, 0x0d, 0xf1, 0x01, 0x05, 0x03, 0x19, 0x1e, 0x06, 0x48, 0xef, 0xe4, + 0x21, 0xde, 0xfe, 0xdc, 0xe4, 0xc2, 0x0d, 0xd7, 0xe1, 0x0c, 0xca, 0x13, 0x2d, + 0x0d, 0xf1, 0xed, 0xba, 0xe6, 0xae, 0xf5, 0x29, 0x00, 0xcc, 0xfa, 0x07, 0x46, + 0x15, 0xd8, 0xd0, 0xd9, 0xec, 0xe4, 0xca, 0xde, 0xf9, 0xd1, 0xef, 0xc9, 0xe2, + 0x0e, 0xd2, 0xfe, 0x04, 0x1a, 0x18, 0xf3, 0x2e, 0xfa, 0x15, 0x67, 0xfd, 0xc3, + 0xf4, 0xc7, 0xec, 0xdd, 0x19, 0x0c, 0xd9, 0xfd, 0xd6, 0xd8, 0x45, 0xe3, 0xe1, + 0xed, 0xe6, 0xf7, 0xd9, 0xda, 0xea, 0x1c, 0x41, 0x13, 0x25, 0x0e, 0x02, 0xfa, + 0xc3, 0xde, 0x68, 0x00, 0xfa, 0x01, 0x1e, 0xc5, 0xf9, 0x14, 0x11, 0xda, 0xf5, + 0xec, 0xf9, 0xc8, 0xf7, 0xf4, 0xd4, 0x18, 0xf3, 0xd8, 0xe8, 0x0e, 0x0e, 0x02, + 0xea, 0x07, 0x3d, 0xb8, 0x2f, 0xd5, 0xfd, 0xe3, 0xf4, 0x66, 0x28, 0xfa, 0x20, + 0x03, 0x1f, 0xf1, 0xd4, 0xcc, 0xd4, 0x13, 0xd5, 0x7f, 0x0a, 0xee, 0x02, 0x18, + 0x2c, 0x00, 0xea, 0x3e, 0x18, 0x09, 0xf6, 0x06, 0x46, 0xfe, 0xed, 0xb6, 0xff, + 0xec, 0xe5, 0xc6, 0x26, 0x07, 0x1f, 0xff, 0xfe, 0x04, 0x21, 0x0a, 0x01, 0xe7, + 0xc5, 0xf5, 0x2d, 0xe8, 0x1a, 0x1e, 0xe6, 0xd7, 0xfa, 0xe5, 0xee, 0x01, 0x1e, + 0xbd, 0x15, 0x08, 0x4d, 0xdd, 0x01, 0x0d, 0x17, 0xbf, 0x0b, 0xe5, 0x1a, 0xbb, + 0xc3, 0xb7, 0xd6, 0x0e, 0xf1, 0xed, 0x15, 0x39, 0x21, 0x2b, 0x27, 0x0e, 0x04, + 0xd5, 0xe0, 0xf8, 0xeb, 0xb0, 0xd5, 0xde, 0x10, 0x08, 0xcb, 0xf7, 0x15, 0xe5, + 0x1c, 0xa3, 0xdb, 0x31, 0xcb, 0xdb, 0x4e, 0x30, 0xea, 0x18, 0x41, 0xdc, 0x09, + 0xcf, 0x0e, 0xf9, 0x04, 0xc4, 0xc8, 0xe1, 0x08, 0x46, 0x05, 0xd3, 0xec, 0xb9, + 0xd8, 0x00, 0x58, 0xeb, 0x3a, 0xb3, 0xc8, 0xf1, 0x0d, 0x08, 0x1f, 0x06, 0xdb, + 0xf6, 0xf8, 0xcd, 0x24, 0xd9, 0x1a, 0x18, 0x0a, 0xe5, 0xe4, 0x2d, 0x13, 0xee, + 0x18, 0xaf, 0xba, 0xd1, 0x0c, 0xea, 0x0f, 0x17, 0xec, 0xbc, 0x7e, 0x2e, 0x08, + 0xc5, 0xe4, 0xeb, 0xd9, 0xf4, 0xc8, 0xea, 0xca, 0xc8, 0xe6, 0x33, 0x81, 0x13, + 0x06, 0xf5, 0xf0, 0xf9, 0x3c, 0xe8, 0xd3, 0xde, 0xc6, 0x00, 0x2e, 0xf2, 0xe4, + 0x27, 0xe0, 0xb9, 0xf3, 0xff, 0x2d, 0xd7, 0xf5, 0x1a, 0xcb, 0xe9, 0xf8, 0x43, + 0x03, 0x05, 0x08, 0xce, 0xfd, 0xf7, 0xd0, 0x0c, 0xfb, 0xe5, 0xd4, 0xaa, 0x19, + 0xd2, 0xd7, 0x11, 0xed, 0xce, 0xf3, 0xe6, 0xe0, 0xf7, 0xc7, 0xde, 0xb2, 0x0e, + 0xc4, 0x08, 0x38, 0xf3, 0xe7, 0xe8, 0xf8, 0xef, 0xec, 0x0a, 0x41, 0x00, 0x01, + 0xec, 0xec, 0xe3, 0x03, 0x31, 0xaa, 0x1d, 0x1c, 0xff, 0x2d, 0xb8, 0x3c, 0xb1, + 0xdf, 0xfb, 0xd1, 0x28, 0xf1, 0xe3, 0xf4, 0xe4, 0x2e, 0xcf, 0xe2, 0xba, 0x11, + 0x26, 0xbf, 0x01, 0xb1, 0xd2, 0xc2, 0x0e, 0x88, 0xed, 0x14, 0x0a, 0xdf, 0x48, + 0xba, 0x16, 0xbc, 0xe2, 0x18, 0xb9, 0xf5, 0xe2, 0xd2, 0x06, 0x14, 0xec, 0x8c, + 0xdf, 0x1b, 0x13, 0xd7, 0xcf, 0xf7, 0xd9, 0xc2, 0xd3, 0xdb, 0xff, 0xf2, 0x46, + 0xe1, 0xe3, 0xcd, 0xa2, 0xf0, 0xef, 0x24, 0xf8, 0x14, 0xe0, 0x12, 0x07, 0xbd, + 0xf8, 0x16, 0xf6, 0x0f, 0xa7, 0x0c, 0xb7, 0xab, 0xe3, 0xd8, 0x9c, 0xed, 0x08, + 0x20, 0x16, 0x1b, 0x27, 0x19, 0xb7, 0x02, 0xda, 0xd1, 0xf6, 0xb3, 0x25, 0xaa, + 0xe2, 0x13, 0x1d, 0xfe, 0xf1, 0xc0, 0xdc, 0xc6, 0xf9, 0x17, 0xd4, 0xf8, 0xe4, + 0xfb, 0xdb, 0xa6, 0xed, 0xf6, 0x03, 0x2f, 0xd5, 0xe1, 0xb3, 0xb3, 0x13, 0xec, + 0x06, 0xde, 0xee, 0x06, 0xbe, 0x1f, 0x08, 0x1a, 0x23, 0x04, 0xd1, 0xb8, 0x07, + 0xb8, 0xe3, 0x13, 0x0f, 0x18, 0x05, 0xc0, 0xd5, 0xf8, 0x35, 0xa4, 0x22, 0xe3, + 0xf2, 0x0d, 0x0f, 0xd4, 0xfc, 0xb2, 0xd6, 0xdc, 0xeb, 0xd1, 0x1e, 0x30, 0xb9, + 0xcf, 0xff, 0x0f, 0xe6, 0x0a, 0xc7, 0xea, 0x0a, 0x37, 0x8f, 0x21, 0x1e, 0xaf, + 0x29, 0x1d, 0xe6, 0xda, 0x26, 0x14, 0x1d, 0x66, 0xe9, 0xab, 0xcc, 0xed, 0xa5, + 0xd6, 0x2c, 0xff, 0xf6, 0x04, 0xcc, 0xda, 0xf3, 0x1f, 0xdc, 0x00, 0x35, 0xce, + 0xde, 0xb5, 0x15, 0xf3, 0xbb, 0x01, 0xce, 0xea, 0xcd, 0xdc, 0xff, 0x00, 0x09, + 0xc2, 0x04, 0xee, 0xcb, 0x37, 0xf0, 0xf5, 0xaa, 0xac, 0xef, 0xc8, 0xbe, 0x10, + 0xfe, 0xdd, 0x37, 0x1f, 0x23, 0xdf, 0xee, 0x98, 0xf6, 0x0b, 0x02, 0xeb, 0xff, + 0xea, 0x10, 0xcd, 0xf6, 0xc6, 0x18, 0xc7, 0xd2, 0x33, 0x35, 0xff, 0x22, 0x03, + 0x9b, 0x51, 0xc3, 0x00, 0x76, 0xc6, 0xf6, 0xbe, 0xd2, 0x27, 0xf4, 0xf8, 0x28, + 0x09, 0x22, 0x16, 0xea, 0xb1, 0x02, 0xe6, 0x7f, 0x2e, 0xe4, 0xfa, 0x0e, 0x07, + 0xf1, 0xc0, 0xe0, 0xec, 0xff, 0xef, 0xd8, 0x17, 0x9f, 0xd0, 0xdf, 0xf8, 0xef, + 0xec, 0xd1, 0x10, 0xf4, 0xfd, 0xf6, 0x13, 0xd4, 0xe3, 0x66, 0xea, 0xfe, 0x3b, + 0xfe, 0xfc, 0x19, 0x20, 0x22, 0x08, 0xc4, 0xf9, 0x0b, 0xdc, 0x02, 0xd6, 0xe9, + 0x29, 0x19, 0xdc, 0xe5, 0xf4, 0x58, 0xef, 0x24, 0xd3, 0xdf, 0xb7, 0x36, 0xf5, + 0x22, 0xc4, 0xde, 0xce, 0xd7, 0x39, 0x20, 0x06, 0x08, 0xf4, 0xc7, 0x30, 0xfa, + 0xe6, 0xe6, 0xc7, 0x08, 0xfb, 0x22, 0xb9, 0x0d, 0x1b, 0x1a, 0x17, 0xe4, 0x18, + 0xcd, 0xe0, 0x11, 0xe6, 0x1d, 0xf5, 0xcc, 0xc0, 0xea, 0xd8, 0x32, 0xf0, 0xe7, + 0x5a, 0xf5, 0xc9, 0xff, 0xee, 0xca, 0x32, 0xec, 0xf8, 0x2c, 0x0c, 0xd3, 0xd7, + 0x30, 0x0c, 0xe5, 0xd7, 0xf5, 0x18, 0xe6, 0xe7, 0x27, 0x0a, 0x10, 0xcb, 0x0c, + 0xe7, 0xef, 0x15, 0xe5, 0xea, 0xff, 0x13, 0xeb, 0xd3, 0x14, 0x14, 0x01, 0x0f, + 0x0f, 0x07, 0xe1, 0xfc, 0x93, 0xcc, 0x0c, 0x32, 0xea, 0x1c, 0x06, 0x16, 0xd7, + 0xec, 0x13, 0xe3, 0x7f, 0x27, 0xe9, 0x32, 0x0f, 0xfa, 0x51, 0x1b, 0xba, 0xfb, + 0x2d, 0x03, 0x16, 0xfd, 0x05, 0xd8, 0x10, 0x0d, 0xbc, 0x0f, 0x18, 0x01, 0xe1, + 0xea, 0xe5, 0x2a, 0xe9, 0xe2, 0xec, 0xf8, 0xf6, 0x57, 0xf2, 0xf2, 0x05, 0x06, + 0xf6, 0xde, 0x1c, 0xe6, 0x03, 0xfa, 0xec, 0xcb, 0x0e, 0x19, 0x1a, 0x23, 0x01, + 0xda, 0xfe, 0xe4, 0xbf, 0x14, 0x00, 0xf3, 0x0c, 0x42, 0x11, 0x00, 0x0a, 0x2f, + 0xf3, 0xbf, 0x09, 0xd8, 0x19, 0xf6, 0xe4, 0xe2, 0x15, 0x55, 0xdd, 0xeb, 0xcc, + 0x14, 0xd3, 0x22, 0xee, 0xd7, 0xf6, 0x05, 0xed, 0x05, 0x02, 0xea, 0x02, 0xc3, + 0xe8, 0xee, 0x07, 0x0c, 0x10, 0xda, 0xfb, 0xe9, 0x05, 0xf0, 0xd0, 0xe7, 0xd2, + 0x05, 0xfc, 0xdc, 0xf0, 0xec, 0xff, 0xe9, 0xec, 0xc0, 0xc8, 0xe1, 0xf0, 0xf9, + 0xe0, 0xfd, 0x1e, 0xd6, 0xbe, 0xf4, 0xfa, 0xdd, 0xc6, 0x1d, 0xfe, 0xff, 0x06, + 0xda, 0x0b, 0xf9, 0xdf, 0xf2, 0xfb, 0xf3, 0xfe, 0xe7, 0x09, 0x00, 0x1a, 0x23, + 0xfd, 0xe3, 0x33, 0xfd, 0xf9, 0x10, 0x01, 0x1b, 0xdf, 0xf0, 0xcb, 0x09, 0x16, + 0x13, 0xd4, 0x0b, 0xd1, 0xec, 0xeb, 0xef, 0x13, 0x12, 0xbe, 0x20, 0xd2, 0xf0, + 0xce, 0xfe, 0xf1, 0xd3, 0x0e, 0x2c, 0xd4, 0x0e, 0xf5, 0x25, 0xd3, 0xf6, 0xeb, + 0xee, 0xc9, 0x14, 0xea, 0xd7, 0xe1, 0xea, 0x09, 0x3b, 0xfc, 0xca, 0x17, 0xd3, + 0xf1, 0x20, 0xaf, 0xf1, 0x1c, 0xbf, 0xe1, 0xe5, 0x04, 0xc2, 0xf5, 0x1a, 0xe9, + 0xf0, 0xd9, 0xf5, 0x11, 0xfd, 0xe5, 0xf2, 0x16, 0x07, 0x12, 0x33, 0xb6, 0x31, + 0xc7, 0xef, 0xdb, 0x0a, 0x18, 0xc5, 0xfd, 0xea, 0xf7, 0x11, 0x07, 0xe8, 0xfb, + 0xf4, 0xfd, 0x07, 0xd5, 0x0f, 0xbe, 0x12, 0x19, 0xfd, 0xf9, 0xd7, 0xd0, 0x05, + 0x26, 0xd1, 0xf5, 0xe4, 0xe0, 0xf2, 0x1a, 0xf6, 0xdb, 0xe5, 0xd9, 0x2c, 0x14, + 0x1a, 0x2f, 0xed, 0xd2, 0x2a, 0x2e, 0x13, 0xf9, 0xe1, 0xa3, 0xf8, 0xe3, 0xe6, + 0xdf, 0xcc, 0xe5, 0x0d, 0x03, 0xd9, 0xf2, 0xf3, 0x1c, 0x2e, 0xf5, 0x1c, 0x21, + 0xd5, 0xe2, 0x21, 0xdb, 0x0b, 0x02, 0xef, 0x03, 0xff, 0xf2, 0xde, 0xdc, 0xe5, + 0xd7, 0x02, 0xe1, 0xf1, 0x04, 0xf5, 0x05, 0xd5, 0xf1, 0x09, 0xe4, 0xcf, 0xfc, + 0xf8, 0x05, 0xd0, 0xdc, 0x15, 0xea, 0x28, 0x2b, 0x1c, 0x0c, 0xe5, 0xee, 0xb8, + 0xf3, 0x11, 0xf1, 0xf7, 0xe7, 0x03, 0xc0, 0x0a, 0xd5, 0x1f, 0xcf, 0x18, 0xf1, + 0xea, 0x02, 0xd1, 0xe8, 0xd6, 0xfe, 0xfd, 0xee, 0x02, 0x31, 0x0f, 0xc3, 0xeb, + 0x08, 0xcf, 0xfd, 0xd1, 0xf0, 0x0a, 0x1c, 0x15, 0xf6, 0xae, 0xc3, 0x07, 0x49, + 0xe6, 0xe0, 0x03, 0xde, 0xbc, 0xf7, 0xd6, 0xf4, 0x81, 0x3f, 0xee, 0xd5, 0x96, + 0xe3, 0x14, 0x74, 0xf7, 0x02, 0x04, 0xf3, 0xda, 0x1b, 0x3c, 0x27, 0x10, 0xf0, + 0x4a, 0xc6, 0x98, 0x51, 0xfa, 0x0f, 0x27, 0x11, 0xb0, 0xa0, 0x07, 0xef, 0x4f, + 0xef, 0x1c, 0xdf, 0xde, 0xcf, 0xf2, 0x43, 0xd7, 0xe9, 0x92, 0x0e, 0xe5, 0xf7, + 0xe3, 0x93, 0xbb, 0xd7, 0xe8, 0xda, 0x10, 0x15, 0x09, 0xf3, 0xdb, 0x05, 0xe3, + 0xe2, 0xd3, 0x63, 0x89, 0x01, 0xc9, 0x3b, 0x24, 0xcc, 0x47, 0x06, 0x06, 0x2c, + 0x0c, 0xe4, 0xe2, 0x8f, 0x04, 0x05, 0x1e, 0xc2, 0xdd, 0xf8, 0x60, 0x0b, 0x06, + 0x23, 0x30, 0xed, 0x2d, 0x26, 0x1f, 0x0d, 0xca, 0x33, 0x35, 0x2f, 0xed, 0x4a, + 0x07, 0xef, 0x09, 0xd3, 0x9e, 0xc6, 0x35, 0xd9, 0xde, 0x00, 0x13, 0x58, 0x0b, + 0xfb, 0xe3, 0x0b, 0x08, 0x06, 0xd1, 0x33, 0xea, 0xaf, 0xe6, 0xd5, 0x67, 0xe3, + 0xb9, 0xf7, 0x1f, 0x0e, 0xf2, 0xbf, 0x58, 0x06, 0xff, 0xa3, 0xc6, 0xf4, 0x42, + 0xc8, 0xfd, 0x28, 0x1d, 0x09, 0x22, 0x21, 0xe8, 0xd7, 0xf2, 0x0c, 0x8b, 0xa0, + 0x0b, 0x00, 0xbf, 0xe4, 0xce, 0xf6, 0x65, 0xf3, 0xfc, 0x25, 0x18, 0xf4, 0x02, + 0xd4, 0x10, 0x02, 0x34, 0xd3, 0xf6, 0xbb, 0x1e, 0x02, 0x0c, 0x1f, 0x16, 0x9a, + 0x5c, 0xc0, 0xd1, 0xd0, 0x04, 0xf9, 0xfc, 0x9d, 0xa5, 0xf2, 0x08, 0x3e, 0xc8, + 0xce, 0x0e, 0x0f, 0xcb, 0xc8, 0xfa, 0x3e, 0xe2, 0xbe, 0x0f, 0x51, 0xdb, 0x3b, + 0x07, 0xf4, 0xdf, 0x25, 0x1b, 0x15, 0x1b, 0x07, 0xf0, 0x28, 0x07, 0x81, 0xef, + 0xfe, 0xe5, 0xa1, 0x29, 0xc6, 0xdc, 0x0a, 0xf2, 0x00, 0xb1, 0xd8, 0x15, 0x04, + 0x50, 0x45, 0x1b, 0xf9, 0xf4, 0xe8, 0x07, 0xc3, 0xce, 0x3c, 0xde, 0x47, 0x10, + 0x01, 0x2f, 0x23, 0xf7, 0xd4, 0xd4, 0xd8, 0xfe, 0x45, 0xea, 0x23, 0x1b, 0x10, + 0xd2, 0x24, 0xdc, 0x0c, 0x00, 0x25, 0xfb, 0xa3, 0xe4, 0xf6, 0xcf, 0x5e, 0xfd, + 0x13, 0xd1, 0xf4, 0xe7, 0xe6, 0xc1, 0xb9, 0xc4, 0xc6, 0x1c, 0x8e, 0x09, 0x3a, + 0xda, 0x03, 0xf4, 0xe5, 0x35, 0xfc, 0x08, 0xee, 0x81, 0xf1, 0x20, 0x11, 0xf2, + 0xcd, 0xb2, 0x2a, 0x28, 0x31, 0x25, 0xb4, 0xf6, 0x21, 0xd2, 0xf9, 0xa5, 0xf7, + 0xb8, 0xf2, 0x12, 0x02, 0x29, 0x3b, 0x08, 0xc4, 0xbb, 0xe3, 0xce, 0x16, 0xc9, + 0x20, 0xd7, 0x47, 0x0c, 0xa6, 0x10, 0x18, 0xfb, 0x4f, 0xc0, 0xc1, 0x17, 0xd8, + 0xb9, 0xf4, 0xd9, 0xcf, 0x07, 0x2a, 0x2e, 0x10, 0xfc, 0x22, 0x4f, 0x94, 0x2b, + 0x15, 0x1b, 0xbe, 0xb0, 0xa6, 0x37, 0xf1, 0x19, 0xdb, 0xe3, 0xe4, 0xfc, 0x26, + 0xee, 0xe0, 0x2b, 0xdd, 0xba, 0x1e, 0x06, 0x05, 0xbe, 0xe6, 0xc5, 0x1f, 0xd0, + 0xce, 0xb5, 0xd0, 0xfd, 0xbf, 0x9d, 0xcd, 0x1f, 0xe8, 0x5f, 0xd7, 0xb1, 0xf6, + 0x0d, 0xb5, 0x4c, 0x0b, 0xd2, 0xf5, 0x1f, 0x04, 0xe6, 0x12, 0xcf, 0xbb, 0xe6, + 0xf3, 0xcb, 0x3d, 0x24, 0xc1, 0xe6, 0x97, 0xa3, 0xf4, 0x3b, 0xd3, 0x13, 0x34, + 0xbc, 0x23, 0x2b, 0x19, 0xb2, 0x45, 0xc4, 0xb7, 0xe7, 0x3b, 0xf0, 0xf0, 0x02, + 0xab, 0xc8, 0x95, 0x32, 0x14, 0x0a, 0x4e, 0xba, 0x4b, 0x2a, 0x9c, 0xf4, 0xe1, + 0xfe, 0xe9, 0x2d, 0xe9, 0x3c, 0xed, 0x03, 0xf8, 0x11, 0xf5, 0xed, 0x0b, 0x1a, + 0x16, 0x06, 0x25, 0xb1, 0xb5, 0xdc, 0x3e, 0xea, 0x38, 0x40, 0xa5, 0xfe, 0xd6, + 0x48, 0x0f, 0x9e, 0xd1, 0xc4, 0x3b, 0x0b, 0xb1, 0xe6, 0x1b, 0x0a, 0xc0, 0xdd, + 0x0e, 0xaa, 0x66, 0x02, 0x11, 0xfb, 0xff, 0x0a, 0xc2, 0xb3, 0xf6, 0xfa, 0xe7, + 0x67, 0x0a, 0x08, 0x22, 0xf5, 0x41, 0x0d, 0xc3, 0xda, 0x0b, 0x14, 0x3c, 0xf2, + 0xcc, 0xf6, 0x33, 0xe7, 0x50, 0xfa, 0xa4, 0x2a, 0x16, 0x27, 0x2a, 0x9c, 0x33, + 0xd2, 0xbf, 0xcf, 0x02, 0xf6, 0xba, 0xf5, 0xcf, 0x1e, 0xf0, 0xd7, 0xb0, 0xe2, + 0x81, 0xf9, 0x02, 0xb9, 0x02, 0xe5, 0xe9, 0xf7, 0xd2, 0xf2, 0xe2, 0x06, 0xfc, + 0xe0, 0x03, 0x0a, 0x30, 0xd9, 0xef, 0x24, 0xc4, 0xf0, 0xbc, 0xf9, 0xdb, 0x0c, + 0xd5, 0x09, 0x03, 0x43, 0xbc, 0x4e, 0xf7, 0x08, 0x00, 0x15, 0xec, 0x19, 0xc9, + 0xe6, 0xc0, 0xd4, 0x03, 0x00, 0xe0, 0xd0, 0xa1, 0x16, 0xeb, 0x0f, 0x2e, 0xfe, + 0x02, 0x04, 0xcf, 0x07, 0xda, 0x32, 0x0d, 0xf8, 0xbe, 0x1a, 0x34, 0x15, 0x35, + 0xea, 0xe9, 0xff, 0xdd, 0xe5, 0x2a, 0xc9, 0xfe, 0x19, 0xf8, 0xbe, 0xd2, 0x25, + 0xea, 0xe2, 0xf5, 0x26, 0xe0, 0xb6, 0xfb, 0xe4, 0xd0, 0x22, 0x37, 0x22, 0x8f, + 0x11, 0xe6, 0xe1, 0x1a, 0x0a, 0xbf, 0xd8, 0xe3, 0xd1, 0xee, 0xd8, 0x32, 0x4a, + 0xb1, 0xce, 0xec, 0xde, 0xee, 0xcc, 0x25, 0x07, 0xf4, 0x33, 0x02, 0xf9, 0x33, + 0x23, 0xd0, 0xf6, 0xd1, 0x08, 0xdd, 0xe4, 0xd9, 0xbe, 0xe1, 0x2d, 0xc3, 0xed, + 0x03, 0xbc, 0x3b, 0xc3, 0xd0, 0x44, 0x08, 0x14, 0xcb, 0xca, 0xa6, 0xb1, 0xe9, + 0xa6, 0xf5, 0x41, 0x39, 0xf4, 0x01, 0xed, 0x4f, 0x1d, 0xed, 0xc5, 0x40, 0x2c, + 0x29, 0xd1, 0x45, 0x0a, 0xe1, 0x32, 0x50, 0xf5, 0x31, 0x10, 0x05, 0xdd, 0xfc, + 0xbc, 0x20, 0x2c, 0x0e, 0xdb, 0xf7, 0xfc, 0xf6, 0xa9, 0xcb, 0xff, 0xf1, 0xc8, + 0xd6, 0xec, 0xb1, 0xd8, 0xbb, 0x3d, 0xf9, 0xec, 0x03, 0xe1, 0x12, 0xbb, 0xeb, + 0x1d, 0x1e, 0xea, 0xed, 0xf1, 0x0e, 0x11, 0xe5, 0x05, 0xf1, 0xf7, 0x13, 0x29, + 0xcb, 0x0e, 0xc0, 0xec, 0xf7, 0x09, 0x01, 0xb4, 0x00, 0x3e, 0xc2, 0x23, 0xeb, + 0x1f, 0xbe, 0xaf, 0x0f, 0xbe, 0x09, 0xc2, 0xf5, 0xe6, 0x9e, 0x04, 0xbe, 0xd1, + 0xea, 0xd6, 0x28, 0xaa, 0x06, 0xd8, 0x03, 0xe8, 0xf6, 0xc6, 0x24, 0x10, 0xe0, + 0xe1, 0x17, 0xdd, 0xe0, 0x0c, 0x0a, 0xf9, 0xf8, 0xd3, 0x4a, 0x13, 0xd1, 0x0b, + 0x24, 0x17, 0xd3, 0x04, 0xd9, 0x10, 0x37, 0xc2, 0x67, 0xf6, 0xf4, 0xeb, 0x0c, + 0x1d, 0x24, 0x12, 0x1f, 0x09, 0x42, 0xff, 0x32, 0xe7, 0xca, 0x2a, 0x04, 0x40, + 0x30, 0xe8, 0xfb, 0xc2, 0xfc, 0xe7, 0x0b, 0xf8, 0x2c, 0xed, 0x0a, 0x13, 0x4e, + 0xc5, 0x2d, 0x30, 0xe7, 0x26, 0xcb, 0x09, 0x53, 0xfc, 0xf2, 0xd4, 0xd7, 0x0a, + 0xee, 0x05, 0x12, 0x25, 0xff, 0x0d, 0xd3, 0xd9, 0x17, 0x0f, 0xf8, 0x1f, 0x26, + 0x06, 0x02, 0x0f, 0x20, 0x09, 0x33, 0x10, 0x12, 0x09, 0xfd, 0xf6, 0xde, 0x7f, + 0x12, 0xf4, 0x0f, 0xc0, 0x05, 0xce, 0x0e, 0x05, 0xf7, 0xd9, 0x14, 0xe3, 0x07, + 0xa0, 0x2e, 0x23, 0x43, 0xfd, 0xf8, 0xdb, 0xfd, 0xec, 0xdb, 0xaf, 0xe6, 0x23, + 0x0b, 0xd6, 0x09, 0xe3, 0x14, 0x13, 0x07, 0xe5, 0xd3, 0x43, 0x13, 0x18, 0xff, + 0xec, 0x00, 0xe9, 0xf8, 0xc7, 0xeb, 0xe2, 0xfd, 0x09, 0x35, 0x22, 0x36, 0x18, + 0xf0, 0x1b, 0x0c, 0x02, 0xf3, 0xa8, 0xdb, 0xe1, 0xfd, 0x06, 0xdf, 0x12, 0xc3, + 0xf1, 0xf0, 0xbe, 0x0c, 0x2b, 0x3b, 0x38, 0x33, 0x5f, 0x7c, 0xf6, 0x08, 0xf8, + 0xee, 0xb7, 0x03, 0x26, 0x5e, 0xf6, 0xfa, 0xd8, 0x18, 0x07, 0x03, 0xfe, 0x1e, + 0xee, 0x38, 0xb0, 0x0c, 0x2c, 0xc6, 0x22, 0xe0, 0x05, 0x11, 0x01, 0xff, 0x03, + 0x0f, 0x08, 0x19, 0xfa, 0x03, 0xb2, 0xd7, 0x40, 0x2c, 0x0c, 0x0b, 0x24, 0x08, + 0xb3, 0x36, 0xd4, 0xbe, 0xeb, 0xe2, 0x1e, 0xfc, 0xf7, 0xe6, 0x08, 0xfa, 0xed, + 0xcf, 0x09, 0xb3, 0x30, 0xf4, 0xfb, 0x16, 0xf7, 0x1c, 0xfd, 0x2a, 0xd5, 0xff, + 0xf5, 0xf7, 0xee, 0x25, 0x04, 0x08, 0x05, 0xdc, 0xe3, 0xef, 0xc4, 0x1a, 0x02, + 0xd2, 0xf6, 0x4c, 0xb3, 0xf7, 0xc8, 0xf3, 0x36, 0xff, 0xe7, 0x33, 0xd2, 0xf9, + 0xf6, 0x0c, 0x88, 0x09, 0xb3, 0xe2, 0xc7, 0xe7, 0xf8, 0x27, 0xda, 0xbc, 0xf1, + 0xac, 0xf9, 0x0f, 0xc5, 0xba, 0xe3, 0xb1, 0x04, 0xfb, 0xfc, 0x40, 0x2e, 0xde, + 0xb6, 0xdc, 0xbb, 0x25, 0x2b, 0x0f, 0x1c, 0x21, 0xf3, 0x31, 0x15, 0xf2, 0x25, + 0xf1, 0xe0, 0xc5, 0x22, 0xc3, 0xed, 0xdc, 0x4d, 0xdb, 0xf3, 0xd3, 0x55, 0x38, + 0xf3, 0xd7, 0xac, 0xf3, 0x04, 0xa4, 0x3c, 0xd2, 0xee, 0xe1, 0xd7, 0xfc, 0xde, + 0xdb, 0xe8, 0xd6, 0x0a, 0xb3, 0x65, 0x0d, 0x2e, 0xca, 0xfe, 0xe9, 0xca, 0xc4, + 0x81, 0x16, 0x47, 0xb6, 0x5d, 0xcf, 0xac, 0x39, 0xff, 0x38, 0xdb, 0x49, 0xcd, + 0xe0, 0x34, 0x07, 0x4e, 0xc1, 0x0c, 0x1f, 0xb6, 0xaa, 0x1e, 0x2d, 0x0e, 0x29, + 0xed, 0x30, 0xdc, 0xba, 0xc7, 0xf4, 0x2f, 0x6e, 0xbe, 0x31, 0xf8, 0xdd, 0xb8, + 0x05, 0xfc, 0xee, 0xe8, 0xda, 0x0b, 0xb7, 0xf7, 0x02, 0x0f, 0x85, 0x9f, 0x3d, + 0xd2, 0x3d, 0xff, 0xd1, 0xc0, 0x27, 0xe5, 0x0f, 0xff, 0xfc, 0xcf, 0x10, 0x4b, + 0xf5, 0xf5, 0x08, 0x2b, 0xeb, 0xe5, 0xd9, 0xd2, 0xc4, 0xd4, 0xf0, 0xd8, 0xfc, + 0xac, 0xe6, 0xe6, 0xc7, 0x15, 0xf1, 0xfc, 0xc3, 0x09, 0x15, 0xc9, 0xe2, 0x00, + 0x44, 0x41, 0xbf, 0x49, 0x21, 0x17, 0xdb, 0x83, 0xa3, 0xc2, 0xfb, 0x26, 0x1a, + 0xf4, 0x26, 0x20, 0xd1, 0xa7, 0x1f, 0xe6, 0x06, 0x99, 0x07, 0x16, 0x4d, 0xb1, + 0x3e, 0xc7, 0x2b, 0x30, 0xdc, 0xed, 0xed, 0xf7, 0xd9, 0xe8, 0x1c, 0xdf, 0x17, + 0xaf, 0xfb, 0xdf, 0xfb, 0xe0, 0x18, 0xe3, 0x39, 0x15, 0xf9, 0x3d, 0xaf, 0x3e, + 0x10, 0xb6, 0x3b, 0xf3, 0xee, 0xcf, 0xfa, 0xe4, 0xd2, 0xf4, 0x02, 0xf4, 0x15, + 0x24, 0xf2, 0xea, 0xfb, 0x12, 0x4e, 0xe3, 0xfd, 0xff, 0x26, 0x13, 0x38, 0xe9, + 0xe0, 0x06, 0x26, 0xf2, 0xff, 0xde, 0xef, 0xe4, 0x3d, 0xe6, 0xe6, 0xd3, 0xf1, + 0x05, 0xcd, 0xc8, 0xe4, 0xc2, 0xe0, 0x00, 0xea, 0xe2, 0x11, 0xfc, 0xd7, 0xe7, + 0xcd, 0xe8, 0xb5, 0xc6, 0x06, 0xf3, 0xbc, 0xda, 0xd6, 0xce, 0x05, 0xfa, 0xf0, + 0xe1, 0xfd, 0xe6, 0x35, 0x49, 0xfc, 0x00, 0xf8, 0xed, 0x1e, 0x24, 0x81, 0x2d, + 0x11, 0xe6, 0xfe, 0xdc, 0xba, 0xb8, 0xf7, 0x26, 0x04, 0x12, 0x1e, 0x24, 0x6f, + 0x0b, 0xf9, 0xcd, 0xd4, 0x0c, 0xce, 0x15, 0xc6, 0xe8, 0xb3, 0x05, 0x0f, 0xac, + 0x2a, 0xbd, 0xf5, 0x2f, 0xdf, 0xd3, 0x00, 0xed, 0xd2, 0x12, 0xed, 0x19, 0x36, + 0x1a, 0xf3, 0xe6, 0x02, 0x21, 0x10, 0xfe, 0xdb, 0xa6, 0xdc, 0xd2, 0x10, 0x6b, + 0xd7, 0xde, 0xce, 0xfd, 0xc2, 0x12, 0xd2, 0xfd, 0xe4, 0xd0, 0xe2, 0xfb, 0x11, + 0xdc, 0xc0, 0xda, 0xd4, 0xf8, 0x0e, 0x05, 0xdd, 0xf9, 0xee, 0x2e, 0x22, 0xe6, + 0xc2, 0xd9, 0x0b, 0xf6, 0xe0, 0x21, 0xf9, 0xdf, 0x32, 0x0c, 0x14, 0xbc, 0xc3, + 0x17, 0xf2, 0xe0, 0xe9, 0xf4, 0xf7, 0x0c, 0xdd, 0x3b, 0xbc, 0xdb, 0x1b, 0xdf, + 0xfb, 0xd9, 0x06, 0xcb, 0xde, 0x1a, 0x35, 0x21, 0x16, 0xe7, 0xd7, 0x19, 0xfb, + 0x2b, 0xc1, 0xd2, 0x0f, 0x2c, 0x02, 0x22, 0x09, 0xf0, 0xcd, 0xd8, 0x1f, 0xaf, + 0xf2, 0xd1, 0x04, 0x05, 0xbc, 0xd2, 0xea, 0x30, 0xeb, 0xee, 0xe8, 0xef, 0xd7, + 0xce, 0xbe, 0xff, 0xbe, 0xa8, 0xbc, 0xdc, 0xfd, 0xea, 0x07, 0x00, 0xe2, 0xee, + 0x27, 0xe6, 0xe7, 0x01, 0xf8, 0x07, 0xf3, 0x07, 0x01, 0xf7, 0xec, 0xe8, 0xf9, + 0xee, 0xfe, 0x14, 0x01, 0xdd, 0x2d, 0x31, 0x25, 0xf1, 0xfe, 0x22, 0xf7, 0xcf, + 0x09, 0xcf, 0xfe, 0xfb, 0xdd, 0xcc, 0x3d, 0x2f, 0xed, 0xf1, 0xe5, 0xaa, 0xed, + 0xe2, 0xea, 0xca, 0x00, 0xf8, 0xf6, 0xe7, 0xf6, 0x0c, 0x0b, 0xd0, 0x18, 0x01, + 0x1f, 0xb3, 0x1f, 0xf0, 0x07, 0xad, 0xf1, 0xca, 0xc4, 0xec, 0xf5, 0x36, 0xa4, + 0x15, 0xd1, 0xf5, 0xae, 0xcb, 0x21, 0x81, 0xfd, 0xcc, 0xd0, 0x00, 0xbf, 0xe2, + 0x0c, 0x27, 0x64, 0x22, 0x49, 0x21, 0xbd, 0xfd, 0xdb, 0xd9, 0xa7, 0x04, 0x04, + 0xe3, 0x30, 0xf4, 0xfb, 0x2b, 0xc6, 0xef, 0xfe, 0x1c, 0xe4, 0xdd, 0x01, 0x43, + 0xef, 0x4b, 0x72, 0x5c, 0x33, 0x37, 0xe5, 0xe4, 0x01, 0xea, 0xb0, 0x0b, 0x43, + 0xde, 0x06, 0xe4, 0x30, 0x5c, 0xea, 0xcd, 0xe5, 0x1e, 0x13, 0xe9, 0x0a, 0x2e, + 0xcf, 0xd9, 0x35, 0x13, 0xb7, 0xf3, 0x1f, 0xeb, 0xc5, 0x1c, 0x09, 0x13, 0x02, + 0x20, 0x13, 0x9e, 0x20, 0xe2, 0xba, 0x0d, 0xf8, 0xdf, 0x45, 0xeb, 0x1c, 0xf6, + 0x03, 0xec, 0xe5, 0x5e, 0xbb, 0x2a, 0xd3, 0xc1, 0xce, 0xb5, 0xe7, 0xff, 0xfc, + 0xf6, 0x1c, 0xb6, 0x11, 0xa6, 0xe6, 0x1b, 0xfa, 0x32, 0x24, 0xee, 0xca, 0xdd, + 0xe6, 0x17, 0x9a, 0xef, 0xea, 0xd8, 0x47, 0xf0, 0x14, 0x37, 0xd5, 0xff, 0x8a, + 0xe8, 0x03, 0xf6, 0x8e, 0x14, 0xec, 0xc4, 0x3e, 0xfc, 0xd4, 0x11, 0xd9, 0x96, + 0x9f, 0x11, 0xf3, 0x14, 0xa6, 0xdd, 0x1a, 0xfd, 0xa8, 0xcf, 0xdd, 0x18, 0xf4, + 0xd0, 0x5c, 0xf3, 0x25, 0x02, 0x2b, 0x3a, 0x44, 0xe0, 0xce, 0xf1, 0x09, 0xbe, + 0xe2, 0x1f, 0xa3, 0x11, 0xf9, 0xe7, 0x45, 0xcd, 0xeb, 0xda, 0xe0, 0xd0, 0xd6, + 0x3c, 0xf9, 0x63, 0xc2, 0x46, 0x30, 0xd3, 0xf9, 0xfa, 0xec, 0x97, 0x3f, 0x36, + 0x1b, 0xe7, 0x0f, 0xed, 0x0d, 0xe3, 0x18, 0x42, 0xcb, 0x0d, 0x37, 0x13, 0x13, + 0x49, 0xd2, 0x01, 0xcf, 0xd6, 0x27, 0xfc, 0x0e, 0xec, 0xb7, 0x1a, 0xc6, 0xf3, + 0x15, 0x60, 0x08, 0xf9, 0xe8, 0x3b, 0xc3, 0x34, 0xfc, 0x02, 0xa8, 0xcf, 0x26, + 0x37, 0xed, 0xee, 0xfc, 0xce, 0x15, 0x63, 0xb6, 0x3e, 0x09, 0xfb, 0xec, 0xfd, + 0x00, 0xc1, 0xf3, 0x08, 0x9e, 0xe7, 0xcc, 0xcf, 0xed, 0xf4, 0xd5, 0xf8, 0x11, + 0xdd, 0x12, 0xe8, 0xfc, 0xeb, 0x05, 0x03, 0x12, 0xf8, 0x12, 0xf8, 0xdb, 0x0c, + 0xda, 0x1a, 0xe8, 0x23, 0xd9, 0x16, 0x21, 0xde, 0xe0, 0x33, 0x00, 0xd5, 0x0d, + 0xeb, 0xfd, 0xfd, 0xd2, 0x23, 0xf9, 0xda, 0xcd, 0xd8, 0x1e, 0xdf, 0x13, 0x51, + 0xe8, 0xf1, 0x0b, 0x1e, 0x1e, 0xf7, 0x19, 0xff, 0xd8, 0xde, 0xdb, 0x1b, 0xe5, + 0xf4, 0xce, 0x0a, 0xfc, 0x0b, 0x00, 0xdd, 0xf0, 0xde, 0xcd, 0xbb, 0xec, 0xc4, + 0xe0, 0x25, 0xe0, 0x13, 0xef, 0xef, 0xd6, 0xe4, 0xeb, 0x0d, 0x0c, 0x15, 0xeb, + 0x0b, 0xd8, 0x20, 0x12, 0x03, 0x81, 0x01, 0x07, 0x18, 0xfb, 0xb5, 0xb6, 0xaf, + 0xb7, 0xd8, 0x0f, 0x00, 0x17, 0xde, 0xd1, 0x24, 0x16, 0xfc, 0xfa, 0x0e, 0xed, + 0xea, 0xe3, 0x09, 0x06, 0xd1, 0xe3, 0x38, 0x11, 0x03, 0xe6, 0xcd, 0x0a, 0x0d, + 0xd9, 0xeb, 0xbb, 0xe4, 0xd5, 0xb5, 0x14, 0x0d, 0x09, 0xf3, 0x22, 0x04, 0x03, + 0xe3, 0x03, 0xce, 0xdf, 0x1a, 0xc7, 0xdf, 0xdd, 0x1c, 0x1e, 0x0b, 0x01, 0xf4, + 0x0d, 0xff, 0x18, 0xf3, 0x1a, 0xff, 0x53, 0xff, 0x19, 0xfb, 0x2f, 0xf4, 0xca, + 0xea, 0x40, 0x1b, 0xf3, 0x09, 0xf9, 0xbc, 0x01, 0xec, 0xe7, 0xdf, 0x01, 0xb4, + 0x2c, 0xf4, 0xd6, 0xf8, 0x05, 0xca, 0xf9, 0xe3, 0xef, 0xdc, 0xfe, 0xf4, 0xf3, + 0xee, 0xfc, 0x05, 0x2f, 0xbf, 0xd4, 0x0e, 0xed, 0x0e, 0xfb, 0xe5, 0xf0, 0xe3, + 0xe3, 0x05, 0x0b, 0xec, 0xde, 0x13, 0xd6, 0xd3, 0xe1, 0xf6, 0xd4, 0xee, 0x22, + 0x27, 0x14, 0xf3, 0x1b, 0xec, 0xd0, 0xfd, 0xc9, 0xe9, 0x03, 0xee, 0x13, 0x0c, + 0x2d, 0xeb, 0x03, 0x9d, 0x1a, 0xed, 0x39, 0xf7, 0xde, 0xaa, 0xd2, 0xfc, 0x4f, + 0xd4, 0xf6, 0xba, 0xf9, 0xe9, 0xd3, 0xea, 0x17, 0x93, 0x2d, 0xfe, 0xf9, 0x00, + 0x00, 0x08, 0xb7, 0xfb, 0x8d, 0x2c, 0x40, 0xc1, 0x42, 0x1f, 0xbb, 0xd3, 0x41, + 0xfb, 0x13, 0xe6, 0xa8, 0x53, 0x05, 0x24, 0x1b, 0x1a, 0xf7, 0x0c, 0x2d, 0xab, + 0x23, 0xeb, 0xee, 0x42, 0x26, 0xb0, 0x05, 0x1a, 0xf0, 0xa8, 0xf2, 0x38, 0xd0, + 0xff, 0xef, 0x21, 0x41, 0x1f, 0x2a, 0x2a, 0xeb, 0xfe, 0x23, 0x0a, 0x43, 0xff, + 0x29, 0xe1, 0xad, 0xcd, 0xf8, 0x14, 0xcc, 0xd3, 0xc2, 0xf5, 0xfa, 0xb1, 0x18, + 0xa3, 0xe6, 0x49, 0x15, 0x0d, 0xf9, 0xd1, 0xf1, 0x10, 0x14, 0xea, 0xc7, 0x55, + 0xf4, 0x22, 0xcf, 0x07, 0xc4, 0xee, 0x27, 0xc0, 0x22, 0x1c, 0xf9, 0xf7, 0xda, + 0x0f, 0xd6, 0x27, 0x35, 0x10, 0xe7, 0x01, 0x33, 0xb5, 0xf5, 0x31, 0xd5, 0xef, + 0xcd, 0xe3, 0x1a, 0xa8, 0x13, 0x23, 0x3f, 0xbb, 0xe0, 0xf7, 0xda, 0xe9, 0xf8, + 0xf6, 0x00, 0x15, 0x09, 0xba, 0x27, 0xf4, 0x81, 0xe1, 0x17, 0x06, 0x0a, 0x3f, + 0xde, 0xcd, 0x07, 0xd7, 0xdc, 0xc5, 0x44, 0xe3, 0xb8, 0xd9, 0xfc, 0xf1, 0xc5, + 0xc8, 0xec, 0xdb, 0x1a, 0xc6, 0xf7, 0x31, 0xde, 0xe3, 0xe6, 0xc7, 0x9a, 0x32, + 0xb3, 0xb4, 0x2a, 0xdc, 0xe1, 0xe5, 0x15, 0xd8, 0xe2, 0xfd, 0x46, 0xfd, 0xe0, + 0x0b, 0x0d, 0x24, 0x0f, 0x0d, 0xfb, 0xc2, 0xfe, 0xa2, 0xd2, 0x0d, 0xea, 0x09, + 0x3e, 0xd6, 0xf5, 0x21, 0xb0, 0x31, 0xd3, 0x23, 0x06, 0x20, 0x06, 0xdc, 0x35, + 0x23, 0x29, 0xf3, 0xa9, 0xa8, 0xe8, 0xc8, 0x00, 0xfa, 0xf5, 0x0b, 0xd8, 0x1b, + 0x01, 0xd5, 0xec, 0xe3, 0xa4, 0xc7, 0xb6, 0xdd, 0x14, 0x3c, 0xde, 0xde, 0x14, + 0xe1, 0x30, 0xd1, 0x1b, 0xd8, 0x3c, 0x13, 0xaf, 0xbc, 0xe7, 0xd4, 0x0b, 0x01, + 0x08, 0xd5, 0x2d, 0x27, 0xfc, 0xcd, 0xef, 0x04, 0xfb, 0xcf, 0xf3, 0x16, 0x40, + 0x4a, 0xac, 0x06, 0xce, 0x18, 0xfe, 0x13, 0xc2, 0xce, 0x28, 0xef, 0xc3, 0xf0, + 0x1f, 0xd6, 0x05, 0xd7, 0x04, 0xf5, 0x0c, 0xe1, 0xe9, 0xca, 0x06, 0x18, 0xc4, + 0x11, 0x08, 0x3b, 0x18, 0xf6, 0xd7, 0xdd, 0x0a, 0xa7, 0xb7, 0xfa, 0xf4, 0x41, + 0x11, 0x28, 0x33, 0x17, 0x9f, 0x2e, 0x17, 0xde, 0x06, 0x0d, 0xa9, 0x30, 0xdd, + 0x24, 0xe5, 0xe2, 0xe2, 0x1e, 0xd6, 0x20, 0x2c, 0x0a, 0xf8, 0xd9, 0xd7, 0x14, + 0xda, 0xff, 0xd6, 0x19, 0xf0, 0x13, 0x36, 0x2b, 0xfc, 0xb6, 0xc4, 0x2b, 0xbf, + 0xf4, 0xe0, 0xa2, 0x05, 0x8b, 0x3c, 0xf6, 0xeb, 0xe3, 0xdc, 0x24, 0xba, 0xe3, + 0x3a, 0x1f, 0x07, 0xf8, 0x34, 0x14, 0xd2, 0xdd, 0x47, 0x3d, 0xad, 0xc9, 0x06, + 0x14, 0x16, 0xf3, 0xe8, 0xcb, 0xe9, 0xec, 0xe1, 0xec, 0x0c, 0x14, 0xd1, 0xd2, + 0x0c, 0xfa, 0xeb, 0xd4, 0xfc, 0xdf, 0x43, 0x2a, 0xdc, 0x02, 0xe1, 0xc2, 0x0a, + 0xe2, 0xfa, 0xec, 0x3a, 0xf7, 0x0b, 0xbd, 0x1d, 0x18, 0x26, 0xe8, 0x08, 0x1f, + 0xda, 0xdd, 0x0b, 0xf3, 0x13, 0x15, 0xd2, 0x1a, 0x81, 0xe7, 0x07, 0xfe, 0xb2, + 0xb3, 0x39, 0x0a, 0xda, 0xee, 0xd6, 0xf3, 0xf6, 0xde, 0xb5, 0x22, 0xe4, 0x1b, + 0xe9, 0x2d, 0x07, 0x02, 0x20, 0x1f, 0xdd, 0xe9, 0xde, 0x21, 0xfa, 0xee, 0xda, + 0x39, 0xf8, 0xdc, 0xf9, 0x01, 0xfe, 0x13, 0x12, 0x0f, 0x22, 0xd1, 0xfa, 0xf4, + 0xfa, 0xca, 0xf8, 0x18, 0xfb, 0x28, 0x11, 0x0a, 0x15, 0xe4, 0xce, 0x0e, 0x23, + 0x08, 0x04, 0x09, 0xd6, 0x07, 0x06, 0x01, 0x27, 0xdd, 0xf6, 0xef, 0xbf, 0x44, + 0xd2, 0xf1, 0xd9, 0x0a, 0xde, 0x11, 0x42, 0x16, 0xf7, 0xf0, 0xe3, 0x0d, 0x00, + 0x08, 0xbe, 0xca, 0x2b, 0xf3, 0x50, 0xe6, 0xd4, 0x1d, 0x1a, 0xf3, 0x10, 0x2e, + 0xf8, 0xc1, 0x20, 0xc4, 0xf4, 0xa7, 0xe8, 0xbb, 0x03, 0xf1, 0x08, 0xc2, 0x35, + 0xde, 0xd5, 0xe1, 0x6b, 0x1e, 0xbf, 0x1d, 0xb3, 0xc3, 0x2e, 0x3c, 0x81, 0x22, + 0x1e, 0xb4, 0x15, 0xc1, 0xeb, 0xc7, 0xc5, 0xfb, 0xc7, 0xaa, 0xb5, 0x20, 0xf4, + 0xb1, 0x2e, 0xbe, 0xfa, 0x27, 0xe2, 0x28, 0xef, 0x5c, 0xd9, 0xf6, 0xf6, 0x41, + 0xd1, 0xd0, 0x20, 0x26, 0x41, 0x03, 0xd4, 0x11, 0xbf, 0xfe, 0x49, 0x01, 0xc8, + 0xc1, 0xd8, 0x35, 0xaf, 0xac, 0x17, 0xdf, 0xbf, 0xcd, 0x00, 0xba, 0xbc, 0xb2, + 0xec, 0xb8, 0xc1, 0x4e, 0xc9, 0xe6, 0xf1, 0xb3, 0xb3, 0xd9, 0x04, 0xf1, 0xdf, + 0x52, 0x24, 0xf2, 0x24, 0x00, 0xe6, 0xf3, 0xe4, 0xc5, 0xa1, 0xac, 0xb7, 0x31, + 0xc2, 0x3c, 0xf0, 0xfd, 0x27, 0xee, 0xc9, 0xe6, 0xc3, 0xad, 0xd8, 0xb7, 0x37, + 0x06, 0x96, 0xfb, 0x53, 0xc5, 0x1e, 0x0f, 0x13, 0xbd, 0x9f, 0xed, 0xf5, 0x49, + 0x33, 0x13, 0xca, 0x52, 0x58, 0x39, 0x16, 0x02, 0xd0, 0x2a, 0x11, 0x0f, 0xd0, + 0x21, 0xbe, 0xe5, 0xe0, 0x03, 0x03, 0xe5, 0x37, 0xed, 0xda, 0x16, 0x5a, 0xd9, + 0xfe, 0xfe, 0xd0, 0x0a, 0xec, 0x0f, 0xff, 0xf8, 0x22, 0xe9, 0xf5, 0xf7, 0xe3, + 0xfd, 0x09, 0xef, 0xc8, 0x03, 0xfa, 0x01, 0x2e, 0xf7, 0x1b, 0x1c, 0xfd, 0xec, + 0xe7, 0xcd, 0xec, 0x0e, 0x46, 0xe6, 0xf9, 0xc6, 0xb0, 0x15, 0x50, 0xdf, 0xf0, + 0xe4, 0x12, 0x01, 0xe2, 0xc8, 0x0b, 0x12, 0x0e, 0x10, 0x0b, 0x21, 0x2b, 0xee, + 0x14, 0xd3, 0x12, 0xe3, 0xc7, 0xaf, 0xf0, 0xe8, 0xa4, 0xc4, 0xeb, 0x99, 0x15, + 0x32, 0x2c, 0xd3, 0xe5, 0xb4, 0xaf, 0x28, 0xce, 0xd1, 0xec, 0xb7, 0xd9, 0x4e, + 0xe4, 0xed, 0x5e, 0xc2, 0x2e, 0xd6, 0xdc, 0xf6, 0xe1, 0x30, 0xd1, 0xf6, 0xf0, + 0xc0, 0x00, 0xd1, 0x03, 0xde, 0xeb, 0x15, 0xef, 0xde, 0xc7, 0xfc, 0xd7, 0x35, + 0xef, 0xbd, 0xce, 0xda, 0xc0, 0xf7, 0x1c, 0x0c, 0xde, 0xe7, 0xbe, 0x09, 0xeb, + 0xbe, 0x12, 0xc9, 0x05, 0xe7, 0xe5, 0x0b, 0x1a, 0x23, 0x18, 0xf4, 0x0c, 0x09, + 0xf7, 0x1f, 0xc0, 0x2f, 0xfb, 0x16, 0xbf, 0x05, 0xe8, 0xe1, 0xf9, 0xea, 0x24, + 0xe9, 0x11, 0x3b, 0xfa, 0xeb, 0xcf, 0xe6, 0xdc, 0xd6, 0x1c, 0x1f, 0x03, 0xb8, + 0x0d, 0x0e, 0x01, 0x37, 0x08, 0x0a, 0x45, 0x2b, 0xf3, 0xe4, 0xf9, 0x1a, 0x0e, + 0x0d, 0xf6, 0x1b, 0xe8, 0xc5, 0x03, 0x14, 0x30, 0xe3, 0x45, 0xbd, 0x0a, 0xf8, + 0xb5, 0xee, 0x12, 0xe2, 0x17, 0x21, 0x32, 0x24, 0x32, 0x2e, 0x35, 0xf0, 0xe5, + 0x12, 0xd2, 0xe9, 0x11, 0x1e, 0x06, 0xf9, 0x21, 0x16, 0x36, 0x12, 0x0e, 0x05, + 0xe1, 0xb1, 0x2e, 0xe9, 0xe9, 0xe1, 0x01, 0x03, 0xe1, 0xfc, 0xf6, 0x29, 0x2d, + 0x12, 0x03, 0xfb, 0x37, 0x0e, 0x06, 0x30, 0xbd, 0x03, 0x40, 0xd9, 0x00, 0xe7, + 0x09, 0xfd, 0xef, 0xe6, 0xec, 0x2a, 0xf8, 0xfa, 0xfe, 0x09, 0xfd, 0x29, 0xd1, + 0xe5, 0x4a, 0xc9, 0xfc, 0xdd, 0xfe, 0x2f, 0x0e, 0xdd, 0x21, 0xda, 0x11, 0xee, + 0xc7, 0xfd, 0xfe, 0xcf, 0x02, 0xe3, 0x0b, 0xed, 0xf0, 0x6f, 0xf3, 0xf5, 0x11, + 0xf5, 0xbd, 0xf0, 0xeb, 0x08, 0x00, 0x08, 0xe8, 0x25, 0xfb, 0x08, 0x26, 0x17, + 0x06, 0xe6, 0xd7, 0x12, 0xf6, 0xc3, 0x05, 0xf9, 0x1d, 0xc8, 0xc5, 0xdb, 0xe5, + 0xc0, 0x18, 0x27, 0x10, 0xfc, 0xd7, 0x3a, 0x1f, 0x21, 0xf7, 0x01, 0x0c, 0xcd, + 0xed, 0x2e, 0xd3, 0xef, 0xda, 0xd9, 0x0a, 0xe8, 0xf6, 0x07, 0x00, 0x11, 0x12, + 0x01, 0xf2, 0xe7, 0xf5, 0x0e, 0xeb, 0x0a, 0x0f, 0x2f, 0xd4, 0xcb, 0x00, 0xf4, + 0xeb, 0xea, 0xec, 0xf1, 0x24, 0x0d, 0xdd, 0x1b, 0x00, 0xff, 0x11, 0x08, 0x0d, + 0xcd, 0x06, 0xf3, 0xc7, 0xde, 0xf4, 0x02, 0x23, 0x0e, 0x7f, 0xf3, 0x32, 0x11, + 0x12, 0x02, 0x2d, 0xd9, 0x48, 0xce, 0xe2, 0xc9, 0x14, 0xe5, 0xd7, 0x28, 0x20, + 0x1a, 0xc1, 0x36, 0xe7, 0x30, 0x38, 0xec, 0x0d, 0x4c, 0x3a, 0x24, 0xd2, 0xb1, + 0x3d, 0x19, 0xbb, 0xd3, 0xca, 0xdb, 0x03, 0xe3, 0xd7, 0x0e, 0xe0, 0xc3, 0xb5, + 0xe3, 0x3e, 0xe0, 0x0f, 0xd2, 0xec, 0xb8, 0xae, 0x2c, 0xf4, 0xec, 0xcd, 0x14, + 0xee, 0xe2, 0x52, 0xdf, 0x64, 0xf3, 0xef, 0x1e, 0xb3, 0x9c, 0x08, 0x02, 0xf2, + 0x1c, 0xd6, 0x20, 0x17, 0x2b, 0x20, 0xdc, 0xed, 0xfc, 0xf7, 0xc4, 0x21, 0xd2, + 0x47, 0x2a, 0x0b, 0x00, 0x09, 0x3d, 0x3e, 0xf3, 0x32, 0xc6, 0x0b, 0xc0, 0xf9, + 0x1c, 0x00, 0x14, 0xfb, 0xfe, 0x46, 0x1f, 0xcd, 0xdf, 0x40, 0xe5, 0x0d, 0xdd, + 0x24, 0xd8, 0xf7, 0xf3, 0xf4, 0x1e, 0x0c, 0xd4, 0x2c, 0x07, 0x92, 0xd9, 0x1a, + 0xda, 0x42, 0xd2, 0x33, 0x0c, 0xe6, 0xed, 0xf6, 0xe1, 0xca, 0x27, 0x11, 0xe2, + 0xf4, 0x81, 0x26, 0x08, 0xf4, 0x40, 0xcb, 0xb6, 0xf1, 0xf7, 0x22, 0xd2, 0xce, + 0xda, 0xe7, 0xd3, 0xf3, 0xdd, 0x43, 0x36, 0xff, 0x20, 0x10, 0x18, 0x06, 0xbf, + 0x07, 0x1c, 0x0e, 0x07, 0x03, 0x2a, 0xf0, 0xec, 0xc8, 0xf8, 0xb7, 0xe3, 0xe2, + 0x14, 0xde, 0xaf, 0xda, 0x3f, 0x0f, 0xfb, 0x11, 0x2a, 0xbd, 0xe7, 0x12, 0x04, + 0xf5, 0x24, 0x17, 0xf3, 0x05, 0x22, 0x3c, 0x1b, 0xe2, 0xfb, 0xb4, 0x38, 0x04, + 0x0a, 0x1c, 0x09, 0xf0, 0x34, 0xf7, 0xf5, 0x10, 0x32, 0xe9, 0xbc, 0x36, 0xc7, + 0xef, 0x1b, 0xff, 0x29, 0xf6, 0xfc, 0xfa, 0xd8, 0x0c, 0xae, 0x9a, 0x1b, 0x06, + 0x03, 0xbf, 0x09, 0x3a, 0xde, 0x16, 0x1f, 0xca, 0x0b, 0xd6, 0x21, 0xcb, 0xb2, + 0xc4, 0x1e, 0x05, 0xc8, 0xc7, 0xdf, 0xfb, 0x0c, 0xc7, 0xef, 0x11, 0xe3, 0xdc, + 0xe4, 0x0b, 0xe1, 0xf6, 0xe2, 0xce, 0xad, 0xea, 0x1c, 0xf2, 0xe8, 0xe8, 0xde, + 0xf2, 0xe8, 0xd7, 0xfe, 0xfc, 0x23, 0xc6, 0x47, 0x06, 0xdd, 0xde, 0x64, 0x0e, + 0xda, 0xfe, 0xd5, 0x21, 0x19, 0x06, 0xf7, 0xe9, 0xe6, 0xf9, 0x1e, 0xbc, 0xea, + 0x11, 0xe1, 0x0b, 0xd0, 0x20, 0x12, 0x39, 0xf1, 0x08, 0xed, 0xcb, 0x38, 0x0c, + 0xe3, 0xe5, 0xbf, 0x39, 0x00, 0xdd, 0xcc, 0xa3, 0x0f, 0xf4, 0x29, 0x1f, 0xd4, + 0x3d, 0x25, 0xe3, 0x62, 0xf2, 0xc1, 0x02, 0x97, 0x2a, 0xfd, 0xe1, 0xc8, 0xea, + 0x36, 0x0f, 0xf4, 0xc1, 0xfb, 0x26, 0xd4, 0x2d, 0xe2, 0x09, 0xe0, 0xfa, 0xae, + 0xff, 0xf7, 0x31, 0x08, 0x1b, 0x5e, 0x0b, 0xe1, 0xd1, 0x2b, 0xd2, 0xfa, 0xec, + 0xbc, 0xed, 0x44, 0xd7, 0xcf, 0x7f, 0xd8, 0xca, 0xe9, 0x0f, 0x53, 0x44, 0x3c, + 0x15, 0x24, 0x07, 0xd1, 0x1e, 0x9f, 0xd1, 0xca, 0xe6, 0xec, 0xba, 0xea, 0xbc, + 0xc7, 0xef, 0x0c, 0xf9, 0xe8, 0x1f, 0xf4, 0xf7, 0x47, 0xbb, 0xa3, 0xe9, 0xd4, + 0xda, 0xde, 0xe0, 0x01, 0xd8, 0x1c, 0x0b, 0x21, 0x26, 0xe0, 0x32, 0x26, 0x4f, + 0xe4, 0x4e, 0xf8, 0x01, 0xed, 0xef, 0xfa, 0xf9, 0x27, 0x1c, 0xe2, 0xfb, 0xd4, + 0xfd, 0xf7, 0x01, 0xdd, 0x95, 0x02, 0xea, 0xf1, 0x2e, 0x37, 0x16, 0x0b, 0x4a, + 0x17, 0x4b, 0xcb, 0x21, 0x2e, 0x26, 0x16, 0x0a, 0x14, 0x1b, 0xf9, 0x13, 0xb9, + 0xee, 0x3a, 0x46, 0xfe, 0x16, 0xf1, 0xa4, 0x45, 0xf1, 0x24, 0xf4, 0x11, 0x1e, + 0x2f, 0x03, 0xe9, 0x34, 0x52, 0xfa, 0xb4, 0x10, 0xec, 0x47, 0x2a, 0xd4, 0xd9, + 0x08, 0x70, 0x36, 0xd7, 0x22, 0xd1, 0xaa, 0xf0, 0x00, 0xbd, 0xdd, 0xee, 0xb1, + 0x05, 0x1a, 0x00, 0xd0, 0xbb, 0xbc, 0xf5, 0x07, 0xe6, 0xfc, 0x2a, 0xeb, 0xe0, + 0x01, 0xa0, 0xfd, 0xda, 0xde, 0xf4, 0xff, 0xeb, 0xe1, 0x14, 0x1c, 0xf3, 0xf0, + 0x02, 0xe4, 0xe5, 0xef, 0xe6, 0x06, 0x05, 0x17, 0x0f, 0x20, 0xc9, 0x01, 0xd6, + 0x1e, 0xf0, 0xc9, 0xb3, 0x2d, 0x00, 0x03, 0xb6, 0xd5, 0x17, 0x0a, 0xa5, 0x13, + 0xfd, 0x44, 0x17, 0xbc, 0xec, 0xd8, 0xf2, 0xe4, 0x05, 0x2b, 0xe8, 0xcf, 0xea, + 0x2f, 0xf2, 0xde, 0xf4, 0x0a, 0xe6, 0x00, 0x04, 0xde, 0xf2, 0x9e, 0xd3, 0x12, + 0x09, 0xf6, 0x16, 0x11, 0x38, 0xd5, 0x30, 0xf0, 0x3d, 0x0d, 0xef, 0x45, 0xd8, + 0x1c, 0xe7, 0x07, 0xc8, 0x13, 0xed, 0x17, 0xe9, 0x16, 0x47, 0x22, 0xf6, 0x81, + 0x45, 0x07, 0xf8, 0xab, 0x2f, 0xd8, 0xb9, 0xfd, 0xfb, 0xeb, 0xcb, 0xcb, 0xf9, + 0x3a, 0x2c, 0xe6, 0x0c, 0x93, 0xec, 0x1d, 0x12, 0x06, 0xd9, 0x15, 0xf6, 0x16, + 0x91, 0xf7, 0xd0, 0xdf, 0x2b, 0x1a, 0x30, 0xef, 0xc5, 0x05, 0x28, 0xbb, 0xc5, + 0x9d, 0xfd, 0xce, 0xe4, 0x13, 0xc7, 0x0e, 0xd5, 0xcb, 0xeb, 0xd1, 0xdb, 0x3f, + 0x25, 0x02, 0x01, 0xa2, 0x47, 0xe0, 0xf6, 0x3d, 0xd3, 0x1a, 0x30, 0x1a, 0x25, + 0xdf, 0xc6, 0x0d, 0xfd, 0x2d, 0xde, 0xdb, 0xd4, 0x43, 0xc5, 0x35, 0xee, 0xf4, + 0x13, 0xd0, 0xe2, 0xb8, 0x05, 0x2f, 0xe4, 0xaa, 0x17, 0x36, 0xe3, 0x4e, 0x2e, + 0x09, 0x01, 0xef, 0x06, 0xb2, 0xeb, 0x04, 0x2e, 0x12, 0x02, 0x16, 0xf0, 0x0f, + 0xda, 0x14, 0xfa, 0xd2, 0xba, 0xe9, 0x02, 0x2e, 0x17, 0xeb, 0xcb, 0x8d, 0x06, + 0xd3, 0xa7, 0x17, 0x15, 0x1a, 0x0f, 0xcf, 0x23, 0x3d, 0xff, 0x33, 0xd4, 0x21, + 0xfe, 0xbe, 0xf8, 0xf0, 0xd0, 0xbf, 0xab, 0x11, 0xe0, 0x18, 0xb1, 0x41, 0xb5, + 0x26, 0x1e, 0xff, 0x07, 0x37, 0xec, 0xbc, 0x96, 0x19, 0x0c, 0x1b, 0xf0, 0x48, + 0x2f, 0xc6, 0xd2, 0xd8, 0xbc, 0xf9, 0x11, 0xbb, 0xff, 0xe7, 0xe7, 0x1f, 0x3d, + 0x24, 0xff, 0x16, 0x54, 0x0c, 0xdf, 0x1b, 0xd3, 0xba, 0xf6, 0x43, 0x01, 0xd8, + 0x4f, 0x23, 0x02, 0x00, 0x41, 0xab, 0xdb, 0xbe, 0x12, 0xf7, 0xfe, 0xcc, 0xdb, + 0xaf, 0x2c, 0xf3, 0x10, 0xea, 0x96, 0x18, 0x00, 0xf4, 0xf0, 0x06, 0xbc, 0x00, + 0xac, 0xe3, 0x3d, 0xa3, 0xbb, 0xba, 0xf5, 0xd5, 0x19, 0xe6, 0xa6, 0xff, 0x56, + 0xf8, 0x07, 0x26, 0xeb, 0x11, 0xed, 0xb1, 0xcb, 0xc9, 0x07, 0x27, 0x69, 0xaa, + 0xef, 0x06, 0x4b, 0xf1, 0xe6, 0xe4, 0x21, 0xa4, 0xe1, 0xda, 0xe7, 0xe2, 0xb9, + 0x30, 0x0c, 0x0a, 0x44, 0x2c, 0xdc, 0xf3, 0xe8, 0xe3, 0xe0, 0x1a, 0xcb, 0xa4, + 0xfd, 0x07, 0xdf, 0xd8, 0x11, 0xe1, 0x08, 0x2b, 0xcc, 0x15, 0x13, 0xd0, 0xc0, + 0xf3, 0x22, 0x59, 0xd2, 0x33, 0xf5, 0x1d, 0xd9, 0xfc, 0xd6, 0x30, 0x1a, 0xf5, + 0xd5, 0x19, 0x1c, 0x11, 0xd7, 0x20, 0x3f, 0xd9, 0xdb, 0x18, 0xf7, 0xae, 0xfd, + 0x15, 0x54, 0x06, 0x27, 0xc8, 0xe6, 0xa4, 0xc4, 0x3f, 0x03, 0x4f, 0xda, 0xaf, + 0xd1, 0xad, 0xf7, 0x31, 0x37, 0x1b, 0xa6, 0xe6, 0x32, 0x2e, 0x04, 0x15, 0x1a, + 0x0f, 0xb8, 0xc0, 0x37, 0xbc, 0x81, 0x09, 0xe5, 0x1b, 0x51, 0x94, 0x10, 0x19, + 0x1b, 0xf5, 0xea, 0xc5, 0xee, 0x00, 0xe5, 0xcd, 0x01, 0xfe, 0x11, 0x9b, 0xa2, + 0x05, 0xd7, 0xab, 0xe7, 0xfd, 0xb6, 0xd9, 0xec, 0xe3, 0x3d, 0xbb, 0x1f, 0x10, + 0x1e, 0xe7, 0xdd, 0xeb, 0x4d, 0x21, 0xd2, 0x35, 0x9d, 0x53, 0x41, 0x23, 0x1c, + 0xe5, 0xc6, 0xf7, 0x15, 0xd4, 0x3d, 0x1a, 0x0d, 0xec, 0xba, 0x23, 0xfc, 0x02, + 0x38, 0xa1, 0x04, 0xf5, 0x99, 0xff, 0x49, 0xbc, 0xab, 0xba, 0xad, 0xe3, 0xb7, + 0x19, 0xcf, 0xf7, 0x0e, 0x25, 0x68, 0x13, 0xbe, 0xcb, 0xd7, 0x1b, 0xd5, 0x29, + 0xfe, 0x0c, 0x42, 0x1d, 0x61, 0x0b, 0xfa, 0x08, 0xf0, 0xde, 0xff, 0xf3, 0xbd, + 0x29, 0x9d, 0xb1, 0xf6, 0x50, 0x07, 0x55, 0xf8, 0x1e, 0xe2, 0xfe, 0x19, 0xfc, + 0xc5, 0xde, 0xdc, 0x0d, 0xfb, 0x17, 0x13, 0xf6, 0xf3, 0xf4, 0xfe, 0xe8, 0x0e, + 0xc7, 0xee, 0xb8, 0xd1, 0x5a, 0xd4, 0x1a, 0xbe, 0xe9, 0x1e, 0xb2, 0x15, 0xa6, + 0xc0, 0x06, 0xd4, 0x0f, 0xcd, 0xec, 0x0d, 0xd9, 0x03, 0xd9, 0xc9, 0xd2, 0x05, + 0xdf, 0x23, 0xd2, 0xbe, 0x66, 0xec, 0xf7, 0xbf, 0x02, 0xd8, 0xdc, 0x60, 0xf3, + 0x27, 0x28, 0xe5, 0xf7, 0xfa, 0xca, 0xbe, 0x2f, 0x0d, 0xcc, 0xd8, 0x0a, 0xff, + 0x18, 0x11, 0xfa, 0x01, 0xe9, 0x2e, 0xd6, 0x03, 0x4b, 0xe4, 0x20, 0x0c, 0xe3, + 0xca, 0xb2, 0x12, 0x34, 0x13, 0x42, 0x49, 0x0e, 0xd3, 0xc5, 0xee, 0xfe, 0x16, + 0x09, 0x03, 0x39, 0x1d, 0xcf, 0xcc, 0xff, 0x0b, 0xb9, 0xf8, 0x10, 0xf4, 0x34, + 0xd7, 0xe5, 0x05, 0x06, 0xd7, 0x02, 0xd0, 0xe7, 0xe0, 0xb6, 0xc2, 0xbc, 0xca, + 0xd3, 0xcd, 0x1a, 0xdc, 0xeb, 0x28, 0x2c, 0x1a, 0x07, 0x16, 0x86, 0xd9, 0x01, + 0x02, 0xeb, 0xc1, 0xcc, 0x58, 0xd1, 0x17, 0x06, 0xe0, 0x6d, 0xdd, 0x05, 0x19, + 0x2e, 0x04, 0x0d, 0x3d, 0xe6, 0xd9, 0xfe, 0x02, 0x0f, 0xf0, 0x10, 0xfb, 0xff, + 0x13, 0xc1, 0xe7, 0xe8, 0x01, 0xc0, 0xfa, 0x01, 0xed, 0x34, 0x16, 0xf2, 0xe1, + 0xea, 0x03, 0x14, 0xe4, 0xed, 0x25, 0x12, 0x11, 0xee, 0x01, 0x18, 0x0d, 0xdd, + 0xfe, 0xb7, 0x1c, 0x04, 0x14, 0xfc, 0x00, 0xcd, 0x24, 0x08, 0x0e, 0xfc, 0x0b, + 0xdc, 0x23, 0xf9, 0xba, 0x5b, 0x31, 0x28, 0xc0, 0x1b, 0xdd, 0x31, 0x20, 0x09, + 0xea, 0xf5, 0x7e, 0xca, 0xcb, 0x0d, 0xb8, 0xf5, 0x09, 0xf8, 0xad, 0xec, 0x0f, + 0xd3, 0xfd, 0x0d, 0xe7, 0xc7, 0x82, 0xe6, 0xd9, 0x03, 0x05, 0x26, 0xe0, 0xe0, + 0xde, 0xfd, 0xde, 0x05, 0x81, 0xea, 0xd9, 0xfc, 0x0e, 0xeb, 0xcd, 0x12, 0xf4, + 0xc1, 0x0a, 0xdd, 0xdc, 0xea, 0xef, 0xdb, 0xe2, 0x07, 0xe8, 0xe4, 0xaa, 0xd4, + 0x2b, 0xb1, 0xce, 0x04, 0xfd, 0xf3, 0xe7, 0xd6, 0x4e, 0x83, 0xd1, 0x89, 0xa6, + 0x2f, 0x00, 0x06, 0xc9, 0x36, 0x1f, 0x35, 0x28, 0xee, 0xdf, 0x1a, 0x11, 0x2e, + 0xb4, 0xc7, 0x23, 0x37, 0xf9, 0x2f, 0x0d, 0xdb, 0xe8, 0x11, 0x3a, 0xc2, 0x91, + 0x48, 0x34, 0x38, 0x13, 0x07, 0xe8, 0xa5, 0xcf, 0x27, 0x52, 0x8d, 0x0a, 0x04, + 0x3a, 0x17, 0x3d, 0x5c, 0xf6, 0xff, 0xe0, 0xd9, 0x4c, 0x20, 0x05, 0xb0, 0xe9, + 0xc6, 0x2b, 0x0c, 0xd7, 0x1d, 0xec, 0xb5, 0x7a, 0xd0, 0xa0, 0xd4, 0x49, 0x34, + 0x3d, 0x1b, 0x6e, 0x5f, 0x63, 0xff, 0xe3, 0x11, 0xa6, 0xff, 0x3e, 0x99, 0xcb, + 0xff, 0x88, 0xa1, 0x3b, 0xe1, 0xca, 0xa6, 0x2c, 0x3f, 0x3d, 0xf3, 0xb4, 0xb5, + 0x32, 0x53, 0xb2, 0xf2, 0x2a, 0x39, 0x11, 0xdc, 0x32, 0xdd, 0x5c, 0x60, 0x10, + 0xfe, 0xdb, 0x01, 0x18, 0xbf, 0x94, 0x34, 0xb2, 0xaf, 0xa2, 0xf4, 0x05, 0x2e, + 0x19, 0x09, 0xc8, 0x3f, 0x01, 0xfa, 0xfa, 0xe1, 0x17, 0x0f, 0x3c, 0xc6, 0xe6, + 0xf5, 0xb7, 0xf8, 0xe7, 0xed, 0x0d, 0xf5, 0xec, 0x1c, 0x27, 0xf6, 0x19, 0xec, + 0xd3, 0xc5, 0xc6, 0x9a, 0x11, 0x03, 0x58, 0x08, 0x09, 0x54, 0xd9, 0x36, 0xb7, + 0x26, 0xe7, 0x41, 0xf9, 0xfe, 0xf9, 0x20, 0x3e, 0x33, 0xb1, 0x01, 0xd2, 0x0f, + 0xf8, 0x36, 0x27, 0xbd, 0xe8, 0x06, 0x3b, 0x24, 0xf8, 0xf1, 0xa7, 0x52, 0x2b, + 0x25, 0xe7, 0x49, 0x2b, 0x01, 0xcf, 0xd9, 0x1b, 0x1b, 0xa1, 0xf1, 0x41, 0x24, + 0xcc, 0xcf, 0xaf, 0x4d, 0xcc, 0x58, 0x04, 0xd3, 0xbf, 0xde, 0x13, 0xca, 0x41, + 0x06, 0xfb, 0x33, 0xd7, 0xd3, 0xdc, 0xe2, 0x00, 0x12, 0xbb, 0xbd, 0xd9, 0x5a, + 0xf0, 0xcf, 0xf6, 0x12, 0x28, 0x02, 0x13, 0xd3, 0x9e, 0xff, 0xf4, 0x7f, 0x0c, + 0xf1, 0xb5, 0x09, 0xd4, 0x10, 0x8c, 0xff, 0x12, 0x23, 0x4a, 0x9f, 0xae, 0xed, + 0x17, 0xec, 0xd4, 0xf2, 0xd5, 0xa6, 0x2b, 0xe8, 0xcb, 0xde, 0x4d, 0xec, 0xf9, + 0xae, 0xaf, 0x0f, 0xa6, 0xcf, 0x08, 0x96, 0xd1, 0xb9, 0xa5, 0x1b, 0x1f, 0xf2, + 0xe6, 0x36, 0xf5, 0x97, 0xfc, 0x19, 0x34, 0xe0, 0xeb, 0x02, 0x40, 0xde, 0xf5, + 0x2d, 0xb7, 0xce, 0xae, 0xb9, 0x1a, 0x05, 0x5d, 0x64, 0xdb, 0xf2, 0x67, 0x27, + 0xf6, 0x1f, 0xa5, 0xb9, 0xe4, 0xf3, 0xc6, 0x6b, 0x8d, 0x12, 0xf6, 0x48, 0xed, + 0xf4, 0xfe, 0xc7, 0x32, 0xe4, 0x96, 0x27, 0xde, 0xcc, 0x44, 0x16, 0xe7, 0xeb, + 0xef, 0xbb, 0x23, 0x4f, 0x36, 0x0b, 0xf4, 0xbb, 0xcb, 0x05, 0xdf, 0x0f, 0x24, + 0xc1, 0x3c, 0xc8, 0xb4, 0xb9, 0xcf, 0xf5, 0x36, 0xa9, 0x05, 0x51, 0x29, 0xef, + 0xc9, 0x15, 0xdc, 0x99, 0xe0, 0xbf, 0xf1, 0x21, 0x3f, 0xfb, 0xe0, 0xfe, 0x3e, + 0x31, 0xf2, 0xef, 0xcd, 0xc7, 0xa6, 0xc3, 0xfa, 0xce, 0x2d, 0xae, 0xcd, 0xe9, + 0xce, 0x15, 0x1b, 0x2b, 0x29, 0xbc, 0xf1, 0xfa, 0xe6, 0x0b, 0x3e, 0xc8, 0x27, + 0x2c, 0xe7, 0xc0, 0xe1, 0x2c, 0x5b, 0x59, 0x0f, 0xca, 0xca, 0x23, 0x9b, 0xc2, + 0x34, 0x6c, 0x12, 0x0c, 0xc1, 0xe7, 0xf4, 0x27, 0x0c, 0x02, 0xbb, 0xf8, 0x06, + 0xda, 0xe5, 0xd3, 0xe6, 0xb5, 0x4a, 0x2e, 0x18, 0xf9, 0xea, 0x20, 0x22, 0x33, + 0xdd, 0xec, 0xdc, 0xd2, 0x04, 0xd7, 0xed, 0xf0, 0xbb, 0x9e, 0xbc, 0x0d, 0xea, + 0xe5, 0xc9, 0xcd, 0xec, 0x1e, 0x99, 0xa0, 0xe0, 0xfd, 0x1b, 0xa4, 0x3a, 0xfe, + 0xd7, 0xea, 0xa6, 0x3c, 0x8f, 0x1b, 0x18, 0x42, 0xf8, 0xf8, 0x05, 0x25, 0x52, + 0x2b, 0x06, 0xe8, 0x69, 0xf5, 0xc4, 0xd8, 0x0e, 0x05, 0x03, 0xf6, 0x58, 0x40, + 0xd6, 0x46, 0x02, 0x5d, 0x81, 0xdb, 0x99, 0xf2, 0xd2, 0xd7, 0xd1, 0x0b, 0x0d, + 0xc5, 0xc6, 0x05, 0x0b, 0x52, 0xfe, 0xb9, 0x1d, 0x28, 0xbe, 0x33, 0x36, 0xff, + 0xf5, 0xab, 0x53, 0xed, 0x62, 0xfd, 0xb1, 0x54, 0x26, 0xf5, 0x32, 0xd0, 0xba, + 0x02, 0xfa, 0x96, 0x37, 0x03, 0xcf, 0x19, 0xa7, 0x16, 0x3c, 0xe3, 0x8e, 0x8f, + 0xe4, 0xf4, 0xba, 0xaf, 0x95, 0xed, 0x29, 0xbb, 0xb7, 0x3d, 0x29, 0xfa, 0xba, + 0x0a, 0xf8, 0x24, 0x02, 0x43, 0xb6, 0x38, 0xd9, 0x22, 0x0c, 0x23, 0x45, 0xf4, + 0x0b, 0x04, 0x3d, 0x13, 0xfb, 0x42, 0x59, 0xd7, 0xd4, 0x59, 0x0c, 0xe4, 0x49, + 0x34, 0xae, 0x35, 0x28, 0xb7, 0xb7, 0x43, 0xd8, 0x1a, 0x83, 0x38, 0x35, 0xf9, + 0x48, 0x3d, 0xc7, 0x54, 0x66, 0x0c, 0xc9, 0xb5, 0xae, 0xe9, 0xb9, 0xe7, 0x2c, + 0x3e, 0xdf, 0xef, 0xde, 0x93, 0xa7, 0xf7, 0xdb, 0x44, 0xad, 0xfa, 0x04, 0xfc, + 0x1d, 0x18, 0x24, 0x1f, 0xb9, 0x01, 0xb2, 0xe8, 0xe2, 0x9c, 0xd3, 0xb0, 0xe2, + 0x03, 0x35, 0xe4, 0x3d, 0xe5, 0x1e, 0x2c, 0xad, 0x2e, 0x1e, 0xba, 0xb1, 0x0d, + 0xa6, 0xe9, 0x0e, 0xe9, 0x06, 0x85, 0xfa, 0x11, 0x32, 0xeb, 0x18, 0x47, 0xdf, + 0x98, 0x29, 0x22, 0xcb, 0x05, 0xdb, 0xe4, 0x1f, 0xf5, 0x3c, 0x6c, 0xf2, 0x14, + 0x18, 0x1b, 0x5a, 0xe8, 0xd8, 0xc9, 0xf6, 0xeb, 0x1b, 0xc3, 0x07, 0xd6, 0xac, + 0xb9, 0x11, 0xc4, 0x20, 0xd4, 0x1a, 0x28, 0xc2, 0x25, 0x53, 0x37, 0x10, 0xdf, + 0x08, 0xf3, 0x1a, 0xcd, 0x01, 0x38, 0x50, 0x47, 0xe0, 0x17, 0xc8, 0xd5, 0xef, + 0x9c, 0x3c, 0xf4, 0x17, 0x8d, 0xb8, 0x04, 0xa8, 0xea, 0x29, 0xf5, 0x5c, 0xe2, + 0x20, 0xf2, 0x23, 0x7f, 0x36, 0x13, 0xb1, 0xe9, 0x32, 0x05, 0xca, 0xf4, 0x02, + 0xfe, 0x11, 0x0d, 0xf1, 0x31, 0x9c, 0xdb, 0x13, 0x4d, 0x1a, 0x01, 0xf2, 0x18, + 0xf9, 0xbe, 0xcf, 0x61, 0xf2, 0x3f, 0x3f, 0x29, 0x0d, 0x28, 0x15, 0x92, 0x0e, + 0xea, 0xe4, 0x18, 0xd5, 0x15, 0xc7, 0x8d, 0x07, 0x3e, 0xb4, 0xc5, 0xdb, 0x03, + 0x00, 0xc9, 0xbd, 0x0b, 0xaf, 0xde, 0xf7, 0x0c, 0xdd, 0x09, 0x0a, 0xb6, 0xf6, + 0x1c, 0xc8, 0x11, 0x1e, 0xf9, 0xd4, 0xbd, 0xfe, 0xe7, 0x27, 0xe4, 0xe4, 0xf0, + 0xde, 0x2a, 0xcd, 0xdd, 0x0d, 0xd7, 0x10, 0xd3, 0x0c, 0x0b, 0xe6, 0x1b, 0xce, + 0xf0, 0x0a, 0x2a, 0xe7, 0x7a, 0xeb, 0xea, 0x18, 0xe7, 0x0f, 0xcd, 0xec, 0xba, + 0x14, 0xb7, 0xe4, 0x23, 0x0b, 0x1c, 0x40, 0x85, 0xdd, 0x9a, 0xe6, 0xd8, 0xbc, + 0x0c, 0xed, 0x20, 0xff, 0xfd, 0x9f, 0x37, 0x09, 0x41, 0x39, 0xed, 0xab, 0x1e, + 0x0f, 0xfb, 0xe8, 0x33, 0xc7, 0xc8, 0x04, 0xd0, 0x00, 0x04, 0xff, 0xfd, 0x07, + 0x16, 0x11, 0xdd, 0x05, 0x0d, 0xe3, 0xca, 0xe1, 0x06, 0x09, 0xda, 0x28, 0x06, + 0xfe, 0xeb, 0x31, 0x51, 0xc6, 0xf4, 0x0e, 0xfa, 0xce, 0x07, 0xfe, 0xe0, 0x30, + 0x42, 0xea, 0x18, 0xf4, 0xe2, 0xd1, 0xf2, 0xce, 0x39, 0xa3, 0xc2, 0x0f, 0x9e, + 0x37, 0xb0, 0x81, 0xe8, 0x1e, 0x04, 0xce, 0x1e, 0xc3, 0x45, 0x11, 0x54, 0x08, + 0xcf, 0xe3, 0xf7, 0xb3, 0x44, 0x1c, 0xc3, 0xf2, 0x23, 0x11, 0xfb, 0x26, 0x0c, + 0xf4, 0x00, 0xef, 0xf3, 0x00, 0xb9, 0xf4, 0xed, 0x17, 0xd7, 0x1c, 0xd1, 0xe7, + 0xed, 0xbf, 0x3f, 0xe3, 0xca, 0x23, 0x15, 0x0d, 0x08, 0xa7, 0xf8, 0x33, 0xf3, + 0x41, 0x0a, 0xbc, 0x05, 0xd9, 0x35, 0xd8, 0xba, 0xda, 0xea, 0xfe, 0xd3, 0x0c, + 0x1a, 0xd8, 0xb9, 0x24, 0xfc, 0x0c, 0x11, 0x0d, 0x24, 0xdb, 0x13, 0x4b, 0x0d, + 0xc3, 0xd9, 0xf3, 0xc9, 0x11, 0xeb, 0x10, 0xd2, 0xdb, 0xe1, 0xc7, 0x63, 0x16, + 0x08, 0x0a, 0xd0, 0xf3, 0x06, 0xb6, 0x22, 0xf2, 0x05, 0xa3, 0xdb, 0xfc, 0xfb, + 0x08, 0xff, 0xd3, 0xf8, 0xc8, 0x0f, 0x20, 0xc2, 0xed, 0xec, 0x1c, 0xdf, 0x29, + 0xdf, 0x12, 0xdf, 0xd6, 0xec, 0x56, 0xc7, 0xf3, 0x11, 0xae, 0xf6, 0xf6, 0x1a, + 0xd5, 0xcd, 0xdd, 0x04, 0xdb, 0x0d, 0xde, 0xd5, 0xf7, 0x4c, 0xd7, 0xec, 0x0b, + 0x25, 0xf9, 0x11, 0xfa, 0x1d, 0xf7, 0x3e, 0xfb, 0xc5, 0xdd, 0x23, 0xb2, 0x26, + 0xc6, 0xe6, 0x14, 0xd0, 0x1d, 0x25, 0x14, 0x2f, 0x21, 0xc0, 0x26, 0xe6, 0xce, + 0x1a, 0xd6, 0xf8, 0x00, 0x02, 0x08, 0x0d, 0xee, 0x17, 0xff, 0xbf, 0xeb, 0x3b, + 0xf5, 0x1c, 0xe0, 0xe6, 0x2d, 0x05, 0xb6, 0xe2, 0xef, 0x3a, 0xfa, 0x29, 0x70, + 0xda, 0xc2, 0xc1, 0xd5, 0x0a, 0x43, 0x15, 0xfe, 0xeb, 0x0c, 0xc5, 0xca, 0x2d, + 0xf8, 0x05, 0xf3, 0xf2, 0xfb, 0x3d, 0xf9, 0x35, 0x03, 0xee, 0xb6, 0x23, 0xd5, + 0xbb, 0xb8, 0xfc, 0xfc, 0xbd, 0xcd, 0x10, 0xb4, 0x0c, 0xfe, 0x1b, 0xf8, 0x12, + 0x12, 0xad, 0xfc, 0xa1, 0xbd, 0x16, 0x39, 0xee, 0xd5, 0xd2, 0xf7, 0xef, 0xd9, + 0xd3, 0xfd, 0x38, 0xf5, 0xde, 0x0f, 0x4c, 0xfd, 0x38, 0x38, 0xdb, 0x1a, 0x2d, + 0xce, 0xff, 0xed, 0x20, 0xe9, 0x1f, 0x23, 0xd3, 0xf8, 0x0c, 0x02, 0xb8, 0xc2, + 0xe6, 0x30, 0x2c, 0x0d, 0xe3, 0x01, 0x0c, 0x23, 0x3a, 0xe4, 0x07, 0x17, 0x31, + 0xe5, 0x17, 0xe8, 0x04, 0xe2, 0x9d, 0xd2, 0xe7, 0x27, 0xf0, 0x11, 0xdd, 0xe5, + 0xda, 0xc4, 0xe9, 0x17, 0xf1, 0x05, 0x17, 0x16, 0x32, 0xb1, 0x2c, 0x1e, 0x18, + 0xbf, 0xf6, 0xe4, 0x22, 0x08, 0xdc, 0x01, 0x1f, 0x7f, 0x02, 0xf2, 0x07, 0xd0, + 0xd7, 0x24, 0x06, 0xff, 0xf2, 0x37, 0x97, 0xe5, 0x0c, 0x0b, 0xf3, 0xcb, 0xd3, + 0xf3, 0xdb, 0x1c, 0x08, 0xe6, 0xfd, 0xda, 0x11, 0xda, 0x18, 0xe3, 0xd8, 0xfb, + 0xfa, 0x13, 0x09, 0x13, 0xfb, 0xe4, 0x12, 0x0a, 0xe0, 0xf7, 0xd3, 0xd3, 0x23, + 0xb8, 0x10, 0xa3, 0xe6, 0xc0, 0xe6, 0xde, 0xed, 0xdf, 0x05, 0xca, 0x16, 0xd2, + 0xe1, 0xfe, 0xd2, 0x30, 0xd7, 0x1b, 0xb6, 0x1a, 0x2a, 0xf5, 0xdc, 0x41, 0xd7, + 0x8a, 0x17, 0x2b, 0xd9, 0xec, 0xba, 0x1d, 0xa5, 0x06, 0x9b, 0x2c, 0x21, 0x18, + 0x9b, 0x1d, 0x1c, 0xc0, 0xe3, 0xce, 0x27, 0x16, 0xa4, 0x4a, 0xe3, 0x97, 0x9b, + 0x0b, 0xf8, 0x16, 0x3b, 0x26, 0x0a, 0xe6, 0xf5, 0x3d, 0x73, 0x2d, 0xfe, 0x00, + 0xc7, 0x41, 0xe6, 0xf7, 0x08, 0x03, 0x07, 0x28, 0x0d, 0xb5, 0xa9, 0xb0, 0xac, + 0x3b, 0xac, 0xd0, 0x32, 0xc8, 0xf9, 0x29, 0xf2, 0x07, 0xd3, 0xc4, 0xf3, 0xf3, + 0xfc, 0x20, 0xea, 0x12, 0xae, 0x84, 0xb1, 0x38, 0xe0, 0x66, 0xb4, 0xc5, 0xc0, + 0xf7, 0xc8, 0xb1, 0x2b, 0xb5, 0xb6, 0xf2, 0x09, 0x04, 0x2d, 0xdd, 0x81, 0xc4, + 0x13, 0xda, 0xf4, 0x06, 0xd5, 0x24, 0x1a, 0x20, 0x07, 0xd6, 0xea, 0xc0, 0xc2, + 0x06, 0xbb, 0xb1, 0xee, 0xdf, 0xff, 0x23, 0xcf, 0xb4, 0xb2, 0xfe, 0xf5, 0x13, + 0x1b, 0xea, 0x23, 0xc5, 0x05, 0x18, 0xa3, 0x00, 0x13, 0xe7, 0x33, 0x03, 0xff, + 0xa7, 0xf4, 0x16, 0x37, 0x68, 0x06, 0xa3, 0xec, 0x0f, 0x1c, 0x53, 0x28, 0xbc, + 0xd2, 0x0f, 0x28, 0x01, 0xe1, 0xdf, 0x7f, 0xb6, 0x26, 0xaf, 0x09, 0xff, 0xe6, + 0xcc, 0xa6, 0xef, 0xfb, 0x23, 0xc4, 0x4d, 0x16, 0xc0, 0x27, 0xdf, 0x93, 0x15, + 0xab, 0x9d, 0xcc, 0xcb, 0x1d, 0xb4, 0xe3, 0xfc, 0xf1, 0xdd, 0x10, 0xce, 0x9e, + 0x12, 0xf5, 0xdc, 0x38, 0xf2, 0x20, 0x4d, 0xac, 0xea, 0xe0, 0x24, 0xaf, 0x31, + 0xe6, 0xb1, 0x25, 0xc7, 0x1d, 0xf8, 0x04, 0xf9, 0x2c, 0xf9, 0xbd, 0xc8, 0xc0, + 0x53, 0x4c, 0xdf, 0x60, 0x05, 0xf3, 0xf3, 0x15, 0xd4, 0x12, 0xbc, 0xdc, 0x35, + 0x00, 0x08, 0xee, 0xb4, 0x20, 0xc2, 0x43, 0xe6, 0x11, 0xf9, 0x24, 0xcc, 0xdd, + 0x1c, 0x19, 0xef, 0x9e, 0x04, 0xfe, 0xf6, 0xc1, 0xd1, 0xf3, 0xf9, 0xe3, 0xf8, + 0x19, 0x39, 0xea, 0x38, 0x07, 0x28, 0x1a, 0x20, 0xca, 0xcf, 0xe8, 0xc2, 0xb4, + 0xe3, 0x33, 0xc8, 0xdd, 0xfb, 0x0a, 0x10, 0x33, 0x0c, 0xc8, 0x51, 0xd7, 0x11, + 0xcd, 0xc7, 0x0a, 0xf7, 0x3f, 0x26, 0x03, 0xf3, 0xec, 0x10, 0x16, 0xce, 0xee, + 0xf0, 0x03, 0x1f, 0xee, 0xe7, 0x0e, 0x43, 0xe9, 0xfb, 0xfe, 0xef, 0xc0, 0xc7, + 0x04, 0x06, 0x11, 0x18, 0xc4, 0xbd, 0x09, 0x06, 0xf4, 0x11, 0xdd, 0xde, 0x32, + 0x95, 0xa5, 0x07, 0x11, 0xe1, 0x03, 0x39, 0xea, 0x27, 0xef, 0xcf, 0x00, 0xc8, + 0xf0, 0x12, 0xf1, 0xf1, 0xe1, 0x2f, 0xbd, 0x59, 0x13, 0xc2, 0x0a, 0x24, 0xa8, + 0x36, 0x08, 0x3a, 0xde, 0xbb, 0xea, 0x24, 0x46, 0xfc, 0xd5, 0x12, 0xdb, 0xdd, + 0xe6, 0x21, 0xea, 0x00, 0xac, 0x25, 0x07, 0xfc, 0x0f, 0xec, 0xbe, 0xf0, 0x22, + 0xec, 0x0a, 0x3b, 0x1c, 0x30, 0x02, 0x2f, 0x4d, 0x19, 0xf6, 0xe8, 0x25, 0x24, + 0xe7, 0xc0, 0x1c, 0xa5, 0x27, 0x96, 0x1f, 0xd7, 0xf9, 0x2d, 0x16, 0x41, 0x22, + 0xe5, 0xdd, 0xf0, 0xec, 0x27, 0x09, 0x20, 0xf6, 0x14, 0x38, 0xdf, 0xc5, 0xf7, + 0x19, 0x25, 0x14, 0xd7, 0x28, 0xbf, 0xd5, 0xcb, 0x05, 0x50, 0xff, 0xed, 0x13, + 0xfe, 0xb7, 0xc9, 0xbc, 0x25, 0xd1, 0xeb, 0xd1, 0x55, 0xba, 0xef, 0x15, 0x51, + 0x03, 0xe7, 0xea, 0xb7, 0x09, 0xe9, 0x22, 0x37, 0xe2, 0x39, 0xd2, 0xe8, 0xe7, + 0x15, 0xac, 0x2f, 0xfa, 0x01, 0xdb, 0x49, 0xe4, 0xea, 0xda, 0xc9, 0xce, 0xfb, + 0xe1, 0x10, 0xe9, 0x14, 0xc3, 0x13, 0xd4, 0x46, 0xaa, 0x65, 0xe7, 0xb5, 0xf1, + 0xef, 0xfa, 0x37, 0x10, 0x02, 0xba, 0xee, 0xd4, 0xed, 0x33, 0x81, 0xcd, 0xb6, + 0x47, 0x0c, 0x10, 0xd2, 0x54, 0xe7, 0x0e, 0xe0, 0xe4, 0xf5, 0x02, 0x00, 0x0f, + 0xd7, 0xb5, 0x14, 0xff, 0xef, 0xdf, 0xfd, 0x03, 0xe9, 0x3d, 0xe1, 0xd3, 0x7f, + 0xfc, 0xeb, 0xf8, 0x9a, 0xe3, 0xf0, 0x2a, 0xef, 0xf2, 0xfe, 0x43, 0xde, 0xec, + 0xfb, 0xd2, 0xff, 0xe4, 0x1c, 0x04, 0xe6, 0x0a, 0x16, 0xec, 0xc7, 0x9d, 0xfc, + 0x0e, 0x2c, 0xcd, 0xc3, 0xed, 0xf1, 0x15, 0xf5, 0x05, 0xef, 0x27, 0x21, 0xef, + 0xda, 0xfc, 0x1d, 0x26, 0x28, 0x15, 0xff, 0x0d, 0xdf, 0x1e, 0x06, 0xe2, 0xba, + 0x28, 0xec, 0x04, 0xee, 0x04, 0x21, 0xff, 0x01, 0x1d, 0x15, 0xd3, 0x26, 0xf5, + 0xdf, 0x37, 0x06, 0xf2, 0x1a, 0xe7, 0x45, 0xf9, 0xfa, 0x2a, 0x25, 0xd8, 0x12, + 0xd3, 0x07, 0x1c, 0xe1, 0xfb, 0x00, 0xee, 0xdd, 0x27, 0x1f, 0xd9, 0xed, 0x14, + 0xf5, 0x1a, 0xcd, 0x3c, 0xfa, 0x1b, 0x00, 0xe2, 0xf4, 0xe2, 0x10, 0xdd, 0x17, + 0xd3, 0x15, 0xcd, 0x3d, 0x5c, 0xc4, 0x04, 0x03, 0xde, 0xed, 0xef, 0xeb, 0xe4, + 0xf7, 0x15, 0xbf, 0xe8, 0xee, 0xec, 0x05, 0x0a, 0xe1, 0x24, 0x26, 0xde, 0x09, + 0xfb, 0x2a, 0xf0, 0x29, 0xde, 0x09, 0xea, 0xf5, 0xdc, 0xf0, 0xfd, 0xfd, 0xbd, + 0xfa, 0xe1, 0x30, 0xc5, 0x08, 0xc6, 0xf5, 0xca, 0xfd, 0xea, 0xd4, 0xde, 0xe7, + 0xe7, 0x0a, 0xdf, 0xf1, 0xe4, 0xe9, 0x01, 0x04, 0xf9, 0xd8, 0x3c, 0xe6, 0xe3, + 0xeb, 0xe4, 0x22, 0xec, 0xdf, 0x15, 0x24, 0x07, 0x23, 0xff, 0x18, 0xf7, 0x0a, + 0xb7, 0xe5, 0x28, 0xe6, 0x0f, 0x0b, 0x06, 0xf8, 0xdc, 0x00, 0x20, 0xf4, 0xcb, + 0x06, 0xf6, 0xfe, 0xfb, 0xd3, 0xc2, 0x0b, 0x47, 0x05, 0x0c, 0x22, 0x07, 0x06, + 0xec, 0x1f, 0xe1, 0xfc, 0x08, 0xdf, 0xb6, 0xf1, 0x0b, 0x05, 0xf6, 0x38, 0x00, + 0xeb, 0x07, 0xcd, 0x19, 0x29, 0xda, 0xed, 0xfa, 0xfe, 0x39, 0xa8, 0xc1, 0x19, + 0xd9, 0xdf, 0x23, 0xec, 0x2a, 0xfc, 0x0a, 0x00, 0xc1, 0x26, 0xb7, 0xfe, 0xbd, + 0xf6, 0x48, 0x0a, 0xd6, 0xe3, 0xd5, 0xe0, 0x1a, 0xf3, 0x0e, 0x00, 0x19, 0x22, + 0xf8, 0xcf, 0x22, 0x04, 0xbf, 0xeb, 0x08, 0xee, 0xbb, 0xfd, 0xf6, 0xd9, 0x30, + 0x26, 0xd0, 0xe7, 0x01, 0x07, 0xee, 0x1f, 0x07, 0xf8, 0xb1, 0x41, 0x00, 0x17, + 0xb9, 0xd2, 0xeb, 0xce, 0x0b, 0xea, 0xe5, 0xf0, 0xd7, 0x1d, 0x10, 0xe8, 0x23, + 0x02, 0xdb, 0x25, 0x06, 0xdf, 0xe0, 0xf9, 0xec, 0xf1, 0xe1, 0xee, 0xfd, 0xea, + 0xde, 0xfe, 0x03, 0xd1, 0xe5, 0xd9, 0xfb, 0xed, 0x01, 0xe2, 0x1a, 0x02, 0x1a, + 0x31, 0xc8, 0x1b, 0x3c, 0xf5, 0xe2, 0xfd, 0x0d, 0x31, 0xec, 0x30, 0xb9, 0x3f, + 0xc8, 0xe7, 0x0a, 0x0f, 0xee, 0xea, 0xfd, 0xfd, 0x04, 0x01, 0x05, 0x27, 0xff, + 0xee, 0x00, 0xef, 0xd1, 0xc1, 0xde, 0x11, 0xf2, 0xe0, 0x0a, 0xbe, 0xed, 0x20, + 0x09, 0x08, 0xed, 0xd4, 0xc7, 0x08, 0x05, 0xcc, 0x00, 0xcf, 0xd3, 0x0d, 0x07, + 0x24, 0xc8, 0x0e, 0xe8, 0x4e, 0x41, 0xf1, 0xdf, 0xd8, 0xc5, 0x30, 0xfc, 0x12, + 0xf4, 0xfd, 0xdd, 0x23, 0x34, 0xf1, 0x18, 0xef, 0x20, 0x01, 0x01, 0x10, 0x04, + 0x03, 0x14, 0xf8, 0x0b, 0xcf, 0xfd, 0x35, 0xff, 0xf3, 0x0c, 0x0a, 0xc0, 0xb9, + 0xf9, 0x2d, 0x0f, 0xe0, 0x24, 0xef, 0x26, 0xae, 0xde, 0xdc, 0xf4, 0x1a, 0xe3, + 0x25, 0xfb, 0xd5, 0x1b, 0x22, 0xf7, 0x17, 0x1c, 0xb8, 0x40, 0xb7, 0xf0, 0xe1, + 0x09, 0x1c, 0xc3, 0xdf, 0xd1, 0xc9, 0xd6, 0xf2, 0xf6, 0x07, 0xd6, 0x0c, 0xd7, + 0xbb, 0xe5, 0xbd, 0xd6, 0xdf, 0xf9, 0x04, 0x17, 0xe2, 0xda, 0x1a, 0x45, 0x1c, + 0xd6, 0xe7, 0x0c, 0xdd, 0x14, 0x1a, 0xcf, 0x0f, 0xd1, 0xe3, 0xef, 0xd8, 0x27, + 0x16, 0xe3, 0xd1, 0xc9, 0x0e, 0xf9, 0xfb, 0xd9, 0x81, 0x13, 0xeb, 0x01, 0xe5, + 0x26, 0xee, 0x7f, 0xcf, 0xc3, 0xe0, 0xc1, 0x20, 0xd6, 0x01, 0xdf, 0x27, 0xfb, + 0xe9, 0x10, 0xb8, 0xfa, 0xda, 0x15, 0xb8, 0xe7, 0xc9, 0xeb, 0xbf, 0x03, 0xea, + 0xed, 0x11, 0xe5, 0x0f, 0xc5, 0xee, 0xe6, 0xa5, 0x03, 0x0a, 0x0e, 0x11, 0x24, + 0xdd, 0x11, 0xdc, 0x1c, 0xe1, 0xc5, 0x19, 0xf0, 0xd7, 0xdb, 0xdc, 0xc4, 0xec, + 0x10, 0x60, 0x3d, 0x25, 0x06, 0xf2, 0xee, 0x05, 0x23, 0xf3, 0xf4, 0xfb, 0xfb, + 0xb8, 0xfb, 0x02, 0xd3, 0x16, 0xae, 0xca, 0xfe, 0xa2, 0xfd, 0x16, 0xd2, 0xbe, + 0xec, 0xe6, 0xb0, 0xb9, 0xe5, 0x03, 0x07, 0x14, 0xa9, 0x25, 0xee, 0xc6, 0x1e, + 0xf5, 0xb1, 0xc5, 0xdb, 0xfb, 0xd5, 0x49, 0xda, 0x2e, 0xf1, 0xe7, 0x08, 0xe0, + 0xe4, 0xc2, 0xbf, 0xdd, 0x0a, 0xd5, 0xf1, 0xe3, 0xc1, 0x01, 0x42, 0xdc, 0xe4, + 0xfd, 0xfa, 0xd6, 0xd7, 0xcb, 0x37, 0xc3, 0xf1, 0xd8, 0x07, 0xbc, 0x21, 0xf8, + 0xc8, 0xc7, 0xf2, 0x38, 0xe6, 0xc4, 0xc3, 0x0a, 0xff, 0xb9, 0xf4, 0xc5, 0xda, + 0xc4, 0xf9, 0x3d, 0x00, 0x0d, 0x1c, 0x06, 0xfa, 0x35, 0x2e, 0xe8, 0xec, 0x05, + 0x04, 0x15, 0x26, 0xc0, 0xde, 0x23, 0xda, 0x23, 0xd7, 0x12, 0xa9, 0xf5, 0x36, + 0xfb, 0xc1, 0xe6, 0xaa, 0xf4, 0xfb, 0x1b, 0xd3, 0x1b, 0xea, 0xd0, 0xc7, 0x03, + 0xd4, 0x30, 0x0c, 0x0d, 0xed, 0x16, 0xf5, 0xd2, 0xc2, 0xf8, 0xe7, 0xd1, 0xa7, + 0xef, 0x07, 0xe4, 0xf5, 0x25, 0x2e, 0xd1, 0x58, 0xef, 0x15, 0xfe, 0x1d, 0xe7, + 0x14, 0xfe, 0x05, 0xda, 0xfc, 0x1a, 0x09, 0x95, 0xca, 0xe8, 0x0d, 0xce, 0x06, + 0x1a, 0x13, 0x1c, 0x05, 0x0c, 0x28, 0x02, 0x39, 0xe6, 0xc0, 0xe1, 0x02, 0xbf, + 0x36, 0x30, 0xf9, 0x1c, 0xc5, 0xa8, 0xff, 0xd0, 0x2d, 0xff, 0xf1, 0x0e, 0xf1, + 0x05, 0xfb, 0xd4, 0xf4, 0x24, 0x09, 0xec, 0x18, 0xf2, 0xfa, 0xe8, 0x11, 0xbb, + 0x41, 0xce, 0xbb, 0xd5, 0xf1, 0x01, 0x34, 0x16, 0xc3, 0xec, 0xfb, 0xbd, 0x61, + 0xd6, 0x20, 0xdb, 0xd9, 0xf9, 0xb1, 0xff, 0x03, 0x4a, 0x14, 0x31, 0xe8, 0xe5, + 0x14, 0xd0, 0xe6, 0xb3, 0x8c, 0x5e, 0xc3, 0x0e, 0xc4, 0xfd, 0x98, 0xf8, 0xfe, + 0x42, 0xa4, 0x1e, 0x16, 0xee, 0x15, 0xc9, 0xee, 0xe6, 0x31, 0x1e, 0xea, 0x53, + 0x2e, 0x81, 0x1b, 0xb6, 0xe6, 0x14, 0x28, 0xe4, 0x4f, 0x1f, 0x28, 0x11, 0xd6, + 0xd5, 0x5e, 0x39, 0x07, 0x1d, 0xdc, 0xb5, 0xea, 0xfe, 0x2b, 0x35, 0x54, 0xc3, + 0xba, 0x32, 0xec, 0xe9, 0xc3, 0x29, 0x13, 0xcc, 0xc4, 0xf8, 0x37, 0xbf, 0x85, + 0xb4, 0xcd, 0x23, 0xf4, 0xa4, 0xeb, 0xdc, 0x20, 0x48, 0x0b, 0xce, 0x03, 0x0d, + 0xf7, 0xdb, 0x93, 0x0d, 0xfd, 0xaf, 0x1c, 0x32, 0x24, 0x07, 0x0e, 0xb5, 0x3e, + 0x2a, 0xdc, 0x43, 0xe9, 0xe7, 0x1a, 0x1b, 0xe4, 0x28, 0x12, 0xf3, 0x28, 0xd1, + 0xc6, 0xfa, 0x18, 0xe8, 0x21, 0xef, 0x88, 0xea, 0xe8, 0xe2, 0x9b, 0xca, 0xdb, + 0x57, 0x0d, 0x07, 0x94, 0xf2, 0x2e, 0x9e, 0xda, 0xb6, 0x2c, 0x2d, 0xf6, 0xfa, + 0xba, 0x3f, 0xd9, 0x6c, 0x23, 0x06, 0x2d, 0xff, 0xfe, 0x27, 0x11, 0x1f, 0x13, + 0x1a, 0xd2, 0x1f, 0x99, 0xd9, 0xb0, 0xe7, 0xe4, 0xb2, 0x2c, 0xb0, 0xce, 0xcf, + 0x4a, 0x41, 0xbf, 0xb8, 0xd5, 0x93, 0xed, 0x55, 0xbe, 0x05, 0xed, 0xf1, 0x2b, + 0x27, 0x49, 0xcf, 0x05, 0x07, 0xd6, 0x21, 0x1b, 0xf3, 0xcc, 0x0c, 0xa9, 0x26, + 0x32, 0xd0, 0x1d, 0xc6, 0x18, 0x0c, 0x15, 0x08, 0xba, 0x19, 0xb9, 0xe7, 0xe4, + 0x42, 0x35, 0x11, 0xe2, 0xea, 0x05, 0xe9, 0x10, 0xb0, 0xd3, 0xe8, 0x25, 0x28, + 0xbf, 0xc5, 0xe9, 0x09, 0xd5, 0xed, 0x0d, 0x98, 0x22, 0xf0, 0x50, 0x0a, 0x26, + 0x33, 0x0e, 0xff, 0xca, 0xe0, 0x17, 0xd6, 0xe9, 0xf0, 0x1e, 0x02, 0x1d, 0xd1, + 0xfd, 0xe3, 0x1c, 0xfe, 0xe2, 0x42, 0xb2, 0x2f, 0x48, 0x07, 0xec, 0xb1, 0xb7, + 0x00, 0x88, 0x23, 0xd5, 0x21, 0xa2, 0x18, 0xd8, 0x81, 0xef, 0x0b, 0xf8, 0x01, + 0x25, 0x14, 0x3d, 0xc3, 0x00, 0x03, 0x0f, 0x42, 0xa1, 0x3a, 0xc3, 0x3b, 0xb8, + 0x4e, 0xdb, 0xf4, 0xf4, 0xfe, 0xea, 0x1b, 0x23, 0xc1, 0x23, 0x1a, 0x3b, 0xcc, + 0x22, 0x1d, 0x0c, 0x8c, 0xdd, 0xf5, 0xca, 0xed, 0xf8, 0xef, 0xf3, 0x1c, 0x2a, + 0xd3, 0xc0, 0xc9, 0xdc, 0xeb, 0x11, 0xeb, 0xe7, 0xc5, 0xcb, 0x02, 0xff, 0xfe, + 0xb9, 0xe3, 0xf3, 0x22, 0x4f, 0x10, 0xfb, 0x37, 0x0e, 0x2d, 0x1f, 0xc7, 0x1e, + 0xce, 0x1d, 0xfd, 0x12, 0x86, 0x39, 0xcd, 0xc5, 0x33, 0xce, 0xc3, 0x45, 0x11, + 0x24, 0x9f, 0x1b, 0xd0, 0x24, 0xf6, 0x22, 0xb7, 0x30, 0xc7, 0xb8, 0x2a, 0xef, + 0x02, 0x3d, 0x5c, 0x15, 0x60, 0xf2, 0xc6, 0xe3, 0xd5, 0x05, 0xc2, 0x0e, 0xe2, + 0xb2, 0xc6, 0x2e, 0xf4, 0xef, 0x0f, 0x98, 0xc4, 0xce, 0x1f, 0xe6, 0xd2, 0xaa, + 0xf2, 0x46, 0xc6, 0xe5, 0x62, 0x3f, 0xcc, 0x4f, 0xe9, 0xdf, 0x16, 0xed, 0x53, + 0xb6, 0xf3, 0xde, 0xc3, 0x89, 0x32, 0xc7, 0xe5, 0x04, 0x09, 0x2c, 0x07, 0xc0, + 0xe0, 0x4a, 0x31, 0x41, 0xdc, 0xb2, 0xbe, 0xc4, 0x3f, 0xf1, 0x09, 0xb0, 0x0f, + 0x42, 0x0c, 0x15, 0x26, 0xd6, 0xad, 0x29, 0xcc, 0x98, 0xb1, 0xe9, 0xd6, 0xf7, + 0xa8, 0xe4, 0xe4, 0x0a, 0xd2, 0x1c, 0xdf, 0xbe, 0xa9, 0xeb, 0x09, 0xdf, 0x2e, + 0x13, 0x31, 0x0a, 0x37, 0xad, 0x3c, 0xcb, 0xf3, 0x37, 0xe9, 0xe8, 0x3d, 0xae, + 0x14, 0xf2, 0xef, 0xe6, 0x18, 0x00, 0xc6, 0xc3, 0xe3, 0xf3, 0xcd, 0xb0, 0xee, + 0x28, 0x19, 0x4b, 0xb1, 0xd4, 0x2b, 0x0a, 0xe5, 0x05, 0x05, 0xee, 0xfb, 0xfa, + 0x23, 0xeb, 0x01, 0xf1, 0xe5, 0x1c, 0xe5, 0xd1, 0xb9, 0xeb, 0x18, 0xe1, 0x02, + 0xe6, 0x24, 0x24, 0xd6, 0xf3, 0x0b, 0x27, 0xfa, 0xe6, 0xce, 0xfe, 0xe9, 0xf3, + 0xe3, 0x06, 0x0d, 0x0d, 0xf4, 0x3f, 0xf6, 0xdc, 0x27, 0xd2, 0xf7, 0xd8, 0x01, + 0xe9, 0x05, 0x15, 0xf6, 0x17, 0xfd, 0x1d, 0x08, 0xcd, 0xf5, 0xfb, 0x06, 0x0d, + 0x08, 0xe0, 0x37, 0x20, 0x0b, 0x16, 0xfc, 0x29, 0x09, 0xdc, 0x16, 0xdc, 0x14, + 0x1a, 0x51, 0xc2, 0x58, 0x05, 0x16, 0xf9, 0x11, 0xee, 0x14, 0xd7, 0x22, 0x19, + 0xd3, 0xfc, 0xf3, 0x00, 0x44, 0xe5, 0xff, 0xea, 0xe5, 0x13, 0xd3, 0xee, 0xe9, + 0x0e, 0xf6, 0xdc, 0x49, 0xe1, 0xf9, 0x12, 0xe3, 0xcb, 0x04, 0xe0, 0xe1, 0x15, + 0xe9, 0xeb, 0x08, 0x01, 0x02, 0xda, 0x04, 0xf5, 0x13, 0xfd, 0xec, 0x1c, 0xdb, + 0x16, 0xed, 0xf8, 0xcc, 0x0f, 0xd2, 0x3d, 0x0e, 0xd6, 0x1d, 0x1b, 0x13, 0x19, + 0x13, 0x03, 0xf3, 0x1c, 0x24, 0x25, 0x4d, 0xc2, 0xc8, 0x00, 0xbf, 0x27, 0x18, + 0x15, 0x28, 0x02, 0x1a, 0x06, 0xe9, 0xde, 0x0e, 0x2a, 0xfe, 0x03, 0x10, 0x36, + 0xe4, 0xd6, 0xec, 0x0f, 0x0e, 0xf7, 0xd1, 0xe5, 0x12, 0xf5, 0xcf, 0x46, 0x12, + 0xd2, 0xd6, 0x10, 0x01, 0x7f, 0x0b, 0xd1, 0x22, 0xd6, 0xf7, 0xe4, 0xdf, 0xe6, + 0xf4, 0xda, 0xd5, 0xf3, 0x2f, 0xe2, 0x18, 0x09, 0xd2, 0xdb, 0xe2, 0x1c, 0xf5, + 0xd7, 0x1c, 0xed, 0xe2, 0xff, 0xb5, 0x38, 0xd7, 0xf6, 0xbc, 0x2b, 0x06, 0xc5, + 0xea, 0x14, 0xf3, 0xb7, 0xfa, 0xfe, 0x20, 0x12, 0xe8, 0x27, 0xd1, 0xf4, 0xdc, + 0xf3, 0xf1, 0xfb, 0x37, 0x29, 0xfc, 0x0d, 0xc5, 0xfc, 0xcd, 0x1d, 0xff, 0xc4, + 0xd4, 0xc5, 0x25, 0xf9, 0x16, 0x0a, 0x18, 0xfc, 0x08, 0x03, 0xd9, 0xf3, 0xe1, + 0xfc, 0xea, 0x06, 0x19, 0xe5, 0x05, 0xfe, 0x01, 0xe6, 0xfc, 0x1f, 0x24, 0xd9, + 0x10, 0xfc, 0xfc, 0xe5, 0xd8, 0x30, 0x10, 0xcc, 0x04, 0xd7, 0xe5, 0xad, 0x0a, + 0xf4, 0xfc, 0x21, 0xb5, 0x16, 0x03, 0x30, 0x1f, 0x3f, 0xfa, 0xe1, 0x3b, 0xf2, + 0xc1, 0xe1, 0xe1, 0x0c, 0x15, 0xe7, 0xee, 0x19, 0xfd, 0x38, 0xef, 0xfc, 0xf4, + 0xf0, 0x0e, 0xf8, 0x2d, 0xdb, 0xc9, 0xeb, 0x18, 0x48, 0x1d, 0x14, 0xd6, 0x2e, + 0xd9, 0x27, 0xaf, 0x2a, 0xe6, 0xe1, 0xe8, 0x07, 0x2d, 0xff, 0xe7, 0xd8, 0xcf, + 0xc6, 0x09, 0x29, 0xd9, 0x0d, 0xd2, 0xe3, 0x3f, 0xbe, 0x09, 0xf5, 0x0d, 0x02, + 0xea, 0x14, 0xfc, 0xe9, 0x01, 0xb3, 0x04, 0x1d, 0xf1, 0xfc, 0xe0, 0x36, 0x39, + 0xff, 0xa9, 0xfc, 0xdb, 0x04, 0x09, 0x23, 0xf0, 0x28, 0xca, 0xd6, 0xed, 0x08, + 0xf0, 0x97, 0xf3, 0xec, 0xf4, 0x50, 0x0e, 0x56, 0xff, 0xe5, 0x20, 0xf7, 0xcb, + 0xf0, 0x13, 0xf4, 0xfa, 0x0f, 0x23, 0x7f, 0x0f, 0x04, 0xe0, 0x2e, 0xff, 0xd5, + 0xbd, 0x09, 0xe6, 0x11, 0x27, 0xfc, 0xb6, 0xfd, 0xa8, 0xd8, 0xe8, 0xf1, 0x08, + 0xc1, 0xdb, 0x1a, 0x00, 0xf1, 0x2c, 0xc1, 0xf5, 0xad, 0x10, 0x05, 0xe9, 0x07, + 0xed, 0xca, 0xdb, 0xd8, 0x13, 0xd9, 0x0c, 0x09, 0xe2, 0xe6, 0xd4, 0x25, 0x17, + 0xff, 0x17, 0xf0, 0x50, 0xfb, 0x04, 0x18, 0xdd, 0xef, 0x21, 0xd0, 0xfc, 0xe9, + 0xe3, 0xfe, 0xc1, 0xf0, 0x24, 0xfd, 0x0f, 0x05, 0x08, 0xef, 0xf7, 0x1c, 0xd4, + 0xce, 0xff, 0xb1, 0xdf, 0x16, 0x05, 0xf0, 0xd8, 0xe3, 0xf6, 0xe9, 0x1a, 0x1a, + 0xf8, 0xfd, 0xe5, 0xc1, 0x1d, 0x03, 0x0a, 0xd0, 0xf6, 0xf6, 0x16, 0x27, 0xe8, + 0x04, 0x3c, 0xd3, 0xba, 0xc8, 0x35, 0x29, 0x14, 0x17, 0x03, 0xeb, 0xca, 0x44, + 0xee, 0xe4, 0xb4, 0x0e, 0x16, 0x16, 0x0b, 0xfc, 0xd5, 0x04, 0xea, 0x19, 0xdd, + 0xe5, 0x11, 0x23, 0x18, 0x36, 0xe9, 0xb7, 0xfd, 0x2f, 0x1e, 0x8c, 0xbf, 0x4b, + 0x17, 0xba, 0xe8, 0xef, 0x0f, 0xaf, 0xc8, 0x11, 0xdf, 0x13, 0x98, 0x29, 0x20, + 0x12, 0x4c, 0xe9, 0x9c, 0x28, 0x18, 0xc9, 0x24, 0xf5, 0xf5, 0xe3, 0x9b, 0x21, + 0x19, 0xe1, 0xd0, 0xb5, 0xf7, 0x41, 0x0a, 0xef, 0x88, 0xd0, 0xe5, 0xc1, 0xf0, + 0xfc, 0xca, 0xc6, 0x06, 0xf0, 0xea, 0x21, 0xf2, 0x1e, 0xd5, 0xc3, 0xf6, 0xfb, + 0x09, 0x01, 0x9a, 0x13, 0x04, 0xb0, 0xbb, 0x0b, 0x18, 0x05, 0xa0, 0x01, 0xcc, + 0xe3, 0x45, 0x81, 0xae, 0x28, 0x98, 0xe3, 0x8a, 0x1c, 0x6b, 0xe6, 0xca, 0xf9, + 0x1d, 0xe7, 0x08, 0x1a, 0xcd, 0xda, 0x58, 0x4c, 0x0f, 0xa9, 0xf1, 0x16, 0x08, + 0xa6, 0x47, 0x05, 0xd5, 0x17, 0xfc, 0x39, 0x31, 0xe1, 0x5f, 0x12, 0x5f, 0x00, + 0xf0, 0xac, 0xe5, 0x29, 0xbc, 0xec, 0xf2, 0x11, 0x07, 0x33, 0x0e, 0x19, 0x1e, + 0xbb, 0x29, 0xfc, 0xc4, 0xb3, 0x41, 0x59, 0x15, 0xe4, 0x64, 0x57, 0xf0, 0xb7, + 0xeb, 0xef, 0x00, 0xad, 0xc7, 0x19, 0xdb, 0xed, 0x15, 0xdc, 0xfa, 0xeb, 0xde, + 0x26, 0xd2, 0x0c, 0x8b, 0xf0, 0x3b, 0x04, 0xed, 0xee, 0x1d, 0xe9, 0xe6, 0x23, + 0xe3, 0x34, 0x34, 0x07, 0x4f, 0x3e, 0x08, 0xa5, 0xa9, 0x3f, 0xe6, 0x0a, 0xeb, + 0xd6, 0xd6, 0xf0, 0xe4, 0x09, 0x97, 0xec, 0x41, 0xd5, 0x04, 0xe0, 0xf3, 0x04, + 0xfe, 0x10, 0xc9, 0x07, 0x86, 0xfc, 0x55, 0xc4, 0xe6, 0xf9, 0x1a, 0x57, 0x4e, + 0xd5, 0xd5, 0xd6, 0xe8, 0x07, 0x1a, 0xe4, 0x01, 0xb0, 0xe2, 0x83, 0xff, 0xee, + 0xb2, 0xf4, 0x2f, 0xc0, 0x17, 0x52, 0x39, 0x0b, 0x0a, 0x08, 0x24, 0xe5, 0xfc, + 0x20, 0x35, 0x81, 0x2c, 0x4d, 0x3a, 0x33, 0x2c, 0x15, 0x14, 0x93, 0xb8, 0x29, + 0xff, 0x08, 0x50, 0xd8, 0xc2, 0xb6, 0xd6, 0x3b, 0xc6, 0x13, 0xe4, 0x12, 0xfb, + 0xcf, 0x29, 0x33, 0x11, 0x10, 0xf2, 0x1f, 0x1a, 0xe6, 0xb2, 0x0c, 0x0e, 0x1f, + 0x0a, 0x1a, 0x14, 0xde, 0x03, 0xec, 0xed, 0x28, 0xe4, 0xbe, 0x0d, 0xaf, 0x1a, + 0x10, 0xe5, 0xe7, 0x03, 0xfd, 0xb7, 0xe6, 0xd5, 0xff, 0x0a, 0x15, 0x06, 0xca, + 0xe3, 0x07, 0xe9, 0xc3, 0xae, 0xe5, 0x11, 0x31, 0x1a, 0xfd, 0x38, 0x09, 0xe4, + 0x02, 0xe3, 0xec, 0xd6, 0x1f, 0xae, 0xed, 0xe3, 0x00, 0xc9, 0xfe, 0xd1, 0xf5, + 0x00, 0xf7, 0xf1, 0x04, 0x14, 0x05, 0xed, 0x3a, 0xfd, 0xf1, 0xea, 0xec, 0x31, + 0x41, 0x1f, 0x21, 0xf7, 0xbc, 0x3e, 0xea, 0x39, 0x01, 0x05, 0x09, 0x0e, 0xd9, + 0x22, 0xfb, 0xef, 0x04, 0x42, 0x22, 0x02, 0xc5, 0xc7, 0x1a, 0x1a, 0x0a, 0xed, + 0xfd, 0x14, 0xf7, 0xf2, 0x0d, 0xf4, 0xc3, 0x1f, 0x27, 0xe7, 0xd9, 0xdd, 0x04, + 0x20, 0x02, 0x7f, 0xb3, 0xc0, 0xcf, 0xe2, 0xd1, 0x0c, 0x07, 0xe0, 0x6d, 0x12, + 0x28, 0xf5, 0x1c, 0x18, 0x1f, 0xf6, 0xfe, 0xb9, 0xf2, 0xfa, 0xda, 0xa9, 0xeb, + 0xd9, 0xe3, 0x1d, 0x08, 0xd0, 0xcc, 0x1c, 0xd7, 0x30, 0xea, 0x09, 0xed, 0xe5, + 0x04, 0x1d, 0x14, 0xdb, 0x1c, 0x1d, 0xf8, 0xfd, 0xe0, 0x14, 0x05, 0xcd, 0xd4, + 0xdb, 0xbc, 0x02, 0xf2, 0xf2, 0x00, 0xd5, 0xf4, 0x07, 0x29, 0xe4, 0xfc, 0x01, + 0x35, 0xd8, 0xd3, 0xd4, 0xeb, 0x3e, 0xee, 0xd5, 0x0a, 0xd1, 0x0c, 0x0a, 0x10, + 0x2c, 0xf1, 0x0d, 0xeb, 0xdc, 0xff, 0xe9, 0xd2, 0x02, 0x14, 0xf0, 0xae, 0x22, + 0x06, 0xd6, 0xf4, 0x30, 0xc5, 0xd4, 0xcc, 0x19, 0x05, 0x18, 0xe0, 0xc6, 0x15, + 0x0e, 0xea, 0xf9, 0x11, 0x3b, 0xe8, 0x60, 0x15, 0xfe, 0xec, 0xfb, 0x24, 0xe1, + 0xf8, 0x1a, 0x14, 0x12, 0xea, 0x23, 0xce, 0xe0, 0xe3, 0x0e, 0x32, 0x51, 0x05, + 0x26, 0x06, 0x06, 0x4c, 0xde, 0xeb, 0xf0, 0xdf, 0xf1, 0x02, 0x1f, 0x3a, 0x1b, + 0x3d, 0xd7, 0xcc, 0x0c, 0xd4, 0xe3, 0xef, 0x08, 0xed, 0xaa, 0x15, 0xb3, 0x19, + 0xe6, 0xbb, 0x2b, 0x1d, 0xde, 0x2d, 0x01, 0xbd, 0xe5, 0xfa, 0x10, 0xba, 0x1a, + 0xec, 0xe9, 0xb5, 0x17, 0x1f, 0xd5, 0x19, 0xd8, 0x3a, 0x1c, 0xe0, 0xb8, 0x07, + 0xe4, 0x14, 0x38, 0xeb, 0x06, 0xfe, 0xc5, 0xee, 0xf8, 0xa6, 0x08, 0xff, 0xf2, + 0x00, 0xd4, 0xe2, 0x2c, 0xfe, 0x28, 0x2a, 0x17, 0xa0, 0x05, 0xe9, 0xf9, 0xb6, + 0x15, 0xef, 0x06, 0x27, 0xfa, 0x17, 0xda, 0xe1, 0x18, 0xd0, 0xb8, 0x58, 0xaf, + 0xf6, 0xdd, 0xf6, 0x2f, 0x05, 0x0f, 0xe1, 0x38, 0xfd, 0x06, 0xd2, 0x05, 0xb4, + 0x00, 0xd6, 0x02, 0x01, 0x27, 0x8b, 0x06, 0xdb, 0xfa, 0x10, 0x4c, 0xe8, 0x02, + 0xa1, 0x16, 0xf8, 0xe8, 0xdd, 0xf4, 0xa5, 0xcd, 0xab, 0xf8, 0xf7, 0x09, 0xc2, + 0x18, 0x2f, 0x10, 0xd6, 0xd3, 0x40, 0xea, 0x33, 0xd2, 0xec, 0x08, 0xf4, 0x01, + 0x03, 0xe3, 0x1f, 0xc5, 0xe5, 0x7f, 0xd7, 0xe1, 0x16, 0x0c, 0x0d, 0xb1, 0xf3, + 0x3e, 0xed, 0xc9, 0xd8, 0xf9, 0x72, 0x08, 0x9a, 0xea, 0xf9, 0x2f, 0x4d, 0xd7, + 0xc5, 0x0a, 0xe2, 0xe2, 0xb8, 0x54, 0xd2, 0xe0, 0x16, 0x0b, 0xeb, 0x13, 0xe0, + 0x2a, 0xbe, 0xce, 0x33, 0x8c, 0xfc, 0xdc, 0x60, 0xdf, 0xe0, 0xed, 0xe5, 0x2b, + 0xd9, 0xbd, 0xd3, 0x2a, 0x26, 0xb1, 0xab, 0x12, 0x9a, 0xc0, 0xd3, 0xb0, 0x12, + 0xd4, 0x17, 0xc6, 0xed, 0xa6, 0xe5, 0x06, 0x09, 0x2a, 0xf5, 0xa9, 0xfc, 0xe1, + 0x5b, 0xd2, 0xfa, 0xed, 0x23, 0x1f, 0xed, 0xb1, 0x11, 0xec, 0x0c, 0x01, 0x01, + 0xcb, 0x25, 0xd8, 0x13, 0x15, 0xf2, 0x1c, 0xee, 0xd4, 0xd8, 0xf6, 0xfe, 0x3d, + 0xde, 0x01, 0xca, 0xc7, 0xe7, 0x9a, 0xd4, 0x15, 0x0d, 0xf9, 0x17, 0xd7, 0xfa, + 0xe6, 0xc0, 0xcc, 0x36, 0x23, 0xeb, 0xf8, 0xe5, 0xd2, 0x1c, 0xd8, 0xdf, 0xb2, + 0xeb, 0xf4, 0xea, 0x1e, 0xfb, 0xdd, 0xfc, 0xf2, 0x1f, 0xe0, 0xfb, 0xd0, 0x26, + 0xef, 0xa5, 0xeb, 0xd2, 0xfb, 0x07, 0x19, 0xfd, 0xee, 0x16, 0x06, 0xd2, 0xee, + 0x0f, 0x21, 0xea, 0x04, 0x20, 0x4b, 0xf0, 0x17, 0x0f, 0x19, 0xfe, 0x3d, 0xdf, + 0xdd, 0xd5, 0xe7, 0x14, 0x00, 0x06, 0x02, 0x11, 0x0d, 0x0e, 0x02, 0xf6, 0xe7, + 0x4a, 0xf0, 0xff, 0xff, 0xb2, 0x28, 0x22, 0x1b, 0xd0, 0x25, 0xd7, 0x03, 0xf9, + 0xfb, 0x0c, 0x05, 0xdf, 0x14, 0x1a, 0x17, 0x34, 0xef, 0x0c, 0x22, 0xf5, 0x0d, + 0xf5, 0x0e, 0x09, 0xdd, 0xfc, 0x42, 0xf7, 0x07, 0xfb, 0xdf, 0xe0, 0xd7, 0x08, + 0xcd, 0xf6, 0xcb, 0xe1, 0xdc, 0x18, 0xf0, 0xee, 0x07, 0x1d, 0x26, 0xd6, 0x10, + 0xf3, 0xf0, 0xd8, 0xf5, 0xf1, 0xc8, 0x23, 0xf4, 0xc1, 0xd4, 0xed, 0x07, 0xcf, + 0x4c, 0x1b, 0x21, 0x34, 0xf3, 0xe3, 0xf4, 0x22, 0xeb, 0xfd, 0x01, 0xcb, 0xfc, + 0xd0, 0xeb, 0x0a, 0x07, 0x20, 0x00, 0x1a, 0xcc, 0x23, 0x31, 0xfa, 0xe6, 0xc3, + 0xf0, 0x08, 0x15, 0xdf, 0xed, 0xf3, 0xf4, 0xf6, 0x17, 0xf9, 0x16, 0xd6, 0xd2, + 0x11, 0x31, 0xdb, 0xfe, 0x1d, 0x13, 0xdf, 0x09, 0x1f, 0x00, 0x7f, 0x20, 0xe1, + 0xff, 0xdd, 0xba, 0xfd, 0xe7, 0xe4, 0xf2, 0x00, 0xda, 0xdf, 0x1e, 0xbd, 0x04, + 0xd1, 0xfd, 0xd1, 0x05, 0xf0, 0xfa, 0xd3, 0xd2, 0xec, 0xcb, 0x28, 0xf4, 0xf9, + 0xf1, 0x08, 0xbb, 0xea, 0x0d, 0x0f, 0x27, 0x10, 0xce, 0x23, 0xe1, 0xec, 0x38, + 0x1a, 0x17, 0xcc, 0x12, 0x17, 0xe2, 0xf4, 0x33, 0xdf, 0xcf, 0x37, 0x1a, 0x0b, + 0xda, 0x12, 0xcb, 0xf4, 0xe4, 0x9a, 0x06, 0xf7, 0x28, 0x00, 0x0b, 0xc4, 0x12, + 0xfd, 0xe0, 0xf9, 0xdc, 0xce, 0xda, 0x12, 0x04, 0x24, 0xfb, 0x18, 0x14, 0x20, + 0xff, 0x13, 0xf2, 0x16, 0xdb, 0xfc, 0xf2, 0x02, 0x2b, 0x00, 0xe4, 0xef, 0x22, + 0xf5, 0xe7, 0x13, 0xf6, 0xe5, 0x19, 0xdf, 0x14, 0x1e, 0xd5, 0xf3, 0xf4, 0xcc, + 0xe0, 0x01, 0xf4, 0xe6, 0xeb, 0x1f, 0x06, 0xed, 0xcf, 0xcd, 0x36, 0xf1, 0x03, + 0x24, 0x0d, 0xf4, 0x2f, 0xda, 0xf5, 0xee, 0xfc, 0xe1, 0xe0, 0xff, 0xf5, 0xd7, + 0xd6, 0xdd, 0x17, 0x17, 0xde, 0xf8, 0x02, 0xce, 0x1a, 0x7f, 0x15, 0xda, 0x03, + 0xd1, 0xf4, 0xe4, 0x35, 0xf9, 0xf1, 0xf1, 0x04, 0xf3, 0xbe, 0x10, 0xf3, 0xfd, + 0x0c, 0xd5, 0xdb, 0x15, 0x0e, 0xfa, 0xd5, 0x0b, 0x13, 0xf8, 0x00, 0xef, 0xf5, + 0xfc, 0x2a, 0x05, 0xf9, 0xfe, 0xdf, 0xd9, 0x14, 0x00, 0x4b, 0x1b, 0x01, 0xd0, + 0xf0, 0xf7, 0x07, 0xfe, 0xe5, 0x04, 0x0d, 0xec, 0xf2, 0xf1, 0xd9, 0xf7, 0x02, + 0xcb, 0xf7, 0x1a, 0xe5, 0xe3, 0xdf, 0xca, 0xf2, 0xf8, 0xf6, 0xe2, 0xe4, 0x22, + 0xfd, 0xf8, 0xe5, 0xe6, 0xed, 0xfe, 0x00, 0xf0, 0xc0, 0x00, 0xc7, 0x1d, 0xe3, + 0xd6, 0xfe, 0xf1, 0xef, 0xda, 0x12, 0xf6, 0x08, 0x00, 0xf0, 0xe3, 0xdb, 0x06, + 0xf3, 0xf7, 0x14, 0x3b, 0x0c, 0xfa, 0x00, 0xff, 0xd6, 0xe8, 0x4b, 0xd7, 0xec, + 0x33, 0x04, 0x0d, 0x40, 0xe7, 0x00, 0xfb, 0x00, 0x05, 0xee, 0x1f, 0x38, 0x21, + 0xb8, 0xf3, 0x1b, 0xfa, 0x13, 0xe2, 0xd8, 0xe1, 0x0b, 0xfc, 0xe8, 0xea, 0x00, + 0xe1, 0xf7, 0x0d, 0xe0, 0x22, 0xd3, 0xee, 0xf2, 0xce, 0xee, 0x32, 0xf5, 0xfe, + 0xcd, 0x10, 0x01, 0x15, 0xea, 0x2b, 0xef, 0x1c, 0xd9, 0xfa, 0x0e, 0x22, 0x13, + 0xf1, 0xf8, 0xfb, 0xff, 0x2a, 0xfd, 0x03, 0x2e, 0x19, 0xca, 0x05, 0xfc, 0x13, + 0x1f, 0x16, 0xea, 0x0b, 0x2c, 0xfd, 0xdf, 0x11, 0xf5, 0xc7, 0x12, 0x06, 0xd3, + 0x07, 0x2b, 0x13, 0xf2, 0x05, 0xf4, 0x0a, 0x0a, 0x18, 0x03, 0xf9, 0xeb, 0xdb, + 0x0f, 0xd2, 0xff, 0xd5, 0xda, 0xf6, 0xd5, 0xda, 0xf4, 0xc7, 0xf7, 0xb9, 0xf0, + 0x10, 0xca, 0x45, 0xf1, 0xf8, 0x1e, 0xe3, 0xbd, 0xe8, 0x0f, 0x10, 0x2b, 0xd3, + 0x0a, 0x18, 0xe1, 0x25, 0xbd, 0x23, 0xd8, 0xd1, 0x11, 0x20, 0xef, 0xee, 0x0d, + 0x11, 0xdb, 0x1e, 0xfb, 0x52, 0x15, 0xdb, 0xf5, 0x10, 0xd2, 0xf2, 0x02, 0x2b, + 0xf3, 0xf2, 0x46, 0x07, 0x00, 0xbe, 0x10, 0xf2, 0xef, 0x15, 0xe8, 0x07, 0x05, + 0x25, 0x10, 0x33, 0x32, 0xd7, 0xb5, 0xe8, 0x24, 0xf5, 0xf4, 0xf1, 0xdd, 0x08, + 0xc4, 0x0b, 0xd0, 0x20, 0xdb, 0xcf, 0xf8, 0x0c, 0x30, 0x07, 0xbd, 0x06, 0x04, + 0x15, 0x1f, 0xd8, 0x2e, 0xf6, 0xb7, 0xe4, 0xec, 0xef, 0xb1, 0x0b, 0xec, 0xf5, + 0xcc, 0xf3, 0x43, 0x2c, 0x07, 0xdc, 0x42, 0x24, 0xe7, 0xff, 0xdc, 0xed, 0x12, + 0xc2, 0xb6, 0x21, 0xda, 0xf7, 0xf2, 0xe7, 0x00, 0xd9, 0xf2, 0x1b, 0x25, 0x07, + 0x2a, 0x37, 0xd4, 0xe1, 0xf1, 0xeb, 0xc4, 0x1d, 0x0e, 0xd2, 0xd3, 0xe7, 0x26, + 0x1c, 0xe9, 0x33, 0xdb, 0xa6, 0x32, 0x02, 0x07, 0xe8, 0xf9, 0xf8, 0x0f, 0xde, + 0xe0, 0x27, 0x14, 0x20, 0x10, 0xe0, 0xf3, 0xe2, 0x06, 0xcd, 0x24, 0xc0, 0xf2, + 0x10, 0x4b, 0x7f, 0xe0, 0xad, 0xef, 0x01, 0xb3, 0xc6, 0xf7, 0x17, 0xdd, 0x52, + 0xd8, 0xdb, 0x4c, 0xfc, 0x2b, 0x0d, 0xbc, 0xf9, 0xe2, 0x00, 0x18, 0xbb, 0x04, + 0x30, 0x0e, 0x1a, 0xdb, 0x17, 0xd1, 0xd8, 0x01, 0xf1, 0xf6, 0xfa, 0x23, 0x20, + 0xfe, 0xdd, 0x0d, 0xef, 0xce, 0x09, 0xdc, 0xda, 0xe4, 0x5c, 0xc6, 0x11, 0x03, + 0xdc, 0xf6, 0x2b, 0x40, 0xf3, 0x0b, 0x1d, 0x19, 0xa7, 0x05, 0xc5, 0x09, 0xc8, + 0xed, 0x28, 0x07, 0xe8, 0x0c, 0x0a, 0x24, 0x13, 0xec, 0xb4, 0x09, 0xfd, 0xec, + 0x25, 0x1a, 0xe2, 0xe1, 0xfe, 0x26, 0xa1, 0xcd, 0x15, 0xe6, 0x1d, 0xdf, 0xeb, + 0x9e, 0xe7, 0x0f, 0x05, 0x9c, 0x33, 0x36, 0xcb, 0x39, 0xd2, 0x0e, 0x4c, 0xa6, + 0xe5, 0xbd, 0xd1, 0x07, 0xc9, 0xef, 0xaa, 0xdd, 0xec, 0x02, 0x09, 0xe5, 0xed, + 0xf7, 0xd3, 0xfb, 0xd1, 0xa8, 0xb0, 0xdb, 0xf3, 0xed, 0x0a, 0x81, 0x49, 0x00, + 0xb3, 0xc6, 0xc3, 0xd5, 0xfa, 0xfc, 0xe1, 0xbd, 0x48, 0xd9, 0xfd, 0xc3, 0x09, + 0xe4, 0x24, 0x26, 0xd9, 0xd4, 0xfc, 0x03, 0x51, 0x2f, 0x07, 0xe5, 0x9d, 0x02, + 0xc5, 0xd1, 0x07, 0xf8, 0x31, 0xea, 0xf6, 0xeb, 0x05, 0x01, 0x0c, 0x21, 0xa9, + 0xea, 0xf1, 0xb1, 0xfb, 0x60, 0xf4, 0x0b, 0x40, 0xb0, 0x4f, 0x33, 0xba, 0xcf, + 0x13, 0x03, 0xea, 0xd5, 0x3d, 0xd0, 0x3d, 0x06, 0x99, 0xf2, 0x04, 0xf1, 0xe2, + 0x94, 0xee, 0xf2, 0xa5, 0xac, 0x33, 0x19, 0xcc, 0x84, 0x30, 0xd4, 0xa8, 0x34, + 0x81, 0x26, 0x0a, 0xb8, 0xde, 0xfa, 0x32, 0x02, 0xd8, 0xfb, 0x39, 0x49, 0xd7, + 0x0e, 0x24, 0xda, 0xda, 0xed, 0x3d, 0x93, 0xbe, 0x0b, 0xdb, 0x39, 0xd9, 0xfb, + 0xe3, 0x27, 0xe3, 0xba, 0xe9, 0x36, 0xf3, 0xea, 0xde, 0xb9, 0x20, 0x21, 0x84, + 0xf9, 0x2c, 0x0a, 0xff, 0xed, 0x27, 0xef, 0x1a, 0x08, 0xe1, 0xe0, 0xfb, 0xe1, + 0x0a, 0x13, 0xe2, 0x20, 0xfa, 0xae, 0xf9, 0xe1, 0xf4, 0x96, 0x30, 0x11, 0xb3, + 0xdf, 0x49, 0x42, 0xd9, 0xbc, 0xbc, 0xcf, 0xf4, 0xe3, 0xff, 0x02, 0x57, 0x17, + 0xf6, 0xc5, 0x35, 0xe4, 0xf1, 0x03, 0xc1, 0xd4, 0x26, 0xa5, 0x05, 0xcd, 0x31, + 0xab, 0xf8, 0x14, 0x18, 0xa6, 0xe4, 0x3b, 0x94, 0xf5, 0xe7, 0xc3, 0xb1, 0x0e, + 0xc6, 0xd4, 0xd2, 0x33, 0x02, 0x60, 0xf0, 0xe2, 0xc8, 0x08, 0x20, 0x93, 0xe8, + 0xc0, 0x20, 0xfd, 0x46, 0xcc, 0x3d, 0x0b, 0xf9, 0xe6, 0xae, 0xf5, 0xff, 0xff, + 0xd6, 0xdd, 0x10, 0xd0, 0xd3, 0x01, 0xe0, 0x11, 0xf9, 0x09, 0x0e, 0xc3, 0xbe, + 0x0f, 0xea, 0xde, 0xc9, 0x02, 0x02, 0x0b, 0xeb, 0xfa, 0xed, 0xf6, 0x15, 0x04, + 0x14, 0xf7, 0x11, 0x10, 0xde, 0x2b, 0x0f, 0xe0, 0xc8, 0xed, 0xec, 0x2b, 0x24, + 0x10, 0xd1, 0xf0, 0xfd, 0xeb, 0xef, 0x06, 0xcc, 0x15, 0xf5, 0xf3, 0xf0, 0x27, + 0xe4, 0xf9, 0xc0, 0x04, 0xcd, 0x01, 0xf6, 0x10, 0x20, 0xea, 0x81, 0x15, 0xdd, + 0xef, 0xd3, 0x11, 0xe5, 0xbd, 0x0e, 0xd5, 0x2d, 0x1e, 0x1d, 0x0b, 0x0d, 0x13, + 0xf1, 0xe9, 0x05, 0x00, 0x0b, 0xe7, 0x01, 0xdf, 0xfc, 0x01, 0xe6, 0xe7, 0xee, + 0x11, 0x14, 0xc4, 0xf2, 0xde, 0xfd, 0xe1, 0x12, 0x0a, 0x12, 0xf1, 0xe5, 0xe4, + 0x17, 0xee, 0x12, 0x14, 0x0c, 0x02, 0xf9, 0xf8, 0x35, 0x07, 0x0a, 0x03, 0x04, + 0x10, 0x0d, 0x07, 0xd7, 0x03, 0x0f, 0x0d, 0x2c, 0x0a, 0xdf, 0x0e, 0xd5, 0xf7, + 0xc9, 0x14, 0xd7, 0xd5, 0x14, 0xea, 0x00, 0xee, 0x12, 0xf4, 0x2e, 0x08, 0x15, + 0xf5, 0x18, 0x18, 0xdd, 0x25, 0x12, 0xea, 0xe8, 0xf2, 0xad, 0x1c, 0x12, 0xe6, + 0x01, 0xeb, 0xf0, 0xfa, 0xee, 0x1a, 0x22, 0xed, 0x22, 0x29, 0xfe, 0x0e, 0x23, + 0xd2, 0xfd, 0x15, 0x07, 0xfc, 0xf1, 0x3c, 0xde, 0xd6, 0x09, 0xbb, 0xcf, 0xef, + 0xc1, 0x1e, 0x19, 0x09, 0x1d, 0xfd, 0xf3, 0xec, 0x14, 0xf1, 0xe8, 0xf9, 0x22, + 0xf7, 0xe5, 0x0a, 0x02, 0x13, 0xee, 0x26, 0x03, 0x0f, 0xef, 0xdb, 0xe9, 0x46, + 0xed, 0x0c, 0xf0, 0xfb, 0xd4, 0xdb, 0xfd, 0xe3, 0x13, 0x14, 0xc9, 0x07, 0xea, + 0xea, 0xda, 0xcc, 0x08, 0x2e, 0xdc, 0xde, 0xe6, 0x21, 0xc5, 0xf1, 0x0c, 0x38, + 0xde, 0xf3, 0x0e, 0x01, 0xc3, 0xe9, 0xfd, 0x0b, 0xf7, 0x39, 0xe2, 0x17, 0xdf, + 0x0e, 0x1b, 0xda, 0x08, 0xeb, 0xdf, 0x0b, 0x03, 0xd0, 0x35, 0x43, 0xa9, 0x00, + 0xb6, 0xba, 0x9e, 0xa9, 0xa4, 0xe3, 0x01, 0x1a, 0xdf, 0x12, 0x10, 0xba, 0xb0, + 0xd2, 0xf7, 0x69, 0xfa, 0xfe, 0xdc, 0xb0, 0x00, 0x01, 0x05, 0xe5, 0x3d, 0xaa, + 0xe7, 0xa4, 0xf0, 0xc5, 0xeb, 0xa0, 0xc0, 0xa6, 0xc9, 0xbf, 0x17, 0x74, 0xe7, + 0x08, 0x11, 0x1c, 0x1f, 0x2b, 0xed, 0x39, 0x01, 0x00, 0x9b, 0xfb, 0xd8, 0xfa, + 0x21, 0xc9, 0x14, 0x2e, 0x0e, 0x17, 0x9a, 0x08, 0xd3, 0xfc, 0x00, 0xcf, 0xff, + 0xc5, 0xba, 0xf6, 0x1a, 0xfd, 0x2f, 0xd8, 0x36, 0x4d, 0xcd, 0xf6, 0x11, 0x06, + 0x65, 0xe2, 0x1b, 0xc3, 0x0f, 0xc7, 0xdd, 0xde, 0xd2, 0xcf, 0xeb, 0xcc, 0xfb, + 0xb7, 0x56, 0xc6, 0x12, 0xdd, 0xec, 0xdc, 0xfb, 0x04, 0x20, 0xc0, 0xcc, 0x17, + 0xd3, 0xf4, 0xe4, 0x0d, 0x21, 0xde, 0xc5, 0xb5, 0x0d, 0x3e, 0x1d, 0x06, 0xe9, + 0x23, 0xfa, 0xc0, 0xd2, 0xf2, 0x69, 0xff, 0x05, 0xda, 0x11, 0xe5, 0xb9, 0x21, + 0xd5, 0x97, 0x25, 0xe4, 0x0e, 0xfc, 0x05, 0x1c, 0xc0, 0xef, 0xed, 0xa8, 0xf9, + 0xe5, 0xed, 0x44, 0x0d, 0x26, 0xff, 0x29, 0x1c, 0x41, 0xc3, 0xd1, 0xff, 0xe3, + 0xe7, 0x9a, 0xc9, 0x34, 0x29, 0x5e, 0xbd, 0xdc, 0xc4, 0xf2, 0xe4, 0xeb, 0xf9, + 0x7f, 0x3b, 0xf1, 0x63, 0x19, 0xdd, 0xea, 0xda, 0x34, 0xe5, 0xf0, 0xf9, 0xc2, + 0x1d, 0xcc, 0x1f, 0xd8, 0xd0, 0x40, 0xfe, 0x26, 0xd2, 0xad, 0x32, 0xb3, 0xdc, + 0xa5, 0xe1, 0x14, 0x11, 0x76, 0x5f, 0xe7, 0x13, 0xde, 0xdf, 0x2e, 0x32, 0x05, + 0xe3, 0x27, 0xf5, 0xfc, 0xee, 0x1a, 0x3d, 0xb4, 0x1f, 0xd4, 0xf2, 0xd9, 0x2e, + 0xe1, 0x00, 0x1e, 0x05, 0x2c, 0xd4, 0xc4, 0x09, 0x25, 0xea, 0xa1, 0xc8, 0x29, + 0xd5, 0x1f, 0xcb, 0x0f, 0x2e, 0xf1, 0xee, 0xe5, 0x3b, 0xed, 0xd7, 0x22, 0xfe, + 0xdb, 0x32, 0xd7, 0xd6, 0xff, 0x09, 0x02, 0x18, 0xf2, 0x01, 0x05, 0x01, 0xe2, + 0xd4, 0xdb, 0xf4, 0x10, 0xaf, 0xfc, 0xe8, 0x22, 0xe0, 0x0f, 0xe0, 0xff, 0x36, + 0x04, 0xf5, 0xd2, 0xd1, 0xa9, 0x12, 0xde, 0x0e, 0x0d, 0xe2, 0xfe, 0xdf, 0xf5, + 0xf5, 0xd3, 0x1a, 0x13, 0x0a, 0x2f, 0x03, 0xeb, 0xe2, 0xdb, 0x11, 0xfd, 0xf7, + 0xd8, 0x0f, 0x02, 0xbf, 0xc8, 0x1e, 0xe2, 0x0e, 0x05, 0xd1, 0x23, 0x02, 0x22, + 0x11, 0xff, 0x92, 0x27, 0x2b, 0xd3, 0x07, 0xb1, 0xfd, 0xd1, 0xd1, 0x32, 0xeb, + 0x2c, 0xfe, 0xd2, 0xea, 0xf7, 0xe1, 0x21, 0x0e, 0xde, 0x0a, 0x02, 0xf9, 0xc4, + 0x0c, 0xfc, 0x0a, 0x20, 0x01, 0xbf, 0xc9, 0xee, 0x09, 0xd3, 0x05, 0xff, 0xcb, + 0xf4, 0x15, 0xe8, 0x1b, 0x0a, 0xd3, 0xf0, 0xef, 0xb1, 0x33, 0xba, 0x4f, 0xd8, + 0xfa, 0x06, 0xcd, 0x13, 0x00, 0xe5, 0x31, 0xd6, 0x25, 0xec, 0xfe, 0xb0, 0xd6, + 0xf5, 0x11, 0x1a, 0xd9, 0x03, 0xe6, 0x0c, 0x4c, 0xf4, 0xe9, 0xf4, 0xd6, 0xbb, + 0xfa, 0xf8, 0xde, 0x9f, 0x1a, 0xb7, 0xef, 0xe2, 0x17, 0x0d, 0x0f, 0x2c, 0xf0, + 0x07, 0xbc, 0x36, 0xf9, 0x32, 0x04, 0xfe, 0x07, 0xe3, 0xe9, 0xc0, 0xf7, 0xde, + 0x2d, 0xe0, 0xed, 0x18, 0xd6, 0x38, 0xf6, 0xe3, 0xdd, 0xe0, 0xfc, 0xc1, 0x7f, + 0x13, 0xe0, 0x25, 0x2e, 0x13, 0xed, 0xde, 0xe5, 0xe5, 0x17, 0xe3, 0xc9, 0x3c, + 0xde, 0x0c, 0xf2, 0xa5, 0xda, 0xdd, 0x3c, 0xec, 0xdb, 0x0c, 0x27, 0xed, 0xef, + 0xd2, 0x36, 0xd1, 0xf5, 0xc2, 0xab, 0x0c, 0x0a, 0xc2, 0x28, 0xdc, 0xcf, 0x10, + 0xc6, 0xd9, 0xca, 0xe6, 0xdf, 0x16, 0x10, 0xe4, 0xfe, 0x1e, 0xe5, 0x4f, 0x02, + 0x15, 0xfe, 0x00, 0xd7, 0x0e, 0x07, 0xef, 0xd4, 0xef, 0xf1, 0xf2, 0x21, 0x2f, + 0xc6, 0xfc, 0x39, 0x16, 0x32, 0x9a, 0xcd, 0x07, 0x1e, 0x04, 0x23, 0xf5, 0xfa, + 0x12, 0x34, 0x21, 0xfa, 0x05, 0x30, 0x24, 0x33, 0xf2, 0xf9, 0xfd, 0xd5, 0xff, + 0x46, 0xd2, 0x18, 0x1a, 0xc3, 0x32, 0x15, 0xdc, 0x03, 0xd7, 0x32, 0xf2, 0xe7, + 0xd7, 0x16, 0xf0, 0xf0, 0x03, 0xe9, 0xdd, 0x25, 0xf4, 0xf8, 0xfa, 0x13, 0xe3, + 0x41, 0x1b, 0xc4, 0xe1, 0x18, 0x14, 0xe9, 0xe7, 0xe2, 0xff, 0x2d, 0xf6, 0xea, + 0xd4, 0xdc, 0x23, 0xea, 0xea, 0x29, 0x14, 0x0e, 0xec, 0x0b, 0xec, 0x00, 0xf7, + 0x08, 0xdc, 0x1a, 0xef, 0xe4, 0xf2, 0x20, 0xcb, 0xc3, 0xf6, 0x3d, 0x14, 0xe2, + 0xc5, 0xf7, 0xf7, 0xd2, 0xe6, 0x0b, 0x1a, 0xf9, 0x26, 0x20, 0x1f, 0x0f, 0xd4, + 0xf3, 0x0e, 0xd6, 0x4d, 0x01, 0x07, 0x1a, 0xf1, 0xe1, 0xe0, 0x1e, 0xea, 0xea, + 0x1d, 0xfe, 0xed, 0x1e, 0xf0, 0x00, 0x00, 0xff, 0x0d, 0xb3, 0x02, 0x4b, 0x0a, + 0xf3, 0x1c, 0x38, 0xfb, 0xee, 0x5d, 0x0c, 0xe6, 0xdf, 0x02, 0xed, 0x1f, 0xfe, + 0xea, 0x7f, 0xe5, 0xf7, 0x01, 0x02, 0x22, 0x60, 0xdd, 0xee, 0xcf, 0x11, 0xfc, + 0xee, 0xf1, 0x14, 0xc7, 0xe4, 0xf8, 0x3b, 0x09, 0xe6, 0xf7, 0xdc, 0xf9, 0x27, + 0x06, 0x10, 0x25, 0xf8, 0xe6, 0x12, 0xe5, 0xe1, 0x1b, 0xd3, 0xd3, 0xea, 0x04, + 0x12, 0x02, 0xe1, 0xe4, 0xf3, 0x4a, 0x13, 0xf1, 0xb4, 0x0c, 0xf7, 0x53, 0xd0, + 0xcd, 0xe5, 0x2c, 0x09, 0x06, 0xdf, 0xf1, 0x0d, 0x1f, 0xfc, 0xdd, 0xdf, 0x07, + 0x1f, 0x41, 0x23, 0xff, 0x1f, 0x22, 0x15, 0x06, 0x0f, 0x02, 0xd7, 0x11, 0x1f, + 0xea, 0x24, 0xef, 0xe9, 0x0a, 0x0d, 0x1c, 0xd9, 0xeb, 0xe1, 0x2b, 0x00, 0x08, + 0xd9, 0xd1, 0xfa, 0xdc, 0x06, 0x14, 0x0b, 0x03, 0x40, 0x3c, 0xdc, 0xf4, 0xc3, + 0xeb, 0xfa, 0xeb, 0x07, 0xd8, 0x18, 0x09, 0xfa, 0x6d, 0xe2, 0xff, 0x06, 0xfa, + 0x16, 0xec, 0xd4, 0xf8, 0xdc, 0xd7, 0x30, 0x08, 0xe1, 0x37, 0x08, 0xca, 0xe1, + 0xc7, 0x0a, 0xd0, 0x10, 0xed, 0x10, 0x09, 0xd4, 0xed, 0x4e, 0xea, 0x1b, 0x2b, + 0xd3, 0x14, 0xe0, 0xfd, 0x0a, 0x12, 0xeb, 0xd1, 0xe8, 0x2f, 0xc6, 0xd8, 0xfe, + 0xec, 0xf6, 0xca, 0xfa, 0xc1, 0xfd, 0xc9, 0x22, 0xdb, 0xdb, 0xe4, 0x09, 0x22, + 0xfb, 0xb7, 0xb5, 0xdd, 0xf9, 0x03, 0xda, 0x1f, 0x00, 0x24, 0xf5, 0xd6, 0x05, + 0x0e, 0x07, 0x16, 0x01, 0x3e, 0xbe, 0x44, 0x18, 0x00, 0xe0, 0xdb, 0x4e, 0x0b, + 0xe6, 0xf2, 0xd9, 0xd1, 0x1e, 0x00, 0x95, 0x0e, 0xd4, 0xf3, 0xd9, 0x10, 0xf9, + 0xf8, 0x0f, 0x51, 0xa0, 0xb9, 0x4f, 0xc9, 0xd9, 0x05, 0xf5, 0xde, 0xc4, 0x27, + 0x37, 0x26, 0x06, 0xef, 0xf0, 0x13, 0xd2, 0xc9, 0x35, 0xe0, 0x19, 0x00, 0xf8, + 0x81, 0xf0, 0xf1, 0xf5, 0xd6, 0x33, 0xf4, 0x19, 0x0e, 0xf9, 0xc5, 0x25, 0xe8, + 0x0f, 0x0e, 0xee, 0xd0, 0x92, 0xe2, 0xf5, 0x01, 0xf0, 0x01, 0x10, 0x0c, 0x0a, + 0xeb, 0xd1, 0xc0, 0x04, 0x25, 0x22, 0xc9, 0xbd, 0xf8, 0xff, 0x17, 0xe9, 0x2d, + 0x1c, 0xcd, 0xd5, 0x2d, 0xae, 0x0d, 0x05, 0xf6, 0x1b, 0x0f, 0xf7, 0xeb, 0xf9, + 0xe6, 0xe2, 0x1d, 0x0c, 0xc3, 0x0f, 0x1f, 0xb7, 0xf7, 0xcb, 0x22, 0x26, 0xfe, + 0x16, 0x30, 0xbe, 0x18, 0xbd, 0x24, 0x2c, 0xe0, 0x00, 0xdf, 0xa5, 0xe1, 0x28, + 0x1a, 0x09, 0xf0, 0xef, 0xc9, 0x13, 0x3c, 0x06, 0xd6, 0x4c, 0xe1, 0x04, 0xfc, + 0x12, 0xf0, 0xda, 0xcd, 0x15, 0x0a, 0x67, 0xf1, 0x1e, 0xe9, 0xf7, 0x0c, 0x20, + 0xf4, 0x3f, 0x11, 0xfd, 0x38, 0x07, 0x0b, 0xf0, 0xde, 0xff, 0x21, 0x15, 0x14, + 0x02, 0x15, 0xcd, 0x70, 0xba, 0x08, 0xdd, 0xf5, 0xe5, 0xd9, 0xe7, 0x4b, 0x61, + 0x0e, 0x15, 0x0a, 0xe7, 0x34, 0xe6, 0xd0, 0xc0, 0xf4, 0x28, 0x2e, 0x22, 0xfd, + 0x07, 0xf8, 0xfe, 0xed, 0x24, 0x33, 0x03, 0x05, 0xd3, 0xd8, 0xd7, 0xd8, 0x3a, + 0x1e, 0xfd, 0x58, 0x16, 0x9e, 0xc8, 0x1f, 0xb8, 0xc0, 0xfa, 0x1f, 0x33, 0x0c, + 0xf5, 0xb7, 0x17, 0x25, 0x30, 0x21, 0xb6, 0xdd, 0x0f, 0x42, 0x0f, 0xdb, 0x22, + 0xc1, 0x91, 0xd3, 0x5c, 0x16, 0xc6, 0xdf, 0x01, 0x15, 0x0e, 0x42, 0xed, 0x1c, + 0x01, 0x7a, 0xbe, 0x28, 0x32, 0x1a, 0x04, 0xda, 0xff, 0xc1, 0x1e, 0xc2, 0x0c, + 0x3a, 0xdd, 0xe7, 0x38, 0xc3, 0x9a, 0x0a, 0x02, 0xf0, 0xfd, 0xf9, 0xce, 0xbb, + 0x8e, 0x27, 0xdf, 0x23, 0x38, 0x1e, 0xf5, 0x06, 0xfc, 0xdb, 0x43, 0xfe, 0xdf, + 0x35, 0x03, 0xf4, 0x14, 0x1c, 0xc8, 0xe1, 0xf0, 0xf1, 0xe0, 0xc3, 0xdd, 0xba, + 0xc9, 0xf3, 0x0e, 0xda, 0x07, 0xfc, 0x2c, 0xf7, 0x2c, 0x1c, 0xeb, 0x4e, 0xfd, + 0xef, 0xb4, 0x0a, 0xd2, 0x07, 0xb7, 0xe3, 0xcf, 0x0a, 0x07, 0xf9, 0x18, 0xa4, + 0xeb, 0x30, 0xaf, 0xf0, 0x0b, 0xfc, 0x3e, 0xf2, 0x24, 0x0b, 0xac, 0xb8, 0xfe, + 0xdc, 0xd9, 0x05, 0xd5, 0x16, 0x33, 0xe2, 0xf3, 0x15, 0xca, 0xd5, 0xc7, 0x10, + 0x0d, 0xd4, 0x16, 0x19, 0xab, 0x3e, 0xc0, 0xa5, 0xd3, 0xac, 0xed, 0x20, 0xf1, + 0xbf, 0x05, 0xf3, 0xc7, 0x44, 0x38, 0x33, 0x4f, 0xdd, 0xd4, 0x61, 0xff, 0x39, + 0xdd, 0x0d, 0x15, 0xfc, 0x58, 0x13, 0xe7, 0xc9, 0xfb, 0x1c, 0x0a, 0xcc, 0x74, + 0x99, 0xec, 0x00, 0xec, 0x01, 0xe0, 0xfb, 0xfb, 0xe5, 0xce, 0x24, 0xb5, 0x42, + 0x46, 0x02, 0xe5, 0xf9, 0x13, 0x1b, 0xd3, 0x00, 0x0a, 0xe9, 0xbd, 0xfe, 0x00, + 0x32, 0x1c, 0xc1, 0x2a, 0x0d, 0x0c, 0x07, 0xbb, 0xe1, 0xdd, 0x17, 0xd3, 0x06, + 0x02, 0x24, 0xc8, 0xbc, 0xd5, 0x45, 0xbe, 0x81, 0x53, 0xdf, 0x13, 0x11, 0x43, + 0x01, 0x00, 0xc8, 0xcb, 0xb1, 0xea, 0x1b, 0xcd, 0x24, 0x1b, 0xd9, 0xd0, 0x25, + 0xfe, 0xeb, 0xc7, 0x07, 0xe3, 0xf9, 0x9e, 0xda, 0x26, 0x04, 0xca, 0x05, 0xfc, + 0x12, 0x10, 0xdd, 0x1d, 0x26, 0xe1, 0xd8, 0x74, 0xe5, 0x92, 0x7f, 0x06, 0x08, + 0x0c, 0xc5, 0xfd, 0xee, 0xfc, 0xe1, 0xf7, 0xba, 0x2f, 0x25, 0xf7, 0xe6, 0xd9, + 0xe9, 0xee, 0x00, 0x58, 0xea, 0x2a, 0xec, 0xab, 0xdc, 0xb5, 0x29, 0x25, 0xfa, + 0xe5, 0x06, 0x25, 0xff, 0x24, 0x0e, 0x06, 0xf8, 0x16, 0x77, 0xbb, 0xf5, 0xe6, + 0xcb, 0xf0, 0xdf, 0x07, 0xea, 0x07, 0xd1, 0x2e, 0x15, 0xdf, 0xfd, 0x16, 0xed, + 0x33, 0x14, 0xfe, 0xe4, 0xc2, 0xe4, 0x10, 0x07, 0x24, 0xd8, 0xe7, 0x2d, 0x09, + 0x1e, 0xdc, 0xf8, 0xc0, 0x42, 0x17, 0x0e, 0x3a, 0x09, 0xde, 0xc9, 0xf0, 0xf0, + 0xd3, 0x00, 0x1e, 0xb5, 0xb6, 0xdb, 0x3d, 0x06, 0x0c, 0xe7, 0x43, 0x23, 0x06, + 0x19, 0xe4, 0x0c, 0xf8, 0x2a, 0xd2, 0x28, 0xe6, 0xf1, 0x31, 0xff, 0x16, 0xf9, + 0xb1, 0x20, 0x4e, 0xe1, 0x17, 0xfc, 0xe8, 0x2b, 0xfd, 0xeb, 0xf3, 0xf1, 0xea, + 0xd2, 0x16, 0x1d, 0x0b, 0x6c, 0x1a, 0xed, 0x03, 0x23, 0x11, 0xe8, 0xe8, 0x15, + 0x09, 0x25, 0xd3, 0x0e, 0xfa, 0xe1, 0xfa, 0xf3, 0x12, 0x04, 0x10, 0xca, 0x07, + 0x03, 0xce, 0xfb, 0xd5, 0x16, 0x06, 0x08, 0xd2, 0xea, 0xc3, 0xf8, 0x0d, 0xf7, + 0xea, 0xe6, 0x04, 0xc5, 0x09, 0xd8, 0x1c, 0xbb, 0x1c, 0x0f, 0x14, 0xc9, 0xf0, + 0xef, 0xd2, 0x1b, 0x07, 0x17, 0x31, 0x56, 0xee, 0x38, 0xf6, 0x10, 0xfb, 0x9f, + 0x11, 0xec, 0xf5, 0x1b, 0xf7, 0x27, 0x0e, 0x09, 0x32, 0xf7, 0xc1, 0xf8, 0x07, + 0xf7, 0xf3, 0xa3, 0xec, 0xc5, 0x71, 0xe1, 0x04, 0xeb, 0x3e, 0xf5, 0x03, 0x1a, + 0xe1, 0xec, 0x1a, 0xb9, 0xf6, 0x24, 0x21, 0xd6, 0xd7, 0x47, 0xb9, 0xe1, 0xef, + 0xed, 0x15, 0x10, 0xe0, 0xf0, 0xb4, 0x06, 0x36, 0x8f, 0xed, 0x16, 0xc6, 0x14, + 0xc2, 0xf8, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x15, + 0x1a, 0x00, 0x00, 0xf7, 0xf1, 0xff, 0xff, 0xaa, 0x0e, 0x00, 0x00, 0xcc, 0x66, + 0x00, 0x00, 0x67, 0xed, 0xff, 0xff, 0x7e, 0x1d, 0x00, 0x00, 0x14, 0x05, 0x00, + 0x00, 0xd9, 0xd3, 0xff, 0xff, 0xe0, 0x30, 0x00, 0x00, 0x3b, 0x29, 0x00, 0x00, + 0x40, 0x3e, 0x00, 0x00, 0x99, 0xfa, 0xff, 0xff, 0x83, 0x1b, 0x00, 0x00, 0x78, + 0xe4, 0xff, 0xff, 0xf8, 0x23, 0x00, 0x00, 0x0e, 0x25, 0x00, 0x00, 0x33, 0x06, + 0x00, 0x00, 0xfe, 0x32, 0x00, 0x00, 0x27, 0xe5, 0xff, 0xff, 0xba, 0x0d, 0x00, + 0x00, 0xc4, 0x51, 0x00, 0x00, 0x07, 0xf0, 0xff, 0xff, 0x40, 0xf2, 0xff, 0xff, + 0x2a, 0x57, 0x00, 0x00, 0xd1, 0x01, 0x00, 0x00, 0x11, 0x0e, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0x51, 0x29, 0x00, 0x00, 0x53, 0x29, 0x00, 0x00, 0xcf, 0x38, + 0x00, 0x00, 0x78, 0x5f, 0x00, 0x00, 0x90, 0x13, 0x00, 0x00, 0xee, 0x08, 0x00, + 0x00, 0xec, 0xec, 0xff, 0xff, 0x2c, 0x3d, 0x00, 0x00, 0x53, 0x34, 0x00, 0x00, + 0xd2, 0x08, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0xa9, 0xe5, 0xff, 0xff, 0x91, + 0x0c, 0x00, 0x00, 0xc7, 0x02, 0x00, 0x00, 0xdc, 0x12, 0x00, 0x00, 0x67, 0xd1, + 0xff, 0xff, 0x8b, 0xfc, 0xff, 0xff, 0x6e, 0x13, 0x00, 0x00, 0x3e, 0xe7, 0xff, + 0xff, 0x34, 0x53, 0x00, 0x00, 0x05, 0x3a, 0x00, 0x00, 0x5c, 0x1a, 0x00, 0x00, + 0xdd, 0x16, 0x00, 0x00, 0x31, 0x52, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x4a, + 0x15, 0x00, 0x00, 0x26, 0x2f, 0x00, 0x00, 0xcb, 0x12, 0x00, 0x00, 0xd0, 0x1a, + 0x00, 0x00, 0xda, 0x19, 0x00, 0x00, 0x2e, 0x57, 0x00, 0x00, 0x3d, 0x04, 0x00, + 0x00, 0x9d, 0x28, 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0x7f, 0xfa, 0xff, 0xff, + 0x11, 0x22, 0x00, 0x00, 0x06, 0x0a, 0x00, 0x00, 0xce, 0x4b, 0x00, 0x00, 0xff, + 0x16, 0x00, 0x00, 0xf2, 0x41, 0x00, 0x00, 0xca, 0x1c, 0x00, 0x00, 0x57, 0x28, + 0x00, 0x00, 0x6d, 0x27, 0x00, 0x00, 0x4a, 0x0a, 0x00, 0x00, 0xbf, 0x50, 0x00, + 0x00, 0x55, 0x3d, 0x00, 0x00, 0x59, 0x57, 0x00, 0x00, 0x44, 0x4c, 0x00, 0x00, + 0x32, 0x22, 0x00, 0x00, 0x88, 0x02, 0x00, 0x00, 0x73, 0xde, 0xff, 0xff, 0xbe, + 0x37, 0x00, 0x00, 0xca, 0x18, 0x00, 0x00, 0x3c, 0xfb, 0xff, 0xff, 0x0b, 0x42, + 0x00, 0x00, 0x68, 0x72, 0x00, 0x00, 0xff, 0xe9, 0xff, 0xff, 0x03, 0x0d, 0x00, + 0x00, 0x40, 0x22, 0x00, 0x00, 0x79, 0x2e, 0x00, 0x00, 0x3f, 0xe5, 0xff, 0xff, + 0x63, 0x33, 0x00, 0x00, 0x2c, 0x5f, 0x00, 0x00, 0x94, 0x2e, 0x00, 0x00, 0x71, + 0x01, 0x00, 0x00, 0x4e, 0x38, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x9e, 0x2e, + 0x00, 0x00, 0xc4, 0xdd, 0xff, 0xff, 0x1b, 0x0c, 0x00, 0x00, 0x23, 0x28, 0x00, + 0x00, 0xee, 0x1c, 0x00, 0x00, 0x8b, 0x2e, 0x00, 0x00, 0xff, 0xf7, 0xff, 0xff, + 0xab, 0x0b, 0x00, 0x00, 0x96, 0x3a, 0x00, 0x00, 0xdf, 0x2b, 0x00, 0x00, 0xc2, + 0x4e, 0x00, 0x00, 0x6f, 0x09, 0x00, 0x00, 0xc3, 0x6a, 0x00, 0x00, 0x61, 0x19, + 0x00, 0x00, 0x2c, 0xdc, 0xff, 0xff, 0xfb, 0x25, 0x00, 0x00, 0x67, 0x66, 0x00, + 0x00, 0x65, 0xf6, 0xff, 0xff, 0xf5, 0x6e, 0x00, 0x00, 0xb6, 0x17, 0x00, 0x00, + 0xc3, 0x08, 0x00, 0x00, 0x81, 0xf3, 0xff, 0xff, 0x6b, 0xe9, 0xff, 0xff, 0x36, + 0x38, 0x00, 0x00, 0xbb, 0x0e, 0x00, 0x00, 0x35, 0xcf, 0xff, 0xff, 0xdb, 0xd7, + 0xff, 0xff, 0xcd, 0xfb, 0xff, 0xff, 0x2f, 0x11, 0x00, 0x00, 0xfd, 0xfe, 0xff, + 0xff, 0x5d, 0x13, 0x00, 0x00, 0x45, 0x1c, 0x00, 0x00, 0xd6, 0x22, 0x00, 0x00, + 0xb2, 0x0a, 0x00, 0x00, 0x82, 0x17, 0x00, 0x00, 0x9a, 0x52, 0x00, 0x00, 0xe0, + 0xe2, 0xff, 0xff, 0x20, 0x02, 0x00, 0x00, 0x25, 0xfd, 0xff, 0xff, 0xb1, 0x2f, + 0x00, 0x00, 0xa0, 0x3b, 0x00, 0x00, 0xae, 0x26, 0x00, 0x00, 0xb5, 0x3e, 0x00, + 0x00, 0xb9, 0xfb, 0xff, 0xff, 0x2c, 0x40, 0x00, 0x00, 0x64, 0x39, 0x00, 0x00, + 0xeb, 0x46, 0x00, 0x00, 0x2a, 0x1c, 0x00, 0x00, 0xd9, 0x0a, 0x00, 0x00, 0xf0, + 0x40, 0x00, 0x00, 0x55, 0xda, 0xff, 0xff, 0xa7, 0x1e, 0x00, 0x00, 0xa3, 0xf6, + 0xff, 0xff, 0x68, 0x31, 0x00, 0x00, 0x23, 0x29, 0x00, 0x00, 0x0f, 0x25, 0x00, + 0x00, 0x55, 0xfd, 0xff, 0xff, 0x83, 0x1c, 0x00, 0x00, 0xc6, 0x87, 0x00, 0x00, + 0x65, 0xf8, 0xff, 0xff, 0x13, 0xfe, 0xff, 0xff, 0x56, 0x13, 0x00, 0x00, 0xfc, + 0x17, 0x00, 0x00, 0x4e, 0x10, 0x00, 0x00, 0xfd, 0x15, 0x00, 0x00, 0x93, 0xd1, + 0xff, 0xff, 0x13, 0x12, 0x00, 0x00, 0x9d, 0x14, 0x00, 0x00, 0xf3, 0xde, 0xff, + 0xff, 0x83, 0x37, 0x00, 0x00, 0x9f, 0xf9, 0xff, 0xff, 0xbb, 0xed, 0xff, 0xff, + 0x05, 0x2e, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x23, 0x5c, 0x00, 0x00, 0xb8, + 0xf8, 0xff, 0xff, 0xd8, 0x08, 0x00, 0x00, 0x05, 0x44, 0x00, 0x00, 0xc2, 0x5b, + 0x00, 0x00, 0xe8, 0x0a, 0x00, 0x00, 0xe8, 0x47, 0x00, 0x00, 0x1e, 0x1b, 0x00, + 0x00, 0xcd, 0xff, 0xff, 0xff, 0x0e, 0x1c, 0x00, 0x00, 0x4c, 0x40, 0x00, 0x00, + 0x5b, 0x28, 0x00, 0x00, 0x17, 0x3a, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x53, + 0x77, 0x00, 0x00, 0xf4, 0x42, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00, 0x5e, 0xed, + 0xff, 0xff, 0x78, 0x17, 0x00, 0x00, 0x32, 0x26, 0x00, 0x00, 0x50, 0x1a, 0x00, + 0x00, 0x91, 0xfb, 0xff, 0xff, 0xb9, 0x4f, 0x00, 0x00, 0xd8, 0x05, 0x00, 0x00, + 0x64, 0x38, 0x00, 0x00, 0x17, 0x2f, 0x00, 0x00, 0x81, 0x1e, 0x00, 0x00, 0xf4, + 0x17, 0x00, 0x00, 0x27, 0x26, 0x00, 0x00, 0xea, 0xed, 0xff, 0xff, 0x1a, 0x3b, + 0x00, 0x00, 0x87, 0x7b, 0x00, 0x00, 0xcd, 0x22, 0x00, 0x00, 0xb0, 0x53, 0x00, + 0x00, 0x7a, 0xda, 0xff, 0xff, 0x7f, 0x0c, 0x00, 0x00, 0x01, 0x43, 0x00, 0x00, + 0x2e, 0x07, 0x00, 0x00, 0x89, 0xf3, 0xff, 0xff, 0xdf, 0x2b, 0x00, 0x00, 0xb1, + 0x61, 0x00, 0x00, 0xe0, 0x1c, 0x00, 0x00, 0x95, 0x4d, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x9e, 0x40, 0x00, 0x00, 0x44, 0x4a, 0x00, 0x00, 0xa2, 0xcb, 0xff, + 0xff, 0x9d, 0x16, 0x00, 0x00, 0xca, 0x47, 0x00, 0x00, 0x33, 0x0e, 0x00, 0x00, + 0x2e, 0x50, 0x00, 0x00, 0xf9, 0x28, 0x00, 0x00, 0x40, 0x17, 0x00, 0x00, 0x03, + 0x57, 0x00, 0x00, 0xfe, 0xe3, 0xff, 0xff, 0xa8, 0x2f, 0x00, 0x00, 0xe9, 0x00, + 0x00, 0x00, 0xa6, 0x07, 0x00, 0x00, 0x78, 0x10, 0x00, 0x00, 0xd3, 0x45, 0x00, + 0x00, 0xd3, 0xce, 0xff, 0xff, 0x0f, 0x2d, 0x00, 0x00, 0x83, 0xf4, 0xff, 0xff, + 0xba, 0x2a, 0x00, 0x00, 0xec, 0x15, 0x00, 0x00, 0x94, 0x5d, 0x00, 0x00, 0x83, + 0x0e, 0x00, 0x00, 0xe6, 0x1c, 0x00, 0x00, 0x98, 0x39, 0x00, 0x00, 0x9c, 0x3a, + 0x00, 0x00, 0x7e, 0x05, 0x00, 0x00, 0x17, 0x46, 0x00, 0x00, 0xa8, 0xf9, 0xff, + 0xff, 0x40, 0x0d, 0x00, 0x00, 0x40, 0x12, 0x00, 0x00, 0x1a, 0x07, 0x00, 0x00, + 0x32, 0x23, 0x00, 0x00, 0x3f, 0x0c, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x3c, + 0x01, 0x00, 0x00, 0xe3, 0x75, 0x00, 0x00, 0xa3, 0x1f, 0x00, 0x00, 0xa1, 0x27, + 0x00, 0x00, 0xd0, 0x23, 0x00, 0x00, 0xeb, 0xdc, 0xff, 0xff, 0x99, 0x05, 0x00, + 0x00, 0x27, 0x0e, 0x00, 0x00, 0xd7, 0xf2, 0xff, 0xff, 0xce, 0xfc, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf1, 0x25, 0xba, 0xa3, 0xe0, + 0xeb, 0xbd, 0x28, 0xce, 0x20, 0xc9, 0xfb, 0x37, 0x28, 0x43, 0xea, 0x70, 0xa9, + 0xe0, 0x2c, 0xe1, 0x9e, 0x5f, 0xc9, 0x52, 0xd2, 0x28, 0x21, 0xcb, 0xef, 0xc2, + 0x08, 0x13, 0xc5, 0x29, 0xfa, 0x40, 0xfa, 0x0d, 0xfd, 0xdb, 0x16, 0x50, 0x43, + 0xb5, 0xf1, 0x5d, 0xdc, 0x2d, 0x42, 0x0d, 0xd9, 0x94, 0x22, 0xae, 0x1f, 0x31, + 0x13, 0xcc, 0xcf, 0xc2, 0xa6, 0x81, 0xc5, 0xaa, 0x17, 0xaf, 0xef, 0xd4, 0x0c, + 0xab, 0xb2, 0xa8, 0x12, 0x36, 0xa5, 0x3c, 0xd4, 0xbf, 0xbb, 0xca, 0x0f, 0xaf, + 0x14, 0xb6, 0xdb, 0xb0, 0xcb, 0xb1, 0x8b, 0x31, 0xd0, 0x19, 0xcd, 0xab, 0x47, + 0x16, 0xb8, 0x29, 0xa8, 0xfa, 0x82, 0x59, 0xa5, 0xad, 0xb2, 0xa6, 0xde, 0xbf, + 0xbd, 0x17, 0xcf, 0xb9, 0x1a, 0xcd, 0x17, 0xc4, 0xe2, 0xd0, 0xe2, 0x2f, 0xc8, + 0xbf, 0x3e, 0xd4, 0xbe, 0xae, 0xe6, 0x03, 0x1b, 0x2e, 0x47, 0xa0, 0xe2, 0xb4, + 0xc4, 0x28, 0xb1, 0xb7, 0xe4, 0x18, 0x00, 0xcb, 0x18, 0x3a, 0xea, 0x01, 0x22, + 0xe1, 0xb8, 0xd9, 0xfd, 0xbb, 0xd3, 0xd5, 0xc7, 0xde, 0xc1, 0xf8, 0xab, 0xab, + 0x44, 0xb7, 0x08, 0xd9, 0xd2, 0xc9, 0xfe, 0xa4, 0x1a, 0xd8, 0xc5, 0x22, 0x9a, + 0x48, 0xd6, 0x30, 0x38, 0x1e, 0x38, 0xb8, 0xeb, 0x1f, 0x10, 0xd8, 0xbe, 0x15, + 0xde, 0x24, 0x0d, 0x14, 0xa7, 0x97, 0xab, 0x26, 0xeb, 0xe7, 0x9b, 0xd4, 0xb2, + 0xf3, 0xc8, 0x5d, 0x33, 0x0f, 0xce, 0xc5, 0xce, 0xaa, 0x50, 0xbc, 0x1e, 0x11, + 0xbe, 0xde, 0xe2, 0xc6, 0xee, 0xba, 0xf4, 0xe9, 0x0e, 0x97, 0x30, 0x3f, 0x01, + 0xd8, 0x5c, 0x0f, 0xec, 0x22, 0xe0, 0x3e, 0xbb, 0xd8, 0x39, 0xc1, 0xb3, 0x02, + 0x15, 0xd0, 0x17, 0xf9, 0x32, 0xc6, 0xcf, 0xb2, 0xbc, 0x20, 0xbb, 0xd3, 0xc7, + 0x2c, 0xb9, 0xd7, 0x2f, 0x1c, 0xe4, 0x4d, 0x65, 0x2e, 0x08, 0x32, 0xd8, 0x38, + 0xe1, 0x52, 0x19, 0xc4, 0xf2, 0xb8, 0x16, 0x91, 0x5a, 0x27, 0xca, 0x20, 0x74, + 0xa5, 0x22, 0xb3, 0x2e, 0xdd, 0xe5, 0x2c, 0x14, 0x42, 0xf7, 0xe5, 0x40, 0xc0, + 0xf9, 0xb8, 0x07, 0xee, 0x0f, 0x1e, 0xed, 0xa3, 0xc8, 0x3b, 0x0d, 0xa4, 0x0f, + 0xe8, 0xb8, 0xfd, 0x16, 0x64, 0xd9, 0x46, 0xe3, 0xce, 0xe9, 0x2d, 0x48, 0x34, + 0x4f, 0x78, 0x3a, 0x56, 0xe2, 0x55, 0x0d, 0x40, 0xf9, 0x4e, 0x5f, 0x68, 0xea, + 0xb9, 0x63, 0xc9, 0x30, 0x50, 0x57, 0x30, 0xfb, 0x4d, 0xf6, 0x55, 0x2c, 0x56, + 0x35, 0x5e, 0x78, 0xd3, 0x37, 0xe9, 0x3f, 0x64, 0xb0, 0xe5, 0x49, 0xdb, 0x55, + 0x10, 0x7f, 0x9a, 0x61, 0x47, 0x4e, 0x52, 0x27, 0x44, 0x45, 0xdf, 0x2e, 0x46, + 0xe4, 0x53, 0xe4, 0x2c, 0x28, 0x2f, 0x2b, 0xd6, 0x3e, 0x37, 0xbb, 0x28, 0x43, + 0x59, 0x18, 0xe8, 0xd4, 0xe8, 0xd0, 0x5f, 0x0a, 0x47, 0x43, 0xe5, 0x4f, 0x62, + 0x22, 0xf4, 0x00, 0x32, 0xee, 0xb8, 0x27, 0xfd, 0xde, 0x3f, 0x3b, 0x43, 0x05, + 0x4b, 0x38, 0x3c, 0x31, 0x29, 0x40, 0x10, 0x3c, 0x65, 0x9d, 0x38, 0xe0, 0x23, + 0x1e, 0x38, 0xfe, 0x52, 0xed, 0x31, 0x44, 0xd8, 0x6c, 0xb0, 0x33, 0xd4, 0xd4, + 0xf7, 0xca, 0x4f, 0x10, 0xd6, 0xf2, 0x2c, 0x3d, 0xee, 0x1f, 0xe7, 0x00, 0xf0, + 0x58, 0x6d, 0x5d, 0xc1, 0x1b, 0x0d, 0x6a, 0x27, 0x55, 0x05, 0x43, 0xa8, 0xdd, + 0xe8, 0x2a, 0x46, 0x44, 0x53, 0xb4, 0x29, 0xcc, 0xdb, 0x46, 0x26, 0x27, 0x52, + 0x0e, 0x45, 0xfd, 0x17, 0xe1, 0x6b, 0xe1, 0xb5, 0x01, 0x2b, 0x99, 0xf9, 0x23, + 0xe7, 0x34, 0xcb, 0x39, 0x2d, 0xc2, 0x43, 0x5a, 0x0e, 0xeb, 0x3b, 0xe4, 0x19, + 0xd4, 0x4c, 0x30, 0x6b, 0x3e, 0xdc, 0x46, 0x39, 0x38, 0xce, 0x47, 0x2c, 0xc6, + 0xda, 0xfe, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x8b, + 0x3f, 0x00, 0x00, 0x49, 0xbd, 0xff, 0xff, 0xee, 0xfe, 0xff, 0xff, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0xd8, 0x56, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x54, 0x4f, 0x43, 0x4f, + 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x78, 0x54, 0xff, 0xff, 0xf0, 0x08, + 0x00, 0x00, 0xe4, 0x08, 0x00, 0x00, 0xd8, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, + 0xc0, 0x07, 0x00, 0x00, 0x78, 0x07, 0x00, 0x00, 0x34, 0x07, 0x00, 0x00, 0xec, + 0x06, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x1c, 0x06, + 0x00, 0x00, 0xd4, 0x05, 0x00, 0x00, 0x90, 0x05, 0x00, 0x00, 0x48, 0x05, 0x00, + 0x00, 0x04, 0x05, 0x00, 0x00, 0xbc, 0x04, 0x00, 0x00, 0x78, 0x04, 0x00, 0x00, + 0x30, 0x04, 0x00, 0x00, 0xec, 0x03, 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x60, + 0x03, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x8c, 0x02, + 0x00, 0x00, 0x48, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xbc, 0x01, 0x00, + 0x00, 0x74, 0x01, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, + 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xce, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x42, 0xf8, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x11, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x8a, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x10, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x07, + 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x82, 0xf9, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd0, 0xf9, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xc2, 0xf9, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5e, 0xf9, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x06, + 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x54, 0xfa, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x46, 0xfa, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe2, 0xf9, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, + 0x00, 0x8a, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd8, + 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x27, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0xca, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0xfa, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x0e, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x5c, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0x00, + 0x00, 0x00, 0x4e, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xea, 0xfa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x92, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xe0, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0xd2, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x6e, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x53, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x16, 0xfc, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x52, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x56, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xf2, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x9a, 0xfc, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe8, 0xfc, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x4e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0xda, 0xfc, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x76, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4a, + 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x1e, 0xfd, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6c, 0xfd, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x5e, 0xfd, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xfa, 0xfc, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x46, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0xa2, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf0, 0xfd, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xe2, + 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7e, 0xfd, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x26, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x74, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, + 0x00, 0x66, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, + 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xaa, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xf8, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x86, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x2e, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x7c, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x39, 0x00, 0x00, 0x00, 0x6e, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xb2, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, + 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xaa, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, + 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, + 0x00, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x22, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x57, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x59, 0x00, + 0x00, 0x00, 0xb4, 0x2f, 0x01, 0x00, 0x1c, 0x29, 0x01, 0x00, 0x88, 0x22, 0x01, + 0x00, 0x04, 0x1c, 0x01, 0x00, 0x8c, 0x15, 0x01, 0x00, 0x04, 0x0f, 0x01, 0x00, + 0x8c, 0x02, 0x01, 0x00, 0x04, 0xf6, 0x00, 0x00, 0x8c, 0xe9, 0x00, 0x00, 0xa4, + 0xe8, 0x00, 0x00, 0x6c, 0xe7, 0x00, 0x00, 0x24, 0xe6, 0x00, 0x00, 0x2c, 0xe4, + 0x00, 0x00, 0x24, 0xe2, 0x00, 0x00, 0x2c, 0xe0, 0x00, 0x00, 0x24, 0xde, 0x00, + 0x00, 0xac, 0xda, 0x00, 0x00, 0x24, 0xd7, 0x00, 0x00, 0xac, 0xd3, 0x00, 0x00, + 0x24, 0xd0, 0x00, 0x00, 0xac, 0xc9, 0x00, 0x00, 0x24, 0xc3, 0x00, 0x00, 0xac, + 0xbc, 0x00, 0x00, 0x24, 0xb6, 0x00, 0x00, 0xac, 0xaf, 0x00, 0x00, 0x24, 0xa9, + 0x00, 0x00, 0xac, 0xa2, 0x00, 0x00, 0x0c, 0xa2, 0x00, 0x00, 0x74, 0xa1, 0x00, + 0x00, 0xf0, 0xa0, 0x00, 0x00, 0x5c, 0xa0, 0x00, 0x00, 0xd0, 0x9f, 0x00, 0x00, + 0x78, 0x9f, 0x00, 0x00, 0xa4, 0x9e, 0x00, 0x00, 0x0c, 0x9e, 0x00, 0x00, 0x68, + 0x9d, 0x00, 0x00, 0xe8, 0x96, 0x00, 0x00, 0x70, 0x90, 0x00, 0x00, 0xcc, 0x8f, + 0x00, 0x00, 0x28, 0x8f, 0x00, 0x00, 0xa8, 0x88, 0x00, 0x00, 0x30, 0x82, 0x00, + 0x00, 0x8c, 0x81, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x00, 0x68, 0x7a, 0x00, 0x00, + 0xf0, 0x6d, 0x00, 0x00, 0x4c, 0x6d, 0x00, 0x00, 0xa8, 0x6c, 0x00, 0x00, 0x28, + 0x60, 0x00, 0x00, 0xb0, 0x53, 0x00, 0x00, 0x0c, 0x53, 0x00, 0x00, 0x68, 0x52, + 0x00, 0x00, 0x88, 0x51, 0x00, 0x00, 0x50, 0x50, 0x00, 0x00, 0xac, 0x4f, 0x00, + 0x00, 0x08, 0x4f, 0x00, 0x00, 0xc8, 0x4d, 0x00, 0x00, 0xd0, 0x4b, 0x00, 0x00, + 0x2c, 0x4b, 0x00, 0x00, 0x88, 0x4a, 0x00, 0x00, 0x88, 0x48, 0x00, 0x00, 0x90, + 0x46, 0x00, 0x00, 0xec, 0x45, 0x00, 0x00, 0x48, 0x45, 0x00, 0x00, 0x48, 0x43, + 0x00, 0x00, 0xd0, 0x3f, 0x00, 0x00, 0x2c, 0x3f, 0x00, 0x00, 0x88, 0x3e, 0x00, + 0x00, 0x08, 0x3b, 0x00, 0x00, 0x90, 0x37, 0x00, 0x00, 0xec, 0x36, 0x00, 0x00, + 0x48, 0x36, 0x00, 0x00, 0xc8, 0x32, 0x00, 0x00, 0x50, 0x2c, 0x00, 0x00, 0xac, + 0x2b, 0x00, 0x00, 0x08, 0x2b, 0x00, 0x00, 0x88, 0x24, 0x00, 0x00, 0x10, 0x1e, + 0x00, 0x00, 0x6c, 0x1d, 0x00, 0x00, 0xc8, 0x1c, 0x00, 0x00, 0x48, 0x16, 0x00, + 0x00, 0xd0, 0x0f, 0x00, 0x00, 0x2c, 0x0f, 0x00, 0x00, 0x88, 0x0e, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x52, 0xd8, 0xfe, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x54, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xec, 0x5e, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x81, 0x80, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x05, 0x00, 0x00, 0x00, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xc2, 0xd8, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x09, 0x5c, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x44, 0xdf, 0xfe, 0xff, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3b, 0x21, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x52, + 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0xd9, 0xfe, + 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xcc, 0x5f, 0xff, 0xff, 0x30, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x39, + 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, + 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0xd2, 0xd9, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x06, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x54, + 0xe0, 0xfe, 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x09, 0xc1, 0x56, 0x38, 0x70, 0xbe, + 0x8a, 0x38, 0xc6, 0x5e, 0x5c, 0x38, 0x6b, 0x13, 0x7e, 0x38, 0x35, 0xee, 0x4e, + 0x38, 0x92, 0x3c, 0xb2, 0x38, 0x73, 0x8f, 0x83, 0x38, 0x0e, 0x10, 0x96, 0x38, + 0x30, 0xad, 0x59, 0x38, 0x3a, 0xfb, 0x97, 0x38, 0x7d, 0xae, 0x8d, 0x38, 0x37, + 0x9b, 0x8a, 0x38, 0x06, 0xbc, 0x4d, 0x38, 0x17, 0x10, 0x7e, 0x38, 0x6a, 0xf4, + 0x80, 0x38, 0x76, 0x67, 0x2f, 0x38, 0xcc, 0x91, 0x68, 0x38, 0x9a, 0x18, 0x55, + 0x38, 0x1b, 0x65, 0x30, 0x38, 0x52, 0xad, 0x97, 0x38, 0x99, 0x46, 0x80, 0x38, + 0x7e, 0x0e, 0x81, 0x38, 0x50, 0xe4, 0x69, 0x38, 0xc7, 0x6b, 0x51, 0x38, 0x9b, + 0x88, 0x39, 0x38, 0xf3, 0xa1, 0xc5, 0x38, 0x62, 0xe9, 0x42, 0x38, 0x89, 0xe8, + 0xad, 0x38, 0x8e, 0xc1, 0xc0, 0x38, 0x2c, 0xf5, 0x85, 0x38, 0x94, 0xee, 0x7c, + 0x38, 0x4c, 0xde, 0x9f, 0x38, 0xea, 0xa8, 0x98, 0x38, 0xe4, 0x06, 0x5e, 0x38, + 0x83, 0x3e, 0x92, 0x38, 0x1b, 0x6c, 0x4d, 0x38, 0x38, 0xee, 0x8d, 0x38, 0xe2, + 0xb2, 0x82, 0x38, 0x8e, 0xc1, 0x55, 0x38, 0xc9, 0x3b, 0x9d, 0x38, 0xf6, 0x00, + 0x9a, 0x38, 0x65, 0x1f, 0x9f, 0x38, 0x38, 0xc2, 0x5a, 0x38, 0x8c, 0x70, 0x7b, + 0x38, 0xa7, 0x22, 0x53, 0x38, 0xe2, 0xe7, 0x55, 0x38, 0xfc, 0xcf, 0x8c, 0x38, + 0xed, 0x8b, 0x7a, 0x38, 0x13, 0xa5, 0x86, 0x38, 0x7f, 0xf3, 0x87, 0x38, 0x76, + 0x25, 0x69, 0x38, 0x2e, 0x32, 0x80, 0x38, 0x72, 0x5e, 0x95, 0x38, 0x7a, 0x2c, + 0x85, 0x38, 0xc3, 0x7d, 0x94, 0x38, 0x50, 0x99, 0x97, 0x38, 0x0a, 0x98, 0x80, + 0x38, 0x47, 0xa5, 0x4c, 0x38, 0x61, 0x07, 0x7c, 0x38, 0x4b, 0x39, 0x82, 0x38, + 0xc3, 0x09, 0x6f, 0x38, 0x41, 0xb8, 0x78, 0x38, 0x5f, 0x0e, 0x51, 0x38, 0x23, + 0xc2, 0x86, 0x38, 0x30, 0xc3, 0x98, 0x38, 0xa8, 0x15, 0x80, 0x38, 0xea, 0xe4, + 0x8b, 0x38, 0x8b, 0x83, 0x86, 0x38, 0x03, 0xff, 0x52, 0x38, 0x19, 0xcf, 0x84, + 0x38, 0x30, 0xfe, 0xad, 0x38, 0xd5, 0x13, 0x56, 0x38, 0x41, 0x60, 0x7f, 0x38, + 0x73, 0xa4, 0x81, 0x38, 0xd9, 0x0d, 0xbc, 0x38, 0xf5, 0xae, 0xa6, 0x38, 0x59, + 0xa6, 0x7f, 0x38, 0x04, 0xb7, 0x91, 0x38, 0xb0, 0x51, 0x88, 0x38, 0xdf, 0x68, + 0x85, 0x38, 0x73, 0xfc, 0x88, 0x38, 0x3e, 0xf8, 0x79, 0x38, 0xf6, 0x38, 0x97, + 0x38, 0x69, 0x3e, 0x97, 0x38, 0x50, 0xf3, 0x7a, 0x38, 0x91, 0x57, 0x5d, 0x38, + 0x06, 0x22, 0x63, 0x38, 0xaf, 0x51, 0x7c, 0x38, 0x6e, 0x68, 0xa1, 0x38, 0x08, + 0x2a, 0xa3, 0x38, 0x5b, 0x07, 0xb2, 0x38, 0x36, 0x72, 0x95, 0x38, 0x02, 0xcf, + 0x6e, 0x38, 0x17, 0x6b, 0x84, 0x38, 0x7f, 0x72, 0x78, 0x38, 0xc7, 0x37, 0x78, + 0x38, 0xb3, 0xd1, 0x61, 0x38, 0x69, 0xc3, 0x96, 0x38, 0x8e, 0x04, 0x50, 0x38, + 0x4b, 0x1c, 0x89, 0x38, 0x7d, 0x9d, 0x7f, 0x38, 0xb0, 0x7d, 0x5f, 0x38, 0xe8, + 0x6b, 0x70, 0x38, 0xd3, 0x12, 0x65, 0x38, 0x5b, 0x57, 0x91, 0x38, 0x35, 0x42, + 0x6d, 0x38, 0x3d, 0xa2, 0x89, 0x38, 0xa9, 0xdb, 0x56, 0x38, 0x8e, 0x11, 0x5f, + 0x38, 0x0b, 0x42, 0x4b, 0x38, 0xe7, 0x81, 0xc2, 0x38, 0x9e, 0xfc, 0x61, 0x38, + 0x95, 0xd3, 0xb9, 0x38, 0x15, 0x9f, 0x93, 0x38, 0x07, 0x4e, 0x39, 0x38, 0x9e, + 0xa7, 0x70, 0x38, 0x4d, 0xd4, 0x61, 0x38, 0xc6, 0x72, 0x70, 0x38, 0x04, 0xf0, + 0xa8, 0x38, 0x59, 0x15, 0xd0, 0x38, 0x9c, 0x9a, 0xbf, 0x38, 0x39, 0x42, 0x84, + 0x38, 0xfa, 0x8a, 0x8d, 0x38, 0x36, 0x1c, 0x3a, 0x38, 0xfc, 0x64, 0x61, 0x38, + 0x61, 0xb6, 0x73, 0x38, 0x3d, 0x27, 0x75, 0x38, 0xd9, 0xc4, 0x97, 0x38, 0x36, + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x39, 0x5f, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, + 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x46, 0xe0, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x06, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xa2, 0xd9, 0xfe, 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x8f, + 0xcb, 0x23, 0x39, 0x92, 0x83, 0xcf, 0x38, 0x7c, 0x0d, 0xdd, 0x38, 0xbc, 0x8b, + 0x0a, 0x39, 0x18, 0x12, 0x7a, 0x39, 0x9b, 0x70, 0x06, 0x39, 0x6a, 0xc6, 0xff, + 0x38, 0x8b, 0x50, 0x1d, 0x39, 0x18, 0xe3, 0xe4, 0x38, 0xf7, 0x10, 0xdb, 0x38, + 0x6c, 0xc8, 0x1a, 0x39, 0x79, 0x8f, 0x3f, 0x39, 0xb3, 0x01, 0xe1, 0x38, 0xde, + 0x9f, 0xd4, 0x38, 0xdb, 0x07, 0x55, 0x39, 0xea, 0x41, 0x30, 0x39, 0xf5, 0xa0, + 0x3a, 0x39, 0x4b, 0x1f, 0x00, 0x39, 0x59, 0xf8, 0xe1, 0x38, 0xea, 0x98, 0xae, + 0x38, 0x56, 0x25, 0x36, 0x39, 0x43, 0x8e, 0xda, 0x38, 0xa3, 0x92, 0x53, 0x39, + 0xd0, 0x31, 0x66, 0x39, 0x14, 0x14, 0x51, 0x39, 0xa9, 0xf9, 0x2a, 0x39, 0x56, + 0x7e, 0xd5, 0x38, 0x7a, 0x79, 0x55, 0x39, 0xfc, 0xb2, 0x3a, 0x39, 0x8e, 0x31, + 0x95, 0x39, 0x4d, 0x04, 0x49, 0x39, 0x61, 0xaf, 0x20, 0x39, 0xa4, 0xb7, 0x04, + 0x39, 0x80, 0x50, 0x2a, 0x39, 0xff, 0xd1, 0x1a, 0x39, 0x4b, 0xe2, 0x3b, 0x39, + 0x02, 0xbb, 0x21, 0x39, 0x92, 0x95, 0x02, 0x39, 0xba, 0x20, 0x04, 0x39, 0x61, + 0x09, 0x6b, 0x39, 0x8b, 0x71, 0xca, 0x38, 0x98, 0x2e, 0x08, 0x39, 0xf6, 0xa6, + 0xe1, 0x38, 0x29, 0x2a, 0x43, 0x39, 0x0f, 0x60, 0x36, 0x39, 0xe2, 0x80, 0x08, + 0x39, 0xa7, 0x75, 0xf3, 0x38, 0xd4, 0x07, 0x09, 0x39, 0x68, 0x6f, 0x6c, 0x39, + 0xe4, 0x93, 0x7f, 0x39, 0xa9, 0x4c, 0x04, 0x39, 0x53, 0x42, 0x4a, 0x39, 0xe4, + 0x10, 0x1f, 0x39, 0x80, 0x86, 0xe8, 0x38, 0x73, 0xef, 0x04, 0x39, 0xf8, 0xa4, + 0x05, 0x39, 0x28, 0x51, 0x15, 0x39, 0x1e, 0x0c, 0x23, 0x39, 0x8c, 0x98, 0xa8, + 0x39, 0x05, 0x83, 0x7a, 0x39, 0xd1, 0x6b, 0x1a, 0x39, 0x17, 0x32, 0x8c, 0x39, + 0xb9, 0xa8, 0x18, 0x39, 0x00, 0x47, 0x03, 0x39, 0x0b, 0x94, 0x23, 0x39, 0xb5, + 0xd3, 0x5c, 0x39, 0x92, 0xba, 0xd8, 0x38, 0x4b, 0x61, 0x18, 0x39, 0x41, 0x3f, + 0x6f, 0x39, 0x84, 0x04, 0xac, 0x38, 0x30, 0x2b, 0x48, 0x39, 0xa4, 0x34, 0x23, + 0x39, 0x8b, 0x5e, 0xe8, 0x38, 0x2a, 0x30, 0xe6, 0x38, 0xf0, 0x4c, 0x09, 0x39, + 0x29, 0xe9, 0xac, 0x39, 0x2a, 0xdf, 0x08, 0x39, 0xed, 0x3c, 0x30, 0x39, 0x8f, + 0x37, 0xf1, 0x38, 0x94, 0xf6, 0xd6, 0x38, 0x8e, 0x51, 0xee, 0x38, 0x39, 0x4a, + 0x0f, 0x39, 0x83, 0xca, 0x44, 0x39, 0x70, 0x12, 0xf0, 0x38, 0x93, 0x9a, 0x34, + 0x39, 0x77, 0xfc, 0xdc, 0x38, 0x3b, 0xaa, 0xf1, 0x38, 0x86, 0x48, 0x16, 0x39, + 0x52, 0xb3, 0x3c, 0x39, 0xd2, 0x02, 0x37, 0x39, 0xba, 0x0a, 0xe7, 0x38, 0xe5, + 0x71, 0xfc, 0x38, 0x2d, 0x79, 0x05, 0x39, 0xb7, 0x1e, 0xb7, 0x38, 0x7f, 0x1e, + 0x97, 0x39, 0x91, 0xcc, 0xd1, 0x38, 0x2b, 0x81, 0x36, 0x39, 0xb6, 0x3f, 0x4a, + 0x39, 0x2f, 0x77, 0xe9, 0x38, 0xfc, 0x08, 0xe2, 0x38, 0xdb, 0xac, 0x41, 0x39, + 0x6e, 0x60, 0xe8, 0x38, 0x32, 0x5a, 0x0a, 0x39, 0x8c, 0x3a, 0xd8, 0x38, 0x97, + 0x15, 0xd5, 0x38, 0x4d, 0x54, 0xf7, 0x38, 0xc6, 0x45, 0x3a, 0x39, 0xcf, 0x4c, + 0x24, 0x39, 0xf7, 0x4e, 0x00, 0x39, 0x9b, 0xa0, 0x3f, 0x39, 0x7c, 0x4c, 0xeb, + 0x38, 0x34, 0x60, 0x40, 0x39, 0xd8, 0xdc, 0xe2, 0x38, 0x21, 0x86, 0xce, 0x38, + 0x5f, 0x05, 0x0d, 0x39, 0x79, 0x9f, 0x01, 0x39, 0x15, 0xa6, 0x19, 0x39, 0x70, + 0x6d, 0x1a, 0x39, 0x0e, 0xe6, 0x4b, 0x39, 0x22, 0x44, 0x35, 0x39, 0x7a, 0x72, + 0x45, 0x39, 0x75, 0x03, 0xb3, 0x38, 0xdf, 0x93, 0xe4, 0x38, 0xcf, 0x69, 0xd4, + 0x38, 0x56, 0xa3, 0x02, 0x39, 0x29, 0x15, 0xd1, 0x38, 0xf9, 0x55, 0xf6, 0x38, + 0xea, 0x4f, 0x0f, 0x39, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x39, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc2, 0xe6, + 0xfe, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5c, 0x6d, 0xff, 0xff, + 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, + 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x39, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, + 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x62, 0xe7, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, + 0x00, 0x2b, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xfc, 0x6d, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x38, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0xe8, 0xfe, 0xff, 0x00, 0x00, 0x00, + 0x02, 0x64, 0x06, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x84, 0xee, 0xfe, 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, + 0x87, 0x53, 0x38, 0x9e, 0xa2, 0x7d, 0x38, 0x7f, 0xbe, 0x75, 0x38, 0xa1, 0x24, + 0x71, 0x38, 0x94, 0x4d, 0xb1, 0x38, 0x29, 0xe9, 0xae, 0x38, 0x71, 0x40, 0x73, + 0x38, 0x2d, 0x97, 0x66, 0x38, 0x02, 0xf5, 0x6a, 0x38, 0xdf, 0xd8, 0x99, 0x38, + 0x88, 0x06, 0x87, 0x38, 0xd1, 0xe2, 0x82, 0x38, 0x30, 0xc7, 0x82, 0x38, 0x47, + 0x1e, 0x87, 0x38, 0xc7, 0x7d, 0x50, 0x38, 0xac, 0x3f, 0x59, 0x38, 0xf9, 0xac, + 0x8c, 0x38, 0x30, 0xa1, 0x91, 0x38, 0x5b, 0x15, 0x7f, 0x38, 0xff, 0xfa, 0x54, + 0x38, 0x85, 0x90, 0x8c, 0x38, 0x37, 0x35, 0x7e, 0x38, 0xfa, 0xe0, 0x88, 0x38, + 0x18, 0x32, 0x87, 0x38, 0x52, 0x6e, 0x92, 0x38, 0xf0, 0xb0, 0x7e, 0x38, 0x18, + 0xd4, 0x73, 0x38, 0x67, 0x2d, 0x95, 0x38, 0x44, 0x40, 0x83, 0x38, 0x8c, 0xae, + 0x83, 0x38, 0x22, 0xa0, 0x86, 0x38, 0x1a, 0xad, 0x94, 0x38, 0xed, 0xfd, 0x8f, + 0x38, 0xa1, 0x1d, 0x65, 0x38, 0xff, 0x45, 0x67, 0x38, 0x24, 0x9b, 0x85, 0x38, + 0xfb, 0x5f, 0xb1, 0x38, 0xee, 0xe4, 0x8e, 0x38, 0x3f, 0xd4, 0x83, 0x38, 0x67, + 0x1c, 0x70, 0x38, 0xab, 0xef, 0x8a, 0x38, 0x9e, 0x4b, 0x83, 0x38, 0x4d, 0x92, + 0x5c, 0x38, 0xd9, 0x84, 0x7a, 0x38, 0x41, 0xde, 0x51, 0x38, 0x2d, 0x3c, 0x75, + 0x38, 0x6d, 0x6f, 0x96, 0x38, 0xb5, 0x6d, 0x95, 0x38, 0xdc, 0xf4, 0x31, 0x38, + 0x74, 0x9c, 0x2c, 0x38, 0xb6, 0x91, 0x8b, 0x38, 0xa3, 0xac, 0x32, 0x38, 0x8e, + 0xf8, 0x80, 0x38, 0x33, 0x35, 0x66, 0x38, 0x91, 0x5c, 0x41, 0x38, 0x70, 0x7b, + 0x88, 0x38, 0xa8, 0x31, 0x85, 0x38, 0x4a, 0xf1, 0x50, 0x38, 0x20, 0x68, 0x86, + 0x38, 0x2f, 0x82, 0x80, 0x38, 0x08, 0x63, 0x43, 0x38, 0x62, 0x65, 0x70, 0x38, + 0x5b, 0x58, 0x84, 0x38, 0x3c, 0x49, 0x97, 0x38, 0x98, 0x68, 0x60, 0x38, 0xd0, + 0xe8, 0x83, 0x38, 0x62, 0xca, 0x4b, 0x38, 0xc5, 0xaf, 0x81, 0x38, 0x0f, 0x62, + 0x73, 0x38, 0xff, 0xbd, 0x7f, 0x38, 0xc6, 0x43, 0x9f, 0x38, 0x96, 0x2d, 0x93, + 0x38, 0x40, 0x9d, 0x8f, 0x38, 0x54, 0xaa, 0xac, 0x38, 0x20, 0x51, 0xb0, 0x38, + 0x8e, 0xa3, 0x84, 0x38, 0xaa, 0x0f, 0xb8, 0x38, 0xad, 0x3d, 0x5f, 0x38, 0x45, + 0x6d, 0x83, 0x38, 0x4d, 0x6c, 0x6a, 0x38, 0xea, 0xc4, 0x87, 0x38, 0xa7, 0x52, + 0xac, 0x38, 0x12, 0xef, 0x95, 0x38, 0xeb, 0x1b, 0x8b, 0x38, 0xf0, 0xe9, 0xaf, + 0x38, 0xb3, 0xf3, 0x81, 0x38, 0xe4, 0xa8, 0x3e, 0x38, 0xde, 0x8f, 0x5d, 0x38, + 0xaa, 0xd3, 0x44, 0x38, 0x61, 0x96, 0x87, 0x38, 0x40, 0x35, 0x7a, 0x38, 0xf3, + 0x84, 0x90, 0x38, 0x05, 0x94, 0x79, 0x38, 0x90, 0x70, 0x93, 0x38, 0xa9, 0x54, + 0x6c, 0x38, 0x5d, 0x5e, 0x81, 0x38, 0xd6, 0x95, 0xa7, 0x38, 0xc0, 0xd9, 0x8d, + 0x38, 0xb8, 0xd5, 0x62, 0x38, 0x94, 0x3e, 0x6c, 0x38, 0x0c, 0xf8, 0xa4, 0x38, + 0xd5, 0x76, 0x54, 0x38, 0xe6, 0xe2, 0x93, 0x38, 0x74, 0x27, 0x3d, 0x38, 0x9e, + 0xcb, 0x93, 0x38, 0xeb, 0x8c, 0x5d, 0x38, 0x6f, 0x7d, 0x94, 0x38, 0x2e, 0x42, + 0xb9, 0x38, 0x94, 0x65, 0x55, 0x38, 0x1a, 0xe5, 0x66, 0x38, 0x17, 0x0f, 0x55, + 0x38, 0xbe, 0x91, 0x84, 0x38, 0x1b, 0xc5, 0x89, 0x38, 0x72, 0x38, 0x85, 0x38, + 0x87, 0xcc, 0x8f, 0x38, 0x96, 0x71, 0x83, 0x38, 0xbd, 0x04, 0x6f, 0x38, 0x33, + 0x99, 0x3c, 0x38, 0x73, 0x9d, 0x7d, 0x38, 0x8f, 0x0d, 0x4b, 0x38, 0xa4, 0x6f, + 0x73, 0x38, 0xca, 0xbf, 0x69, 0x38, 0x64, 0x33, 0x7e, 0x38, 0x55, 0x02, 0x81, + 0x38, 0xe5, 0xd2, 0x96, 0x38, 0x27, 0x00, 0x5d, 0x38, 0xd2, 0x15, 0x7b, 0x38, + 0xbf, 0xea, 0x81, 0x38, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x38, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x76, 0xee, 0xfe, 0xff, 0x00, 0x00, + 0x00, 0x02, 0x6c, 0x06, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xd2, 0xe7, 0xfe, 0xff, 0x14, 0x04, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x6c, 0xe2, 0x0b, 0x39, 0xc3, 0x54, 0x4b, 0x39, 0x78, + 0x29, 0x00, 0x39, 0x17, 0x23, 0xcd, 0x38, 0xa2, 0x60, 0x0c, 0x39, 0xf0, 0xcc, + 0x5e, 0x39, 0x9b, 0x41, 0x5d, 0x39, 0x8d, 0xb7, 0x25, 0x39, 0x5c, 0xc1, 0xdf, + 0x38, 0x54, 0x8d, 0x01, 0x39, 0x37, 0x5d, 0xf5, 0x38, 0xa0, 0xf1, 0x70, 0x39, + 0x3e, 0xb2, 0xfd, 0x38, 0x98, 0x3f, 0xe4, 0x38, 0x65, 0x48, 0xd0, 0x38, 0x3e, + 0x60, 0xdd, 0x38, 0xcd, 0x65, 0x7b, 0x39, 0xed, 0xa9, 0x21, 0x39, 0x7c, 0x44, + 0x8c, 0x39, 0x68, 0xf2, 0xf6, 0x38, 0xa0, 0x2a, 0x85, 0x39, 0xd6, 0x79, 0xf1, + 0x38, 0xc9, 0x1a, 0x1f, 0x39, 0x70, 0xb3, 0x08, 0x39, 0xa4, 0x37, 0xdd, 0x38, + 0x6e, 0xfb, 0x15, 0x39, 0x6c, 0xa5, 0x39, 0x39, 0x82, 0xd6, 0x00, 0x39, 0xd5, + 0x9a, 0x0b, 0x39, 0xef, 0xa1, 0x14, 0x39, 0x02, 0xd1, 0x81, 0x39, 0x00, 0x71, + 0x57, 0x39, 0x77, 0xd6, 0x30, 0x39, 0xb3, 0xe9, 0x1e, 0x39, 0x08, 0x37, 0xbf, + 0x38, 0x7f, 0x9e, 0x1a, 0x39, 0x5c, 0xb7, 0xf5, 0x38, 0x1d, 0xb5, 0x22, 0x39, + 0x92, 0x15, 0xf4, 0x38, 0xaa, 0x0e, 0x04, 0x39, 0xa1, 0x4e, 0x02, 0x39, 0x83, + 0xd2, 0x54, 0x39, 0xad, 0x3c, 0x25, 0x39, 0x70, 0x88, 0x09, 0x39, 0x65, 0x13, + 0xc3, 0x38, 0x18, 0x02, 0xf0, 0x38, 0xc2, 0xa6, 0x36, 0x39, 0xeb, 0x6f, 0x6a, + 0x39, 0xfa, 0x9a, 0xe6, 0x38, 0x03, 0xd5, 0x20, 0x39, 0xef, 0x8b, 0x13, 0x39, + 0x3e, 0xdb, 0xfb, 0x38, 0xca, 0xc2, 0x1b, 0x39, 0x9a, 0x7a, 0xe7, 0x38, 0x9b, + 0x14, 0x00, 0x39, 0x5f, 0x15, 0x27, 0x39, 0x39, 0xd9, 0x30, 0x39, 0x4c, 0xbf, + 0x86, 0x39, 0xe9, 0x2f, 0x29, 0x39, 0xcc, 0xda, 0xda, 0x38, 0xf4, 0x7f, 0x7a, + 0x39, 0x3a, 0x7d, 0x1a, 0x39, 0xe4, 0xb2, 0xf3, 0x38, 0xb8, 0x92, 0x3a, 0x39, + 0x03, 0x6d, 0x1a, 0x39, 0x35, 0x9d, 0x4e, 0x39, 0xb0, 0xf5, 0xef, 0x38, 0x15, + 0xc7, 0xce, 0x38, 0x91, 0x19, 0x50, 0x39, 0xbc, 0x6d, 0x0a, 0x39, 0x06, 0xfe, + 0x22, 0x39, 0x61, 0xea, 0x30, 0x39, 0xe8, 0x52, 0x26, 0x39, 0xfd, 0xea, 0xd6, + 0x38, 0x17, 0xba, 0x33, 0x39, 0xd8, 0x54, 0x12, 0x39, 0x0f, 0x2a, 0x18, 0x39, + 0x14, 0x44, 0x04, 0x39, 0xf2, 0x1f, 0x2a, 0x39, 0x3f, 0x04, 0x99, 0x39, 0xc7, + 0xa3, 0x09, 0x39, 0x83, 0x12, 0xe8, 0x38, 0x05, 0x9a, 0x6f, 0x39, 0x21, 0xbe, + 0x02, 0x39, 0x81, 0xf9, 0x26, 0x39, 0xf0, 0x4d, 0xec, 0x38, 0x17, 0x0e, 0x21, + 0x39, 0xc4, 0x6f, 0x63, 0x39, 0x3e, 0xa9, 0x36, 0x39, 0x3b, 0x91, 0x35, 0x39, + 0xe8, 0x6e, 0x95, 0x39, 0xe8, 0xd4, 0xfd, 0x38, 0xbf, 0xfb, 0x43, 0x39, 0xfd, + 0xd8, 0xce, 0x38, 0x0f, 0x5e, 0xea, 0x38, 0x8c, 0x83, 0xdf, 0x38, 0xc4, 0x46, + 0x5a, 0x39, 0x57, 0x2e, 0x27, 0x39, 0xad, 0x75, 0x20, 0x39, 0xdd, 0xcf, 0x24, + 0x39, 0x79, 0xcb, 0xd9, 0x38, 0x8c, 0xf2, 0xf7, 0x38, 0x00, 0xbe, 0xeb, 0x38, + 0xe8, 0x7c, 0x32, 0x39, 0xbd, 0xe0, 0xd3, 0x38, 0x73, 0xd3, 0xf3, 0x38, 0xb9, + 0x02, 0x2a, 0x39, 0x3b, 0xd8, 0x30, 0x39, 0x18, 0xb2, 0x09, 0x39, 0xc7, 0x6b, + 0x62, 0x39, 0xbf, 0x36, 0x06, 0x39, 0xe1, 0x87, 0x3c, 0x39, 0xde, 0xa6, 0x27, + 0x39, 0x44, 0x9f, 0x63, 0x39, 0xa9, 0x3e, 0x2c, 0x39, 0x1b, 0xd6, 0xfb, 0x38, + 0xd8, 0x3c, 0xdb, 0x38, 0xcd, 0xf0, 0xed, 0x38, 0xa1, 0xb9, 0x82, 0x39, 0xd9, + 0x5d, 0xd8, 0x38, 0xf4, 0x20, 0xef, 0x38, 0x68, 0x24, 0x71, 0x39, 0x7a, 0x10, + 0xe4, 0x38, 0x0b, 0x9c, 0x88, 0x39, 0x8f, 0xcb, 0x35, 0x39, 0x82, 0xaa, 0xfb, + 0x38, 0xce, 0x66, 0x02, 0x39, 0xde, 0x38, 0x17, 0x39, 0x39, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x38, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, + 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xf2, 0xf4, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x8c, 0x7b, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x38, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x92, 0xf5, 0xfe, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x2c, 0x7c, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x37, 0x5f, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x32, 0xf6, + 0xfe, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x06, 0x00, 0x00, 0x53, 0x00, 0x00, + 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb4, 0xfc, 0xfe, 0xff, + 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xaa, 0x0c, 0x61, 0x38, 0xf0, 0x53, 0xb3, 0x38, 0x35, + 0xea, 0x8d, 0x38, 0xa4, 0xc2, 0x86, 0x38, 0xe8, 0x92, 0x60, 0x38, 0xc0, 0x2c, + 0x5c, 0x38, 0x67, 0xa0, 0x62, 0x38, 0xa1, 0xb3, 0xb4, 0x38, 0x5c, 0x07, 0x60, + 0x38, 0x30, 0xdc, 0x5f, 0x38, 0x2a, 0xa0, 0xd1, 0x38, 0xc9, 0x14, 0x9e, 0x38, + 0x9d, 0xac, 0x58, 0x38, 0xf3, 0x95, 0x8a, 0x38, 0x83, 0x03, 0x8d, 0x38, 0x78, + 0x46, 0x86, 0x38, 0x80, 0xea, 0x5d, 0x38, 0xe1, 0x99, 0x9a, 0x38, 0x4b, 0xe2, + 0x96, 0x38, 0xa9, 0xeb, 0x83, 0x38, 0x6b, 0x80, 0x8f, 0x38, 0x18, 0xf4, 0x80, + 0x38, 0x65, 0xfb, 0x67, 0x38, 0x1b, 0xd7, 0x8e, 0x38, 0xc4, 0x6c, 0x96, 0x38, + 0x92, 0x70, 0x98, 0x38, 0x9e, 0x46, 0x47, 0x38, 0xaa, 0xde, 0x7c, 0x38, 0x5f, + 0xc7, 0x4b, 0x38, 0xff, 0xa2, 0x83, 0x38, 0x4b, 0xa4, 0x82, 0x38, 0x61, 0xee, + 0x9b, 0x38, 0x47, 0xdb, 0x66, 0x38, 0xb4, 0x48, 0x85, 0x38, 0xe1, 0x54, 0x6e, + 0x38, 0x47, 0xba, 0xb8, 0x38, 0x65, 0x8b, 0x85, 0x38, 0xaa, 0x65, 0x41, 0x38, + 0x33, 0x6d, 0x88, 0x38, 0xfc, 0xe2, 0x72, 0x38, 0x92, 0x90, 0xae, 0x38, 0x60, + 0x60, 0x9e, 0x38, 0x9a, 0xa0, 0x77, 0x38, 0x67, 0x07, 0x78, 0x38, 0x6a, 0x34, + 0x83, 0x38, 0xba, 0xe1, 0x6b, 0x38, 0x1d, 0x9b, 0x78, 0x38, 0xd7, 0x8f, 0x8b, + 0x38, 0x0f, 0xc0, 0x8a, 0x38, 0xbb, 0xcc, 0x85, 0x38, 0x85, 0xf7, 0x50, 0x38, + 0x48, 0xc2, 0x8c, 0x38, 0x4a, 0x58, 0x56, 0x38, 0x73, 0x66, 0x5a, 0x38, 0x6d, + 0x58, 0x63, 0x38, 0x49, 0x9b, 0x6a, 0x38, 0xd9, 0x6a, 0x5b, 0x38, 0x61, 0xbc, + 0x58, 0x38, 0xe4, 0x43, 0x55, 0x38, 0x4c, 0x13, 0x9a, 0x38, 0xe5, 0xe5, 0x94, + 0x38, 0x92, 0xf8, 0x3a, 0x38, 0xa9, 0x4e, 0x66, 0x38, 0x46, 0xdf, 0x69, 0x38, + 0xc3, 0xbc, 0x92, 0x38, 0xee, 0xc7, 0x84, 0x38, 0x63, 0x4c, 0x9c, 0x38, 0xfc, + 0x62, 0x60, 0x38, 0xfb, 0x60, 0x85, 0x38, 0xeb, 0x7f, 0x7b, 0x38, 0xb0, 0xbc, + 0xa1, 0x38, 0x0d, 0x46, 0x8c, 0x38, 0xc8, 0xf9, 0x88, 0x38, 0x81, 0x37, 0x81, + 0x38, 0xf2, 0x93, 0x95, 0x38, 0x38, 0xc8, 0x98, 0x38, 0x1f, 0x9a, 0x9b, 0x38, + 0xfb, 0x1e, 0x80, 0x38, 0xce, 0x84, 0x81, 0x38, 0x1d, 0x96, 0x7d, 0x38, 0xbb, + 0x15, 0xb2, 0x38, 0x39, 0x9f, 0x84, 0x38, 0xeb, 0xbe, 0x7a, 0x38, 0xc4, 0x6f, + 0x87, 0x38, 0x37, 0x62, 0x93, 0x38, 0xc1, 0x53, 0x99, 0x38, 0xa2, 0xe3, 0x3f, + 0x38, 0x67, 0xdf, 0x43, 0x38, 0x7f, 0xd2, 0x64, 0x38, 0x7c, 0x06, 0x7f, 0x38, + 0x0c, 0xe0, 0x6c, 0x38, 0x30, 0x77, 0x90, 0x38, 0x49, 0xd7, 0x57, 0x38, 0x65, + 0x1d, 0x7a, 0x38, 0x36, 0x38, 0xb0, 0x38, 0xb9, 0x08, 0x86, 0x38, 0x9d, 0x25, + 0x47, 0x38, 0xd6, 0x87, 0x69, 0x38, 0x73, 0x64, 0xce, 0x38, 0x14, 0xae, 0x5b, + 0x38, 0x65, 0xe5, 0x99, 0x38, 0xb0, 0xec, 0x5e, 0x38, 0xf2, 0x88, 0x9f, 0x38, + 0x3c, 0x3b, 0x8a, 0x38, 0xd1, 0xf0, 0x82, 0x38, 0x3e, 0xe0, 0x7b, 0x38, 0xc9, + 0xd2, 0x6f, 0x38, 0xa4, 0x9f, 0x95, 0x38, 0x0e, 0x3b, 0x5b, 0x38, 0x15, 0x3c, + 0x6d, 0x38, 0xd3, 0xed, 0x5a, 0x38, 0xa0, 0x9e, 0x96, 0x38, 0x49, 0x50, 0xcc, + 0x38, 0x1e, 0xe4, 0x48, 0x38, 0xda, 0x56, 0x3a, 0x38, 0x41, 0x0d, 0x57, 0x38, + 0xc9, 0x68, 0xc0, 0x38, 0x86, 0x69, 0x4a, 0x38, 0x97, 0x84, 0x6f, 0x38, 0xb3, + 0x7c, 0x9d, 0x38, 0x24, 0x1c, 0x6f, 0x38, 0x62, 0xb0, 0x8e, 0x38, 0x61, 0xaf, + 0x72, 0x38, 0x03, 0x03, 0x83, 0x38, 0xf3, 0x9f, 0x5b, 0x38, 0x6f, 0xbe, 0x89, + 0x38, 0x82, 0x3b, 0x9c, 0x38, 0x9f, 0x52, 0x8a, 0x38, 0x36, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x37, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, + 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xa6, + 0xfc, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x00, 0x4e, 0x00, + 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf6, 0xfe, + 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xa1, 0x0c, 0xe5, 0x38, + 0xb5, 0x80, 0x28, 0x39, 0x9e, 0xce, 0x25, 0x39, 0xeb, 0xb3, 0x62, 0x39, 0x74, + 0x53, 0x38, 0x39, 0x9f, 0x2b, 0xb8, 0x38, 0xb9, 0x9e, 0x07, 0x39, 0xdb, 0x1c, + 0x63, 0x39, 0x9e, 0x9d, 0x0f, 0x39, 0xbd, 0x02, 0x0c, 0x39, 0xc0, 0xda, 0x50, + 0x39, 0x0c, 0x9f, 0x4e, 0x39, 0xfb, 0xe3, 0x85, 0x39, 0x9b, 0x35, 0xd1, 0x39, + 0xde, 0x77, 0x12, 0x39, 0x61, 0x64, 0x33, 0x39, 0xeb, 0xba, 0x62, 0x39, 0xa4, + 0x8c, 0x63, 0x39, 0x4c, 0xd0, 0x39, 0x39, 0xb5, 0x69, 0x9b, 0x39, 0xb9, 0x55, + 0x80, 0x39, 0x97, 0x96, 0x52, 0x39, 0xd6, 0x78, 0x74, 0x39, 0xa2, 0x2d, 0x09, + 0x39, 0x67, 0xac, 0xc4, 0x38, 0x1d, 0x5f, 0x21, 0x39, 0x02, 0x83, 0x13, 0x39, + 0xdb, 0x4b, 0x4a, 0x39, 0xcf, 0x1b, 0x20, 0x39, 0xb4, 0x50, 0x70, 0x39, 0xf7, + 0xd3, 0xe9, 0x38, 0xe2, 0x48, 0x15, 0x39, 0x93, 0x55, 0x04, 0x39, 0xfc, 0xb9, + 0x34, 0x39, 0xda, 0x08, 0x2d, 0x39, 0xb3, 0x09, 0x5f, 0x39, 0x25, 0x87, 0x07, + 0x39, 0x7c, 0x80, 0x37, 0x39, 0xfd, 0x85, 0x24, 0x39, 0x0b, 0x4b, 0x0d, 0x39, + 0xae, 0xfa, 0x17, 0x39, 0x80, 0x0e, 0x44, 0x39, 0xa4, 0x0e, 0x12, 0x39, 0xa1, + 0xb3, 0x12, 0x39, 0xd2, 0x44, 0x1c, 0x39, 0x15, 0x69, 0xd7, 0x38, 0x18, 0x08, + 0x25, 0x39, 0x73, 0x4a, 0x6f, 0x39, 0x70, 0xe3, 0x78, 0x39, 0xbe, 0x9e, 0x31, + 0x39, 0x1b, 0x13, 0x1b, 0x39, 0x3f, 0xf2, 0x41, 0x39, 0xc3, 0xb6, 0x1c, 0x39, + 0xfe, 0x9d, 0x13, 0x39, 0x61, 0x1b, 0x0d, 0x39, 0x23, 0x75, 0x06, 0x39, 0x7b, + 0xa1, 0x3c, 0x39, 0xde, 0x43, 0x7c, 0x39, 0xeb, 0x1b, 0x22, 0x39, 0x76, 0xff, + 0x30, 0x39, 0x24, 0x23, 0x53, 0x39, 0x8b, 0x71, 0x03, 0x39, 0x3b, 0x12, 0x84, + 0x39, 0x9b, 0x1d, 0x9a, 0x39, 0x1e, 0xe6, 0x02, 0x39, 0x2c, 0xbe, 0xdd, 0x38, + 0x55, 0xdd, 0x7b, 0x39, 0xc8, 0xdf, 0x05, 0x39, 0x61, 0x65, 0x25, 0x39, 0x23, + 0xbb, 0x43, 0x39, 0x18, 0x72, 0xe3, 0x38, 0x4d, 0x09, 0x6e, 0x39, 0x91, 0xf0, + 0x36, 0x39, 0x9b, 0x10, 0x1e, 0x39, 0x54, 0xa5, 0x8f, 0x39, 0x8c, 0x4f, 0xbb, + 0x39, 0xf5, 0xd3, 0x1a, 0x39, 0xe7, 0x86, 0xc7, 0x38, 0x0f, 0x4e, 0x11, 0x39, + 0xab, 0xce, 0x17, 0x39, 0xc4, 0xb5, 0x56, 0x39, 0x18, 0xfb, 0x76, 0x39, 0x06, + 0x4d, 0x46, 0x39, 0x1f, 0x49, 0x09, 0x39, 0xd0, 0x09, 0xf7, 0x38, 0xbc, 0x92, + 0x38, 0x39, 0x5c, 0x55, 0x63, 0x39, 0x49, 0xda, 0x43, 0x39, 0xf9, 0xcd, 0x0a, + 0x39, 0xfd, 0xf5, 0xc2, 0x39, 0x49, 0xd8, 0x45, 0x39, 0xf9, 0x91, 0x0d, 0x39, + 0x59, 0x18, 0x15, 0x39, 0xc5, 0x1a, 0x12, 0x39, 0xa6, 0xfe, 0x1d, 0x39, 0x1d, + 0x58, 0x35, 0x39, 0x24, 0x78, 0x42, 0x39, 0x59, 0x85, 0x63, 0x39, 0xd1, 0x0f, + 0x00, 0x39, 0xfa, 0x4c, 0x6a, 0x39, 0xf8, 0x36, 0x27, 0x39, 0x8e, 0xea, 0x21, + 0x39, 0x6e, 0xdc, 0x77, 0x39, 0x21, 0x26, 0xf4, 0x38, 0x3f, 0xff, 0x00, 0x39, + 0x2c, 0x94, 0x14, 0x39, 0x12, 0x2e, 0x36, 0x39, 0x00, 0xd5, 0xd7, 0x38, 0xbd, + 0xa6, 0x18, 0x39, 0xb5, 0xda, 0x5d, 0x39, 0xcd, 0x8e, 0x94, 0x39, 0x64, 0x41, + 0xa4, 0x39, 0xcf, 0x85, 0x10, 0x39, 0x15, 0x89, 0x8f, 0x39, 0x7a, 0x67, 0x1f, + 0x39, 0x30, 0x0c, 0x8e, 0x39, 0x2d, 0x18, 0x1b, 0x39, 0x5e, 0x4b, 0x6d, 0x39, + 0xda, 0x52, 0x25, 0x39, 0x27, 0x75, 0x70, 0x39, 0xea, 0x56, 0x39, 0x39, 0x05, + 0x83, 0xce, 0x38, 0x68, 0x65, 0xea, 0x38, 0x05, 0xd0, 0xe0, 0x38, 0xf6, 0xf8, + 0x67, 0x39, 0x3c, 0x43, 0x41, 0x39, 0xa0, 0x45, 0x4d, 0x39, 0xa9, 0x70, 0xda, + 0x38, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x37, 0x5f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x22, 0x03, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xbc, 0x89, 0xff, 0xff, 0x30, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x37, 0x5f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc2, + 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x31, 0x00, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5c, 0x8a, 0xff, + 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, + 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x36, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x62, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x06, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0xe4, 0x0a, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x30, 0x0b, 0xba, 0x38, + 0x07, 0xe6, 0x99, 0x38, 0x5b, 0xb2, 0x0d, 0x39, 0x9a, 0xf2, 0xbe, 0x38, 0x1f, + 0x1d, 0x99, 0x38, 0x8b, 0x74, 0xed, 0x38, 0xaf, 0x9e, 0x6d, 0x38, 0xcb, 0xd4, + 0x9e, 0x38, 0xde, 0xf6, 0xda, 0x38, 0x9a, 0xb8, 0xa7, 0x38, 0x2e, 0x44, 0x99, + 0x38, 0x6a, 0x0c, 0xd5, 0x38, 0x30, 0x65, 0x86, 0x38, 0xcb, 0xe2, 0x38, 0x38, + 0x20, 0xca, 0x7d, 0x38, 0xa1, 0x51, 0x8b, 0x38, 0x0e, 0xc5, 0x88, 0x38, 0x3e, + 0x33, 0x95, 0x38, 0xa2, 0x88, 0xbb, 0x38, 0xcf, 0xaf, 0x7e, 0x38, 0x6a, 0x0d, + 0xae, 0x38, 0xf3, 0x33, 0x86, 0x38, 0x67, 0xd4, 0xc5, 0x38, 0x0f, 0x0f, 0xcc, + 0x38, 0xa6, 0xfb, 0xd7, 0x38, 0x6e, 0xf4, 0x8e, 0x38, 0x61, 0x41, 0xa3, 0x38, + 0xf7, 0xbe, 0xb4, 0x38, 0xb1, 0xe2, 0x9b, 0x38, 0x70, 0x32, 0xca, 0x38, 0xe1, + 0xfb, 0xac, 0x38, 0xff, 0xc4, 0x93, 0x38, 0x49, 0x65, 0xb3, 0x38, 0x95, 0xae, + 0x8b, 0x38, 0x1e, 0x8a, 0x86, 0x38, 0xcf, 0x20, 0x83, 0x38, 0x64, 0x37, 0x9c, + 0x38, 0x8a, 0xb5, 0x35, 0x38, 0xe5, 0xbe, 0xa6, 0x38, 0x35, 0x13, 0xbe, 0x38, + 0x70, 0x9c, 0xc5, 0x38, 0xa9, 0xf2, 0xa6, 0x38, 0x45, 0x16, 0x95, 0x38, 0x29, + 0xe0, 0xaa, 0x38, 0x64, 0xfa, 0xc7, 0x38, 0xa3, 0x66, 0x49, 0x38, 0xe7, 0x2d, + 0xa4, 0x38, 0xd4, 0x74, 0xa8, 0x38, 0xb8, 0xb8, 0x63, 0x38, 0x26, 0x53, 0x72, + 0x38, 0x06, 0x28, 0xc2, 0x38, 0x06, 0xe0, 0xb0, 0x38, 0xa7, 0x1d, 0xa6, 0x38, + 0x05, 0x41, 0xaa, 0x38, 0xc2, 0x93, 0x95, 0x38, 0x38, 0xc1, 0x97, 0x38, 0xb0, + 0xa8, 0xb6, 0x38, 0x7a, 0x24, 0xa5, 0x38, 0xeb, 0xed, 0x83, 0x38, 0xd6, 0x54, + 0x48, 0x38, 0x6f, 0x32, 0x94, 0x38, 0x54, 0x98, 0x8a, 0x38, 0x88, 0x4d, 0x83, + 0x38, 0xb0, 0xe4, 0x96, 0x38, 0xf9, 0xf6, 0xa9, 0x38, 0xe1, 0x67, 0xa6, 0x38, + 0x06, 0x46, 0x78, 0x38, 0xed, 0xd5, 0xea, 0x38, 0x05, 0x1f, 0x94, 0x38, 0x91, + 0xe5, 0x91, 0x38, 0xf6, 0x2e, 0x98, 0x38, 0x94, 0x63, 0x5d, 0x38, 0xf9, 0x4f, + 0xa4, 0x38, 0x4b, 0x46, 0x9e, 0x38, 0x19, 0xcf, 0x98, 0x38, 0x3e, 0x3b, 0x4b, + 0x38, 0x38, 0xc9, 0x79, 0x38, 0x24, 0xbb, 0x88, 0x38, 0xda, 0x39, 0x87, 0x38, + 0xd0, 0xe6, 0x84, 0x38, 0x05, 0x05, 0xa9, 0x38, 0x1a, 0xae, 0x9d, 0x38, 0xc1, + 0x65, 0xbe, 0x38, 0xf1, 0xc2, 0x98, 0x38, 0x20, 0x08, 0x93, 0x38, 0x15, 0xb5, + 0x9c, 0x38, 0xba, 0x98, 0x63, 0x38, 0x98, 0xf0, 0x97, 0x38, 0x04, 0xe0, 0x90, + 0x38, 0xc7, 0x9e, 0x74, 0x38, 0xfe, 0x4c, 0xb7, 0x38, 0x50, 0xeb, 0x7f, 0x38, + 0x2a, 0xe3, 0xa6, 0x38, 0x14, 0xed, 0x73, 0x38, 0x62, 0x8f, 0xcd, 0x38, 0xee, + 0x19, 0x78, 0x38, 0x3a, 0xd7, 0x6c, 0x38, 0x61, 0x01, 0xbd, 0x38, 0x56, 0xda, + 0x97, 0x38, 0xd0, 0xa5, 0xa5, 0x38, 0x1b, 0xb8, 0xc4, 0x38, 0xbb, 0x0b, 0xcc, + 0x38, 0x9d, 0xe2, 0xa7, 0x38, 0xef, 0xaf, 0xb6, 0x38, 0x9e, 0x37, 0xae, 0x38, + 0x6a, 0x46, 0x72, 0x38, 0xfb, 0x4c, 0x88, 0x38, 0x7a, 0xea, 0x96, 0x38, 0x2e, + 0xf7, 0x98, 0x38, 0x08, 0x3a, 0xa5, 0x38, 0xe1, 0xdf, 0xb4, 0x38, 0xcf, 0x6f, + 0x4d, 0x38, 0x9b, 0xe7, 0x91, 0x38, 0xd6, 0x8a, 0x94, 0x38, 0x71, 0x6f, 0x88, + 0x38, 0xa5, 0x79, 0x9d, 0x38, 0xf7, 0xe3, 0xa4, 0x38, 0x3d, 0xe7, 0x6e, 0x38, + 0xea, 0xa0, 0x8c, 0x38, 0x66, 0x7f, 0x3d, 0x38, 0x0e, 0x6e, 0x93, 0x38, 0xd3, + 0x64, 0x6d, 0x38, 0xc9, 0xb9, 0x9b, 0x38, 0xde, 0x7c, 0xdc, 0x38, 0xc9, 0xa5, + 0xcf, 0x38, 0xc7, 0xca, 0x7d, 0x38, 0x79, 0x75, 0xa0, 0x38, 0x5e, 0xab, 0x95, + 0x38, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x36, 0x5f, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, + 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xd6, 0x0a, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, + 0x03, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x24, 0x03, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x32, 0x04, 0xff, 0xff, 0x14, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe4, 0xe1, 0xd9, 0x38, + 0x59, 0x7e, 0xcd, 0x38, 0x89, 0x65, 0xac, 0x38, 0x2d, 0x36, 0xbb, 0x38, 0xa1, + 0x1e, 0x8e, 0x38, 0xbb, 0x08, 0x92, 0x38, 0x77, 0xc7, 0xf3, 0x38, 0xb3, 0xfb, + 0xbc, 0x38, 0x7f, 0x6a, 0xba, 0x38, 0xff, 0xe1, 0x05, 0x39, 0x24, 0xf5, 0xb9, + 0x38, 0x71, 0xb3, 0xcb, 0x38, 0xbe, 0x56, 0xce, 0x38, 0x18, 0xb7, 0xc0, 0x38, + 0xd2, 0x9d, 0xbd, 0x38, 0x74, 0x16, 0x37, 0x39, 0x46, 0x11, 0xb2, 0x38, 0xbd, + 0x56, 0x6c, 0x39, 0xdb, 0x35, 0xb7, 0x38, 0xe8, 0x93, 0xd7, 0x38, 0x53, 0xc4, + 0xab, 0x38, 0xb6, 0xa6, 0xc4, 0x38, 0xb5, 0xd1, 0x09, 0x39, 0xdd, 0x60, 0xa5, + 0x38, 0x77, 0x4e, 0xed, 0x38, 0x35, 0x67, 0xb4, 0x38, 0x85, 0x14, 0xe0, 0x38, + 0x6b, 0x21, 0xc0, 0x38, 0xfd, 0x90, 0xbf, 0x38, 0xd6, 0x8b, 0xe1, 0x38, 0x76, + 0x9c, 0xaa, 0x38, 0x06, 0x37, 0xc2, 0x38, 0x18, 0x19, 0xac, 0x38, 0xbc, 0x40, + 0xb5, 0x38, 0x54, 0x25, 0x3a, 0x39, 0x03, 0xd8, 0x01, 0x39, 0x1a, 0xdc, 0xe0, + 0x38, 0xdb, 0x58, 0xe6, 0x38, 0x8f, 0xb3, 0x98, 0x38, 0xe6, 0xda, 0x9c, 0x38, + 0x80, 0xed, 0xb5, 0x38, 0x71, 0x6c, 0xfd, 0x38, 0x0f, 0xc1, 0xf6, 0x38, 0x20, + 0x63, 0xde, 0x38, 0x89, 0x1f, 0xab, 0x38, 0xc7, 0xcd, 0xdd, 0x38, 0x5c, 0xf0, + 0x9f, 0x38, 0x1a, 0x54, 0xe4, 0x38, 0x2d, 0x39, 0xba, 0x38, 0x20, 0x55, 0xd1, + 0x38, 0xcf, 0x66, 0x87, 0x38, 0xe1, 0xb7, 0xe6, 0x38, 0x9a, 0x6d, 0x1a, 0x39, + 0xfc, 0x97, 0x11, 0x39, 0x28, 0x62, 0xaf, 0x38, 0x0b, 0xcf, 0xc5, 0x38, 0x61, + 0xbc, 0x23, 0x39, 0x0c, 0x7b, 0xc5, 0x38, 0xfc, 0xfa, 0x94, 0x38, 0x39, 0x7c, + 0x96, 0x38, 0x2a, 0x7e, 0x8e, 0x38, 0x5e, 0x2d, 0xd6, 0x38, 0xa1, 0xd1, 0xcc, + 0x38, 0x43, 0x1a, 0x24, 0x39, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x36, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, + 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x52, + 0x0e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x2c, 0x00, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xec, 0x94, 0xff, + 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, + 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x36, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, + 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x8c, 0x95, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x35, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x92, 0x0f, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x02, 0x64, 0x03, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x16, 0xff, 0xff, 0x10, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xd3, 0x57, 0x81, 0x38, 0x47, + 0x8c, 0xbc, 0x38, 0x50, 0xdf, 0xd4, 0x38, 0xe8, 0xc0, 0xf7, 0x38, 0xa1, 0x2a, + 0xaa, 0x38, 0x11, 0x80, 0x8b, 0x38, 0xdc, 0xc8, 0xb0, 0x38, 0xbc, 0xd0, 0xa3, + 0x38, 0x79, 0xa4, 0xd5, 0x38, 0xb0, 0x8f, 0xc2, 0x38, 0x83, 0xa4, 0xbf, 0x38, + 0xf4, 0xa6, 0xa9, 0x38, 0x77, 0x21, 0xc2, 0x38, 0x2f, 0xca, 0x6f, 0x38, 0x06, + 0x11, 0xfe, 0x38, 0xe8, 0xd1, 0x57, 0x38, 0x97, 0xa2, 0xc2, 0x38, 0x6b, 0x93, + 0x59, 0x38, 0x7a, 0x86, 0x7d, 0x38, 0x15, 0xc0, 0xe4, 0x38, 0x70, 0xa8, 0xb4, + 0x38, 0x14, 0x02, 0xa1, 0x38, 0x58, 0x71, 0xb0, 0x38, 0xfd, 0x49, 0xb5, 0x38, + 0x91, 0x89, 0x81, 0x38, 0x3a, 0x10, 0x6c, 0x38, 0x68, 0x77, 0xea, 0x38, 0x45, + 0xdc, 0xa9, 0x38, 0x91, 0x2c, 0xd9, 0x38, 0x22, 0x65, 0xa5, 0x38, 0x4c, 0x00, + 0xc3, 0x38, 0x82, 0x95, 0xa6, 0x38, 0xdf, 0xb7, 0x91, 0x38, 0x4f, 0xb4, 0xa3, + 0x38, 0xcf, 0x1e, 0x9a, 0x38, 0x15, 0xe8, 0x8d, 0x38, 0xd5, 0xfc, 0xa2, 0x38, + 0x68, 0xb5, 0x62, 0x38, 0x51, 0x04, 0x82, 0x38, 0x4a, 0x25, 0xd2, 0x38, 0x8b, + 0xd1, 0xc4, 0x38, 0x02, 0x61, 0xb0, 0x38, 0x5f, 0x34, 0x8b, 0x38, 0xf3, 0xd3, + 0xb3, 0x38, 0x6d, 0x60, 0xb8, 0x38, 0x7f, 0xeb, 0xa8, 0x38, 0x85, 0x4d, 0x8d, + 0x38, 0x56, 0x3a, 0x6c, 0x38, 0x9d, 0xee, 0x94, 0x38, 0x9c, 0x0c, 0x3d, 0x38, + 0xc0, 0x96, 0xae, 0x38, 0x52, 0xab, 0xd5, 0x38, 0xe1, 0xa7, 0x18, 0x38, 0x47, + 0xfe, 0x55, 0x38, 0x36, 0xac, 0xb0, 0x38, 0xd8, 0xdf, 0xa3, 0x38, 0xc1, 0x94, + 0x9c, 0x38, 0x24, 0xd7, 0xb0, 0x38, 0x40, 0x4a, 0xad, 0x38, 0x0f, 0x31, 0xa7, + 0x38, 0x7c, 0xb9, 0xbf, 0x38, 0xd0, 0x06, 0xc6, 0x38, 0x53, 0x4e, 0x5f, 0x38, + 0x94, 0x25, 0x5d, 0x38, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x35, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x06, 0x13, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x02, 0x6c, 0x03, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x24, 0x03, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x62, 0x0c, 0xff, 0xff, 0x14, 0x02, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa7, + 0x20, 0xfc, 0x38, 0x89, 0x62, 0x69, 0x39, 0xfc, 0x00, 0x35, 0x39, 0xca, 0x7e, + 0x39, 0x39, 0x08, 0x4e, 0x66, 0x39, 0xf3, 0x61, 0xd8, 0x38, 0x94, 0xb7, 0x05, + 0x39, 0x40, 0x49, 0x97, 0x38, 0x31, 0xdd, 0x9c, 0x39, 0x72, 0x72, 0xb2, 0x39, + 0x74, 0xe6, 0xd4, 0x39, 0x53, 0x96, 0x64, 0x39, 0x38, 0xbe, 0x5f, 0x39, 0x6a, + 0x5f, 0xbe, 0x38, 0x01, 0x21, 0x21, 0x39, 0x8f, 0xf1, 0x40, 0x39, 0xa2, 0x39, + 0x0f, 0x39, 0xc1, 0x47, 0xe9, 0x38, 0x86, 0x92, 0x22, 0x39, 0x34, 0xfb, 0xec, + 0x38, 0xdf, 0x67, 0xe0, 0x38, 0x53, 0x3a, 0x11, 0x39, 0x1a, 0xf8, 0xd1, 0x39, + 0xb5, 0x00, 0x19, 0x39, 0x26, 0x8e, 0x05, 0x39, 0x43, 0x28, 0xac, 0x39, 0xdb, + 0xee, 0x8a, 0x39, 0x85, 0x31, 0xe1, 0x38, 0x0f, 0x1e, 0x11, 0x39, 0xe7, 0xea, + 0x2f, 0x39, 0x42, 0x73, 0x05, 0x39, 0xec, 0x15, 0x2f, 0x39, 0x12, 0x09, 0xd2, + 0x38, 0xd2, 0x2e, 0x09, 0x39, 0x1e, 0x05, 0x22, 0x39, 0xaa, 0x44, 0xaf, 0x38, + 0x02, 0xe1, 0x86, 0x39, 0x59, 0x42, 0x92, 0x39, 0xe4, 0x90, 0x09, 0x39, 0x3c, + 0xde, 0x04, 0x39, 0xaa, 0xf2, 0x32, 0x39, 0xc0, 0x84, 0x2a, 0x39, 0x1d, 0xd5, + 0x76, 0x39, 0x1a, 0x13, 0x24, 0x39, 0x4f, 0xbd, 0xbc, 0x38, 0xe0, 0x06, 0xa8, + 0x38, 0xd5, 0x4b, 0x8f, 0x39, 0xe1, 0xed, 0xc7, 0x38, 0xfd, 0xea, 0x80, 0x39, + 0x77, 0xf5, 0x5b, 0x39, 0x00, 0xa6, 0x37, 0x39, 0xf3, 0x36, 0x55, 0x39, 0x77, + 0x6e, 0xa1, 0x39, 0x2b, 0x10, 0x07, 0x39, 0xd0, 0xf0, 0xdb, 0x38, 0x62, 0xd5, + 0xff, 0x38, 0xcd, 0xfc, 0x53, 0x39, 0x5c, 0xc1, 0x16, 0x39, 0xd3, 0xbe, 0xe9, + 0x38, 0x77, 0xc2, 0xf2, 0x38, 0x71, 0x2a, 0x98, 0x39, 0xe4, 0x4e, 0xd0, 0x38, + 0x4b, 0x79, 0x0a, 0x39, 0x56, 0x9a, 0x8e, 0x39, 0x39, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x35, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x82, 0x16, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, + 0x00, 0x57, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1c, 0x9d, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x35, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x17, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x09, 0x84, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xbc, 0x9d, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x34, 0x5f, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xc2, 0x17, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x03, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x20, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x44, 0x1e, 0xff, 0xff, 0x10, + 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa9, 0xbb, + 0xd0, 0x38, 0x3a, 0x81, 0x84, 0x38, 0x12, 0x86, 0xf8, 0x38, 0xd8, 0xe1, 0xd0, + 0x38, 0xb4, 0x0a, 0xa1, 0x38, 0x93, 0x51, 0xb6, 0x38, 0x65, 0xd7, 0xf0, 0x38, + 0x98, 0x9a, 0xc6, 0x38, 0xbf, 0x4e, 0x88, 0x38, 0xc6, 0xa5, 0xd3, 0x38, 0x59, + 0xc6, 0x60, 0x38, 0xd2, 0xdc, 0xf0, 0x38, 0x70, 0x7e, 0x87, 0x38, 0xa3, 0xd3, + 0xcf, 0x38, 0x54, 0xfb, 0x02, 0x39, 0xdb, 0x90, 0x45, 0x39, 0x8b, 0x00, 0xcc, + 0x38, 0x3b, 0xd8, 0xc4, 0x38, 0x73, 0xed, 0xd3, 0x38, 0xcb, 0xb7, 0x8d, 0x38, + 0x3e, 0xc5, 0x2d, 0x39, 0xe9, 0xaf, 0x9f, 0x38, 0x61, 0x00, 0xa6, 0x38, 0xa9, + 0xf7, 0x12, 0x39, 0x70, 0x6d, 0x0c, 0x39, 0x18, 0x81, 0x2a, 0x38, 0x9d, 0x17, + 0x83, 0x38, 0x0b, 0x0d, 0x22, 0x39, 0x83, 0x52, 0x07, 0x39, 0x26, 0x7c, 0xc5, + 0x38, 0xb5, 0x04, 0xd0, 0x38, 0x42, 0xcc, 0x12, 0x39, 0x01, 0x47, 0x00, 0x39, + 0x5e, 0x12, 0x74, 0x38, 0x62, 0x92, 0xb3, 0x38, 0x20, 0xfd, 0x27, 0x39, 0xd0, + 0x51, 0x6e, 0x38, 0x79, 0x0f, 0x77, 0x38, 0x3e, 0x76, 0xb4, 0x38, 0x32, 0x98, + 0x88, 0x38, 0x30, 0x5d, 0xa8, 0x38, 0x11, 0x95, 0xd5, 0x38, 0xb0, 0x91, 0x9f, + 0x38, 0xad, 0x1f, 0xd7, 0x38, 0xec, 0x9d, 0x1b, 0x39, 0xcb, 0x15, 0x1d, 0x39, + 0x27, 0x48, 0x4a, 0x38, 0x09, 0xb3, 0xb5, 0x38, 0x98, 0x7f, 0x02, 0x39, 0x47, + 0x95, 0x53, 0x39, 0xf1, 0x99, 0x47, 0x39, 0x73, 0x76, 0xd8, 0x38, 0x71, 0x7a, + 0xd5, 0x38, 0x67, 0x79, 0x4e, 0x39, 0x42, 0xf0, 0x01, 0x39, 0x59, 0xbe, 0xe5, + 0x38, 0x0a, 0xec, 0x9f, 0x38, 0x87, 0x6a, 0x20, 0x39, 0x6a, 0x06, 0xdc, 0x38, + 0x40, 0x5d, 0xfa, 0x38, 0x95, 0x1d, 0x92, 0x38, 0xd3, 0xcd, 0x3e, 0x39, 0xa1, + 0x43, 0x0d, 0x39, 0x6b, 0x23, 0x97, 0x38, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, + 0x32, 0x64, 0x5f, 0x34, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, + 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x36, 0x1b, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x02, 0xec, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x92, 0x14, 0xff, 0xff, 0x14, + 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xc5, 0xba, 0x8c, 0x38, 0x92, 0x4d, 0xa9, + 0x38, 0x52, 0x02, 0x82, 0x38, 0xfc, 0xa9, 0xaf, 0x38, 0xff, 0x9a, 0x46, 0x39, + 0x14, 0xa1, 0xcb, 0x38, 0x60, 0xad, 0x95, 0x38, 0xb6, 0xdd, 0x96, 0x38, 0x69, + 0x54, 0x96, 0x38, 0xca, 0x22, 0x68, 0x38, 0x68, 0x2c, 0xac, 0x38, 0xe7, 0x85, + 0x95, 0x38, 0x41, 0x03, 0xd5, 0x38, 0xd5, 0x13, 0x28, 0x39, 0xa9, 0xae, 0xde, + 0x38, 0x26, 0x06, 0xa4, 0x38, 0xa7, 0x7b, 0x9a, 0x38, 0x0e, 0x89, 0x8f, 0x38, + 0x4c, 0x4a, 0xf2, 0x38, 0x6d, 0x8f, 0x9d, 0x38, 0x03, 0xb2, 0xef, 0x38, 0x3e, + 0x97, 0xd8, 0x38, 0x80, 0xfe, 0x4b, 0x38, 0xed, 0x28, 0xad, 0x38, 0x04, 0xbb, + 0x2a, 0x39, 0x49, 0x6b, 0xbb, 0x38, 0x82, 0x54, 0xa2, 0x38, 0xbd, 0xee, 0x90, + 0x38, 0x46, 0xb5, 0xea, 0x38, 0xd2, 0x63, 0xa7, 0x38, 0x11, 0x03, 0xda, 0x38, + 0x48, 0x20, 0x22, 0x39, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x34, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x1d, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xcc, 0xa3, 0xff, 0xff, + 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, + 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x34, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, + 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0xd2, 0x1d, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6c, 0xa4, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x33, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x72, 0x1e, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x02, 0xe4, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xf4, 0x24, 0xff, 0xff, 0x10, 0x01, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3e, 0x8f, + 0xd5, 0x38, 0xe1, 0xa8, 0x15, 0x39, 0x06, 0x19, 0xf5, 0x38, 0x79, 0x80, 0xc5, + 0x38, 0x35, 0x5e, 0x4f, 0x38, 0x3f, 0x44, 0x8d, 0x38, 0x0a, 0xa0, 0xb7, 0x38, + 0xb2, 0xf2, 0xa7, 0x38, 0x34, 0xb7, 0xf3, 0x38, 0xb4, 0xd4, 0xb8, 0x38, 0x08, + 0x3d, 0x0e, 0x39, 0xea, 0xad, 0xa8, 0x38, 0x47, 0xf9, 0x00, 0x39, 0xbf, 0x4e, + 0x04, 0x39, 0xdb, 0x31, 0xa0, 0x38, 0xed, 0x1d, 0xbd, 0x38, 0x41, 0x75, 0xc6, + 0x38, 0x76, 0x6a, 0xe9, 0x38, 0xe5, 0x13, 0x0f, 0x39, 0x14, 0xa9, 0xed, 0x38, + 0xd2, 0x34, 0x26, 0x39, 0xc4, 0x70, 0xc7, 0x38, 0x27, 0xd1, 0xb3, 0x38, 0xb7, + 0x3f, 0xfd, 0x38, 0x58, 0x20, 0x1e, 0x39, 0xd6, 0xeb, 0x47, 0x39, 0x15, 0x4c, + 0x22, 0x39, 0xa1, 0xd0, 0x04, 0x39, 0xa2, 0x9e, 0x8c, 0x38, 0x2c, 0x4b, 0xbe, + 0x38, 0xd9, 0xb7, 0xe5, 0x38, 0x2a, 0xdd, 0xbf, 0x38, 0x36, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x33, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, + 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x66, + 0x20, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xec, 0x01, 0x00, 0x00, 0x22, 0x00, + 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc2, 0x19, 0xff, + 0xff, 0x14, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xe1, 0x95, 0x47, 0x39, 0x5c, + 0xa6, 0x6d, 0x39, 0x76, 0xe7, 0x2c, 0x39, 0x44, 0x2e, 0x74, 0x39, 0x27, 0x35, + 0x9d, 0x39, 0x0c, 0xe8, 0x14, 0x3a, 0x59, 0x1e, 0xd8, 0x38, 0x9b, 0xf8, 0x30, + 0x39, 0xfc, 0xec, 0x33, 0x39, 0xcd, 0x64, 0xd1, 0x39, 0x39, 0xe6, 0x05, 0x3a, + 0x72, 0xd9, 0x25, 0x39, 0x42, 0xa7, 0x87, 0x38, 0xd6, 0xfc, 0xa1, 0x39, 0xe1, + 0x80, 0x50, 0x39, 0xe2, 0x17, 0x4b, 0x38, 0x07, 0xb7, 0x2c, 0x39, 0xa1, 0x48, + 0xd2, 0x38, 0x3d, 0xfc, 0x06, 0x3a, 0xae, 0x9c, 0x16, 0x3a, 0x53, 0xec, 0x07, + 0x39, 0x9c, 0xa6, 0x10, 0x3a, 0x59, 0x92, 0x9c, 0x38, 0xd0, 0xc6, 0x1f, 0x39, + 0x61, 0x0a, 0x16, 0x39, 0xb9, 0x19, 0x35, 0x3a, 0x4d, 0x18, 0x3b, 0x39, 0x21, + 0x5f, 0x9e, 0x38, 0x70, 0x69, 0xfb, 0x38, 0x85, 0x13, 0x29, 0x39, 0xca, 0x56, + 0x1f, 0x39, 0x98, 0x9d, 0x8a, 0x39, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x33, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, + 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, + 0x61, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x62, 0x22, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xfc, 0xa8, + 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, + 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x33, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, + 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x02, 0x23, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x9c, 0xa9, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x32, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xa2, 0x23, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x02, 0xe4, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xa0, 0x01, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x24, 0x2a, 0xff, 0xff, 0x10, 0x01, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0xa9, 0x23, 0x8e, 0x39, 0xb2, 0x18, 0xc6, 0x38, 0x94, 0x74, 0x1a, 0x39, 0x67, + 0xb0, 0x1d, 0x39, 0xcd, 0x82, 0xf5, 0x38, 0xb3, 0x69, 0x1d, 0x38, 0x67, 0xcc, + 0x03, 0x39, 0x74, 0xc8, 0x29, 0x39, 0xaf, 0x8a, 0xb9, 0x38, 0x18, 0x9b, 0xa7, + 0x38, 0xb5, 0x00, 0x2d, 0x38, 0x4f, 0x24, 0xfe, 0x38, 0xce, 0xc8, 0x1c, 0x39, + 0xe2, 0x95, 0xfb, 0x38, 0xc4, 0x61, 0x72, 0x39, 0x18, 0x6d, 0x8d, 0x39, 0x57, + 0x16, 0x24, 0x39, 0x92, 0xe1, 0x3c, 0x39, 0x03, 0x6a, 0x5a, 0x38, 0x21, 0x2c, + 0x9b, 0x38, 0xa9, 0x0d, 0x05, 0x39, 0xd1, 0x14, 0x3f, 0x38, 0x2a, 0xa9, 0x11, + 0x39, 0xf1, 0xe3, 0x25, 0x39, 0xd4, 0x0c, 0x05, 0x39, 0x8c, 0x1e, 0xdc, 0x37, + 0xfa, 0xf1, 0x07, 0x39, 0x33, 0x53, 0x34, 0x39, 0x97, 0x2f, 0x6a, 0x39, 0xd0, + 0x60, 0xe8, 0x38, 0x00, 0x42, 0x4d, 0x39, 0xf1, 0xd0, 0xb5, 0x38, 0x36, 0x00, + 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x32, 0x5f, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, + 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x96, 0x25, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x2c, 0x01, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf2, + 0x1e, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x27, + 0xf0, 0xac, 0x38, 0x4d, 0xb4, 0x95, 0x38, 0x20, 0x35, 0xf3, 0x38, 0xed, 0x7a, + 0xc5, 0x38, 0x08, 0x25, 0x10, 0x39, 0xff, 0xdf, 0xec, 0x38, 0x1b, 0x9b, 0xf9, + 0x38, 0xce, 0x25, 0x84, 0x38, 0x67, 0xff, 0xf7, 0x38, 0xf1, 0x99, 0x5b, 0x39, + 0x59, 0xbf, 0x93, 0x38, 0x9e, 0x8e, 0xf4, 0x38, 0xf9, 0x05, 0xb2, 0x38, 0xa0, + 0x01, 0xad, 0x38, 0x04, 0x3f, 0x24, 0x39, 0xef, 0x8a, 0x32, 0x39, 0x39, 0x00, + 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x32, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xd2, 0x26, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x84, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x6c, 0xad, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x32, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x72, 0x27, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x44, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0xae, 0xff, 0xff, 0x30, 0x00, + 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x5f, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, + 0x75, 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x12, 0x28, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x24, 0x01, 0x00, 0x00, 0x24, + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x94, 0x2e, + 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x58, 0x91, 0xaa, 0x39, 0x89, 0x15, + 0x5a, 0x39, 0x0c, 0xe3, 0xcb, 0x39, 0x37, 0x66, 0x33, 0x39, 0xb6, 0xee, 0x95, + 0x39, 0x82, 0xd1, 0x97, 0x39, 0xc1, 0x33, 0x41, 0x39, 0x27, 0x74, 0x53, 0x39, + 0xfc, 0x35, 0xb0, 0x39, 0x97, 0x5a, 0x4c, 0x39, 0x7b, 0xb4, 0x9e, 0x39, 0x95, + 0xda, 0x45, 0x39, 0xfc, 0x96, 0x95, 0x39, 0x36, 0x8b, 0x2b, 0x39, 0x2f, 0x32, + 0x48, 0x39, 0x51, 0x8f, 0x86, 0x39, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x31, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x29, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa2, 0x22, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfa, 0x50, 0xd3, 0x38, 0x62, + 0x8a, 0x18, 0x39, 0x74, 0x24, 0x61, 0x3b, 0x22, 0x48, 0x8f, 0x38, 0xec, 0xd9, + 0xb4, 0x39, 0x0a, 0xb5, 0x82, 0x38, 0x1c, 0xef, 0x35, 0x39, 0xd6, 0x72, 0xf6, + 0x3b, 0x39, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x5f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0x2a, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xbc, 0xb0, 0xff, 0xff, 0x30, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x5f, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xc2, + 0x2a, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5c, 0xb1, 0xff, + 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x72, + 0x98, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x25, 0xda, 0x97, 0x40, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x31, 0x33, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x62, 0x2b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x0c, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0xe4, 0x31, 0xff, 0xff, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1f, 0x37, 0xa6, 0x37, 0xa1, 0xb4, 0x00, + 0x38, 0x98, 0x9f, 0xe0, 0x37, 0x43, 0x01, 0x4f, 0x37, 0x0f, 0xa8, 0xe7, 0x37, + 0x6d, 0x06, 0x84, 0x37, 0x96, 0x2b, 0x92, 0x37, 0x4d, 0xf5, 0xe0, 0x37, 0x9e, + 0xa2, 0xa7, 0x37, 0xa0, 0x06, 0xcc, 0x37, 0xe4, 0x70, 0xa6, 0x37, 0x4d, 0x9c, + 0x85, 0x37, 0xbd, 0x71, 0xd4, 0x37, 0xfe, 0x3d, 0x8b, 0x37, 0xd5, 0xe9, 0x87, + 0x37, 0x0a, 0x83, 0xa1, 0x37, 0xae, 0x42, 0xae, 0x37, 0xc5, 0xda, 0x82, 0x37, + 0xad, 0xbd, 0x6b, 0x37, 0xa5, 0x09, 0xbe, 0x37, 0xb8, 0xf0, 0x5c, 0x37, 0x78, + 0xb8, 0x95, 0x37, 0x6a, 0xbe, 0xc1, 0x37, 0xc7, 0xbc, 0x96, 0x37, 0x14, 0xb4, + 0xe4, 0x37, 0xf2, 0x48, 0x92, 0x37, 0x46, 0xc4, 0x06, 0x38, 0x59, 0x42, 0xc5, + 0x37, 0x7c, 0x19, 0x66, 0x37, 0x30, 0xe4, 0x8a, 0x37, 0x5b, 0x24, 0xa4, 0x37, + 0x78, 0x26, 0xba, 0x37, 0xca, 0xbf, 0xd9, 0x37, 0xf5, 0xb8, 0x9c, 0x37, 0xee, + 0xa0, 0x96, 0x37, 0xb5, 0xa5, 0x8f, 0x37, 0x58, 0xa9, 0x9e, 0x37, 0xc0, 0x9e, + 0x79, 0x37, 0x56, 0xde, 0xac, 0x37, 0x89, 0xa8, 0x94, 0x37, 0xcc, 0xeb, 0xc6, + 0x37, 0xd2, 0x26, 0xa3, 0x37, 0x3b, 0x10, 0xc7, 0x37, 0x7c, 0x49, 0xba, 0x37, + 0xbb, 0x07, 0x5a, 0x37, 0xe4, 0x03, 0x6f, 0x37, 0xee, 0x71, 0x93, 0x37, 0x74, + 0x4a, 0x89, 0x37, 0x3d, 0x2f, 0xd1, 0x37, 0x38, 0x2e, 0xca, 0x37, 0xa3, 0x44, + 0xa3, 0x37, 0x4d, 0xbe, 0x6d, 0x37, 0x27, 0x53, 0x88, 0x37, 0x87, 0x38, 0x1c, + 0x38, 0x53, 0x4c, 0x8e, 0x37, 0x3f, 0x6a, 0xbe, 0x37, 0x6a, 0x06, 0xc9, 0x37, + 0xf6, 0xa8, 0x96, 0x37, 0x07, 0x79, 0x87, 0x37, 0xa5, 0x0f, 0xa6, 0x37, 0xc0, + 0x65, 0xa6, 0x37, 0x4d, 0xf4, 0x9a, 0x37, 0xa1, 0x4f, 0xc2, 0x37, 0x49, 0xa7, + 0x8f, 0x37, 0x46, 0x94, 0x68, 0x37, 0xd8, 0x90, 0xa0, 0x37, 0x00, 0x2c, 0x76, + 0x37, 0xe0, 0xdc, 0x92, 0x37, 0x02, 0x50, 0x92, 0x37, 0xb5, 0x1f, 0xab, 0x37, + 0x77, 0x9c, 0xae, 0x37, 0x4f, 0x20, 0x8f, 0x37, 0x30, 0xd6, 0x43, 0x37, 0xbc, + 0xb3, 0x9f, 0x37, 0x08, 0x44, 0x7e, 0x37, 0x8b, 0x1a, 0x79, 0x37, 0x2f, 0xb3, + 0xf9, 0x37, 0x19, 0x9a, 0xa3, 0x37, 0x64, 0xa1, 0x87, 0x37, 0x39, 0xb2, 0x4f, + 0x37, 0x24, 0x04, 0x19, 0x38, 0x06, 0x87, 0x81, 0x37, 0x8b, 0xfb, 0x4f, 0x37, + 0xbc, 0x34, 0x93, 0x37, 0xff, 0x66, 0xd9, 0x37, 0xfc, 0x08, 0x66, 0x37, 0x44, + 0xf8, 0x87, 0x37, 0xfd, 0xf8, 0xec, 0x37, 0x74, 0x22, 0x93, 0x37, 0x8b, 0x02, + 0x99, 0x37, 0x05, 0x49, 0xc1, 0x37, 0x7d, 0x68, 0x7d, 0x37, 0x7e, 0x66, 0x99, + 0x37, 0xff, 0xdd, 0xa3, 0x37, 0xc7, 0x00, 0x5b, 0x37, 0x1b, 0x9c, 0xe9, 0x37, + 0xbe, 0x3f, 0xc6, 0x37, 0x12, 0x48, 0xad, 0x37, 0x61, 0x61, 0xe4, 0x37, 0x61, + 0xd1, 0x81, 0x37, 0x4f, 0xd5, 0x80, 0x37, 0x5b, 0x9b, 0x7c, 0x37, 0xc3, 0x4c, + 0x7c, 0x37, 0xad, 0xdd, 0xa6, 0x37, 0x0f, 0x98, 0xcf, 0x37, 0x6f, 0xb3, 0x83, + 0x37, 0xff, 0xdd, 0x7e, 0x37, 0x8f, 0x15, 0x7e, 0x37, 0x39, 0xbb, 0xb7, 0x37, + 0xc2, 0xa7, 0xa1, 0x37, 0x33, 0xa7, 0xc9, 0x37, 0x5e, 0x0a, 0x7d, 0x37, 0xb5, + 0x3e, 0x45, 0x37, 0xbb, 0x10, 0xe8, 0x37, 0xc9, 0xc0, 0x86, 0x37, 0xb3, 0x01, + 0xc6, 0x37, 0x1a, 0xfe, 0xd6, 0x37, 0x12, 0x88, 0x8b, 0x37, 0x5b, 0x0c, 0xf5, + 0x37, 0xeb, 0x77, 0x7b, 0x37, 0xb1, 0x5b, 0xa6, 0x37, 0x80, 0xb2, 0x6e, 0x37, + 0x2c, 0x7e, 0x78, 0x37, 0xea, 0xc5, 0xa0, 0x37, 0x8c, 0xee, 0xa6, 0x37, 0xf1, + 0x74, 0x7a, 0x37, 0x47, 0xd0, 0x72, 0x37, 0x7a, 0xca, 0xb8, 0x37, 0x4f, 0x17, + 0xb1, 0x37, 0xe8, 0xee, 0xe9, 0x37, 0x0c, 0xb2, 0xf3, 0x37, 0x43, 0xcd, 0xbe, + 0x37, 0x4e, 0xe2, 0xa2, 0x37, 0xcc, 0x69, 0x77, 0x37, 0x63, 0xbf, 0xae, 0x37, + 0xcf, 0xf5, 0x49, 0x37, 0x15, 0x5a, 0xbd, 0x37, 0x87, 0xe5, 0xb5, 0x37, 0x0e, + 0x9c, 0x78, 0x37, 0x58, 0x6c, 0x92, 0x37, 0x82, 0xbe, 0xb3, 0x37, 0xbe, 0xbd, + 0x92, 0x37, 0xd5, 0xe0, 0x97, 0x37, 0xcb, 0xee, 0xa7, 0x37, 0x6e, 0xab, 0xa0, + 0x37, 0x21, 0x07, 0x9d, 0x37, 0xa1, 0x64, 0xac, 0x37, 0x56, 0xbc, 0xa9, 0x37, + 0xb5, 0x8d, 0xb8, 0x37, 0xed, 0x81, 0x87, 0x37, 0x95, 0xbf, 0xaa, 0x37, 0xc1, + 0xd9, 0x93, 0x37, 0xaa, 0x1d, 0x79, 0x37, 0x89, 0xa7, 0x66, 0x37, 0x52, 0x2f, + 0xb7, 0x37, 0x72, 0xb9, 0xa3, 0x37, 0x1d, 0xa3, 0x91, 0x37, 0xe2, 0x52, 0xef, + 0x37, 0xb0, 0x2b, 0x95, 0x37, 0xed, 0x68, 0x97, 0x37, 0x15, 0xd7, 0x76, 0x37, + 0x53, 0xba, 0x95, 0x37, 0x24, 0x50, 0x0a, 0x38, 0xbd, 0xc8, 0x9b, 0x37, 0xcd, + 0x2e, 0x92, 0x37, 0x41, 0x93, 0x8c, 0x37, 0x7d, 0xa0, 0x6e, 0x37, 0x05, 0x97, + 0x97, 0x37, 0x11, 0xc1, 0x5d, 0x37, 0x40, 0x3d, 0xf4, 0x37, 0x88, 0x74, 0x9c, + 0x37, 0x6d, 0x48, 0x6e, 0x37, 0xf1, 0x0a, 0xd1, 0x37, 0x6b, 0x91, 0x87, 0x37, + 0x1d, 0x90, 0x96, 0x37, 0x8a, 0x5c, 0x97, 0x37, 0xcd, 0x78, 0x4c, 0x38, 0xb6, + 0xc4, 0x18, 0x38, 0xe7, 0xee, 0xaa, 0x37, 0x76, 0xff, 0x9c, 0x37, 0x3e, 0xe5, + 0x75, 0x37, 0x5e, 0x91, 0x8d, 0x37, 0xe8, 0x93, 0x94, 0x37, 0x67, 0xa9, 0xa1, + 0x37, 0x38, 0x67, 0xbc, 0x37, 0x0f, 0x70, 0xae, 0x37, 0x56, 0xb9, 0xe5, 0x37, + 0xb9, 0x85, 0x8f, 0x37, 0x9e, 0xfe, 0x89, 0x37, 0xeb, 0x2d, 0x98, 0x37, 0xad, + 0x33, 0x9e, 0x37, 0x15, 0x54, 0xbd, 0x37, 0xac, 0x25, 0x78, 0x37, 0xa2, 0x99, + 0xa2, 0x37, 0x0f, 0x39, 0xb8, 0x37, 0x1d, 0x29, 0x70, 0x37, 0x49, 0x30, 0x88, + 0x37, 0x29, 0x56, 0xc4, 0x37, 0x5c, 0xc7, 0x73, 0x37, 0x5a, 0x86, 0x28, 0x37, + 0xb9, 0x1a, 0x89, 0x37, 0x19, 0x6d, 0x34, 0x37, 0x86, 0xf1, 0xb0, 0x37, 0xc2, + 0xbb, 0xb5, 0x37, 0xb9, 0xcc, 0x9e, 0x37, 0x53, 0xfc, 0xc1, 0x37, 0x15, 0x65, + 0xd7, 0x37, 0x36, 0x53, 0x84, 0x37, 0x11, 0x3c, 0x5f, 0x37, 0x21, 0xdf, 0xad, + 0x37, 0xaa, 0xa4, 0xb3, 0x37, 0xf0, 0x1d, 0xc0, 0x37, 0x89, 0x4d, 0x9d, 0x37, + 0x0b, 0x3f, 0x90, 0x37, 0xc7, 0x60, 0x0d, 0x38, 0x17, 0xd5, 0x62, 0x37, 0x79, + 0xf9, 0x64, 0x37, 0x05, 0xa7, 0x9d, 0x37, 0xa4, 0x54, 0xb6, 0x37, 0xd5, 0xd7, + 0x9a, 0x37, 0x6d, 0x6c, 0xa5, 0x37, 0xbc, 0x04, 0x84, 0x37, 0x26, 0xd0, 0xc6, + 0x37, 0x27, 0x4f, 0xd9, 0x37, 0xe4, 0x88, 0x97, 0x37, 0xa0, 0xb0, 0x90, 0x37, + 0xd0, 0x8a, 0x70, 0x37, 0x37, 0x89, 0x65, 0x37, 0xd0, 0xed, 0x84, 0x37, 0x51, + 0x5b, 0x81, 0x37, 0xa1, 0xcb, 0xcf, 0x37, 0x50, 0x99, 0x89, 0x37, 0x06, 0x12, + 0x98, 0x37, 0xb9, 0x3c, 0x46, 0x37, 0x79, 0x62, 0xc0, 0x37, 0x77, 0x44, 0xfd, + 0x37, 0xe2, 0x7a, 0xc5, 0x37, 0xcd, 0xd7, 0x74, 0x37, 0xfe, 0x0e, 0x80, 0x37, + 0xc2, 0x16, 0xbe, 0x37, 0xd8, 0x0f, 0x0f, 0x38, 0x06, 0x17, 0xd0, 0x37, 0x17, + 0xb5, 0x7e, 0x37, 0xda, 0x09, 0x0d, 0x38, 0x12, 0xbe, 0x6c, 0x37, 0xae, 0x7e, + 0xfe, 0x37, 0xc7, 0xb0, 0xe0, 0x37, 0x2b, 0xdd, 0xaf, 0x37, 0x8a, 0xa2, 0x86, + 0x37, 0x71, 0x66, 0x13, 0x38, 0x3e, 0x15, 0x8b, 0x37, 0xd1, 0x60, 0xa3, 0x37, + 0xd0, 0xe7, 0xf9, 0x37, 0xf3, 0xcf, 0xcb, 0x37, 0xc5, 0x4b, 0xa0, 0x37, 0x35, + 0xae, 0xcb, 0x37, 0x37, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, + 0x33, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xd6, 0x37, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x02, 0x6c, 0x0c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x32, 0x31, 0xff, 0xff, 0x14, 0x08, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0xb0, 0xe5, 0x90, 0x39, 0xc1, 0x92, 0x2e, 0x39, 0x18, 0xad, 0xa1, 0x39, 0x8b, + 0xcb, 0x3b, 0x39, 0x27, 0xd9, 0x0f, 0x39, 0xb2, 0x7b, 0x51, 0x39, 0x41, 0xb1, + 0x05, 0x39, 0x4f, 0x04, 0x77, 0x39, 0xf3, 0x6c, 0x0f, 0x39, 0x3d, 0xfc, 0x77, + 0x39, 0x70, 0x73, 0x25, 0x39, 0x99, 0xd2, 0x12, 0x39, 0x26, 0xc1, 0x33, 0x39, + 0x8f, 0x0b, 0x33, 0x39, 0xae, 0xe1, 0x81, 0x39, 0xe4, 0xf5, 0x62, 0x39, 0x63, + 0x50, 0x20, 0x39, 0x76, 0x82, 0x10, 0x39, 0xc6, 0x80, 0x65, 0x39, 0xf6, 0x7d, + 0x54, 0x39, 0x0f, 0x03, 0x79, 0x39, 0x9b, 0xef, 0x4c, 0x39, 0xa1, 0x12, 0x48, + 0x39, 0x23, 0x63, 0x51, 0x39, 0x52, 0xcf, 0x62, 0x39, 0x3c, 0xff, 0x24, 0x39, + 0x9a, 0xbd, 0x33, 0x39, 0x89, 0x8e, 0x5a, 0x39, 0x53, 0x05, 0x71, 0x39, 0xe1, + 0x35, 0x06, 0x39, 0x36, 0x71, 0x1b, 0x39, 0x3b, 0x22, 0x09, 0x39, 0x4e, 0x59, + 0x17, 0x39, 0x51, 0x6c, 0x31, 0x39, 0xd2, 0x94, 0x46, 0x39, 0x15, 0x9a, 0x4c, + 0x39, 0x68, 0x27, 0x85, 0x39, 0x57, 0x9e, 0x40, 0x39, 0xdd, 0x3e, 0x9e, 0x39, + 0x05, 0x2d, 0x87, 0x39, 0x9b, 0xb1, 0x55, 0x39, 0x79, 0x55, 0x42, 0x39, 0x5e, + 0x90, 0x21, 0x39, 0xa1, 0x2a, 0x2d, 0x39, 0xb0, 0xa2, 0x36, 0x39, 0x06, 0x7a, + 0x40, 0x39, 0x00, 0x86, 0x4d, 0x39, 0x12, 0xab, 0x82, 0x39, 0x90, 0xf3, 0x3f, + 0x39, 0xe0, 0x70, 0x2c, 0x39, 0x5b, 0x73, 0x27, 0x39, 0x54, 0x38, 0x23, 0x39, + 0xf7, 0xd0, 0xff, 0x38, 0xbb, 0x29, 0x5e, 0x39, 0x1b, 0xd5, 0x83, 0x39, 0x4d, + 0xff, 0x25, 0x39, 0x21, 0xa7, 0x28, 0x39, 0x92, 0x5f, 0x2c, 0x39, 0x55, 0x77, + 0x76, 0x39, 0xc4, 0x8a, 0x09, 0x39, 0x5f, 0xdc, 0x3d, 0x39, 0xed, 0xe2, 0x8c, + 0x39, 0xde, 0x2b, 0x44, 0x39, 0x36, 0x74, 0x9c, 0x39, 0xf6, 0xe6, 0x7d, 0x39, + 0x15, 0xad, 0x6c, 0x39, 0x94, 0x7b, 0x23, 0x39, 0x21, 0xda, 0x65, 0x39, 0xf0, + 0xe6, 0x51, 0x39, 0xb0, 0xcd, 0x54, 0x39, 0x93, 0x79, 0x19, 0x39, 0x8c, 0x13, + 0x6c, 0x39, 0x9b, 0x9e, 0x26, 0x39, 0x2e, 0xd8, 0x37, 0x39, 0x2c, 0x02, 0x4e, + 0x39, 0xe1, 0x82, 0x3b, 0x39, 0x80, 0x97, 0x14, 0x39, 0xb0, 0x36, 0x47, 0x39, + 0x4b, 0x5c, 0x84, 0x39, 0xac, 0xcb, 0x38, 0x39, 0xad, 0xc9, 0x78, 0x39, 0x77, + 0x79, 0x25, 0x39, 0x58, 0x48, 0x7a, 0x39, 0xb6, 0x02, 0x31, 0x39, 0x6a, 0xcd, + 0x0b, 0x39, 0xde, 0xf4, 0x50, 0x39, 0xd2, 0x52, 0x83, 0x39, 0x30, 0x2e, 0x34, + 0x39, 0x35, 0x7c, 0x59, 0x39, 0x2c, 0x59, 0x2f, 0x39, 0x3b, 0x14, 0x19, 0x39, + 0xc2, 0x49, 0x26, 0x39, 0xea, 0xbf, 0x4c, 0x39, 0x64, 0xb8, 0x97, 0x39, 0xf3, + 0xb8, 0x52, 0x39, 0xed, 0xde, 0x44, 0x39, 0xb5, 0xb9, 0x58, 0x39, 0x58, 0x74, + 0x62, 0x39, 0x6f, 0x38, 0x1a, 0x39, 0x82, 0x10, 0x2f, 0x39, 0xf7, 0xa6, 0x60, + 0x39, 0xd3, 0xbd, 0x6f, 0x39, 0x12, 0xb3, 0x3b, 0x39, 0xf1, 0x46, 0x42, 0x39, + 0x72, 0xd8, 0x2c, 0x39, 0xd3, 0x91, 0x4e, 0x39, 0xaa, 0x80, 0x26, 0x39, 0x1b, + 0x95, 0xff, 0x38, 0xf0, 0xa8, 0x69, 0x39, 0xcf, 0x29, 0x86, 0x39, 0xd1, 0x23, + 0x1a, 0x39, 0xb6, 0x2f, 0x3a, 0x39, 0xa5, 0x55, 0x1e, 0x39, 0x17, 0xcf, 0x45, + 0x39, 0x15, 0x57, 0xea, 0x38, 0xcf, 0xbb, 0x17, 0x39, 0x52, 0xc3, 0x44, 0x39, + 0x2d, 0x44, 0x66, 0x39, 0x13, 0x22, 0x9e, 0x39, 0xa2, 0x1f, 0x2b, 0x39, 0x6d, + 0xac, 0x57, 0x39, 0x06, 0xa5, 0x84, 0x39, 0x9f, 0x2c, 0x0f, 0x39, 0x2a, 0xab, + 0x35, 0x39, 0x8c, 0x72, 0x49, 0x39, 0x73, 0x53, 0x4c, 0x39, 0xc6, 0x1a, 0x90, + 0x39, 0xf9, 0xa3, 0x6c, 0x39, 0xa7, 0xa9, 0xac, 0x39, 0x5d, 0x07, 0x1c, 0x39, + 0x75, 0x46, 0x21, 0x39, 0x4d, 0xad, 0x4a, 0x39, 0x23, 0x7f, 0x52, 0x39, 0x94, + 0x97, 0x4b, 0x39, 0xab, 0x86, 0x17, 0x39, 0x15, 0xa4, 0x05, 0x39, 0xe3, 0xce, + 0x1b, 0x39, 0xbb, 0xe3, 0xd9, 0x38, 0x55, 0x62, 0x1e, 0x39, 0x8e, 0x3c, 0x6c, + 0x39, 0x92, 0xd5, 0x4d, 0x39, 0x33, 0x73, 0x81, 0x39, 0x98, 0xce, 0xb0, 0x39, + 0x57, 0xe4, 0x25, 0x39, 0x59, 0x1f, 0x67, 0x39, 0x09, 0x6b, 0x77, 0x39, 0xbe, + 0xcc, 0x52, 0x39, 0x30, 0x00, 0x5a, 0x39, 0x24, 0x7f, 0x5c, 0x39, 0x62, 0x99, + 0x6e, 0x39, 0xa7, 0xc8, 0x44, 0x39, 0xd3, 0x1c, 0xf9, 0x38, 0xad, 0xa2, 0x8b, + 0x39, 0x0b, 0xe0, 0x61, 0x39, 0x64, 0xf5, 0x25, 0x39, 0x56, 0x0a, 0x53, 0x39, + 0x35, 0x4a, 0x47, 0x39, 0x0f, 0x33, 0x3c, 0x39, 0xc0, 0xb1, 0x34, 0x39, 0x24, + 0x11, 0x6c, 0x39, 0x32, 0x70, 0x3c, 0x39, 0xfe, 0x33, 0x36, 0x39, 0xe7, 0xbc, + 0xeb, 0x38, 0xba, 0xd8, 0x17, 0x39, 0x27, 0x6b, 0x5f, 0x39, 0xef, 0x82, 0x2d, + 0x39, 0x34, 0x5c, 0x6a, 0x39, 0x8c, 0x54, 0x3b, 0x39, 0x44, 0x16, 0x3c, 0x39, + 0x08, 0x5b, 0x78, 0x39, 0x20, 0xb4, 0xc1, 0x39, 0x49, 0xb8, 0x08, 0x39, 0x08, + 0xe9, 0x63, 0x39, 0x4d, 0x7b, 0x49, 0x39, 0x0a, 0x6c, 0x2c, 0x39, 0x15, 0x27, + 0x86, 0x39, 0x71, 0xda, 0x74, 0x39, 0xb1, 0x10, 0x18, 0x39, 0xa4, 0x45, 0x94, + 0x39, 0x61, 0x87, 0x71, 0x39, 0x8c, 0x1c, 0x64, 0x39, 0x7a, 0x1e, 0x7b, 0x39, + 0x7e, 0xb6, 0x36, 0x39, 0x2f, 0x59, 0x14, 0x39, 0xd5, 0x70, 0x1a, 0x39, 0x12, + 0xa8, 0xc2, 0x39, 0xe5, 0x23, 0x80, 0x39, 0x73, 0xd2, 0x95, 0x39, 0xe4, 0xe4, + 0x2c, 0x39, 0xc7, 0x98, 0x50, 0x39, 0xe2, 0x0d, 0x62, 0x39, 0xef, 0xd1, 0x22, + 0x39, 0xc5, 0xb5, 0x05, 0x39, 0x7b, 0x81, 0x3b, 0x39, 0xe7, 0xc4, 0x00, 0x39, + 0x93, 0xcf, 0x24, 0x39, 0xa4, 0x08, 0x18, 0x39, 0xa9, 0xa7, 0x5f, 0x39, 0x70, + 0xad, 0x8b, 0x39, 0x8c, 0xa8, 0x7c, 0x39, 0x9e, 0x62, 0x85, 0x39, 0x26, 0x5a, + 0x54, 0x39, 0xfc, 0x19, 0x0d, 0x39, 0x66, 0x93, 0x06, 0x39, 0x5c, 0x72, 0x7e, + 0x39, 0xde, 0x33, 0xf3, 0x38, 0x1e, 0x7d, 0x42, 0x39, 0x73, 0xfb, 0x46, 0x39, + 0x9a, 0x5f, 0x96, 0x39, 0x9c, 0xf5, 0x80, 0x39, 0x92, 0x05, 0x2a, 0x39, 0x64, + 0x49, 0x2e, 0x39, 0xcf, 0xb0, 0x3c, 0x39, 0x6e, 0x23, 0x41, 0x39, 0x46, 0xda, + 0x63, 0x39, 0xde, 0x7d, 0x7f, 0x39, 0x2c, 0x55, 0x5c, 0x39, 0xc0, 0x05, 0x29, + 0x39, 0xdf, 0xf3, 0x44, 0x39, 0xba, 0x41, 0x06, 0x39, 0xe5, 0x32, 0x7a, 0x39, + 0xee, 0xf3, 0x67, 0x39, 0x0c, 0x2d, 0x49, 0x39, 0xf7, 0x67, 0x7f, 0x39, 0x86, + 0x07, 0x3b, 0x39, 0x94, 0x91, 0x50, 0x39, 0x8a, 0xc6, 0x32, 0x39, 0x20, 0x3b, + 0x17, 0x39, 0x77, 0xba, 0x46, 0x39, 0x53, 0xe6, 0x58, 0x39, 0x2a, 0x2e, 0x9f, + 0x39, 0x08, 0x04, 0x5a, 0x39, 0x02, 0xc9, 0x2c, 0x39, 0x9e, 0x69, 0x6e, 0x39, + 0x42, 0xac, 0x92, 0x39, 0xb7, 0xa2, 0x17, 0x39, 0x1b, 0x22, 0x7f, 0x39, 0x59, + 0x99, 0x24, 0x39, 0x8c, 0xee, 0x42, 0x39, 0x79, 0xb6, 0x2a, 0x39, 0x41, 0xef, + 0x78, 0x39, 0xad, 0x11, 0x25, 0x39, 0x55, 0x23, 0x07, 0x39, 0x13, 0xd7, 0x38, + 0x39, 0x6e, 0xff, 0x5f, 0x39, 0x80, 0x41, 0x7f, 0x39, 0x58, 0xd1, 0x52, 0x39, + 0x4a, 0x08, 0x74, 0x39, 0x7a, 0xa0, 0x64, 0x39, 0xc1, 0x91, 0x66, 0x39, 0xbe, + 0x37, 0x6e, 0x39, 0xb9, 0xa4, 0x32, 0x39, 0x67, 0x88, 0x00, 0x39, 0xb8, 0xeb, + 0x56, 0x39, 0xec, 0x29, 0x15, 0x39, 0xec, 0x57, 0x40, 0x39, 0x3a, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x33, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x52, 0x44, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, + 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xec, 0xca, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x33, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf2, 0x44, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8c, 0xcb, 0xff, 0xff, 0x30, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x32, 0x5f, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, + 0x75, 0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x92, + 0x45, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x0c, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x20, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x4c, 0xff, + 0xff, 0x10, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x5e, 0xab, 0x58, 0x38, 0x1b, 0x09, 0x10, 0x38, 0x76, 0x32, 0x30, + 0x38, 0xb8, 0xde, 0x27, 0x38, 0xe2, 0x95, 0x9b, 0x38, 0xac, 0xeb, 0x28, 0x38, + 0x59, 0xcd, 0x7f, 0x38, 0xfb, 0xe1, 0x81, 0x38, 0x42, 0x88, 0x30, 0x38, 0x21, + 0x9e, 0x49, 0x38, 0x15, 0x51, 0x46, 0x38, 0x57, 0xbd, 0x3e, 0x38, 0x2f, 0xbe, + 0x17, 0x38, 0xdc, 0x57, 0x53, 0x38, 0xae, 0xf1, 0xa4, 0x38, 0x12, 0xd3, 0x64, + 0x38, 0x91, 0x27, 0x7a, 0x38, 0xf3, 0x6c, 0x14, 0x38, 0x97, 0x6f, 0x4a, 0x38, + 0x8b, 0xcb, 0x48, 0x38, 0x08, 0xfb, 0x82, 0x38, 0x3f, 0x07, 0x44, 0x38, 0xdb, + 0xb2, 0x3a, 0x38, 0x27, 0xbd, 0x26, 0x38, 0xde, 0xeb, 0x56, 0x38, 0x6a, 0x0a, + 0x7d, 0x38, 0x79, 0x0c, 0x58, 0x38, 0x98, 0x0d, 0x79, 0x38, 0x22, 0x01, 0x2f, + 0x38, 0xaa, 0x72, 0x46, 0x38, 0x91, 0x50, 0x07, 0x38, 0xea, 0xe2, 0x68, 0x38, + 0x14, 0x55, 0x53, 0x38, 0x32, 0xe4, 0x4b, 0x38, 0x9b, 0x92, 0x0f, 0x38, 0xf7, + 0xef, 0x3c, 0x38, 0x62, 0x4e, 0xa8, 0x38, 0x67, 0x90, 0x3c, 0x38, 0x05, 0xdf, + 0x14, 0x38, 0x3a, 0x8e, 0x7d, 0x38, 0x32, 0x6c, 0x7f, 0x38, 0x05, 0x40, 0x4b, + 0x38, 0x85, 0x4e, 0x46, 0x38, 0xbe, 0x73, 0x26, 0x38, 0xf9, 0x5d, 0x36, 0x38, + 0x8a, 0x30, 0x3d, 0x38, 0x3c, 0x9b, 0x2c, 0x38, 0x6a, 0x3b, 0x2c, 0x38, 0xe1, + 0x38, 0x89, 0x38, 0xdf, 0x1e, 0x5c, 0x38, 0x11, 0x07, 0x4f, 0x38, 0x08, 0x26, + 0x15, 0x38, 0x92, 0x27, 0x75, 0x38, 0xcf, 0x76, 0x3a, 0x38, 0x14, 0x13, 0x55, + 0x38, 0x64, 0x30, 0x53, 0x38, 0x4d, 0x19, 0x75, 0x38, 0xea, 0x65, 0x3d, 0x38, + 0xe5, 0x0c, 0x1d, 0x38, 0xc0, 0xb7, 0x4a, 0x38, 0x9f, 0xc4, 0x1c, 0x38, 0x38, + 0xae, 0x72, 0x38, 0x00, 0xba, 0x11, 0x38, 0xc9, 0xb0, 0x54, 0x38, 0x51, 0xb9, + 0x83, 0x38, 0x30, 0xf6, 0x57, 0x38, 0x2f, 0x3b, 0x4f, 0x38, 0xe4, 0x2f, 0x58, + 0x38, 0x59, 0xec, 0x16, 0x38, 0xf4, 0x06, 0x4a, 0x38, 0x8e, 0x81, 0x41, 0x38, + 0x30, 0x10, 0x40, 0x38, 0xb3, 0xfd, 0x95, 0x38, 0xa9, 0xfa, 0x49, 0x38, 0xcd, + 0x4f, 0x45, 0x38, 0x48, 0x3e, 0x22, 0x38, 0x5b, 0xb5, 0x5e, 0x38, 0x80, 0x22, + 0x44, 0x38, 0x02, 0x38, 0x78, 0x38, 0xfc, 0x94, 0xef, 0x38, 0xc1, 0xab, 0x95, + 0x38, 0xfc, 0x35, 0x17, 0x38, 0xcd, 0xd4, 0x6d, 0x38, 0xa0, 0xed, 0xe6, 0x37, + 0x17, 0xfc, 0x26, 0x38, 0x9a, 0x2a, 0xdd, 0x37, 0x00, 0x2a, 0x6e, 0x38, 0xc3, + 0xcf, 0x97, 0x38, 0x4b, 0x50, 0x1a, 0x38, 0x34, 0xe2, 0x78, 0x38, 0x65, 0x83, + 0x76, 0x38, 0xff, 0xf5, 0x8f, 0x38, 0x00, 0x75, 0x4c, 0x38, 0xed, 0x8f, 0x8a, + 0x38, 0xa4, 0x3f, 0x6c, 0x38, 0x32, 0x37, 0x66, 0x38, 0xb9, 0xa6, 0x40, 0x38, + 0x6f, 0x8b, 0x40, 0x38, 0xea, 0x25, 0x5f, 0x38, 0x8c, 0xbb, 0x52, 0x38, 0x1e, + 0x92, 0x4d, 0x38, 0x64, 0xda, 0x51, 0x38, 0xb2, 0xc2, 0x16, 0x38, 0xa6, 0x8a, + 0x2f, 0x38, 0x8b, 0x23, 0x58, 0x38, 0x9d, 0x86, 0x4c, 0x38, 0x39, 0xd1, 0x24, + 0x38, 0x59, 0x2d, 0x2d, 0x38, 0xdd, 0x33, 0x92, 0x38, 0x39, 0xe8, 0x28, 0x38, + 0xc6, 0x34, 0x57, 0x38, 0x16, 0xd8, 0x2d, 0x38, 0x44, 0x45, 0x63, 0x38, 0x12, + 0x10, 0x9b, 0x38, 0xf7, 0x0b, 0x05, 0x38, 0xae, 0x23, 0x35, 0x38, 0xd5, 0xd1, + 0x96, 0x38, 0xfd, 0xf5, 0x81, 0x38, 0x0b, 0x99, 0x71, 0x38, 0xd5, 0xae, 0x7e, + 0x38, 0xb0, 0x03, 0x50, 0x38, 0xff, 0x6c, 0x70, 0x38, 0xbd, 0xeb, 0x23, 0x38, + 0xce, 0xd1, 0x33, 0x38, 0x27, 0xe9, 0x3f, 0x38, 0x94, 0xc7, 0x39, 0x38, 0x1c, + 0x36, 0x22, 0x38, 0xb0, 0x96, 0x37, 0x38, 0x2e, 0x1b, 0x24, 0x38, 0xa6, 0x99, + 0x53, 0x38, 0x89, 0x1b, 0x3e, 0x38, 0x4d, 0x3d, 0x65, 0x38, 0x82, 0xda, 0x30, + 0x38, 0x7f, 0xe9, 0x47, 0x38, 0xe8, 0xd4, 0xa1, 0x38, 0xc1, 0x4b, 0x2f, 0x38, + 0x68, 0x9d, 0x48, 0x38, 0x62, 0xfb, 0x09, 0x38, 0xa7, 0x96, 0xff, 0x37, 0xb3, + 0x52, 0x43, 0x38, 0x3f, 0x5f, 0x2a, 0x38, 0x08, 0x03, 0x76, 0x38, 0x11, 0x90, + 0x2d, 0x38, 0xed, 0x50, 0x4f, 0x38, 0x46, 0xf5, 0x75, 0x38, 0x73, 0xd3, 0x8e, + 0x38, 0x4a, 0x4a, 0x84, 0x38, 0xaf, 0xdc, 0x82, 0x38, 0x77, 0xda, 0x24, 0x38, + 0x5e, 0x8b, 0x45, 0x38, 0x6e, 0x38, 0x4a, 0x38, 0x12, 0x5b, 0x3c, 0x38, 0x7c, + 0x27, 0x68, 0x38, 0x77, 0x4e, 0x0f, 0x38, 0xb6, 0x1d, 0x5c, 0x38, 0xa2, 0x68, + 0x9c, 0x38, 0x32, 0x4e, 0x5c, 0x38, 0xa4, 0xeb, 0x6b, 0x38, 0xfa, 0x00, 0x69, + 0x38, 0xe1, 0xb9, 0x5a, 0x38, 0xe2, 0xa4, 0x57, 0x38, 0xb3, 0x7c, 0x4e, 0x38, + 0xef, 0x33, 0x32, 0x38, 0x6b, 0x57, 0x08, 0x38, 0x25, 0xf4, 0x2b, 0x38, 0x26, + 0x3a, 0x74, 0x38, 0xc7, 0x13, 0x74, 0x38, 0x1f, 0x16, 0x82, 0x38, 0x27, 0x5f, + 0x21, 0x38, 0xbe, 0x7b, 0x7d, 0x38, 0x7b, 0x58, 0x98, 0x38, 0xe7, 0x8b, 0x95, + 0x38, 0x4f, 0xd2, 0x3c, 0x38, 0xdb, 0x19, 0x3f, 0x38, 0x06, 0xed, 0x7d, 0x38, + 0x75, 0x64, 0x2a, 0x38, 0xcf, 0x6a, 0x56, 0x38, 0x32, 0x2a, 0x39, 0x38, 0xb3, + 0xd9, 0x4d, 0x38, 0x8f, 0xe5, 0x79, 0x38, 0x20, 0xf9, 0x4a, 0x38, 0x9b, 0x1b, + 0x4f, 0x38, 0xa1, 0xbf, 0x9e, 0x38, 0xa5, 0x73, 0x3a, 0x38, 0x33, 0xe8, 0x34, + 0x38, 0xbb, 0x0b, 0x3b, 0x38, 0x8b, 0xbd, 0x42, 0x38, 0xc6, 0x6b, 0x38, 0x38, + 0x80, 0x3c, 0x52, 0x38, 0x18, 0xd2, 0x8b, 0x38, 0x2e, 0x63, 0x40, 0x38, 0x07, + 0x07, 0x3d, 0x38, 0xb8, 0x65, 0x5a, 0x38, 0xa2, 0x62, 0x11, 0x38, 0x44, 0x30, + 0x4b, 0x38, 0x7c, 0xf0, 0x4c, 0x38, 0x5b, 0xf6, 0x3d, 0x38, 0x2f, 0x0b, 0x84, + 0x38, 0xc7, 0xb6, 0x77, 0x38, 0x7c, 0x0e, 0x82, 0x38, 0x3e, 0x69, 0x6a, 0x38, + 0x80, 0x1a, 0x62, 0x38, 0x55, 0x09, 0x7f, 0x38, 0x05, 0x5b, 0x89, 0x38, 0xbf, + 0xa8, 0x10, 0x38, 0xac, 0x94, 0x86, 0x38, 0x84, 0xe1, 0x39, 0x38, 0xcd, 0xe1, + 0x6c, 0x38, 0x44, 0xc8, 0x6d, 0x38, 0xb5, 0x9e, 0x32, 0x38, 0xb0, 0x68, 0x71, + 0x38, 0x58, 0x21, 0x1f, 0x38, 0x68, 0x40, 0x4a, 0x38, 0xb5, 0x63, 0x7e, 0x38, + 0x51, 0x7d, 0x25, 0x38, 0x76, 0x9f, 0x4e, 0x38, 0xc6, 0x16, 0x7e, 0x38, 0x82, + 0x8f, 0x41, 0x38, 0xbe, 0x2b, 0x58, 0x38, 0xe2, 0x0c, 0x5e, 0x38, 0xff, 0xba, + 0x83, 0x38, 0xf0, 0x81, 0x99, 0x38, 0x97, 0x78, 0x4f, 0x38, 0x44, 0x39, 0x51, + 0x38, 0x49, 0xee, 0x6f, 0x38, 0x32, 0xce, 0x0c, 0x38, 0x67, 0x24, 0x2f, 0x38, + 0xde, 0xb2, 0x52, 0x38, 0xad, 0x9c, 0x36, 0x38, 0x03, 0x36, 0x23, 0x38, 0x55, + 0x22, 0x60, 0x38, 0x68, 0xd0, 0x87, 0x38, 0x77, 0x81, 0x41, 0x38, 0x0b, 0xc1, + 0x4c, 0x38, 0x41, 0xfd, 0x7a, 0x38, 0x32, 0x30, 0x24, 0x38, 0x0c, 0xca, 0x24, + 0x38, 0xb9, 0xa1, 0x48, 0x38, 0x92, 0x65, 0x73, 0x38, 0x20, 0x5f, 0x55, 0x38, + 0xdb, 0xe4, 0x2a, 0x38, 0x86, 0x64, 0x13, 0x38, 0x71, 0x46, 0x5a, 0x38, 0x3e, + 0x8c, 0x96, 0x38, 0x09, 0xa2, 0x35, 0x38, 0x49, 0x97, 0x71, 0x38, 0x38, 0xd5, + 0x4b, 0x38, 0xd9, 0xfc, 0x5a, 0x38, 0x7a, 0xbd, 0x73, 0x38, 0xba, 0x91, 0x8a, + 0x38, 0xcc, 0x88, 0x54, 0x38, 0xaa, 0xbe, 0x3f, 0x38, 0x39, 0xe4, 0x2d, 0x38, + 0x47, 0x27, 0x4a, 0x38, 0x22, 0xc9, 0x98, 0x38, 0x3c, 0x45, 0x93, 0x38, 0x37, + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x32, 0x5f, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x06, 0x52, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x06, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x62, 0x4b, 0xff, 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xaf, + 0xee, 0x04, 0x39, 0x1a, 0x2d, 0xe1, 0x38, 0xcd, 0x5c, 0x4a, 0x39, 0x9e, 0x09, + 0x23, 0x39, 0x24, 0x90, 0x63, 0x39, 0x5e, 0x18, 0xd8, 0x38, 0x4f, 0x1f, 0x02, + 0x39, 0x8f, 0x4d, 0x25, 0x39, 0xb8, 0x22, 0xe3, 0x38, 0xbb, 0xb9, 0x51, 0x39, + 0x64, 0x85, 0x10, 0x39, 0xfc, 0xae, 0xee, 0x38, 0x6d, 0x49, 0x23, 0x39, 0x77, + 0xdd, 0x05, 0x39, 0xac, 0xbd, 0xfc, 0x38, 0xfc, 0x0d, 0x1b, 0x39, 0x8f, 0xdc, + 0x65, 0x39, 0x40, 0xf4, 0x2c, 0x39, 0x34, 0xb4, 0x0b, 0x39, 0xc5, 0x81, 0x01, + 0x39, 0xbe, 0xfd, 0x06, 0x39, 0x4c, 0xa1, 0xe8, 0x38, 0x53, 0xb2, 0x25, 0x39, + 0xcb, 0x38, 0x0b, 0x39, 0x73, 0x8a, 0xce, 0x38, 0x69, 0xdc, 0x28, 0x39, 0x95, + 0x30, 0x0e, 0x39, 0xee, 0x53, 0xdd, 0x38, 0x1a, 0x2f, 0x33, 0x39, 0xbf, 0x3e, + 0x1e, 0x39, 0x45, 0x1b, 0x1e, 0x39, 0x12, 0x7d, 0x3e, 0x39, 0x16, 0x99, 0x24, + 0x39, 0x2a, 0xbc, 0x36, 0x39, 0xa1, 0x90, 0x05, 0x39, 0xbe, 0x5a, 0x33, 0x39, + 0x74, 0x39, 0x2d, 0x39, 0x1b, 0xc8, 0xbe, 0x38, 0x73, 0xbe, 0xda, 0x38, 0xff, + 0x96, 0x5e, 0x39, 0xb8, 0xdb, 0xc5, 0x38, 0x08, 0x9c, 0x74, 0x39, 0x5c, 0x88, + 0x46, 0x39, 0x2f, 0x30, 0x12, 0x39, 0xe2, 0x1a, 0xff, 0x38, 0xf5, 0x05, 0x12, + 0x39, 0xd8, 0x56, 0xed, 0x38, 0xee, 0xd7, 0x53, 0x39, 0xf4, 0x60, 0xfa, 0x38, + 0x44, 0x47, 0xfc, 0x38, 0x65, 0x71, 0xf3, 0x38, 0x7d, 0x30, 0xdc, 0x38, 0x8c, + 0xb8, 0x2e, 0x39, 0x7a, 0x16, 0x40, 0x39, 0x1f, 0x90, 0x29, 0x39, 0xf5, 0x2a, + 0x39, 0x39, 0x15, 0x22, 0xde, 0x38, 0x49, 0x46, 0x28, 0x39, 0x24, 0x4d, 0xc1, + 0x38, 0x9a, 0x81, 0x05, 0x39, 0xb0, 0xfd, 0x31, 0x39, 0x87, 0x96, 0x35, 0x39, + 0xfd, 0x04, 0x14, 0x39, 0x56, 0x18, 0xce, 0x38, 0xe7, 0x38, 0x04, 0x39, 0x89, + 0x3d, 0x2d, 0x39, 0xad, 0x29, 0xe1, 0x38, 0x89, 0x83, 0x17, 0x39, 0xa7, 0x0c, + 0x16, 0x39, 0x41, 0x56, 0x4d, 0x39, 0x04, 0x5a, 0x0f, 0x39, 0x6d, 0x76, 0xd5, + 0x38, 0x6a, 0xbd, 0x03, 0x39, 0x8e, 0x29, 0xdd, 0x38, 0xa9, 0x07, 0x09, 0x39, + 0x75, 0x72, 0x02, 0x39, 0x9b, 0x42, 0xb7, 0x38, 0x42, 0x41, 0x03, 0x39, 0xbc, + 0xb7, 0x1e, 0x39, 0x2c, 0xaa, 0xf1, 0x38, 0xaf, 0xed, 0x1f, 0x39, 0x8c, 0xe9, + 0x3d, 0x39, 0x4f, 0xae, 0x02, 0x39, 0xb3, 0x70, 0x19, 0x39, 0x78, 0xa2, 0x37, + 0x39, 0xcf, 0xbf, 0x24, 0x39, 0x11, 0x48, 0x2a, 0x39, 0x88, 0xc4, 0x09, 0x39, + 0xb8, 0x9c, 0x61, 0x39, 0x2a, 0xbb, 0x2d, 0x39, 0x4d, 0x46, 0xb3, 0x38, 0x2c, + 0xb1, 0x2f, 0x39, 0x3b, 0xb2, 0x5c, 0x39, 0x68, 0x02, 0x0b, 0x39, 0xac, 0x5f, + 0x0e, 0x39, 0x97, 0x49, 0x52, 0x39, 0x5b, 0x3c, 0xf5, 0x38, 0x9c, 0x54, 0x14, + 0x39, 0xa5, 0x79, 0x19, 0x39, 0x05, 0x86, 0xf3, 0x38, 0x98, 0xb5, 0x4e, 0x39, + 0xeb, 0x2d, 0x65, 0x39, 0x64, 0xe8, 0x74, 0x39, 0x2c, 0xf8, 0xf9, 0x38, 0x76, + 0x51, 0x20, 0x39, 0x6d, 0xf2, 0xf9, 0x38, 0x23, 0xa2, 0x4d, 0x39, 0xb9, 0xfe, + 0x14, 0x39, 0xcc, 0x69, 0x09, 0x39, 0xa2, 0x12, 0x85, 0x39, 0x09, 0x0a, 0x39, + 0x39, 0xc0, 0xa2, 0xf4, 0x38, 0x3e, 0x22, 0x19, 0x39, 0xa1, 0x25, 0x0e, 0x39, + 0x1b, 0xf8, 0x13, 0x39, 0x19, 0x29, 0x16, 0x39, 0xa0, 0x37, 0x5e, 0x39, 0x24, + 0x0b, 0x1c, 0x39, 0x9d, 0x0b, 0xce, 0x38, 0x1b, 0x8f, 0xe9, 0x38, 0xd7, 0x0e, + 0x26, 0x39, 0x18, 0x13, 0xc2, 0x38, 0x5a, 0xb2, 0x07, 0x39, 0xe5, 0xa3, 0x74, + 0x39, 0x15, 0x8b, 0x99, 0x38, 0x37, 0xae, 0xfe, 0x38, 0x85, 0x31, 0x53, 0x39, + 0x73, 0x9b, 0x49, 0x39, 0x3a, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x31, 0x32, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, + 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x82, 0x58, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0xdf, 0xff, 0xff, + 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, + 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x31, 0x32, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x22, 0x59, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xbc, 0xdf, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x31, 0x31, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, + 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc2, 0x59, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x02, 0x64, 0x06, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x44, 0x60, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x69, + 0x47, 0x9f, 0x38, 0x5b, 0xf0, 0x8b, 0x38, 0xaa, 0xcd, 0x9a, 0x38, 0x40, 0x1d, + 0x5d, 0x38, 0x15, 0xe3, 0x78, 0x38, 0xdb, 0x22, 0x2f, 0x38, 0xb7, 0xfc, 0x7c, + 0x38, 0x05, 0xdd, 0x4b, 0x38, 0x70, 0xd6, 0x56, 0x38, 0xfd, 0x3d, 0x4a, 0x38, + 0x70, 0xb2, 0x4d, 0x38, 0x21, 0xe6, 0x7e, 0x38, 0x51, 0xa8, 0x8b, 0x38, 0x00, + 0x8f, 0x43, 0x38, 0x02, 0xd3, 0x73, 0x38, 0x4c, 0x13, 0x44, 0x38, 0x1e, 0x6c, + 0xa3, 0x38, 0xa9, 0x97, 0x88, 0x38, 0x5b, 0x0c, 0x3e, 0x38, 0xf6, 0x0a, 0x6a, + 0x38, 0x1a, 0x32, 0x71, 0x38, 0x05, 0xfb, 0x42, 0x38, 0x7d, 0x9d, 0x57, 0x38, + 0x1e, 0x05, 0x7c, 0x38, 0x9b, 0x6e, 0x9b, 0x38, 0xe5, 0x57, 0x55, 0x38, 0x15, + 0xcd, 0x74, 0x38, 0x79, 0xb9, 0x82, 0x38, 0x9a, 0x43, 0x30, 0x38, 0xa6, 0xd0, + 0x75, 0x38, 0xba, 0x21, 0x79, 0x38, 0x85, 0x96, 0x5f, 0x38, 0x89, 0xcb, 0x5d, + 0x38, 0xee, 0xb0, 0x90, 0x38, 0x39, 0xf4, 0x8c, 0x38, 0x98, 0xf8, 0x3a, 0x38, + 0x85, 0x5f, 0x65, 0x38, 0x93, 0x54, 0x39, 0x38, 0xf6, 0xa8, 0x77, 0x38, 0xb8, + 0xa7, 0x58, 0x38, 0x38, 0x90, 0x54, 0x38, 0x66, 0x29, 0x8a, 0x38, 0xbb, 0xbe, + 0x59, 0x38, 0x69, 0x3f, 0x85, 0x38, 0x96, 0x0d, 0xaa, 0x38, 0x2b, 0x8d, 0x98, + 0x38, 0x0b, 0x19, 0x57, 0x38, 0x14, 0x47, 0x7c, 0x38, 0xe1, 0x06, 0x91, 0x38, + 0xaa, 0x54, 0x72, 0x38, 0xaa, 0x43, 0x4b, 0x38, 0x24, 0x3a, 0x55, 0x38, 0xad, + 0xc2, 0x45, 0x38, 0x38, 0xd2, 0x6c, 0x38, 0x21, 0x95, 0x43, 0x38, 0xd6, 0x2d, + 0x5f, 0x38, 0x6b, 0x28, 0xaa, 0x38, 0x59, 0xf8, 0x56, 0x38, 0x3d, 0xa1, 0x72, + 0x38, 0xcf, 0x5e, 0x46, 0x38, 0x98, 0x72, 0x64, 0x38, 0x59, 0xb0, 0x82, 0x38, + 0x93, 0x97, 0x89, 0x38, 0x94, 0x0b, 0x71, 0x38, 0x68, 0x1e, 0x9e, 0x38, 0x4f, + 0x79, 0x6b, 0x38, 0x64, 0x7c, 0x71, 0x38, 0x5c, 0x15, 0x69, 0x38, 0x5c, 0x37, + 0x82, 0x38, 0xbb, 0x01, 0x5e, 0x38, 0x38, 0x98, 0x3c, 0x38, 0x40, 0xc6, 0x59, + 0x38, 0xa7, 0x14, 0x57, 0x38, 0xa7, 0xad, 0x8f, 0x38, 0x1a, 0xc8, 0x51, 0x38, + 0x30, 0x3a, 0x6b, 0x38, 0x18, 0xbd, 0x2f, 0x38, 0x27, 0x7e, 0x34, 0x38, 0x24, + 0xe2, 0x84, 0x38, 0x5c, 0x2c, 0x74, 0x38, 0xfd, 0xc7, 0xc2, 0x38, 0xe7, 0xfd, + 0xb9, 0x38, 0x1a, 0x1c, 0x75, 0x38, 0x07, 0x09, 0x86, 0x38, 0x1b, 0x05, 0x4b, + 0x38, 0x4f, 0xc3, 0x5a, 0x38, 0xbc, 0x2c, 0x36, 0x38, 0x17, 0x0d, 0x45, 0x38, + 0xb3, 0x8a, 0x92, 0x38, 0x30, 0x8f, 0x94, 0x38, 0x79, 0xf2, 0x53, 0x38, 0x2c, + 0x41, 0x95, 0x38, 0x57, 0x91, 0x8f, 0x38, 0x46, 0x02, 0x4b, 0x38, 0xd0, 0xaa, + 0x2d, 0x38, 0xe4, 0x49, 0x5a, 0x38, 0xf2, 0xaa, 0x37, 0x38, 0x02, 0x5e, 0x5a, + 0x38, 0x30, 0x54, 0x40, 0x38, 0x44, 0xbc, 0xb3, 0x38, 0xe7, 0x64, 0x79, 0x38, + 0xe5, 0x9f, 0x78, 0x38, 0x9c, 0x06, 0x88, 0x38, 0x2d, 0x40, 0x77, 0x38, 0x82, + 0x16, 0x2f, 0x38, 0xce, 0xd7, 0x8c, 0x38, 0x11, 0x5a, 0x54, 0x38, 0xa5, 0x49, + 0x8a, 0x38, 0xa3, 0x55, 0x6f, 0x38, 0x39, 0xb9, 0x4d, 0x38, 0xcb, 0x17, 0x85, + 0x38, 0x20, 0xec, 0x5f, 0x38, 0xe8, 0x9c, 0x7f, 0x38, 0x12, 0xe5, 0x55, 0x38, + 0xcc, 0xb5, 0x6b, 0x38, 0xc3, 0xa4, 0x6c, 0x38, 0x2e, 0x80, 0x87, 0x38, 0xb6, + 0x54, 0x47, 0x38, 0xfd, 0x78, 0x88, 0x38, 0xca, 0x4d, 0x62, 0x38, 0x88, 0x90, + 0x74, 0x38, 0xf6, 0xe1, 0x42, 0x38, 0x0b, 0x9f, 0x55, 0x38, 0xfb, 0xe5, 0x94, + 0x38, 0x2c, 0x57, 0x49, 0x38, 0x58, 0xdf, 0x76, 0x38, 0x7f, 0x56, 0x9a, 0x38, + 0x80, 0x6d, 0x6d, 0x38, 0x37, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x31, 0x31, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x36, 0x60, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x02, 0x6c, 0x06, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x92, 0x59, 0xff, 0xff, 0x14, 0x04, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xa6, 0x5d, 0x16, 0x39, 0x80, 0xca, 0x26, 0x39, 0x1d, + 0x38, 0x4e, 0x39, 0x85, 0x11, 0x0e, 0x39, 0x7a, 0xb2, 0xf1, 0x38, 0xe4, 0x71, + 0xf9, 0x38, 0xf8, 0xbb, 0x22, 0x39, 0x83, 0xfe, 0x50, 0x39, 0xa7, 0x56, 0x2a, + 0x39, 0x64, 0xa7, 0x64, 0x39, 0xc3, 0x88, 0x5f, 0x39, 0xe8, 0x19, 0x12, 0x39, + 0x73, 0xa6, 0x46, 0x39, 0x32, 0xc1, 0x7c, 0x39, 0xfc, 0x05, 0x25, 0x39, 0x2c, + 0x83, 0xdd, 0x38, 0x09, 0x83, 0x3f, 0x39, 0x1a, 0xee, 0xf2, 0x38, 0xca, 0x53, + 0xff, 0x38, 0x98, 0xc7, 0x8a, 0x38, 0x3c, 0x4e, 0x0a, 0x39, 0xbb, 0xe2, 0x2a, + 0x39, 0x73, 0x31, 0xa6, 0x38, 0xba, 0x18, 0x16, 0x39, 0x16, 0x5c, 0x26, 0x39, + 0x16, 0x0f, 0x23, 0x39, 0x9d, 0x2c, 0x7a, 0x39, 0xed, 0x6f, 0x80, 0x39, 0xfd, + 0xae, 0x61, 0x39, 0xb5, 0xd3, 0x56, 0x39, 0x52, 0xe0, 0xaa, 0x38, 0x71, 0x4c, + 0x34, 0x39, 0x86, 0x28, 0x3a, 0x39, 0xff, 0xb9, 0x3d, 0x39, 0x86, 0x87, 0xff, + 0x38, 0x5b, 0xb7, 0x33, 0x39, 0x6e, 0x8a, 0xdc, 0x38, 0xd8, 0xfa, 0x17, 0x39, + 0xfa, 0x05, 0x9b, 0x39, 0x54, 0x55, 0x03, 0x39, 0x2e, 0x3e, 0x38, 0x39, 0x55, + 0xe2, 0x58, 0x39, 0x6b, 0x3d, 0x7a, 0x39, 0xa9, 0xf1, 0x01, 0x39, 0xc4, 0x32, + 0xd8, 0x38, 0x2f, 0xa2, 0xe2, 0x38, 0x64, 0x41, 0x24, 0x39, 0x74, 0x1a, 0x21, + 0x39, 0x02, 0x5f, 0x36, 0x39, 0x27, 0x2b, 0x03, 0x39, 0xfc, 0xdf, 0xf0, 0x38, + 0x63, 0xa1, 0x31, 0x39, 0x45, 0x79, 0x16, 0x39, 0xd8, 0x1d, 0x39, 0x39, 0x72, + 0x33, 0x1b, 0x39, 0xe9, 0x8d, 0x85, 0x39, 0xcd, 0xf4, 0x07, 0x39, 0x30, 0x96, + 0x60, 0x39, 0x2d, 0x4a, 0x36, 0x39, 0x73, 0xac, 0x17, 0x39, 0x8f, 0x96, 0x04, + 0x39, 0xe0, 0xe9, 0x14, 0x39, 0x02, 0xd8, 0x74, 0x39, 0xd3, 0x31, 0x3b, 0x39, + 0xc6, 0x17, 0x61, 0x39, 0x47, 0xbf, 0x00, 0x39, 0x3b, 0x76, 0xf1, 0x38, 0x1b, + 0x81, 0xeb, 0x38, 0xd8, 0xf2, 0xf8, 0x38, 0xbd, 0xd6, 0x2a, 0x39, 0x99, 0x29, + 0x23, 0x39, 0xa7, 0x7a, 0x10, 0x39, 0x7d, 0x22, 0x30, 0x39, 0x9b, 0xd2, 0xf2, + 0x38, 0xfd, 0x0b, 0x16, 0x39, 0x88, 0xd2, 0x14, 0x39, 0x0c, 0x47, 0x46, 0x39, + 0x25, 0x27, 0x35, 0x39, 0xed, 0xda, 0x4c, 0x39, 0x61, 0xa7, 0x3d, 0x39, 0x47, + 0xde, 0xfb, 0x38, 0x92, 0x79, 0xf0, 0x38, 0x33, 0x22, 0x1d, 0x39, 0xe0, 0x77, + 0xb5, 0x38, 0xcc, 0x41, 0x13, 0x39, 0x32, 0xe3, 0x24, 0x39, 0xef, 0xfb, 0x3c, + 0x39, 0x18, 0x5d, 0x89, 0x39, 0xed, 0xb6, 0x31, 0x39, 0x80, 0xf8, 0xdc, 0x38, + 0xde, 0xc0, 0x61, 0x39, 0xab, 0x1b, 0x1d, 0x39, 0xd7, 0xde, 0x3a, 0x39, 0x2b, + 0xa0, 0x80, 0x39, 0x9b, 0xbf, 0x6f, 0x39, 0xa3, 0x07, 0x82, 0x39, 0x11, 0xa3, + 0x68, 0x39, 0x0d, 0x4d, 0x28, 0x39, 0x37, 0xf5, 0xe5, 0x38, 0xe2, 0x07, 0x1d, + 0x39, 0x22, 0xe9, 0x2b, 0x39, 0x64, 0x6d, 0xdc, 0x38, 0xe7, 0xfb, 0x96, 0x38, + 0xa9, 0x83, 0x2e, 0x39, 0xce, 0x74, 0x31, 0x39, 0xa4, 0xab, 0x71, 0x39, 0xf6, + 0xbc, 0x3b, 0x39, 0xb8, 0x99, 0x7f, 0x39, 0xa7, 0xd0, 0x18, 0x39, 0x3b, 0x6e, + 0x5f, 0x39, 0x35, 0x63, 0xd0, 0x38, 0x92, 0xbf, 0xf0, 0x38, 0x99, 0x14, 0x40, + 0x39, 0x36, 0xed, 0x0d, 0x39, 0x67, 0x31, 0x17, 0x39, 0x3e, 0x94, 0x28, 0x39, + 0x57, 0x94, 0x17, 0x39, 0x1e, 0x64, 0x11, 0x39, 0x73, 0x4a, 0x72, 0x39, 0xa7, + 0xf6, 0x39, 0x39, 0x73, 0xd8, 0x35, 0x39, 0xc5, 0x95, 0x1a, 0x39, 0x01, 0xa4, + 0x07, 0x39, 0x15, 0x2b, 0x2f, 0x39, 0xcf, 0xa3, 0x5c, 0x39, 0x98, 0xfc, 0x71, + 0x39, 0x66, 0xc2, 0x88, 0x39, 0xc0, 0xba, 0x55, 0x39, 0x3a, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x31, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, + 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xb2, 0x66, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, + 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x4c, 0xed, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x31, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x52, 0x67, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xec, 0xed, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x30, 0x5f, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, 0x75, + 0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf2, 0x67, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x64, 0x06, 0x00, 0x00, 0x46, 0x00, 0x00, + 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x74, 0x6e, 0xff, 0xff, + 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x0f, 0xdb, 0x81, 0x38, 0x9a, 0x27, 0x6e, 0x38, 0xf4, + 0x34, 0x6d, 0x38, 0xd5, 0x59, 0x5c, 0x38, 0xfa, 0x44, 0x57, 0x38, 0x7d, 0xe6, + 0x46, 0x38, 0xc9, 0xad, 0x3f, 0x38, 0xcc, 0x17, 0x2a, 0x38, 0xc3, 0x1f, 0x69, + 0x38, 0x5a, 0x69, 0x85, 0x38, 0xa7, 0xd6, 0xad, 0x38, 0xd1, 0x8d, 0x8a, 0x38, + 0x68, 0xae, 0x66, 0x38, 0xeb, 0xdf, 0x6a, 0x38, 0x20, 0x8b, 0x56, 0x38, 0x3c, + 0x9c, 0x91, 0x38, 0x20, 0xc1, 0x8e, 0x38, 0x56, 0x75, 0x5d, 0x38, 0xb0, 0x8a, + 0x82, 0x38, 0xd1, 0xe7, 0x87, 0x38, 0xa7, 0xbf, 0x82, 0x38, 0x8b, 0xf8, 0xa1, + 0x38, 0x6e, 0x1e, 0x6c, 0x38, 0xbb, 0x19, 0x7f, 0x38, 0x32, 0xb7, 0x7a, 0x38, + 0xb2, 0x5a, 0x75, 0x38, 0x36, 0x30, 0xaa, 0x38, 0x09, 0x83, 0x67, 0x38, 0x76, + 0x02, 0x91, 0x38, 0x95, 0x5a, 0x7b, 0x38, 0xc1, 0xa1, 0x55, 0x38, 0x6a, 0x3e, + 0x3d, 0x38, 0x67, 0xf7, 0x6f, 0x38, 0x32, 0x6e, 0x40, 0x38, 0x0f, 0x3a, 0x86, + 0x38, 0xb5, 0xd7, 0x7d, 0x38, 0x6c, 0xfd, 0xa5, 0x38, 0x24, 0xfa, 0x7b, 0x38, + 0x47, 0x81, 0x70, 0x38, 0xad, 0x65, 0x65, 0x38, 0xa2, 0xce, 0x83, 0x38, 0x27, + 0xa2, 0x62, 0x38, 0x6d, 0x47, 0x6b, 0x38, 0x82, 0x04, 0x3a, 0x38, 0x52, 0x8e, + 0x69, 0x38, 0xfc, 0x53, 0x45, 0x38, 0x77, 0x70, 0x61, 0x38, 0xc8, 0xc8, 0x95, + 0x38, 0x9b, 0x83, 0x5f, 0x38, 0x95, 0xb5, 0x9d, 0x38, 0x71, 0x60, 0x6c, 0x38, + 0x49, 0x40, 0xa6, 0x38, 0x6a, 0x26, 0x80, 0x38, 0x89, 0x76, 0x4b, 0x38, 0x7a, + 0xdd, 0x87, 0x38, 0x01, 0x7e, 0x90, 0x38, 0x12, 0xd1, 0x73, 0x38, 0x62, 0x7a, + 0x8e, 0x38, 0xf4, 0xd6, 0x6a, 0x38, 0x8b, 0xd9, 0x4a, 0x38, 0x41, 0x51, 0x3c, + 0x38, 0xf6, 0x05, 0x3a, 0x38, 0xa1, 0x01, 0x81, 0x38, 0x43, 0x13, 0x72, 0x38, + 0x92, 0x81, 0x94, 0x38, 0x70, 0x8b, 0x6d, 0x38, 0x18, 0xc6, 0x71, 0x38, 0x80, + 0xd6, 0xa2, 0x38, 0x1f, 0xdb, 0xae, 0x38, 0xb3, 0x44, 0xd1, 0x38, 0xde, 0x33, + 0x3f, 0x38, 0x51, 0xf0, 0x3c, 0x38, 0xbe, 0x68, 0x6d, 0x38, 0xf0, 0xc2, 0x30, + 0x38, 0x8b, 0x96, 0x84, 0x38, 0xcf, 0x4e, 0x6d, 0x38, 0x39, 0xcb, 0x4c, 0x38, + 0x64, 0xf9, 0x32, 0x38, 0x90, 0x6f, 0x3f, 0x38, 0xa0, 0xd9, 0x65, 0x38, 0x2d, + 0x33, 0x74, 0x38, 0x8f, 0x61, 0x5b, 0x38, 0xc8, 0xcb, 0x80, 0x38, 0x9e, 0x5d, + 0x4b, 0x38, 0xb8, 0x83, 0x97, 0x38, 0x2a, 0x05, 0x96, 0x38, 0xfc, 0x2b, 0x6a, + 0x38, 0xb6, 0x3f, 0x36, 0x38, 0x50, 0x70, 0x6a, 0x38, 0x52, 0xfe, 0x64, 0x38, + 0xd2, 0x09, 0x6d, 0x38, 0x2a, 0x53, 0x9e, 0x38, 0x4c, 0x99, 0x8c, 0x38, 0xac, + 0x4d, 0x94, 0x38, 0x6f, 0x65, 0xa6, 0x38, 0xe0, 0xc6, 0x83, 0x38, 0x24, 0xb7, + 0x8a, 0x38, 0x5e, 0x02, 0x74, 0x38, 0xdb, 0xbe, 0x4d, 0x38, 0x1b, 0x8b, 0x43, + 0x38, 0xa1, 0x86, 0x2b, 0x38, 0x67, 0x24, 0x89, 0x38, 0xd5, 0x4c, 0x40, 0x38, + 0x30, 0xf2, 0x4b, 0x38, 0x8c, 0xf6, 0x63, 0x38, 0x3d, 0x68, 0x78, 0x38, 0x64, + 0x47, 0x98, 0x38, 0xde, 0xaa, 0x66, 0x38, 0x2f, 0x29, 0x6a, 0x38, 0xa3, 0x0e, + 0x50, 0x38, 0x4a, 0xd1, 0x53, 0x38, 0xa1, 0xd8, 0x62, 0x38, 0xfc, 0x95, 0x84, + 0x38, 0x64, 0x6e, 0x9d, 0x38, 0x4f, 0xa2, 0x8d, 0x38, 0x03, 0xbe, 0x80, 0x38, + 0xa1, 0x5f, 0x55, 0x38, 0x43, 0x55, 0x71, 0x38, 0xb5, 0xef, 0x5b, 0x38, 0x94, + 0x43, 0x5e, 0x38, 0x31, 0x5b, 0x77, 0x38, 0x32, 0xe8, 0x61, 0x38, 0x0c, 0x74, + 0x53, 0x38, 0x7a, 0xe4, 0x5f, 0x38, 0x62, 0xdf, 0x51, 0x38, 0x23, 0x25, 0x99, + 0x38, 0x17, 0xd0, 0x64, 0x38, 0x62, 0xd0, 0x68, 0x38, 0x37, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x30, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x77, 0x69, 0x73, 0x65, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, + 0x69, 0x61, 0x73, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x66, + 0x6e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, 0x06, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc2, 0x67, 0xff, + 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x8d, 0xb4, 0x0a, 0x39, + 0x7e, 0xcb, 0x12, 0x39, 0x18, 0x65, 0x2f, 0x39, 0x96, 0xaa, 0x18, 0x39, 0x5e, + 0xca, 0x1c, 0x39, 0x2f, 0x14, 0x37, 0x39, 0x40, 0x9c, 0x08, 0x39, 0x42, 0x07, + 0x23, 0x39, 0x7b, 0xbd, 0x1c, 0x39, 0x0f, 0xa2, 0xf1, 0x38, 0xeb, 0x75, 0x25, + 0x39, 0xb6, 0x10, 0x4c, 0x39, 0x1e, 0x2c, 0x31, 0x39, 0x98, 0xa3, 0x48, 0x39, + 0xfa, 0x46, 0x7a, 0x39, 0xaa, 0xdf, 0xd6, 0x38, 0xff, 0xec, 0x4e, 0x39, 0x8f, + 0xac, 0x3e, 0x39, 0x94, 0x6b, 0x02, 0x39, 0xfd, 0xcc, 0xf7, 0x38, 0x71, 0x65, + 0x42, 0x39, 0x9a, 0x8d, 0x17, 0x39, 0x2a, 0x92, 0xb3, 0x38, 0x2a, 0x7d, 0x27, + 0x39, 0x7d, 0x6a, 0x6f, 0x39, 0xd8, 0xce, 0xda, 0x38, 0x2a, 0x54, 0x0b, 0x39, + 0x05, 0x96, 0x05, 0x39, 0xef, 0x61, 0x2b, 0x39, 0xe2, 0x57, 0x75, 0x39, 0x3b, + 0x78, 0x2c, 0x39, 0xbe, 0x24, 0xb6, 0x38, 0x8b, 0xca, 0x46, 0x39, 0x11, 0x3f, + 0x42, 0x39, 0x03, 0x1c, 0x14, 0x39, 0x3f, 0x96, 0x8c, 0x39, 0x53, 0xac, 0x00, + 0x39, 0x20, 0x71, 0x35, 0x39, 0x29, 0x32, 0x53, 0x39, 0x8e, 0x91, 0xfc, 0x38, + 0xb9, 0xf3, 0x29, 0x39, 0x2f, 0xed, 0xde, 0x38, 0x52, 0x28, 0x5a, 0x39, 0xb4, + 0x10, 0x82, 0x39, 0xd9, 0xdb, 0x42, 0x39, 0x26, 0xb8, 0xd0, 0x38, 0xd1, 0x22, + 0x22, 0x39, 0x73, 0xda, 0x13, 0x39, 0x23, 0x11, 0x55, 0x39, 0x4d, 0xd7, 0xce, + 0x38, 0x7c, 0x2d, 0x29, 0x39, 0xa2, 0x76, 0x3a, 0x39, 0x30, 0x7f, 0x45, 0x39, + 0x36, 0x9d, 0x29, 0x39, 0x49, 0x0c, 0xd5, 0x38, 0x70, 0x44, 0x30, 0x39, 0x4f, + 0x38, 0xec, 0x38, 0x3f, 0x3d, 0xb5, 0x38, 0xbf, 0x25, 0x33, 0x39, 0x12, 0xd7, + 0xbd, 0x38, 0xc6, 0x3e, 0xd0, 0x38, 0x9e, 0xdd, 0x25, 0x39, 0x5d, 0x82, 0x93, + 0x39, 0x3c, 0x1b, 0x19, 0x39, 0xe8, 0xcc, 0xf0, 0x38, 0x73, 0x56, 0x38, 0x39, + 0xbe, 0x5c, 0xf0, 0x38, 0x7f, 0x48, 0x30, 0x39, 0x02, 0xed, 0x57, 0x39, 0x6d, + 0x10, 0x1d, 0x39, 0x94, 0xbf, 0x21, 0x39, 0x89, 0x6e, 0x5e, 0x39, 0x52, 0x37, + 0x01, 0x39, 0x36, 0x31, 0xb7, 0x38, 0x09, 0xc4, 0xec, 0x38, 0x1d, 0xcd, 0x17, + 0x39, 0xb8, 0xd1, 0xd2, 0x38, 0x14, 0x86, 0x03, 0x39, 0x0f, 0xd3, 0xc9, 0x38, + 0x0a, 0x46, 0x03, 0x39, 0xa7, 0xb6, 0x1f, 0x39, 0x91, 0x21, 0xfc, 0x38, 0x47, + 0x19, 0x61, 0x39, 0x33, 0x5a, 0x0f, 0x39, 0x3e, 0x5c, 0xb4, 0x38, 0xb6, 0x11, + 0x22, 0x39, 0xf3, 0x79, 0x61, 0x39, 0xd8, 0x00, 0x6c, 0x39, 0x67, 0xe8, 0x30, + 0x39, 0x41, 0xd7, 0x8a, 0x39, 0xff, 0x16, 0x1f, 0x39, 0x75, 0x6b, 0x28, 0x39, + 0xe4, 0x57, 0x40, 0x39, 0x82, 0xef, 0xdb, 0x38, 0x8c, 0x69, 0xa0, 0x39, 0xc2, + 0xb9, 0x40, 0x39, 0x04, 0xc8, 0x83, 0x39, 0xce, 0xdd, 0x0e, 0x39, 0x4d, 0xa8, + 0xee, 0x38, 0xea, 0xbf, 0x24, 0x39, 0xfe, 0x8e, 0x10, 0x39, 0x17, 0x94, 0xe9, + 0x38, 0x38, 0x42, 0xaa, 0x38, 0x87, 0x5e, 0x37, 0x39, 0xa7, 0xe2, 0xd0, 0x38, + 0xa6, 0x2c, 0x21, 0x39, 0xd0, 0xeb, 0x41, 0x39, 0x59, 0x17, 0x5a, 0x39, 0x15, + 0xe7, 0x8c, 0x39, 0xf4, 0xde, 0x67, 0x39, 0x58, 0x8c, 0x2d, 0x39, 0x5c, 0x8e, + 0x1b, 0x39, 0x9a, 0xe9, 0xe6, 0x38, 0xa4, 0xe6, 0x29, 0x39, 0x3c, 0x34, 0x0a, + 0x39, 0x7c, 0x46, 0xcb, 0x38, 0xe7, 0x15, 0x28, 0x39, 0xa1, 0x03, 0x35, 0x39, + 0xa3, 0x8a, 0x20, 0x39, 0x05, 0xe8, 0xf2, 0x38, 0x61, 0xcf, 0xbb, 0x38, 0xc6, + 0x8a, 0x13, 0x39, 0x4d, 0xb1, 0x41, 0x39, 0x3f, 0x33, 0x38, 0x39, 0xac, 0x8c, + 0x5d, 0x39, 0xa1, 0x08, 0xc6, 0x38, 0x12, 0x0e, 0x39, 0x39, 0x79, 0x73, 0x3a, + 0x39, 0x3a, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x30, 0x5f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe2, 0x74, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7c, 0xfb, 0xff, 0xff, 0x30, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, 0xc0, 0x3c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x30, 0x5f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x52, 0x65, 0x6c, + 0x75, 0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x82, + 0x75, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x78, 0x00, 0x00, 0x00, 0x59, 0x00, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0xfc, 0xff, + 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc1, 0xc0, + 0xc0, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x30, 0x2f, 0x52, 0x65, 0x6c, 0x75, 0x36, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x16, 0x76, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xc0, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x72, 0x6f, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x8c, 0x89, 0x06, 0x39, 0x3a, 0xd9, 0x5a, 0x39, 0xb1, 0xe4, + 0xc7, 0x37, 0x81, 0xa6, 0xd6, 0x37, 0x69, 0xc0, 0xbd, 0x38, 0xcd, 0xb7, 0x99, + 0x39, 0xeb, 0x2f, 0x15, 0x39, 0x7f, 0xee, 0x0e, 0x37, 0x2c, 0x00, 0x00, 0x00, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, + 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x30, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, + 0x5f, 0x62, 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xe6, 0x76, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x44, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x73, 0x2f, 0x53, 0x70, 0x61, 0x74, 0x69, 0x61, + 0x6c, 0x53, 0x71, 0x75, 0x65, 0x65, 0x7a, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x70, + 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x77, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x09, 0x74, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd4, 0xfd, 0xff, 0xff, 0x30, + 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x1b, 0x4d, 0x3c, + 0x01, 0x00, 0x00, 0x00, 0xce, 0xb0, 0xcc, 0x3f, 0x01, 0x00, 0x00, 0x00, 0xe2, + 0xeb, 0xcb, 0xbf, 0x21, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x73, 0x2f, + 0x53, 0x70, 0x61, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x71, 0x75, 0x65, 0x65, 0x7a, + 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0xc2, 0x77, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x74, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x44, 0x7e, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0xe5, 0xd6, 0xbf, 0x3a, 0x4a, 0xd6, 0xb6, 0x3a, 0x2d, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x73, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x31, 0x63, 0x5f, 0x31, 0x78, 0x31, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x52, 0x78, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x70, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xd4, 0x7e, 0xff, 0xff, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xef, + 0x7a, 0xe4, 0x37, 0x28, 0xc2, 0xd9, 0x37, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4c, 0x6f, 0x67, + 0x69, 0x74, 0x73, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x63, + 0x5f, 0x31, 0x78, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x5f, 0x62, + 0x69, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0xd2, 0x78, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x78, 0x00, 0x00, + 0x00, 0x4b, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6c, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x73, 0x1b, 0x4d, + 0x3c, 0x01, 0x00, 0x00, 0x00, 0xce, 0xb0, 0xcc, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0xe2, 0xeb, 0xcb, 0xbf, 0x28, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x73, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x63, 0x5f, 0x31, 0x78, + 0x31, 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x66, 0x79, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x80, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x98, 0x72, 0x98, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x25, 0xda, 0x97, 0x40, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x4c, 0x6f, + 0x67, 0x69, 0x74, 0x73, 0x2f, 0x41, 0x76, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x5f, + 0x31, 0x61, 0x2f, 0x41, 0x76, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x7a, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x58, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x84, 0x80, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x30, 0x9c, 0x0e, 0x3b, 0xed, 0x44, 0x38, 0x3b, 0xef, 0x56, 0x12, 0x3b, 0xe5, + 0xb8, 0x28, 0x3b, 0x2f, 0x6a, 0x09, 0x3b, 0x71, 0xb8, 0x6c, 0x3b, 0x85, 0xba, + 0x2e, 0x3b, 0x52, 0x4d, 0x47, 0x3b, 0x02, 0x8d, 0x10, 0x3b, 0xa9, 0xd9, 0x49, + 0x3b, 0xbe, 0x2b, 0x3c, 0x3b, 0x25, 0x16, 0x38, 0x3b, 0xdc, 0x9e, 0x08, 0x3b, + 0xaf, 0xb6, 0x28, 0x3b, 0x9d, 0x44, 0x2b, 0x3b, 0x68, 0xf5, 0xe8, 0x3a, 0xd1, + 0x70, 0x1a, 0x3b, 0x56, 0x82, 0x0d, 0x3b, 0x47, 0x46, 0xea, 0x3a, 0x30, 0x72, + 0x49, 0x3b, 0xc3, 0x5d, 0x2a, 0x3b, 0x3f, 0x67, 0x2b, 0x3b, 0x9d, 0x51, 0x1b, + 0x3b, 0x92, 0x11, 0x0b, 0x3b, 0x6e, 0x69, 0xf6, 0x3a, 0x8b, 0x3d, 0x83, 0x3b, + 0xfb, 0x6e, 0x01, 0x3b, 0xd5, 0xf8, 0x66, 0x3b, 0x88, 0x00, 0x80, 0x3b, 0x9e, + 0xe9, 0x31, 0x3b, 0x6e, 0xf6, 0x27, 0x3b, 0x3d, 0x53, 0x54, 0x3b, 0x57, 0xc0, + 0x4a, 0x3b, 0x93, 0x70, 0x13, 0x3b, 0x06, 0x3b, 0x42, 0x3b, 0xca, 0x69, 0x08, + 0x3b, 0x62, 0x80, 0x3c, 0x3b, 0x94, 0x95, 0x2d, 0x3b, 0x88, 0xf2, 0x0d, 0x3b, + 0x67, 0xd3, 0x50, 0x3b, 0x47, 0x89, 0x4c, 0x3b, 0xb2, 0x55, 0x53, 0x3b, 0xf9, + 0x44, 0x11, 0x3b, 0xbd, 0xf8, 0x26, 0x3b, 0x03, 0x35, 0x0c, 0x3b, 0xfc, 0x0b, + 0x0e, 0x3b, 0x3a, 0x04, 0x3b, 0x3b, 0xeb, 0x60, 0x26, 0x3b, 0x3d, 0xd3, 0x32, + 0x3b, 0x65, 0x8f, 0x34, 0x3b, 0xe0, 0xd2, 0x1a, 0x3b, 0xa5, 0x42, 0x2a, 0x3b, + 0x6f, 0x61, 0x46, 0x3b, 0x12, 0xdf, 0x30, 0x3b, 0x07, 0x37, 0x45, 0x3b, 0x9e, + 0x57, 0x49, 0x3b, 0xed, 0xc9, 0x2a, 0x3b, 0xc1, 0xe5, 0x07, 0x3b, 0xe6, 0x5c, + 0x27, 0x3b, 0x18, 0xf4, 0x2c, 0x3b, 0x7b, 0xbc, 0x1e, 0x3b, 0x5b, 0x2a, 0x25, + 0x3b, 0x8b, 0xd3, 0x0a, 0x3b, 0xd6, 0xf9, 0x32, 0x3b, 0x3b, 0xe3, 0x4a, 0x3b, + 0xc3, 0x1c, 0x2a, 0x3b, 0x06, 0xcc, 0x39, 0x3b, 0xb5, 0xa6, 0x32, 0x3b, 0x58, + 0x1d, 0x0c, 0x3b, 0x0d, 0x63, 0x30, 0x3b, 0x98, 0x15, 0x67, 0x3b, 0x2b, 0x29, + 0x0e, 0x3b, 0xeb, 0x95, 0x29, 0x3b, 0x68, 0x2e, 0x2c, 0x3b, 0x64, 0xc2, 0x79, + 0x3b, 0x5d, 0x60, 0x5d, 0x3b, 0x77, 0xc4, 0x29, 0x3b, 0x11, 0x87, 0x41, 0x3b, + 0x7e, 0x0c, 0x35, 0x3b, 0x48, 0x2f, 0x31, 0x3b, 0x48, 0xef, 0x35, 0x3b, 0xd9, + 0xfe, 0x25, 0x3b, 0xa7, 0xd7, 0x48, 0x3b, 0xe3, 0xde, 0x48, 0x3b, 0x93, 0xa5, + 0x26, 0x3b, 0x26, 0xfc, 0x12, 0x3b, 0x98, 0xd4, 0x16, 0x3b, 0x3e, 0x8e, 0x27, + 0x3b, 0xb2, 0x5e, 0x56, 0x3b, 0xd3, 0xb3, 0x58, 0x3b, 0xc5, 0x71, 0x6c, 0x3b, + 0xb0, 0x7b, 0x46, 0x3b, 0x77, 0x95, 0x1e, 0x3b, 0x3a, 0xde, 0x2f, 0x3b, 0x08, + 0xfc, 0x24, 0x3b, 0x0a, 0xd5, 0x24, 0x3b, 0x41, 0xf5, 0x15, 0x3b, 0x87, 0x3b, + 0x48, 0x3b, 0x06, 0x23, 0x0a, 0x3b, 0x94, 0x19, 0x36, 0x3b, 0x95, 0xbe, 0x29, + 0x3b, 0x77, 0x69, 0x14, 0x3b, 0xa8, 0xa7, 0x1f, 0x3b, 0x80, 0x1e, 0x18, 0x3b, + 0x05, 0x08, 0x41, 0x3b, 0xf7, 0x8d, 0x1d, 0x3b, 0x79, 0xcb, 0x36, 0x3b, 0xde, + 0xad, 0x0e, 0x3b, 0xa8, 0x21, 0x14, 0x3b, 0xdb, 0xf9, 0x06, 0x3b, 0x43, 0x2a, + 0x81, 0x3b, 0xc1, 0x11, 0x16, 0x3b, 0x01, 0xcd, 0x76, 0x3b, 0x47, 0x0f, 0x44, + 0x3b, 0xa1, 0x1b, 0xf6, 0x3a, 0x4f, 0xcf, 0x1f, 0x3b, 0xfb, 0xf6, 0x15, 0x3b, + 0x37, 0xac, 0x1f, 0x3b, 0xc5, 0x5e, 0x60, 0x3b, 0x2d, 0x2e, 0x8a, 0x3b, 0x57, + 0x79, 0x7e, 0x3b, 0xf3, 0xa7, 0x2f, 0x3b, 0x94, 0xfc, 0x3b, 0x3b, 0x78, 0x2d, + 0xf7, 0x3a, 0x0f, 0xad, 0x15, 0x3b, 0x1c, 0xd7, 0x21, 0x3b, 0x0e, 0xcc, 0x22, + 0x3b, 0x70, 0x91, 0x49, 0x3b, 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x39, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, + 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x76, 0x80, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x68, 0x06, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x24, 0x06, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd2, 0x79, 0xff, 0xff, 0x14, 0x04, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x5a, 0x8a, 0xd9, 0x3b, 0x5f, 0xcd, 0x89, 0x3b, + 0xf4, 0xca, 0x92, 0x3b, 0x96, 0x01, 0xb8, 0x3b, 0x04, 0x10, 0x26, 0x3c, 0x8e, + 0x8d, 0xb2, 0x3b, 0xc2, 0xd9, 0xa9, 0x3b, 0xf9, 0xee, 0xd0, 0x3b, 0xce, 0xfe, + 0x97, 0x3b, 0x44, 0x79, 0x91, 0x3b, 0x2f, 0x92, 0xcd, 0x3b, 0x8d, 0x6a, 0xfe, + 0x3b, 0x21, 0x6b, 0x95, 0x3b, 0x29, 0x32, 0x8d, 0x3b, 0x37, 0x77, 0x0d, 0x3c, + 0x8a, 0x17, 0xea, 0x3b, 0xc5, 0xdd, 0xf7, 0x3b, 0x8f, 0x29, 0xaa, 0x3b, 0xeb, + 0x0e, 0x96, 0x3b, 0x17, 0xe3, 0x67, 0x3b, 0x96, 0xe9, 0xf1, 0x3b, 0x78, 0x22, + 0x91, 0x3b, 0x60, 0x7f, 0x0c, 0x3c, 0x14, 0xdd, 0x18, 0x3c, 0x55, 0xd7, 0x0a, + 0x3c, 0x94, 0x13, 0xe3, 0x3b, 0xe5, 0xc5, 0x8d, 0x3b, 0xab, 0xc2, 0x0d, 0x3c, + 0xb7, 0xf5, 0xf7, 0x3b, 0xd0, 0x25, 0x46, 0x3c, 0xdb, 0x7c, 0x05, 0x3c, 0xec, + 0x68, 0xd5, 0x3b, 0xe5, 0x43, 0xb0, 0x3b, 0xea, 0x32, 0xe2, 0x3b, 0xe6, 0x9e, + 0xcd, 0x3b, 0x8b, 0x88, 0xf9, 0x3b, 0x5e, 0xcc, 0xd6, 0x3b, 0xa6, 0x6e, 0xad, + 0x3b, 0x77, 0x7b, 0xaf, 0x3b, 0x3a, 0x14, 0x1c, 0x3c, 0x66, 0x6f, 0x86, 0x3b, + 0xe2, 0xdd, 0xb4, 0x3b, 0xdf, 0xd8, 0x95, 0x3b, 0xff, 0x99, 0x01, 0x3c, 0x94, + 0x37, 0xf2, 0x3b, 0x2c, 0x4b, 0xb5, 0x3b, 0x21, 0xac, 0xa1, 0x3b, 0x65, 0xfe, + 0xb5, 0x3b, 0xfb, 0x01, 0x1d, 0x3c, 0x35, 0xb8, 0x29, 0x3c, 0xd0, 0xb5, 0xaf, + 0x3b, 0x0b, 0x50, 0x06, 0x3c, 0x6f, 0x42, 0xd3, 0x3b, 0x51, 0x69, 0x9a, 0x3b, + 0x05, 0x8e, 0xb0, 0x3b, 0x19, 0x7f, 0xb1, 0x3b, 0xc9, 0x4f, 0xc6, 0x3b, 0x17, + 0x8c, 0xd8, 0x3b, 0x99, 0xea, 0x5f, 0x3c, 0x01, 0x5b, 0x26, 0x3c, 0x31, 0x17, + 0xcd, 0x3b, 0x86, 0x32, 0x3a, 0x3c, 0x16, 0xc0, 0xca, 0x3b, 0x4c, 0x5a, 0xae, + 0x3b, 0x9e, 0x40, 0xd9, 0x3b, 0x96, 0xa4, 0x12, 0x3c, 0xe5, 0xeb, 0x8f, 0x3b, + 0x37, 0x61, 0xca, 0x3b, 0x01, 0xe0, 0x1e, 0x3c, 0xff, 0x75, 0x64, 0x3b, 0xae, + 0xec, 0x04, 0x3c, 0xe9, 0xc1, 0xd8, 0x3b, 0xc8, 0x4e, 0x9a, 0x3b, 0xfc, 0xdb, + 0x98, 0x3b, 0x2e, 0x5a, 0xb6, 0x3b, 0xaa, 0xa5, 0x65, 0x3c, 0x63, 0xc8, 0xb5, + 0x3b, 0xeb, 0x10, 0xea, 0x3b, 0xe5, 0x2e, 0xa0, 0x3b, 0xbe, 0xbf, 0x8e, 0x3b, + 0x28, 0x42, 0x9e, 0x3b, 0x94, 0x4e, 0xbe, 0x3b, 0x7b, 0xae, 0x02, 0x3c, 0x3e, + 0x6c, 0x9f, 0x3b, 0x4b, 0xdd, 0xef, 0x3b, 0xa7, 0xbf, 0x92, 0x3b, 0x0b, 0x7b, + 0xa0, 0x3b, 0x52, 0x98, 0xc7, 0x3b, 0x29, 0x9e, 0xfa, 0x3b, 0xbf, 0x0f, 0xf3, + 0x3b, 0x1f, 0x6d, 0x99, 0x3b, 0xa2, 0xa3, 0xa7, 0x3b, 0xf0, 0x44, 0xb1, 0x3b, + 0xcb, 0x34, 0x73, 0x3b, 0x80, 0xb4, 0x48, 0x3c, 0xd8, 0x51, 0x8b, 0x3b, 0x8d, + 0x63, 0xf2, 0x3b, 0x4f, 0x4e, 0x06, 0x3c, 0x25, 0x09, 0x9b, 0x3b, 0xf7, 0x19, + 0x96, 0x3b, 0xc9, 0x9c, 0x00, 0x3c, 0x09, 0x50, 0x9a, 0x3b, 0xca, 0xbf, 0xb7, + 0x3b, 0xe1, 0x96, 0x8f, 0x3b, 0x56, 0x80, 0x8d, 0x3b, 0xfb, 0x3d, 0xa4, 0x3b, + 0xab, 0x64, 0xf7, 0x3b, 0x02, 0x36, 0xda, 0x3b, 0xe0, 0x68, 0xaa, 0x3b, 0x4d, + 0x81, 0xfe, 0x3b, 0xca, 0x40, 0x9c, 0x3b, 0xc5, 0x7f, 0xff, 0x3b, 0xa7, 0xa6, + 0x96, 0x3b, 0x12, 0x25, 0x89, 0x3b, 0x22, 0x4b, 0xbb, 0x3b, 0xcd, 0x27, 0xac, + 0x3b, 0x94, 0x10, 0xcc, 0x3b, 0x58, 0x19, 0xcd, 0x3b, 0xc5, 0x66, 0x07, 0x3c, + 0x7d, 0xbe, 0xf0, 0x3b, 0x05, 0x1e, 0x03, 0x3c, 0x97, 0xc0, 0x6d, 0x3b, 0x32, + 0xca, 0x97, 0x3b, 0x43, 0x0e, 0x8d, 0x3b, 0xee, 0x80, 0xad, 0x3b, 0x0d, 0xd8, + 0x8a, 0x3b, 0x17, 0x95, 0xa3, 0x3b, 0x22, 0x56, 0xbe, 0x3b, 0x35, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x39, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xfa, + 0x86, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x58, 0x06, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x8d, 0xff, + 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x25, 0x78, 0x0c, 0x3b, 0xfd, 0x6d, 0x28, 0x3b, + 0x80, 0x30, 0x23, 0x3b, 0x53, 0x22, 0x20, 0x3b, 0x08, 0x7b, 0x6b, 0x3b, 0xaa, + 0x4d, 0x68, 0x3b, 0xcb, 0x88, 0x21, 0x3b, 0x64, 0x20, 0x19, 0x3b, 0xb3, 0x06, + 0x1c, 0x3b, 0x08, 0x54, 0x4c, 0x3b, 0xad, 0x54, 0x33, 0x3b, 0x3e, 0xd5, 0x2d, + 0x3b, 0x8c, 0xb0, 0x2d, 0x3b, 0x36, 0x74, 0x33, 0x3b, 0x86, 0x73, 0x0a, 0x3b, + 0x48, 0x44, 0x10, 0x3b, 0xba, 0xd5, 0x3a, 0x3b, 0x14, 0x6a, 0x41, 0x3b, 0x2e, + 0x64, 0x29, 0x3b, 0xad, 0x6e, 0x0d, 0x3b, 0xf0, 0xaf, 0x3a, 0x3b, 0x56, 0xcf, + 0x28, 0x3b, 0xcc, 0xca, 0x35, 0x3b, 0x87, 0x8e, 0x33, 0x3b, 0x84, 0x7a, 0x42, + 0x3b, 0x7f, 0x21, 0x29, 0x3b, 0xd8, 0xea, 0x21, 0x3b, 0x4c, 0x20, 0x46, 0x3b, + 0x5a, 0x51, 0x2e, 0x3b, 0xd2, 0xe3, 0x2e, 0x3b, 0xad, 0xcc, 0x32, 0x3b, 0xe6, + 0x75, 0x45, 0x3b, 0x3e, 0x3d, 0x3f, 0x3b, 0xad, 0x25, 0x18, 0x3b, 0x7b, 0x94, + 0x19, 0x3b, 0x0c, 0x72, 0x31, 0x3b, 0x79, 0x93, 0x6b, 0x3b, 0x0c, 0xc8, 0x3d, + 0x3b, 0xe3, 0x15, 0x2f, 0x3b, 0xdc, 0x72, 0x1f, 0x3b, 0x4f, 0x86, 0x38, 0x3b, + 0x6e, 0x60, 0x2e, 0x3b, 0x27, 0x79, 0x12, 0x3b, 0x38, 0x5c, 0x26, 0x3b, 0x97, + 0x5d, 0x0b, 0x3b, 0xf6, 0xd9, 0x22, 0x3b, 0xfd, 0xcb, 0x47, 0x3b, 0xb4, 0x75, + 0x46, 0x3b, 0x34, 0x59, 0xec, 0x3a, 0xca, 0x3f, 0xe5, 0x3a, 0x85, 0x5d, 0x39, + 0x3b, 0x48, 0x4d, 0xed, 0x3a, 0x1c, 0x4a, 0x2b, 0x3b, 0x54, 0xdf, 0x18, 0x3b, + 0x78, 0x67, 0x00, 0x3b, 0xf0, 0x43, 0x35, 0x3b, 0xf3, 0xe5, 0x30, 0x3b, 0x3b, + 0xc0, 0x0a, 0x3b, 0x4a, 0x82, 0x32, 0x3b, 0xe6, 0xac, 0x2a, 0x3b, 0xc3, 0xbf, + 0x01, 0x3b, 0x53, 0xa3, 0x1f, 0x3b, 0x59, 0xc5, 0x2f, 0x3b, 0x43, 0xed, 0x48, + 0x3b, 0x75, 0x05, 0x15, 0x3b, 0x34, 0x31, 0x2f, 0x3b, 0x65, 0x54, 0x07, 0x3b, + 0x71, 0x3d, 0x2c, 0x3b, 0x1e, 0x9f, 0x21, 0x3b, 0x2b, 0xd4, 0x29, 0x3b, 0x03, + 0x86, 0x53, 0x3b, 0x8b, 0x78, 0x43, 0x3b, 0xd9, 0xbc, 0x3e, 0x3b, 0x37, 0x52, + 0x65, 0x3b, 0xbe, 0x2b, 0x6a, 0x3b, 0x39, 0x29, 0x30, 0x3b, 0xce, 0x74, 0x74, + 0x3b, 0xf5, 0x3e, 0x14, 0x3b, 0x20, 0x8d, 0x2e, 0x3b, 0xeb, 0xab, 0x1b, 0x3b, + 0x86, 0x51, 0x34, 0x3b, 0xc5, 0xdd, 0x64, 0x3b, 0x83, 0x21, 0x47, 0x3b, 0x14, + 0xc1, 0x38, 0x3b, 0xb2, 0xa2, 0x69, 0x3b, 0xaa, 0x97, 0x2c, 0x3b, 0x4f, 0x38, + 0xfd, 0x3a, 0x89, 0x21, 0x13, 0x3b, 0x8f, 0xb4, 0x02, 0x3b, 0xb8, 0x13, 0x34, + 0x3b, 0x5c, 0x27, 0x26, 0x3b, 0x92, 0xf0, 0x3f, 0x3b, 0x4b, 0xbc, 0x25, 0x3b, + 0x7f, 0xd1, 0x43, 0x3b, 0x38, 0xf0, 0x1c, 0x3b, 0x53, 0xd1, 0x2b, 0x3b, 0x00, + 0x93, 0x5e, 0x3b, 0x33, 0x65, 0x3c, 0x3b, 0xec, 0xa1, 0x16, 0x3b, 0x8e, 0xe1, + 0x1c, 0x3b, 0x70, 0x19, 0x5b, 0x3b, 0xe9, 0x16, 0x0d, 0x3b, 0x59, 0x69, 0x44, + 0x3b, 0x66, 0x38, 0xfb, 0x3a, 0x6d, 0x4a, 0x44, 0x3b, 0x94, 0x1f, 0x13, 0x3b, + 0x97, 0x36, 0x45, 0x3b, 0xe5, 0x0b, 0x76, 0x3b, 0x74, 0xb5, 0x0d, 0x3b, 0x23, + 0x54, 0x19, 0x3b, 0x05, 0x7c, 0x0d, 0x3b, 0x90, 0x11, 0x30, 0x3b, 0xc7, 0xf9, + 0x36, 0x3b, 0xf7, 0xee, 0x30, 0x3b, 0xa3, 0xfb, 0x3e, 0x3b, 0xdb, 0x92, 0x2e, + 0x3b, 0x25, 0xb9, 0x1e, 0x3b, 0x77, 0x7b, 0xfa, 0x3a, 0x8e, 0x6a, 0x28, 0x3b, + 0x01, 0xd7, 0x06, 0x3b, 0x23, 0xa8, 0x21, 0x3b, 0x5c, 0x39, 0x1b, 0x3b, 0x20, + 0xce, 0x28, 0x3b, 0x19, 0x57, 0x2b, 0x3b, 0x18, 0x50, 0x48, 0x3b, 0x1a, 0xc2, + 0x12, 0x3b, 0x7d, 0xbc, 0x26, 0x3b, 0xc6, 0x8b, 0x2c, 0x3b, 0x2b, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x38, 0x5f, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x6e, 0x8d, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x68, 0x06, 0x00, 0x00, 0x47, + 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xca, 0x86, + 0xff, 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb7, 0xc8, 0xb9, + 0x3b, 0x49, 0x06, 0x07, 0x3c, 0x13, 0x37, 0xaa, 0x3b, 0x4d, 0x39, 0x88, 0x3b, + 0x57, 0x70, 0xba, 0x3b, 0x17, 0xf4, 0x13, 0x3c, 0x91, 0xed, 0x12, 0x3c, 0xc7, + 0x17, 0xdc, 0x3b, 0x67, 0x96, 0x94, 0x3b, 0xb3, 0x0f, 0xac, 0x3b, 0xe6, 0xef, + 0xa2, 0x3b, 0x74, 0x00, 0x20, 0x3c, 0x5d, 0x78, 0xa8, 0x3b, 0x3b, 0x92, 0x97, + 0x3b, 0x13, 0x50, 0x8a, 0x3b, 0xe9, 0x01, 0x93, 0x3b, 0x9a, 0xf1, 0x26, 0x3c, + 0xaf, 0xb5, 0xd6, 0x3b, 0xf4, 0x4a, 0x3a, 0x3c, 0xf9, 0xfc, 0xa3, 0x3b, 0x9c, + 0xdc, 0x30, 0x3c, 0xe8, 0x5a, 0xa0, 0x3b, 0x93, 0x4f, 0xd3, 0x3b, 0x50, 0x8e, + 0xb5, 0x3b, 0xf3, 0xe6, 0x92, 0x3b, 0xee, 0x31, 0xc7, 0x3b, 0xb3, 0x8f, 0xf6, + 0x3b, 0xe5, 0x1c, 0xab, 0x3b, 0xa2, 0x69, 0xb9, 0x3b, 0x11, 0x67, 0xc5, 0x3b, + 0x97, 0x69, 0x2c, 0x3c, 0x0a, 0x11, 0x0f, 0x3c, 0xd6, 0xdc, 0xea, 0x3b, 0x62, + 0x0e, 0xd3, 0x3b, 0x16, 0xf5, 0x7d, 0x3b, 0x81, 0x5a, 0xcd, 0x3b, 0xc3, 0x2b, + 0xa3, 0x3b, 0x8a, 0x18, 0xd8, 0x3b, 0x53, 0x16, 0xa2, 0x3b, 0x79, 0x63, 0xaf, + 0x3b, 0x6d, 0x10, 0xad, 0x3b, 0xcb, 0x53, 0x0d, 0x3c, 0x96, 0x74, 0xdb, 0x3b, + 0x34, 0xa9, 0xb6, 0x3b, 0xe1, 0x8a, 0x81, 0x3b, 0x64, 0x61, 0x9f, 0x3b, 0x79, + 0x95, 0xf2, 0x3b, 0x52, 0xae, 0x1b, 0x3c, 0xea, 0x22, 0x99, 0x3b, 0xe8, 0x9a, + 0xd5, 0x3b, 0xd9, 0xf5, 0xc3, 0x3b, 0x97, 0x3f, 0xa7, 0x3b, 0xb4, 0xde, 0xce, + 0x3b, 0x6a, 0xb7, 0x99, 0x3b, 0x5d, 0x1b, 0xaa, 0x3b, 0x62, 0xe8, 0xdd, 0x3b, + 0x80, 0xe0, 0xea, 0x3b, 0x11, 0xf6, 0x32, 0x3c, 0xa1, 0xb3, 0xe0, 0x3b, 0x4b, + 0x55, 0x91, 0x3b, 0xf8, 0x58, 0x26, 0x3c, 0x51, 0x2e, 0xcd, 0x3b, 0xcb, 0xd4, + 0xa1, 0x3b, 0xdc, 0xca, 0xf7, 0x3b, 0xc8, 0x18, 0xcd, 0x3b, 0x65, 0x34, 0x09, + 0x3c, 0x27, 0x59, 0x9f, 0x3b, 0x34, 0x50, 0x89, 0x3b, 0xfa, 0x30, 0x0a, 0x3c, + 0xbd, 0xd9, 0xb7, 0x3b, 0x60, 0x79, 0xd8, 0x3b, 0x48, 0xf7, 0xea, 0x3b, 0x1c, + 0xe6, 0xdc, 0x3b, 0x0c, 0xb8, 0x8e, 0x3b, 0x26, 0xb3, 0xee, 0x3b, 0xae, 0x58, + 0xc2, 0x3b, 0xdb, 0x17, 0xca, 0x3b, 0x6b, 0xaa, 0xaf, 0x3b, 0x6d, 0xf2, 0xe1, + 0x3b, 0xa3, 0x39, 0x4b, 0x3c, 0x84, 0xcd, 0xb6, 0x3b, 0x4b, 0x1c, 0x9a, 0x3b, + 0x47, 0x1c, 0x1f, 0x3c, 0x83, 0xa4, 0xad, 0x3b, 0x5f, 0xc3, 0xdd, 0x3b, 0xc1, + 0xeb, 0x9c, 0x3b, 0xb6, 0xe6, 0xd5, 0x3b, 0x38, 0x08, 0x17, 0x3c, 0xc6, 0x98, + 0xf2, 0x3b, 0xe2, 0x24, 0xf1, 0x3b, 0x4c, 0x77, 0x46, 0x3c, 0x62, 0x8f, 0xa8, + 0x3b, 0x2d, 0x25, 0x02, 0x3c, 0x18, 0x5c, 0x89, 0x3b, 0x76, 0xa2, 0x9b, 0x3b, + 0x5b, 0x6d, 0x94, 0x3b, 0xfe, 0xf2, 0x10, 0x3c, 0x8b, 0x09, 0xde, 0x3b, 0x4a, + 0x1c, 0xd5, 0x3b, 0x11, 0xe4, 0xda, 0x3b, 0x1e, 0xa1, 0x90, 0x3b, 0x11, 0xa7, + 0xa4, 0x3b, 0x2c, 0x8c, 0x9c, 0x3b, 0xe4, 0x0d, 0xed, 0x3b, 0x3d, 0xb3, 0x8c, + 0x3b, 0x6a, 0xea, 0xa1, 0x3b, 0x9e, 0xcb, 0xe1, 0x3b, 0x2e, 0xdf, 0xea, 0x3b, + 0x87, 0xe0, 0xb6, 0x3b, 0x92, 0x5b, 0x16, 0x3c, 0xb6, 0x40, 0xb2, 0x3b, 0x77, + 0x64, 0xfa, 0x3b, 0x9f, 0xa9, 0xde, 0x3b, 0xc3, 0x27, 0x17, 0x3c, 0x38, 0xc3, + 0xe4, 0x3b, 0x2e, 0x3c, 0xa7, 0x3b, 0x67, 0x96, 0x91, 0x3b, 0xe8, 0x01, 0x9e, + 0x3b, 0x8a, 0x9e, 0x2d, 0x3c, 0x52, 0xae, 0x8f, 0x3b, 0xe2, 0xcb, 0x9e, 0x3b, + 0x2d, 0x22, 0x20, 0x3c, 0xf1, 0x72, 0x97, 0x3b, 0x3e, 0x6f, 0x35, 0x3c, 0x5a, + 0x72, 0xf1, 0x3b, 0x3a, 0x1f, 0xa7, 0x3b, 0x8a, 0x30, 0xad, 0x3b, 0x86, 0xd7, + 0xc8, 0x3b, 0x35, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x38, + 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xf2, 0x93, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x58, + 0x06, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x74, 0x9a, 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x69, 0x72, 0x15, + 0x3b, 0x7b, 0x2b, 0x6e, 0x3b, 0x0e, 0x7b, 0x3c, 0x3b, 0x82, 0xfa, 0x32, 0x3b, + 0x8e, 0x21, 0x15, 0x3b, 0xb7, 0x35, 0x12, 0x3b, 0x84, 0x7e, 0x16, 0x3b, 0x91, + 0xfe, 0x6f, 0x3b, 0xe3, 0xc4, 0x14, 0x3b, 0x38, 0xa8, 0x14, 0x3b, 0x5c, 0x34, + 0x8b, 0x3b, 0x9b, 0xf3, 0x51, 0x3b, 0xa0, 0xe2, 0x0f, 0x3b, 0x26, 0x0f, 0x38, + 0x3b, 0xaa, 0x48, 0x3b, 0x3b, 0x97, 0x55, 0x32, 0x3b, 0xb9, 0x5d, 0x13, 0x3b, + 0x5e, 0x54, 0x4d, 0x3b, 0x8b, 0x64, 0x48, 0x3b, 0xfc, 0x34, 0x2f, 0x3b, 0x8e, + 0x96, 0x3e, 0x3b, 0x2f, 0x44, 0x2b, 0x3b, 0xf1, 0x0c, 0x1a, 0x3b, 0xaf, 0xb5, + 0x3d, 0x3b, 0x74, 0xc8, 0x47, 0x3b, 0x81, 0x75, 0x4a, 0x3b, 0xe5, 0x54, 0x04, + 0x3b, 0xdd, 0xeb, 0x27, 0x3b, 0x65, 0x52, 0x07, 0x3b, 0x7a, 0xd4, 0x2e, 0x3b, + 0x34, 0x82, 0x2d, 0x3b, 0x98, 0x18, 0x4f, 0x3b, 0x9d, 0x4d, 0x19, 0x3b, 0x8f, + 0x04, 0x31, 0x3b, 0x5d, 0x44, 0x1e, 0x3b, 0x66, 0x57, 0x75, 0x3b, 0x22, 0x5d, + 0x31, 0x3b, 0x83, 0x6d, 0x00, 0x3b, 0x07, 0x31, 0x35, 0x3b, 0xbb, 0x4a, 0x21, + 0x3b, 0x02, 0xd8, 0x67, 0x3b, 0xff, 0x57, 0x52, 0x3b, 0xa6, 0x70, 0x24, 0x3b, + 0xea, 0xb4, 0x24, 0x3b, 0x9d, 0x41, 0x2e, 0x3b, 0xe5, 0xa3, 0x1c, 0x3b, 0x01, + 0x17, 0x25, 0x3b, 0x09, 0x5b, 0x39, 0x3b, 0x14, 0x47, 0x38, 0x3b, 0xe8, 0xb3, + 0x31, 0x3b, 0x5e, 0xc4, 0x0a, 0x3b, 0x07, 0xf2, 0x3a, 0x3b, 0xa1, 0x56, 0x0e, + 0x3b, 0x08, 0x08, 0x11, 0x3b, 0xb8, 0xf8, 0x16, 0x3b, 0x1e, 0xcb, 0x1b, 0x3b, + 0xf4, 0xb4, 0x11, 0x3b, 0x18, 0xed, 0x0f, 0x3b, 0x15, 0x9f, 0x0d, 0x3b, 0xa1, + 0xa1, 0x4c, 0x3b, 0x54, 0xc1, 0x45, 0x3b, 0x22, 0x52, 0xf8, 0x3a, 0x3c, 0xf0, + 0x18, 0x3b, 0x44, 0x4e, 0x1b, 0x3b, 0xb3, 0xe2, 0x42, 0x3b, 0x88, 0x59, 0x30, + 0x3b, 0x73, 0x95, 0x4f, 0x3b, 0xbb, 0x01, 0x15, 0x3b, 0xcd, 0x24, 0x31, 0x3b, + 0xf2, 0x02, 0x27, 0x3b, 0x99, 0xce, 0x56, 0x3b, 0x09, 0x4d, 0x3a, 0x3b, 0xbe, + 0xeb, 0x35, 0x3b, 0xb7, 0x9d, 0x2b, 0x3b, 0x7d, 0xa8, 0x46, 0x3b, 0xea, 0xe9, + 0x4a, 0x3b, 0xb1, 0xa8, 0x4e, 0x3b, 0x25, 0x29, 0x2a, 0x3b, 0x61, 0x04, 0x2c, + 0x3b, 0xaf, 0x65, 0x28, 0x3b, 0xdc, 0x84, 0x6c, 0x3b, 0x77, 0x23, 0x30, 0x3b, + 0xc8, 0x82, 0x26, 0x3b, 0x70, 0xe0, 0x33, 0x3b, 0x71, 0xbe, 0x43, 0x3b, 0x3c, + 0xa3, 0x4b, 0x3b, 0x53, 0xda, 0xfe, 0x3a, 0x5a, 0x12, 0x02, 0x3b, 0xc8, 0xf3, + 0x17, 0x3b, 0x4e, 0x5a, 0x29, 0x3b, 0xc8, 0x4c, 0x1d, 0x3b, 0x4b, 0xde, 0x3f, + 0x3b, 0xf6, 0x54, 0x0f, 0x3b, 0x85, 0x17, 0x26, 0x3b, 0xa8, 0x0a, 0x6a, 0x3b, + 0x96, 0x03, 0x32, 0x3b, 0xfa, 0x3e, 0x04, 0x3b, 0x34, 0x14, 0x1b, 0x3b, 0xb4, + 0x0e, 0x89, 0x3b, 0x99, 0xe1, 0x11, 0x3b, 0xaa, 0x64, 0x4c, 0x3b, 0x2d, 0x09, + 0x14, 0x3b, 0xe1, 0xe1, 0x53, 0x3b, 0xac, 0x96, 0x37, 0x3b, 0xd6, 0xe7, 0x2d, + 0x3b, 0xe9, 0x42, 0x27, 0x3b, 0xf9, 0x41, 0x1f, 0x3b, 0x05, 0xb8, 0x46, 0x3b, + 0x37, 0x95, 0x11, 0x3b, 0xe6, 0x89, 0x1d, 0x3b, 0xee, 0x61, 0x11, 0x3b, 0xac, + 0x0a, 0x48, 0x3b, 0x50, 0xad, 0x87, 0x3b, 0x7c, 0x67, 0x05, 0x3b, 0x59, 0x7b, + 0xf7, 0x3a, 0xcd, 0xce, 0x0e, 0x3b, 0x2b, 0x8b, 0x7f, 0x3b, 0x13, 0x6a, 0x06, + 0x3b, 0x0c, 0x0e, 0x1f, 0x3b, 0x9d, 0x29, 0x51, 0x3b, 0xb0, 0xc8, 0x1e, 0x3b, + 0x42, 0x82, 0x3d, 0x3b, 0x76, 0x28, 0x21, 0x3b, 0x00, 0x00, 0x2e, 0x3b, 0x37, + 0xd8, 0x11, 0x3b, 0xeb, 0xf0, 0x36, 0x3b, 0x08, 0x7f, 0x4f, 0x3b, 0xbb, 0xb5, + 0x37, 0x3b, 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x37, + 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x66, 0x9a, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x68, 0x06, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xc2, 0x93, 0xff, 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x63, 0x1a, 0x98, 0x3b, 0xf0, 0xca, 0xdf, 0x3b, 0x6a, 0x36, 0xdc, + 0x3b, 0x7a, 0x8b, 0x16, 0x3c, 0xd6, 0xce, 0xf4, 0x3b, 0xef, 0x99, 0x74, 0x3b, + 0xcd, 0x1e, 0xb4, 0x3b, 0x29, 0xd1, 0x16, 0x3c, 0x55, 0xbd, 0xbe, 0x3b, 0xa3, + 0xf3, 0xb9, 0x3b, 0x43, 0xb1, 0x0a, 0x3c, 0x9e, 0x35, 0x09, 0x3c, 0xc9, 0xd2, + 0x31, 0x3c, 0x99, 0xed, 0x8a, 0x3c, 0x32, 0x87, 0xc2, 0x3b, 0x50, 0x41, 0xee, + 0x3b, 0x20, 0x90, 0x16, 0x3c, 0x65, 0x1b, 0x17, 0x3c, 0xa5, 0xc8, 0xf6, 0x3b, + 0x64, 0x68, 0x4e, 0x3c, 0xda, 0x71, 0x2a, 0x3c, 0x00, 0xd8, 0x0b, 0x3c, 0x3e, + 0x58, 0x22, 0x3c, 0x9b, 0x30, 0xb6, 0x3b, 0x7c, 0x9a, 0x82, 0x3b, 0x52, 0x52, + 0xd6, 0x3b, 0xfe, 0xe9, 0xc3, 0x3b, 0x5f, 0x56, 0x06, 0x3c, 0xef, 0xa4, 0xd4, + 0x3b, 0x97, 0x95, 0x1f, 0x3c, 0xc2, 0x46, 0x9b, 0x3b, 0xcc, 0x44, 0xc6, 0x3b, + 0xa7, 0xc1, 0xaf, 0x3b, 0x02, 0x07, 0xf0, 0x3b, 0xc1, 0xcf, 0xe5, 0x3b, 0x71, + 0x1c, 0x14, 0x3c, 0x7d, 0xff, 0xb3, 0x3b, 0xa4, 0xb6, 0xf3, 0x3b, 0xf4, 0x81, + 0xda, 0x3b, 0xab, 0xa7, 0xbb, 0x3b, 0xef, 0xd8, 0xc9, 0x3b, 0xa1, 0x31, 0x02, + 0x3c, 0x71, 0xfb, 0xc1, 0x3b, 0x91, 0xd6, 0xc2, 0x3b, 0x67, 0x8b, 0xcf, 0x3b, + 0xc8, 0x0b, 0x8f, 0x3b, 0xbf, 0x2e, 0xdb, 0x3b, 0x70, 0xe7, 0x1e, 0x3c, 0x08, + 0x47, 0x25, 0x3c, 0xd4, 0xe6, 0xeb, 0x3b, 0x60, 0xf5, 0xcd, 0x3b, 0xde, 0xca, + 0x00, 0x3c, 0xbb, 0x22, 0xd0, 0x3b, 0xd5, 0x0d, 0xc4, 0x3b, 0x5c, 0x68, 0xbb, + 0x3b, 0x92, 0x93, 0xb2, 0x3b, 0x77, 0x86, 0xfa, 0x3b, 0x11, 0x85, 0x27, 0x3c, + 0x14, 0x4d, 0xd7, 0x3b, 0x49, 0x13, 0xeb, 0x3b, 0x56, 0x35, 0x0c, 0x3c, 0xcc, + 0x92, 0xae, 0x3b, 0x36, 0x68, 0x2f, 0x3c, 0x52, 0xaf, 0x4c, 0x3c, 0xa0, 0xd9, + 0xad, 0x3b, 0x49, 0x40, 0x93, 0x3b, 0xfa, 0x40, 0x27, 0x3c, 0x35, 0xcd, 0xb1, + 0x3b, 0xa4, 0xaa, 0xdb, 0x3b, 0x45, 0xfa, 0x01, 0x3c, 0xc4, 0x09, 0x97, 0x3b, + 0x2d, 0x12, 0x1e, 0x3c, 0x80, 0xf7, 0xf2, 0x3b, 0x0e, 0xee, 0xd1, 0x3b, 0x93, + 0xc7, 0x3e, 0x3c, 0xa5, 0xc5, 0x78, 0x3c, 0x81, 0xa1, 0xcd, 0x3b, 0x95, 0x7f, + 0x84, 0x3b, 0xac, 0xfb, 0xc0, 0x3b, 0x7b, 0x9e, 0xc9, 0x3b, 0xb4, 0x94, 0x0e, + 0x3c, 0xbe, 0x02, 0x24, 0x3c, 0x26, 0xaf, 0x03, 0x3c, 0x1d, 0x55, 0xb6, 0x3b, + 0x84, 0x0c, 0xa4, 0x3b, 0xe1, 0x22, 0xf5, 0x3b, 0xaf, 0xf6, 0x16, 0x3c, 0xf4, + 0x0e, 0x02, 0x3c, 0x8f, 0x59, 0xb8, 0x3b, 0x5a, 0x77, 0x81, 0x3c, 0xa0, 0x61, + 0x03, 0x3c, 0xdf, 0x05, 0xbc, 0x3b, 0x56, 0x04, 0xc6, 0x3b, 0x8d, 0x0b, 0xc2, + 0x3b, 0x34, 0xd6, 0xd1, 0x3b, 0x06, 0xd9, 0xf0, 0x3b, 0xc8, 0x23, 0x01, 0x3c, + 0x8d, 0x16, 0x17, 0x3c, 0x01, 0x15, 0xaa, 0x3b, 0x1e, 0x97, 0x1b, 0x3c, 0x01, + 0x15, 0xde, 0x3b, 0x84, 0x0b, 0xd7, 0x3b, 0x61, 0x98, 0x24, 0x3c, 0x52, 0x21, + 0xa2, 0x3b, 0x00, 0x53, 0xab, 0x3b, 0xca, 0x54, 0xc5, 0x3b, 0x2f, 0xf5, 0xf1, + 0x3b, 0x72, 0x53, 0x8f, 0x3b, 0x73, 0xbd, 0xca, 0x3b, 0x3c, 0x53, 0x13, 0x3c, + 0xa8, 0x4d, 0x45, 0x3c, 0xd9, 0x26, 0x5a, 0x3c, 0xb7, 0xf1, 0xbf, 0x3b, 0x0f, + 0xa2, 0x3e, 0x3c, 0x6e, 0xb5, 0xd3, 0x3b, 0x30, 0xa8, 0x3c, 0x3c, 0x1c, 0xfc, + 0xcd, 0x3b, 0x0c, 0x94, 0x1d, 0x3c, 0x09, 0x92, 0xdb, 0x3b, 0xcc, 0xad, 0x1f, + 0x3c, 0x6e, 0x27, 0xf6, 0x3b, 0x01, 0x23, 0x89, 0x3b, 0x57, 0xa7, 0x9b, 0x3b, + 0x23, 0x4a, 0x95, 0x3b, 0x53, 0x0b, 0x1a, 0x3c, 0xa6, 0x56, 0x00, 0x3c, 0x3c, + 0x50, 0x08, 0x3c, 0xd0, 0x0e, 0x91, 0x3b, 0x35, 0x00, 0x00, 0x00, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x37, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xea, 0xa0, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x58, 0x06, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, + 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6c, 0xa7, 0xff, 0xff, 0x10, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0xdb, 0x16, 0x77, 0x3b, 0x81, 0x65, 0x4c, 0x3b, 0xe0, 0x30, 0xbc, + 0x3b, 0x34, 0x9a, 0x7d, 0x3b, 0xad, 0x5a, 0x4b, 0x3b, 0x64, 0xaf, 0x9d, 0x3b, + 0x60, 0xcb, 0x1d, 0x3b, 0x9d, 0xf2, 0x52, 0x3b, 0xef, 0x67, 0x91, 0x3b, 0x2c, + 0xc1, 0x5e, 0x3b, 0x8d, 0x8e, 0x4b, 0x3b, 0x3e, 0x7a, 0x8d, 0x3b, 0x64, 0x7e, + 0x32, 0x3b, 0x35, 0x8d, 0xf5, 0x3a, 0x39, 0x88, 0x28, 0x3b, 0x69, 0x08, 0x39, + 0x3b, 0xb7, 0xa5, 0x35, 0x3b, 0x0e, 0x28, 0x46, 0x3b, 0x77, 0x11, 0x79, 0x3b, + 0xbf, 0x20, 0x29, 0x3b, 0xd0, 0x29, 0x67, 0x3b, 0xff, 0x3c, 0x32, 0x3b, 0x0c, + 0x5f, 0x83, 0x3b, 0x00, 0x82, 0x87, 0x3b, 0x1c, 0x6d, 0x8f, 0x3b, 0xa2, 0xdc, + 0x3d, 0x3b, 0xd5, 0xd2, 0x58, 0x3b, 0xa0, 0x0d, 0x70, 0x3b, 0x13, 0x09, 0x4f, + 0x3b, 0x7e, 0x45, 0x86, 0x3b, 0x87, 0xbe, 0x65, 0x3b, 0xa3, 0x41, 0x44, 0x3b, + 0x85, 0x42, 0x6e, 0x3b, 0xdd, 0x83, 0x39, 0x3b, 0x70, 0xaf, 0x32, 0x3b, 0x93, + 0x27, 0x2e, 0x3b, 0x90, 0x79, 0x4f, 0x3b, 0x1b, 0x55, 0xf1, 0x3a, 0x88, 0x75, + 0x5d, 0x3b, 0x82, 0x71, 0x7c, 0x3b, 0xe2, 0x39, 0x83, 0x3b, 0x48, 0xba, 0x5d, + 0x3b, 0x93, 0x01, 0x46, 0x3b, 0xb6, 0xf1, 0x62, 0x3b, 0x46, 0xcc, 0x84, 0x3b, + 0x28, 0xbe, 0x05, 0x3b, 0xf6, 0x0c, 0x5a, 0x3b, 0x29, 0xbb, 0x5f, 0x3b, 0xaa, + 0x38, 0x17, 0x3b, 0x37, 0xeb, 0x20, 0x3b, 0x94, 0xee, 0x80, 0x3b, 0x88, 0xe9, + 0x6a, 0x3b, 0x62, 0x9f, 0x5c, 0x3b, 0x5b, 0x1e, 0x62, 0x3b, 0x3d, 0xa8, 0x46, + 0x3b, 0x9e, 0x8c, 0x49, 0x3b, 0x0a, 0x98, 0x72, 0x3b, 0x72, 0x54, 0x5b, 0x3b, + 0xfc, 0x37, 0x2f, 0x3b, 0x56, 0x08, 0x05, 0x3b, 0xfb, 0xd2, 0x44, 0x3b, 0x4f, + 0x12, 0x38, 0x3b, 0xf8, 0x62, 0x2e, 0x3b, 0xba, 0x67, 0x48, 0x3b, 0x02, 0xbc, + 0x61, 0x3b, 0xf7, 0x01, 0x5d, 0x3b, 0x80, 0xde, 0x24, 0x3b, 0x0f, 0xf2, 0x9b, + 0x3b, 0x33, 0xb9, 0x44, 0x3b, 0xe4, 0xc4, 0x41, 0x3b, 0x5e, 0x1e, 0x4a, 0x3b, + 0x20, 0x04, 0x13, 0x3b, 0x37, 0x3a, 0x5a, 0x3b, 0x5c, 0x35, 0x52, 0x3b, 0x0d, + 0xf3, 0x4a, 0x3b, 0x57, 0xf5, 0x06, 0x3b, 0x9f, 0xdf, 0x25, 0x3b, 0x8c, 0x98, + 0x35, 0x3b, 0xd5, 0x98, 0x33, 0x3b, 0x8c, 0x82, 0x30, 0x3b, 0xaa, 0x7a, 0x60, + 0x3b, 0x3a, 0x6b, 0x51, 0x3b, 0x24, 0xdf, 0x7c, 0x3b, 0xe8, 0xe2, 0x4a, 0x3b, + 0xca, 0x46, 0x43, 0x3b, 0x7f, 0x20, 0x50, 0x3b, 0x6b, 0x23, 0x17, 0x3b, 0x89, + 0xcb, 0x49, 0x3b, 0x85, 0x69, 0x40, 0x3b, 0x70, 0x71, 0x22, 0x3b, 0x41, 0x72, + 0x73, 0x3b, 0x43, 0xf2, 0x29, 0x3b, 0xb4, 0xa5, 0x5d, 0x3b, 0x6f, 0xfb, 0x21, + 0x3b, 0x37, 0x81, 0x88, 0x3b, 0x38, 0xc1, 0x24, 0x3b, 0xec, 0x46, 0x1d, 0x3b, + 0xd5, 0x05, 0x7b, 0x3b, 0xfa, 0xad, 0x49, 0x3b, 0x38, 0x00, 0x5c, 0x3b, 0x42, + 0xa2, 0x82, 0x3b, 0xca, 0x7f, 0x87, 0x3b, 0xf8, 0xf8, 0x5e, 0x3b, 0xa9, 0xa1, + 0x72, 0x3b, 0xdd, 0x61, 0x67, 0x3b, 0xc2, 0xe2, 0x20, 0x3b, 0x3d, 0x06, 0x35, + 0x3b, 0x6a, 0x6f, 0x48, 0x3b, 0x49, 0x28, 0x4b, 0x3b, 0x13, 0x71, 0x5b, 0x3b, + 0x57, 0x39, 0x70, 0x3b, 0x3f, 0x6c, 0x08, 0x3b, 0x99, 0xc7, 0x41, 0x3b, 0x64, + 0x48, 0x45, 0x3b, 0x02, 0x34, 0x35, 0x3b, 0x8f, 0x25, 0x51, 0x3b, 0xc4, 0xfe, + 0x5a, 0x3b, 0x8e, 0xa5, 0x1e, 0x3b, 0xb6, 0xc5, 0x3a, 0x3b, 0x33, 0xad, 0xfb, + 0x3a, 0x2b, 0xce, 0x43, 0x3b, 0xf4, 0xa4, 0x1d, 0x3b, 0xbf, 0xd2, 0x4e, 0x3b, + 0xeb, 0x6a, 0x92, 0x3b, 0x17, 0xe4, 0x89, 0x3b, 0xa8, 0x88, 0x28, 0x3b, 0x04, + 0x1c, 0x55, 0x3b, 0x98, 0xc7, 0x46, 0x3b, 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x36, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x5e, 0xa7, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x09, 0x68, 0x03, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x24, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xba, 0xa0, 0xff, 0xff, 0x14, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x01, 0xb0, 0x90, 0x3b, 0xe7, 0x75, 0x88, 0x3b, 0xda, 0xf6, 0x64, + 0x3b, 0xf3, 0xa3, 0x78, 0x3b, 0xae, 0xc0, 0x3c, 0x3b, 0x98, 0xf3, 0x41, 0x3b, + 0x75, 0xe2, 0xa1, 0x3b, 0x49, 0xfe, 0x7a, 0x3b, 0x71, 0x95, 0x77, 0x3b, 0x26, + 0xd0, 0xb1, 0x3b, 0x93, 0xf9, 0x76, 0x3b, 0x29, 0x45, 0x87, 0x3b, 0x9a, 0x05, + 0x89, 0x3b, 0x2c, 0xf3, 0x7f, 0x3b, 0x9b, 0xd5, 0x7b, 0x3b, 0xd2, 0x29, 0xf3, + 0x3b, 0xf1, 0x7e, 0x6c, 0x3b, 0x99, 0xf1, 0x1c, 0x3c, 0x86, 0x53, 0x73, 0x3b, + 0x38, 0x28, 0x8f, 0x3b, 0xbe, 0x20, 0x64, 0x3b, 0xb5, 0x96, 0x82, 0x3b, 0x84, + 0x0a, 0xb7, 0x3b, 0xa5, 0xa4, 0x5b, 0x3b, 0x1b, 0x96, 0x9d, 0x3b, 0x12, 0x99, + 0x6f, 0x3b, 0xa0, 0xcd, 0x94, 0x3b, 0x62, 0x2c, 0x7f, 0x3b, 0x90, 0x6c, 0x7e, + 0x3b, 0xdc, 0xc6, 0x95, 0x3b, 0xcd, 0x97, 0x62, 0x3b, 0x8a, 0xf8, 0x80, 0x3b, + 0x53, 0x91, 0x64, 0x3b, 0xf9, 0xb9, 0x70, 0x3b, 0x93, 0x39, 0xf7, 0x3b, 0xe4, + 0x72, 0xac, 0x3b, 0x29, 0x52, 0x95, 0x3b, 0x01, 0xf7, 0x98, 0x3b, 0x7a, 0xce, + 0x4a, 0x3b, 0xb9, 0x52, 0x50, 0x3b, 0x6e, 0x9f, 0x71, 0x3b, 0x03, 0x4a, 0xa8, + 0x3b, 0x34, 0xdc, 0xa3, 0x3b, 0xd3, 0xad, 0x93, 0x3b, 0xe2, 0x45, 0x63, 0x3b, + 0xa6, 0x4a, 0x93, 0x3b, 0x3a, 0x6b, 0x54, 0x3b, 0xd9, 0x9f, 0x97, 0x3b, 0xef, + 0x53, 0x77, 0x3b, 0x87, 0x02, 0x8b, 0x3b, 0x8b, 0xd4, 0x33, 0x3b, 0x1b, 0x36, + 0x99, 0x3b, 0x90, 0x19, 0xcd, 0x3b, 0xda, 0x5d, 0xc1, 0x3b, 0x5d, 0xee, 0x68, + 0x3b, 0x7d, 0x5b, 0x83, 0x3b, 0x30, 0x76, 0xd9, 0x3b, 0xb6, 0x23, 0x83, 0x3b, + 0x57, 0xdd, 0x45, 0x3b, 0xfc, 0xdc, 0x47, 0x3b, 0x90, 0x3f, 0x3d, 0x3b, 0x20, + 0x3a, 0x8e, 0x3b, 0x35, 0x03, 0x88, 0x3b, 0xe1, 0xf2, 0xd9, 0x3b, 0x35, 0x00, + 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x36, 0x5f, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, + 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, + 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xe2, 0xaa, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x58, 0x03, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0xb1, + 0xff, 0xff, 0x10, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0xa4, 0xc8, 0x2b, 0x3b, 0x4e, 0x6a, 0x7a, 0x3b, 0x4b, 0x5c, 0x8d, 0x3b, + 0x1a, 0x86, 0xa4, 0x3b, 0x9d, 0x00, 0x62, 0x3b, 0x17, 0x46, 0x39, 0x3b, 0xc4, + 0xca, 0x6a, 0x3b, 0x39, 0x91, 0x59, 0x3b, 0x38, 0xdf, 0x8d, 0x3b, 0x6b, 0x33, + 0x81, 0x3b, 0x7e, 0x86, 0x7e, 0x3b, 0xbc, 0x51, 0x61, 0x3b, 0x39, 0xea, 0x80, + 0x3b, 0x43, 0x3c, 0x1f, 0x3b, 0x4e, 0xb7, 0xa8, 0x3b, 0x64, 0x51, 0x0f, 0x3b, + 0xf8, 0x3f, 0x81, 0x3b, 0xe5, 0x7b, 0x10, 0x3b, 0x4d, 0x5b, 0x28, 0x3b, 0x8e, + 0xe7, 0x97, 0x3b, 0xb4, 0xef, 0x6f, 0x3b, 0xc2, 0xd6, 0x55, 0x3b, 0x89, 0x56, + 0x6a, 0x3b, 0x44, 0xc6, 0x70, 0x3b, 0xb4, 0x0a, 0x2c, 0x3b, 0xc6, 0xc2, 0x1c, + 0x3b, 0x4b, 0xb3, 0x9b, 0x3b, 0x8c, 0x98, 0x61, 0x3b, 0x98, 0x37, 0x90, 0x3b, + 0x51, 0xaa, 0x5b, 0x3b, 0x32, 0x7e, 0x81, 0x3b, 0x90, 0x3e, 0x5d, 0x3b, 0x34, + 0x88, 0x41, 0x3b, 0x78, 0x6b, 0x59, 0x3b, 0xeb, 0xb0, 0x4c, 0x3b, 0x3c, 0x78, + 0x3c, 0x3b, 0xcb, 0x77, 0x58, 0x3b, 0x77, 0x8c, 0x16, 0x3b, 0xbb, 0xad, 0x2c, + 0x3b, 0xc3, 0x8c, 0x8b, 0x3b, 0x26, 0xb3, 0x82, 0x3b, 0xd6, 0x40, 0x6a, 0x3b, + 0x8e, 0xe1, 0x38, 0x3b, 0x7e, 0xd5, 0x6e, 0x3b, 0x10, 0xe0, 0x74, 0x3b, 0xc5, + 0x58, 0x60, 0x3b, 0xf5, 0xaa, 0x3b, 0x3b, 0xbd, 0xde, 0x1c, 0x3b, 0xe8, 0xcc, + 0x45, 0x3b, 0xbf, 0x14, 0xfb, 0x3a, 0x37, 0xe0, 0x67, 0x3b, 0xc4, 0xe3, 0x8d, + 0x3b, 0xf7, 0xbe, 0xca, 0x3a, 0xdb, 0x1a, 0x0e, 0x3b, 0xb8, 0xa4, 0x6a, 0x3b, + 0x4b, 0xa5, 0x59, 0x3b, 0x90, 0xf5, 0x4f, 0x3b, 0xbc, 0xdd, 0x6a, 0x3b, 0x9d, + 0x26, 0x66, 0x3b, 0x28, 0x0d, 0x5e, 0x3b, 0x58, 0xa2, 0x7e, 0x3b, 0x86, 0x80, + 0x83, 0x3b, 0x03, 0x4a, 0x14, 0x3b, 0xf4, 0xda, 0x12, 0x3b, 0x2b, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x35, 0x5f, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x56, 0xae, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x68, 0x03, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x24, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb2, 0xa7, + 0xff, 0xff, 0x14, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0xaf, 0x6d, 0xa7, 0x3b, 0x6f, 0xfb, 0x1a, 0x3c, + 0x4f, 0x65, 0xf0, 0x3b, 0x64, 0x5c, 0xf6, 0x3b, 0xd1, 0xef, 0x18, 0x3c, 0x0b, + 0xb1, 0x8f, 0x3b, 0xd0, 0x97, 0xb1, 0x3b, 0x49, 0xed, 0x48, 0x3b, 0xc5, 0x55, + 0x50, 0x3c, 0xff, 0xff, 0x6c, 0x3c, 0x09, 0x61, 0x8d, 0x3c, 0xd3, 0xcb, 0x17, + 0x3c, 0x51, 0x94, 0x14, 0x3c, 0xb9, 0xd6, 0x7c, 0x3b, 0xd5, 0xff, 0xd5, 0x3b, + 0x69, 0x20, 0x00, 0x3c, 0x8b, 0x38, 0xbe, 0x3b, 0xa6, 0xe9, 0x9a, 0x3b, 0x9a, + 0xea, 0xd7, 0x3b, 0xd0, 0x5e, 0x9d, 0x3b, 0xfa, 0x04, 0x95, 0x3b, 0x76, 0xe1, + 0xc0, 0x3b, 0xc1, 0x6e, 0x8b, 0x3c, 0xf0, 0x34, 0xcb, 0x3b, 0xca, 0x60, 0xb1, + 0x3b, 0x79, 0xa5, 0x64, 0x3c, 0x3b, 0x85, 0x38, 0x3c, 0xe2, 0x8a, 0x95, 0x3b, + 0xec, 0xbb, 0xc0, 0x3b, 0xfb, 0xa3, 0xe9, 0x3b, 0x14, 0x3d, 0xb1, 0x3b, 0x1d, + 0x89, 0xe8, 0x3b, 0x06, 0x7a, 0x8b, 0x3b, 0x2f, 0x32, 0xb6, 0x3b, 0xcc, 0x2e, + 0xd7, 0x3b, 0x32, 0xc7, 0x68, 0x3b, 0xd7, 0x22, 0x33, 0x3c, 0x1e, 0x40, 0x42, + 0x3c, 0x6e, 0xb4, 0xb6, 0x3b, 0x28, 0x77, 0xb0, 0x3b, 0x49, 0xaa, 0xed, 0x3b, + 0x4f, 0x78, 0xe2, 0x3b, 0x85, 0xe9, 0x23, 0x3c, 0x5e, 0xe9, 0xd9, 0x3b, 0x6d, + 0xab, 0x7a, 0x3b, 0x21, 0x29, 0x5f, 0x3b, 0xb7, 0x50, 0x3e, 0x3c, 0xf7, 0xc3, + 0x84, 0x3b, 0x18, 0x38, 0x2b, 0x3c, 0x01, 0x11, 0x12, 0x3c, 0x78, 0xe8, 0xf3, + 0x3b, 0x7d, 0x96, 0x0d, 0x3c, 0xb6, 0x66, 0x56, 0x3c, 0x79, 0x61, 0xb3, 0x3b, + 0xea, 0x0d, 0x92, 0x3b, 0xb3, 0xe3, 0xa9, 0x3b, 0xe0, 0xc5, 0x0c, 0x3c, 0xce, + 0x38, 0xc8, 0x3b, 0xb8, 0x38, 0x9b, 0x3b, 0x23, 0x35, 0xa1, 0x3b, 0x5e, 0x18, + 0x4a, 0x3c, 0x63, 0x54, 0x8a, 0x3b, 0x17, 0xe9, 0xb7, 0x3b, 0xfa, 0x64, 0x3d, + 0x3c, 0x35, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x35, 0x5f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0xda, 0xb1, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x58, 0x03, + 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x5c, 0xb8, 0xff, 0xff, 0x10, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x9e, 0x9c, 0x8a, 0x3b, 0xa1, 0xfb, 0x2f, 0x3b, 0x08, + 0x09, 0xa5, 0x3b, 0xf9, 0xb5, 0x8a, 0x3b, 0x37, 0xe2, 0x55, 0x3b, 0x57, 0x24, + 0x72, 0x3b, 0x09, 0xef, 0x9f, 0x3b, 0xa9, 0xe2, 0x83, 0x3b, 0x95, 0x08, 0x35, + 0x3b, 0x15, 0x8c, 0x8c, 0x3b, 0xb7, 0x43, 0x15, 0x3b, 0xa3, 0xf2, 0x9f, 0x3b, + 0xed, 0xf3, 0x33, 0x3b, 0x8a, 0x02, 0x8a, 0x3b, 0xcc, 0xf5, 0xad, 0x3b, 0x31, + 0x32, 0x03, 0x3c, 0x5c, 0x78, 0x87, 0x3b, 0x97, 0xb7, 0x82, 0x3b, 0xae, 0xbb, + 0x8c, 0x3b, 0x1a, 0x38, 0x3c, 0x3b, 0xf6, 0xc9, 0xe6, 0x3b, 0xa1, 0x15, 0x54, + 0x3b, 0x80, 0x78, 0x5c, 0x3b, 0xec, 0x30, 0xc3, 0x3b, 0x58, 0x81, 0xba, 0x3b, + 0x74, 0x73, 0xe2, 0x3a, 0x5c, 0x1b, 0x2e, 0x3b, 0x52, 0x39, 0xd7, 0x3b, 0x96, + 0xb9, 0xb3, 0x3b, 0x71, 0x24, 0x83, 0x3b, 0x20, 0x23, 0x8a, 0x3b, 0x48, 0xf7, + 0xc2, 0x3b, 0x4d, 0x5e, 0xaa, 0x3b, 0x32, 0x14, 0x22, 0x3b, 0x6a, 0x7e, 0x6e, + 0x3b, 0x2e, 0x1c, 0xdf, 0x3b, 0x54, 0x42, 0x1e, 0x3b, 0x46, 0x10, 0x24, 0x3b, + 0x0a, 0xad, 0x6f, 0x3b, 0x22, 0x6a, 0x35, 0x3b, 0xc4, 0x9b, 0x5f, 0x3b, 0xfd, + 0xd4, 0x8d, 0x3b, 0x7e, 0xed, 0x53, 0x3b, 0x09, 0xdb, 0x8e, 0x3b, 0xbd, 0xad, + 0xce, 0x3b, 0xf2, 0xa0, 0xd0, 0x3b, 0xea, 0x53, 0x06, 0x3b, 0xc8, 0x51, 0x71, + 0x3b, 0x76, 0x51, 0xad, 0x3b, 0x21, 0x81, 0x0c, 0x3c, 0x3a, 0x8c, 0x04, 0x3c, + 0xa8, 0xbe, 0x8f, 0x3b, 0x4f, 0xc3, 0x8d, 0x3b, 0x9e, 0x1c, 0x09, 0x3c, 0x17, + 0x93, 0xac, 0x3b, 0x67, 0x90, 0x98, 0x3b, 0x7d, 0x65, 0x54, 0x3b, 0x7b, 0x0d, + 0xd5, 0x3b, 0x42, 0x1c, 0x92, 0x3b, 0xec, 0x41, 0xa6, 0x3b, 0x4a, 0x0f, 0x42, + 0x3b, 0x5c, 0x69, 0xfd, 0x3b, 0xd2, 0x9d, 0xbb, 0x3b, 0x0a, 0xbb, 0x48, 0x3b, + 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, + 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x34, 0x5f, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x4e, 0xb5, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xe8, 0x01, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0xaa, 0xae, 0xff, 0xff, 0x14, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0e, + 0xe8, 0x3a, 0x3b, 0x06, 0xdb, 0x60, 0x3b, 0x15, 0xab, 0x2c, 0x3b, 0xc2, 0x4d, + 0x69, 0x3b, 0xed, 0xe2, 0x03, 0x3c, 0xf7, 0x38, 0x87, 0x3b, 0x43, 0xca, 0x46, + 0x3b, 0x75, 0x5e, 0x48, 0x3b, 0x1b, 0xa8, 0x47, 0x3b, 0x1a, 0x27, 0x1a, 0x3b, + 0xfa, 0xaa, 0x64, 0x3b, 0xd7, 0x95, 0x46, 0x3b, 0x29, 0x74, 0x8d, 0x3b, 0x56, + 0x3a, 0xdf, 0x3b, 0xfc, 0xdf, 0x93, 0x3b, 0x2a, 0xd8, 0x59, 0x3b, 0x3a, 0x2c, + 0x4d, 0x3b, 0x06, 0xa2, 0x3e, 0x3b, 0x56, 0xe5, 0xa0, 0x3b, 0x7c, 0x42, 0x51, + 0x3b, 0x36, 0x2c, 0x9f, 0x3b, 0x6f, 0xd4, 0x8f, 0x3b, 0x01, 0x77, 0x07, 0x3b, + 0x5a, 0xfa, 0x65, 0x3b, 0x61, 0xc0, 0xe2, 0x3b, 0x7d, 0xea, 0x78, 0x3b, 0x3d, + 0x98, 0x57, 0x3b, 0x13, 0x7d, 0x40, 0x3b, 0x60, 0xdc, 0x9b, 0x3b, 0x92, 0x50, + 0x5e, 0x3b, 0x09, 0xc6, 0x90, 0x3b, 0xe0, 0x52, 0xd7, 0x3b, 0x35, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x34, 0x5f, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x52, + 0xb7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xd8, 0x01, 0x00, 0x00, 0x21, 0x00, + 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd4, 0xbd, 0xff, + 0xff, 0x10, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x1f, 0xd1, 0x8d, 0x3b, 0x4a, 0xc4, 0xc6, 0x3b, 0x9e, + 0xc2, 0xa2, 0x3b, 0x50, 0x27, 0x83, 0x3b, 0x8f, 0xb4, 0x09, 0x3b, 0xa4, 0x9e, + 0x3b, 0x3b, 0x8d, 0xe0, 0x73, 0x3b, 0x54, 0x0e, 0x5f, 0x3b, 0xa8, 0xd7, 0xa1, + 0x3b, 0x7f, 0x7a, 0x75, 0x3b, 0x0e, 0xe9, 0xbc, 0x3b, 0xfa, 0x06, 0x60, 0x3b, + 0x12, 0x4b, 0xab, 0x3b, 0x95, 0xb8, 0xaf, 0x3b, 0x37, 0xc2, 0x54, 0x3b, 0xbe, + 0x2b, 0x7b, 0x3b, 0xdd, 0xc9, 0x83, 0x3b, 0xb2, 0x00, 0x9b, 0x3b, 0x6c, 0x06, + 0xbe, 0x3b, 0x47, 0xd2, 0x9d, 0x3b, 0x27, 0xbe, 0xdc, 0x3b, 0xe2, 0x70, 0x84, + 0x3b, 0xc7, 0xd1, 0x6e, 0x3b, 0x4f, 0x2c, 0xa8, 0x3b, 0xf4, 0x02, 0xd2, 0x3b, + 0x9c, 0xc2, 0x04, 0x3c, 0x0b, 0x8d, 0xd7, 0x3b, 0x16, 0x65, 0xb0, 0x3b, 0xaf, + 0xc2, 0x3a, 0x3b, 0xd6, 0xbb, 0x7c, 0x3b, 0x16, 0x8c, 0x98, 0x3b, 0xbb, 0xd1, + 0x7e, 0x3b, 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, + 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x33, + 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x46, 0xb9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0xe8, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0xa2, 0xb2, 0xff, 0xff, 0x14, 0x01, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x87, 0x89, 0x04, 0x3c, 0x79, 0xd0, 0x1d, 0x3c, 0x68, 0xa3, 0xe5, 0x3b, + 0xb9, 0x26, 0x22, 0x3c, 0x98, 0xca, 0x50, 0x3c, 0x30, 0xc4, 0xc5, 0x3c, 0x27, + 0x84, 0x8f, 0x3b, 0x2d, 0x0a, 0xeb, 0x3b, 0xbe, 0xf6, 0xee, 0x3b, 0xf0, 0x0c, + 0x8b, 0x3c, 0xc4, 0xd5, 0xb1, 0x3c, 0xcb, 0x44, 0xdc, 0x3b, 0x23, 0x2a, 0x34, + 0x3b, 0xcc, 0x23, 0x57, 0x3c, 0x95, 0x75, 0x0a, 0x3c, 0xdc, 0xdd, 0x06, 0x3b, + 0x15, 0x63, 0xe5, 0x3b, 0x3b, 0xa4, 0x8b, 0x3b, 0x01, 0x47, 0xb3, 0x3c, 0x17, + 0x08, 0xc8, 0x3c, 0xde, 0x85, 0xb4, 0x3b, 0x47, 0x1d, 0xc0, 0x3c, 0x5e, 0xf2, + 0x4f, 0x3b, 0x0c, 0x34, 0xd4, 0x3b, 0xc9, 0x45, 0xc7, 0x3b, 0x2a, 0x86, 0xf0, + 0x3c, 0x46, 0x7c, 0xf8, 0x3b, 0x57, 0x56, 0x52, 0x3b, 0x04, 0xf4, 0xa6, 0x3b, + 0xec, 0x8d, 0xe0, 0x3b, 0x44, 0x9f, 0xd3, 0x3b, 0x4d, 0x19, 0x38, 0x3c, 0x35, + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x33, 0x5f, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, + 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x4a, 0xbb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xd8, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xcc, + 0xc1, 0xff, 0xff, 0x10, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x5c, 0xc7, 0x3c, 0x3c, 0x66, 0x8c, 0x83, + 0x3b, 0xd4, 0x22, 0xcd, 0x3b, 0x48, 0x6e, 0xd1, 0x3b, 0xdc, 0x08, 0xa3, 0x3b, + 0x61, 0x10, 0xd1, 0x3a, 0x79, 0x0b, 0xaf, 0x3b, 0x3a, 0x7e, 0xe1, 0x3b, 0x30, + 0x6c, 0x76, 0x3b, 0xfb, 0x99, 0x5e, 0x3b, 0xf0, 0xc4, 0xe5, 0x3a, 0x1c, 0xc4, + 0xa8, 0x3b, 0xb1, 0x3a, 0xd0, 0x3b, 0x88, 0x11, 0xa7, 0x3b, 0xec, 0xf4, 0x20, + 0x3c, 0xe3, 0xd4, 0x3b, 0x3c, 0xab, 0xed, 0xd9, 0x3b, 0x95, 0xdb, 0xfa, 0x3b, + 0x66, 0x0a, 0x11, 0x3b, 0x9b, 0x16, 0x4e, 0x3b, 0x24, 0xb6, 0xb0, 0x3b, 0xa5, + 0xc7, 0xfd, 0x3a, 0xac, 0x74, 0xc1, 0x3b, 0xbc, 0x52, 0xdc, 0x3b, 0x0a, 0xb5, + 0xb0, 0x3b, 0x49, 0x2c, 0x92, 0x3a, 0x60, 0x8d, 0xb4, 0x3b, 0x7f, 0x7e, 0xef, + 0x3b, 0x9a, 0x83, 0x1b, 0x3c, 0x4a, 0x50, 0x9a, 0x3b, 0xd4, 0x4d, 0x08, 0x3c, + 0x80, 0x79, 0x71, 0x3b, 0x2b, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x32, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3e, 0xbd, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x09, 0x28, 0x01, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x9a, 0xb6, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xf3, 0xae, 0x65, 0x3b, 0x76, 0xd3, 0x46, 0x3b, + 0x47, 0x81, 0xa1, 0x3b, 0xa1, 0x23, 0x83, 0x3b, 0x2e, 0x71, 0xbf, 0x3b, 0xbf, + 0x4c, 0x9d, 0x3b, 0x00, 0xc1, 0xa5, 0x3b, 0x36, 0x82, 0x2f, 0x3b, 0x9a, 0xaf, + 0xa4, 0x3b, 0x3a, 0xd4, 0x11, 0x3c, 0x22, 0x3a, 0x44, 0x3b, 0xb5, 0x66, 0xa2, + 0x3b, 0xef, 0x6f, 0x6c, 0x3b, 0x28, 0xc6, 0x65, 0x3b, 0xb1, 0x23, 0xda, 0x3b, + 0x85, 0x20, 0xed, 0x3b, 0x35, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, + 0x5f, 0x32, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x82, 0xbe, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x09, 0x18, 0x01, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0xc5, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x09, 0x89, 0x62, 0x3c, 0x4d, 0xd2, 0x10, 0x3c, 0xc6, 0x64, 0x87, 0x3c, 0xc1, + 0x43, 0xee, 0x3b, 0x0a, 0x21, 0x47, 0x3c, 0x41, 0xa2, 0x49, 0x3c, 0x5e, 0x4c, + 0x00, 0x3c, 0x22, 0x6b, 0x0c, 0x3c, 0xb3, 0x07, 0x6a, 0x3c, 0x28, 0xb4, 0x07, + 0x3c, 0xb3, 0xc7, 0x52, 0x3c, 0x27, 0x63, 0x03, 0x3c, 0x87, 0xac, 0x46, 0x3c, + 0xe4, 0xd4, 0xe3, 0x3b, 0x53, 0xf1, 0x04, 0x3c, 0x58, 0xb6, 0x32, 0x3c, 0x2b, + 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, + 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x5f, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0xb6, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xc8, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x12, 0xb9, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0xc6, 0x53, 0x8c, 0x3b, 0xca, 0x97, 0xca, 0x3b, 0x35, 0x82, 0x15, 0x3e, + 0xcd, 0x4b, 0x3e, 0x3b, 0x6d, 0x31, 0x70, 0x3c, 0x71, 0x98, 0x2d, 0x3b, 0x91, + 0xa1, 0xf1, 0x3b, 0x42, 0xa8, 0xa3, 0x3e, 0x35, 0x00, 0x00, 0x00, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, + 0x76, 0x32, 0x64, 0x5f, 0x31, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9a, 0xc0, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x58, 0x0c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1c, + 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1c, 0xc7, 0xff, 0xff, 0x0c, 0x08, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x35, 0xc1, 0x5c, 0x3a, 0xe5, + 0xef, 0xaa, 0x3a, 0xfb, 0x29, 0x95, 0x3a, 0xd6, 0x76, 0x09, 0x3a, 0x9a, 0xd5, + 0x99, 0x3a, 0x88, 0x58, 0x2f, 0x3a, 0xe3, 0x21, 0x42, 0x3a, 0xe5, 0x62, 0x95, + 0x3a, 0xfa, 0xa3, 0x5e, 0x3a, 0x66, 0x7c, 0x87, 0x3a, 0xef, 0x0d, 0x5d, 0x3a, + 0x96, 0x73, 0x31, 0x3a, 0x87, 0x13, 0x8d, 0x3a, 0x55, 0xee, 0x38, 0x3a, 0x8f, + 0x82, 0x34, 0x3a, 0x09, 0x82, 0x56, 0x3a, 0x8f, 0x70, 0x67, 0x3a, 0x8d, 0xca, + 0x2d, 0x3a, 0xf5, 0x8b, 0x1c, 0x3a, 0xcf, 0x64, 0x7c, 0x3a, 0xda, 0xb7, 0x12, + 0x3a, 0xff, 0xd8, 0x46, 0x3a, 0x72, 0xa8, 0x80, 0x3a, 0xb8, 0x32, 0x48, 0x3a, + 0x95, 0xdf, 0x97, 0x3a, 0xe1, 0x48, 0x42, 0x3a, 0xad, 0xfc, 0xb2, 0x3a, 0x0f, + 0xfe, 0x82, 0x3a, 0xec, 0xcc, 0x18, 0x3a, 0x0f, 0x77, 0x38, 0x3a, 0x48, 0x00, + 0x5a, 0x3a, 0x17, 0x3b, 0x77, 0x3a, 0x5c, 0x99, 0x90, 0x3a, 0xa5, 0x25, 0x50, + 0x3a, 0xbc, 0x0d, 0x48, 0x3a, 0x14, 0xc8, 0x3e, 0x3a, 0xe9, 0xb8, 0x52, 0x3a, + 0x6b, 0xc3, 0x25, 0x3a, 0x4a, 0x97, 0x65, 0x3a, 0xd6, 0x6f, 0x45, 0x3a, 0x95, + 0x18, 0x84, 0x3a, 0x8e, 0xaf, 0x58, 0x3a, 0xc7, 0x30, 0x84, 0x3a, 0x99, 0x69, + 0x77, 0x3a, 0x22, 0xc9, 0x10, 0x3a, 0x95, 0xb8, 0x1e, 0x3a, 0x50, 0xd3, 0x43, + 0x3a, 0xe2, 0x56, 0x36, 0x3a, 0x5e, 0xe9, 0x8a, 0x3a, 0xb1, 0x42, 0x86, 0x3a, + 0x28, 0xd7, 0x58, 0x3a, 0x5f, 0xe0, 0x1d, 0x3a, 0x70, 0x0e, 0x35, 0x3a, 0x13, + 0x7b, 0xcf, 0x3a, 0x5e, 0xfd, 0x3c, 0x3a, 0x1c, 0xe5, 0x7c, 0x3a, 0x42, 0x7e, + 0x85, 0x3a, 0x67, 0x18, 0x48, 0x3a, 0xbd, 0xec, 0x33, 0x3a, 0xc7, 0x8c, 0x5c, + 0x3a, 0x23, 0xff, 0x5c, 0x3a, 0x76, 0xcc, 0x4d, 0x3a, 0xe1, 0x08, 0x81, 0x3a, + 0x2d, 0xca, 0x3e, 0x3a, 0x76, 0x72, 0x1a, 0x3a, 0x5e, 0x40, 0x55, 0x3a, 0x38, + 0x79, 0x23, 0x3a, 0x59, 0x0d, 0x43, 0x3a, 0x43, 0x52, 0x42, 0x3a, 0x1c, 0x46, + 0x63, 0x3a, 0xce, 0xe7, 0x67, 0x3a, 0xe9, 0x16, 0x3e, 0x3a, 0x3c, 0x0c, 0x02, + 0x3a, 0xb6, 0x1a, 0x54, 0x3a, 0x2d, 0xd9, 0x28, 0x3a, 0xa0, 0x6b, 0x25, 0x3a, + 0xfd, 0xd0, 0xa5, 0x3a, 0xa9, 0x48, 0x59, 0x3a, 0x58, 0x22, 0x34, 0x3a, 0x5a, + 0xec, 0x09, 0x3a, 0x80, 0x39, 0xcb, 0x3a, 0x54, 0x07, 0x2c, 0x3a, 0x0a, 0x1d, + 0x0a, 0x3a, 0x0a, 0x82, 0x43, 0x3a, 0x65, 0x5e, 0x90, 0x3a, 0xf7, 0xc1, 0x18, + 0x3a, 0xba, 0x95, 0x34, 0x3a, 0x58, 0x5d, 0x9d, 0x3a, 0xc2, 0x69, 0x43, 0x3a, + 0x61, 0x37, 0x4b, 0x3a, 0x7d, 0x5a, 0x80, 0x3a, 0x63, 0x47, 0x28, 0x3a, 0x1f, + 0xbc, 0x4b, 0x3a, 0xd7, 0xa2, 0x59, 0x3a, 0x84, 0x6e, 0x11, 0x3a, 0xaa, 0x21, + 0x9b, 0x3a, 0x54, 0xa6, 0x83, 0x3a, 0xb7, 0x23, 0x66, 0x3a, 0xaa, 0xa8, 0x97, + 0x3a, 0x14, 0x6a, 0x2c, 0x3a, 0x4d, 0x1b, 0x2b, 0x3a, 0x2a, 0xbf, 0x27, 0x3a, + 0xf9, 0x8a, 0x27, 0x3a, 0x6a, 0x9e, 0x5d, 0x3a, 0xfa, 0xda, 0x89, 0x3a, 0x4f, + 0xea, 0x2e, 0x3a, 0x6b, 0x3f, 0x29, 0x3a, 0x51, 0xba, 0x28, 0x3a, 0xa8, 0x04, + 0x74, 0x3a, 0xcd, 0xb2, 0x56, 0x3a, 0x08, 0xe9, 0x85, 0x3a, 0xe2, 0x08, 0x28, + 0x3a, 0xa4, 0xfb, 0x02, 0x3a, 0x1c, 0x1b, 0x9a, 0x3a, 0x0b, 0xf8, 0x32, 0x3a, + 0x21, 0x7d, 0x83, 0x3a, 0xbd, 0xc4, 0x8e, 0x3a, 0xb8, 0x50, 0x39, 0x3a, 0x34, + 0xba, 0xa2, 0x3a, 0xa2, 0xfd, 0x26, 0x3a, 0xc7, 0xf1, 0x5c, 0x3a, 0x89, 0x82, + 0x1e, 0x3a, 0xc9, 0x03, 0x25, 0x3a, 0xda, 0x86, 0x55, 0x3a, 0xd2, 0xb4, 0x5d, + 0x3a, 0xa8, 0x51, 0x26, 0x3a, 0x4f, 0x3e, 0x21, 0x3a, 0xea, 0x6c, 0x75, 0x3a, + 0xf4, 0x32, 0x6b, 0x3a, 0xa6, 0x58, 0x9b, 0x3a, 0x3c, 0xd4, 0xa1, 0x3a, 0x9c, + 0x68, 0x7d, 0x3a, 0x8f, 0x54, 0x58, 0x3a, 0x41, 0x4c, 0x24, 0x3a, 0x2f, 0x16, + 0x68, 0x3a, 0x3b, 0x1d, 0x06, 0x3a, 0xa3, 0x7b, 0x7b, 0x3a, 0xd7, 0x94, 0x71, + 0x3a, 0xa1, 0x17, 0x25, 0x3a, 0xe4, 0x77, 0x42, 0x3a, 0x05, 0xb9, 0x6e, 0x3a, + 0x00, 0xe4, 0x42, 0x3a, 0x9b, 0xb6, 0x49, 0x3a, 0x25, 0x09, 0x5f, 0x3a, 0xae, + 0x63, 0x55, 0x3a, 0x78, 0x8d, 0x50, 0x3a, 0xa5, 0xf5, 0x64, 0x3a, 0x22, 0x6e, + 0x61, 0x3a, 0x34, 0x1c, 0x75, 0x3a, 0x8f, 0xf8, 0x33, 0x3a, 0x71, 0xc6, 0x62, + 0x3a, 0x34, 0x5d, 0x44, 0x3a, 0xb3, 0x6d, 0x25, 0x3a, 0x41, 0x2b, 0x19, 0x3a, + 0xd8, 0x4a, 0x73, 0x3a, 0x4b, 0x72, 0x59, 0x3a, 0xa2, 0x6c, 0x41, 0x3a, 0x0a, + 0xed, 0x9e, 0x3a, 0x05, 0x1e, 0x46, 0x3a, 0x5a, 0x17, 0x49, 0x3a, 0xd4, 0xea, + 0x23, 0x3a, 0x76, 0xdb, 0x46, 0x3a, 0x6f, 0xb2, 0xb7, 0x3a, 0x9b, 0xe6, 0x4e, + 0x3a, 0x28, 0x26, 0x42, 0x3a, 0x92, 0xb3, 0x3a, 0x3a, 0x93, 0x76, 0x1e, 0x3a, + 0x92, 0x54, 0x49, 0x3a, 0x35, 0x42, 0x13, 0x3a, 0xac, 0x30, 0xa2, 0x3a, 0xc4, + 0xca, 0x4f, 0x3a, 0x18, 0x3c, 0x1e, 0x3a, 0x44, 0xd1, 0x8a, 0x3a, 0x22, 0x0d, + 0x34, 0x3a, 0x66, 0xf7, 0x47, 0x3a, 0xe7, 0x06, 0x49, 0x3a, 0x38, 0xc8, 0x07, + 0x3b, 0x41, 0xe5, 0xca, 0x3a, 0x4b, 0x05, 0x63, 0x3a, 0x48, 0x83, 0x50, 0x3a, + 0x3b, 0x4a, 0x23, 0x3a, 0x10, 0x05, 0x3c, 0x3a, 0x70, 0x54, 0x45, 0x3a, 0xfc, + 0xb4, 0x56, 0x3a, 0x16, 0x39, 0x7a, 0x3a, 0xd3, 0xac, 0x67, 0x3a, 0x13, 0x8d, + 0x98, 0x3a, 0x99, 0x9d, 0x3e, 0x3a, 0x2a, 0x46, 0x37, 0x3a, 0xfc, 0x1c, 0x4a, + 0x3a, 0xa1, 0x1c, 0x52, 0x3a, 0xab, 0x73, 0x7b, 0x3a, 0x04, 0xc9, 0x24, 0x3a, + 0x0b, 0xf4, 0x57, 0x3a, 0xc8, 0xab, 0x74, 0x3a, 0x4d, 0x7b, 0x1f, 0x3a, 0x21, + 0xe0, 0x34, 0x3a, 0x37, 0x61, 0x82, 0x3a, 0x63, 0xe2, 0x21, 0x3a, 0x6f, 0xd2, + 0xdf, 0x39, 0x7e, 0x17, 0x36, 0x3a, 0xe5, 0xa0, 0xef, 0x39, 0xc6, 0x00, 0x6b, + 0x3a, 0x5d, 0x5d, 0x71, 0x3a, 0xe6, 0xe7, 0x52, 0x3a, 0x8f, 0xd1, 0x80, 0x3a, + 0x20, 0x09, 0x8f, 0x3a, 0x83, 0xbe, 0x2f, 0x3a, 0xe3, 0x3d, 0x14, 0x3a, 0x58, + 0xec, 0x66, 0x3a, 0xb2, 0x96, 0x6e, 0x3a, 0xc3, 0x27, 0x7f, 0x3a, 0xfa, 0xea, + 0x50, 0x3a, 0xbb, 0x93, 0x3f, 0x3a, 0x88, 0xc4, 0xbb, 0x3a, 0x81, 0xa1, 0x16, + 0x3a, 0xaa, 0x0d, 0x18, 0x3a, 0xd3, 0x61, 0x51, 0x3a, 0x6a, 0x28, 0x72, 0x3a, + 0xa7, 0xa6, 0x4d, 0x3a, 0x01, 0xb4, 0x5b, 0x3a, 0x49, 0x56, 0x2f, 0x3a, 0x39, + 0x06, 0x84, 0x3a, 0x90, 0x4e, 0x90, 0x3a, 0xce, 0x41, 0x49, 0x3a, 0x94, 0x2a, + 0x40, 0x3a, 0x2e, 0xbc, 0x1f, 0x3a, 0x1e, 0x6d, 0x18, 0x3a, 0xd8, 0x8b, 0x30, + 0x3a, 0x48, 0xcd, 0x2b, 0x3a, 0x39, 0xfd, 0x89, 0x3a, 0x9e, 0xbf, 0x36, 0x3a, + 0xf0, 0xf7, 0x49, 0x3a, 0x53, 0xa4, 0x03, 0x3a, 0xc8, 0x82, 0x7f, 0x3a, 0x77, + 0x2f, 0xa8, 0x3a, 0x9a, 0x23, 0x83, 0x3a, 0x4e, 0x97, 0x22, 0x3a, 0xe9, 0x13, + 0x2a, 0x3a, 0x39, 0x76, 0x7c, 0x3a, 0x0b, 0x01, 0xbe, 0x3a, 0x4a, 0x2f, 0x8a, + 0x3a, 0x41, 0x24, 0x29, 0x3a, 0x15, 0x51, 0xbb, 0x3a, 0x38, 0x36, 0x1d, 0x3a, + 0x1f, 0x00, 0xa9, 0x3a, 0x64, 0x35, 0x95, 0x3a, 0xbd, 0x91, 0x69, 0x3a, 0xdf, + 0xcf, 0x32, 0x3a, 0x0e, 0xc4, 0xc3, 0x3a, 0x36, 0xb8, 0x38, 0x3a, 0x95, 0xfc, + 0x58, 0x3a, 0xf0, 0xf3, 0xa5, 0x3a, 0x17, 0x58, 0x87, 0x3a, 0xa1, 0xe4, 0x54, + 0x3a, 0xaf, 0x41, 0x87, 0x3a, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x31, 0x33, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, + 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0e, + 0xcd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x68, 0x0c, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6a, 0xc6, 0xff, + 0xff, 0x14, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x71, 0x40, 0x3c, 0xe8, 0xda, 0xe7, + 0x3b, 0xe4, 0xb9, 0x56, 0x3c, 0x54, 0x6a, 0xf9, 0x3b, 0x67, 0x0c, 0xbf, 0x3b, + 0x24, 0x1c, 0x0b, 0x3c, 0x6a, 0x8f, 0xb1, 0x3b, 0xdc, 0x08, 0x24, 0x3c, 0xb2, + 0x7c, 0xbe, 0x3b, 0x80, 0xad, 0x24, 0x3c, 0x51, 0xbd, 0xdb, 0x3b, 0xb3, 0xff, + 0xc2, 0x3b, 0x86, 0xbc, 0xee, 0x3b, 0x59, 0xcb, 0xed, 0x3b, 0xbb, 0x7f, 0x2c, + 0x3c, 0x49, 0xb7, 0x16, 0x3c, 0xc3, 0xea, 0xd4, 0x3b, 0x45, 0xed, 0xbf, 0x3b, + 0x83, 0x67, 0x18, 0x3c, 0xa5, 0x1b, 0x0d, 0x3c, 0x08, 0x5c, 0x25, 0x3c, 0x1d, + 0x17, 0x08, 0x3c, 0x5f, 0xdc, 0x04, 0x3c, 0xd5, 0x0b, 0x0b, 0x3c, 0xac, 0x9d, + 0x16, 0x3c, 0xfb, 0x22, 0xdb, 0x3b, 0xd0, 0xb7, 0xee, 0x3b, 0xa7, 0x22, 0x11, + 0x3c, 0x89, 0x0d, 0x20, 0x3c, 0x8f, 0x3f, 0xb2, 0x3b, 0x5b, 0x72, 0xce, 0x3b, + 0x76, 0x21, 0xb6, 0x3b, 0x9b, 0x02, 0xc9, 0x3b, 0xdb, 0xa3, 0xeb, 0x3b, 0xd3, + 0xde, 0x03, 0x3c, 0x52, 0xde, 0x07, 0x3c, 0x56, 0xd8, 0x30, 0x3c, 0x4b, 0xd2, + 0xff, 0x3b, 0x7d, 0x2b, 0x52, 0x3c, 0xca, 0x87, 0x33, 0x3c, 0xf1, 0xe7, 0x0d, + 0x3c, 0xc2, 0x0c, 0x01, 0x3c, 0xbc, 0x93, 0xd6, 0x3b, 0x9d, 0xfc, 0xe5, 0x3b, + 0x11, 0x90, 0xf2, 0x3b, 0x0f, 0xa2, 0xff, 0x3b, 0xfc, 0x7a, 0x08, 0x3c, 0x34, + 0x8b, 0x2d, 0x3c, 0x7b, 0xef, 0xfe, 0x3b, 0xe9, 0x05, 0xe5, 0x3b, 0x35, 0x65, + 0xde, 0x3b, 0xcf, 0xc6, 0xd8, 0x3b, 0xc4, 0xe0, 0xa9, 0x3b, 0xb6, 0x87, 0x13, + 0x3c, 0x08, 0x17, 0x2f, 0x3c, 0x12, 0x77, 0xdc, 0x3b, 0xf8, 0xfd, 0xdf, 0x3b, + 0xed, 0xee, 0xe4, 0x3b, 0x3e, 0xab, 0x23, 0x3c, 0x4c, 0xac, 0xb6, 0x3b, 0xae, + 0x28, 0xfc, 0x3b, 0x63, 0x1d, 0x3b, 0x3c, 0x21, 0x45, 0x02, 0x3c, 0x58, 0xca, + 0x4f, 0x3c, 0x5f, 0x9b, 0x28, 0x3c, 0xf0, 0x2a, 0x1d, 0x3c, 0x20, 0x20, 0xd9, + 0x3b, 0xda, 0xa2, 0x18, 0x3c, 0x5b, 0x63, 0x0b, 0x3c, 0x97, 0x50, 0x0d, 0x3c, + 0x77, 0xd5, 0xcb, 0x3b, 0xfb, 0xc4, 0x1c, 0x3c, 0xa6, 0x4a, 0xdd, 0x3b, 0x1d, + 0x2b, 0xf4, 0x3b, 0x71, 0xcd, 0x08, 0x3c, 0xd3, 0x09, 0xf9, 0x3b, 0x36, 0x59, + 0xc5, 0x3b, 0x51, 0x4a, 0x04, 0x3c, 0x93, 0xca, 0x2f, 0x3c, 0x80, 0x6e, 0xf5, + 0x3b, 0xed, 0x35, 0x25, 0x3c, 0x52, 0xc5, 0xdb, 0x3b, 0x0a, 0x34, 0x26, 0x3c, + 0x9a, 0x17, 0xeb, 0x3b, 0xd1, 0xac, 0xb9, 0x3b, 0x9b, 0xc2, 0x0a, 0x3c, 0xff, + 0x69, 0x2e, 0x3c, 0x57, 0x4d, 0xef, 0x3b, 0x7b, 0x6c, 0x10, 0x3c, 0x6e, 0xe2, + 0xe8, 0x3b, 0xde, 0x4e, 0xcb, 0x3b, 0xf6, 0xd9, 0xdc, 0x3b, 0x71, 0xf7, 0x07, + 0x3c, 0xe5, 0x80, 0x49, 0x3c, 0xd1, 0xee, 0x0b, 0x3c, 0x09, 0xbc, 0x02, 0x3c, + 0x52, 0xeb, 0x0f, 0x3c, 0x42, 0x61, 0x16, 0x3c, 0xf3, 0xd2, 0xcc, 0x3b, 0xec, + 0x81, 0xe8, 0x3b, 0xe0, 0x2e, 0x15, 0x3c, 0x0e, 0x34, 0x1f, 0x3c, 0xd3, 0x49, + 0xf9, 0x3b, 0x1c, 0x03, 0x01, 0x3c, 0x77, 0x8f, 0xe5, 0x3b, 0xd6, 0x2c, 0x09, + 0x3c, 0xe1, 0x22, 0xdd, 0x3b, 0x04, 0xb9, 0xa9, 0x3b, 0x2f, 0x2a, 0x1b, 0x3c, + 0x87, 0x2f, 0x32, 0x3c, 0x91, 0xb7, 0xcc, 0x3b, 0x5e, 0x47, 0xf7, 0x3b, 0xbf, + 0x49, 0xd2, 0x3b, 0x85, 0x5b, 0x03, 0x3c, 0xd4, 0x9d, 0x9b, 0x3b, 0x6f, 0x85, + 0xc9, 0x3b, 0xb4, 0xa9, 0x02, 0x3c, 0x46, 0xe9, 0x18, 0x3c, 0x41, 0x05, 0x52, + 0x3c, 0x03, 0x46, 0xe3, 0x3b, 0x80, 0x38, 0x0f, 0x3c, 0x2c, 0x2b, 0x30, 0x3c, + 0x43, 0x27, 0xbe, 0x3b, 0x53, 0x47, 0xf1, 0x3b, 0x11, 0xc6, 0x05, 0x3c, 0x6a, + 0xaf, 0x07, 0x3c, 0x8f, 0x63, 0x3f, 0x3c, 0xe3, 0x24, 0x1d, 0x3c, 0x52, 0x51, + 0x65, 0x3c, 0xc7, 0x39, 0xcf, 0x3b, 0x93, 0x31, 0xd6, 0x3b, 0x15, 0x97, 0x06, + 0x3c, 0x6d, 0xc8, 0x0b, 0x3c, 0xa8, 0x32, 0x07, 0x3c, 0xdb, 0x3e, 0xc9, 0x3b, + 0xec, 0x7d, 0xb1, 0x3b, 0xc5, 0xee, 0xce, 0x3b, 0x3a, 0xb1, 0x90, 0x3b, 0x99, + 0x5a, 0xd2, 0x3b, 0x36, 0xe0, 0x1c, 0x3c, 0xd3, 0xaf, 0x08, 0x3c, 0x00, 0xed, + 0x2b, 0x3c, 0x61, 0xd2, 0x6a, 0x3c, 0x43, 0x53, 0xdc, 0x3b, 0xd1, 0x7a, 0x19, + 0x3c, 0x14, 0x4d, 0x24, 0x3c, 0xf6, 0xfb, 0x0b, 0x3c, 0x20, 0xc4, 0x10, 0x3c, + 0x6e, 0x6c, 0x12, 0x3c, 0xdb, 0x71, 0x1e, 0x3c, 0x3f, 0xad, 0x02, 0x3c, 0x24, + 0x6d, 0xa5, 0x3b, 0x0e, 0x74, 0x39, 0x3c, 0xc7, 0xfe, 0x15, 0x3c, 0xe8, 0x69, + 0xdc, 0x3b, 0xdd, 0x24, 0x0c, 0x3c, 0x47, 0x57, 0x04, 0x3c, 0xcf, 0xf3, 0xf9, + 0x3b, 0x13, 0xfc, 0xef, 0x3b, 0x62, 0xc3, 0x1c, 0x3c, 0x02, 0x45, 0xfa, 0x3b, + 0x0d, 0xfd, 0xf1, 0x3b, 0x71, 0x8b, 0x9c, 0x3b, 0xd7, 0xab, 0xc9, 0x3b, 0x28, + 0x5d, 0x14, 0x3c, 0xe5, 0x71, 0xe6, 0x3b, 0x3a, 0xa1, 0x1b, 0x3c, 0x49, 0xcc, + 0xf8, 0x3b, 0x92, 0xcd, 0xf9, 0x3b, 0x73, 0xec, 0x24, 0x3c, 0x9d, 0xa1, 0x80, + 0x3c, 0xc1, 0x94, 0xb5, 0x3b, 0xbf, 0x58, 0x17, 0x3c, 0xe1, 0xcb, 0x05, 0x3c, + 0x7d, 0xff, 0xe4, 0x3b, 0xe8, 0x2b, 0x32, 0x3c, 0x0f, 0x99, 0x22, 0x3c, 0x2b, + 0xf6, 0xc9, 0x3b, 0x7d, 0xec, 0x44, 0x3c, 0xe6, 0x63, 0x20, 0x3c, 0xf5, 0x7a, + 0x17, 0x3c, 0x3d, 0xc2, 0x26, 0x3c, 0x5f, 0xaa, 0xf2, 0x3b, 0x72, 0x06, 0xc5, + 0x3b, 0xdb, 0x1d, 0xcd, 0x3b, 0x9c, 0x43, 0x81, 0x3c, 0xac, 0x2f, 0x2a, 0x3c, + 0x80, 0xfb, 0x46, 0x3c, 0xfe, 0x9f, 0xe5, 0x3b, 0x74, 0x85, 0x0a, 0x3c, 0x38, + 0x1d, 0x16, 0x3c, 0xd1, 0x3e, 0xd8, 0x3b, 0x6a, 0x95, 0xb1, 0x3b, 0xf7, 0x07, + 0xf9, 0x3b, 0x82, 0x05, 0xab, 0x3b, 0xaf, 0xe3, 0xda, 0x3b, 0x7a, 0xeb, 0xc9, + 0x3b, 0x56, 0x85, 0x14, 0x3c, 0x58, 0x82, 0x39, 0x3c, 0xed, 0xc7, 0x27, 0x3c, + 0xfa, 0x26, 0x31, 0x3c, 0xdd, 0x03, 0x0d, 0x3c, 0x82, 0x66, 0xbb, 0x3b, 0xc3, + 0xbb, 0xb2, 0x3b, 0xf1, 0xf7, 0x28, 0x3c, 0x71, 0x80, 0xa1, 0x3b, 0x16, 0x27, + 0x01, 0x3c, 0xfa, 0x22, 0x04, 0x3c, 0xf8, 0xb6, 0x47, 0x3c, 0x33, 0x46, 0x2b, + 0x3c, 0x65, 0xcf, 0xe1, 0x3b, 0x78, 0x79, 0xe7, 0x3b, 0xd3, 0x9a, 0xfa, 0x3b, + 0x87, 0x41, 0x00, 0x3c, 0xf2, 0x4e, 0x17, 0x3c, 0x95, 0xa9, 0x29, 0x3c, 0x8f, + 0x50, 0x12, 0x3c, 0xa3, 0x7b, 0xe0, 0x3b, 0xf2, 0xc9, 0x02, 0x3c, 0x4b, 0x4f, + 0xb2, 0x3b, 0xcc, 0x25, 0x26, 0x3c, 0xfc, 0x07, 0x1a, 0x3c, 0xea, 0x97, 0x05, + 0x3c, 0x0a, 0x9b, 0x29, 0x3c, 0xfe, 0x65, 0xf8, 0x3b, 0xac, 0x80, 0x0a, 0x3c, + 0xaf, 0x6f, 0xed, 0x3b, 0x86, 0xda, 0xc8, 0x3b, 0xd3, 0xf7, 0x03, 0x3c, 0xf3, + 0x08, 0x10, 0x3c, 0x4f, 0x69, 0x53, 0x3c, 0xad, 0xc6, 0x10, 0x3c, 0xf6, 0x7a, + 0xe5, 0x3b, 0x23, 0x52, 0x1e, 0x3c, 0xc8, 0xcc, 0x42, 0x3c, 0x1b, 0x64, 0xc9, + 0x3b, 0xa6, 0x6c, 0x29, 0x3c, 0xaa, 0x9b, 0xda, 0x3b, 0x69, 0x72, 0x01, 0x3c, + 0x59, 0xba, 0xe2, 0x3b, 0xe1, 0x4e, 0x25, 0x3c, 0x79, 0x3b, 0xdb, 0x3b, 0xed, + 0x7a, 0xb3, 0x3b, 0xa5, 0x7d, 0xf5, 0x3b, 0x9f, 0xbf, 0x14, 0x3c, 0x7f, 0x81, + 0x29, 0x3c, 0x04, 0xff, 0x0b, 0x3c, 0x81, 0x0d, 0x22, 0x3c, 0x91, 0xd2, 0x17, + 0x3c, 0xca, 0x1c, 0x19, 0x3c, 0x04, 0x31, 0x1e, 0x3c, 0xc5, 0x42, 0xed, 0x3b, + 0x29, 0xb5, 0xaa, 0x3b, 0x88, 0xb8, 0x0e, 0x3c, 0xad, 0x1b, 0xc6, 0x3b, 0xc5, + 0x74, 0xff, 0x3b, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, + 0x31, 0x33, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x92, 0xd9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x58, 0x0c, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x14, 0xe0, 0xff, 0xff, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0xcc, 0xe1, 0x0f, 0x3b, 0x17, 0x4c, 0xbf, 0x3a, 0x04, + 0x03, 0xea, 0x3a, 0xcc, 0xf3, 0xde, 0x3a, 0x10, 0xa3, 0x4e, 0x3b, 0x00, 0x59, + 0xe0, 0x3a, 0x5d, 0xde, 0x29, 0x3b, 0x21, 0x80, 0x2c, 0x3b, 0xf8, 0x74, 0xea, + 0x3a, 0x02, 0xe3, 0x05, 0x3b, 0xd8, 0xb1, 0x03, 0x3b, 0x77, 0x53, 0xfd, 0x3a, + 0x96, 0x88, 0xc9, 0x3a, 0x58, 0x58, 0x0c, 0x3b, 0xfb, 0x10, 0x5b, 0x3b, 0x2a, + 0xf4, 0x17, 0x3b, 0x46, 0x1e, 0x26, 0x3b, 0xb2, 0x20, 0xc5, 0x3a, 0x1a, 0x6e, + 0x06, 0x3b, 0x2a, 0x57, 0x05, 0x3b, 0x67, 0xf5, 0x2d, 0x3b, 0xd0, 0x2c, 0x02, + 0x3b, 0x8a, 0xf5, 0xf7, 0x3a, 0x38, 0x73, 0xdd, 0x3a, 0xa1, 0xb8, 0x0e, 0x3b, + 0xea, 0x08, 0x28, 0x3b, 0x48, 0x78, 0x0f, 0x3b, 0x07, 0x63, 0x25, 0x3b, 0x81, + 0x6d, 0xe8, 0x3a, 0x25, 0xc8, 0x03, 0x3b, 0x00, 0xb7, 0xb3, 0x3a, 0xaf, 0xa6, + 0x1a, 0x3b, 0x7f, 0x56, 0x0c, 0x3b, 0x89, 0x65, 0x07, 0x3b, 0xb5, 0xae, 0xbe, + 0x3a, 0xb4, 0xee, 0xfa, 0x3a, 0x1a, 0x88, 0x5f, 0x3b, 0xc9, 0x6f, 0xfa, 0x3a, + 0x32, 0xb8, 0xc5, 0x3a, 0x72, 0x60, 0x28, 0x3b, 0xd9, 0x9d, 0x29, 0x3b, 0x83, + 0xf8, 0x06, 0x3b, 0x24, 0xb0, 0x03, 0x3b, 0xb8, 0x11, 0xdd, 0x3a, 0xce, 0x34, + 0xf2, 0x3a, 0x77, 0x44, 0xfb, 0x3a, 0x2c, 0x3e, 0xe5, 0x3a, 0xe8, 0xbe, 0xe4, + 0x3a, 0x8b, 0x3f, 0x36, 0x3b, 0x80, 0x2c, 0x12, 0x3b, 0xb1, 0x7a, 0x09, 0x3b, + 0x83, 0x16, 0xc6, 0x3a, 0x47, 0xcc, 0x22, 0x3b, 0xcb, 0xa5, 0xf7, 0x3a, 0xab, + 0x7e, 0x0d, 0x3b, 0x22, 0x3e, 0x0c, 0x3b, 0xcd, 0xc2, 0x22, 0x3b, 0x5a, 0x8b, + 0xfb, 0x3a, 0x20, 0x95, 0xd0, 0x3a, 0x05, 0x9e, 0x06, 0x3b, 0x23, 0x35, 0xd0, + 0x3a, 0xb1, 0x27, 0x21, 0x3b, 0x08, 0x8b, 0xc1, 0x3a, 0x65, 0x3d, 0x0d, 0x3b, + 0x1f, 0xf2, 0x2e, 0x3b, 0x7c, 0x69, 0x0f, 0x3b, 0x4d, 0x9d, 0x09, 0x3b, 0xcd, + 0x8f, 0x0f, 0x3b, 0xe6, 0x71, 0xc8, 0x3a, 0x9e, 0x28, 0x06, 0x3b, 0x08, 0x80, + 0x00, 0x3b, 0x80, 0x15, 0xff, 0x3a, 0xf1, 0x34, 0x47, 0x3b, 0x74, 0x20, 0x06, + 0x3b, 0xfe, 0x06, 0x03, 0x3b, 0xb7, 0x7a, 0xd7, 0x3a, 0x6e, 0xe4, 0x13, 0x3b, + 0xe9, 0x3e, 0x02, 0x3b, 0x31, 0xd5, 0x24, 0x3b, 0xef, 0x18, 0x9f, 0x3b, 0x1c, + 0xc8, 0x46, 0x3b, 0xb3, 0xd3, 0xc8, 0x3a, 0x50, 0xef, 0x1d, 0x3b, 0xcc, 0x59, + 0x99, 0x3a, 0xce, 0xc6, 0xdd, 0x3a, 0x4a, 0xde, 0x92, 0x3a, 0xe4, 0x27, 0x1e, + 0x3b, 0xef, 0x9f, 0x49, 0x3b, 0xa4, 0xf2, 0xcc, 0x3a, 0x36, 0x46, 0x25, 0x3b, + 0x41, 0xb3, 0x23, 0x3b, 0xb6, 0x32, 0x3f, 0x3b, 0xb2, 0xc5, 0x07, 0x3b, 0x26, + 0x07, 0x38, 0x3b, 0x43, 0xe2, 0x1c, 0x3b, 0xa7, 0xe0, 0x18, 0x3b, 0x6e, 0xdd, + 0xff, 0x3a, 0x2f, 0xb9, 0xff, 0x3a, 0x2d, 0x2f, 0x14, 0x3b, 0x8b, 0xf0, 0x0b, + 0x3b, 0x08, 0x83, 0x08, 0x3b, 0x06, 0x5b, 0x0b, 0x3b, 0x94, 0x3a, 0xc8, 0x3a, + 0x24, 0x24, 0xe9, 0x3a, 0x9a, 0x87, 0x0f, 0x3b, 0x64, 0xd1, 0x07, 0x3b, 0xdf, + 0xe5, 0xda, 0x3a, 0x3a, 0x00, 0xe6, 0x3a, 0xe1, 0x2c, 0x42, 0x3b, 0x6c, 0x54, + 0xe0, 0x3a, 0x0b, 0xe9, 0x0e, 0x3b, 0xfd, 0xe2, 0xe6, 0x3a, 0xff, 0xeb, 0x16, + 0x3b, 0x57, 0xf1, 0x4d, 0x3b, 0xe4, 0xb3, 0xb0, 0x3a, 0x63, 0x93, 0xf0, 0x3a, + 0xaf, 0x4e, 0x48, 0x3b, 0xb4, 0x9a, 0x2c, 0x3b, 0xa1, 0x6f, 0x20, 0x3b, 0x19, + 0x20, 0x29, 0x3b, 0x73, 0x22, 0x0a, 0x3b, 0x61, 0xa8, 0x1f, 0x3b, 0x17, 0xb5, + 0xd9, 0x3a, 0xa5, 0xd2, 0xee, 0x3a, 0xa7, 0xe1, 0xfe, 0x3a, 0x10, 0xbd, 0xf6, + 0x3a, 0xdd, 0x6f, 0xd7, 0x3a, 0x21, 0xd4, 0xf3, 0x3a, 0x19, 0xf4, 0xd9, 0x3a, + 0x08, 0x84, 0x0c, 0x3b, 0x92, 0x7c, 0xfc, 0x3a, 0xb5, 0x3a, 0x18, 0x3b, 0x34, + 0xe2, 0xea, 0x3a, 0x0e, 0xc1, 0x04, 0x3b, 0xc4, 0xee, 0x56, 0x3b, 0x9c, 0xd0, + 0xe8, 0x3a, 0x87, 0x38, 0x05, 0x3b, 0xde, 0x41, 0xb7, 0x3a, 0x0b, 0xba, 0xa9, + 0x3a, 0xeb, 0xb4, 0x01, 0x3b, 0x7f, 0x46, 0xe2, 0x3a, 0x03, 0x5e, 0x23, 0x3b, + 0x56, 0x83, 0xe6, 0x3a, 0xbd, 0xab, 0x09, 0x3b, 0xe0, 0x54, 0x23, 0x3b, 0xd5, + 0xb0, 0x3d, 0x3b, 0xaa, 0xb2, 0x2f, 0x3b, 0x18, 0xcd, 0x2d, 0x3b, 0x26, 0xf2, + 0xda, 0x3a, 0x8c, 0x2e, 0x03, 0x3b, 0x79, 0x49, 0x06, 0x3b, 0xf3, 0x28, 0xfa, + 0x3a, 0x38, 0x2a, 0x1a, 0x3b, 0x36, 0x54, 0xbe, 0x3a, 0xbb, 0x2b, 0x12, 0x3b, + 0xf7, 0xba, 0x4f, 0x3b, 0xed, 0x4b, 0x12, 0x3b, 0x7b, 0xaa, 0x1c, 0x3b, 0xa6, + 0xba, 0x1a, 0x3b, 0x6f, 0x3f, 0x11, 0x3b, 0x7e, 0x33, 0x0f, 0x3b, 0xcf, 0x1e, + 0x09, 0x3b, 0xf9, 0xac, 0xec, 0x3a, 0x1a, 0x14, 0xb5, 0x3a, 0x41, 0x60, 0xe4, + 0x3a, 0x9d, 0x2e, 0x22, 0x3b, 0x22, 0x15, 0x22, 0x3b, 0x61, 0xc5, 0x2c, 0x3b, + 0x5f, 0x52, 0xd6, 0x3a, 0x2c, 0x54, 0x28, 0x3b, 0x83, 0x55, 0x4a, 0x3b, 0xce, + 0x9d, 0x46, 0x3b, 0x50, 0xc7, 0xfa, 0x3a, 0x57, 0xce, 0xfd, 0x3a, 0x66, 0x9f, + 0x28, 0x3b, 0x6b, 0x4d, 0xe2, 0x3a, 0xed, 0x62, 0x0e, 0x3b, 0x0a, 0xec, 0xf5, + 0x3a, 0x91, 0xb2, 0x08, 0x3b, 0x71, 0xf2, 0x25, 0x3b, 0x6f, 0xc9, 0x06, 0x3b, + 0x55, 0x88, 0x09, 0x3b, 0x81, 0xd6, 0x52, 0x3b, 0x97, 0xa1, 0xf7, 0x3a, 0x63, + 0x44, 0xf0, 0x3a, 0x94, 0x6b, 0xf8, 0x3a, 0xde, 0x51, 0x01, 0x3b, 0x22, 0xef, + 0xf4, 0x3a, 0x2d, 0x9c, 0x0b, 0x3b, 0x08, 0xb3, 0x39, 0x3b, 0xb9, 0x83, 0xff, + 0x3a, 0x55, 0x0d, 0xfb, 0x3a, 0x8c, 0x07, 0x11, 0x3b, 0xff, 0x16, 0xc1, 0x3a, + 0x0d, 0xee, 0x06, 0x3b, 0xb2, 0x17, 0x08, 0x3b, 0x31, 0x4b, 0xfc, 0x3a, 0xda, + 0x5e, 0x2f, 0x3b, 0x60, 0x7f, 0x24, 0x3b, 0x3d, 0xbb, 0x2c, 0x3b, 0xe3, 0xa9, + 0x1b, 0x3b, 0x99, 0x25, 0x16, 0x3b, 0x32, 0x5c, 0x29, 0x3b, 0xe2, 0x6c, 0x36, + 0x3b, 0x1e, 0x20, 0xc0, 0x3a, 0x74, 0xbd, 0x32, 0x3b, 0x83, 0xdf, 0xf6, 0x3a, + 0xf2, 0x4d, 0x1d, 0x3b, 0xfd, 0xe6, 0x1d, 0x3b, 0xc8, 0x3a, 0xed, 0x3a, 0x85, + 0x4f, 0x20, 0x3b, 0x49, 0x58, 0xd3, 0x3a, 0xc5, 0x4e, 0x06, 0x3b, 0x36, 0xee, + 0x28, 0x3b, 0x6f, 0xca, 0xdb, 0x3a, 0xe4, 0x35, 0x09, 0x3b, 0x1f, 0xbb, 0x28, + 0x3b, 0x4c, 0x89, 0x00, 0x3b, 0x0c, 0x8d, 0x0f, 0x3b, 0x8e, 0x74, 0x13, 0x3b, + 0x5b, 0xf4, 0x2e, 0x3b, 0x93, 0xe0, 0x4b, 0x3b, 0x14, 0xc6, 0x09, 0x3b, 0x07, + 0xf0, 0x0a, 0x3b, 0x3c, 0x54, 0x1f, 0x3b, 0xda, 0x01, 0xbb, 0x3a, 0x59, 0x9c, + 0xe8, 0x3a, 0xc7, 0xea, 0x0b, 0x3b, 0x15, 0x88, 0xf2, 0x3a, 0xbc, 0xc3, 0xd8, + 0x3a, 0xcc, 0xd6, 0x14, 0x3b, 0xca, 0x60, 0x34, 0x3b, 0xf9, 0x7f, 0x00, 0x3b, + 0x31, 0xf8, 0x07, 0x3b, 0x2d, 0xac, 0x26, 0x3b, 0x02, 0x10, 0xda, 0x3a, 0x58, + 0xdc, 0xda, 0x3a, 0x65, 0x3b, 0x05, 0x3b, 0x73, 0xa1, 0x21, 0x3b, 0x2b, 0xb1, + 0x0d, 0x3b, 0xf2, 0xf7, 0xe2, 0x3a, 0x82, 0xc1, 0xc3, 0x3a, 0xc7, 0xf2, 0x10, + 0x3b, 0x42, 0xf2, 0x47, 0x3b, 0x33, 0x3b, 0xf1, 0x3a, 0x76, 0x6e, 0x20, 0x3b, + 0x97, 0x5b, 0x07, 0x3b, 0xe8, 0x6b, 0x11, 0x3b, 0xd3, 0xdb, 0x21, 0x3b, 0x8b, + 0x09, 0x38, 0x3b, 0xd7, 0x22, 0x0d, 0x3b, 0x39, 0xa9, 0xfe, 0x3a, 0x1b, 0xf3, + 0xe6, 0x3a, 0x15, 0x3e, 0x06, 0x3b, 0x21, 0xeb, 0x4a, 0x3b, 0xf3, 0x97, 0x43, + 0x3b, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, + 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x32, + 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x09, 0x68, 0x06, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x24, 0x06, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x62, 0xdf, 0xff, 0xff, 0x14, 0x04, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xb0, 0x3b, 0xf3, 0x87, 0x95, 0x3b, + 0xa0, 0x61, 0x06, 0x3c, 0xc6, 0x88, 0xd8, 0x3b, 0xb8, 0x1d, 0x17, 0x3c, 0x2e, + 0x80, 0x8f, 0x3b, 0x95, 0xd1, 0xac, 0x3b, 0x02, 0x8b, 0xdb, 0x3b, 0x0e, 0xd5, + 0x96, 0x3b, 0x56, 0x45, 0x0b, 0x3c, 0x29, 0xf1, 0xbf, 0x3b, 0x33, 0x80, 0x9e, + 0x3b, 0x84, 0xdd, 0xd8, 0x3b, 0x22, 0xca, 0xb1, 0x3b, 0xf4, 0xd5, 0xa7, 0x3b, + 0x93, 0xee, 0xcd, 0x3b, 0x77, 0xa4, 0x18, 0x3c, 0x65, 0xb4, 0xe5, 0x3b, 0x55, + 0x8b, 0xb9, 0x3b, 0x5a, 0x00, 0xac, 0x3b, 0x00, 0x49, 0xb3, 0x3b, 0x1c, 0x7b, + 0x9a, 0x3b, 0xd6, 0x10, 0xdc, 0x3b, 0x6d, 0xe7, 0xb8, 0x3b, 0xf0, 0x27, 0x89, + 0x3b, 0xbb, 0x44, 0xe0, 0x3b, 0x85, 0xd8, 0xbc, 0x3b, 0xbc, 0xf9, 0x92, 0x3b, + 0x8e, 0xfa, 0xed, 0x3b, 0x55, 0x2b, 0xd2, 0x3b, 0x37, 0xfc, 0xd1, 0x3b, 0x1b, + 0xfe, 0xfc, 0x3b, 0x51, 0x9b, 0xda, 0x3b, 0xe7, 0xb1, 0xf2, 0x3b, 0x15, 0x64, + 0xb1, 0x3b, 0x84, 0x34, 0xee, 0x3b, 0x4e, 0x10, 0xe6, 0x3b, 0xc4, 0x61, 0x7d, + 0x3b, 0x78, 0x42, 0x91, 0x3b, 0x45, 0xd0, 0x13, 0x3c, 0xe8, 0x63, 0x83, 0x3b, + 0x9d, 0x6f, 0x22, 0x3c, 0x8d, 0xd6, 0x03, 0x3c, 0xfe, 0x27, 0xc2, 0x3b, 0xda, + 0x67, 0xa9, 0x3b, 0xe9, 0xef, 0xc1, 0x3b, 0xab, 0x9b, 0x9d, 0x3b, 0x64, 0xad, + 0x0c, 0x3c, 0x62, 0x44, 0xa6, 0x3b, 0x53, 0x87, 0xa7, 0x3b, 0x4d, 0xa9, 0xa1, + 0x3b, 0x33, 0x38, 0x92, 0x3b, 0x1a, 0x0d, 0xe8, 0x3b, 0xda, 0x1d, 0xff, 0x3b, + 0x69, 0x33, 0xe1, 0x3b, 0x0d, 0xed, 0xf5, 0x3b, 0xa2, 0x82, 0x93, 0x3b, 0x59, + 0x7d, 0xdf, 0x3b, 0x3a, 0x5d, 0x80, 0x3b, 0x20, 0x50, 0xb1, 0x3b, 0xee, 0x64, + 0xec, 0x3b, 0xeb, 0x2b, 0xf1, 0x3b, 0xa0, 0x96, 0xc4, 0x3b, 0x29, 0xdc, 0x88, + 0x3b, 0x92, 0x9b, 0xaf, 0x3b, 0xb9, 0x15, 0xe6, 0x3b, 0xad, 0x85, 0x95, 0x3b, + 0xb2, 0x3a, 0xc9, 0x3b, 0xcd, 0x48, 0xc7, 0x3b, 0x47, 0x5b, 0x08, 0x3c, 0x8d, + 0x63, 0xbe, 0x3b, 0xa4, 0xc0, 0x8d, 0x3b, 0x91, 0xf7, 0xae, 0x3b, 0x98, 0xdd, + 0x92, 0x3b, 0x2c, 0xfe, 0xb5, 0x3b, 0x03, 0x40, 0xad, 0x3b, 0x76, 0x64, 0x73, + 0x3b, 0xac, 0x52, 0xae, 0x3b, 0x06, 0xcc, 0xd2, 0x3b, 0x01, 0x7b, 0xa0, 0x3b, + 0xac, 0x67, 0xd4, 0x3b, 0x2d, 0x3a, 0xfc, 0x3b, 0x81, 0x8f, 0xad, 0x3b, 0xae, + 0xc9, 0xcb, 0x3b, 0xc7, 0xe3, 0xf3, 0x3b, 0xbf, 0xce, 0xda, 0x3b, 0xb6, 0x27, + 0xe2, 0x3b, 0x05, 0xf9, 0xb6, 0x3b, 0x12, 0xd2, 0x15, 0x3c, 0x93, 0xbc, 0xe6, + 0x3b, 0x5e, 0x19, 0x6e, 0x3b, 0x4e, 0x57, 0xe9, 0x3b, 0x5b, 0x8e, 0x12, 0x3c, + 0x32, 0x9f, 0xb8, 0x3b, 0x10, 0x17, 0xbd, 0x3b, 0xde, 0xa4, 0x0b, 0x3c, 0x14, + 0xda, 0xa2, 0x3b, 0x5f, 0x00, 0xc5, 0x3b, 0x8f, 0xd5, 0xcb, 0x3b, 0xff, 0xb6, + 0xa1, 0x3b, 0x97, 0x44, 0x09, 0x3c, 0x7e, 0x30, 0x18, 0x3c, 0x52, 0xa2, 0x22, + 0x3c, 0xcd, 0xfe, 0xa5, 0x3b, 0x30, 0xec, 0xd4, 0x3b, 0xfc, 0xfa, 0xa5, 0x3b, + 0xab, 0x8d, 0x08, 0x3c, 0x4e, 0xe2, 0xc5, 0x3b, 0x83, 0x80, 0xb6, 0x3b, 0xbf, + 0xbc, 0x30, 0x3c, 0x53, 0xc1, 0xf5, 0x3b, 0x13, 0x74, 0xa2, 0x3b, 0x7a, 0x61, + 0xcb, 0x3b, 0xf9, 0xc9, 0xbc, 0x3b, 0x84, 0x85, 0xc4, 0x3b, 0x95, 0x6e, 0xc7, + 0x3b, 0xf0, 0x90, 0x13, 0x3c, 0xcc, 0x3e, 0xcf, 0x3b, 0xb6, 0xd3, 0x88, 0x3b, + 0x08, 0x19, 0x9b, 0x3b, 0xb5, 0x8b, 0xdc, 0x3b, 0xae, 0xe0, 0x80, 0x3b, 0xdf, + 0x38, 0xb4, 0x3b, 0xd6, 0x74, 0x22, 0x3c, 0xb8, 0xec, 0x4b, 0x3b, 0xb0, 0x1f, + 0xa9, 0x3b, 0xe2, 0x3e, 0x0c, 0x3c, 0x3a, 0xe1, 0x05, 0x3c, 0x36, 0x00, 0x00, + 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, + 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x32, 0x5f, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, + 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, + 0x65, 0x61, 0x64, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x8a, + 0xec, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x58, 0x06, 0x00, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0x1c, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0xf3, 0xff, + 0xff, 0x0c, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0xd7, 0x8a, 0x53, 0x3b, 0x38, 0xdb, 0x39, 0x3b, 0x26, 0x99, 0x4d, 0x3b, + 0x6c, 0xd5, 0x12, 0x3b, 0xcc, 0x46, 0x25, 0x3b, 0x4b, 0x9a, 0xe8, 0x3a, 0xd1, + 0xff, 0x27, 0x3b, 0xc5, 0x60, 0x07, 0x3b, 0x66, 0xaa, 0x0e, 0x3b, 0x2a, 0x4d, + 0x06, 0x3b, 0x7e, 0x98, 0x08, 0x3b, 0xd2, 0x44, 0x29, 0x3b, 0x8c, 0x7b, 0x39, + 0x3b, 0xf6, 0xdc, 0x01, 0x3b, 0x1f, 0xea, 0x21, 0x3b, 0xd0, 0x34, 0x02, 0x3b, + 0x98, 0x0b, 0x59, 0x3b, 0x6c, 0x69, 0x35, 0x3b, 0x68, 0x68, 0xfc, 0x3a, 0x47, + 0x6b, 0x1b, 0x3b, 0x45, 0x2b, 0x20, 0x3b, 0xb1, 0x7a, 0x01, 0x3b, 0x95, 0x2e, + 0x0f, 0x3b, 0x66, 0x5b, 0x27, 0x3b, 0xe6, 0x6e, 0x4e, 0x3b, 0x5e, 0xac, 0x0d, + 0x3b, 0x30, 0x90, 0x22, 0x3b, 0x54, 0x9e, 0x2d, 0x3b, 0xc8, 0x19, 0xea, 0x3a, + 0x8e, 0x3c, 0x23, 0x3b, 0x65, 0x70, 0x25, 0x3b, 0xf4, 0x79, 0x14, 0x3b, 0x29, + 0x49, 0x13, 0x3b, 0xfc, 0x2a, 0x40, 0x3b, 0x5c, 0x34, 0x3b, 0x3b, 0x2a, 0x52, + 0xf8, 0x3a, 0x6e, 0x51, 0x18, 0x3b, 0x53, 0x24, 0xf6, 0x3a, 0x33, 0x76, 0x24, + 0x3b, 0x60, 0xdf, 0x0f, 0x3b, 0xc5, 0x27, 0x0d, 0x3b, 0xfb, 0x7e, 0x37, 0x3b, + 0xa8, 0x98, 0x10, 0x3b, 0x37, 0xf8, 0x30, 0x3b, 0x0b, 0xda, 0x61, 0x3b, 0x7d, + 0x9b, 0x4a, 0x3b, 0xa1, 0xd6, 0x0e, 0x3b, 0x33, 0x87, 0x27, 0x3b, 0x23, 0x9d, + 0x40, 0x3b, 0x39, 0xec, 0x20, 0x3b, 0xef, 0xfa, 0x06, 0x3b, 0x9c, 0x98, 0x0d, + 0x3b, 0x47, 0x53, 0x03, 0x3b, 0x99, 0x43, 0x1d, 0x3b, 0x08, 0xe1, 0x01, 0x3b, + 0x70, 0x34, 0x14, 0x3b, 0xae, 0xfd, 0x61, 0x3b, 0xeb, 0xc0, 0x0e, 0x3b, 0x12, + 0x1f, 0x21, 0x3b, 0xf5, 0xba, 0x03, 0x3b, 0x19, 0xb4, 0x17, 0x3b, 0x36, 0x92, + 0x2d, 0x3b, 0x4f, 0xbd, 0x36, 0x3b, 0xb0, 0x11, 0x20, 0x3b, 0x62, 0x00, 0x52, + 0x3b, 0x8e, 0x5e, 0x1c, 0x3b, 0x9a, 0x5c, 0x20, 0x3b, 0x2f, 0xc8, 0x1a, 0x3b, + 0x86, 0xf1, 0x2c, 0x3b, 0x26, 0x6d, 0x13, 0x3b, 0x2a, 0x7a, 0xfa, 0x3a, 0xa6, + 0x9d, 0x10, 0x3b, 0xb7, 0xd3, 0x0e, 0x3b, 0xa1, 0xd2, 0x3e, 0x3b, 0xe1, 0x4e, + 0x0b, 0x3b, 0xa4, 0x34, 0x1c, 0x3b, 0x23, 0x67, 0xe9, 0x3a, 0x8c, 0xb7, 0xef, + 0x3a, 0x58, 0x7c, 0x30, 0x3b, 0x75, 0x25, 0x22, 0x3b, 0xce, 0x58, 0x81, 0x3b, + 0x37, 0x05, 0x77, 0x3b, 0xa9, 0xc4, 0x22, 0x3b, 0xfd, 0x03, 0x32, 0x3b, 0x64, + 0xd1, 0x06, 0x3b, 0xb2, 0x45, 0x11, 0x3b, 0x69, 0xf3, 0xf1, 0x3a, 0xb1, 0xda, + 0x02, 0x3b, 0x36, 0xa0, 0x42, 0x3b, 0x2c, 0x4e, 0x45, 0x3b, 0x04, 0xbf, 0x0c, + 0x3b, 0x8e, 0x3a, 0x46, 0x3b, 0x07, 0xad, 0x3e, 0x3b, 0x82, 0xcf, 0x06, 0x3b, + 0xdc, 0xa6, 0xe6, 0x3a, 0x11, 0xf5, 0x10, 0x3b, 0x09, 0xef, 0xf3, 0x3a, 0x6d, + 0x02, 0x11, 0x3b, 0xcf, 0x6f, 0xff, 0x3a, 0x0a, 0xb6, 0x6e, 0x3b, 0x01, 0x9d, + 0x25, 0x3b, 0x2e, 0x1a, 0x25, 0x3b, 0xc7, 0xa8, 0x34, 0x3b, 0x9e, 0x30, 0x24, + 0x3b, 0xe5, 0x89, 0xe8, 0x3a, 0x9e, 0x0e, 0x3b, 0x3b, 0xcf, 0x03, 0x0d, 0x3b, + 0xcf, 0xa9, 0x37, 0x3b, 0xde, 0xee, 0x1e, 0x3b, 0x00, 0x9d, 0x08, 0x3b, 0x9a, + 0xc3, 0x30, 0x3b, 0xcd, 0xb2, 0x14, 0x3b, 0x32, 0xbe, 0x29, 0x3b, 0x1e, 0x0a, + 0x0e, 0x3b, 0xb9, 0x86, 0x1c, 0x3b, 0x69, 0x25, 0x1d, 0x3b, 0x3d, 0xf6, 0x33, + 0x3b, 0x41, 0x5e, 0x04, 0x3b, 0xb0, 0x40, 0x35, 0x3b, 0xa8, 0x47, 0x16, 0x3b, + 0xfa, 0x67, 0x22, 0x3b, 0x0d, 0x6a, 0x01, 0x3b, 0x9d, 0xdb, 0x0d, 0x3b, 0x71, + 0xc1, 0x45, 0x3b, 0xe3, 0xb3, 0x05, 0x3b, 0x50, 0xf0, 0x23, 0x3b, 0xe0, 0xfa, + 0x4c, 0x3b, 0xb7, 0xaa, 0x1d, 0x3b, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, + 0x32, 0x64, 0x5f, 0x31, 0x31, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xfe, 0xf2, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x64, 0x06, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5a, 0xec, + 0xff, 0xff, 0x10, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x60, 0xb4, 0xc7, 0x3b, 0xf2, 0x84, 0xdd, + 0x3b, 0x43, 0xf1, 0x08, 0x3c, 0x44, 0xaf, 0xbc, 0x3b, 0x85, 0x80, 0xa0, 0x3b, + 0xa1, 0xa5, 0xa5, 0x3b, 0xa5, 0x21, 0xd8, 0x3b, 0x03, 0xc9, 0x0a, 0x3c, 0x16, + 0x3b, 0xe2, 0x3b, 0x28, 0xd7, 0x17, 0x3c, 0xd1, 0x70, 0x14, 0x3c, 0x68, 0x0a, + 0xc2, 0x3b, 0x88, 0xea, 0x03, 0x3c, 0x4b, 0xd8, 0x27, 0x3c, 0xf2, 0x2b, 0xdb, + 0x3b, 0x1b, 0x19, 0x93, 0x3b, 0x08, 0x5a, 0xfe, 0x3b, 0x1d, 0x52, 0xa1, 0x3b, + 0xa4, 0x8d, 0xa9, 0x3b, 0x15, 0x51, 0x38, 0x3b, 0xe8, 0xaf, 0xb7, 0x3b, 0x20, + 0xf5, 0xe2, 0x3b, 0xad, 0xb9, 0x5c, 0x3b, 0xd7, 0x58, 0xc7, 0x3b, 0x4d, 0xf2, + 0xdc, 0x3b, 0x09, 0x90, 0xd8, 0x3b, 0xa0, 0x21, 0x26, 0x3c, 0xa6, 0x94, 0x2a, + 0x3c, 0x34, 0xde, 0x15, 0x3c, 0x96, 0xa8, 0x0e, 0x3c, 0xec, 0xf1, 0x62, 0x3b, + 0x86, 0x75, 0xef, 0x3b, 0xd2, 0x3d, 0xf7, 0x3b, 0x06, 0xfb, 0xfb, 0x3b, 0xff, + 0xaf, 0xa9, 0x3b, 0x84, 0xaf, 0xee, 0x3b, 0xed, 0x73, 0x92, 0x3b, 0x26, 0xd9, + 0xc9, 0x3b, 0xf0, 0xe3, 0x4d, 0x3c, 0x54, 0x6d, 0xae, 0x3b, 0x95, 0xb2, 0xf4, + 0x3b, 0x4c, 0x06, 0x10, 0x3c, 0xc9, 0x2c, 0x26, 0x3c, 0xf4, 0x94, 0xac, 0x3b, + 0xb6, 0x91, 0x8f, 0x3b, 0xb3, 0x7f, 0x96, 0x3b, 0xd8, 0x26, 0xda, 0x3b, 0x22, + 0xf7, 0xd5, 0x3b, 0x2f, 0x36, 0xf2, 0x3b, 0x4f, 0x35, 0xae, 0x3b, 0xbd, 0xf4, + 0x9f, 0x3b, 0x57, 0xea, 0xeb, 0x3b, 0x0f, 0xd9, 0xc7, 0x3b, 0xa2, 0xdb, 0xf5, + 0x3b, 0x53, 0x20, 0xce, 0x3b, 0x79, 0x60, 0x31, 0x3c, 0x20, 0x91, 0xb4, 0x3b, + 0xbc, 0x23, 0x15, 0x3c, 0x83, 0x1a, 0xf2, 0x3b, 0x09, 0x71, 0xc9, 0x3b, 0xf6, + 0x17, 0xb0, 0x3b, 0x9d, 0xc6, 0xc5, 0x3b, 0x71, 0x97, 0x22, 0x3c, 0x2c, 0x9e, + 0xf8, 0x3b, 0xc9, 0x79, 0x15, 0x3c, 0x0a, 0xfe, 0xaa, 0x3b, 0x83, 0x58, 0xa0, + 0x3b, 0xbc, 0x63, 0x9c, 0x3b, 0x43, 0x51, 0xa5, 0x3b, 0x33, 0xe5, 0xe2, 0x3b, + 0x3f, 0xb3, 0xd8, 0x3b, 0xe6, 0xe2, 0xbf, 0x3b, 0xce, 0xed, 0xe9, 0x3b, 0xdb, + 0x3f, 0xa1, 0x3b, 0xec, 0x47, 0xc7, 0x3b, 0x9d, 0xa7, 0xc5, 0x3b, 0x2e, 0xab, + 0x03, 0x3c, 0xfd, 0x97, 0xf0, 0x3b, 0x61, 0x09, 0x08, 0x3c, 0x4c, 0xe2, 0xfb, + 0x3b, 0x9b, 0x41, 0xa7, 0x3b, 0xbb, 0xb0, 0x9f, 0x3b, 0x6c, 0xb1, 0xd0, 0x3b, + 0x35, 0x03, 0x71, 0x3b, 0x63, 0x93, 0xc3, 0x3b, 0xbe, 0xfd, 0xda, 0x3b, 0x99, + 0xfe, 0xfa, 0x3b, 0xa3, 0x6f, 0x36, 0x3c, 0xf2, 0x06, 0xec, 0x3b, 0x05, 0xbd, + 0x92, 0x3b, 0x13, 0xea, 0x15, 0x3c, 0xbf, 0xa8, 0xd0, 0x3b, 0xf5, 0x2f, 0xf8, + 0x3b, 0xb9, 0xd4, 0x2a, 0x3c, 0x3d, 0x35, 0x1f, 0x3c, 0x24, 0xb2, 0x2c, 0x3c, + 0x49, 0x7c, 0x1a, 0x3c, 0x55, 0x86, 0xdf, 0x3b, 0xd6, 0xb4, 0x98, 0x3b, 0x78, + 0x8e, 0xd0, 0x3b, 0xa1, 0x51, 0xe4, 0x3b, 0xa4, 0x60, 0x92, 0x3b, 0x8e, 0x86, + 0x48, 0x3b, 0xdc, 0xc6, 0xe7, 0x3b, 0x21, 0xaf, 0xeb, 0x3b, 0xfb, 0x7b, 0x20, + 0x3c, 0xf6, 0x56, 0xf9, 0x3b, 0x14, 0xbc, 0x29, 0x3c, 0x1e, 0xf5, 0xca, 0x3b, + 0x33, 0x5f, 0x14, 0x3c, 0xe1, 0x61, 0x8a, 0x3b, 0x37, 0xdf, 0x9f, 0x3b, 0x5b, + 0x1b, 0xff, 0x3b, 0x0b, 0x7f, 0xbc, 0x3b, 0x9d, 0xcd, 0xc8, 0x3b, 0xe2, 0xe4, + 0xdf, 0x3b, 0x03, 0x51, 0xc9, 0x3b, 0xf8, 0x18, 0xc1, 0x3b, 0x70, 0xe5, 0x20, + 0x3c, 0x96, 0xfb, 0xf6, 0x3b, 0x78, 0x83, 0xf1, 0x3b, 0xe9, 0x4e, 0xcd, 0x3b, + 0xd1, 0x25, 0xb4, 0x3b, 0x38, 0xa5, 0xe8, 0x3b, 0xc7, 0x84, 0x12, 0x3c, 0xbd, + 0xb1, 0x20, 0x3c, 0x2f, 0xa2, 0x35, 0x3c, 0x03, 0xee, 0x0d, 0x3c, 0x36, 0x00, + 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, + 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x31, 0x5f, 0x64, 0x65, + 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, + 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x7e, 0xf9, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x64, 0x06, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x28, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x0c, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0xf0, 0x76, 0x2c, 0x3b, 0x4c, 0x26, 0x1e, 0x3b, 0x2a, 0x85, 0x1d, 0x3b, + 0xa7, 0x53, 0x12, 0x3b, 0xce, 0xf3, 0x0e, 0x3b, 0x0f, 0x15, 0x04, 0x3b, 0xce, + 0x92, 0xfe, 0x3a, 0x9b, 0xe7, 0xe1, 0x3a, 0x17, 0xcf, 0x1a, 0x3b, 0xeb, 0x2f, + 0x31, 0x3b, 0x15, 0xe1, 0x66, 0x3b, 0x5a, 0x04, 0x38, 0x3b, 0xd1, 0x2f, 0x19, + 0x3b, 0xb2, 0xf8, 0x1b, 0x3b, 0x63, 0x78, 0x0e, 0x3b, 0x80, 0x63, 0x41, 0x3b, + 0x7e, 0x98, 0x3d, 0x3b, 0xeb, 0x0f, 0x13, 0x3b, 0x31, 0x60, 0x2d, 0x3b, 0xe1, + 0x7f, 0x34, 0x3b, 0x89, 0xa6, 0x2d, 0x3b, 0x18, 0x1e, 0x57, 0x3b, 0x35, 0xcc, + 0x1c, 0x3b, 0x16, 0x67, 0x29, 0x3b, 0xa7, 0x7d, 0x26, 0x3b, 0x3a, 0xee, 0x22, + 0x3b, 0x08, 0x08, 0x62, 0x3b, 0x04, 0xbd, 0x19, 0x3b, 0x44, 0x97, 0x40, 0x3b, + 0x27, 0xea, 0x26, 0x3b, 0x6a, 0xdd, 0x0d, 0x3b, 0xe4, 0x56, 0xfb, 0x3a, 0x4a, + 0x5a, 0x1f, 0x3b, 0x5a, 0x92, 0xff, 0x3a, 0x1c, 0x45, 0x32, 0x3b, 0x3e, 0x91, + 0x28, 0x3b, 0x93, 0x74, 0x5c, 0x3b, 0x1c, 0x54, 0x27, 0x3b, 0xd9, 0xb5, 0x1f, + 0x3b, 0x85, 0x55, 0x18, 0x3b, 0x6f, 0x0e, 0x2f, 0x3b, 0xae, 0x7f, 0x16, 0x3b, + 0x6e, 0x3d, 0x1c, 0x3b, 0xfc, 0x0d, 0xf7, 0x3a, 0x82, 0x18, 0x1b, 0x3b, 0xc5, + 0x09, 0x03, 0x3b, 0xaf, 0xb4, 0x15, 0x3b, 0xa9, 0xee, 0x46, 0x3b, 0x65, 0x6d, + 0x14, 0x3b, 0x29, 0x75, 0x51, 0x3b, 0x0b, 0xf8, 0x1c, 0x3b, 0x61, 0xcd, 0x5c, + 0x3b, 0x05, 0x33, 0x2a, 0x3b, 0xb7, 0x1c, 0x07, 0x3b, 0x26, 0x72, 0x34, 0x3b, + 0x59, 0xe7, 0x3f, 0x3b, 0xd6, 0xe8, 0x21, 0x3b, 0x8a, 0x3a, 0x3d, 0x3b, 0xbe, + 0xf2, 0x1b, 0x3b, 0x76, 0xb4, 0x06, 0x3b, 0xea, 0x1b, 0xfa, 0x3a, 0xeb, 0x0f, + 0xf7, 0x3a, 0x2a, 0x56, 0x2b, 0x3b, 0xca, 0xc0, 0x20, 0x3b, 0x15, 0x3c, 0x45, + 0x3b, 0x98, 0xbe, 0x1d, 0x3b, 0x8c, 0x8d, 0x20, 0x3b, 0xe2, 0x44, 0x58, 0x3b, + 0x05, 0x3b, 0x68, 0x3b, 0x9f, 0xf7, 0x8a, 0x3b, 0xe2, 0xf0, 0xfd, 0x3a, 0x2b, + 0xef, 0xfa, 0x3a, 0x8e, 0xa7, 0x1d, 0x3b, 0xe6, 0xc2, 0xea, 0x3a, 0xf1, 0x17, + 0x30, 0x3b, 0x55, 0x96, 0x1d, 0x3b, 0xf4, 0xfe, 0x07, 0x3b, 0x39, 0xb3, 0xed, + 0x3a, 0x2b, 0x40, 0xfe, 0x3a, 0x84, 0xa2, 0x18, 0x3b, 0xfc, 0x29, 0x22, 0x3b, + 0xc9, 0xae, 0x11, 0x3b, 0xa5, 0x0e, 0x2b, 0x3b, 0x2b, 0x0c, 0x07, 0x3b, 0xf0, + 0x3a, 0x49, 0x3b, 0xdc, 0x3e, 0x47, 0x3b, 0x35, 0x81, 0x1b, 0x3b, 0x9d, 0x0c, + 0xf2, 0x3a, 0x95, 0xae, 0x1b, 0x3b, 0xe2, 0x10, 0x18, 0x3b, 0x85, 0x68, 0x1d, + 0x3b, 0x74, 0x46, 0x52, 0x3b, 0x99, 0xbb, 0x3a, 0x3b, 0x28, 0xf7, 0x44, 0x3b, + 0xb7, 0xfe, 0x5c, 0x3b, 0x21, 0x04, 0x2f, 0x3b, 0x3b, 0x3b, 0x38, 0x3b, 0x92, + 0x09, 0x22, 0x3b, 0xbd, 0xa0, 0x08, 0x3b, 0x60, 0xda, 0x01, 0x3b, 0xcd, 0xce, + 0xe3, 0x3a, 0x59, 0x24, 0x36, 0x3b, 0x0a, 0x66, 0xff, 0x3a, 0xd4, 0x6e, 0x07, + 0x3b, 0xb9, 0x61, 0x17, 0x3b, 0x38, 0xf5, 0x24, 0x3b, 0xd1, 0x3e, 0x4a, 0x3b, + 0x77, 0x2d, 0x19, 0x3b, 0x59, 0x7f, 0x1b, 0x3b, 0xb8, 0x29, 0x0a, 0x3b, 0xfb, + 0xa8, 0x0c, 0x3b, 0xdb, 0xa3, 0x16, 0x3b, 0x33, 0x17, 0x30, 0x3b, 0x9c, 0x16, + 0x51, 0x3b, 0x91, 0x1b, 0x3c, 0x3b, 0x5c, 0xfc, 0x2a, 0x3b, 0x81, 0xb1, 0x0d, + 0x3b, 0x9e, 0x42, 0x20, 0x3b, 0x2e, 0x0d, 0x12, 0x3b, 0xe0, 0x98, 0x13, 0x3b, + 0x8e, 0x42, 0x24, 0x3b, 0x31, 0x04, 0x16, 0x3b, 0x10, 0x6b, 0x0c, 0x3b, 0xb9, + 0xad, 0x14, 0x3b, 0x57, 0x5e, 0x0b, 0x3b, 0x52, 0x65, 0x4b, 0x3b, 0x2f, 0xf2, + 0x17, 0x3b, 0x61, 0x9a, 0x1a, 0x3b, 0x2c, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, + 0x69, 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, + 0x32, 0x64, 0x5f, 0x31, 0x30, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x77, 0x69, + 0x73, 0x65, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, + 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x68, 0x06, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x24, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x6a, 0xf9, 0xff, 0xff, 0x14, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xcb, 0x37, 0xb8, 0x3b, 0x43, 0xf6, 0xc2, 0x3b, 0x44, 0xf2, 0xe8, 0x3b, 0x8f, + 0xc2, 0xca, 0x3b, 0xc4, 0x3c, 0xd0, 0x3b, 0xce, 0x26, 0xf3, 0x3b, 0x85, 0x6f, + 0xb5, 0x3b, 0xa4, 0x85, 0xd8, 0x3b, 0xa7, 0x2b, 0xd0, 0x3b, 0x9e, 0x75, 0xa0, + 0x3b, 0x9c, 0xc0, 0xdb, 0x3b, 0x19, 0x83, 0x07, 0x3c, 0x97, 0x4e, 0xeb, 0x3b, + 0xa3, 0x3c, 0x05, 0x3c, 0x22, 0x33, 0x26, 0x3c, 0x87, 0xb0, 0x8e, 0x3b, 0x61, + 0x69, 0x09, 0x3c, 0x2e, 0x3d, 0xfd, 0x3b, 0xe0, 0x36, 0xad, 0x3b, 0x20, 0x8e, + 0xa4, 0x3b, 0x5d, 0x17, 0x01, 0x3c, 0x10, 0x48, 0xc9, 0x3b, 0x1f, 0x7e, 0x6e, + 0x3b, 0x3c, 0x72, 0xde, 0x3b, 0xb7, 0xfc, 0x1e, 0x3c, 0x5b, 0x4d, 0x91, 0x3b, + 0xc7, 0x0b, 0xb9, 0x3b, 0x3f, 0x6b, 0xb1, 0x3b, 0x11, 0x9e, 0xe3, 0x3b, 0x5c, + 0xec, 0x22, 0x3c, 0xae, 0x0f, 0xe5, 0x3b, 0xcc, 0xe8, 0x71, 0x3b, 0x80, 0x02, + 0x04, 0x3c, 0xe1, 0xfd, 0x00, 0x3c, 0x34, 0xb5, 0xc4, 0x3b, 0x8c, 0xb7, 0x3a, + 0x3c, 0xde, 0xe4, 0xaa, 0x3b, 0x3e, 0xfa, 0xf0, 0x3b, 0x4f, 0x3f, 0x0c, 0x3c, + 0xa8, 0xb8, 0xa7, 0x3b, 0xb1, 0xb7, 0xe1, 0x3b, 0x81, 0x09, 0x94, 0x3b, 0xc6, + 0xde, 0x10, 0x3c, 0x2f, 0xbe, 0x2c, 0x3c, 0xfe, 0x65, 0x01, 0x3c, 0x49, 0x9a, + 0x8a, 0x3b, 0x3d, 0x56, 0xd7, 0x3b, 0x21, 0x5e, 0xc4, 0x3b, 0x61, 0x7d, 0x0d, + 0x3c, 0xf9, 0x5a, 0x89, 0x3b, 0x69, 0xb0, 0xe0, 0x3b, 0x8f, 0xa5, 0xf7, 0x3b, + 0x76, 0x26, 0x03, 0x3c, 0xcb, 0x44, 0xe1, 0x3b, 0x28, 0x7a, 0x8d, 0x3b, 0xe5, + 0x1a, 0xea, 0x3b, 0x64, 0xdd, 0x9c, 0x3b, 0x57, 0xb5, 0x70, 0x3b, 0x22, 0xee, + 0xed, 0x3b, 0xa3, 0x21, 0x7c, 0x3b, 0xaf, 0x49, 0x8a, 0x3b, 0x56, 0x4a, 0xdc, + 0x3b, 0x23, 0xe9, 0x43, 0x3c, 0x2c, 0x58, 0xcb, 0x3b, 0x12, 0xe8, 0x9f, 0x3b, + 0xd0, 0xd2, 0xf4, 0x3b, 0x96, 0x9d, 0x9f, 0x3b, 0x48, 0x20, 0xea, 0x3b, 0x63, + 0x63, 0x0f, 0x3c, 0xd0, 0x99, 0xd0, 0x3b, 0x70, 0xd2, 0xd6, 0x3b, 0x67, 0xb5, + 0x13, 0x3c, 0x79, 0x9d, 0xab, 0x3b, 0x5b, 0x4d, 0x73, 0x3b, 0x2e, 0x3a, 0x9d, + 0x3b, 0x6a, 0x9c, 0xc9, 0x3b, 0x44, 0xff, 0x8b, 0x3b, 0x13, 0xae, 0xae, 0x3b, + 0x28, 0x06, 0x86, 0x3b, 0x05, 0x59, 0xae, 0x3b, 0x95, 0x1e, 0xd4, 0x3b, 0x4a, + 0x6e, 0xa7, 0x3b, 0xc9, 0x7a, 0x15, 0x3c, 0xcb, 0x63, 0xbe, 0x3b, 0x82, 0x8a, + 0x6f, 0x3b, 0x86, 0x3f, 0xd7, 0x3b, 0xfb, 0xba, 0x15, 0x3c, 0x8f, 0xb8, 0x1c, + 0x3c, 0xa9, 0xf4, 0xea, 0x3b, 0xe2, 0x65, 0x38, 0x3c, 0x8b, 0x4a, 0xd3, 0x3b, + 0xb7, 0xae, 0xdf, 0x3b, 0xbb, 0x74, 0xff, 0x3b, 0x0c, 0x0d, 0x92, 0x3b, 0x2e, + 0x0c, 0x55, 0x3c, 0xb5, 0xf6, 0xff, 0x3b, 0xa5, 0x05, 0x2f, 0x3c, 0x95, 0xbe, + 0xbd, 0x3b, 0xc3, 0x7b, 0x9e, 0x3b, 0xe2, 0xce, 0xda, 0x3b, 0xe9, 0xfd, 0xbf, + 0x3b, 0x57, 0x1c, 0x9b, 0x3b, 0xf2, 0x1f, 0x62, 0x3b, 0x8b, 0x89, 0xf3, 0x3b, + 0x83, 0xb6, 0x8a, 0x3b, 0x4c, 0x0f, 0xd6, 0x3b, 0x98, 0xc6, 0x00, 0x3c, 0x81, + 0xd3, 0x10, 0x3c, 0xe8, 0x22, 0x3b, 0x3c, 0x0e, 0xfa, 0x19, 0x3c, 0x64, 0x7e, + 0xe6, 0x3b, 0x12, 0x99, 0xce, 0x3b, 0x20, 0x57, 0x99, 0x3b, 0x51, 0xa6, 0xe1, + 0x3b, 0x5f, 0x8d, 0xb7, 0x3b, 0xce, 0xfc, 0x86, 0x3b, 0x17, 0x3d, 0xdf, 0x3b, + 0xd1, 0x68, 0xf0, 0x3b, 0x20, 0x38, 0xd5, 0x3b, 0x13, 0x4e, 0xa1, 0x3b, 0x6d, + 0x6f, 0x79, 0x3b, 0x4f, 0xf4, 0xc3, 0x3b, 0xbd, 0x9f, 0x00, 0x3c, 0x0f, 0xa4, + 0xf4, 0x3b, 0x6a, 0x1f, 0x13, 0x3c, 0xbb, 0x81, 0x83, 0x3b, 0xaf, 0xc6, 0xf5, + 0x3b, 0x5c, 0xa1, 0xf7, 0x3b, 0x36, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x31, 0x30, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, + 0x65, 0x2f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x77, 0x69, 0x73, 0x65, 0x5f, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x1a, 0x00, + 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0xc4, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x12, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, + 0x03, 0x86, 0x3c, 0x60, 0xfe, 0xd9, 0x3c, 0xcc, 0x1c, 0x47, 0x3b, 0xda, 0xcf, + 0x55, 0x3b, 0xa8, 0x02, 0x3d, 0x3c, 0x15, 0x1e, 0x19, 0x3d, 0xbb, 0x9a, 0x94, + 0x3c, 0x90, 0x5f, 0x8e, 0x3a, 0x21, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x62, 0x69, + 0x6c, 0x65, 0x6e, 0x65, 0x74, 0x56, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x5f, 0x30, 0x2f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2f, 0x72, + 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd6, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x19, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + 0xf2, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, +}; +const int g_person_detect_model_data_len = 300568; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.h new file mode 100644 index 0000000..5d1b59f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_detect_model_data.h @@ -0,0 +1,27 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This is a standard TensorFlow Lite model file that has been converted into a +// C data array, so it can be easily compiled into a binary for devices that +// don't have a file system. It was created using the command: +// xxd -i person_detect.tflite > person_detect_model_data.cc + +#ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_PERSON_DETECT_MODEL_DATA_H_ +#define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_PERSON_DETECT_MODEL_DATA_H_ + +extern const unsigned char g_person_detect_model_data[]; +extern const int g_person_detect_model_data_len; + +#endif // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_EXPERIMENTAL_PERSON_DETECT_MODEL_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.cc b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.cc new file mode 100644 index 0000000..1637159 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.cc @@ -0,0 +1,792 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// See the header for documentation on the meaning of this data. + +#include "tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.h" + +#include "tensorflow/lite/micro/examples/person_detection_experimental/model_settings.h" + +const int g_person_data_size = kMaxImageSize; +const uint8_t g_person_data[g_person_data_size] = { + 0x8b, 0x90, 0x92, 0x9d, 0xad, 0xb7, 0xc4, 0xce, 0xd0, 0xcf, 0xdd, 0xe8, + 0xe1, 0xff, 0xe4, 0xdd, 0xfa, 0xe6, 0x38, 0x42, 0x44, 0x2f, 0x26, 0x28, + 0x42, 0x4d, 0x47, 0x39, 0xcb, 0xff, 0xff, 0xf2, 0xf9, 0xed, 0xff, 0xe8, + 0xff, 0xff, 0xff, 0xf8, 0xe0, 0xee, 0xed, 0xe0, 0xd3, 0xd2, 0xc9, 0xbc, + 0xb7, 0xac, 0xa8, 0xa6, 0x9f, 0x97, 0x92, 0x8f, 0x8d, 0x86, 0x7e, 0x72, + 0x7e, 0x81, 0x7b, 0x7a, 0x72, 0x6f, 0x69, 0x66, 0x64, 0x62, 0x61, 0x5e, + 0x5d, 0x5d, 0x58, 0x57, 0x55, 0x55, 0x57, 0x56, 0x52, 0x52, 0x50, 0x53, + 0x55, 0x51, 0x54, 0x51, 0x51, 0x53, 0x54, 0x56, 0x56, 0x58, 0x5b, 0x5a, + 0x89, 0x8d, 0x92, 0x9f, 0xab, 0xb9, 0xc0, 0xd4, 0xd4, 0xdf, 0xdf, 0xf1, + 0xf0, 0xff, 0xf0, 0xed, 0xfa, 0xf4, 0x39, 0x44, 0x44, 0x2f, 0x27, 0x28, + 0x44, 0x50, 0x47, 0x40, 0xea, 0xff, 0xdf, 0xf7, 0xf0, 0xfd, 0xfe, 0xf3, + 0xff, 0xff, 0xf0, 0xf4, 0xed, 0xf1, 0xf1, 0xe7, 0xdb, 0xd5, 0xc5, 0xc5, + 0xb2, 0xab, 0xa4, 0x9c, 0x95, 0x8f, 0x90, 0x8c, 0x84, 0x83, 0x79, 0x72, + 0x81, 0x80, 0x79, 0x78, 0x75, 0x6f, 0x6b, 0x65, 0x62, 0x62, 0x60, 0x5f, + 0x5c, 0x59, 0x58, 0x58, 0x58, 0x58, 0x56, 0x58, 0x55, 0x4d, 0x55, 0x56, + 0x55, 0x55, 0x55, 0x54, 0x55, 0x58, 0x59, 0x57, 0x58, 0x59, 0x5c, 0x5d, + 0x8a, 0x8e, 0x96, 0xa3, 0xa9, 0xb8, 0xbd, 0xd0, 0xd5, 0xe0, 0xe8, 0xe7, + 0xe7, 0xff, 0xe5, 0xff, 0xf5, 0xff, 0x38, 0x40, 0x43, 0x2f, 0x25, 0x28, + 0x45, 0x4e, 0x43, 0x3e, 0xf1, 0xf0, 0xfe, 0xff, 0xfc, 0xf9, 0xff, 0xff, + 0xfa, 0xea, 0xfd, 0xf3, 0xf4, 0xef, 0xe7, 0xd2, 0xe1, 0xc9, 0xcb, 0xc2, + 0xbc, 0xb4, 0xad, 0xa1, 0x98, 0x90, 0x8c, 0x84, 0x7c, 0x79, 0x73, 0x7c, + 0x80, 0x7f, 0x78, 0x75, 0x74, 0x6e, 0x69, 0x6a, 0x65, 0x5f, 0x5e, 0x5a, + 0x59, 0x56, 0x5b, 0x58, 0x5b, 0x5b, 0x5a, 0x54, 0x4f, 0x54, 0x57, 0x56, + 0x57, 0x56, 0x52, 0x52, 0x55, 0x56, 0x55, 0x59, 0x59, 0x5a, 0x5c, 0x5d, + 0x88, 0x8d, 0x96, 0x9d, 0xa6, 0xb6, 0xc2, 0xc3, 0xd1, 0xd9, 0xf1, 0xea, + 0xe1, 0xf3, 0xf8, 0xff, 0xeb, 0xf9, 0x3c, 0x3f, 0x45, 0x30, 0x25, 0x28, + 0x44, 0x4e, 0x43, 0x42, 0xe8, 0xfb, 0xf2, 0xe4, 0xde, 0xff, 0xff, 0xed, + 0xfa, 0xe4, 0xee, 0xff, 0xed, 0xf8, 0xe8, 0xe8, 0xe1, 0xcf, 0xcb, 0xbe, + 0xb7, 0xb5, 0xab, 0xa3, 0xa3, 0x98, 0x91, 0x89, 0x83, 0x7b, 0x71, 0x74, + 0x70, 0x6c, 0x6d, 0x6d, 0x6e, 0x6b, 0x6a, 0x66, 0x64, 0x5e, 0x5f, 0x5f, + 0x57, 0x5d, 0x5a, 0x5d, 0x5c, 0x5b, 0x59, 0x50, 0x50, 0x59, 0x56, 0x56, + 0x54, 0x58, 0x58, 0x5a, 0x58, 0x58, 0x5a, 0x5a, 0x5c, 0x5c, 0x5c, 0x60, + 0x87, 0x8e, 0x93, 0x9e, 0xaa, 0xb7, 0xba, 0xc1, 0xda, 0xcc, 0xef, 0xe6, + 0xf8, 0xe7, 0xe4, 0xeb, 0xdd, 0xf9, 0x42, 0x41, 0x48, 0x31, 0x23, 0x28, + 0x40, 0x4c, 0x42, 0x43, 0xf5, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, + 0xf5, 0xf6, 0xf1, 0xf0, 0xdc, 0xf7, 0xe3, 0xec, 0xd9, 0xd1, 0xcb, 0xc0, + 0xbc, 0xaf, 0xac, 0xa9, 0xa0, 0x94, 0x90, 0x89, 0x84, 0x76, 0x74, 0x77, + 0x73, 0x74, 0x69, 0x65, 0x62, 0x5f, 0x5d, 0x63, 0x5e, 0x5d, 0x5e, 0x5e, + 0x5b, 0x5d, 0x5b, 0x5b, 0x5b, 0x5b, 0x55, 0x4f, 0x57, 0x5b, 0x59, 0x59, + 0x5c, 0x58, 0x57, 0x59, 0x59, 0x5a, 0x5a, 0x5f, 0x5e, 0x5d, 0x5d, 0x60, + 0x85, 0x8b, 0x94, 0xa0, 0xab, 0xad, 0xbf, 0xc9, 0xd2, 0xdc, 0xda, 0xef, + 0xef, 0xf6, 0xe9, 0xea, 0xf1, 0xff, 0x48, 0x43, 0x4a, 0x32, 0x25, 0x27, + 0x43, 0x4e, 0x40, 0x47, 0xff, 0xe8, 0xff, 0xf0, 0xf0, 0xf9, 0xff, 0xff, + 0xe7, 0xfd, 0xe4, 0xf2, 0xf4, 0xe3, 0xe3, 0xe6, 0xdf, 0xd8, 0xca, 0xbb, + 0xb2, 0xac, 0xab, 0x9c, 0x9e, 0x96, 0x8f, 0x89, 0x7d, 0x73, 0x7b, 0x78, + 0x7b, 0x77, 0x71, 0x6e, 0x65, 0x64, 0x60, 0x58, 0x57, 0x56, 0x5a, 0x5d, + 0x5d, 0x5c, 0x60, 0x5c, 0x5c, 0x57, 0x52, 0x58, 0x57, 0x5d, 0x5b, 0x5a, + 0x58, 0x58, 0x5a, 0x5a, 0x5b, 0x5a, 0x5c, 0x5f, 0x5f, 0x60, 0x63, 0x66, + 0x85, 0x8c, 0x91, 0x9c, 0xa5, 0xb3, 0xba, 0xc7, 0xd6, 0xdd, 0xe6, 0xd9, + 0xdd, 0xe0, 0xf3, 0xf1, 0xfd, 0xff, 0x51, 0x48, 0x4c, 0x35, 0x23, 0x26, + 0x45, 0x49, 0x40, 0x4b, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xf0, 0xe5, + 0xe4, 0xff, 0xda, 0xe6, 0xee, 0xf4, 0xef, 0xd3, 0xd2, 0xd0, 0xc9, 0xc0, + 0xb2, 0xb1, 0xa8, 0xa0, 0x9b, 0x95, 0x93, 0x85, 0x79, 0x78, 0x81, 0x7a, + 0x75, 0x75, 0x74, 0x70, 0x6a, 0x67, 0x65, 0x62, 0x5d, 0x5c, 0x57, 0x53, + 0x51, 0x54, 0x53, 0x56, 0x5c, 0x50, 0x56, 0x5b, 0x5b, 0x5b, 0x5e, 0x57, + 0x58, 0x5b, 0x59, 0x5d, 0x5d, 0x5e, 0x5c, 0x60, 0x61, 0x64, 0x69, 0x6e, + 0x7a, 0x88, 0x8d, 0x9a, 0xa3, 0xae, 0xb8, 0xc0, 0xcc, 0xd5, 0xd8, 0xe8, + 0xe5, 0xe8, 0xfb, 0xf1, 0xed, 0xf8, 0x5b, 0x4b, 0x54, 0x3a, 0x25, 0x26, + 0x46, 0x4b, 0x40, 0x52, 0xea, 0xff, 0xe7, 0xf7, 0xff, 0xea, 0xe9, 0xf5, + 0xcc, 0xe1, 0xf5, 0xe3, 0xd2, 0xf6, 0xe6, 0xe0, 0xdc, 0xc4, 0xc8, 0xbc, + 0xb5, 0xad, 0xa7, 0xa2, 0x99, 0x94, 0x8f, 0x87, 0x78, 0x7f, 0x7c, 0x78, + 0x77, 0x73, 0x6f, 0x6c, 0x69, 0x66, 0x63, 0x61, 0x61, 0x5c, 0x5c, 0x5c, + 0x58, 0x57, 0x52, 0x4d, 0x4f, 0x50, 0x54, 0x5b, 0x5a, 0x59, 0x5b, 0x5b, + 0x5c, 0x5b, 0x5d, 0x5b, 0x5e, 0x5e, 0x60, 0x67, 0x65, 0x6a, 0x6a, 0x72, + 0x87, 0x8f, 0x91, 0x94, 0x99, 0x9c, 0xa9, 0xb3, 0xc6, 0xca, 0xd6, 0xdf, + 0xe2, 0xdf, 0xef, 0xea, 0xf4, 0xf4, 0x69, 0x48, 0x5d, 0x42, 0x25, 0x25, + 0x45, 0x51, 0x43, 0x59, 0xef, 0xfe, 0xff, 0xfd, 0xfc, 0xee, 0xff, 0xfb, + 0xfd, 0xf9, 0xe4, 0xf4, 0xeb, 0xf6, 0xd2, 0xdd, 0xd3, 0xcb, 0xc5, 0xba, + 0xb6, 0xab, 0xac, 0xa3, 0x9b, 0x92, 0x89, 0x7e, 0x7a, 0x7f, 0x7b, 0x79, + 0x76, 0x77, 0x6e, 0x6a, 0x65, 0x67, 0x66, 0x60, 0x5f, 0x61, 0x5b, 0x5a, + 0x57, 0x5b, 0x58, 0x52, 0x51, 0x53, 0x52, 0x53, 0x53, 0x53, 0x57, 0x5c, + 0x5d, 0x5b, 0x5d, 0x5f, 0x5c, 0x62, 0x65, 0x67, 0x69, 0x70, 0x71, 0x74, + 0x8b, 0x93, 0x98, 0xa2, 0xa8, 0xad, 0xb7, 0xbb, 0xc7, 0xce, 0xd5, 0xdc, + 0xd5, 0xf9, 0xdf, 0xe9, 0xf7, 0xff, 0x7e, 0x4c, 0x62, 0x49, 0x24, 0x27, + 0x57, 0x5d, 0x4a, 0x60, 0xf1, 0xf9, 0xf0, 0xdf, 0xfd, 0xf5, 0xff, 0xff, + 0xda, 0xf8, 0xf1, 0xeb, 0xef, 0xd8, 0xdb, 0xdb, 0xce, 0xcb, 0xc0, 0xbb, + 0xb0, 0xb1, 0xa8, 0xa2, 0x99, 0x91, 0x84, 0x78, 0x87, 0x81, 0x7f, 0x79, + 0x79, 0x76, 0x71, 0x6c, 0x68, 0x67, 0x64, 0x66, 0x62, 0x60, 0x5e, 0x5d, + 0x5c, 0x5d, 0x56, 0x51, 0x53, 0x56, 0x57, 0x57, 0x59, 0x56, 0x55, 0x57, + 0x56, 0x5a, 0x5b, 0x5f, 0x64, 0x68, 0x6a, 0x6d, 0x72, 0x75, 0x75, 0x77, + 0x85, 0x8f, 0x98, 0x9f, 0xa8, 0xb1, 0xbb, 0xc8, 0xd4, 0xda, 0xea, 0xec, + 0xde, 0xd9, 0xff, 0xee, 0xfa, 0xeb, 0x91, 0x46, 0x61, 0x4c, 0x26, 0x27, + 0x5d, 0x68, 0x4c, 0x66, 0xf5, 0xff, 0xf4, 0xff, 0xf7, 0xed, 0xea, 0xf9, + 0xf1, 0xf6, 0xd6, 0xee, 0xe8, 0xee, 0xdd, 0xd9, 0xce, 0xc8, 0xbf, 0xba, + 0xae, 0xaa, 0xa6, 0x9d, 0x97, 0x90, 0x82, 0x7a, 0x85, 0x83, 0x7f, 0x80, + 0x79, 0x77, 0x70, 0x6c, 0x6a, 0x68, 0x66, 0x65, 0x62, 0x5f, 0x5b, 0x5d, + 0x5c, 0x59, 0x53, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5b, 0x59, 0x59, 0x59, + 0x5b, 0x5a, 0x5d, 0x60, 0x64, 0x6a, 0x6c, 0x70, 0x74, 0x73, 0x79, 0x7d, + 0x84, 0x8a, 0x94, 0x9a, 0xa5, 0xb4, 0xba, 0xc4, 0xd6, 0xde, 0xdf, 0xdc, + 0xeb, 0xd9, 0xff, 0xf0, 0xd1, 0xf5, 0xb9, 0x46, 0x60, 0x4e, 0x29, 0x2d, + 0x62, 0x6b, 0x4f, 0x6e, 0xff, 0xff, 0xff, 0xf6, 0xfb, 0xff, 0xf1, 0xea, + 0xed, 0xf0, 0xcf, 0xed, 0xe7, 0xd6, 0xdb, 0xdb, 0xd0, 0xc6, 0xc4, 0xb9, + 0xb0, 0xa9, 0xa2, 0x9c, 0x90, 0x8a, 0x7d, 0x88, 0x87, 0x82, 0x7d, 0x7e, + 0x7a, 0x76, 0x70, 0x6d, 0x67, 0x6c, 0x65, 0x66, 0x62, 0x60, 0x63, 0x61, + 0x5d, 0x57, 0x56, 0x5a, 0x5d, 0x5d, 0x5d, 0x5d, 0x5b, 0x5d, 0x5f, 0x5e, + 0x5d, 0x5f, 0x61, 0x61, 0x64, 0x66, 0x68, 0x72, 0x77, 0x7a, 0x81, 0x88, + 0x7e, 0x89, 0x91, 0x99, 0xa6, 0xaf, 0xb8, 0xc6, 0xd0, 0xd7, 0xe6, 0xe6, + 0xd5, 0xe6, 0xe7, 0xcc, 0xff, 0xf3, 0xd3, 0x43, 0x63, 0x4e, 0x25, 0x29, + 0x63, 0x6f, 0x4d, 0x7f, 0xf2, 0xfd, 0xde, 0xff, 0xf8, 0xff, 0xec, 0xfb, + 0xf8, 0xde, 0xf5, 0xfb, 0xeb, 0xf0, 0xe1, 0xd5, 0xd1, 0xc5, 0xba, 0xb5, + 0xaf, 0xa0, 0x9c, 0x90, 0x8c, 0x87, 0x7c, 0x8d, 0x88, 0x82, 0x80, 0x7e, + 0x75, 0x71, 0x6e, 0x69, 0x68, 0x69, 0x66, 0x63, 0x62, 0x63, 0x5e, 0x5f, + 0x5e, 0x55, 0x5c, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, 0x5d, 0x5e, 0x5b, 0x5e, + 0x62, 0x64, 0x64, 0x66, 0x67, 0x6d, 0x6b, 0x71, 0x78, 0x85, 0x8a, 0x94, + 0x7c, 0x88, 0x96, 0x95, 0xa1, 0xaa, 0xb2, 0xc5, 0xce, 0xda, 0xe7, 0xdd, + 0xf7, 0xe8, 0xf2, 0xf6, 0xe5, 0xff, 0xe8, 0x40, 0x60, 0x52, 0x27, 0x27, + 0x5f, 0x6b, 0x4c, 0x8d, 0xfe, 0xde, 0xeb, 0xf5, 0xe2, 0xf7, 0xfa, 0xf3, + 0xf8, 0xe9, 0xe9, 0xf0, 0xe3, 0xd2, 0xd4, 0xca, 0xc7, 0xc2, 0xaf, 0x8b, + 0x58, 0x46, 0x3d, 0x48, 0x4b, 0x50, 0x6c, 0x86, 0x83, 0x83, 0x7e, 0x79, + 0x74, 0x72, 0x6d, 0x6b, 0x67, 0x65, 0x64, 0x67, 0x61, 0x64, 0x62, 0x5f, + 0x58, 0x58, 0x60, 0x5e, 0x5d, 0x5b, 0x5b, 0x5d, 0x5f, 0x62, 0x60, 0x5f, + 0x61, 0x68, 0x66, 0x68, 0x69, 0x6e, 0x6f, 0x79, 0x83, 0x8c, 0x8c, 0x93, + 0x7a, 0x84, 0x8f, 0x90, 0x9b, 0xac, 0xb8, 0xc2, 0xcb, 0xcf, 0xdb, 0xe8, + 0xe2, 0xdc, 0xea, 0xd7, 0xf1, 0xff, 0xee, 0x41, 0x59, 0x51, 0x25, 0x24, + 0x51, 0x6f, 0x4c, 0x9f, 0xe7, 0xff, 0xfe, 0xfb, 0xff, 0xfb, 0xe9, 0xef, + 0xfa, 0xeb, 0xe4, 0xf3, 0xdf, 0xc1, 0xce, 0xc4, 0xb0, 0x99, 0x51, 0x2d, + 0x2c, 0x31, 0x33, 0x34, 0x30, 0x2c, 0x33, 0x4d, 0x72, 0x81, 0x79, 0x76, + 0x71, 0x6f, 0x6d, 0x69, 0x69, 0x6c, 0x65, 0x62, 0x61, 0x62, 0x61, 0x5d, + 0x5a, 0x5f, 0x5e, 0x5f, 0x5e, 0x5d, 0x60, 0x64, 0x62, 0x61, 0x63, 0x67, + 0x66, 0x66, 0x69, 0x6a, 0x70, 0x6f, 0x79, 0x85, 0x89, 0x8e, 0x94, 0x97, + 0x7c, 0x85, 0x8c, 0x92, 0x9f, 0xa7, 0xaf, 0xbf, 0xcb, 0xd3, 0xc6, 0xd7, + 0xf2, 0xf3, 0xf2, 0xf0, 0xe4, 0xf7, 0xdc, 0x40, 0x58, 0x50, 0x28, 0x26, + 0x61, 0x6c, 0x4c, 0xb3, 0xfb, 0xf7, 0xff, 0xf1, 0xe5, 0xf1, 0xff, 0xe6, + 0xee, 0xdf, 0xda, 0xf4, 0xeb, 0xc9, 0xd1, 0x8e, 0x47, 0x2d, 0x29, 0x26, + 0x21, 0x20, 0x22, 0x22, 0x21, 0x22, 0x26, 0x29, 0x32, 0x57, 0x74, 0x72, + 0x73, 0x71, 0x6e, 0x68, 0x6a, 0x68, 0x65, 0x63, 0x65, 0x65, 0x60, 0x5a, + 0x60, 0x61, 0x60, 0x5e, 0x60, 0x60, 0x5f, 0x63, 0x64, 0x66, 0x66, 0x67, + 0x6d, 0x71, 0x73, 0x75, 0x78, 0x78, 0x87, 0x89, 0x90, 0x97, 0x9b, 0xa2, + 0x7c, 0x85, 0x8e, 0x94, 0x9c, 0xa2, 0xad, 0xbb, 0xc4, 0xd0, 0xd6, 0xcb, + 0xef, 0xe3, 0xff, 0xed, 0xdf, 0xf9, 0xf4, 0x43, 0x5b, 0x54, 0x27, 0x29, + 0x63, 0x6d, 0x4b, 0xca, 0xf1, 0xfb, 0xff, 0xef, 0xff, 0xf0, 0xe8, 0xf2, + 0xf2, 0xe6, 0xe8, 0xe9, 0xcc, 0xd7, 0x99, 0x37, 0x27, 0x20, 0x1d, 0x1b, + 0x1a, 0x19, 0x1b, 0x1b, 0x1c, 0x1b, 0x20, 0x23, 0x24, 0x2f, 0x4d, 0x6a, + 0x6f, 0x70, 0x6a, 0x69, 0x67, 0x67, 0x63, 0x68, 0x64, 0x64, 0x59, 0x63, + 0x62, 0x62, 0x62, 0x61, 0x65, 0x64, 0x63, 0x64, 0x69, 0x64, 0x6b, 0x6a, + 0x6f, 0x74, 0x76, 0x7c, 0x7d, 0x8a, 0x8b, 0x90, 0x92, 0x9a, 0xa8, 0xb1, + 0x76, 0x84, 0x8b, 0x95, 0x9c, 0xa8, 0xae, 0xb0, 0xc3, 0xd8, 0xe5, 0xed, + 0xec, 0xfe, 0xde, 0xed, 0xfb, 0xdf, 0xff, 0x49, 0x58, 0x55, 0x28, 0x29, + 0x61, 0x69, 0x4c, 0xcb, 0xe3, 0xf0, 0xee, 0xff, 0xf8, 0xf8, 0xff, 0xe2, + 0xff, 0xf9, 0xde, 0xfb, 0xe0, 0xd1, 0x44, 0x24, 0x21, 0x20, 0x20, 0x22, + 0x21, 0x22, 0x1c, 0x1d, 0x20, 0x1d, 0x1a, 0x1e, 0x1c, 0x24, 0x2c, 0x39, + 0x5b, 0x66, 0x68, 0x68, 0x64, 0x67, 0x66, 0x65, 0x66, 0x60, 0x5c, 0x66, + 0x62, 0x63, 0x62, 0x61, 0x65, 0x63, 0x65, 0x68, 0x69, 0x69, 0x6d, 0x71, + 0x75, 0x7b, 0x80, 0x7e, 0x88, 0x8c, 0x8f, 0x92, 0xa3, 0xa9, 0xb5, 0xb7, + 0x6b, 0x84, 0x8b, 0x92, 0x9a, 0xa8, 0xb7, 0xc1, 0xc9, 0xd0, 0xd7, 0xda, + 0xef, 0xf6, 0xe3, 0xe9, 0xe7, 0xdc, 0xfc, 0x4e, 0x56, 0x53, 0x2b, 0x2a, + 0x60, 0x68, 0x48, 0xe5, 0xf3, 0xff, 0xf5, 0xfd, 0xe2, 0xf0, 0xff, 0xf2, + 0xf9, 0xea, 0xfb, 0xea, 0xd9, 0x82, 0x25, 0x21, 0x27, 0x2c, 0x2d, 0x2f, + 0x2e, 0x28, 0x29, 0x21, 0x1e, 0x20, 0x1f, 0x1c, 0x1a, 0x1b, 0x24, 0x29, + 0x37, 0x50, 0x55, 0x5a, 0x58, 0x61, 0x63, 0x64, 0x5f, 0x59, 0x65, 0x65, + 0x60, 0x63, 0x63, 0x63, 0x66, 0x64, 0x66, 0x69, 0x6c, 0x72, 0x70, 0x76, + 0x7c, 0x80, 0x80, 0x8b, 0x90, 0x8f, 0x9a, 0x9f, 0xa8, 0xb6, 0xc0, 0xc7, + 0x65, 0x72, 0x7b, 0x82, 0x8c, 0x99, 0xa8, 0xb3, 0xc4, 0xd3, 0xd0, 0xf0, + 0xf9, 0xf2, 0xe6, 0xff, 0xfe, 0xed, 0xff, 0x5b, 0x58, 0x58, 0x29, 0x29, + 0x5f, 0x6b, 0x46, 0xdc, 0xfd, 0xf7, 0xf0, 0xff, 0xff, 0xf6, 0xcb, 0xfc, + 0xed, 0xe2, 0xe5, 0xe0, 0xdb, 0x38, 0x22, 0x29, 0x32, 0x35, 0x37, 0x37, + 0x33, 0x32, 0x2d, 0x2b, 0x27, 0x21, 0x23, 0x1e, 0x1c, 0x1d, 0x1e, 0x24, + 0x2b, 0x3d, 0x49, 0x4c, 0x4d, 0x50, 0x4e, 0x52, 0x52, 0x59, 0x5e, 0x60, + 0x62, 0x60, 0x62, 0x64, 0x66, 0x66, 0x69, 0x69, 0x6e, 0x70, 0x78, 0x7f, + 0x81, 0x81, 0x8b, 0x8d, 0x94, 0x99, 0x9f, 0xab, 0xad, 0xbf, 0xc2, 0xda, + 0x6f, 0x7a, 0x8d, 0x8f, 0x98, 0xa6, 0xa9, 0xb4, 0xba, 0xc6, 0xcd, 0xd9, + 0xe9, 0xe4, 0xed, 0xf2, 0xf0, 0xff, 0xdc, 0x6d, 0x55, 0x54, 0x29, 0x28, + 0x63, 0x66, 0x4a, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xed, 0xf6, + 0xf0, 0xff, 0xff, 0xed, 0x9c, 0x20, 0x25, 0x2d, 0x32, 0x35, 0x32, 0x34, + 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2d, 0x2b, 0x2a, 0x23, 0x1e, 0x1f, 0x1f, + 0x22, 0x2b, 0x42, 0x49, 0x4d, 0x4f, 0x4f, 0x4d, 0x4b, 0x4b, 0x4c, 0x4e, + 0x54, 0x5b, 0x5b, 0x5f, 0x61, 0x69, 0x6f, 0x71, 0x70, 0x78, 0x7c, 0x84, + 0x83, 0x89, 0x8f, 0x95, 0xa2, 0xa4, 0xa9, 0xb7, 0xc0, 0xcc, 0xdb, 0xe0, + 0x72, 0x6a, 0x83, 0x8f, 0x9c, 0xa7, 0xab, 0xc0, 0xc5, 0xcb, 0xcf, 0xe5, + 0xe9, 0xcc, 0xdd, 0xec, 0xe5, 0xef, 0xe8, 0x80, 0x4f, 0x52, 0x29, 0x28, + 0x61, 0x63, 0x4d, 0xff, 0xff, 0xf2, 0xfe, 0xff, 0xf9, 0xf9, 0xfa, 0xff, + 0xf9, 0xff, 0xee, 0xe6, 0x5b, 0x1a, 0x25, 0x2c, 0x2f, 0x31, 0x36, 0x36, + 0x36, 0x34, 0x33, 0x31, 0x33, 0x32, 0x33, 0x32, 0x32, 0x2c, 0x27, 0x20, + 0x1f, 0x29, 0x3f, 0x47, 0x4e, 0x4e, 0x4d, 0x4f, 0x4e, 0x4a, 0x47, 0x46, + 0x44, 0x43, 0x4b, 0x50, 0x59, 0x61, 0x69, 0x71, 0x75, 0x7a, 0x7e, 0x81, + 0x8a, 0x8c, 0x92, 0x9b, 0xa2, 0xae, 0xb7, 0xbe, 0xcc, 0xde, 0xec, 0xe4, + 0x73, 0x67, 0x80, 0x91, 0x9b, 0xa8, 0xae, 0xbb, 0xc5, 0xca, 0xcd, 0xe2, + 0xec, 0xec, 0xf6, 0xfe, 0xd7, 0xfc, 0xff, 0x9c, 0x48, 0x4e, 0x29, 0x2a, + 0x5a, 0x61, 0x4b, 0xeb, 0xff, 0xf0, 0xf8, 0xfb, 0xff, 0xff, 0xfa, 0xf6, + 0xff, 0xff, 0xf5, 0xf2, 0x41, 0x1b, 0x2b, 0x31, 0x32, 0x34, 0x34, 0x35, + 0x34, 0x33, 0x35, 0x32, 0x35, 0x37, 0x37, 0x3c, 0x3a, 0x3b, 0x3a, 0x2b, + 0x19, 0x24, 0x3f, 0x4b, 0x4e, 0x4b, 0x51, 0x4f, 0x49, 0x40, 0x3f, 0x40, + 0x3d, 0x40, 0x3f, 0x44, 0x4c, 0x57, 0x5d, 0x60, 0x66, 0x74, 0x82, 0x8f, + 0x8e, 0x97, 0x9b, 0xa4, 0xae, 0xb4, 0xbe, 0xcc, 0xd0, 0xe5, 0xe5, 0xf5, + 0x6e, 0x70, 0x75, 0x89, 0x94, 0x9c, 0xac, 0xb3, 0xbe, 0xcb, 0xd3, 0xe4, + 0xe4, 0xf1, 0xe1, 0xfb, 0xfe, 0xfe, 0xff, 0xc8, 0x41, 0x43, 0x2b, 0x29, + 0x53, 0x5a, 0x4a, 0xf1, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xfe, 0xef, + 0xff, 0xfb, 0xef, 0xde, 0x35, 0x1a, 0x2c, 0x33, 0x32, 0x31, 0x2f, 0x2f, + 0x2c, 0x31, 0x32, 0x30, 0x32, 0x35, 0x3a, 0x3c, 0x3c, 0x3a, 0x43, 0x2e, + 0x19, 0x1d, 0x38, 0x4c, 0x4c, 0x4f, 0x48, 0x49, 0x40, 0x3c, 0x3c, 0x3e, + 0x3b, 0x3f, 0x3f, 0x43, 0x47, 0x57, 0x57, 0x5b, 0x5f, 0x6c, 0x89, 0x8e, + 0x92, 0x9f, 0xb4, 0xbd, 0xbe, 0xc1, 0xcd, 0xd8, 0xdb, 0xf3, 0xfa, 0xf8, + 0x6f, 0x71, 0x69, 0x85, 0x8f, 0x9c, 0xa5, 0xb3, 0xb8, 0xcc, 0xd3, 0xd0, + 0xec, 0xfb, 0xfa, 0xfe, 0xee, 0xff, 0xfa, 0xea, 0x2f, 0x28, 0x28, 0x28, + 0x3a, 0x44, 0x4b, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xf1, 0xf3, 0xf7, 0xf9, + 0xee, 0xe8, 0xe8, 0xd6, 0x30, 0x1d, 0x33, 0x2c, 0x21, 0x1c, 0x1a, 0x1f, + 0x24, 0x29, 0x2b, 0x2c, 0x2c, 0x2c, 0x31, 0x35, 0x3c, 0x40, 0x43, 0x29, + 0x1a, 0x1c, 0x32, 0x4d, 0x4b, 0x4b, 0x4c, 0x41, 0x3c, 0x39, 0x3e, 0x3f, + 0x3f, 0x42, 0x42, 0x46, 0x49, 0x55, 0x56, 0x5d, 0x6a, 0x87, 0x8b, 0x94, + 0x9a, 0xa7, 0xab, 0xba, 0xc0, 0xd1, 0xf1, 0xf3, 0xec, 0xf5, 0xfa, 0xe3, + 0x6d, 0x72, 0x6c, 0x7c, 0x8c, 0x98, 0x9e, 0xab, 0xb6, 0xc2, 0xc9, 0xdb, + 0xe0, 0xf2, 0xde, 0xf7, 0xfb, 0xfc, 0xde, 0xfa, 0x31, 0x29, 0x28, 0x29, + 0x28, 0x2d, 0x4d, 0xf8, 0xff, 0xf6, 0xff, 0xf9, 0xf4, 0xff, 0xfe, 0xdf, + 0xf5, 0xf9, 0xf0, 0xe0, 0x32, 0x20, 0x35, 0x23, 0x1d, 0x16, 0x13, 0x14, + 0x1a, 0x1f, 0x20, 0x21, 0x1e, 0x1d, 0x1c, 0x22, 0x29, 0x3f, 0x3f, 0x23, + 0x1b, 0x21, 0x4b, 0x4c, 0x4f, 0x4b, 0x49, 0x47, 0x3f, 0x3b, 0x3e, 0x3f, + 0x40, 0x42, 0x45, 0x4b, 0x51, 0x57, 0x5a, 0x67, 0x8a, 0x8f, 0x98, 0x9e, + 0xa6, 0xb0, 0xbc, 0xc1, 0xd0, 0xcb, 0xec, 0xe1, 0xf8, 0xff, 0xf8, 0xff, + 0x69, 0x6f, 0x6d, 0x6b, 0x80, 0x90, 0x94, 0xa3, 0xaf, 0xbb, 0xca, 0xdc, + 0xdd, 0xec, 0xde, 0xe8, 0xff, 0xff, 0xef, 0xec, 0x41, 0x46, 0x2c, 0x2a, + 0x35, 0x36, 0x50, 0xfe, 0xff, 0xff, 0xf7, 0xff, 0xfb, 0xfc, 0xff, 0xff, + 0xe0, 0xfc, 0xf0, 0xb9, 0x2a, 0x2a, 0x32, 0x1f, 0x18, 0x13, 0x11, 0x10, + 0x15, 0x19, 0x1c, 0x17, 0x14, 0x12, 0x14, 0x17, 0x1e, 0x2b, 0x41, 0x20, + 0x1e, 0x23, 0x4c, 0x4f, 0x4f, 0x4c, 0x48, 0x4a, 0x44, 0x44, 0x40, 0x44, + 0x44, 0x48, 0x50, 0x55, 0x58, 0x57, 0x65, 0x89, 0x91, 0x97, 0x9e, 0xad, + 0xb8, 0xbf, 0xcb, 0xd7, 0xd5, 0xf4, 0xf5, 0xf5, 0xe7, 0xfb, 0xff, 0xf5, + 0x5d, 0x63, 0x67, 0x64, 0x76, 0x86, 0x89, 0x98, 0xa9, 0xb9, 0xc6, 0xcb, + 0xdc, 0xdb, 0xe4, 0xfc, 0xf6, 0xf8, 0xfd, 0xfb, 0x48, 0x54, 0x2f, 0x2b, + 0x5d, 0x60, 0x5c, 0xff, 0xff, 0xfe, 0xfd, 0xff, 0xff, 0xf8, 0xf3, 0xf0, + 0xff, 0xf0, 0xd4, 0x96, 0x27, 0x2f, 0x30, 0x1e, 0x19, 0x12, 0x10, 0x12, + 0x14, 0x1f, 0x24, 0x1a, 0x14, 0x12, 0x12, 0x15, 0x1c, 0x2c, 0x44, 0x28, + 0x1a, 0x24, 0x4c, 0x4e, 0x4d, 0x4c, 0x49, 0x4d, 0x4b, 0x4d, 0x4e, 0x4d, + 0x4f, 0x57, 0x54, 0x56, 0x5a, 0x67, 0x8b, 0x92, 0x98, 0xa4, 0xb0, 0xb7, + 0xc8, 0xd0, 0xd9, 0xd3, 0xf7, 0xff, 0xec, 0xf8, 0xf2, 0xf5, 0xff, 0xff, + 0x68, 0x6a, 0x73, 0x70, 0x6b, 0x78, 0x7f, 0x8a, 0x92, 0xa4, 0xbb, 0xc7, + 0xde, 0xe1, 0xe3, 0xf2, 0xe5, 0xf1, 0xff, 0xf2, 0x4b, 0x58, 0x32, 0x2c, + 0x5f, 0x6a, 0x61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xfe, 0xff, + 0xfe, 0xf8, 0xe1, 0x9b, 0x2a, 0x35, 0x33, 0x27, 0x21, 0x18, 0x17, 0x18, + 0x1c, 0x2c, 0x33, 0x21, 0x18, 0x16, 0x10, 0x18, 0x1b, 0x29, 0x45, 0x2d, + 0x1b, 0x27, 0x56, 0x57, 0x53, 0x4f, 0x53, 0x4e, 0x4f, 0x50, 0x4f, 0x56, + 0x59, 0x58, 0x5b, 0x5b, 0x63, 0x8b, 0x95, 0x9b, 0xa7, 0xb1, 0xbd, 0xca, + 0xd1, 0xd9, 0xe3, 0xe3, 0xe5, 0xee, 0xf9, 0xd7, 0xff, 0xf2, 0xe2, 0xf8, + 0x69, 0x69, 0x71, 0x75, 0x65, 0x78, 0x82, 0x8e, 0x9e, 0xac, 0xbd, 0xcc, + 0xda, 0xe7, 0xf6, 0xf6, 0xe7, 0xe7, 0xfc, 0xff, 0x4c, 0x58, 0x34, 0x2d, + 0x61, 0x70, 0x68, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xff, 0xfc, 0xf5, 0xf4, + 0xe1, 0xf4, 0xf0, 0xbd, 0x25, 0x32, 0x38, 0x30, 0x24, 0x1d, 0x1b, 0x1f, + 0x26, 0x35, 0x37, 0x2b, 0x20, 0x19, 0x1a, 0x20, 0x2a, 0x2d, 0x46, 0x30, + 0x1f, 0x3a, 0x68, 0x67, 0x6b, 0x66, 0x67, 0x63, 0x60, 0x5d, 0x5e, 0x5d, + 0x5e, 0x60, 0x63, 0x62, 0x8a, 0x94, 0x9d, 0xaa, 0xb7, 0xbe, 0xc4, 0xda, + 0xe2, 0xfb, 0xf6, 0xfa, 0xfe, 0xff, 0xf3, 0xf6, 0xf5, 0xff, 0xff, 0xff, + 0x63, 0x6a, 0x6c, 0x71, 0x6a, 0x6c, 0x7a, 0x87, 0x90, 0xa3, 0xb5, 0xcb, + 0xd1, 0xf0, 0xdf, 0xef, 0xff, 0xfd, 0xe1, 0xe6, 0x56, 0x5b, 0x35, 0x2a, + 0x63, 0x6e, 0x71, 0xec, 0xea, 0xff, 0xfd, 0xff, 0xf2, 0xef, 0xff, 0xea, + 0xe8, 0xfa, 0xed, 0xcb, 0x2f, 0x30, 0x35, 0x2e, 0x26, 0x1f, 0x20, 0x27, + 0x2b, 0x33, 0x3d, 0x35, 0x2b, 0x1e, 0x20, 0x2a, 0x32, 0x3b, 0x48, 0x2b, + 0x25, 0x56, 0x68, 0x69, 0x69, 0x6b, 0x6a, 0x6d, 0x6a, 0x6e, 0x71, 0x70, + 0x76, 0x7d, 0x7f, 0x8e, 0x93, 0x9f, 0xac, 0xb0, 0xc5, 0xc3, 0xe4, 0xec, + 0xe6, 0xe1, 0xf4, 0xe5, 0xf0, 0xf7, 0xe6, 0xff, 0xed, 0xff, 0xff, 0xe0, + 0x61, 0x67, 0x6a, 0x70, 0x71, 0x68, 0x7a, 0x79, 0x7d, 0x8c, 0x94, 0xb3, + 0xcd, 0xee, 0xec, 0xf6, 0xfd, 0xf5, 0xde, 0xfa, 0x66, 0x58, 0x38, 0x2a, + 0x5f, 0x69, 0x78, 0xff, 0xf8, 0xfc, 0xfb, 0xed, 0xeb, 0xff, 0xf2, 0xe0, + 0xf1, 0xee, 0xde, 0xd0, 0x40, 0x2d, 0x30, 0x2a, 0x2c, 0x29, 0x28, 0x26, + 0x2f, 0x35, 0x3d, 0x3a, 0x2b, 0x2c, 0x29, 0x2e, 0x39, 0x3f, 0x48, 0x2a, + 0x2c, 0x61, 0x6b, 0x67, 0x6a, 0x6b, 0x6c, 0x6c, 0x70, 0x70, 0x77, 0x7a, + 0x7f, 0x88, 0x8c, 0x8f, 0x9a, 0xa9, 0xb2, 0xcd, 0xd8, 0xd9, 0xf2, 0xe4, + 0xe3, 0xfc, 0xe9, 0xff, 0xfa, 0xeb, 0xff, 0xe2, 0xe9, 0xf6, 0xf1, 0xff, + 0x5e, 0x65, 0x65, 0x6d, 0x71, 0x6b, 0x78, 0x7b, 0x82, 0x83, 0x80, 0x84, + 0x88, 0xaa, 0xe6, 0xf9, 0xff, 0xff, 0xff, 0xfe, 0x81, 0x51, 0x39, 0x2a, + 0x65, 0x6b, 0x85, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xf4, 0xf7, 0xfb, + 0xed, 0xdf, 0xdc, 0xbc, 0x67, 0x2b, 0x2c, 0x2d, 0x2c, 0x2d, 0x26, 0x23, + 0x30, 0x31, 0x39, 0x3c, 0x29, 0x2f, 0x31, 0x32, 0x37, 0x3f, 0x45, 0x35, + 0x3f, 0x63, 0x68, 0x68, 0x6d, 0x5d, 0x56, 0x6c, 0x70, 0x75, 0x7b, 0x85, + 0x89, 0x90, 0x95, 0x98, 0xa5, 0xaf, 0xb8, 0xca, 0xd1, 0xe8, 0xe7, 0xe7, + 0xef, 0xff, 0xff, 0xf5, 0xe8, 0xff, 0xf1, 0xff, 0xf9, 0xf8, 0xff, 0xfe, + 0x59, 0x5f, 0x63, 0x67, 0x6b, 0x6a, 0x74, 0x80, 0x87, 0x83, 0x85, 0x86, + 0x9c, 0xa8, 0xd7, 0xf0, 0xff, 0xff, 0xff, 0xcc, 0xa5, 0x4d, 0x3c, 0x2a, + 0x5d, 0x6a, 0x92, 0xfb, 0xff, 0xff, 0xff, 0xfd, 0xf7, 0xfe, 0xd4, 0xf8, + 0xe9, 0xcf, 0x93, 0x4e, 0x29, 0x1b, 0x28, 0x29, 0x2c, 0x28, 0x21, 0x22, + 0x1e, 0x22, 0x24, 0x2b, 0x25, 0x2a, 0x31, 0x32, 0x34, 0x38, 0x3f, 0x3e, + 0x5d, 0x64, 0x67, 0x69, 0x67, 0x5b, 0x54, 0x6f, 0x76, 0x7b, 0x82, 0x84, + 0x8d, 0x8f, 0x9d, 0xa6, 0xb1, 0xb9, 0xc7, 0xd7, 0xdb, 0xf8, 0xfc, 0xfa, + 0xe8, 0xf9, 0xff, 0xfc, 0xee, 0xff, 0xe5, 0xff, 0xe9, 0xf8, 0xf0, 0xde, + 0x61, 0x63, 0x66, 0x69, 0x67, 0x69, 0x69, 0x7a, 0x8a, 0x7d, 0x87, 0x8b, + 0xa2, 0x9b, 0xdc, 0xf0, 0xf1, 0xf1, 0xfc, 0xf3, 0xc8, 0x4c, 0x3e, 0x28, + 0x5e, 0x6a, 0xa3, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xfe, 0xfb, 0xe8, 0x75, + 0x49, 0x35, 0x29, 0x24, 0x17, 0x19, 0x27, 0x2a, 0x27, 0x23, 0x25, 0x21, + 0x18, 0x16, 0x1a, 0x1c, 0x26, 0x24, 0x2d, 0x33, 0x35, 0x37, 0x3a, 0x52, + 0x60, 0x63, 0x67, 0x67, 0x68, 0x67, 0x6e, 0x73, 0x7a, 0x85, 0x85, 0x8c, + 0x91, 0x9a, 0xa6, 0xaf, 0xb8, 0xc7, 0xda, 0xe7, 0xeb, 0xf9, 0xff, 0xef, + 0xff, 0xff, 0xfd, 0xf5, 0xfb, 0xff, 0xff, 0xe5, 0xec, 0xff, 0xfb, 0xff, + 0x60, 0x68, 0x68, 0x6e, 0x70, 0x77, 0x76, 0x77, 0x84, 0x8a, 0x8d, 0x90, + 0x9c, 0xae, 0xd9, 0xd5, 0xf6, 0xff, 0xe5, 0xf7, 0xe0, 0x46, 0x3c, 0x27, + 0x5d, 0x66, 0xab, 0xff, 0xfa, 0xff, 0xf0, 0xcc, 0x73, 0x45, 0x31, 0x27, + 0x1d, 0x1c, 0x1b, 0x17, 0x11, 0x14, 0x1d, 0x28, 0x25, 0x26, 0x27, 0x24, + 0x1d, 0x18, 0x1d, 0x24, 0x2c, 0x29, 0x2c, 0x33, 0x36, 0x31, 0x21, 0x2d, + 0x3d, 0x56, 0x60, 0x64, 0x68, 0x6d, 0x71, 0x78, 0x82, 0x84, 0x8b, 0x91, + 0x9c, 0xa6, 0xb0, 0xba, 0xcc, 0xd8, 0xe3, 0xf1, 0xf1, 0xf3, 0xfc, 0xd7, + 0xf8, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xfe, 0xff, 0xf5, 0xf1, 0xfd, 0xeb, + 0x5d, 0x60, 0x65, 0x6e, 0x71, 0x75, 0x7b, 0x74, 0x84, 0x84, 0x89, 0x8a, + 0x9e, 0xb7, 0xef, 0xff, 0xe3, 0xff, 0xf1, 0xff, 0xf1, 0x3f, 0x39, 0x27, + 0x55, 0x5f, 0xb9, 0xf7, 0xfa, 0x59, 0x3e, 0x32, 0x2b, 0x25, 0x20, 0x1a, + 0x17, 0x17, 0x15, 0x14, 0x11, 0x10, 0x16, 0x25, 0x24, 0x23, 0x1d, 0x1f, + 0x1e, 0x20, 0x22, 0x22, 0x26, 0x2a, 0x2a, 0x33, 0x31, 0x2c, 0x1a, 0x23, + 0x26, 0x2e, 0x3f, 0x5c, 0x6d, 0x70, 0x77, 0x7f, 0x84, 0x8e, 0x93, 0x9b, + 0xa8, 0xb1, 0xba, 0xc6, 0xd9, 0xeb, 0xf9, 0xd0, 0xf6, 0xff, 0xf9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfe, 0xf3, 0xf9, 0xf6, 0xf6, + 0x5f, 0x5c, 0x64, 0x67, 0x71, 0x76, 0x7c, 0x74, 0x85, 0x90, 0xa2, 0xb0, + 0xbf, 0xda, 0xe5, 0xf8, 0xf7, 0xee, 0xeb, 0xfc, 0xf4, 0x43, 0x36, 0x25, + 0x4a, 0x56, 0xaa, 0xc4, 0x3a, 0x28, 0x21, 0x20, 0x1f, 0x1d, 0x1a, 0x1a, + 0x17, 0x16, 0x16, 0x12, 0x11, 0x11, 0x13, 0x23, 0x21, 0x19, 0x15, 0x15, + 0x14, 0x14, 0x16, 0x1b, 0x1c, 0x21, 0x29, 0x30, 0x2b, 0x19, 0x15, 0x1a, + 0x1f, 0x25, 0x27, 0x2f, 0x3e, 0x60, 0x76, 0x83, 0x8c, 0x9a, 0xa2, 0xab, + 0xc0, 0xc9, 0xdb, 0xe3, 0xff, 0xe8, 0xf8, 0xff, 0xeb, 0xf6, 0xff, 0xf5, + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xf6, 0xf5, 0xf2, 0xe5, + 0x55, 0x57, 0x5b, 0x62, 0x67, 0x6d, 0x77, 0x79, 0x7e, 0x8f, 0x99, 0xae, + 0xbd, 0xc5, 0xe3, 0xf1, 0xfb, 0xff, 0xe8, 0xff, 0xff, 0x44, 0x3a, 0x24, + 0x47, 0x4f, 0x43, 0x2e, 0x24, 0x20, 0x1f, 0x1e, 0x1c, 0x1b, 0x1c, 0x1a, + 0x16, 0x15, 0x16, 0x11, 0x11, 0x11, 0x10, 0x1d, 0x1e, 0x18, 0x19, 0x17, + 0x18, 0x19, 0x18, 0x1a, 0x1c, 0x1b, 0x28, 0x2d, 0x1b, 0x12, 0x13, 0x15, + 0x17, 0x1b, 0x1d, 0x26, 0x2e, 0x33, 0x40, 0x51, 0x7b, 0xa1, 0xad, 0xb9, + 0xbb, 0xca, 0xe3, 0xe3, 0xfb, 0xf5, 0xeb, 0xe8, 0xe7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xf3, 0xed, 0xff, 0xf1, + 0x56, 0x5b, 0x59, 0x5d, 0x60, 0x66, 0x6d, 0x73, 0x74, 0x8d, 0x96, 0xaa, + 0xba, 0xc6, 0xc9, 0xde, 0xf0, 0xe8, 0xf2, 0xf5, 0xff, 0x47, 0x38, 0x23, + 0x44, 0x4d, 0x2a, 0x22, 0x1d, 0x1c, 0x1c, 0x19, 0x19, 0x18, 0x18, 0x1a, + 0x16, 0x15, 0x12, 0x10, 0x12, 0x11, 0x0f, 0x1a, 0x1b, 0x15, 0x14, 0x13, + 0x11, 0x12, 0x12, 0x15, 0x1b, 0x1c, 0x24, 0x24, 0x15, 0x12, 0x12, 0x14, + 0x17, 0x18, 0x19, 0x1c, 0x1f, 0x23, 0x25, 0x2d, 0x37, 0x60, 0xb2, 0xcc, + 0xdc, 0xe2, 0xe9, 0xea, 0xdf, 0xec, 0xfc, 0xf3, 0xf5, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xe8, 0xf0, 0xdb, 0xef, 0xf5, 0xe9, 0xdc, + 0x54, 0x58, 0x5c, 0x63, 0x65, 0x6a, 0x72, 0x7a, 0x76, 0x8f, 0x9b, 0xa8, + 0xb7, 0xc8, 0xd7, 0xea, 0xe3, 0xf4, 0xee, 0xfb, 0xd3, 0x4c, 0x34, 0x23, + 0x40, 0x43, 0x22, 0x1d, 0x19, 0x18, 0x16, 0x15, 0x17, 0x16, 0x16, 0x15, + 0x13, 0x15, 0x12, 0x0e, 0x10, 0x11, 0x0f, 0x16, 0x1a, 0x17, 0x16, 0x17, + 0x15, 0x15, 0x17, 0x16, 0x17, 0x1c, 0x21, 0x19, 0x11, 0x11, 0x11, 0x11, + 0x17, 0x17, 0x19, 0x1a, 0x1c, 0x1d, 0x1c, 0x22, 0x27, 0x34, 0x75, 0xd9, + 0xe1, 0xe8, 0xe9, 0xf3, 0xfd, 0xff, 0xff, 0xf5, 0xfe, 0xff, 0xf0, 0xfe, + 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xec, 0xed, 0xe9, 0xe5, 0xe2, 0xd3, 0xc3, + 0x52, 0x52, 0x5b, 0x5d, 0x67, 0x67, 0x6e, 0x76, 0x7a, 0x82, 0x9a, 0xac, + 0xbc, 0xce, 0xdf, 0xdd, 0xdd, 0xfb, 0xff, 0xfb, 0xeb, 0x53, 0x26, 0x22, + 0x28, 0x2a, 0x1d, 0x19, 0x16, 0x16, 0x14, 0x15, 0x15, 0x14, 0x14, 0x14, + 0x14, 0x11, 0x11, 0x10, 0x11, 0x11, 0x0e, 0x12, 0x1a, 0x19, 0x16, 0x17, + 0x16, 0x15, 0x19, 0x1b, 0x1a, 0x1a, 0x1d, 0x10, 0x11, 0x10, 0x10, 0x13, + 0x16, 0x17, 0x1a, 0x19, 0x1a, 0x19, 0x1d, 0x1f, 0x21, 0x27, 0x3e, 0xd7, + 0xf1, 0xff, 0xf7, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf1, 0xf0, 0xe1, 0xff, 0xeb, 0xe9, 0xed, 0xdf, 0x79, 0x42, + 0x4f, 0x52, 0x54, 0x5b, 0x61, 0x61, 0x6b, 0x71, 0x7b, 0x77, 0x92, 0x9e, + 0xb1, 0xc7, 0xde, 0xf4, 0xf3, 0xfc, 0xf8, 0xea, 0xf5, 0x69, 0x35, 0x22, + 0x27, 0x20, 0x19, 0x17, 0x15, 0x17, 0x14, 0x13, 0x14, 0x12, 0x12, 0x12, + 0x10, 0x10, 0x11, 0x0f, 0x10, 0x0f, 0x0c, 0x0f, 0x18, 0x16, 0x15, 0x11, + 0x11, 0x10, 0x12, 0x16, 0x19, 0x19, 0x18, 0x0e, 0x12, 0x10, 0x0f, 0x13, + 0x16, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1b, 0x1e, 0x24, 0x30, 0x9d, + 0xf1, 0xf6, 0xfd, 0xf9, 0xf6, 0xff, 0xff, 0xef, 0xfc, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0xe3, 0xf1, 0xea, 0xf4, 0xd9, 0x9c, 0x50, 0x37, 0x39, + 0x48, 0x4a, 0x4c, 0x51, 0x55, 0x5a, 0x61, 0x6b, 0x70, 0x77, 0x88, 0x99, + 0xab, 0xbc, 0xcd, 0xe0, 0xe9, 0xf1, 0xf7, 0xff, 0xff, 0x8a, 0x38, 0x21, + 0x27, 0x1d, 0x16, 0x15, 0x14, 0x15, 0x13, 0x13, 0x12, 0x11, 0x12, 0x12, + 0x11, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x0c, 0x0e, 0x13, 0x14, 0x13, 0x12, + 0x10, 0x11, 0x14, 0x16, 0x15, 0x18, 0x10, 0x0d, 0x12, 0x11, 0x10, 0x14, + 0x14, 0x15, 0x17, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1c, 0x1f, 0x29, 0x5a, + 0xf6, 0xfb, 0xe5, 0xff, 0xff, 0xf5, 0xe8, 0xf7, 0xe3, 0xff, 0xde, 0xff, + 0xf8, 0xf7, 0xf8, 0xe7, 0xed, 0xe8, 0xbf, 0x5e, 0x3f, 0x41, 0x35, 0x3c, + 0x40, 0x49, 0x4c, 0x51, 0x54, 0x5c, 0x5f, 0x67, 0x6b, 0x76, 0x75, 0x93, + 0x9d, 0xac, 0xc1, 0xd0, 0xe6, 0xe5, 0xeb, 0xea, 0xfe, 0xaa, 0x3b, 0x22, + 0x22, 0x1b, 0x16, 0x15, 0x14, 0x13, 0x13, 0x11, 0x11, 0x12, 0x11, 0x10, + 0x10, 0x0f, 0x10, 0x0f, 0x0e, 0x0f, 0x0c, 0x0e, 0x0e, 0x10, 0x12, 0x11, + 0x0f, 0x0f, 0x12, 0x13, 0x14, 0x13, 0x0f, 0x0c, 0x11, 0x10, 0x0f, 0x11, + 0x12, 0x14, 0x14, 0x15, 0x15, 0x15, 0x17, 0x18, 0x18, 0x1d, 0x25, 0x42, + 0xf5, 0xfc, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xe6, 0xec, 0xdf, 0xe5, + 0xff, 0xfa, 0xdf, 0xe2, 0xd1, 0x76, 0x40, 0x41, 0x39, 0x37, 0x4f, 0x74, + 0x42, 0x43, 0x49, 0x4b, 0x4f, 0x55, 0x59, 0x62, 0x64, 0x6c, 0x6d, 0x86, + 0x94, 0xa7, 0xb3, 0xd6, 0xe7, 0xf4, 0xfb, 0xff, 0xff, 0xd0, 0x3e, 0x23, + 0x1f, 0x19, 0x16, 0x15, 0x15, 0x13, 0x13, 0x11, 0x12, 0x13, 0x11, 0x10, + 0x10, 0x0f, 0x11, 0x10, 0x10, 0x0f, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x10, + 0x10, 0x11, 0x11, 0x13, 0x14, 0x10, 0x0f, 0x0e, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x13, 0x12, 0x15, 0x14, 0x15, 0x16, 0x17, 0x1a, 0x1c, 0x24, 0x35, + 0xff, 0xff, 0xf4, 0xff, 0xf8, 0xf6, 0xff, 0xf8, 0xf8, 0xeb, 0xe5, 0xff, + 0xec, 0xe7, 0xe6, 0x92, 0x4d, 0x40, 0x3b, 0x35, 0x4b, 0x6d, 0x76, 0x75, + 0x3f, 0x3e, 0x3e, 0x41, 0x41, 0x48, 0x55, 0x57, 0x5d, 0x61, 0x63, 0x6d, + 0x84, 0x87, 0x73, 0xba, 0xec, 0xee, 0xf7, 0xff, 0xec, 0xe5, 0x45, 0x25, + 0x1c, 0x15, 0x15, 0x13, 0x14, 0x11, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, + 0x10, 0x11, 0x0e, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x10, 0x10, + 0x0f, 0x0f, 0x11, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x11, 0x0f, 0x0f, 0x0f, + 0x11, 0x10, 0x11, 0x13, 0x13, 0x14, 0x15, 0x17, 0x15, 0x1a, 0x1f, 0x2d, + 0xe1, 0xff, 0xf1, 0xff, 0xf1, 0xef, 0xef, 0xeb, 0xee, 0xf2, 0xe6, 0xff, + 0xeb, 0xb7, 0x5b, 0x42, 0x3f, 0x33, 0x43, 0x67, 0x7d, 0x7e, 0x6f, 0x6e, + 0x3e, 0x3c, 0x38, 0x3c, 0x35, 0x38, 0x3d, 0x52, 0x4f, 0x52, 0x58, 0x56, + 0x68, 0x75, 0x82, 0xa7, 0xc8, 0xc7, 0xec, 0xfa, 0xec, 0xd8, 0x41, 0x24, + 0x19, 0x15, 0x14, 0x14, 0x11, 0x12, 0x10, 0x10, 0x11, 0x10, 0x11, 0x10, + 0x11, 0x10, 0x0f, 0x0f, 0x0f, 0x11, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, + 0x0f, 0x10, 0x10, 0x10, 0x0f, 0x0d, 0x0f, 0x0f, 0x11, 0x10, 0x0f, 0x10, + 0x0f, 0x10, 0x14, 0x13, 0x13, 0x13, 0x15, 0x15, 0x17, 0x18, 0x20, 0x2b, + 0xba, 0xff, 0xf4, 0xfc, 0xff, 0xe8, 0xe1, 0xff, 0xec, 0xf9, 0xed, 0xd4, + 0x6a, 0x3e, 0x40, 0x35, 0x40, 0x67, 0x77, 0x75, 0x76, 0x74, 0x6b, 0x6c, + 0x3a, 0x39, 0x37, 0x35, 0x39, 0x39, 0x3c, 0x43, 0x44, 0x4b, 0x4f, 0x50, + 0x5c, 0x65, 0x6e, 0x79, 0x87, 0x9a, 0xb1, 0xc6, 0xd3, 0xc1, 0x3a, 0x25, + 0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, + 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f, 0x11, + 0x0f, 0x11, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x10, 0x0f, 0x0f, 0x0e, + 0x0f, 0x0f, 0x11, 0x10, 0x10, 0x12, 0x13, 0x14, 0x16, 0x16, 0x19, 0x26, + 0x9b, 0xff, 0xff, 0xf7, 0xf0, 0xea, 0xdc, 0xff, 0xf6, 0xdd, 0x88, 0x43, + 0x2f, 0x31, 0x33, 0x59, 0x71, 0x7a, 0x73, 0x6f, 0x70, 0x6c, 0x69, 0x69, + 0x33, 0x35, 0x32, 0x31, 0x34, 0x35, 0x38, 0x3a, 0x3b, 0x42, 0x43, 0x47, + 0x42, 0x51, 0x57, 0x5c, 0x65, 0x6e, 0x81, 0x8d, 0x96, 0x8b, 0x37, 0x26, + 0x14, 0x15, 0x11, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, + 0x0e, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x10, 0x10, 0x11, + 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, 0x0f, 0x0e, + 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x11, 0x11, 0x14, 0x15, 0x14, 0x1b, 0x22, + 0x79, 0xec, 0xf1, 0xe7, 0xf1, 0xdd, 0xe8, 0xe1, 0xaa, 0x4e, 0x3e, 0x31, + 0x33, 0x54, 0x7c, 0x7c, 0x76, 0x72, 0x6e, 0x6d, 0x6b, 0x6e, 0x6e, 0x6f, + 0x31, 0x34, 0x31, 0x2f, 0x2e, 0x2b, 0x2c, 0x2c, 0x2e, 0x2e, 0x2f, 0x32, + 0x33, 0x3d, 0x42, 0x49, 0x49, 0x52, 0x58, 0x5c, 0x61, 0x5c, 0x29, 0x20, + 0x15, 0x14, 0x11, 0x10, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0f, 0x0f, + 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x11, 0x0f, 0x0e, 0x11, 0x0f, 0x11, + 0x10, 0x10, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x10, + 0x0e, 0x0f, 0x10, 0x0f, 0x0f, 0x12, 0x11, 0x12, 0x13, 0x14, 0x18, 0x21, + 0x55, 0xff, 0xf3, 0xe6, 0xda, 0xe3, 0xce, 0x62, 0x3e, 0x36, 0x36, 0x4e, + 0x78, 0x80, 0x7d, 0x78, 0x72, 0x6f, 0x6f, 0x68, 0x6c, 0x6b, 0x6b, 0x6f, + 0x2f, 0x31, 0x2d, 0x2e, 0x2f, 0x2c, 0x28, 0x28, 0x28, 0x27, 0x29, 0x29, + 0x2b, 0x32, 0x36, 0x3b, 0x3c, 0x3e, 0x3e, 0x41, 0x43, 0x3e, 0x2e, 0x1e, + 0x15, 0x13, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0d, 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0f, 0x0e, 0x0e, + 0x0d, 0x0f, 0x0e, 0x0d, 0x0e, 0x0f, 0x0d, 0x0f, 0x0e, 0x0e, 0x0f, 0x10, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x12, 0x12, 0x17, 0x1d, + 0x3d, 0xe5, 0xef, 0xeb, 0xce, 0x7b, 0x46, 0x3c, 0x35, 0x4e, 0x76, 0x80, + 0x78, 0x78, 0x75, 0x71, 0x70, 0x6f, 0x6e, 0x6d, 0x75, 0x78, 0x7c, 0x86, + 0x2e, 0x2f, 0x2e, 0x2b, 0x2d, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2a, 0x2c, + 0x2d, 0x2c, 0x33, 0x31, 0x32, 0x34, 0x32, 0x31, 0x32, 0x2f, 0x2a, 0x19, + 0x17, 0x12, 0x11, 0x0e, 0x10, 0x0e, 0x0e, 0x0e, 0x0d, 0x0b, 0x0c, 0x0e, + 0x0e, 0x10, 0x0e, 0x0e, 0x0f, 0x0d, 0x10, 0x0e, 0x0e, 0x0f, 0x0e, 0x0f, + 0x0d, 0x0e, 0x0f, 0x0d, 0x0f, 0x0d, 0x0e, 0x0f, 0x10, 0x0f, 0x0d, 0x0e, + 0x0e, 0x0c, 0x0e, 0x0e, 0x0c, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x15, 0x1c, + 0x2e, 0xea, 0xdb, 0x9b, 0x4a, 0x41, 0x37, 0x48, 0x78, 0x85, 0x7e, 0x7c, + 0x77, 0x72, 0x76, 0x70, 0x73, 0x75, 0x78, 0x85, 0x8f, 0x9f, 0xaf, 0xb1, + 0x35, 0x33, 0x32, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2e, 0x2f, 0x31, 0x31, + 0x30, 0x2f, 0x2d, 0x32, 0x33, 0x32, 0x31, 0x2f, 0x2c, 0x29, 0x27, 0x18, + 0x15, 0x11, 0x10, 0x10, 0x0f, 0x0e, 0x0f, 0x0d, 0x0c, 0x0c, 0x0d, 0x0e, + 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0e, 0x0c, 0x0e, 0x0e, 0x0d, + 0x0d, 0x0f, 0x0f, 0x0c, 0x0f, 0x0d, 0x0e, 0x10, 0x0f, 0x0e, 0x0f, 0x0e, + 0x0d, 0x0e, 0x0c, 0x0c, 0x0b, 0x0e, 0x10, 0x11, 0x10, 0x12, 0x16, 0x19, + 0x23, 0x91, 0x55, 0x42, 0x34, 0x43, 0x6b, 0x81, 0x7e, 0x79, 0x76, 0x77, + 0x76, 0x75, 0x74, 0x75, 0x7c, 0x7f, 0x89, 0x9a, 0xa1, 0xa7, 0xb5, 0xc9, + 0x47, 0x38, 0x37, 0x35, 0x34, 0x35, 0x31, 0x30, 0x31, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x2f, 0x27, 0x2b, 0x2a, 0x2d, 0x2d, 0x2c, 0x25, 0x23, 0x17, + 0x14, 0x11, 0x11, 0x10, 0x10, 0x10, 0x0f, 0x0e, 0x0f, 0x0b, 0x0c, 0x0d, + 0x0d, 0x0e, 0x0f, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, 0x0d, 0x0c, + 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, + 0x0d, 0x0d, 0x0c, 0x0b, 0x0d, 0x0c, 0x0e, 0x10, 0x11, 0x12, 0x15, 0x17, + 0x21, 0x32, 0x36, 0x3a, 0x69, 0x83, 0x83, 0x7f, 0x78, 0x73, 0x75, 0x6f, + 0x72, 0x77, 0x81, 0x89, 0x9a, 0xab, 0xb0, 0xb4, 0xc8, 0xd6, 0xe2, 0xd2, + 0x5a, 0x54, 0x48, 0x40, 0x3c, 0x3d, 0x3a, 0x37, 0x33, 0x36, 0x38, 0x38, + 0x38, 0x38, 0x34, 0x3e, 0x41, 0x43, 0x40, 0x35, 0x24, 0x2b, 0x28, 0x1c, + 0x15, 0x12, 0x12, 0x11, 0x0f, 0x0f, 0x10, 0x10, 0x0e, 0x0d, 0x0d, 0x0c, + 0x0c, 0x0d, 0x0e, 0x0e, 0x0e, 0x0f, 0x0d, 0x0e, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0e, 0x0e, 0x0d, 0x0e, 0x0f, 0x0d, 0x0f, 0x10, 0x0e, 0x0f, 0x0e, 0x0e, + 0x0f, 0x13, 0x1f, 0x0e, 0x0d, 0x0e, 0x10, 0x10, 0x11, 0x12, 0x16, 0x17, + 0x1f, 0x32, 0x5b, 0x80, 0x7b, 0x7c, 0x7a, 0x74, 0x73, 0x75, 0x79, 0x78, + 0x81, 0x89, 0x99, 0xad, 0xb1, 0xc5, 0xcf, 0xdf, 0xed, 0xd1, 0xf0, 0x47, + 0x7f, 0x6e, 0x62, 0x55, 0x4f, 0x46, 0x41, 0x40, 0x3e, 0x3e, 0x41, 0x3e, + 0x41, 0x41, 0x41, 0x46, 0x4f, 0x50, 0x36, 0x29, 0x2c, 0x2f, 0x2a, 0x34, + 0x1b, 0x14, 0x11, 0x12, 0x12, 0x10, 0x11, 0x0f, 0x0f, 0x0f, 0x0f, 0x0d, + 0x0d, 0x0d, 0x0f, 0x0e, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x0c, 0x0e, 0x0c, + 0x0e, 0x0d, 0x0c, 0x0c, 0x0d, 0x0f, 0x0e, 0x10, 0x0e, 0x0f, 0x0d, 0x0c, + 0x0f, 0x37, 0xc2, 0x12, 0x0d, 0x0f, 0x10, 0x0f, 0x10, 0x13, 0x15, 0x16, + 0x20, 0x5b, 0x7f, 0x7c, 0x76, 0x70, 0x70, 0x73, 0x77, 0x7c, 0x87, 0x91, + 0xaa, 0xb2, 0xc9, 0xd4, 0xf1, 0xe5, 0xff, 0xfd, 0xf1, 0xff, 0xe2, 0x20, + 0xb4, 0x92, 0x7f, 0x6b, 0x61, 0x55, 0x4d, 0x4a, 0x47, 0x43, 0x45, 0x48, + 0x48, 0x47, 0x50, 0x58, 0x5d, 0x30, 0x2a, 0x2e, 0x2c, 0x35, 0xa9, 0xe2, + 0x2c, 0x1b, 0x12, 0x12, 0x12, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x10, 0x0c, + 0x0d, 0x0e, 0x0d, 0x0c, 0x0c, 0x0e, 0x0d, 0x0f, 0x0d, 0x0c, 0x0e, 0x0d, + 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0c, 0x0f, + 0x14, 0xb4, 0xed, 0x19, 0x0f, 0x10, 0x10, 0x12, 0x11, 0x13, 0x15, 0x1a, + 0x52, 0x75, 0x76, 0x74, 0x76, 0x72, 0x76, 0x7f, 0x87, 0x91, 0xa7, 0xb6, + 0xc8, 0xdb, 0xe6, 0xff, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xea, 0x74, 0x1c, + 0xe9, 0xc1, 0xa5, 0x8b, 0x75, 0x69, 0x5d, 0x57, 0x52, 0x4d, 0x49, 0x4e, + 0x50, 0x48, 0x54, 0x4d, 0x29, 0x2a, 0x2a, 0x2a, 0x3d, 0xde, 0xff, 0xfc, + 0x49, 0x1c, 0x1a, 0x16, 0x13, 0x13, 0x12, 0x10, 0x13, 0x2f, 0x15, 0x0d, + 0x0c, 0x0d, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0d, 0x0e, 0x0c, 0x0d, 0x11, + 0x27, 0xf2, 0xec, 0x1d, 0x10, 0x0f, 0x0f, 0x11, 0x13, 0x14, 0x15, 0x2b, + 0x71, 0x75, 0x75, 0x78, 0x79, 0x84, 0x89, 0x9a, 0xa7, 0xbc, 0xd2, 0xe1, + 0xff, 0xfa, 0xfa, 0xf0, 0xff, 0xff, 0xfc, 0xf9, 0xff, 0xf1, 0x3e, 0x18, + 0xe8, 0xd6, 0xc5, 0x9f, 0x8d, 0x77, 0x6a, 0x60, 0x5b, 0x58, 0x50, 0x52, + 0x54, 0x42, 0x37, 0x28, 0x29, 0x2a, 0x27, 0x46, 0xd5, 0xea, 0xf9, 0xe3, + 0x43, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x17, 0x17, 0x18, 0x37, 0x19, 0x11, + 0x0c, 0x0d, 0x0d, 0x0e, 0x0d, 0x0c, 0x0d, 0x0e, 0x10, 0x0c, 0x0b, 0x0c, + 0x0e, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0d, 0x0c, 0x0d, 0x0d, 0x13, + 0x8b, 0xeb, 0xdf, 0x23, 0x12, 0x10, 0x13, 0x14, 0x14, 0x18, 0x1c, 0x3b, + 0x70, 0x78, 0x7e, 0x86, 0x90, 0xa7, 0xb6, 0xc5, 0xde, 0xe5, 0xfb, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xed, 0xeb, 0xcb, 0x2b, 0x15, + 0xff, 0xeb, 0xd8, 0xc3, 0xa5, 0x88, 0x75, 0x6b, 0x63, 0x5d, 0x56, 0x51, + 0x51, 0x2c, 0x28, 0x2b, 0x28, 0x2a, 0x59, 0xbf, 0xe0, 0xe6, 0xfd, 0xf1, + 0x40, 0x1c, 0x1a, 0x19, 0x19, 0x19, 0x1a, 0x17, 0x1a, 0x48, 0x3a, 0x15, + 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0d, 0x0c, 0x0c, + 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0e, 0x1e, + 0xd7, 0xb8, 0x4b, 0x18, 0x14, 0x16, 0x16, 0x18, 0x17, 0x19, 0x1d, 0x47, + 0x7f, 0x8a, 0x99, 0xab, 0xb6, 0xcd, 0xe5, 0xeb, 0xff, 0xed, 0xff, 0xff, + 0xff, 0xff, 0xf5, 0xff, 0xfd, 0xee, 0xd5, 0xc6, 0xac, 0x92, 0x23, 0x15, + 0x5f, 0x60, 0x5c, 0x58, 0x54, 0x51, 0x4e, 0x4a, 0x4c, 0x4c, 0x4c, 0x49, + 0x2f, 0x31, 0x31, 0x29, 0x2b, 0x5c, 0x99, 0xbb, 0xe0, 0xff, 0xf6, 0xff, + 0x40, 0x1d, 0x1c, 0x1b, 0x1b, 0x1b, 0x18, 0x17, 0x1b, 0x4d, 0x35, 0x16, + 0x10, 0x0d, 0x0f, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x0d, 0x0d, + 0x0d, 0x0c, 0x0c, 0x0e, 0x0d, 0x0e, 0x0c, 0x0c, 0x0d, 0x0f, 0x10, 0x37, + 0x58, 0x3b, 0x37, 0x18, 0x15, 0x16, 0x18, 0x1a, 0x19, 0x19, 0x21, 0x50, + 0x9d, 0xaa, 0xbe, 0xd6, 0xde, 0xf0, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, + 0xee, 0xff, 0xff, 0xe1, 0xcd, 0xb7, 0xa7, 0x99, 0x8f, 0x85, 0x2d, 0x15, + 0xdf, 0xc8, 0xa8, 0x84, 0x61, 0x50, 0x48, 0x43, 0x42, 0x46, 0x44, 0x4d, + 0x4c, 0x4c, 0x4b, 0x4c, 0x56, 0x5b, 0x5e, 0x5f, 0x6b, 0x72, 0x86, 0x86, + 0x2a, 0x1b, 0x1b, 0x1a, 0x18, 0x1a, 0x18, 0x16, 0x1c, 0x39, 0x26, 0x17, + 0x0f, 0x0c, 0x0e, 0x0d, 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0d, 0x0c, 0x0d, + 0x0e, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0c, 0x0b, 0x0d, 0x0d, 0x10, 0x2f, + 0x39, 0x5f, 0x6a, 0x18, 0x14, 0x16, 0x17, 0x18, 0x18, 0x1b, 0x1f, 0x67, + 0xc2, 0xd1, 0xee, 0xf7, 0xff, 0xff, 0xf2, 0xff, 0xe9, 0xff, 0xeb, 0xfa, + 0xe5, 0xc9, 0xbb, 0xa4, 0x9a, 0x95, 0x91, 0x9e, 0x80, 0x54, 0x25, 0x15, + 0xec, 0xef, 0xe0, 0xf7, 0xf9, 0xde, 0xca, 0xa9, 0x58, 0x3e, 0x42, 0x4c, + 0x4b, 0x4f, 0x4c, 0x55, 0x51, 0x60, 0x67, 0x6d, 0x6e, 0x67, 0x6c, 0x2e, + 0x22, 0x1c, 0x1b, 0x1a, 0x18, 0x18, 0x18, 0x17, 0x1b, 0x38, 0x25, 0x16, + 0x0f, 0x0e, 0x0d, 0x0e, 0x0c, 0x0b, 0x0d, 0x0c, 0x0d, 0x0d, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, 0x0c, 0x0e, 0x0d, 0x10, 0x1a, 0x5b, + 0x75, 0x7b, 0x69, 0x1b, 0x17, 0x17, 0x15, 0x16, 0x19, 0x19, 0x22, 0x9a, + 0xfe, 0xee, 0xff, 0xfa, 0xf4, 0xff, 0xff, 0xea, 0xd1, 0xed, 0xc8, 0xb5, + 0xa7, 0x9a, 0x90, 0x98, 0x9a, 0x70, 0x53, 0x50, 0x6f, 0x94, 0x5c, 0x17, + 0xdf, 0xf7, 0xff, 0xf9, 0xff, 0xed, 0xdf, 0x60, 0x4b, 0x4c, 0x4a, 0x4c, + 0x4b, 0x4e, 0x49, 0x57, 0x6b, 0x8e, 0xa6, 0xbe, 0xdc, 0xee, 0xf8, 0x36, + 0x21, 0x1c, 0x1a, 0x18, 0x18, 0x16, 0x15, 0x17, 0x16, 0x1f, 0x1d, 0x15, + 0x10, 0x0e, 0x0d, 0x0b, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0d, 0x0c, 0x0e, 0x27, 0x6c, + 0x74, 0x6f, 0x69, 0x1c, 0x15, 0x15, 0x15, 0x18, 0x17, 0x1b, 0x24, 0xe3, + 0xff, 0xf8, 0xfa, 0xe2, 0xff, 0xf1, 0xd9, 0xc9, 0xaf, 0x9e, 0x94, 0x93, + 0x9a, 0x8d, 0x63, 0x4e, 0x5e, 0x8a, 0xa6, 0xb6, 0xd3, 0xf2, 0xea, 0x1d, + 0x8d, 0xa9, 0xca, 0xed, 0xf8, 0xcc, 0x63, 0x56, 0x58, 0x53, 0x4d, 0x50, + 0x4d, 0x50, 0x44, 0x55, 0x76, 0x9b, 0xb2, 0xc1, 0xdc, 0xf2, 0xea, 0x31, + 0x1f, 0x20, 0x1a, 0x1a, 0x17, 0x16, 0x15, 0x14, 0x15, 0x1d, 0x1a, 0x14, + 0x10, 0x0e, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0d, 0x0c, 0x0c, + 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0a, 0x0c, 0x0d, 0x0c, 0x11, 0x26, 0x3f, + 0x5f, 0x6b, 0x6a, 0x23, 0x15, 0x14, 0x16, 0x15, 0x17, 0x19, 0x27, 0x6a, + 0x9b, 0x9d, 0x98, 0x8e, 0x87, 0x73, 0x69, 0x66, 0x65, 0x69, 0x71, 0x58, + 0x47, 0x61, 0x87, 0xa8, 0xc0, 0xed, 0xf1, 0xff, 0xdb, 0xff, 0xbb, 0x1e, + 0x4e, 0x5c, 0x56, 0x6c, 0x72, 0x5a, 0x58, 0x54, 0x50, 0x4e, 0x4e, 0x4d, + 0x4c, 0x4e, 0x40, 0x57, 0x70, 0x97, 0xab, 0xba, 0xd3, 0xe8, 0xe0, 0x2d, + 0x24, 0x20, 0x1c, 0x1c, 0x19, 0x15, 0x14, 0x12, 0x16, 0x19, 0x18, 0x12, + 0x0f, 0x0d, 0x0d, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, + 0x0b, 0x0d, 0x0d, 0x0b, 0x0c, 0x0d, 0x0e, 0x0d, 0x0e, 0x13, 0x25, 0x2d, + 0x6b, 0xc2, 0xcd, 0x48, 0x18, 0x13, 0x13, 0x14, 0x17, 0x1b, 0x2b, 0x9c, + 0xa4, 0x93, 0x75, 0x67, 0x66, 0x43, 0x2b, 0x27, 0x28, 0x2a, 0x29, 0x2c, + 0x2e, 0x30, 0x33, 0x3a, 0x3e, 0x48, 0x50, 0x59, 0x58, 0x54, 0x4b, 0x1c, + 0x3f, 0x39, 0x5d, 0x3a, 0x30, 0x30, 0x2b, 0x2a, 0x27, 0x2e, 0x4f, 0x49, + 0x4d, 0x49, 0x3b, 0x55, 0x6c, 0x9a, 0xaa, 0xb4, 0xca, 0xd7, 0xda, 0x28, + 0x27, 0x21, 0x1d, 0x1c, 0x1a, 0x15, 0x13, 0x16, 0x16, 0x14, 0x14, 0x11, + 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0b, 0x0c, 0x0b, 0x0d, 0x0c, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0a, 0x0c, 0x0d, 0x0c, 0x0d, 0x0d, 0x15, 0x27, 0x34, + 0x9e, 0xf3, 0xfd, 0xe2, 0x1c, 0x13, 0x15, 0x16, 0x18, 0x1b, 0x2d, 0x8d, + 0x97, 0x9d, 0x95, 0x86, 0x65, 0x44, 0x24, 0x20, 0x20, 0x22, 0x24, 0x24, + 0x26, 0x27, 0x27, 0x29, 0x2a, 0x2a, 0x2a, 0x2c, 0x31, 0x30, 0x30, 0x43, + 0x41, 0x3f, 0x38, 0x2f, 0x2c, 0x25, 0x22, 0x20, 0x29, 0x4c, 0x50, 0x49, + 0x49, 0x49, 0x3d, 0x4d, 0x4f, 0x52, 0x5c, 0x65, 0x71, 0x8d, 0x7c, 0x21, + 0x25, 0x20, 0x1e, 0x1a, 0x1a, 0x16, 0x14, 0x17, 0x17, 0x15, 0x13, 0x10, + 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x16, 0x29, 0x9a, + 0xec, 0xe9, 0xff, 0xff, 0x27, 0x14, 0x15, 0x16, 0x18, 0x1c, 0x29, 0x75, + 0x73, 0x6f, 0x78, 0xa9, 0xca, 0xb6, 0x27, 0x20, 0x1f, 0x23, 0x24, 0x24, + 0x26, 0x29, 0x28, 0x28, 0x29, 0x27, 0x29, 0x29, 0x2c, 0x31, 0x30, 0x59, + 0x31, 0x27, 0x38, 0x29, 0x25, 0x21, 0x1f, 0x2b, 0x47, 0x49, 0x47, 0x48, + 0x47, 0x45, 0x3b, 0x49, 0x54, 0x4e, 0x4f, 0x57, 0x5a, 0x4c, 0x43, 0x20, + 0x21, 0x1e, 0x1d, 0x1a, 0x1c, 0x17, 0x14, 0x18, 0x1a, 0x14, 0x10, 0x10, + 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0c, 0x0d, 0x0c, 0x0b, 0x0b, + 0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x11, 0x1a, 0x2a, 0xea, + 0xf9, 0xff, 0xfe, 0xfa, 0x2d, 0x16, 0x15, 0x16, 0x19, 0x1c, 0x25, 0x81, + 0xc7, 0xef, 0xff, 0xef, 0xff, 0xca, 0x2c, 0x21, 0x21, 0x24, 0x26, 0x27, + 0x25, 0x28, 0x29, 0x2a, 0x29, 0x28, 0x28, 0x27, 0x2c, 0x2f, 0x2f, 0x37, + 0x3e, 0x48, 0x4f, 0x48, 0x43, 0x38, 0x3e, 0x49, 0x49, 0x4a, 0x45, 0x41, + 0x44, 0x3e, 0x3e, 0x49, 0x43, 0x36, 0x37, 0x39, 0x38, 0x41, 0x2e, 0x1e, + 0x20, 0x1d, 0x1b, 0x1a, 0x1b, 0x1b, 0x19, 0x18, 0x1c, 0x19, 0x16, 0x10, + 0x0e, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x11, 0x1a, 0x28, 0xa7, + 0xff, 0xe9, 0xf1, 0xfb, 0x32, 0x16, 0x18, 0x16, 0x18, 0x1a, 0x25, 0xe2, + 0xf1, 0xff, 0xff, 0xff, 0x88, 0x5d, 0x28, 0x22, 0x23, 0x24, 0x27, 0x27, + 0x26, 0x28, 0x29, 0x28, 0x29, 0x28, 0x25, 0x28, 0x26, 0x2b, 0x2c, 0x2f, + 0x50, 0x5a, 0x5e, 0x65, 0x61, 0x45, 0x41, 0x47, 0x48, 0x47, 0x44, 0x3e, + 0x43, 0x3c, 0x40, 0x4d, 0x4d, 0x4d, 0x4b, 0x4a, 0x48, 0x44, 0x2e, 0x1e, + 0x20, 0x1b, 0x19, 0x1c, 0x1a, 0x1d, 0x19, 0x1e, 0x1d, 0x18, 0x15, 0x12, + 0x10, 0x0e, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0b, + 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x10, 0x15, 0x19, 0x24, 0x46, + 0xff, 0xff, 0xe5, 0xff, 0x33, 0x19, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x4e, + 0x73, 0xcb, 0xe2, 0xbf, 0x6b, 0x5c, 0x2b, 0x22, 0x22, 0x24, 0x25, 0x25, + 0x27, 0x26, 0x28, 0x27, 0x28, 0x26, 0x24, 0x23, 0x24, 0x26, 0x29, 0x2c, + 0x4d, 0x4f, 0x53, 0x60, 0x5b, 0x3e, 0x3a, 0x3a, 0x3d, 0x39, 0x38, 0x38, + 0x3e, 0x38, 0x34, 0x3b, 0x3a, 0x3a, 0x39, 0x3a, 0x38, 0x37, 0x25, 0x1d, + 0x21, 0x1b, 0x19, 0x1b, 0x1b, 0x1c, 0x1b, 0x20, 0x1c, 0x18, 0x15, 0x14, + 0x11, 0x0f, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, 0x0f, 0x15, 0x16, 0x1b, 0x20, 0x2d, + 0x9f, 0xe1, 0xe3, 0xcf, 0x2a, 0x18, 0x19, 0x17, 0x16, 0x17, 0x1f, 0x5c, + 0x91, 0xc7, 0xe6, 0xef, 0xeb, 0xec, 0x35, 0x20, 0x20, 0x23, 0x25, 0x25, + 0x25, 0x25, 0x24, 0x26, 0x25, 0x23, 0x20, 0x21, 0x21, 0x22, 0x21, 0x21, + 0x39, 0x50, 0x56, 0x5f, 0x56, 0x3a, 0x39, 0x3e, 0x3b, 0x3b, 0x37, 0x38, + 0x3c, 0x33, 0x32, 0x3a, 0x39, 0x37, 0x36, 0x35, 0x34, 0x34, 0x1f, 0x18, + 0x1d, 0x18, 0x19, 0x18, 0x19, 0x1a, 0x18, 0x1f, 0x1b, 0x18, 0x17, 0x15, + 0x10, 0x11, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, + 0x0f, 0x0d, 0x0e, 0x0d, 0x10, 0x0f, 0x11, 0x13, 0x15, 0x18, 0x1d, 0x23, + 0x3c, 0x62, 0x67, 0x55, 0x1c, 0x17, 0x16, 0x16, 0x16, 0x15, 0x1e, 0x36, + 0x39, 0x3b, 0x44, 0x3f, 0x33, 0x2f, 0x23, 0x1c, 0x1e, 0x20, 0x21, 0x23, + 0x22, 0x23, 0x24, 0x23, 0x23, 0x1f, 0x1f, 0x1e, 0x1e, 0x1c, 0x1c, 0x1c, + 0x48, 0x50, 0x57, 0x5c, 0x49, 0x38, 0x39, 0x3a, 0x37, 0x39, 0x35, 0x37, + 0x38, 0x2b, 0x31, 0x39, 0x38, 0x36, 0x35, 0x35, 0x33, 0x30, 0x1c, 0x14, + 0x1c, 0x18, 0x17, 0x17, 0x16, 0x19, 0x19, 0x1d, 0x19, 0x17, 0x14, 0x12, + 0x12, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x10, + 0x0f, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x12, 0x15, 0x17, 0x19, 0x1e, + 0x27, 0x44, 0x4d, 0x34, 0x19, 0x15, 0x17, 0x15, 0x13, 0x13, 0x1e, 0x36, + 0x37, 0x32, 0x30, 0x2e, 0x28, 0x28, 0x1e, 0x1a, 0x1b, 0x1c, 0x1c, 0x1e, + 0x20, 0x20, 0x21, 0x21, 0x21, 0x1f, 0x1b, 0x1a, 0x1a, 0x19, 0x1a, 0x17, + 0x41, 0x4c, 0x51, 0x58, 0x40, 0x37, 0x38, 0x37, 0x37, 0x37, 0x30, 0x36, + 0x37, 0x29, 0x32, 0x35, 0x36, 0x38, 0x35, 0x36, 0x33, 0x2e, 0x1a, 0x14, + 0x1b, 0x18, 0x15, 0x16, 0x16, 0x18, 0x18, 0x1d, 0x1a, 0x18, 0x19, 0x18, + 0x14, 0x12, 0x14, 0x10, 0x0f, 0x0f, 0x0e, 0x0f, 0x0d, 0x0d, 0x0f, 0x11, + 0x0e, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x13, 0x11, 0x11, 0x14, 0x1b, + 0x20, 0x39, 0x45, 0x28, 0x16, 0x15, 0x13, 0x12, 0x10, 0x13, 0x1e, 0x37, + 0x38, 0x2f, 0x2d, 0x2d, 0x28, 0x27, 0x1d, 0x16, 0x16, 0x18, 0x1a, 0x1b, + 0x1e, 0x1c, 0x1f, 0x1e, 0x1d, 0x1d, 0x1b, 0x18, 0x19, 0x18, 0x16, 0x17, + 0x43, 0x4f, 0x50, 0x52, 0x3d, 0x37, 0x36, 0x37, 0x36, 0x36, 0x30, 0x33, + 0x34, 0x26, 0x31, 0x34, 0x36, 0x37, 0x37, 0x35, 0x32, 0x30, 0x2b, 0x25, + 0x1c, 0x17, 0x13, 0x15, 0x14, 0x18, 0x17, 0x1a, 0x1a, 0x19, 0x1a, 0x18, + 0x13, 0x13, 0x12, 0x11, 0x11, 0x0f, 0x11, 0x10, 0x0d, 0x0f, 0x10, 0x11, + 0x0f, 0x12, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f, 0x11, 0x13, 0x12, 0x16, 0x1a, + 0x1f, 0x2c, 0x43, 0x1f, 0x17, 0x14, 0x14, 0x12, 0x11, 0x13, 0x21, 0x38, + 0x34, 0x33, 0x2e, 0x2b, 0x2a, 0x25, 0x1b, 0x14, 0x14, 0x14, 0x17, 0x18, + 0x1a, 0x1a, 0x1d, 0x1c, 0x1c, 0x1a, 0x18, 0x18, 0x16, 0x16, 0x14, 0x15, + 0x40, 0x45, 0x4a, 0x4c, 0x36, 0x35, 0x36, 0x37, 0x35, 0x36, 0x2d, 0x32, + 0x31, 0x26, 0x31, 0x34, 0x37, 0x36, 0x36, 0x32, 0x32, 0x32, 0x2e, 0x2b, + 0x1f, 0x15, 0x14, 0x13, 0x14, 0x16, 0x17, 0x19, 0x19, 0x19, 0x17, 0x14, + 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0c, 0x0f, + 0x0e, 0x0f, 0x0e, 0x0f, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x13, 0x15, 0x16, + 0x1d, 0x25, 0x39, 0x1e, 0x16, 0x13, 0x11, 0x0f, 0x11, 0x13, 0x2a, 0x38, + 0x36, 0x32, 0x2d, 0x28, 0x27, 0x24, 0x1c, 0x11, 0x10, 0x10, 0x12, 0x17, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1a, 0x17, 0x17, 0x15, 0x15, 0x14, 0x13, + 0x2c, 0x2e, 0x30, 0x31, 0x33, 0x36, 0x35, 0x34, 0x36, 0x33, 0x2d, 0x31, + 0x30, 0x25, 0x32, 0x38, 0x35, 0x36, 0x34, 0x36, 0x33, 0x31, 0x2e, 0x2d, + 0x23, 0x15, 0x15, 0x12, 0x13, 0x16, 0x17, 0x17, 0x1b, 0x19, 0x15, 0x13, + 0x13, 0x11, 0x10, 0x0f, 0x0e, 0x0f, 0x0f, 0x10, 0x0e, 0x0d, 0x0d, 0x0e, + 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x13, 0x15, 0x15, 0x16, + 0x1b, 0x20, 0x2a, 0x19, 0x15, 0x14, 0x11, 0x0f, 0x12, 0x16, 0x30, 0x38, + 0x35, 0x30, 0x2c, 0x2b, 0x28, 0x25, 0x1b, 0x20, 0x1b, 0x1a, 0x1b, 0x1a, + 0x19, 0x1a, 0x1a, 0x1c, 0x1e, 0x1d, 0x1d, 0x1c, 0x1c, 0x1a, 0x1c, 0x1d, + 0x26, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x33, 0x33, 0x30, 0x2d, 0x31, + 0x2e, 0x25, 0x33, 0x32, 0x37, 0x35, 0x36, 0x37, 0x34, 0x32, 0x2f, 0x2c, + 0x27, 0x17, 0x13, 0x12, 0x12, 0x15, 0x15, 0x17, 0x17, 0x19, 0x16, 0x13, + 0x11, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0c, 0x0e, + 0x0f, 0x10, 0x0f, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x14, 0x14, + 0x18, 0x1e, 0x22, 0x13, 0x13, 0x11, 0x11, 0x11, 0x10, 0x19, 0x37, 0x38, + 0x33, 0x30, 0x2c, 0x29, 0x27, 0x23, 0x21, 0x1f, 0x1d, 0x1b, 0x1b, 0x18, + 0x11, 0x0e, 0x0f, 0x20, 0x22, 0x26, 0x2b, 0x2b, 0x29, 0x30, 0x32, 0x2f, + 0x27, 0x2d, 0x2f, 0x2f, 0x30, 0x31, 0x32, 0x30, 0x31, 0x2f, 0x2b, 0x2f, + 0x2e, 0x28, 0x31, 0x34, 0x34, 0x34, 0x33, 0x33, 0x34, 0x30, 0x2f, 0x2e, + 0x27, 0x18, 0x13, 0x13, 0x11, 0x14, 0x15, 0x18, 0x18, 0x16, 0x15, 0x13, + 0x11, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0f, 0x0e, 0x0d, 0x0d, 0x0c, 0x10, + 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x0f, 0x10, 0x11, 0x12, 0x15, 0x17, 0x17, + 0x19, 0x1d, 0x1d, 0x16, 0x14, 0x10, 0x0f, 0x10, 0x11, 0x1e, 0x39, 0x3a, + 0x36, 0x30, 0x2f, 0x2e, 0x2a, 0x27, 0x27, 0x21, 0x1d, 0x1d, 0x1c, 0x19, + 0x11, 0x0f, 0x0f, 0x21, 0x25, 0x29, 0x2c, 0x2f, 0x2e, 0x2e, 0x32, 0x2f, + 0x26, 0x2a, 0x2c, 0x2d, 0x2e, 0x30, 0x2f, 0x2e, 0x2e, 0x2d, 0x2f, 0x2d, + 0x28, 0x29, 0x2f, 0x30, 0x2e, 0x30, 0x2f, 0x31, 0x2f, 0x2e, 0x2a, 0x2b, + 0x22, 0x18, 0x14, 0x11, 0x11, 0x12, 0x15, 0x17, 0x18, 0x16, 0x14, 0x12, + 0x10, 0x0f, 0x0f, 0x0f, 0x0d, 0x0f, 0x0e, 0x0e, 0x0b, 0x0c, 0x0c, 0x0d, + 0x0f, 0x0e, 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x14, 0x16, 0x17, + 0x17, 0x1b, 0x1c, 0x14, 0x12, 0x10, 0x0f, 0x0f, 0x11, 0x2a, 0x38, 0x37, + 0x34, 0x35, 0x32, 0x31, 0x2e, 0x2c, 0x2a, 0x24, 0x21, 0x22, 0x1f, 0x1b, + 0x13, 0x0f, 0x10, 0x20, 0x27, 0x2b, 0x2e, 0x32, 0x30, 0x2c, 0x2e, 0x2b, + 0x2c, 0x28, 0x28, 0x29, 0x2a, 0x27, 0x21, 0x22, 0x22, 0x23, 0x1b, 0x11, + 0x12, 0x12, 0x12, 0x15, 0x15, 0x14, 0x14, 0x15, 0x14, 0x16, 0x16, 0x16, + 0x14, 0x16, 0x11, 0x11, 0x11, 0x13, 0x15, 0x18, 0x16, 0x14, 0x15, 0x13, + 0x11, 0x11, 0x11, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0b, 0x0c, 0x0c, 0x0b, + 0x0c, 0x0e, 0x0e, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x0f, 0x12, 0x13, 0x15, + 0x16, 0x19, 0x19, 0x14, 0x11, 0x11, 0x0f, 0x10, 0x14, 0x17, 0x19, 0x1b, + 0x23, 0x33, 0x30, 0x2e, 0x2c, 0x28, 0x26, 0x1e, 0x1e, 0x20, 0x1d, 0x1b, + 0x12, 0x0f, 0x10, 0x21, 0x27, 0x29, 0x2a, 0x28, 0x26, 0x24, 0x1f, 0x24, + 0x2a, 0x22, 0x25, 0x27, 0x25, 0x28, 0x26, 0x24, 0x20, 0x14, 0x0f, 0x10, + 0x0e, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0b, 0x0c, 0x0d, + 0x0d, 0x13, 0x14, 0x11, 0x13, 0x13, 0x14, 0x15, 0x14, 0x15, 0x14, 0x12, + 0x10, 0x0d, 0x0f, 0x0d, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, + 0x0e, 0x0c, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x12, 0x12, 0x11, 0x12, 0x15, + 0x16, 0x18, 0x1b, 0x15, 0x13, 0x11, 0x10, 0x11, 0x12, 0x0e, 0x17, 0x2b, + 0x2e, 0x33, 0x2e, 0x2f, 0x28, 0x26, 0x21, 0x1d, 0x1a, 0x1c, 0x1f, 0x1f, + 0x19, 0x15, 0x13, 0x1f, 0x23, 0x27, 0x24, 0x24, 0x1d, 0x19, 0x18, 0x1c, + 0x2e, 0x2c, 0x29, 0x25, 0x1e, 0x1d, 0x23, 0x21, 0x20, 0x11, 0x0f, 0x0d, + 0x0e, 0x0f, 0x15, 0x16, 0x17, 0x13, 0x0d, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, + 0x0d, 0x18, 0x15, 0x12, 0x11, 0x13, 0x15, 0x13, 0x13, 0x11, 0x11, 0x0e, + 0x0f, 0x0f, 0x0f, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x12, 0x12, 0x12, 0x13, + 0x14, 0x17, 0x17, 0x15, 0x13, 0x11, 0x10, 0x14, 0x10, 0x18, 0x1e, 0x27, + 0x24, 0x20, 0x32, 0x3c, 0x38, 0x3a, 0x34, 0x29, 0x32, 0x35, 0x3e, 0x3d, + 0x3c, 0x3f, 0x1c, 0x1f, 0x20, 0x21, 0x26, 0x21, 0x1e, 0x20, 0x20, 0x23, + 0x15, 0x12, 0x11, 0x10, 0x0f, 0x15, 0x23, 0x22, 0x1f, 0x10, 0x0f, 0x0f, + 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0b, 0x0d, 0x0c, 0x0b, 0x0c, 0x0d, 0x0d, + 0x0f, 0x1c, 0x15, 0x13, 0x12, 0x15, 0x15, 0x14, 0x12, 0x10, 0x10, 0x11, + 0x10, 0x0e, 0x0e, 0x0e, 0x0f, 0x0d, 0x0c, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, + 0x0d, 0x0e, 0x0d, 0x0d, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x16, + 0x15, 0x17, 0x16, 0x16, 0x13, 0x12, 0x11, 0x14, 0x0e, 0x0d, 0x0e, 0x0d, + 0x0e, 0x0f, 0x10, 0x13, 0x12, 0x16, 0x14, 0x14, 0x13, 0x12, 0x13, 0x13, + 0x13, 0x13, 0x11, 0x0e, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0d, 0x0d, 0x0e, + 0x10, 0x0e, 0x10, 0x0e, 0x0f, 0x15, 0x21, 0x1f, 0x1c, 0x0e, 0x0d, 0x0e, + 0x0f, 0x10, 0x0e, 0x0d, 0x0d, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, + 0x16, 0x1b, 0x19, 0x13, 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x10, 0x10, + 0x0e, 0x0e, 0x0f, 0x0e, 0x0d, 0x0d, 0x0c, 0x0b, 0x0d, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x14, 0x13, 0x11, 0x13, 0x11, 0x0d, 0x0c, 0x0d, 0x0d, + 0x0d, 0x0d, 0x0c, 0x0c, 0x0e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0b, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0d, 0x0c, 0x0c, + 0x11, 0x0f, 0x0e, 0x0d, 0x0f, 0x16, 0x20, 0x1e, 0x1c, 0x0e, 0x0d, 0x0d, + 0x0f, 0x11, 0x10, 0x10, 0x0d, 0x0b, 0x0b, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, + 0x19, 0x1d, 0x19, 0x15, 0x14, 0x13, 0x15, 0x15, 0x12, 0x13, 0x12, 0x10, + 0x0f, 0x0f, 0x0f, 0x0d, 0x0d, 0x0c, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, + 0x0e, 0x10, 0x10, 0x0d, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f, 0x14, 0x13, 0x13, + 0x14, 0x16, 0x17, 0x13, 0x11, 0x11, 0x16, 0x0f, 0x0c, 0x0d, 0x0e, 0x0d, + 0x0f, 0x0d, 0x0d, 0x0c, 0x0e, 0x0d, 0x0c, 0x0f, 0x13, 0x0f, 0x0d, 0x0c, + 0x0c, 0x0d, 0x0c, 0x0a, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, + 0x10, 0x0e, 0x0e, 0x0e, 0x0f, 0x18, 0x1e, 0x1e, 0x1b, 0x0e, 0x0c, 0x0e, + 0x10, 0x10, 0x11, 0x10, 0x0f, 0x0c, 0x0d, 0x0c, 0x0d, 0x0b, 0x0c, 0x10, + 0x1c, 0x1b, 0x19, 0x16, 0x13, 0x13, 0x14, 0x13, 0x12, 0x12, 0x12, 0x11, + 0x0f, 0x10, 0x0c, 0x0d, 0x0e, 0x0d, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0f, 0x12, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, 0x11, 0x11, 0x13, 0x13, + 0x11, 0x14, 0x16, 0x12, 0x12, 0x14, 0x17, 0x10, 0x0d, 0x0d, 0x0c, 0x0f, + 0x11, 0x11, 0x0f, 0x0f, 0x0e, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0c, 0x0a, 0x09, 0x0a, 0x0c, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0f, 0x0f, 0x0e, 0x0f, 0x11, 0x1b, 0x1d, 0x1e, 0x18, 0x0f, 0x0e, 0x0d, + 0x10, 0x12, 0x12, 0x12, 0x0e, 0x0d, 0x0e, 0x0c, 0x0c, 0x0d, 0x0f, 0x17, + 0x1d, 0x1a, 0x1b, 0x18, 0x15, 0x14, 0x16, 0x14, 0x13, 0x12, 0x11, 0x11, + 0x11, 0x10, 0x0e, 0x0f, 0x0e, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, + 0x0f, 0x11, 0x13, 0x13, 0x0f, 0x10, 0x11, 0x0f, 0x11, 0x12, 0x13, 0x10, + 0x13, 0x12, 0x14, 0x14, 0x13, 0x16, 0x19, 0x12, 0x10, 0x0f, 0x0f, 0x11, + 0x13, 0x14, 0x12, 0x0e, 0x0c, 0x0b, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, + 0x0b, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, + 0x10, 0x0e, 0x0e, 0x0f, 0x0f, 0x1a, 0x1c, 0x1d, 0x16, 0x0d, 0x0d, 0x0d, + 0x10, 0x10, 0x12, 0x11, 0x0e, 0x0d, 0x0e, 0x0d, 0x0e, 0x0f, 0x0f, 0x1b, + 0x1f, 0x29, 0x26, 0x1a, 0x14, 0x12, 0x14, 0x14, 0x13, 0x13, 0x13, 0x11, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0e, 0x0d, 0x0e, 0x0e, 0x0c, 0x0e, 0x0f, + 0x0f, 0x11, 0x10, 0x12, 0x10, 0x0d, 0x0f, 0x11, 0x10, 0x10, 0x11, 0x13, + 0x11, 0x13, 0x14, 0x11, 0x13, 0x19, 0x1e, 0x14, 0x16, 0x20, 0x21, 0x22, + 0x1d, 0x19, 0x11, 0x0c, 0x0b, 0x0b, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, + 0x0e, 0x0d, 0x0e, 0x0f, 0x10, 0x18, 0x1d, 0x1a, 0x13, 0x0c, 0x0d, 0x0c, + 0x0f, 0x11, 0x13, 0x11, 0x0e, 0x0d, 0x0c, 0x0d, 0x0f, 0x0f, 0x12, 0x1e, + 0x2d, 0x2a, 0x25, 0x1e, 0x18, 0x13, 0x12, 0x13, 0x11, 0x12, 0x12, 0x0f, + 0x0e, 0x10, 0x10, 0x0f, 0x0d, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0f, 0x10, 0x11, 0x11, 0x12, 0x0f, 0x0e, 0x0f, 0x0f, 0x12, 0x12, 0x13, + 0x12, 0x13, 0x15, 0x14, 0x17, 0x21, 0x29, 0x15, 0x10, 0x15, 0x15, 0x12, + 0x12, 0x10, 0x0f, 0x0d, 0x0c, 0x0c, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0d, 0x0c, 0x0e, 0x0d, 0x0d, 0x0b, 0x0d, 0x0b, 0x0c, 0x0d, 0x0d, + 0x10, 0x0f, 0x0e, 0x10, 0x13, 0x16, 0x19, 0x1a, 0x12, 0x0f, 0x0c, 0x0d, + 0x10, 0x11, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0d, 0x0f, 0x10, 0x19, 0x2f, + 0x33, 0x29, 0x25, 0x1d, 0x1a, 0x15, 0x13, 0x13, 0x12, 0x12, 0x10, 0x0f, + 0x0d, 0x0e, 0x0e, 0x0e, 0x0c, 0x0c, 0x0c, 0x0e, 0x0e, 0x0e, 0x0c, 0x0d, + 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x0f, 0x10, 0x0f, 0x11, 0x13, 0x13, + 0x12, 0x17, 0x18, 0x18, 0x19, 0x1f, 0x28, 0x28, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x11, 0x10, 0x10, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, 0x0d, 0x0c, + 0x0d, 0x0f, 0x0f, 0x0f, 0x10, 0x14, 0x11, 0x11, 0x11, 0x10, 0x13, 0x14, + 0x10, 0x10, 0x10, 0x12, 0x10, 0x14, 0x16, 0x17, 0x0f, 0x0e, 0x0e, 0x0e, + 0x10, 0x12, 0x12, 0x11, 0x0d, 0x0e, 0x0d, 0x0d, 0x0e, 0x12, 0x22, 0x2c, + 0x2a, 0x26, 0x23, 0x1e, 0x18, 0x17, 0x16, 0x13, 0x12, 0x11, 0x10, 0x0f, + 0x0e, 0x0f, 0x0e, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0d, 0x0d, + 0x0e, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x10, 0x12, 0x12, + 0x17, 0x1b, 0x1a, 0x19, 0x1b, 0x1f, 0x29, 0x2d, 0x13, 0x0c, 0x0d, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 0x0c, 0x0c, 0x0c, 0x0c, 0x11, + 0x18, 0x1a, 0x1a, 0x19, 0x18, 0x1e, 0x1a, 0x1b, 0x1c, 0x1a, 0x23, 0x21, + 0x0e, 0x0d, 0x0c, 0x0e, 0x11, 0x13, 0x14, 0x14, 0x0e, 0x0c, 0x0d, 0x0c, + 0x0d, 0x12, 0x12, 0x10, 0x0c, 0x0b, 0x0b, 0x0b, 0x10, 0x1f, 0x2a, 0x29, + 0x26, 0x27, 0x21, 0x1c, 0x19, 0x18, 0x18, 0x15, 0x10, 0x0f, 0x0f, 0x0e, + 0x0c, 0x0b, 0x0a, 0x0c, 0x0b, 0x0a, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, + 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0d, 0x11, 0x0e, 0x0e, 0x0f, 0x10, 0x11, + 0x17, 0x19, 0x1b, 0x1b, 0x1c, 0x1e, 0x25, 0x2b, 0x2c, 0x10, 0x0d, 0x0b, + 0x0b, 0x0b, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x10, 0x18, 0x16, 0x14, + 0x12, 0x18, 0x14, 0x15, 0x15, 0x15, 0x17, 0x14, 0x15, 0x14, 0x16, 0x18, + 0x0d, 0x0c, 0x0d, 0x0f, 0x10, 0x13, 0x14, 0x15, 0x0f, 0x0e, 0x0d, 0x0c, + 0x10, 0x11, 0x12, 0x11, 0x0d, 0x0c, 0x0b, 0x0c, 0x14, 0x22, 0x23, 0x25, + 0x25, 0x22, 0x1c, 0x21, 0x1e, 0x1c, 0x1a, 0x16, 0x11, 0x0f, 0x0e, 0x0e, + 0x0b, 0x0b, 0x0a, 0x0b, 0x0a, 0x0a, 0x0b, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x0e, 0x0f, 0x11, 0x13, + 0x19, 0x1c, 0x1b, 0x1c, 0x1f, 0x1d, 0x21, 0x25, 0x2c, 0x1d, 0x0d, 0x0c, + 0x0b, 0x12, 0x1d, 0x1d, 0x26, 0x24, 0x1a, 0x18, 0x14, 0x1b, 0x14, 0x14, + 0x15, 0x17, 0x16, 0x14, 0x14, 0x14, 0x1b, 0x15, 0x15, 0x15, 0x13, 0x25}; +unsigned int _tmp_dump_person_4_bmp_len = 9216; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.h b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.h new file mode 100644 index 0000000..02ac2fd --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/examples/person_detection_experimental/person_image_data.h @@ -0,0 +1,30 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// This data was created from a sample image from with a person in it. +// Convert original image to simpler format: +// convert -resize 96x96\! person.PNG person.bmp3 +// Skip the 54 byte bmp3 header and add the reset of the bytes to a C array: +// xxd -s 54 -i /tmp/person.bmp3 > /tmp/person.cc + +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_PERSON_IMAGE_DATA_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_PERSON_IMAGE_DATA_H_ + +#include + +extern const int g_person_data_size; +extern const uint8_t g_person_data[]; + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_PERSON_DETECTION_PERSON_IMAGE_DATA_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activation_utils.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activation_utils.h new file mode 100644 index 0000000..95ecc26 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activation_utils.h @@ -0,0 +1,57 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_ACTIVATION_UTILS_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_ACTIVATION_UTILS_H_ + +#include +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/kernels/internal/cppmath.h" +#include "tensorflow/lite/kernels/internal/max.h" +#include "tensorflow/lite/kernels/internal/min.h" + +namespace tflite { +namespace ops { +namespace micro { + +// Returns the floating point value for a fused activation: +inline float ActivationValFloat(TfLiteFusedActivation act, float a) { + switch (act) { + case kTfLiteActNone: + return a; + case kTfLiteActRelu: + return TfLiteMax(0.0f, a); + case kTfLiteActReluN1To1: + return TfLiteMax(-1.0f, TfLiteMin(a, 1.0f)); + case kTfLiteActRelu6: + return TfLiteMax(0.0f, TfLiteMin(a, 6.0f)); + case kTfLiteActTanh: + return std::tanh(a); + case kTfLiteActSignBit: + return std::signbit(a); + case kTfLiteActSigmoid: + return 1.0f / (1.0f + std::exp(-a)); + } + return 0.0f; // To indicate an unsupported activation (i.e. when a new fused + // activation is added to the enum and not handled here). +} + +} // namespace micro +} // namespace ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_ACTIVATION_UTILS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activations.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activations.cc new file mode 100644 index 0000000..2bdc0b5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/activations.cc @@ -0,0 +1,285 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { + +struct ReluOpData { + ReluParams params; +}; + +struct Relu6OpData { + int8_t six_int8; + int8_t zero_int8; + uint8_t six_uint8; + uint8_t zero_uint8; +}; + +} // namespace + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +template +inline void ReluQuantized(const ReluOpData& data, + const RuntimeShape& input_shape, + const RuntimeShape& output_shape, const T* input_data, + T* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + const int32_t val = static_cast(input_data[i]); + int32_t clamped = + data.params.output_offset + + MultiplyByQuantizedMultiplier(val - data.params.input_offset, + data.params.output_multiplier, + data.params.output_shift); + clamped = std::max(data.params.quantized_activation_min, clamped); + clamped = std::min(data.params.quantized_activation_max, clamped); + output_data[i] = static_cast(clamped); + } +} + +template +inline void CalculateReluOpData(const TfLiteTensor* input, TfLiteTensor* output, + ReluOpData* data) { + float act_min = 0.0; + float act_max = std::numeric_limits::infinity(); + double real_multiplier = + static_cast(input->params.scale / output->params.scale); + + const RuntimeShape input_shape = GetTensorShape(input); + const RuntimeShape output_shape = GetTensorShape(output); + + QuantizeMultiplier(real_multiplier, &data->params.output_multiplier, + &data->params.output_shift); + + data->params.quantized_activation_min = std::max( + static_cast(std::numeric_limits::min()), + output->params.zero_point + + static_cast(roundf(act_min / output->params.scale))); + data->params.quantized_activation_max = + act_max == std::numeric_limits::infinity() + ? static_cast(std::numeric_limits::max()) + : std::min(static_cast(std::numeric_limits::max()), + output->params.zero_point + + static_cast( + roundf(act_max / output->params.scale))); + data->params.input_offset = input->params.zero_point; + data->params.output_offset = output->params.zero_point; +} + +inline void ReluFloat(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + const float val = input_data[i]; + const float lower = 0.0f; + const float clamped = val < lower ? lower : val; + output_data[i] = clamped; + } +} + +inline void Relu6Float(const RuntimeShape& input_shape, const float* input_data, + const RuntimeShape& output_shape, float* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + const float val = input_data[i]; + const float upper = 6.0f; + const float lower = 0.0f; + const float clamped = val > upper ? upper : val < lower ? lower : val; + output_data[i] = clamped; + } +} + +template +inline void Relu6Quantized(Q lower, Q upper, const RuntimeShape& input_shape, + const Q* input_data, + const RuntimeShape& output_shape, Q* output_data) { + const int flat_size = MatchingFlatSize(input_shape, output_shape); + for (int i = 0; i < flat_size; ++i) { + const Q val = input_data[i]; + const Q clamped = val > upper ? upper : val < lower ? lower : val; + output_data[i] = clamped; + } +} + +void* ReluInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(ReluOpData)); +} + +TfLiteStatus ReluPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + ReluOpData* data = static_cast(node->user_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + if (input->type == kTfLiteInt8) { + CalculateReluOpData(input, output, data); + } else if (input->type == kTfLiteUInt8) { + CalculateReluOpData(input, output, data); + } + + return kTfLiteOk; +} + +TfLiteStatus ReluEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const ReluOpData& data = *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input->type) { + case kTfLiteFloat32: { + ReluFloat(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + + return kTfLiteOk; + } + case kTfLiteInt8: { + ReluQuantized(data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + case kTfLiteUInt8: { + ReluQuantized(data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + default: { + TF_LITE_KERNEL_LOG(context, "Only float32 is supported currently, got %s", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + } +} + +void* Relu6Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(Relu6OpData)); +} + +TfLiteStatus Relu6Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + Relu6OpData* data = static_cast(node->user_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + + if (input->type == kTfLiteInt8) { + data->six_int8 = FloatToAsymmetricQuantizedInt8(6.0f, input->params.scale, + input->params.zero_point); + data->zero_int8 = input->params.zero_point; + } else if (input->type == kTfLiteUInt8) { + data->six_uint8 = FloatToAsymmetricQuantizedUInt8(6.0f, input->params.scale, + input->params.zero_point); + data->zero_uint8 = input->params.zero_point; + } + + return kTfLiteOk; +} + +TfLiteStatus Relu6Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const Relu6OpData& data = *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input->type) { + case kTfLiteFloat32: { + Relu6Float(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + + return kTfLiteOk; + } + case kTfLiteInt8: { + Relu6Quantized(data.zero_int8, data.six_int8, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + case kTfLiteUInt8: { + Relu6Quantized(data.zero_uint8, data.six_uint8, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + default: { + TF_LITE_KERNEL_LOG(context, "Only float32 is supported currently, got %s", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + } +} + +} // namespace activations + +TfLiteRegistration Register_RELU() { + return {/*init=*/activations::ReluInit, + /*free=*/nullptr, + /*prepare=*/activations::ReluPrepare, + /*invoke=*/activations::ReluEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_RELU6() { + return {/*init=*/activations::Relu6Init, + /*free=*/nullptr, + /*prepare=*/activations::Relu6Prepare, + /*invoke=*/activations::Relu6Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/add.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/add.cc new file mode 100644 index 0000000..79a0487 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/add.cc @@ -0,0 +1,240 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/add.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/add.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace add { + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + bool requires_broadcast; + + // These fields are used in both the general 8-bit -> 8bit quantized path, + // and the special 16-bit -> 16bit quantized path + int input1_shift; + int input2_shift; + int32_t output_activation_min; + int32_t output_activation_max; + + // These fields are used only in the general 8-bit -> 8bit quantized path + int32_t input1_multiplier; + int32_t input2_multiplier; + int32_t output_multiplier; + int output_shift; + int left_shift; + int32_t input1_offset; + int32_t input2_offset; + int32_t output_offset; + + // Used only for float evals: + float output_activation_min_f32; + float output_activation_max_f32; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteAddParams* params, + const TfLiteTensor* input1, + const TfLiteTensor* input2, TfLiteTensor* output, + OpData* data) { + data->requires_broadcast = !HaveSameShapes(input1, input2); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + // 8bit -> 8bit general quantized path, with general rescalings + data->input1_offset = -input1->params.zero_point; + data->input2_offset = -input2->params.zero_point; + data->output_offset = output->params.zero_point; + data->left_shift = 20; + const double twice_max_input_scale = + 2 * static_cast( + std::max(input1->params.scale, input2->params.scale)); + const double real_input1_multiplier = + static_cast(input1->params.scale) / twice_max_input_scale; + const double real_input2_multiplier = + static_cast(input2->params.scale) / twice_max_input_scale; + const double real_output_multiplier = + twice_max_input_scale / + ((1 << data->left_shift) * static_cast(output->params.scale)); + + QuantizeMultiplierSmallerThanOneExp( + real_input1_multiplier, &data->input1_multiplier, &data->input1_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_input2_multiplier, &data->input2_multiplier, &data->input2_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_output_multiplier, &data->output_multiplier, &data->output_shift); + + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + } else if (output->type == kTfLiteFloat32) { + CalculateActivationRange(params->activation, + &data->output_activation_min_f32, + &data->output_activation_max_f32); + } + + return kTfLiteOk; +} + +void EvalAdd(TfLiteContext* context, TfLiteNode* node, TfLiteAddParams* params, + const OpData* data, const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params; + SetActivationParams(data->output_activation_min_f32, + data->output_activation_max_f32, &op_params); +#define TF_LITE_ADD(opname) \ + reference_ops::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)) + if (data->requires_broadcast) { + TF_LITE_ADD(BroadcastAdd4DSlow); + } else { + TF_LITE_ADD(Add); + } +#undef TF_LITE_ADD +} + +TfLiteStatus EvalAddQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteAddParams* params, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + tflite::ArithmeticParams op_params; + op_params.left_shift = data->left_shift; + op_params.input1_offset = data->input1_offset; + op_params.input1_multiplier = data->input1_multiplier; + op_params.input1_shift = data->input1_shift; + op_params.input2_offset = data->input2_offset; + op_params.input2_multiplier = data->input2_multiplier; + op_params.input2_shift = data->input2_shift; + op_params.output_offset = data->output_offset; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + SetActivationParams(data->output_activation_min, + data->output_activation_max, &op_params); + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); +#define TF_LITE_ADD(type, opname, dtype) \ + type::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)); + if (output->type == kTfLiteInt8) { + if (need_broadcast) { + TF_LITE_ADD(reference_integer_ops, BroadcastAdd4DSlow, int8_t); + } else { + TF_LITE_ADD(reference_integer_ops, Add, int8_t); + } + } else { + if (need_broadcast) { + TF_LITE_ADD(reference_ops, BroadcastAdd4DSlow, uint8_t); + } else { + TF_LITE_ADD(reference_ops, Add, uint8_t); + } + } +#undef TF_LITE_ADD + } + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + const TfLiteTensor* input1 = GetInput(context, node, kInputTensor1); + const TfLiteTensor* input2 = GetInput(context, node, kInputTensor2); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + TF_LITE_ENSURE_STATUS( + CalculateOpData(context, params, input1, input2, output, data)); + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + if (output->type == kTfLiteFloat32) { + EvalAdd(context, node, params, data, input1, input2, output); + } else if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + TF_LITE_ENSURE_OK(context, EvalAddQuantized(context, node, params, data, + input1, input2, output)); + } else { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace add + +TfLiteRegistration Register_ADD() { + return {/*init=*/add::Init, + /*free=*/nullptr, + /*prepare=*/add::Prepare, + /*invoke=*/add::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/arg_min_max.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/arg_min_max.cc new file mode 100644 index 0000000..12ac001 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/arg_min_max.cc @@ -0,0 +1,133 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/arg_min_max.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace arg_min_max { + +constexpr int kInputTensor = 0; +constexpr int kAxis = 1; +constexpr int kOutputTensor = 0; + +template +inline void ArgMinMaxHelper(const RuntimeShape& input1_shape, + const T1* input1_data, const T3* input2_data, + const RuntimeShape& output_shape, T2* output_data, + bool is_arg_max) { + if (is_arg_max) { + reference_ops::ArgMinMax(input1_shape, input1_data, input2_data, + output_shape, output_data, micro::Greater()); + } else { + reference_ops::ArgMinMax(input1_shape, input1_data, input2_data, + output_shape, output_data, micro::Less()); + } +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node, bool is_arg_max) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* axis = + tflite::micro::GetEvalInput(context, node, kAxis); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + +#define TF_LITE_ARG_MIN_MAX(data_type, axis_type, output_type) \ + ArgMinMaxHelper(tflite::micro::GetTensorShape(input), \ + tflite::micro::GetTensorData(input), \ + tflite::micro::GetTensorData(axis), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output), \ + is_arg_max) + if (axis->type == kTfLiteInt32) { + if (output->type == kTfLiteInt32) { + switch (input->type) { + case kTfLiteFloat32: + TF_LITE_ARG_MIN_MAX(float, int32_t, int32_t); + break; + case kTfLiteUInt8: + TF_LITE_ARG_MIN_MAX(uint8_t, int32_t, int32_t); + break; + case kTfLiteInt8: + TF_LITE_ARG_MIN_MAX(int8_t, int32_t, int32_t); + break; + default: + TF_LITE_KERNEL_LOG(context, + "Only float32, uint8_t and int8_t are " + "supported currently, got %s.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + } else { + TF_LITE_KERNEL_LOG(context, + "Only int32_t are supported currently, got %s.", + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else { + TF_LITE_KERNEL_LOG(context, "Only int32_t are supported currently, got %s.", + TfLiteTypeGetName(axis->type)); + return kTfLiteError; + } + +#undef TF_LITE_ARG_MIN_MAX + + return kTfLiteOk; +} + +TfLiteStatus ArgMinEval(TfLiteContext* context, TfLiteNode* node) { + return Eval(context, node, false); +} + +TfLiteStatus ArgMaxEval(TfLiteContext* context, TfLiteNode* node) { + return Eval(context, node, true); +} + +} // namespace arg_min_max + +TfLiteRegistration Register_ARG_MAX() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/arg_min_max::ArgMaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_ARG_MIN() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/arg_min_max::ArgMinEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ceil.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ceil.cc new file mode 100644 index 0000000..3bce8a7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ceil.cc @@ -0,0 +1,74 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/ceil.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace ceil { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32); + TF_LITE_ENSURE_TYPES_EQ(context, output->type, input->type); + TF_LITE_ENSURE_EQ(context, output->bytes, input->bytes); + TF_LITE_ENSURE_EQ(context, output->dims->size, input->dims->size); + for (int i = 0; i < output->dims->size; ++i) { + TF_LITE_ENSURE_EQ(context, output->dims->data[i], input->dims->data[i]); + } + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + reference_ops::Ceil(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + + return kTfLiteOk; +} +} // namespace ceil + +TfLiteRegistration Register_CEIL() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ceil::Prepare, + /*invoke=*/ceil::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/circular_buffer.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/circular_buffer.cc new file mode 100644 index 0000000..b5a8ae1 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/circular_buffer.cc @@ -0,0 +1,178 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/add.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +/* + * The circular buffer custom operator is used to implement strided streaming + * convolutions on TFLite Micro. Each time this operator is invoked, it checks + * whether or not to run, based on a predetermined stride in time. If the op + * runs, it inserts the input into the end of the output buffer and shifts the + * output values towards the start of the buffer. It discards the oldest value + * in the output buffer. + * + * Input: [, , , ] + * + * After shifting: + * Output: [, , , ] + * + * We make some assumptions in this custom operator: + * - Input shape must be [1, 1, 1, depth] + * - Output shape must be [1, num_slots, 1, depth] + * - Input and output types must match. + * - Input and output quantization params must be identical. + */ +namespace tflite { +namespace ops { +namespace micro { +namespace circular_buffer { + +namespace { + +// The CircularBuffer op has one input and one output tensor. +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +// TODO(b/149795762): Add this to TfLiteStatus enum. +constexpr int kTfLiteAbort = -9; + +// These fields control the stride period of a strided streaming model. This op +// returns kTfLiteAbort until cycles_until_run-- is zero. At this time, +// cycles_until_run is reset to cycles_max. +struct OpData { + int cycles_until_run; + int cycles_max; +}; + +// These constants represent constants specific to the music detect model. +// They exist until (b/132070898) is fixed. +constexpr int kMaxOpDataSize = 7; +int op_data_counter = 0; +OpData op_data_array[kMaxOpDataSize]; + +} // namespace + +void Free(TfLiteContext* context, void* buffer) { op_data_counter = 0; } + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE(context, input != nullptr); + TF_LITE_ENSURE(context, output != nullptr); + TF_LITE_ENSURE_EQ(context, 1, output->dims->data[0]); + TF_LITE_ENSURE_EQ(context, 1, input->dims->data[0]); + TF_LITE_ENSURE_EQ(context, 1, input->dims->data[1]); + TF_LITE_ENSURE_EQ(context, 1, output->dims->data[2]); + TF_LITE_ENSURE_EQ(context, 1, input->dims->data[2]); + TF_LITE_ENSURE_EQ(context, output->dims->data[3], input->dims->data[3]); + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + + // The circular buffer custom operator currently only supports int8_t. + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteInt8); + + // TODO(b/132070898): Use statically slotted OpData structures until a + // scratch memory API is ready. + TFLITE_DCHECK_LE(op_data_counter, kMaxOpDataSize); + OpData* op_data = &op_data_array[op_data_counter++]; + // The last circular buffer layer (length 5) simply accumulates outputs, and + // does not run periodically. + // TODO(b/150001379): Move this special case logic to the tflite flatbuffer. + if (output->dims->data[1] == 5) { + op_data->cycles_max = 1; + } else { + op_data->cycles_max = 2; + } + op_data->cycles_until_run = op_data->cycles_max; + node->user_data = op_data; + + return kTfLiteOk; +} + +// Shifts buffer over by the output depth, and write new input to end of buffer. +// num_slots is the number of samples stored in the output buffer. +// depth is the size of each sample. +void EvalInt8(const int8_t* input, int num_slots, int depth, int8_t* output) { + memmove(output, &output[depth], (num_slots - 1) * depth); + memcpy(&output[(num_slots - 1) * depth], input, depth); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + OpData* data = reinterpret_cast(node->user_data); + + int num_slots = output->dims->data[1]; + int depth = output->dims->data[3]; + + if (input->type == kTfLiteInt8) { + EvalInt8(tflite::micro::GetTensorData(input), num_slots, depth, + tflite::micro::GetTensorData(output)); + } else { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + + if (--data->cycles_until_run != 0) { + // Signal the interpreter to end current run if the delay before op invoke + // has not been reached. + // TODO(b/149795762): Add kTfLiteAbort to TfLiteStatus enum. + return static_cast(kTfLiteAbort); + } + + // If prepare is ever called more than one time (for example, when testing the + // ambient model, the interpreter is created a few times), this op data + // counter needs to be reset so that future instances do not overrun this op + // data array. + op_data_counter = 0; + + data->cycles_until_run = data->cycles_max; + + return kTfLiteOk; +} + +} // namespace circular_buffer + +TfLiteRegistration* Register_CIRCULAR_BUFFER() { + static TfLiteRegistration r = {/*init=*/nullptr, + /*free=*/circular_buffer::Free, + /*prepare=*/circular_buffer::Prepare, + /*invoke=*/circular_buffer::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; + return &r; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/add.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/add.cc new file mode 100644 index 0000000..6db8883 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/add.cc @@ -0,0 +1,246 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/add.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/add.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace add { + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + bool requires_broadcast; + + // These fields are used in both the general 8-bit -> 8bit quantized path, + // and the special 16-bit -> 16bit quantized path + int input1_shift; + int input2_shift; + int32_t output_activation_min; + int32_t output_activation_max; + + // These fields are used only in the general 8-bit -> 8bit quantized path + int32_t input1_multiplier; + int32_t input2_multiplier; + int32_t output_multiplier; + int output_shift; + int left_shift; + int32_t input1_offset; + int32_t input2_offset; + int32_t output_offset; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteAddParams* params, + const TfLiteTensor* input1, + const TfLiteTensor* input2, TfLiteTensor* output, + OpData* data) { + data->requires_broadcast = !HaveSameShapes(input1, input2); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + // 8bit -> 8bit general quantized path, with general rescalings + data->input1_offset = -input1->params.zero_point; + data->input2_offset = -input2->params.zero_point; + data->output_offset = output->params.zero_point; + data->left_shift = 20; + const double twice_max_input_scale = + 2 * static_cast( + std::max(input1->params.scale, input2->params.scale)); + const double real_input1_multiplier = + static_cast(input1->params.scale) / twice_max_input_scale; + const double real_input2_multiplier = + static_cast(input2->params.scale) / twice_max_input_scale; + const double real_output_multiplier = + twice_max_input_scale / + ((1 << data->left_shift) * static_cast(output->params.scale)); + + QuantizeMultiplierSmallerThanOneExp( + real_input1_multiplier, &data->input1_multiplier, &data->input1_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_input2_multiplier, &data->input2_multiplier, &data->input2_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_output_multiplier, &data->output_multiplier, &data->output_shift); + + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + } + + return kTfLiteOk; +} + +void EvalAdd(TfLiteContext* context, TfLiteNode* node, TfLiteAddParams* params, + const OpData* data, const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + tflite::ArithmeticParams op_params; + SetActivationParams(output_activation_min, output_activation_max, &op_params); +#define TF_LITE_ADD(opname) \ + reference_ops::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)) + if (data->requires_broadcast) { + TF_LITE_ADD(BroadcastAdd4DSlow); + } else { + TF_LITE_ADD(Add); + } +#undef TF_LITE_ADD +} + +TfLiteStatus EvalAddQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteAddParams* params, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + tflite::ArithmeticParams op_params; + op_params.left_shift = data->left_shift; + op_params.input1_offset = data->input1_offset; + op_params.input1_multiplier = data->input1_multiplier; + op_params.input1_shift = data->input1_shift; + op_params.input2_offset = data->input2_offset; + op_params.input2_multiplier = data->input2_multiplier; + op_params.input2_shift = data->input2_shift; + op_params.output_offset = data->output_offset; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + SetActivationParams(data->output_activation_min, + data->output_activation_max, &op_params); + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); +#define TF_LITE_ADD(type, opname, dtype) \ + type::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)); + if (output->type == kTfLiteInt8) { + if (need_broadcast) { + TF_LITE_ADD(reference_integer_ops, BroadcastAdd4DSlow, int8_t); + } else { + arm_elementwise_add_s8( + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorData(input2), + op_params.input1_offset, op_params.input1_multiplier, + op_params.input1_shift, op_params.input2_offset, + op_params.input2_multiplier, op_params.input2_shift, + op_params.left_shift, tflite::micro::GetTensorData(output), + op_params.output_offset, op_params.output_multiplier, + op_params.output_shift, op_params.quantized_activation_min, + op_params.quantized_activation_max, + MatchingElementsSize(tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorShape(output))); + } + } else { + if (need_broadcast) { + TF_LITE_ADD(reference_ops, BroadcastAdd4DSlow, uint8_t); + } else { + TF_LITE_ADD(reference_ops, Add, uint8_t); + } + } +#undef TF_LITE_ADD + } + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + const TfLiteTensor* input1 = GetInput(context, node, kInputTensor1); + const TfLiteTensor* input2 = GetInput(context, node, kInputTensor2); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + TF_LITE_ENSURE_STATUS( + CalculateOpData(context, params, input1, input2, output, data)); + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + if (output->type == kTfLiteFloat32) { + EvalAdd(context, node, params, data, input1, input2, output); + } else if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + TF_LITE_ENSURE_OK(context, EvalAddQuantized(context, node, params, data, + input1, input2, output)); + } else { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace add + +TfLiteRegistration Register_ADD() { + return {/*init=*/add::Init, + /*free=*/nullptr, + /*prepare=*/add::Prepare, + /*invoke=*/add::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/conv.cc new file mode 100644 index 0000000..cf1ce8c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/conv.cc @@ -0,0 +1,455 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/conv.h" + +#include "cmsis/CMSIS/NN/Include/arm_nn_types.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/conv.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace conv { + +constexpr int kInputTensor = 0; +constexpr int kFilterTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; +constexpr int kMaxChannels = 256; + +// Conv is quantized along dimension 0: +// https://www.tensorflow.org/lite/performance/quantization_spec +constexpr int kConvQuantizedDimension = 0; + +struct OpData { + TfLitePaddingValues padding; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; + + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + // Per channel output multiplier and shift. + // TODO(b/141139247): Allocate these dynamically when possible. + int32_t per_channel_output_multiplier[kMaxChannels]; + int32_t per_channel_output_shift[kMaxChannels]; + + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; + + // Index to buffer for optimizations if applicable. + int buffer_idx; +}; + +inline PaddingType RuntimePaddingType(TfLitePadding padding) { + switch (padding) { + case TfLitePadding::kTfLitePaddingSame: + return PaddingType::kSame; + case TfLitePadding::kTfLitePaddingValid: + return PaddingType::kValid; + case TfLitePadding::kTfLitePaddingUnknown: + default: + return PaddingType::kNone; + } +} + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, int width, int height, + int filter_width, int filter_height, int out_width, + int out_height, const TfLiteType data_type, + OpData* data) { + bool has_bias = node->inputs->size == 3; + // Check number of inputs/outputs + TF_LITE_ENSURE(context, has_bias || node->inputs->size == 2); + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + + // Matching GetWindowedOutputSize in TensorFlow. + auto padding = params->padding; + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, + params->dilation_height_factor, params->dilation_width_factor, height, + width, filter_height, filter_width, padding, &out_height, &out_width); + + // Note that quantized inference requires that all tensors have their + // parameters set. This is usually done during quantized training. + if (data_type != kTfLiteFloat32) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + const TfLiteTensor* bias = + GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + int num_channels = filter->dims->data[kConvQuantizedDimension]; + + TF_LITE_ENSURE_STATUS(tflite::PopulateConvolutionQuantizationParams( + context, input, filter, bias, output, params->activation, + &data->output_multiplier, &data->output_shift, + &data->output_activation_min, &data->output_activation_max, + data->per_channel_output_multiplier, + reinterpret_cast(data->per_channel_output_shift), num_channels)); + } + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { +#if defined(__ARM_FEATURE_DSP) || defined(__ARM_FEATURE_MVE) + int32_t buf_size = 0; + + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + auto* data = reinterpret_cast(node->user_data); + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + const TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + RuntimeShape input_shape = GetTensorShape(input); + RuntimeShape output_shape = GetTensorShape(output); + + // Initialize cmsis-nn input dimensions + cmsis_nn_dims input_dims; + input_dims.n = MatchingDim(input_shape, 0, output_shape, 0); + input_dims.h = input->dims->data[1]; + input_dims.w = input->dims->data[2]; + input_dims.c = input_shape.Dims(3); + + // Initialize cmsis-nn filter dimensions + cmsis_nn_dims filter_dims; + filter_dims.n = output_shape.Dims(3); + filter_dims.h = filter->dims->data[1]; + filter_dims.w = filter->dims->data[2]; + filter_dims.c = input_dims.c; + + // Initialize cmsis-nn output dimensions + cmsis_nn_dims output_dims; + output_dims.n = input_dims.n; + output_dims.h = output->dims->data[1]; + output_dims.w = output->dims->data[2]; + output_dims.c = output_shape.Dims(3); + + TF_LITE_ENSURE_STATUS(CalculateOpData( + context, node, params, input_dims.w, input_dims.h, filter_dims.w, + filter_dims.h, output_dims.w, output_dims.h, input->type, data)); + + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + + if (input->type == kTfLiteInt8) { + // Initialize cmsis-nn convolution parameters + cmsis_nn_conv_params conv_params; + conv_params.input_offset = -input->params.zero_point; + conv_params.output_offset = output->params.zero_point; + conv_params.stride.h = params->stride_height; + conv_params.stride.w = params->stride_width; + conv_params.dilation.h = params->dilation_height_factor; + conv_params.dilation.w = params->dilation_width_factor; + conv_params.padding.h = data->padding.height; + conv_params.padding.w = data->padding.width; + conv_params.activation.min = data->output_activation_min; + conv_params.activation.max = data->output_activation_max; + + buf_size = arm_convolve_wrapper_s8_get_buffer_size( + &conv_params, &input_dims, &filter_dims, &output_dims); + } + + if (buf_size > 0) { + TF_LITE_ENSURE_STATUS(context->RequestScratchBufferInArena( + context, buf_size, &data->buffer_idx)); + } else { + data->buffer_idx = -1; + } +#endif + return kTfLiteOk; +} + +TfLiteStatus EvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* im2col, + TfLiteEvalTensor* hwcn_weights, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data.input_zero_point; + const int32_t filter_offset = -data.filter_zero_point; + const int32_t output_offset = data.output_zero_point; + + ConvParams op_params; + op_params.padding_type = RuntimePaddingType(params->padding); + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data.output_multiplier; + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + reference_ops::Conv(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + tflite::micro::GetTensorShape(im2col), + tflite::micro::GetTensorData(im2col), nullptr); + return kTfLiteOk; +} + +TfLiteStatus EvalQuantizedPerChannel( + TfLiteContext* context, TfLiteNode* node, TfLiteConvParams* params, + const OpData& data, const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output, TfLiteEvalTensor* im2col) { + // Initialize cmsis-nn convolution parameters + cmsis_nn_conv_params conv_params; + conv_params.input_offset = -data.input_zero_point; + conv_params.output_offset = data.output_zero_point; + conv_params.stride.h = params->stride_height; + conv_params.stride.w = params->stride_width; + conv_params.dilation.h = params->dilation_height_factor; + conv_params.dilation.w = params->dilation_width_factor; + conv_params.padding.h = data.padding.height; + conv_params.padding.w = data.padding.width; + conv_params.activation.min = data.output_activation_min; + conv_params.activation.max = data.output_activation_max; + + // Initialize cmsis-nn per channel quantization parameters + cmsis_nn_per_channel_quant_params quant_params; + quant_params.multiplier = + const_cast(data.per_channel_output_multiplier); + quant_params.shift = const_cast(data.per_channel_output_shift); + +#if defined(__ARM_FEATURE_DSP) || defined(__ARM_FEATURE_MVE) + RuntimeShape filter_shape = tflite::micro::GetTensorShape(filter); + RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + RuntimeShape bias_shape = tflite::micro::GetTensorShape(bias); + + // Consistency check. + TFLITE_DCHECK_LE(conv_params.activation.min, conv_params.activation.max); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + const int batch_size = MatchingDim(input_shape, 0, output_shape, 0); + const int input_depth = MatchingDim(input_shape, 3, filter_shape, 3); + const int output_depth = MatchingDim(filter_shape, 0, output_shape, 3); + if (tflite::micro::GetTensorData(bias)) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + + // Initialize cmsis-nn dimensions + // Input + cmsis_nn_dims input_dims; + input_dims.n = batch_size; + input_dims.h = input_shape.Dims(1); + input_dims.w = input_shape.Dims(2); + input_dims.c = input_depth; + + // Filter + cmsis_nn_dims filter_dims; + filter_dims.n = output_depth; + filter_dims.h = filter_shape.Dims(1); + filter_dims.w = filter_shape.Dims(2); + filter_dims.c = input_depth; + + // Bias + cmsis_nn_dims bias_dims; + bias_dims.n = 1; + bias_dims.h = 1; + bias_dims.w = 1; + bias_dims.c = output_depth; + + // Output + cmsis_nn_dims output_dims; + output_dims.n = batch_size; + output_dims.h = output_shape.Dims(1); + output_dims.w = output_shape.Dims(2); + output_dims.c = output_depth; + + // Initialize cmsis-nn context + cmsis_nn_context ctx; + ctx.buf = nullptr; + ctx.size = 0; + + if (data.buffer_idx > -1) { + ctx.buf = context->GetScratchBuffer(context, data.buffer_idx); + // Note: ctx.size is currently not used in cmsis-nn. + // The buffer should be allocated in the Prepare function through + // arm_convolve_wrapper_s8_get_buffer_size + } + + // arm_convolve_wrapper_s8 dispatches the optimized kernel accordingly with + // the parameters passed + arm_status status = arm_convolve_wrapper_s8( + &ctx, &conv_params, &quant_params, &input_dims, + tflite::micro::GetTensorData(input), &filter_dims, + tflite::micro::GetTensorData(filter), &bias_dims, + tflite::micro::GetTensorData(bias), &output_dims, + tflite::micro::GetTensorData(output)); + + if (status == ARM_MATH_SUCCESS) { + return kTfLiteOk; + } else { + return kTfLiteError; + } + +#else +#pragma message( \ + "CMSIS-NN optimization for conv not available for this target. Using reference kernel.") + + ConvParams op_params; + conv_params.input_offset = -data.input_zero_point; + conv_params.output_offset = data.output_zero_point; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.quantized_activation_min = data->output_activation_min; + op_params.quantized_activation_max = data->output_activation_max; + + reference_integer_ops::ConvPerChannel( + op_params, data->per_channel_output_multiplier, + data->per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + +#endif + return kTfLiteOk; +} + +TfLiteStatus EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* im2col, + TfLiteEvalTensor* hwcn_weights, + TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + // TODO(b/154032858): Investigate removing extra copies. + ConvParams op_params; + op_params.padding_type = RuntimePaddingType(params->padding); + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + + reference_ops::Conv(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + tflite::micro::GetTensorShape(im2col), + tflite::micro::GetTensorData(im2col)); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kFilterTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kBiasTensor) + : nullptr; + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: + EvalFloat(context, node, params, data, input, filter, bias, nullptr, + nullptr, output); + break; + case kTfLiteInt8: + return EvalQuantizedPerChannel(context, node, params, data, input, filter, + bias, output, nullptr); + break; + case kTfLiteUInt8: + return EvalQuantized(context, node, params, data, input, filter, bias, + nullptr, nullptr, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace conv + +TfLiteRegistration Register_CONV_2D() { + return {/*init=*/conv::Init, + /*free=*/nullptr, + /*prepare=*/conv::Prepare, + /*invoke=*/conv::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/depthwise_conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/depthwise_conv.cc new file mode 100644 index 0000000..42ac15a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/depthwise_conv.cc @@ -0,0 +1,478 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h" +#include "tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace depthwise_conv { +namespace { + +constexpr int kInputTensor = 0; +constexpr int kFilterTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; +constexpr int kMaxChannels = 256; + +// Depthwise conv is quantized along dimension 3: +// https://www.tensorflow.org/lite/performance/quantization_spec +constexpr int kDepthwiseConvQuantizedDimension = 3; + +struct OpData { + TfLitePaddingValues padding; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; + + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + // Per channel output multiplier and shift. + // TODO: Allocate dynamic buffers when b/158779832 is resolved + int32_t per_channel_output_multiplier[kMaxChannels]; + int32_t per_channel_output_shift[kMaxChannels]; + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; + // Index to buffer for optimizations if applicable. + int buffer_idx; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, int width, + int height, int filter_width, int filter_height, + const TfLiteType data_type, OpData* data) { + bool has_bias = node->inputs->size == 3; + // Check number of inputs/outputs + TF_LITE_ENSURE(context, has_bias || node->inputs->size == 2); + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + + int unused_output_height, unused_output_width; + // Set buffer index to a reset value + data->buffer_idx = -1; + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, 1, 1, height, width, + filter_height, filter_width, params->padding, &unused_output_height, + &unused_output_width); + + // Note that quantized inference requires that all tensors have their + // parameters set. This is usually done during quantized training. + if (data_type != kTfLiteFloat32) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + const TfLiteTensor* bias = + GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + int num_channels = filter->dims->data[kDepthwiseConvQuantizedDimension]; + + return tflite::PopulateConvolutionQuantizationParams( + context, input, filter, bias, output, params->activation, + &data->output_multiplier, &data->output_shift, + &data->output_activation_min, &data->output_activation_max, + data->per_channel_output_multiplier, + reinterpret_cast(data->per_channel_output_shift), num_channels); + } + return kTfLiteOk; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + auto* params = + reinterpret_cast(node->builtin_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + const TfLiteType data_type = input->type; + int width = SizeOfDimension(input, 2); + int height = SizeOfDimension(input, 1); + int filter_width = SizeOfDimension(filter, 2); + int filter_height = SizeOfDimension(filter, 1); + + if (input->type == kTfLiteInt8) { + // Allocate memory for per-channel quantization parameters + const int num_channels = + filter->dims->data[kDepthwiseConvQuantizedDimension]; + TFLITE_DCHECK_LE(num_channels, kMaxChannels); + + TF_LITE_ENSURE_EQ(context, filter->quantization.type, + kTfLiteAffineQuantization); + + // All per-channel quantized tensors need valid zero point and scale arrays. + const auto* affine_quantization = + reinterpret_cast( + filter->quantization.params); + TF_LITE_ENSURE(context, affine_quantization); + TF_LITE_ENSURE(context, affine_quantization->scale); + TF_LITE_ENSURE(context, affine_quantization->zero_point); + TF_LITE_ENSURE( + context, affine_quantization->scale->size == 1 || + affine_quantization->scale->size == + filter->dims->data[kDepthwiseConvQuantizedDimension]); + TF_LITE_ENSURE_EQ(context, affine_quantization->scale->size, + affine_quantization->zero_point->size); + } + + TF_LITE_ENSURE_STATUS(CalculateOpData(context, node, params, width, height, + filter_width, filter_height, data_type, + data)); + + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + + if (input->type == kTfLiteInt8) { + RuntimeShape input_shape = GetTensorShape(input); + RuntimeShape output_shape = GetTensorShape(output); + RuntimeShape filter_shape = GetTensorShape(filter); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(filter_shape.DimensionsCount(), 4); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + const int batch_size = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(output_shape, 3, filter_shape, 3); + TFLITE_DCHECK_EQ(batch_size, 1); /* Only batch = 1 is supported */ + + cmsis_nn_dims input_dims; + input_dims.n = batch_size; + input_dims.h = height; + input_dims.w = width; + input_dims.c = input_shape.Dims(3); + + cmsis_nn_dims filter_dims; + filter_dims.n = 1; + filter_dims.h = filter_height; + filter_dims.w = filter_width; + filter_dims.c = output_depth; + + cmsis_nn_dims output_dims; + output_dims.n = batch_size; + output_dims.h = output_shape.Dims(1); + output_dims.w = output_shape.Dims(2); + output_dims.c = output_depth; + + cmsis_nn_dw_conv_params dw_conv_params; + dw_conv_params.padding.h = data->padding.height; + dw_conv_params.padding.w = data->padding.width; + + const int32_t buf_size = arm_depthwise_conv_wrapper_s8_get_buffer_size( + &dw_conv_params, &input_dims, &filter_dims, &output_dims); + + if (buf_size > 0) { + TF_LITE_ENSURE_STATUS(context->RequestScratchBufferInArena( + context, buf_size, &data->buffer_idx)); + } else { + data->buffer_idx = -1; + } + } + return kTfLiteOk; +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, const OpData* data, + const TfLiteEvalTensor* input, const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + + tflite::DepthwiseParams op_params; + // Padding type is ignored, but still set. + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data->padding.width; + op_params.padding_values.height = data->padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + + tflite::reference_ops::DepthwiseConv( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void EvalQuantizedPerChannel(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, OpData* data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + cmsis_nn_dw_conv_params dw_conv_params; + dw_conv_params.dilation.h = params->dilation_height_factor; + dw_conv_params.dilation.w = params->dilation_width_factor; + // Call to reference implementation can be removed when dilation is supported + // in the optimized implementations. + if (1 == dw_conv_params.dilation.h && 1 == dw_conv_params.dilation.w) { + dw_conv_params.input_offset = -data->input_zero_point; + dw_conv_params.output_offset = data->output_zero_point; + dw_conv_params.stride.h = params->stride_height; + dw_conv_params.stride.w = params->stride_width; + dw_conv_params.padding.h = data->padding.height; + dw_conv_params.padding.w = data->padding.width; + // TODO(b/130439627): Use calculated value for clamping. + dw_conv_params.activation.min = std::numeric_limits::min(); + dw_conv_params.activation.max = std::numeric_limits::max(); + dw_conv_params.ch_mult = params->depth_multiplier; + + cmsis_nn_per_channel_quant_params quant_params; + quant_params.multiplier = data->per_channel_output_multiplier; + quant_params.shift = data->per_channel_output_shift; + + RuntimeShape filter_shape = tflite::micro::GetTensorShape(filter); + RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + RuntimeShape bias_shape = tflite::micro::GetTensorShape(bias); + + TFLITE_DCHECK_LE(dw_conv_params.activation.min, + dw_conv_params.activation.max); + + const int batch_size = MatchingDim(input_shape, 0, output_shape, 0); + const int output_depth = MatchingDim(filter_shape, 3, output_shape, 3); + + if (tflite::micro::GetTensorData(bias)) { + TFLITE_DCHECK_EQ(bias_shape.FlatSize(), output_depth); + } + + cmsis_nn_dims input_dims; + input_dims.n = batch_size; + input_dims.h = input_shape.Dims(1); + input_dims.w = input_shape.Dims(2); + input_dims.c = input_shape.Dims(3); + + cmsis_nn_dims filter_dims; + filter_dims.n = filter_shape.Dims(0); + filter_dims.h = filter_shape.Dims(1); + filter_dims.w = filter_shape.Dims(2); + filter_dims.c = output_depth; + + cmsis_nn_dims bias_dims; + bias_dims.n = 1; + bias_dims.h = 1; + bias_dims.w = 1; + bias_dims.c = output_depth; + + cmsis_nn_dims output_dims; + output_dims.n = batch_size; + output_dims.h = output_shape.Dims(1); + output_dims.w = output_shape.Dims(2); + output_dims.c = output_depth; + + cmsis_nn_context ctx; + ctx.buf = nullptr; + /* 'size' is unused */ + ctx.size = 0; + + if (data->buffer_idx > -1) { + ctx.buf = context->GetScratchBuffer(context, data->buffer_idx); + } + + TFLITE_DCHECK_EQ( + arm_depthwise_conv_wrapper_s8( + &ctx, &dw_conv_params, &quant_params, &input_dims, + tflite::micro::GetTensorData(input), &filter_dims, + tflite::micro::GetTensorData(filter), &bias_dims, + tflite::micro::GetTensorData(bias), &output_dims, + tflite::micro::GetTensorData(output)), + ARM_MATH_SUCCESS); + } else { + DepthwiseParams op_params; + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data->padding.width; + op_params.padding_values.height = data->padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.input_offset = -data->input_zero_point; + op_params.weights_offset = 0; + op_params.output_offset = data->output_zero_point; + // TODO(b/130439627): Use calculated value for clamping. + op_params.quantized_activation_min = std::numeric_limits::min(); + op_params.quantized_activation_max = std::numeric_limits::max(); + + reference_integer_ops::DepthwiseConvPerChannel( + op_params, data->per_channel_output_multiplier, + data->per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, const OpData* data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data->input_zero_point; + const int32_t filter_offset = -data->filter_zero_point; + const int32_t output_offset = data->output_zero_point; + + tflite::DepthwiseParams op_params; + // Padding type is ignored, but still set. + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data->padding.width; + op_params.padding_values.height = data->padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.quantized_activation_min = data->output_activation_min; + op_params.quantized_activation_max = data->output_activation_max; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data->output_multiplier; + // Legacy ops used mixed left and right shifts. Now all are +ve-means-left. + op_params.output_shift = -data->output_shift; + + if (1 == op_params.dilation_width_factor && + 1 == op_params.dilation_height_factor) { + RuntimeShape filter_shape = tflite::micro::GetTensorShape(filter); + const int filter_height = filter_shape.Dims(1); + const int filter_width = filter_shape.Dims(2); + RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + const int input_height = input_shape.Dims(1); + const int input_width = input_shape.Dims(2); + const int input_depth = input_shape.Dims(3); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + const int output_height = output_shape.Dims(1); + const int output_width = output_shape.Dims(2); + arm_depthwise_conv_u8_basic_ver1( + tflite::micro::GetTensorData(input), input_width, input_height, + input_depth, tflite::micro::GetTensorData(filter), + filter_width, filter_height, op_params.depth_multiplier, + op_params.padding_values.width, op_params.padding_values.height, + op_params.stride_width, op_params.stride_height, + op_params.dilation_width_factor, op_params.dilation_height_factor, + tflite::micro::GetTensorData(bias), op_params.input_offset, + op_params.weights_offset, op_params.output_offset, + tflite::micro::GetTensorData(output), output_width, + output_height, op_params.quantized_activation_min, + op_params.quantized_activation_max, op_params.output_shift, + op_params.output_multiplier); + } else { + tflite::reference_ops::DepthwiseConv( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto* params = + reinterpret_cast(node->builtin_data); + OpData& data = *(static_cast(node->user_data)); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kFilterTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kBiasTensor) + : nullptr; + + // TODO(aselle): Consider whether float conv and quantized conv should be + // separate ops to avoid dispatch overhead here. + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: + EvalFloat(context, node, params, &data, input, filter, bias, output); + break; + case kTfLiteInt8: + EvalQuantizedPerChannel(context, node, params, &data, input, filter, bias, + output); + break; + case kTfLiteUInt8: + EvalQuantized(context, node, params, &data, input, filter, bias, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace depthwise_conv + +TfLiteRegistration Register_DEPTHWISE_CONV_2D() { + return {/*init=*/depthwise_conv::Init, + /*free=*/nullptr, + /*prepare=*/depthwise_conv::Prepare, + /*invoke=*/depthwise_conv::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/fully_connected.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/fully_connected.cc new file mode 100644 index 0000000..8af92e6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/fully_connected.cc @@ -0,0 +1,350 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/fully_connected.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace fully_connected { +namespace { + +struct OpData { + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; + // The index of the temporary tensor where the quantized inputs are cached. + int input_quantized_index; + // Index to buffer for optimizations if applicable. + int buffer_idx; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; +}; + +constexpr int kInputTensor = 0; +constexpr int kWeightsTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; + +TfLiteStatus CalculateOpData(TfLiteContext* context, + TfLiteFusedActivation activation, + TfLiteType data_type, const TfLiteTensor* input, + const TfLiteTensor* filter, + const TfLiteTensor* bias, TfLiteTensor* output, + OpData* data) { + TfLiteStatus status = kTfLiteOk; + // Set buffer index to a reset value + data->buffer_idx = -1; + if (data_type != kTfLiteFloat32) { + double real_multiplier = 0.0; + TF_LITE_ENSURE_STATUS(GetQuantizedConvolutionMultipler( + context, input, filter, bias, output, &real_multiplier)); + int exponent; + QuantizeMultiplier(real_multiplier, &data->output_multiplier, &exponent); + data->output_shift = -exponent; + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, activation, output, &data->output_activation_min, + &data->output_activation_max)); + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + } + return status; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + const auto params = + static_cast(node->builtin_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kWeightsTensor); + const TfLiteTensor* bias = GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + TF_LITE_ENSURE_MSG(context, input->type == filter->type, + "Hybrid models are not supported on TFLite Micro."); + TF_LITE_ENSURE_STATUS(CalculateOpData(context, params->activation, + input->type, input, filter, bias, + output, data)); + + if (input->type == kTfLiteInt8 && nullptr != GetTensorData(bias)) { + RuntimeShape filter_shape = GetTensorShape(filter); + RuntimeShape output_shape = GetTensorShape(output); + + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 2); + const int filter_dim_count = filter_shape.DimensionsCount(); + cmsis_nn_dims filter_dims; + filter_dims.n = filter_shape.Dims(filter_dim_count - 1); + filter_dims.h = 1; + filter_dims.w = 1; + filter_dims.c = output_shape.Dims(1); + + const int32_t buf_size = + arm_fully_connected_s8_get_buffer_size(&filter_dims); + + if (buf_size > 0) { + TF_LITE_ENSURE_STATUS(context->RequestScratchBufferInArena( + context, buf_size, &data->buffer_idx)); + } else { + data->buffer_idx = -1; + } + } + return kTfLiteOk; +} + +TfLiteStatus EvalQuantizedInt8(TfLiteContext* context, TfLiteNode* node, + const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + // The 'if' condition can be removed when null handling of bias is added to + // arm_fully_connected_s8 + if (nullptr != tflite::micro::GetTensorData(bias)) { + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 2); + const int batches = output_shape.Dims(0); + const int output_depth = output_shape.Dims(1); + const RuntimeShape filter_shape = tflite::micro::GetTensorShape(filter); + const int filter_dim_count = filter_shape.DimensionsCount(); + const int accum_depth = filter_shape.Dims(filter_dim_count - 1); + const RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + + cmsis_nn_fc_params fc_params; + fc_params.input_offset = -data.input_zero_point; + fc_params.output_offset = data.output_zero_point; + fc_params.activation.min = data.output_activation_min; + fc_params.activation.max = data.output_activation_max; + + cmsis_nn_per_tensor_quant_params quant_params; + quant_params.multiplier = data.output_multiplier; + // TODO(b/138810107): Figure out whether output shift should be inverted + quant_params.shift = -data.output_shift; + + cmsis_nn_dims input_dims; + input_dims.n = batches; + input_dims.h = input_shape.Dims(1); + input_dims.w = input_shape.Dims(2); + input_dims.c = input_shape.Dims(3); + + cmsis_nn_dims filter_dims; + filter_dims.n = accum_depth; + filter_dims.h = 1; + filter_dims.w = 1; + filter_dims.c = output_depth; + + cmsis_nn_dims bias_dims; + bias_dims.n = 1; + bias_dims.h = 1; + bias_dims.w = 1; + bias_dims.c = output_depth; + + cmsis_nn_dims output_dims; + output_dims.n = batches; + output_dims.h = 1; + output_dims.w = 1; + output_dims.c = output_depth; + + cmsis_nn_context ctx; + ctx.buf = nullptr; + ctx.size = 0; + + if (data.buffer_idx > -1) { + ctx.buf = context->GetScratchBuffer(context, data.buffer_idx); + } + + TF_LITE_ENSURE_EQ( + context, + arm_fully_connected_s8( + &ctx, &fc_params, &quant_params, &input_dims, + tflite::micro::GetTensorData(input), &filter_dims, + tflite::micro::GetTensorData(filter), &bias_dims, + tflite::micro::GetTensorData(bias), &output_dims, + tflite::micro::GetTensorData(output)), + ARM_MATH_SUCCESS); + } else { + tflite::FullyConnectedParams op_params; + op_params.input_offset = -data.input_zero_point; + op_params.weights_offset = -data.filter_zero_point; + op_params.output_offset = data.output_zero_point; + op_params.output_multiplier = data.output_multiplier; + // TODO(b/138810107): Figure out whether output shift should be inverted + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + + reference_integer_ops::FullyConnected( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + return kTfLiteOk; +} + +TfLiteStatus EvalQuantized(TfLiteContext* context, TfLiteNode* node, + const OpData& data, const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data.input_zero_point; + const int32_t filter_offset = -data.filter_zero_point; + const int32_t output_offset = data.output_zero_point; + + tflite::FullyConnectedParams op_params; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data.output_multiplier; + // Legacy ops used mixed left and right shifts. Now all are +ve-means-left. + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + +#define TF_LITE_FULLY_CONNECTED(output_data_type) \ + reference_ops::FullyConnected( \ + op_params, tflite::micro::GetTensorShape(input), \ + tflite::micro::GetTensorData(input), \ + tflite::micro::GetTensorShape(filter), \ + tflite::micro::GetTensorData(filter), \ + tflite::micro::GetTensorShape(bias), \ + tflite::micro::GetTensorData(bias), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)) + switch (output->type) { + case kTfLiteUInt8: + TF_LITE_FULLY_CONNECTED(uint8_t); + break; + case kTfLiteInt16: + TF_LITE_FULLY_CONNECTED(int16_t); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +TfLiteStatus EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteFusedActivation activation, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(activation, &output_activation_min, + &output_activation_max); + tflite::FullyConnectedParams op_params; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + tflite::reference_ops::FullyConnected( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + const auto* params = + static_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kWeightsTensor); + const TfLiteEvalTensor* bias = + tflite::micro::GetEvalInput(context, node, kBiasTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + // Checks in Prepare ensure input, output and filter types are all the same. + switch (input->type) { + case kTfLiteFloat32: + return EvalFloat(context, node, params->activation, input, filter, bias, + output); + case kTfLiteInt8: + return EvalQuantizedInt8(context, node, data, input, filter, bias, + output); + + case kTfLiteUInt8: + return EvalQuantized(context, node, data, input, filter, bias, output); + + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace fully_connected + +TfLiteRegistration Register_FULLY_CONNECTED() { + return {/*init=*/fully_connected::Init, + /*free=*/nullptr, + /*prepare=*/fully_connected::Prepare, + /*invoke=*/fully_connected::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/mul.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/mul.cc new file mode 100644 index 0000000..00d884e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/mul.cc @@ -0,0 +1,218 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/mul.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/mul.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace mul { + +constexpr int kInput1Tensor = 0; +constexpr int kInput2Tensor = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + int32_t output_activation_min; + int32_t output_activation_max; + + int32_t output_multiplier; + int output_shift; + + // Cached tensor zero point values for quantized operations. + int32_t input1_zero_point; + int32_t input2_zero_point; + int32_t output_zero_point; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, OpData* data) { + const TfLiteTensor* input1 = GetInput(context, node, kInput1Tensor); + const TfLiteTensor* input2 = GetInput(context, node, kInput2Tensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 2); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + TF_LITE_ENSURE_TYPES_EQ(context, input1->type, input2->type); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + + double real_multiplier = + input1->params.scale * input2->params.scale / output->params.scale; + QuantizeMultiplier(real_multiplier, &data->output_multiplier, + &data->output_shift); + } + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input1 = GetInput(context, node, kInput1Tensor); + const TfLiteTensor* input2 = GetInput(context, node, kInput2Tensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + if (output->dims->size == 0) { + return AllocateOutputDimensionsFromInput(context, input1, input2, output); + } + + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + data->input1_zero_point = input1->params.zero_point; + data->input2_zero_point = input2->params.zero_point; + data->output_zero_point = output->params.zero_point; + CalculateOpData(context, node, params, data); + + return kTfLiteOk; +} + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, const OpData& data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + if (output->type == kTfLiteInt8 || output->type == kTfLiteUInt8) { + tflite::ArithmeticParams op_params; + SetActivationParams(data.output_activation_min, data.output_activation_max, + &op_params); + op_params.input1_offset = -data.input1_zero_point; + op_params.input2_offset = -data.input2_zero_point; + op_params.output_offset = data.output_zero_point; + op_params.output_multiplier = data.output_multiplier; + op_params.output_shift = data.output_shift; + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + +#define TF_LITE_MUL(type, opname, dtype) \ + type::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)); + + if (output->type == kTfLiteInt8) { + if (need_broadcast) { + TF_LITE_MUL(reference_integer_ops, BroadcastMul4DSlow, int8_t); + } else { + arm_elementwise_mul_s8( + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorData(input2), + op_params.input1_offset, op_params.input2_offset, + tflite::micro::GetTensorData(output), + op_params.output_offset, op_params.output_multiplier, + op_params.output_shift, op_params.quantized_activation_min, + op_params.quantized_activation_max, + MatchingElementsSize(tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorShape(output))); + } + } else if (output->type == kTfLiteUInt8) { + if (need_broadcast) { + TF_LITE_MUL(reference_ops, BroadcastMul4DSlow, uint8_t); + } else { + TF_LITE_MUL(reference_ops, Mul, uint8_t); + } + } +#undef TF_LITE_MUL + } +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + tflite::ArithmeticParams op_params; + SetActivationParams(output_activation_min, output_activation_max, &op_params); + + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); +#define TF_LITE_MUL(opname) \ + reference_ops::opname(op_params, tflite::micro::GetTensorShape(input1), \ + tflite::micro::GetTensorData(input1), \ + tflite::micro::GetTensorShape(input2), \ + tflite::micro::GetTensorData(input2), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)); + + if (need_broadcast) { + TF_LITE_MUL(BroadcastMul4DSlow); + } else { + TF_LITE_MUL(Mul); + } +#undef TF_LITE_MUL +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInput1Tensor); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInput2Tensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + switch (input1->type) { + case kTfLiteUInt8: + case kTfLiteInt8: + EvalQuantized(context, node, params, data, input1, input2, output); + break; + case kTfLiteFloat32: + EvalFloat(context, node, params, input1, input2, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + + return kTfLiteOk; +} +} // namespace mul + +TfLiteRegistration Register_MUL() { + return {mul::Init, nullptr /* Free */, mul::Prepare, mul::Eval}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/pooling.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/pooling.cc new file mode 100644 index 0000000..4229b2c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/pooling.cc @@ -0,0 +1,397 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/pooling.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "flatbuffers/base.h" // from @flatbuffers +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace pooling { + +namespace { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +struct OpData { + TfLitePaddingValues padding; + // Index to buffer for optimizations if applicable. + int buffer_idx; + + int32_t activation_min; + int32_t activation_max; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, + const TfLitePoolParams* params, + const TfLiteTensor* input, TfLiteTensor* output, + OpData* data) { + // input: batch, height, width, channel + int height = SizeOfDimension(input, 1); + int width = SizeOfDimension(input, 2); + + int out_height, out_width; + + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, + /*dilation_rate_height=*/1, + /*dilation_rate_width=*/1, height, width, params->filter_height, + params->filter_width, params->padding, &out_height, &out_width); + + if (input->type != kTfLiteFloat32) { + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->activation_min, + &data->activation_max)); + TFLITE_DCHECK_LE(data->activation_min, data->activation_max); + } + + // Set buffer index to a reset value + data->buffer_idx = -1; + + return kTfLiteOk; +} + +void AverageEvalFloat(const TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, const OpData& data, + const TfLiteEvalTensor* input, TfLiteEvalTensor* output) { + float activation_min, activation_max; + CalculateActivationRange(params->activation, &activation_min, + &activation_max); + + PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.float_activation_min = activation_min; + op_params.float_activation_max = activation_max; + reference_ops::AveragePool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void AverageEvalQuantized(TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, const OpData& data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output) { + TFLITE_DCHECK(input->type == kTfLiteUInt8 || input->type == kTfLiteInt8); + + PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.quantized_activation_min = data.activation_min; + op_params.quantized_activation_max = data.activation_max; + + if (input->type == kTfLiteUInt8) { + reference_ops::AveragePool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + + cmsis_nn_dims input_dims; + input_dims.n = 1; + input_dims.h = input_shape.Dims(1); + input_dims.w = input_shape.Dims(2); + input_dims.c = depth; + + cmsis_nn_dims output_dims; + output_dims.n = 1; + output_dims.h = output_shape.Dims(1); + output_dims.w = output_shape.Dims(2); + output_dims.c = depth; + + cmsis_nn_pool_params pool_params; + pool_params.stride.h = params->stride_height; + pool_params.stride.w = params->stride_width; + pool_params.padding.h = data.padding.height; + pool_params.padding.w = data.padding.width; + pool_params.activation.min = data.activation_min; + pool_params.activation.max = data.activation_max; + + cmsis_nn_dims filter_dims; + filter_dims.n = 1; + filter_dims.h = params->filter_height; + filter_dims.w = params->filter_width; + filter_dims.c = 1; + + cmsis_nn_context ctx; + ctx.buf = nullptr; + ctx.size = 0; + if (data.buffer_idx > -1) { + ctx.buf = context->GetScratchBuffer(context, data.buffer_idx); + } + + TFLITE_DCHECK_EQ( + arm_avgpool_s8(&ctx, &pool_params, &input_dims, + tflite::micro::GetTensorData(input), + &filter_dims, &output_dims, + tflite::micro::GetTensorData(output)), + ARM_MATH_SUCCESS); + } +} + +void MaxEvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, const OpData& data, + const TfLiteEvalTensor* input, TfLiteEvalTensor* output) { + float activation_min, activation_max; + CalculateActivationRange(params->activation, &activation_min, + &activation_max); + tflite::PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.float_activation_min = activation_min; + op_params.float_activation_max = activation_max; + reference_ops::MaxPool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void MaxEvalQuantizedUInt8(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, const OpData& data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output) { + tflite::PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.quantized_activation_min = data.activation_min; + op_params.quantized_activation_max = data.activation_max; + reference_ops::MaxPool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +TfLiteStatus MaxEvalInt8(TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, const OpData& data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output) { + RuntimeShape input_shape = tflite::micro::GetTensorShape(input); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + + cmsis_nn_dims input_dims; + input_dims.n = 1; + input_dims.h = input_shape.Dims(1); + input_dims.w = input_shape.Dims(2); + input_dims.c = depth; + + cmsis_nn_dims output_dims; + output_dims.n = 1; + output_dims.h = output_shape.Dims(1); + output_dims.w = output_shape.Dims(2); + output_dims.c = depth; + + cmsis_nn_pool_params pool_params; + pool_params.stride.h = params->stride_height; + pool_params.stride.w = params->stride_width; + pool_params.padding.h = data.padding.height; + pool_params.padding.w = data.padding.width; + pool_params.activation.min = data.activation_min; + pool_params.activation.max = data.activation_max; + + cmsis_nn_dims filter_dims; + filter_dims.n = 1; + filter_dims.h = params->filter_height; + filter_dims.w = params->filter_width; + filter_dims.c = 1; + + cmsis_nn_context ctx; + ctx.buf = nullptr; + ctx.size = 0; + if (data.buffer_idx > -1) { + ctx.buf = context->GetScratchBuffer(context, data.buffer_idx); + } + + TFLITE_DCHECK_EQ( + arm_max_pool_s8(&ctx, &pool_params, &input_dims, + tflite::micro::GetTensorData(input), &filter_dims, + &output_dims, + tflite::micro::GetTensorData(output)), + ARM_MATH_SUCCESS); + + return kTfLiteOk; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus MaxPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_STATUS(CalculateOpData(context, params, input, output, data)); + + return kTfLiteOk; +} + +TfLiteStatus AveragePrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_STATUS(CalculateOpData(context, params, input, output, data)); + + if (input->type == kTfLiteInt8) { + RuntimeShape input_shape = GetTensorShape(input); + TFLITE_DCHECK_EQ(input_shape.DimensionsCount(), 4); + + RuntimeShape output_shape = GetTensorShape(output); + TFLITE_DCHECK_EQ(output_shape.DimensionsCount(), 4); + + const int depth = MatchingDim(input_shape, 3, output_shape, 3); + const int output_width = output_shape.Dims(2); + + const int32_t buffer_size = + arm_avgpool_s8_get_buffer_size(output_width, depth); + + if (buffer_size > 0) { + TF_LITE_ENSURE_STATUS(context->RequestScratchBufferInArena( + context, buffer_size, &data->buffer_idx)); + } else { + data->buffer_idx = -1; + } + } + return kTfLiteOk; +} + +TfLiteStatus AverageEval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const OpData& data = *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + // Inputs and outputs share the same type, guaranteed by the converter. + switch (input->type) { + case kTfLiteFloat32: + AverageEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteUInt8: + case kTfLiteInt8: + AverageEvalQuantized(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input type %s is not currently supported", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus MaxEval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const OpData& data = *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input->type) { + case kTfLiteFloat32: + MaxEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteUInt8: + MaxEvalQuantizedUInt8(context, node, params, data, input, output); + break; + case kTfLiteInt8: + MaxEvalInt8(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s not currently supported.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace pooling + +TfLiteRegistration Register_AVERAGE_POOL_2D() { + return {/*init=*/pooling::Init, + /*free=*/nullptr, + /*prepare=*/pooling::AveragePrepare, + /*invoke=*/pooling::AverageEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_MAX_POOL_2D() { + return {/*init=*/pooling::Init, + /*free=*/nullptr, + /*prepare=*/pooling::MaxPrepare, + /*invoke=*/pooling::MaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/softmax.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/softmax.cc new file mode 100644 index 0000000..194bba4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/cmsis-nn/softmax.cc @@ -0,0 +1,175 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/softmax.h" + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { + +TfLiteStatus CalculateSoftmaxParams(TfLiteContext* context, + const TfLiteTensor* input, + TfLiteTensor* output, + const TfLiteSoftmaxParams* params, + SoftmaxParams* op_data) { + if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) { + if (input->type == kTfLiteUInt8) { + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteUInt8); + TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0); + } else { + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteInt8); + if (output->type == kTfLiteInt16) { + TF_LITE_ENSURE_EQ(context, output->params.zero_point, -32768); + // NOTE: Current int16_t softmax output does not require symmetric + // scaling + // - so no need to verify scale here. + } else { + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteInt8); + TF_LITE_ENSURE_EQ(context, output->params.zero_point, -128); + TF_LITE_ENSURE(context, output->params.scale == 1.f / 256); + } + } + + static const int kScaledDiffIntegerBits = 5; + + int input_left_shift; + tflite::PreprocessSoftmaxScaling( + static_cast(params->beta), + static_cast(input->params.scale), kScaledDiffIntegerBits, + &op_data->input_multiplier, &input_left_shift); + op_data->input_left_shift = input_left_shift; + op_data->diff_min = + -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits, + op_data->input_left_shift); + } else { + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32); + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32); + op_data->beta = static_cast(params->beta); + } + return kTfLiteOk; +} + +} // namespace + +void* SoftmaxInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(SoftmaxParams)); +} + +TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) { + auto* params = static_cast(node->builtin_data); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + const TfLiteTensor* input = GetInput(context, node, 0); + TF_LITE_ENSURE(context, NumDimensions(input) >= 1); + + TfLiteTensor* output = GetOutput(context, node, 0); + + TFLITE_DCHECK(node->user_data != nullptr); + SoftmaxParams* data = static_cast(node->user_data); + return CalculateSoftmaxParams(context, input, output, params, data); +} + +// Takes a tensor and performs softmax along the last dimension. +void SoftmaxFloat(const TfLiteEvalTensor* input, TfLiteEvalTensor* output, + const SoftmaxParams& op_data) { + tflite::reference_ops::Softmax(op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void SoftmaxQuantized(const TfLiteEvalTensor* input, TfLiteEvalTensor* output, + const SoftmaxParams& op_data) { + const auto input_shape = tflite::micro::GetTensorShape(input); + const auto output_shape = tflite::micro::GetTensorShape(output); + + if (input->type == kTfLiteUInt8) { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + if (output->type == kTfLiteInt16) { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + + arm_softmax_s8(tflite::micro::GetTensorData(input), outer_size, + depth, op_data.input_multiplier, op_data.input_left_shift, + op_data.diff_min, + tflite::micro::GetTensorData(output)); + } + } +} + +TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + TFLITE_DCHECK(node->user_data != nullptr); + const SoftmaxParams& data = + *(static_cast(node->user_data)); + + switch (input->type) { + case kTfLiteFloat32: { + SoftmaxFloat(input, output, data); + return kTfLiteOk; + } + case kTfLiteInt8: + case kTfLiteUInt8: { + SoftmaxQuantized(input, output, data); + return kTfLiteOk; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } +} + +} // namespace activations + +TfLiteRegistration Register_SOFTMAX() { + return {/*init=*/activations::SoftmaxInit, + /*free=*/nullptr, + /*prepare=*/activations::SoftmaxPrepare, + /*invoke=*/activations::SoftmaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/comparisons.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/comparisons.cc new file mode 100644 index 0000000..ed7a200 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/comparisons.cc @@ -0,0 +1,722 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/comparisons.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace comparisons { +namespace { + +struct OpData { + ComparisonParams params; +}; + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +TfLiteStatus EqualEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteBool: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::EqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +// TODO(renjieliu): Refactor the logic to avoid duplications. +TfLiteStatus NotEqualEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteBool: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowNotEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::NotEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus GreaterEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus GreaterEqualEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowGreaterEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::GreaterEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus LessEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus LessEqualEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + RuntimeShape input1_shape = tflite::micro::GetTensorShape(input1); + RuntimeShape input2_shape = tflite::micro::GetTensorShape(input2); + RuntimeShape output_shape = tflite::micro::GetTensorShape(output); + bool* output_data = tflite::micro::GetTensorData(output); + + bool requires_broadcast = !tflite::micro::HaveSameShapes(input1, input2); + switch (input1->type) { + case kTfLiteFloat32: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt32: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt64: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessEqualNoScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteUInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + case kTfLiteInt8: + requires_broadcast + ? reference_ops::Broadcast4DSlowLessEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data) + : reference_ops::LessEqualWithScaling( + data->params, input1_shape, + tflite::micro::GetTensorData(input1), input2_shape, + tflite::micro::GetTensorData(input2), output_shape, + output_data); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + const TfLiteTensor* input1 = GetInput(context, node, kInputTensor1); + const TfLiteTensor* input2 = GetInput(context, node, kInputTensor2); + + if (input1->type == kTfLiteUInt8 || input1->type == kTfLiteInt8) { + auto input1_offset = -input1->params.zero_point; + auto input2_offset = -input2->params.zero_point; + const int kLeftShift = 8; + + int32_t input1_multiplier; + int input1_shift; + QuantizeMultiplierSmallerThanOneExp( + static_cast(input1->params.scale), &input1_multiplier, + &input1_shift); + int32_t input2_multiplier; + int input2_shift; + QuantizeMultiplierSmallerThanOneExp( + static_cast(input2->params.scale), &input2_multiplier, + &input2_shift); + + data->params.left_shift = kLeftShift; + data->params.input1_offset = input1_offset; + data->params.input1_multiplier = input1_multiplier; + data->params.input1_shift = input1_shift; + data->params.input2_offset = input2_offset; + data->params.input2_multiplier = input2_multiplier; + data->params.input2_shift = input2_shift; + } + + return kTfLiteOk; +} + +} // namespace comparisons + +TfLiteRegistration Register_EQUAL() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::EqualEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_NOT_EQUAL() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::NotEqualEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_GREATER() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::GreaterEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_GREATER_EQUAL() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::GreaterEqualEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_LESS() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::LessEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_LESS_EQUAL() { + return {/*init=*/comparisons::Init, + /*free=*/nullptr, + /*prepare=*/comparisons::Prepare, + /*invoke=*/comparisons::LessEqualEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/concatenation.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/concatenation.cc new file mode 100644 index 0000000..f643627 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/concatenation.cc @@ -0,0 +1,267 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/concatenation.h" + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace concatenation { + +constexpr int kMaxInputNum = 10; // Maximum number of input tensors +constexpr int kOutputTensor = 0; + +struct OpData { + ConcatenationParams params; +}; + +// Handles negative axis index, coerces to positive index value. +inline int CalculatePositiveAxis(int axis, const TfLiteTensor* output_tensor) { + if (axis >= 0) { + return axis; + } else { + return NumDimensions(output_tensor) + axis; + } +} + +// The following functions are helpers to get tensor data in the format that the +// reference op implementation expects. They provide the same functionality as +// class VectorOfTensors and class VectorOfQuantizedTensors in TFLite. + +// Gets shapes from a list of tensors. +inline void GetAllInputTensorShapes(const TfLiteContext* context, + const TfLiteNode* node, + RuntimeShape all_shapes[kMaxInputNum]) { + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(node != nullptr); + for (int i = 0; i < node->inputs->size; ++i) { + const TfLiteEvalTensor* t = tflite::micro::GetEvalInput(context, node, i); + RuntimeShape shape = tflite::micro::GetTensorShape(t); + all_shapes[i].ReplaceWith(shape.DimensionsCount(), shape.DimsData()); + } +} + +// Get shape pointers from a list of shapes. +inline void GetShapesPointers(const RuntimeShape* shapes, size_t num, + const RuntimeShape* pointers[]) { + for (size_t i = 0; i < num; ++i) { + pointers[i] = &shapes[i]; + } +} + +// Gets data pointers from a list of tensors. +template +inline void GetAllInputTensorData(const TfLiteContext* context, + const TfLiteNode* node, + T* all_data[kMaxInputNum]) { + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(node != nullptr); + for (int i = 0; i < node->inputs->size; ++i) { + const TfLiteEvalTensor* t = tflite::micro::GetEvalInput(context, node, i); + all_data[i] = tflite::micro::GetTensorData(t); + } +} + +template +void EvalUnquantized(TfLiteContext* context, TfLiteNode* node) { + // Collect the shapes and data pointer of input tensors + RuntimeShape inputs_shape[kMaxInputNum]; + const RuntimeShape* inputs_shape_ptr[kMaxInputNum]; + const data_type* inputs_data[kMaxInputNum]; + GetAllInputTensorShapes(context, node, inputs_shape); + GetShapesPointers(inputs_shape, node->inputs->size, inputs_shape_ptr); + GetAllInputTensorData(context, node, inputs_data); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + reference_ops::Concatenation(data->params, inputs_shape_ptr, inputs_data, + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void EvalQuantizedUInt8(TfLiteContext* context, TfLiteNode* node) { + // Collect the shapes and data pointer of input tensors + RuntimeShape inputs_shape[kMaxInputNum]; + const RuntimeShape* inputs_shape_ptr[kMaxInputNum]; + const uint8_t* inputs_data[kMaxInputNum]; + GetAllInputTensorShapes(context, node, inputs_shape); + GetShapesPointers(inputs_shape, node->inputs->size, inputs_shape_ptr); + GetAllInputTensorData(context, node, inputs_data); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + reference_ops::ConcatenationWithScaling( + data->params, inputs_shape_ptr, inputs_data, + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + // This function only checks the types. Additional shape validations are + // performed in the reference implementation called during Eval(). + const TfLiteConcatenationParams* params = + reinterpret_cast(node->builtin_data); + + TfLiteType input_type = GetInput(context, node, 0)->type; + TfLiteType output_type = GetOutput(context, node, kOutputTensor)->type; + + // Check activation and input type + TF_LITE_ENSURE_EQ(context, params->activation, kTfLiteActNone); + TF_LITE_ENSURE(context, + input_type == kTfLiteFloat32 || input_type == kTfLiteUInt8 || + input_type == kTfLiteInt8 || input_type == kTfLiteInt32 || + input_type == kTfLiteInt64); + + // Output type must match input type + TF_LITE_ENSURE_EQ(context, output_type, input_type); + + // This implementation does not support large number of input tensors + const int num_inputs = NumInputs(node); + TF_LITE_ENSURE(context, num_inputs <= kMaxInputNum); + + // Shapes with dimensions >4 are not yet supported with static allocation. + for (int i = 0; i < num_inputs; ++i) { + const TfLiteTensor* input = GetInput(context, node, i); + int num_dimensions = NumDimensions(input); + + if (num_dimensions > 4) { + TF_LITE_KERNEL_LOG( + context, + "Op Concatenation does not currently support num dimensions >4 " + "Tensor has %d dimensions.", + num_dimensions); + return kTfLiteError; + } + } + + // Calculate OpData. + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + switch (output_type) { // Already know in/outtypes are same. + case kTfLiteFloat32: + case kTfLiteInt32: + case kTfLiteInt64: { + data->params.axis = CalculatePositiveAxis(params->axis, output); + data->params.inputs_count = node->inputs->size; + break; + } + case kTfLiteUInt8: + case kTfLiteInt8: { + data->params.axis = CalculatePositiveAxis(params->axis, output); + data->params.inputs_count = node->inputs->size; + + float* input_scales = + reinterpret_cast(context->AllocatePersistentBuffer( + context, node->inputs->size * sizeof(float))); + + int32_t* input_zero_points = + reinterpret_cast(context->AllocatePersistentBuffer( + context, node->inputs->size * sizeof(int32_t))); + + // Allocate persistent scale and zeropoint buffers. + // Store input scale and zero point values in OpParams: + for (int i = 0; i < node->inputs->size; ++i) { + const TfLiteTensor* t = GetInput(context, node, i); + input_scales[i] = t->params.scale; + input_zero_points[i] = t->params.zero_point; + } + + data->params.input_scale = input_scales; + data->params.input_zeropoint = input_zero_points; + data->params.output_zeropoint = output->params.zero_point; + data->params.output_scale = output->params.scale; + break; + } + default: + TF_LITE_KERNEL_LOG( + context, "Op Concatenation does not currently support Type '%s'.", + TfLiteTypeGetName(output_type)); + return kTfLiteError; + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TfLiteType output_type = GetOutput(context, node, kOutputTensor)->type; + + switch (output_type) { // Already know in/outtypes are same. + case kTfLiteFloat32: + EvalUnquantized(context, node); + break; + case kTfLiteInt32: + EvalUnquantized(context, node); + break; + case kTfLiteUInt8: + EvalQuantizedUInt8(context, node); + break; + case kTfLiteInt8: + EvalUnquantized(context, node); + break; + case kTfLiteInt64: + EvalUnquantized(context, node); + break; + + default: + TF_LITE_KERNEL_LOG( + context, "Op Concatenation does not currently support Type '%s'.", + TfLiteTypeGetName(output_type)); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace concatenation + +TfLiteRegistration Register_CONCATENATION() { + return {/*init=*/concatenation::Init, + /*free=*/nullptr, + /*prepare=*/concatenation::Prepare, + /*invoke=*/concatenation::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.cc new file mode 100644 index 0000000..6601213 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.cc @@ -0,0 +1,334 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/conv.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/conv.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace conv { + +constexpr int kInputTensor = 0; +constexpr int kFilterTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; + +// Conv is quantized along dimension 0: +// https://www.tensorflow.org/lite/performance/quantization_spec +constexpr int kConvQuantizedDimension = 0; + +// This file has 2 implementation of Conv. + +struct OpData { + TfLitePaddingValues padding; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; + + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + // Per channel output multiplier and shift. + int32_t* per_channel_output_multiplier; + int32_t* per_channel_output_shift; + + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; +}; + +inline PaddingType RuntimePaddingType(TfLitePadding padding) { + switch (padding) { + case TfLitePadding::kTfLitePaddingSame: + return PaddingType::kSame; + case TfLitePadding::kTfLitePaddingValid: + return PaddingType::kValid; + case TfLitePadding::kTfLitePaddingUnknown: + default: + return PaddingType::kNone; + } +} + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + const TfLiteConvParams* params, int width, + int height, int filter_width, int filter_height, + int out_width, int out_height, + const TfLiteType data_type, OpData* data) { + bool has_bias = node->inputs->size == 3; + // Check number of inputs/outputs + TF_LITE_ENSURE(context, has_bias || node->inputs->size == 2); + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + + // Matching GetWindowedOutputSize in TensorFlow. + auto padding = params->padding; + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, + params->dilation_height_factor, params->dilation_width_factor, height, + width, filter_height, filter_width, padding, &out_height, &out_width); + + // Note that quantized inference requires that all tensors have their + // parameters set. This is usually done during quantized training. + if (data_type != kTfLiteFloat32) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + const TfLiteTensor* bias = + GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + int output_channels = filter->dims->data[kConvQuantizedDimension]; + + TF_LITE_ENSURE_STATUS(tflite::PopulateConvolutionQuantizationParams( + context, input, filter, bias, output, params->activation, + &data->output_multiplier, &data->output_shift, + &data->output_activation_min, &data->output_activation_max, + data->per_channel_output_multiplier, + reinterpret_cast(data->per_channel_output_shift), + output_channels)); + } + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + const auto params = static_cast(node->builtin_data); + + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + + int input_width = input->dims->data[2]; + int input_height = input->dims->data[1]; + int filter_width = filter->dims->data[2]; + int filter_height = filter->dims->data[1]; + int output_width = output->dims->data[2]; + int output_height = output->dims->data[1]; + + // Dynimically allocate per-channel quantization parameters. + const int num_channels = filter->dims->data[kConvQuantizedDimension]; + data->per_channel_output_multiplier = + reinterpret_cast(context->AllocatePersistentBuffer( + context, num_channels * sizeof(int32_t))); + data->per_channel_output_shift = + reinterpret_cast(context->AllocatePersistentBuffer( + context, num_channels * sizeof(int32_t))); + + // All per-channel quantized tensors need valid zero point and scale arrays. + if (input->type == kTfLiteInt8) { + TF_LITE_ENSURE_EQ(context, filter->quantization.type, + kTfLiteAffineQuantization); + + const auto* affine_quantization = + static_cast(filter->quantization.params); + TF_LITE_ENSURE(context, affine_quantization); + TF_LITE_ENSURE(context, affine_quantization->scale); + TF_LITE_ENSURE(context, affine_quantization->zero_point); + + TF_LITE_ENSURE(context, + affine_quantization->scale->size == 1 || + affine_quantization->scale->size == + filter->dims->data[kConvQuantizedDimension]); + TF_LITE_ENSURE_EQ(context, affine_quantization->scale->size, + affine_quantization->zero_point->size); + } + + TF_LITE_ENSURE_STATUS(CalculateOpData( + context, node, params, input_width, input_height, filter_width, + filter_height, output_width, output_height, input->type, data)); + + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + + return kTfLiteOk; +} // namespace conv + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, const TfLiteEvalTensor* bias, + TfLiteEvalTensor* im2col, TfLiteEvalTensor* hwcn_weights, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data.input_zero_point; + const int32_t filter_offset = -data.filter_zero_point; + const int32_t output_offset = data.output_zero_point; + + // TODO(b/154032858): Investigate removing extra copies. + ConvParams op_params; + op_params.padding_type = RuntimePaddingType(params->padding); + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data.output_multiplier; + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + reference_ops::Conv(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + tflite::micro::GetTensorShape(im2col), + tflite::micro::GetTensorData(im2col), nullptr); +} + +void EvalQuantizedPerChannel(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output, + TfLiteEvalTensor* im2col) { + // TODO(b/154032858): Investigate removing extra copies. + ConvParams op_params; + op_params.input_offset = -data.input_zero_point; + op_params.output_offset = data.output_zero_point; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.padding_values.height = data.padding.height; + op_params.padding_values.width = data.padding.width; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + + reference_integer_ops::ConvPerChannel( + op_params, data.per_channel_output_multiplier, + data.per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* im2col, + TfLiteEvalTensor* hwcn_weights, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + // TODO(b/154032858): Investigate removing extra copies. + ConvParams op_params; + op_params.padding_type = RuntimePaddingType(params->padding); + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + + reference_ops::Conv(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + tflite::micro::GetTensorShape(im2col), + tflite::micro::GetTensorData(im2col)); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kFilterTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kBiasTensor) + : nullptr; + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: + EvalFloat(context, node, params, data, input, filter, bias, nullptr, + nullptr, output); + break; + case kTfLiteInt8: + EvalQuantizedPerChannel(context, node, params, data, input, filter, bias, + output, nullptr); + break; + case kTfLiteUInt8: + EvalQuantized(context, node, params, data, input, filter, bias, nullptr, + nullptr, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace conv + +TfLiteRegistration Register_CONV_2D() { + return {/*init=*/conv::Init, + /*free=*/nullptr, + /*prepare=*/conv::Prepare, + /*invoke=*/conv::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.h new file mode 100644 index 0000000..4089a96 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/conv.h @@ -0,0 +1,92 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_CONV_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_CONV_H_ + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +struct OpDataConv { + TfLitePaddingValues padding; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; + + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + // Per channel output multiplier and shift. + int32_t* per_channel_output_multiplier; + int32_t* per_channel_output_shift; + + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; +}; + +extern const int kConvInputTensor; +extern const int kConvWeightsTensor; +extern const int kConvBiasTensor; +extern const int kConvOutputTensor; +extern const int kConvQuantizedDimension; + +// Returns a ConvParams struct with all the parameters needed for a +// float computation. +ConvParams ConvParamsFloat(const TfLiteConvParams& params, + const OpDataConv& data); + +// Returns a ConvParams struct with all the parameters needed for a +// quantized computation. +ConvParams ConvParamsQuantized(const TfLiteConvParams& params, + const OpDataConv& data); + +TfLiteStatus CalculateOpDataConv(TfLiteContext* context, TfLiteNode* node, + const TfLiteConvParams& params, int width, + int height, int filter_width, + int filter_height, int out_width, + int out_height, const TfLiteType data_type, + OpDataConv* data); + +TfLiteStatus ConvPrepare(TfLiteContext* context, TfLiteNode* node); + +// This is the most generic TfLiteRegistration. The actual supported types may +// still be target dependent. The only requirement is that every implementation +// (reference or optimized) must define this function. +TfLiteRegistration Register_CONV_2D(); + +#if defined(XTENSA) +// Returns a TfLiteRegistration struct for kernel variant that only supports +// int8 inputs and outputs. +TfLiteRegistration Register_CONV_2D_INT8REF(); +#else +inline TfLiteRegistration Register_CONV_2D_INT8REF() { + return Register_CONV_2D(); +} +#endif + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.cc new file mode 100644 index 0000000..2f6083d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.cc @@ -0,0 +1,327 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h" +#include "tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace depthwise_conv { +namespace { + +constexpr int kInputTensor = 0; +constexpr int kFilterTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; + +// Depthwise conv is quantized along dimension 3: +// https://www.tensorflow.org/lite/performance/quantization_spec +constexpr int kDepthwiseConvQuantizedDimension = 3; + +struct OpData { + TfLitePaddingValues padding; + + // Cached tensor zero point values for quantized operations. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; + + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + // Per channel output multiplier and shift. + int32_t* per_channel_output_multiplier; + int32_t* per_channel_output_shift; + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, int width, + int height, int filter_width, int filter_height, + const TfLiteType data_type, OpData* data) { + bool has_bias = node->inputs->size == 3; + // Check number of inputs/outputs + TF_LITE_ENSURE(context, has_bias || node->inputs->size == 2); + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + + int unused_output_height, unused_output_width; + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, 1, 1, height, width, + filter_height, filter_width, params->padding, &unused_output_height, + &unused_output_width); + + // Note that quantized inference requires that all tensors have their + // parameters set. This is usually done during quantized training. + if (data_type != kTfLiteFloat32) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + const TfLiteTensor* bias = + GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + int num_channels = filter->dims->data[kDepthwiseConvQuantizedDimension]; + + return tflite::PopulateConvolutionQuantizationParams( + context, input, filter, bias, output, params->activation, + &data->output_multiplier, &data->output_shift, + &data->output_activation_min, &data->output_activation_max, + data->per_channel_output_multiplier, + reinterpret_cast(data->per_channel_output_shift), num_channels); + } + return kTfLiteOk; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto* params = + reinterpret_cast(node->builtin_data); + OpData* data = static_cast(node->user_data); + + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kFilterTensor); + + const TfLiteType data_type = input->type; + int width = SizeOfDimension(input, 2); + int height = SizeOfDimension(input, 1); + int filter_width = SizeOfDimension(filter, 2); + int filter_height = SizeOfDimension(filter, 1); + + // Per channel quantization is only needed for int8_t inference. For other + // quantized types, only a single scale and zero point is needed. + const int num_channels = filter->dims->data[kDepthwiseConvQuantizedDimension]; + // Dynimically allocate per-channel quantization parameters. + data->per_channel_output_multiplier = + reinterpret_cast(context->AllocatePersistentBuffer( + context, num_channels * sizeof(int32_t))); + data->per_channel_output_shift = + reinterpret_cast(context->AllocatePersistentBuffer( + context, num_channels * sizeof(int32_t))); + + // All per-channel quantized tensors need valid zero point and scale arrays. + if (input->type == kTfLiteInt8) { + TF_LITE_ENSURE_EQ(context, filter->quantization.type, + kTfLiteAffineQuantization); + + const auto* affine_quantization = + reinterpret_cast( + filter->quantization.params); + TF_LITE_ENSURE(context, affine_quantization); + TF_LITE_ENSURE(context, affine_quantization->scale); + TF_LITE_ENSURE(context, affine_quantization->zero_point); + TF_LITE_ENSURE( + context, affine_quantization->scale->size == 1 || + affine_quantization->scale->size == + filter->dims->data[kDepthwiseConvQuantizedDimension]); + TF_LITE_ENSURE_EQ(context, affine_quantization->scale->size, + affine_quantization->zero_point->size); + } + + TF_LITE_ENSURE_STATUS(CalculateOpData(context, node, params, width, height, + filter_width, filter_height, data_type, + data)); + + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + + return kTfLiteOk; +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + + tflite::DepthwiseParams op_params; + // Padding type is ignored, but still set. + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + + tflite::reference_ops::DepthwiseConv( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void EvalQuantizedPerChannel(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, + const OpData& data, const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + DepthwiseParams op_params; + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.input_offset = -data.input_zero_point; + op_params.weights_offset = 0; + op_params.output_offset = data.output_zero_point; + // TODO(b/130439627): Use calculated value for clamping. + op_params.quantized_activation_min = std::numeric_limits::min(); + op_params.quantized_activation_max = std::numeric_limits::max(); + + reference_integer_ops::DepthwiseConvPerChannel( + op_params, data.per_channel_output_multiplier, + data.per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteDepthwiseConvParams* params, const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data.input_zero_point; + const int32_t filter_offset = -data.filter_zero_point; + const int32_t output_offset = data.output_zero_point; + + tflite::DepthwiseParams op_params; + // Padding type is ignored, but still set. + op_params.padding_type = PaddingType::kSame; + op_params.padding_values.width = data.padding.width; + op_params.padding_values.height = data.padding.height; + op_params.stride_width = params->stride_width; + op_params.stride_height = params->stride_height; + op_params.dilation_width_factor = params->dilation_width_factor; + op_params.dilation_height_factor = params->dilation_height_factor; + op_params.depth_multiplier = params->depth_multiplier; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data.output_multiplier; + // Legacy ops used mixed left and right shifts. Now all are +ve-means-left. + op_params.output_shift = -data.output_shift; + + tflite::reference_ops::DepthwiseConv( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto* params = + reinterpret_cast(node->builtin_data); + const OpData& data = *(static_cast(node->user_data)); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kFilterTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kBiasTensor) + : nullptr; + + // TODO(aselle): Consider whether float conv and quantized conv should be + // separate ops to avoid dispatch overhead here. + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: + EvalFloat(context, node, params, data, input, filter, bias, output); + break; + case kTfLiteInt8: + EvalQuantizedPerChannel(context, node, params, data, input, filter, bias, + output); + break; + case kTfLiteUInt8: + EvalQuantized(context, node, params, data, input, filter, bias, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace depthwise_conv + +TfLiteRegistration Register_DEPTHWISE_CONV_2D() { + return {/*init=*/depthwise_conv::Init, + /*free=*/nullptr, + /*prepare=*/depthwise_conv::Prepare, + /*invoke=*/depthwise_conv::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.h new file mode 100644 index 0000000..7a7eb0b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/depthwise_conv.h @@ -0,0 +1,54 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_DEPTHWISE_CONV_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_DEPTHWISE_CONV_H_ + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/micro/kernels/conv.h" + +namespace tflite { + +extern const int kDepthwiseConvInputTensor; +extern const int kDepthwiseConvWeightsTensor; +extern const int kDepthwiseConvBiasTensor; +extern const int kDepthwiseConvOutputTensor; +extern const int kDepthwiseConvQuantizedDimension; + +// Returns a DepthwiseParams struct with all the parameters needed for a +// float computation. +DepthwiseParams DepthwiseConvParamsFloat( + const TfLiteDepthwiseConvParams& params, const OpDataConv& data); + +// Returns a DepthwiseParams struct with all the parameters needed for a +// quantized computation. +DepthwiseParams DepthwiseConvParamsQuantized( + const TfLiteDepthwiseConvParams& params, const OpDataConv& data); + +TfLiteStatus CalculateOpDataDepthwiseConv( + TfLiteContext* context, TfLiteNode* node, + const TfLiteDepthwiseConvParams& params, int width, int height, + int filter_width, int filter_height, int out_width, int out_height, + const TfLiteType data_type, OpDataConv* data); + +TfLiteStatus DepthwiseConvPrepare(TfLiteContext* context, TfLiteNode* node); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_DEPTHWISE_CONV_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/dequantize.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/dequantize.cc new file mode 100644 index 0000000..df50188 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/dequantize.cc @@ -0,0 +1,164 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/dequantize.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/quantize.h" +#include "tensorflow/lite/kernels/internal/reference/requantize.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace dequantize { + +struct OpData { + tflite::DequantizationParams quantization_params; + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + int32_t output_zero_point; +}; + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + // TODO(b/140515557): Add cached dequant to improve hybrid model performance. + const TfLiteTensor* input = GetInput(context, node, 0); + TfLiteTensor* output = GetOutput(context, node, 0); + + TF_LITE_ENSURE(context, input->type == kTfLiteUInt8 || + input->type == kTfLiteInt8 || + input->type == kTfLiteInt16); + TF_LITE_ENSURE( + context, output->type == kTfLiteFloat32 || output->type == kTfLiteInt32); + + if (output->type == kTfLiteInt32) { + const double effective_output_scale = + static_cast(input->params.scale) / + static_cast(output->params.scale); + QuantizeMultiplier(effective_output_scale, &data->output_multiplier, + &data->output_shift); + } + + data->quantization_params.zero_point = input->params.zero_point; + data->quantization_params.scale = static_cast(input->params.scale); + data->output_zero_point = output->params.zero_point; + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + if (output->type == kTfLiteFloat32) { + switch (input->type) { + case kTfLiteUInt8: + reference_ops::Dequantize(data->quantization_params, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + case kTfLiteInt8: + reference_ops::Dequantize(data->quantization_params, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + case kTfLiteInt16: + reference_ops::Dequantize(data->quantization_params, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else if (output->type == kTfLiteInt32) { + int flat_size = MatchingFlatSize(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorShape(output)); + switch (input->type) { + case kTfLiteInt16: { + reference_ops::Requantize( + tflite::micro::GetTensorData(input), flat_size, + data->output_multiplier, data->output_shift, + data->quantization_params.zero_point, data->output_zero_point, + tflite::micro::GetTensorData(output)); + break; + } + case kTfLiteInt8: { + reference_ops::Requantize( + tflite::micro::GetTensorData(input), flat_size, + data->output_multiplier, data->output_shift, + data->quantization_params.zero_point, data->output_zero_point, + tflite::micro::GetTensorData(output)); + break; + } + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else { + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace dequantize + +TfLiteRegistration Register_DEQUANTIZE() { + return {/*init=*/dequantize::Init, + /*free=*/nullptr, + /*prepare=*/dequantize::Prepare, + /*invoke=*/dequantize::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/elementwise.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/elementwise.cc new file mode 100644 index 0000000..6488034 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/elementwise.cc @@ -0,0 +1,212 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace elementwise { +namespace { + +bool IsNumericSupportedType(const TfLiteType type) { + return type == kTfLiteFloat32; +} + +bool IsLogicalSupportedType(const TfLiteType type) { + return type == kTfLiteBool; +} + +typedef bool (*IsSupportedType)(TfLiteType); +template +TfLiteStatus GenericPrepare(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + const TfLiteTensor* input = GetInput(context, node, 0); + TfLiteTensor* output = GetOutput(context, node, 0); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + if (!IsSupportedType(input->type)) { + TF_LITE_KERNEL_LOG(context, "Input data type %s (%d) is not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +template +inline TfLiteStatus EvalImpl(TfLiteContext* context, TfLiteNode* node, + T func(T), TfLiteType expected_type) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, expected_type); + const size_t num_elements = ElementCount(*input->dims); + const T* in_data = tflite::micro::GetTensorData(input); + T* out_data = tflite::micro::GetTensorData(output); + for (size_t i = 0; i < num_elements; ++i) { + out_data[i] = func(in_data[i]); + } + return kTfLiteOk; +} + +inline TfLiteStatus EvalNumeric(TfLiteContext* context, TfLiteNode* node, + float float_func(float)) { + return EvalImpl(context, node, float_func, kTfLiteFloat32); +} + +inline TfLiteStatus EvalLogical(TfLiteContext* context, TfLiteNode* node, + bool bool_func(bool)) { + return EvalImpl(context, node, bool_func, kTfLiteBool); +} + +TfLiteStatus AbsEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, std::abs); +} + +TfLiteStatus SinEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, std::sin); +} + +TfLiteStatus CosEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, std::cos); +} + +TfLiteStatus LogEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, std::log); +} + +TfLiteStatus SqrtEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, std::sqrt); +} + +TfLiteStatus RsqrtEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, [](float f) { return 1.f / std::sqrt(f); }); +} + +TfLiteStatus SquareEval(TfLiteContext* context, TfLiteNode* node) { + return EvalNumeric(context, node, [](float f) { return f * f; }); +} + +TfLiteStatus LogicalNotEval(TfLiteContext* context, TfLiteNode* node) { + return EvalLogical(context, node, [](bool v) { return !v; }); +} + +} // namespace +} // namespace elementwise + +TfLiteRegistration Register_ABS() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::AbsEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_SIN() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::SinEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_COS() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::CosEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_LOG() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::LogEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_SQRT() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::SqrtEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_RSQRT() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::RsqrtEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_SQUARE() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::SquareEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_LOGICAL_NOT() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/ + elementwise::GenericPrepare, + /*invoke=*/elementwise::LogicalNotEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ethosu.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ethosu.cc new file mode 100644 index 0000000..eac6cea --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/ethosu.cc @@ -0,0 +1,32 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// +// This is a stub file for non-Ethos platforms +// +#include "tensorflow/lite/c/common.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace custom { +TfLiteRegistration* Register_ETHOSU() { return nullptr; } + +const char* GetString_ETHOSU() { return ""; } + +} // namespace custom +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/floor.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/floor.cc new file mode 100644 index 0000000..b8be1cf --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/floor.cc @@ -0,0 +1,57 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/floor.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace floor { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + reference_ops::Floor(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; +} +} // namespace floor + +TfLiteRegistration Register_FLOOR() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/floor::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.cc new file mode 100644 index 0000000..03078f8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.cc @@ -0,0 +1,256 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/fully_connected.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace fully_connected { +namespace { + +struct OpData { + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; + // The index of the temporary tensor where the quantized inputs are cached. + int input_quantized_index; + // Cached zero point values of tensors. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; +}; + +constexpr int kInputTensor = 0; +constexpr int kWeightsTensor = 1; +constexpr int kBiasTensor = 2; +constexpr int kOutputTensor = 0; + +TfLiteStatus CalculateOpData(TfLiteContext* context, + TfLiteFusedActivation activation, + TfLiteType data_type, const TfLiteTensor* input, + const TfLiteTensor* filter, + const TfLiteTensor* bias, TfLiteTensor* output, + OpData* data) { + TfLiteStatus status = kTfLiteOk; + if (data_type != kTfLiteFloat32) { + double real_multiplier = 0.0; + TF_LITE_ENSURE_STATUS(GetQuantizedConvolutionMultipler( + context, input, filter, bias, output, &real_multiplier)); + int exponent; + QuantizeMultiplier(real_multiplier, &data->output_multiplier, &exponent); + data->output_shift = -exponent; + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, activation, output, &data->output_activation_min, + &data->output_activation_max)); + + data->input_zero_point = input->params.zero_point; + data->filter_zero_point = filter->params.zero_point; + data->output_zero_point = output->params.zero_point; + } + return status; +} + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + const auto params = + static_cast(node->builtin_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* filter = GetInput(context, node, kWeightsTensor); + const TfLiteTensor* bias = GetOptionalInputTensor(context, node, kBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + TF_LITE_ENSURE_MSG(context, input->type == filter->type, + "Hybrid models are not supported on TFLite Micro."); + + return CalculateOpData(context, params->activation, input->type, input, + filter, bias, output, data); +} + +TfLiteStatus EvalQuantizedInt8(TfLiteContext* context, TfLiteNode* node, + const OpData& data, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + tflite::FullyConnectedParams op_params; + op_params.input_offset = -data.input_zero_point; + op_params.weights_offset = -data.filter_zero_point; + op_params.output_offset = data.output_zero_point; + op_params.output_multiplier = data.output_multiplier; + // TODO(b/138810107): Figure out whether output shift should be inverted + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + + reference_integer_ops::FullyConnected( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; +} + +TfLiteStatus EvalQuantized(TfLiteContext* context, TfLiteNode* node, + const OpData& data, const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, + TfLiteEvalTensor* output) { + const int32_t input_offset = -data.input_zero_point; + const int32_t filter_offset = -data.filter_zero_point; + const int32_t output_offset = data.output_zero_point; + + tflite::FullyConnectedParams op_params; + op_params.input_offset = input_offset; + op_params.weights_offset = filter_offset; + op_params.output_offset = output_offset; + op_params.output_multiplier = data.output_multiplier; + // Legacy ops used mixed left and right shifts. Now all are +ve-means-left. + op_params.output_shift = -data.output_shift; + op_params.quantized_activation_min = data.output_activation_min; + op_params.quantized_activation_max = data.output_activation_max; + +#define TF_LITE_FULLY_CONNECTED(output_data_type) \ + reference_ops::FullyConnected( \ + op_params, tflite::micro::GetTensorShape(input), \ + tflite::micro::GetTensorData(input), \ + tflite::micro::GetTensorShape(filter), \ + tflite::micro::GetTensorData(filter), \ + tflite::micro::GetTensorShape(bias), \ + tflite::micro::GetTensorData(bias), \ + tflite::micro::GetTensorShape(output), \ + tflite::micro::GetTensorData(output)) + switch (output->type) { + case kTfLiteUInt8: + TF_LITE_FULLY_CONNECTED(uint8_t); + break; + case kTfLiteInt16: + TF_LITE_FULLY_CONNECTED(int16_t); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +TfLiteStatus EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteFusedActivation activation, + const TfLiteEvalTensor* input, + const TfLiteEvalTensor* filter, + const TfLiteEvalTensor* bias, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(activation, &output_activation_min, + &output_activation_max); + tflite::FullyConnectedParams op_params; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; + tflite::reference_ops::FullyConnected( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + const auto* params = + static_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kWeightsTensor); + const TfLiteEvalTensor* bias = + tflite::micro::GetEvalInput(context, node, kBiasTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + // Checks in Prepare ensure input, output and filter types are all the same. + switch (input->type) { + case kTfLiteFloat32: + return EvalFloat(context, node, params->activation, input, filter, bias, + output); + case kTfLiteInt8: + return EvalQuantizedInt8(context, node, data, input, filter, bias, + output); + + case kTfLiteUInt8: + return EvalQuantized(context, node, data, input, filter, bias, output); + + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace fully_connected + +TfLiteRegistration Register_FULLY_CONNECTED() { + return {/*init=*/fully_connected::Init, + /*free=*/nullptr, + /*prepare=*/fully_connected::Prepare, + /*invoke=*/fully_connected::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.h new file mode 100644 index 0000000..e1215da --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/fully_connected.h @@ -0,0 +1,86 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_FULLY_CONNECTED_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_FULLY_CONNECTED_H_ + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +struct OpDataFullyConnected { + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + // The range of the fused activation layer. For example for kNone and + // uint8_t these would be 0 and 255. + int32_t output_activation_min; + int32_t output_activation_max; + // The index of the temporary tensor where the quantized inputs are cached. + int input_quantized_index; + // Cached zero point values of tensors. + int32_t input_zero_point; + int32_t filter_zero_point; + int32_t output_zero_point; +}; + +extern const int kFullyConnectedInputTensor; +extern const int kFullyConnectedWeightsTensor; +extern const int kFullyConnectedBiasTensor; +extern const int kFullyConnectedOutputTensor; + +// Returns a FullyConnectedParams struct with all the parameters needed for a +// float computation. +FullyConnectedParams FullyConnectedParamsFloat( + TfLiteFusedActivation activation); + +// Returns a FullyConnectedParams struct with all the parameters needed for a +// quantized computation. +FullyConnectedParams FullyConnectedParamsQuantized( + const OpDataFullyConnected& op_data); + +TfLiteStatus CalculateOpDataFullyConnected( + TfLiteContext* context, TfLiteFusedActivation activation, + TfLiteType data_type, const TfLiteTensor* input, const TfLiteTensor* filter, + const TfLiteTensor* bias, TfLiteTensor* output, OpDataFullyConnected* data); + +// This is the most generic TfLiteRegistration. The actual supported types may +// still be target dependent. The only requirement is that every implementation +// (reference or optimized) must define this function. +TfLiteRegistration Register_FULLY_CONNECTED(); + +#if defined(CMSIS_NN) || defined(HEXAGON) +// Returns a TfLiteRegistration struct for kernel variant that only supports +// int8. +TfLiteRegistration Register_FULLY_CONNECTED_INT8(); + +#else +// Note that while this block gets used for both reference and optimized kernels +// that do not have any specialized implementations, the only goal here is to +// define fallback implementation that allow reference kernels to still be used +// from applications that call a more specific kernel variant. + +inline TfLiteRegistration Register_FULLY_CONNECTED_INT8() { + return Register_FULLY_CONNECTED(); +} + +#endif +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_FULLY_CONNECTED_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/hard_swish.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/hard_swish.cc new file mode 100644 index 0000000..11e1d1a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/hard_swish.cc @@ -0,0 +1,140 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/hard_swish.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace hard_swish { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +void* HardSwishInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(HardSwishParams)); +} + +TfLiteStatus HardSwishPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) { + HardSwishParams* params = static_cast(node->user_data); + + params->input_zero_point = input->params.zero_point; + params->output_zero_point = output->params.zero_point; + + const float input_scale = input->params.scale; + const float hires_input_scale = (1.0f / 128.0f) * input_scale; + const float reluish_scale = 3.0f / 32768.0f; + const float output_scale = output->params.scale; + + const double output_multiplier = + static_cast(hires_input_scale / output_scale); + int32_t output_multiplier_fixedpoint_int32; + QuantizeMultiplier(output_multiplier, &output_multiplier_fixedpoint_int32, + ¶ms->output_multiplier_exponent); + DownScaleInt32ToInt16Multiplier( + output_multiplier_fixedpoint_int32, + ¶ms->output_multiplier_fixedpoint_int16); + + TF_LITE_ENSURE(context, params->output_multiplier_exponent <= 0); + + const double reluish_multiplier = + static_cast(hires_input_scale / reluish_scale); + int32_t reluish_multiplier_fixedpoint_int32; + QuantizeMultiplier(reluish_multiplier, &reluish_multiplier_fixedpoint_int32, + ¶ms->reluish_multiplier_exponent); + DownScaleInt32ToInt16Multiplier( + reluish_multiplier_fixedpoint_int32, + ¶ms->reluish_multiplier_fixedpoint_int16); + } + + return kTfLiteOk; +} + +TfLiteStatus HardSwishEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + HardSwishParams* params = static_cast(node->user_data); + + switch (input->type) { + case kTfLiteFloat32: { + tflite::reference_ops::HardSwish( + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } break; + case kTfLiteUInt8: { + tflite::reference_ops::HardSwish( + *params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } break; + case kTfLiteInt8: { + tflite::reference_ops::HardSwish( + *params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } break; + default: { + TF_LITE_KERNEL_LOG( + context, + "Only float32/int8_t/uint8_t are supported currently, got %s", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + } + return kTfLiteOk; +} + +} // namespace hard_swish + +TfLiteRegistration Register_HARD_SWISH() { + return {/*init=*/hard_swish::HardSwishInit, + /*free=*/nullptr, + /*prepare=*/hard_swish::HardSwishPrepare, + /*invoke=*/hard_swish::HardSwishEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.cc new file mode 100644 index 0000000..cef6c01 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.cc @@ -0,0 +1,165 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/kernel_runner.h" + +namespace tflite { +namespace micro { + +namespace { +constexpr size_t kBufferAlignment = 16; +} // namespace + +// TODO(b/161841696): Consider moving away from global arena buffers: +constexpr int KernelRunner::kNumScratchBuffers_; +constexpr int KernelRunner::kKernelRunnerBufferSize_; +uint8_t KernelRunner::kKernelRunnerBuffer_[]; + +KernelRunner::KernelRunner(const TfLiteRegistration& registration, + TfLiteTensor* tensors, int tensors_size, + TfLiteIntArray* inputs, TfLiteIntArray* outputs, + void* builtin_data, ErrorReporter* error_reporter) + : allocator_(SimpleMemoryAllocator::Create( + error_reporter, kKernelRunnerBuffer_, kKernelRunnerBufferSize_)), + registration_(registration), + tensors_(tensors), + error_reporter_(error_reporter) { + // Prepare TfLiteContext: + context_.impl_ = static_cast(this); + context_.ReportError = ReportOpError; + context_.recommended_num_threads = 1; + context_.GetTensor = GetTensor; + context_.GetEvalTensor = GetEvalTensor; + context_.AllocatePersistentBuffer = AllocatePersistentBuffer; + context_.RequestScratchBufferInArena = RequestScratchBufferInArena; + context_.GetScratchBuffer = GetScratchBuffer; + + // Prepare TfLiteNode: + node_.inputs = inputs; + node_.outputs = outputs; + node_.builtin_data = builtin_data; +} + +TfLiteStatus KernelRunner::InitAndPrepare(const char* init_data) { + if (registration_.init) { + node_.user_data = registration_.init(&context_, init_data, /*length=*/0); + } + if (registration_.prepare) { + TF_LITE_ENSURE_STATUS(registration_.prepare(&context_, &node_)); + } + return kTfLiteOk; +} + +TfLiteStatus KernelRunner::Invoke() { + if (registration_.invoke == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "TfLiteRegistration missing invoke function pointer!"); + return kTfLiteError; + } + return registration_.invoke(&context_, &node_); +} + +TfLiteTensor* KernelRunner::GetTensor(const struct TfLiteContext* context, + int tensor_index) { + TFLITE_DCHECK(context != nullptr); + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + return &runner->tensors_[tensor_index]; +} + +TfLiteEvalTensor* KernelRunner::GetEvalTensor( + const struct TfLiteContext* context, int tensor_index) { + TFLITE_DCHECK(context != nullptr); + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + TfLiteEvalTensor* eval_tensor = + reinterpret_cast(runner->allocator_->AllocateTemp( + sizeof(TfLiteEvalTensor), alignof(TfLiteEvalTensor))); + TFLITE_DCHECK(eval_tensor != nullptr); + + // In unit tests, the TfLiteTensor pointer contains the source of truth for + // buffers and values: + eval_tensor->data = runner->tensors_[tensor_index].data; + eval_tensor->dims = runner->tensors_[tensor_index].dims; + eval_tensor->type = runner->tensors_[tensor_index].type; + return eval_tensor; +} + +void* KernelRunner::AllocatePersistentBuffer(TfLiteContext* context, + size_t bytes) { + TFLITE_DCHECK(context != nullptr); + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + return runner->allocator_->AllocateFromTail(bytes, kBufferAlignment); +} + +TfLiteStatus KernelRunner::RequestScratchBufferInArena(TfLiteContext* context, + size_t bytes, + int* buffer_index) { + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(buffer_index != nullptr); + + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + if (runner->scratch_buffer_count_ == kNumScratchBuffers_) { + TF_LITE_REPORT_ERROR( + runner->error_reporter_, + "Exceeded the maximum number of scratch tensors allowed (%d).", + kNumScratchBuffers_); + return kTfLiteError; + } + + // For tests, we allocate scratch buffers from the tail and keep them around + // for the lifetime of model. This means that the arena size in the tests will + // be more than what we would have if the scratch buffers could share memory. + runner->scratch_buffers_[runner->scratch_buffer_count_] = + runner->allocator_->AllocateFromTail(bytes, kBufferAlignment); + TFLITE_DCHECK(runner->scratch_buffers_[runner->scratch_buffer_count_] != + nullptr); + + *buffer_index = runner->scratch_buffer_count_++; + return kTfLiteOk; +} + +void* KernelRunner::GetScratchBuffer(TfLiteContext* context, int buffer_index) { + TFLITE_DCHECK(context != nullptr); + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + TFLITE_DCHECK(runner->scratch_buffer_count_ <= kNumScratchBuffers_); + if (buffer_index >= runner->scratch_buffer_count_) { + return nullptr; + } + return runner->scratch_buffers_[buffer_index]; +} + +void KernelRunner::ReportOpError(struct TfLiteContext* context, + const char* format, ...) { + TFLITE_DCHECK(context != nullptr); + KernelRunner* runner = reinterpret_cast(context->impl_); + TFLITE_DCHECK(runner != nullptr); + + va_list args; + va_start(args, format); + TF_LITE_REPORT_ERROR(runner->error_reporter_, format, args); + va_end(args); +} + +} // namespace micro +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.h new file mode 100644 index 0000000..45d107e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_runner.h @@ -0,0 +1,83 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_RUNNER_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_RUNNER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/simple_memory_allocator.h" + +namespace tflite { +namespace micro { + +// Helper class to perform a simulated kernel (i.e. TfLiteRegistration) lifecyle +// (init, prepare, invoke). All internal allocations are handled by this class. +// Simply pass in the registration, list of required tensors, inputs array, +// outputs array, and any pre-builtin data. Calling Invoke() will automatically +// walk the kernl and outputs will be ready on the the TfLiteTensor output +// provided during construction. +class KernelRunner { + public: + KernelRunner(const TfLiteRegistration& registration, TfLiteTensor* tensors, + int tensors_size, TfLiteIntArray* inputs, + TfLiteIntArray* outputs, void* builtin_data, + ErrorReporter* error_reporter); + + // Calls init and prepare on the kernel (i.e. TfLiteRegistration) struct. Any + // exceptions will be reported through the error_reporter and returned as a + // status code here. + TfLiteStatus InitAndPrepare(const char* init_data = nullptr); + + // Calls init, prepare, and invoke on a given TfLiteRegistration pointer. + // After successful invoke, results will be available in the output tensor as + // passed into the constructor of this class. + TfLiteStatus Invoke(); + + protected: + static TfLiteTensor* GetTensor(const struct TfLiteContext* context, + int tensor_index); + static TfLiteEvalTensor* GetEvalTensor(const struct TfLiteContext* context, + int tensor_index); + static void* AllocatePersistentBuffer(TfLiteContext* context, size_t bytes); + static TfLiteStatus RequestScratchBufferInArena(TfLiteContext* context, + size_t bytes, + int* buffer_index); + static void* GetScratchBuffer(TfLiteContext* context, int buffer_index); + static void ReportOpError(struct TfLiteContext* context, const char* format, + ...); + + private: + static constexpr int kNumScratchBuffers_ = 5; + + static constexpr int kKernelRunnerBufferSize_ = 10000; + static uint8_t kKernelRunnerBuffer_[kKernelRunnerBufferSize_]; + + SimpleMemoryAllocator* allocator_ = nullptr; + const TfLiteRegistration& registration_; + TfLiteTensor* tensors_ = nullptr; + ErrorReporter* error_reporter_ = nullptr; + + TfLiteContext context_ = {}; + TfLiteNode node_ = {}; + + int scratch_buffer_count_ = 0; + uint8_t* scratch_buffers_[kNumScratchBuffers_]; +}; + +} // namespace micro +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_RUNNER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.cc new file mode 100644 index 0000000..1ddfc1d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.cc @@ -0,0 +1,31 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +#include "tensorflow/lite/c/common.h" + +namespace tflite { +namespace micro { + +bool HaveSameShapes(const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2) { + TFLITE_DCHECK(input1 != nullptr); + TFLITE_DCHECK(input2 != nullptr); + return TfLiteIntArrayEqual(input1->dims, input2->dims); +} + +} // namespace micro +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.h new file mode 100644 index 0000000..530e52d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/kernel_util.h @@ -0,0 +1,83 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_UTIL_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_UTIL_H_ + +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { +namespace micro { + +// Returns a mutable tensor for a given input index. is_variable must be checked +// during prepare when the full TfLiteTensor is available. +inline TfLiteEvalTensor* GetMutableEvalInput(const TfLiteContext* context, + const TfLiteNode* node, + int index) { + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(node != nullptr); + return context->GetEvalTensor(context, node->inputs->data[index]); +} + +// Returns the TfLiteEvalTensor struct for a given input index in a node. +inline const TfLiteEvalTensor* GetEvalInput(const TfLiteContext* context, + const TfLiteNode* node, int index) { + return GetMutableEvalInput(context, node, index); +} + +// Returns the TfLiteEvalTensor struct for a given output index in a node. +inline TfLiteEvalTensor* GetEvalOutput(const TfLiteContext* context, + const TfLiteNode* node, int index) { + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(node != nullptr); + return context->GetEvalTensor(context, node->outputs->data[index]); +} + +// Returns data for a TfLiteEvalTensor struct. +template +T* GetTensorData(TfLiteEvalTensor* tensor) { + return tensor != nullptr ? reinterpret_cast(tensor->data.raw) : nullptr; +} + +// Returns const data for a TfLiteEvalTensor struct. +template +const T* GetTensorData(const TfLiteEvalTensor* tensor) { + TFLITE_DCHECK(tensor != nullptr); + return reinterpret_cast(tensor->data.raw); +} + +// Returns the shape of a TfLiteEvalTensor struct. +inline const RuntimeShape GetTensorShape(const TfLiteEvalTensor* tensor) { + if (tensor == nullptr) { + return RuntimeShape(); + } + TfLiteIntArray* dims = tensor->dims; + const int dims_size = dims->size; + const int32_t* dims_data = reinterpret_cast(dims->data); + return RuntimeShape(dims_size, dims_data); +} + +// Return true if the given tensors have the same shape. +bool HaveSameShapes(const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2); + +} // namespace micro +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_KERNEL_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/l2norm.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/l2norm.cc new file mode 100644 index 0000000..f864efa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/l2norm.cc @@ -0,0 +1,155 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h" +#include "tensorflow/lite/kernels/internal/reference/l2normalization.h" +#include "tensorflow/lite/kernels/internal/tensor.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace l2norm { + +namespace { + +// This file has two implementation of L2Norm. +enum KernelType { + kReference, + kGenericOptimized, +}; + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +} // namespace + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto* params = reinterpret_cast(node->builtin_data); + L2NormalizationParams* data = + static_cast(node->user_data); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE(context, NumDimensions(input) <= 4); + + TF_LITE_ENSURE(context, output->type == kTfLiteFloat32 || + output->type == kTfLiteUInt8 || + output->type == kTfLiteInt8); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + data->input_zero_point = input->params.zero_point; + } else if (output->type == kTfLiteFloat32) { + data->input_zero_point = 0; + } + + // TODO(ahentz): For some reason our implementations don't support + // activations. + TF_LITE_ENSURE_EQ(context, params->activation, kTfLiteActNone); + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, + sizeof(L2NormalizationParams)); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const L2NormalizationParams& data = + *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + // TODO(b/143912164): instead of hardcode the epsilon here, we should read it + // from tensorflow, i.e., adding a params. + // We don't compute epsilon for quantized kernel: + // + // epsilon_float = (epsilon_quant - zp) * scale + // so + // espsilon_quant = epsilon_float / scale + zp + // We know epsilon_float is just a very small number to avoid division by + // zero error, and scale is > 1, so the integer value of epsilon for quant + // is just dominated by the zero point. + // Also, GetInvSqrtQuantizedMultiplierExp handles the scenario where the sum + // of input value squared is zero case well. + // So we don't even need to do handle the epsilon for quantized kernel case. + const float epsilon = 1e-6f; + if (output->type == kTfLiteFloat32) { + reference_ops::L2Normalization(data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + epsilon); + } else if (output->type == kTfLiteUInt8) { + reference_ops::L2Normalization( + data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else if (output->type == kTfLiteInt8) { + const auto input_shape = tflite::micro::GetTensorShape(input); + const auto output_shape = tflite::micro::GetTensorShape(output); + const int trailing_dim = input_shape.DimensionsCount() - 1; + const int depth = + MatchingDim(input_shape, trailing_dim, output_shape, trailing_dim); + const int outer_size = + MatchingFlatSizeSkipDim(input_shape, trailing_dim, output_shape); + reference_integer_ops::L2Normalization( + data.input_zero_point, outer_size, depth, + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorData(output)); + } else { + TF_LITE_KERNEL_LOG(context, "Output type is %s, requires float.", + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace l2norm + +TfLiteRegistration Register_L2NORM_REF() { + return {/*init=*/l2norm::Init, + /*free=*/nullptr, + /*prepare=*/l2norm::Prepare, + /*invoke=*/l2norm::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_L2_NORMALIZATION() { return Register_L2NORM_REF(); } + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logical.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logical.cc new file mode 100644 index 0000000..f4033ba --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logical.cc @@ -0,0 +1,105 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/reference/binary_function.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace logical { +namespace { + +// Input/output tensor index. +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +TfLiteStatus LogicalImpl(TfLiteContext* context, TfLiteNode* node, + bool (*func)(bool, bool)) { + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + if (tflite::micro::HaveSameShapes(input1, input2)) { + reference_ops::BinaryFunction( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), func); + } else { + reference_ops::BroadcastBinaryFunction4DSlow( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), func); + } + + return kTfLiteOk; +} + +bool LogicalOr(bool x, bool y) { return x || y; } + +TfLiteStatus LogicalOrEval(TfLiteContext* context, TfLiteNode* node) { + return LogicalImpl(context, node, LogicalOr); +} + +bool LogicalAnd(bool x, bool y) { return x && y; } + +TfLiteStatus LogicalAndEval(TfLiteContext* context, TfLiteNode* node) { + return LogicalImpl(context, node, LogicalAnd); +} + +} // namespace +} // namespace logical + +TfLiteRegistration Register_LOGICAL_OR() { + // Init, Free, Prepare, Eval are satisfying the Interface required by + // TfLiteRegistration. + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/logical::LogicalOrEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_LOGICAL_AND() { + // Init, Free, Prepare, Eval are satisfying the Interface required by + // TfLiteRegistration. + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/logical::LogicalAndEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logistic.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logistic.cc new file mode 100644 index 0000000..7a371da --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/logistic.cc @@ -0,0 +1,148 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/logistic.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +struct OpData { + int32_t input_zero_point; + int32_t input_range_radius; + int32_t input_multiplier; + int input_left_shift; +}; + +TfLiteStatus CalculateArithmeticOpData(TfLiteContext* context, TfLiteNode* node, + OpData* data) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + if (input->type == kTfLiteInt8) { + TF_LITE_ENSURE_EQ(context, output->params.zero_point, + std::numeric_limits::min()); + + static constexpr int kInputIntegerBits = 4; + const double input_real_multiplier = + static_cast(input->params.scale) * + static_cast(1 << (31 - kInputIntegerBits)); + + data->input_zero_point = input->params.zero_point; + + const double q = std::frexp(input_real_multiplier, &data->input_left_shift); + data->input_multiplier = static_cast(TfLiteRound(q * (1ll << 31))); + + data->input_range_radius = + CalculateInputRadius(kInputIntegerBits, data->input_left_shift, 31); + } + return kTfLiteOk; +} +} // namespace + +void* LogisticInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus LogisticPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + return CalculateArithmeticOpData(context, node, data); +} + +TfLiteStatus LogisticEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + if (input->type == kTfLiteFloat32) { + switch (output->type) { + case kTfLiteFloat32: { + reference_ops::Logistic(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else if (input->type == kTfLiteInt8) { + switch (output->type) { + case kTfLiteInt8: { + reference_integer_ops::Logistic( + data->input_zero_point, data->input_range_radius, + data->input_multiplier, data->input_left_shift, + NumElements(input->dims), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else { + // TODO(b/141211002): Also support other data types once we have supported + // temporary tensors in TFLM. + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace activations + +TfLiteRegistration Register_LOGISTIC() { + return {/*init=*/activations::LogisticInit, + /*free=*/nullptr, + /*prepare=*/activations::LogisticPrepare, + /*invoke=*/activations::LogisticEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/maximum_minimum.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/maximum_minimum.cc new file mode 100644 index 0000000..a7c343b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/maximum_minimum.cc @@ -0,0 +1,148 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/maximum_minimum.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace maximum_minimum { +namespace { + +// This file has a reference implementation of TFMaximum/TFMinimum. +enum KernelType { + kReference, +}; + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +struct OpContext { + OpContext(TfLiteContext* context, TfLiteNode* node) { + input1 = tflite::micro::GetEvalInput(context, node, kInputTensor1); + input2 = tflite::micro::GetEvalInput(context, node, kInputTensor2); + output = tflite::micro::GetEvalOutput(context, node, kOutputTensor); + } + const TfLiteEvalTensor* input1; + const TfLiteEvalTensor* input2; + TfLiteEvalTensor* output; +}; + +struct MaximumOp { + template + static data_type op(data_type el1, data_type el2) { + return el1 > el2 ? el1 : el2; + } +}; + +struct MinimumOp { + template + static data_type op(data_type el1, data_type el2) { + return el1 < el2 ? el1 : el2; + } +}; + +} // namespace + +template +void TFLiteOperation(TfLiteContext* context, TfLiteNode* node, + const OpContext& op_context) { + reference_ops::MaximumMinimumBroadcastSlow( + tflite::micro::GetTensorShape(op_context.input1), + tflite::micro::GetTensorData(op_context.input1), + tflite::micro::GetTensorShape(op_context.input2), + tflite::micro::GetTensorData(op_context.input2), + tflite::micro::GetTensorShape(op_context.output), + tflite::micro::GetTensorData(op_context.output), + op_type::template op); +} + +template +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + OpContext op_context(context, node); + + if (kernel_type == kReference) { + switch (op_context.output->type) { + case kTfLiteFloat32: + TFLiteOperation(context, node, op_context); + break; + case kTfLiteUInt8: + TFLiteOperation(context, node, op_context); + break; + case kTfLiteInt8: + TFLiteOperation(context, node, op_context); + break; + case kTfLiteInt32: + TFLiteOperation(context, node, op_context); + break; + case kTfLiteInt64: + TFLiteOperation(context, node, op_context); + break; + default: + TF_LITE_KERNEL_LOG(context, + "Type %s (%d) is not supported by Maximum/Minimum.", + TfLiteTypeGetName(op_context.output->type), + op_context.output->type); + return kTfLiteError; + } + } else { + TF_LITE_KERNEL_LOG(context, + "Kernel type not supported by Maximum/Minimum."); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace maximum_minimum + +TfLiteRegistration Register_MAXIMUM() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/ + maximum_minimum::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_MINIMUM() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/ + maximum_minimum::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_ops.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_ops.h new file mode 100644 index 0000000..7e63f34 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_ops.h @@ -0,0 +1,92 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_MICRO_OPS_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_MICRO_OPS_H_ + +#include "tensorflow/lite/c/common.h" + +namespace tflite { +namespace ops { +namespace micro { + +// Forward declaration of all micro op kernel registration methods. These +// registrations are included with the standard `BuiltinOpResolver`. +// +// This header is particularly useful in cases where only a subset of ops are +// needed. In such cases, the client can selectively add only the registrations +// their model requires, using a custom `(Micro)MutableOpResolver`. Selective +// registration in turn allows the linker to strip unused kernels. + +TfLiteRegistration Register_ABS(); +TfLiteRegistration Register_ADD(); +TfLiteRegistration Register_ARG_MAX(); +TfLiteRegistration Register_ARG_MIN(); +TfLiteRegistration Register_AVERAGE_POOL_2D(); +TfLiteRegistration Register_CEIL(); +// TODO(b/160234179): Change custom OPs to also return by value. +TfLiteRegistration* Register_CIRCULAR_BUFFER(); +TfLiteRegistration Register_CONV_2D(); +TfLiteRegistration Register_CONCATENATION(); +TfLiteRegistration Register_COS(); +TfLiteRegistration Register_DEPTHWISE_CONV_2D(); +TfLiteRegistration Register_DEQUANTIZE(); +TfLiteRegistration Register_EQUAL(); +TfLiteRegistration Register_FLOOR(); +TfLiteRegistration Register_FULLY_CONNECTED(); +TfLiteRegistration Register_GREATER(); +TfLiteRegistration Register_GREATER_EQUAL(); +TfLiteRegistration Register_HARD_SWISH(); +TfLiteRegistration Register_LESS(); +TfLiteRegistration Register_LESS_EQUAL(); +TfLiteRegistration Register_LOG(); +TfLiteRegistration Register_LOGICAL_AND(); +TfLiteRegistration Register_LOGICAL_NOT(); +TfLiteRegistration Register_LOGICAL_OR(); +TfLiteRegistration Register_LOGISTIC(); +TfLiteRegistration Register_MAXIMUM(); +TfLiteRegistration Register_MAX_POOL_2D(); +TfLiteRegistration Register_MEAN(); +TfLiteRegistration Register_MINIMUM(); +TfLiteRegistration Register_MUL(); +TfLiteRegistration Register_NEG(); +TfLiteRegistration Register_NOT_EQUAL(); +TfLiteRegistration Register_PACK(); +TfLiteRegistration Register_PAD(); +TfLiteRegistration Register_PADV2(); +TfLiteRegistration Register_PRELU(); +TfLiteRegistration Register_QUANTIZE(); +TfLiteRegistration Register_RELU(); +TfLiteRegistration Register_RELU6(); +TfLiteRegistration Register_RESHAPE(); +TfLiteRegistration Register_RESIZE_NEAREST_NEIGHBOR(); +TfLiteRegistration Register_ROUND(); +TfLiteRegistration Register_RSQRT(); +TfLiteRegistration Register_SIN(); +TfLiteRegistration Register_SOFTMAX(); +TfLiteRegistration Register_SPLIT(); +TfLiteRegistration Register_SQRT(); +TfLiteRegistration Register_SQUARE(); +TfLiteRegistration Register_STRIDED_SLICE(); +TfLiteRegistration Register_SUB(); +TfLiteRegistration Register_SVDF(); +TfLiteRegistration Register_UNPACK(); +TfLiteRegistration Register_L2_NORMALIZATION(); +TfLiteRegistration Register_TANH(); + +} // namespace micro +} // namespace ops +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_MICRO_OPS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_utils.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_utils.h new file mode 100644 index 0000000..85db263 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/micro_utils.h @@ -0,0 +1,37 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_MICRO_UTILS_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_MICRO_UTILS_H_ +namespace tflite { +namespace ops { +namespace micro { + +// Same as gtl::Greater but defined here to reduce dependencies and +// binary size for micro environment. +struct Greater { + template + bool operator()(const T& x, const T& y) const { + return x > y; + } +}; + +struct Less { + template + bool operator()(const T& x, const T& y) const { + return x < y; + } +}; + +} // namespace micro +} // namespace ops +} // namespace tflite +#endif // TENSORFLOW_LITE_MICRO_KERNELS_MICRO_UTILS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/mul.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/mul.cc new file mode 100644 index 0000000..36e41a3 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/mul.cc @@ -0,0 +1,233 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/mul.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/mul.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace mul { +namespace { + +constexpr int kInput1Tensor = 0; +constexpr int kInput2Tensor = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + int32_t input1_zero_point; + int32_t input2_zero_point; + + int32_t output_activation_min; + int32_t output_activation_max; + int32_t output_zero_point; + int32_t output_multiplier; + int output_shift; + + float output_activation_min_f32; + float output_activation_max_f32; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, OpData* data) { + const TfLiteTensor* input1 = GetInput(context, node, kInput1Tensor); + const TfLiteTensor* input2 = GetInput(context, node, kInput2Tensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 2); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + TF_LITE_ENSURE_TYPES_EQ(context, input1->type, input2->type); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + + double real_multiplier = static_cast(input1->params.scale) * + static_cast(input2->params.scale) / + static_cast(output->params.scale); + QuantizeMultiplier(real_multiplier, &data->output_multiplier, + &data->output_shift); + + data->input1_zero_point = input1->params.zero_point; + data->input2_zero_point = input2->params.zero_point; + data->output_zero_point = output->params.zero_point; + } else { + CalculateActivationRange(params->activation, + &data->output_activation_min_f32, + &data->output_activation_max_f32); + } + + return kTfLiteOk; +} + +} // namespace + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params = {}; + op_params.quantized_activation_min = data->output_activation_min; + op_params.quantized_activation_max = data->output_activation_max; + op_params.float_activation_max = data->output_activation_max_f32; + op_params.input1_offset = -data->input1_zero_point; + op_params.input2_offset = -data->input2_zero_point; + op_params.output_offset = data->output_zero_point; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + if (output->type == kTfLiteInt8) { + if (need_broadcast) { + reference_integer_ops::BroadcastMul4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::Mul(op_params, + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } else if (output->type == kTfLiteUInt8) { + if (need_broadcast) { + reference_integer_ops::BroadcastMul4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::Mul(op_params, + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, const OpData* data, + const TfLiteEvalTensor* input1, const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params = {}; + op_params.float_activation_min = data->output_activation_min_f32; + op_params.float_activation_max = data->output_activation_max_f32; + + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + if (need_broadcast) { + reference_ops::BroadcastMul4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Mul(op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + return CalculateOpData(context, node, params, data); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInput1Tensor); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInput2Tensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input1->type) { + case kTfLiteUInt8: + case kTfLiteInt8: + EvalQuantized(context, node, data, input1, input2, output); + break; + case kTfLiteFloat32: + EvalFloat(context, node, params, data, input1, input2, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + + return kTfLiteOk; +} +} // namespace mul + +TfLiteRegistration Register_MUL() { + return {/*init=*/mul::Init, + /*free=*/nullptr, + /*prepare=*/mul::Prepare, + /*invoke=*/mul::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/neg.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/neg.cc new file mode 100644 index 0000000..74a95ca --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/neg.cc @@ -0,0 +1,66 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/neg.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace neg { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + switch (input->type) { + // TODO(wangtz): handle for kTfLiteInt8 + case kTfLiteFloat32: + reference_ops::Negate(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace neg + +TfLiteRegistration Register_NEG() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/neg::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pack.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pack.cc new file mode 100644 index 0000000..d332fc6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pack.cc @@ -0,0 +1,127 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace pack { +namespace { + +constexpr int kOutputTensor = 0; + +template +TfLiteStatus PackImpl(TfLiteContext* context, TfLiteNode* node, + TfLiteEvalTensor* output, int values_count, int axis) { + const TfLiteEvalTensor* input0 = + tflite::micro::GetEvalInput(context, node, 0); + + const int dimensions = output->dims->size; + const TfLiteIntArray* input_dims = input0->dims; + const TfLiteIntArray* output_dims = output->dims; + + if (axis < 0) { + axis += dimensions; + } + + int outer_size = 1; + for (int i = 0; i < axis; ++i) { + outer_size *= output_dims->data[i]; + } + int copy_size = 1; + for (int i = axis + 1; i < dimensions; ++i) { + copy_size *= output_dims->data[i]; + } + int input_size = 1; + for (int i = 0; i < input_dims->size; ++i) { + input_size *= input_dims->data[i]; + } + TFLITE_DCHECK_EQ(input_size, copy_size * outer_size); + + T* output_data = tflite::micro::GetTensorData(output); + + for (int i = 0; i < values_count; ++i) { + const TfLiteEvalTensor* t = tflite::micro::GetEvalInput(context, node, i); + const T* input_data = tflite::micro::GetTensorData(t); + for (int k = 0; k < outer_size; ++k) { + const T* input_ptr = input_data + copy_size * k; + int loc = k * values_count * copy_size + i * copy_size; + T* output_ptr = output_data + loc; + for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; + } + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLitePackParams* data = + reinterpret_cast(node->builtin_data); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (output->type) { + case kTfLiteFloat32: { + return PackImpl(context, node, output, data->values_count, + data->axis); + } + case kTfLiteUInt8: { + return PackImpl(context, node, output, data->values_count, + data->axis); + } + case kTfLiteInt8: { + return PackImpl(context, node, output, data->values_count, + data->axis); + } + case kTfLiteInt32: { + return PackImpl(context, node, output, data->values_count, + data->axis); + } + case kTfLiteInt64: { + return PackImpl(context, node, output, data->values_count, + data->axis); + } + default: { + TF_LITE_KERNEL_LOG(context, "Type '%s' is not supported by pack.", + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } + + return kTfLiteOk; +} + +} // namespace +} // namespace pack + +TfLiteRegistration Register_PACK() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/pack::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pad.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pad.cc new file mode 100644 index 0000000..39f86cb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pad.cc @@ -0,0 +1,251 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/pad.h" + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace pad { +namespace { + +struct OpData { + PadParams params; + int32_t output_zero_point; +}; + +} // namespace + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + TF_LITE_ENSURE(context, NumInputs(node) == 2 || NumInputs(node) == 3); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + const TfLiteTensor* input = GetInput(context, node, /*index=*/0); + const TfLiteTensor* paddings = GetInput(context, node, /*index=*/1); + const TfLiteTensor* constant_values = + NumInputs(node) == 3 ? GetInput(context, node, /*index=*/2) : nullptr; + TfLiteTensor* output = GetOutput(context, node, /*index=*/0); + + TF_LITE_ENSURE_EQ(context, input->type, output->type); + + // Current implementations rely on the inputs being <= 4D. + TF_LITE_ENSURE(context, NumDimensions(input) <= + reference_ops::PadKernelMaxDimensionCount()); + + if (constant_values != nullptr) { + TF_LITE_ENSURE_EQ(context, input->type, constant_values->type); + // Ensure that constant_values is a scalar. + TF_LITE_ENSURE_EQ(context, NumElements(constant_values), 1); + } + + // There must be a pair of paddings for each output dimension. + TF_LITE_ENSURE_EQ(context, GetTensorShape(paddings).FlatSize(), + output->dims->size * 2); + + // On Micro, outputs must be properly sized by the converter. + // NOTE: This data is only available because the paddings buffer is stored in + // the flatbuffer: + TF_LITE_ENSURE(context, IsConstantTensor(paddings)); + const int32_t* paddings_data = GetTensorData(paddings); + for (int i = 0; i < output->dims->size; i++) { + int output_dim = output->dims->data[i]; + int expected_dim = + input->dims->data[i] + paddings_data[i * 2] + paddings_data[i * 2 + 1]; + TF_LITE_ENSURE_EQ(context, output_dim, expected_dim); + } + + // Calculate OpData: + data->params.resizing_category = ResizingCategory::kGenericResize; + const int paddings_total = GetTensorShape(paddings).FlatSize(); + if (paddings_total == 8 && (paddings_data[0] == 0 && paddings_data[1] == 0) && + (paddings_data[6] == 0 && paddings_data[7] == 0)) { + data->params.resizing_category = ResizingCategory::kImageStyle; + } + + const int num_input_dimensions = NumDimensions(input); + data->params.left_padding_count = num_input_dimensions; + data->params.right_padding_count = num_input_dimensions; + + for (int idx = num_input_dimensions - 1; idx >= 0; --idx) { + data->params.left_padding[idx] = paddings_data[idx * 2]; + data->params.right_padding[idx] = paddings_data[idx * 2 + 1]; + } + + if (input->type == kTfLiteInt8 || input->type == kTfLiteUInt8) { + if (constant_values == nullptr) { + // Quantized Pad requires that 0 is represented in the quantized + // range. + if (input->type == kTfLiteUInt8) { + TF_LITE_ENSURE(context, output->params.zero_point >= + std::numeric_limits::min()); + TF_LITE_ENSURE(context, output->params.zero_point <= + std::numeric_limits::max()); + } else { + TF_LITE_ENSURE(context, output->params.zero_point >= + std::numeric_limits::min()); + TF_LITE_ENSURE(context, output->params.zero_point <= + std::numeric_limits::max()); + } + } else { + // Quantized Pad requires that 'constant_values' is represented in the + // same quantized range as the input and output tensors. + TF_LITE_ENSURE_EQ(context, output->params.zero_point, + constant_values->params.zero_point); + TF_LITE_ENSURE_EQ(context, static_cast(output->params.scale), + static_cast(constant_values->params.scale)); + } + data->output_zero_point = output->params.zero_point; + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, /*index=*/0); + const TfLiteEvalTensor* constant_values = + NumInputs(node) == 3 + ? tflite::micro::GetEvalInput(context, node, /*index=*/2) + : nullptr; + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, /*index=*/0); + + switch (input->type) { + case kTfLiteFloat32: { + float pad_value = + constant_values == nullptr + ? 0.f + : *tflite::micro::GetTensorData(constant_values); + if (data->params.resizing_category == ResizingCategory::kImageStyle) { + reference_ops::PadImageStyle( + data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), &pad_value, + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Pad(data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + &pad_value, tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } break; + case kTfLiteUInt8: { + uint8_t pad_value; + if (constant_values == nullptr) { + pad_value = static_cast(data->output_zero_point); + } else { + pad_value = *tflite::micro::GetTensorData(constant_values); + } + if (data->params.resizing_category == ResizingCategory::kImageStyle) { + reference_ops::PadImageStyle( + data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), &pad_value, + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Pad(data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + &pad_value, tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } break; + case kTfLiteInt8: { + int8_t pad_value; + if (constant_values == nullptr) { + pad_value = static_cast(data->output_zero_point); + } else { + pad_value = *tflite::micro::GetTensorData(constant_values); + } + if (data->params.resizing_category == ResizingCategory::kImageStyle) { + reference_ops::PadImageStyle( + data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), &pad_value, + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Pad(data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + &pad_value, tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } break; + case kTfLiteInt32: { + int32_t pad_value = + constant_values == nullptr + ? 0 + : *tflite::micro::GetTensorData(constant_values); + reference_ops::Pad(data->params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + &pad_value, tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } break; + default: + + TF_LITE_KERNEL_LOG(context, "Type %s not currently supported by Pad.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } +#undef TF_LITE_PAD + return kTfLiteOk; +} + +} // namespace pad + +TfLiteRegistration Register_PAD() { + return {/*init=*/pad::Init, + /*free=*/nullptr, + /*prepare=*/pad::Prepare, + /*invoke=*/pad::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +// Also register Pad as PadV2. +TfLiteRegistration Register_PADV2() { + return {/*init=*/pad::Init, + /*free=*/nullptr, + /*prepare=*/pad::Prepare, + /*invoke=*/pad::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.cc new file mode 100644 index 0000000..90d48aa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.cc @@ -0,0 +1,267 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/pooling.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace pooling { + +namespace { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +struct OpData { + TfLitePaddingValues padding; + int32_t activation_min; + int32_t activation_max; + float activation_min_f32; + float activation_max_f32; +}; + +TfLiteStatus CalculateOpData(const TfLiteContext* context, + const TfLitePoolParams* params, + const TfLiteTensor* input, + const TfLiteTensor* output, OpData* data) { + // input: batch, height, width, channel + int height = SizeOfDimension(input, 1); + int width = SizeOfDimension(input, 2); + + int out_height, out_width; + + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, + /*dilation_rate_height=*/1, + /*dilation_rate_width=*/1, height, width, params->filter_height, + params->filter_width, params->padding, &out_height, &out_width); + + return kTfLiteOk; +} + +void AverageEvalFloat(const TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, const OpData* data, + const TfLiteEvalTensor* input, TfLiteEvalTensor* output) { + PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data->padding.height; + op_params.padding_values.width = data->padding.width; + op_params.float_activation_min = data->activation_min_f32; + op_params.float_activation_max = data->activation_max_f32; + reference_ops::AveragePool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void AverageEvalQuantized(TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, const OpData* data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output) { + TFLITE_DCHECK(input->type == kTfLiteUInt8 || input->type == kTfLiteInt8); + + PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data->padding.height; + op_params.padding_values.width = data->padding.width; + op_params.quantized_activation_min = data->activation_min; + op_params.quantized_activation_max = data->activation_max; + + if (input->type == kTfLiteUInt8) { + reference_ops::AveragePool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::AveragePool( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +void MaxEvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, const OpData* data, + const TfLiteEvalTensor* input, TfLiteEvalTensor* output) { + tflite::PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data->padding.height; + op_params.padding_values.width = data->padding.width; + op_params.float_activation_min = data->activation_min_f32; + op_params.float_activation_max = data->activation_max_f32; + reference_ops::MaxPool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void MaxEvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, const OpData* data, + const TfLiteEvalTensor* input, TfLiteEvalTensor* output) { + tflite::PoolParams op_params; + op_params.stride_height = params->stride_height; + op_params.stride_width = params->stride_width; + op_params.filter_height = params->filter_height; + op_params.filter_width = params->filter_width; + op_params.padding_values.height = data->padding.height; + op_params.padding_values.width = data->padding.width; + op_params.quantized_activation_min = data->activation_min; + op_params.quantized_activation_max = data->activation_max; + + if (input->type == kTfLiteUInt8) { + reference_ops::MaxPool(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::MaxPool( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} +} // namespace + +TfLiteStatus AverageEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + // Inputs and outputs share the same type, guaranteed by the converter. + switch (input->type) { + case kTfLiteFloat32: + AverageEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteUInt8: + case kTfLiteInt8: + AverageEvalQuantized(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input type %s is not currently supported", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus MaxEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input->type) { + case kTfLiteFloat32: + MaxEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteUInt8: + case kTfLiteInt8: + MaxEvalQuantized(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s not currently supported.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_STATUS(CalculateOpData(context, params, input, output, data)); + + if (input->type == kTfLiteFloat32) { + CalculateActivationRange(params->activation, &data->activation_min_f32, + &data->activation_max_f32); + } else if (input->type == kTfLiteInt8 || input->type == kTfLiteUInt8) { + CalculateActivationRangeQuantized(context, params->activation, output, + &data->activation_min, + &data->activation_max); + } + + return kTfLiteOk; +} + +} // namespace pooling + +TfLiteRegistration Register_AVERAGE_POOL_2D() { + return {/*init=*/pooling::Init, + /*free=*/nullptr, + /*prepare=*/pooling::Prepare, + /*invoke=*/pooling::AverageEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_MAX_POOL_2D() { + return {/*init=*/pooling::Init, + /*free=*/nullptr, + /*prepare=*/pooling::Prepare, + /*invoke=*/pooling::MaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.h new file mode 100644 index 0000000..a80f1f5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/pooling.h @@ -0,0 +1,71 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_POOLING_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_POOLING_H_ + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +extern const int kPoolingInputTensor; +extern const int kPoolingOutputTensor; + +struct OpDataPooling { + TfLitePaddingValues padding; + int32_t activation_min; + int32_t activation_max; + float activation_min_f32; + float activation_max_f32; +}; + +TfLiteStatus CalculateOpDataPooling(const TfLiteContext* context, + const TfLitePoolParams* params, + const TfLiteTensor* input, + const TfLiteTensor* output, + OpDataPooling* data); + +TfLiteStatus PoolingPrepare(TfLiteContext* context, TfLiteNode* node); + +void AveragePoolingEvalFloat(const TfLiteContext* context, + const TfLiteNode* node, + const TfLitePoolParams* params, + const OpDataPooling* data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output); + +void AveragePoolingEvalQuantized(TfLiteContext* context, const TfLiteNode* node, + const TfLitePoolParams* params, + const OpDataPooling* data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output); + +void MaxPoolingEvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, const OpDataPooling* data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output); + +void MaxPoolingEvalQuantized(TfLiteContext* context, TfLiteNode* node, + TfLitePoolParams* params, + const OpDataPooling* data, + const TfLiteEvalTensor* input, + TfLiteEvalTensor* output); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_POOLING_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/prelu.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/prelu.cc new file mode 100644 index 0000000..8665dbc --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/prelu.cc @@ -0,0 +1,166 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/prelu.h" + +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { + +TfLiteStatus CalculatePreluParams(const TfLiteTensor* input, + const TfLiteTensor* alpha, + TfLiteTensor* output, PreluParams* params) { + if (output->type == kTfLiteInt8 || output->type == kTfLiteUInt8 || + output->type == kTfLiteInt16) { + double real_multiplier_1 = static_cast(input->params.scale) / + static_cast(output->params.scale); + double real_multiplier_2 = static_cast(input->params.scale) * + static_cast(alpha->params.scale) / + static_cast(output->params.scale); + QuantizeMultiplier(real_multiplier_1, ¶ms->output_multiplier_1, + ¶ms->output_shift_1); + QuantizeMultiplier(real_multiplier_2, ¶ms->output_multiplier_2, + ¶ms->output_shift_2); + + params->input_offset = -input->params.zero_point; + params->alpha_offset = -alpha->params.zero_point; + params->output_offset = output->params.zero_point; + } + + return kTfLiteOk; +} + +} // namespace + +inline void BroadcastPrelu4DSlowFloat( + const RuntimeShape& unextended_input1_shape, const float* input1_data, + const RuntimeShape& unextended_input2_shape, const float* input2_data, + const RuntimeShape& unextended_output_shape, float* output_data) { + TFLITE_DCHECK_LE(unextended_input1_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_input2_shape.DimensionsCount(), 4); + TFLITE_DCHECK_LE(unextended_output_shape.DimensionsCount(), 4); + const RuntimeShape output_shape = + RuntimeShape::ExtendedShape(4, unextended_output_shape); + + NdArrayDesc<4> desc1; + NdArrayDesc<4> desc2; + NdArrayDescsForElementwiseBroadcast(unextended_input1_shape, + unextended_input2_shape, &desc1, &desc2); + + for (int b = 0; b < output_shape.Dims(0); ++b) { + for (int y = 0; y < output_shape.Dims(1); ++y) { + for (int x = 0; x < output_shape.Dims(2); ++x) { + for (int c = 0; c < output_shape.Dims(3); ++c) { + auto out_idx = Offset(output_shape, b, y, x, c); + auto in1_idx = SubscriptToIndex(desc1, b, y, x, c); + auto in2_idx = SubscriptToIndex(desc2, b, y, x, c); + auto in1_val = input1_data[in1_idx]; + auto in2_val = input2_data[in2_idx]; + output_data[out_idx] = in1_val >= 0.0f ? in1_val : in1_val * in2_val; + } + } + } + } +} + +void* PreluInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(PreluParams)); +} + +TfLiteStatus PreluPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + PreluParams* params = static_cast(node->user_data); + + const TfLiteTensor* input = GetInput(context, node, 0); + const TfLiteTensor* alpha = GetInput(context, node, 1); + TfLiteTensor* output = GetOutput(context, node, 0); + + return CalculatePreluParams(input, alpha, output, params); +} + +TfLiteStatus PreluEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const PreluParams& params = + *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + const TfLiteEvalTensor* alpha = tflite::micro::GetEvalInput(context, node, 1); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + switch (input->type) { + case kTfLiteFloat32: { + BroadcastPrelu4DSlowFloat(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(alpha), + tflite::micro::GetTensorData(alpha), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + case kTfLiteUInt8: { + reference_ops::BroadcastPrelu4DSlow( + params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(alpha), + tflite::micro::GetTensorData(alpha), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + case kTfLiteInt8: { + reference_ops::BroadcastPrelu4DSlow( + params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(alpha), + tflite::micro::GetTensorData(alpha), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + default: + TF_LITE_KERNEL_LOG( + context, "Only float32 and uint8_t are supported currently, got %d.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } +} + +} // namespace activations + +TfLiteRegistration Register_PRELU() { + return {/*init=*/activations::PreluInit, + /*free=*/nullptr, + /*prepare=*/activations::PreluPrepare, + /*invoke=*/activations::PreluEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/quantize.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/quantize.cc new file mode 100644 index 0000000..8323790 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/quantize.cc @@ -0,0 +1,178 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/quantize.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/requantize.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace quantize { + +struct OpData { + tflite::QuantizationParams quantization_params; + // The scaling factor from input to output (aka the 'real multiplier') can + // be represented as a fixed point multiplier plus a left shift. + int32_t output_multiplier; + int output_shift; + + int32_t input_zero_point; +}; + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + const TfLiteTensor* input = GetInput(context, node, 0); + TfLiteTensor* output = GetOutput(context, node, 0); + + // TODO(b/128934713): Add support for fixed-point per-channel quantization. + // Currently this only support affine per-layer quantization. + TF_LITE_ENSURE_EQ(context, output->quantization.type, + kTfLiteAffineQuantization); + const auto* affine_quantization = + reinterpret_cast(output->quantization.params); + TF_LITE_ENSURE(context, affine_quantization); + TF_LITE_ENSURE(context, affine_quantization->scale); + TF_LITE_ENSURE(context, affine_quantization->scale->size == 1); + + TF_LITE_ENSURE(context, input->type == kTfLiteFloat32 || + input->type == kTfLiteInt16 || + input->type == kTfLiteInt8); + TF_LITE_ENSURE(context, + output->type == kTfLiteUInt8 || output->type == kTfLiteInt8); + + if ((input->type == kTfLiteInt16 || input->type == kTfLiteInt8) && + output->type == kTfLiteInt8) { + double effective_scale = + static_cast(input->params.scale / output->params.scale); + + QuantizeMultiplier(effective_scale, &data->output_multiplier, + &data->output_shift); + } + + data->quantization_params.zero_point = output->params.zero_point; + data->quantization_params.scale = static_cast(output->params.scale); + + data->input_zero_point = input->params.zero_point; + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + if (input->type == kTfLiteFloat32) { + switch (output->type) { + case kTfLiteInt8: + reference_ops::AffineQuantize( + data->quantization_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + case kTfLiteUInt8: + reference_ops::AffineQuantize( + data->quantization_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else if (input->type == kTfLiteInt16) { + size_t size = ElementCount(*input->dims); + switch (output->type) { + case kTfLiteInt8: + reference_ops::Requantize(tflite::micro::GetTensorData(input), + size, data->output_multiplier, + data->output_shift, data->input_zero_point, + data->quantization_params.zero_point, + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else if (input->type == kTfLiteInt8) { + // Int8 to Int8 requantization, required if the input and output tensors + // have different scales and/or zero points. + size_t size = ElementCount(*input->dims); + switch (output->type) { + case kTfLiteInt8: + reference_ops::Requantize(tflite::micro::GetTensorData(input), + size, data->output_multiplier, + data->output_shift, data->input_zero_point, + data->quantization_params.zero_point, + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + } else { + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace quantize + +// This Op (QUANTIZE) quantizes the input and produces quantized output. +// AffineQuantize takes scale and zero point and quantizes the float value to +// quantized output, in int8_t or uint8_t format. +TfLiteRegistration Register_QUANTIZE() { + return {/*init=*/quantize::Init, + /*free=*/nullptr, + /*prepare=*/quantize::Prepare, + /*invoke=*/quantize::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reduce.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reduce.cc new file mode 100644 index 0000000..5cae782 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reduce.cc @@ -0,0 +1,139 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/reduce.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace reduce { + +constexpr int kMaxNumberOfAxis = 4; +constexpr int kMaxNumberOfReducedAxis = 2; + +TfLiteStatus PrepareSimple(TfLiteContext* context, TfLiteNode* node) { + // Inputs Tensor (dtype depends on quantization): + // [0] = Input + // [1] = Axis + + // Outputs Tensor (dtype depends on quantization): + // [0] = Output + + // Validate number of inputs and outputs + TF_LITE_ENSURE_EQ(context, node->inputs->size, 2); + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + + // Validate axis type + const TfLiteTensor* axis = GetInput(context, node, 1); + TF_LITE_ENSURE_TYPES_EQ(context, axis->type, kTfLiteInt32); + return kTfLiteOk; +} + +TfLiteStatus PrepareMeanOrSum(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE_OK(context, PrepareSimple(context, node)); + // TODO(b/144955155): Support uint8_t(b/144955155) and int8_t(b/144955018) + return kTfLiteOk; +} + +void ResolveAxis(const int* axis_data, int axis_count, + tflite::MeanParams* op_params) { + int i = 0; + for (; i < axis_count; ++i) { + op_params->axis[i] = static_cast(axis_data[i]); + } + for (; i < 4; ++i) { + op_params->axis[i] = 1; + } + op_params->axis_count = axis_count; +} + +TfLiteStatus EvalMean(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 1); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + TfLiteReducerParams* params = + reinterpret_cast(node->builtin_data); + + int num_axis = static_cast(ElementCount(*axis->dims)); + int temp_index[kMaxNumberOfAxis]; + int resolved_axis[kMaxNumberOfReducedAxis]; + + switch (input->type) { + case kTfLiteFloat32: { + tflite::MeanParams op_params; + ResolveAxis(tflite::micro::GetTensorData(axis), num_axis, + &op_params); + // TODO(b/146571391): Support only 4D Input and 2D Axis for Mean until + // scratch tensor allocation has been implemented in (b/132070898) + bool is_valid_inputs = + (input->dims->size == 4 && op_params.axis_count == 2 && + ((op_params.axis[0] == 1 && op_params.axis[1] == 2) || + (op_params.axis[0] == 2 && op_params.axis[1] == 1))); + TF_LITE_ENSURE_MSG( + context, is_valid_inputs == true, + "Number of Input " + "dimensions != 4 OR the Axis is not either [1, 2] or [2, 1]"); + // TODO(b/139102329): Handle the below special case in the combined + // reference method. + // Defer to specialized implementation for 4D Mean across axes 1 & 2. + if (params->keep_dims) { + reference_ops::Mean(op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + TF_LITE_ENSURE( + context, + reference_ops::Mean( + tflite::micro::GetTensorData(input), input->dims->data, + input->dims->size, tflite::micro::GetTensorData(output), + output->dims->data, output->dims->size, + tflite::micro::GetTensorData(axis), num_axis, + params->keep_dims, temp_index, resolved_axis, + tflite::micro::GetTensorData(output))); + } + } break; + default: + // TODO(b/144955155): Support uint8_t(b/144955155) and int8_t(b/144955018) + TF_LITE_ENSURE_MSG(context, false, + "Currently, only float32 input type " + "is supported."); + } + return kTfLiteOk; +} +} // namespace reduce + +TfLiteRegistration Register_MEAN() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/reduce::PrepareMeanOrSum, + /*invoke=*/reduce::EvalMean, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/add.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/add.cc new file mode 100644 index 0000000..c02a749 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/add.cc @@ -0,0 +1,270 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/add.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/add.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace add { + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + bool requires_broadcast; + + // These fields are used in both the general 8-bit -> 8bit quantized path, + // and the special 16-bit -> 16bit quantized path + int input1_shift; + int input2_shift; + int32_t output_activation_min; + int32_t output_activation_max; + + // These fields are used only in the general 8-bit -> 8bit quantized path + int32_t input1_multiplier; + int32_t input2_multiplier; + int32_t output_multiplier; + int output_shift; + int left_shift; + int32_t input1_offset; + int32_t input2_offset; + int32_t output_offset; + + // Used only for float evals: + float output_activation_min_f32; + float output_activation_max_f32; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteAddParams* params, + const TfLiteTensor* input1, + const TfLiteTensor* input2, TfLiteTensor* output, + OpData* data) { + data->requires_broadcast = !HaveSameShapes(input1, input2); + + if (output->type == kTfLiteInt8 || output->type == kTfLiteInt16) { + // 8bit -> 8bit general quantized path, with general rescalings + data->input1_offset = -input1->params.zero_point; + data->input2_offset = -input2->params.zero_point; + data->output_offset = output->params.zero_point; + data->left_shift = (output->type == kTfLiteInt16) ? 15 : 20; + const double twice_max_input_scale = + 2 * static_cast( + std::max(input1->params.scale, input2->params.scale)); + const double real_input1_multiplier = + static_cast(input1->params.scale) / twice_max_input_scale; + const double real_input2_multiplier = + static_cast(input2->params.scale) / twice_max_input_scale; + const double real_output_multiplier = + twice_max_input_scale / + ((1 << data->left_shift) * static_cast(output->params.scale)); + + QuantizeMultiplierSmallerThanOneExp( + real_input1_multiplier, &data->input1_multiplier, &data->input1_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_input2_multiplier, &data->input2_multiplier, &data->input2_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_output_multiplier, &data->output_multiplier, &data->output_shift); + + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + } else if (output->type == kTfLiteFloat32) { + CalculateActivationRange(params->activation, + &data->output_activation_min_f32, + &data->output_activation_max_f32); + } + + return kTfLiteOk; +} + +void EvalAdd(TfLiteContext* context, TfLiteNode* node, TfLiteAddParams* params, + const OpData* data, const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params; + SetActivationParams(data->output_activation_min_f32, + data->output_activation_max_f32, &op_params); + if (data->requires_broadcast) { + reference_ops::BroadcastAdd4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Add(op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +TfLiteStatus EvalAddQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteAddParams* params, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params; + op_params.left_shift = data->left_shift; + op_params.input1_offset = data->input1_offset; + op_params.input1_multiplier = data->input1_multiplier; + op_params.input1_shift = data->input1_shift; + op_params.input2_offset = data->input2_offset; + op_params.input2_multiplier = data->input2_multiplier; + op_params.input2_shift = data->input2_shift; + op_params.output_offset = data->output_offset; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + SetActivationParams(data->output_activation_min, data->output_activation_max, + &op_params); + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + switch (output->type) { + case kTfLiteInt8: { + if (need_broadcast) { + reference_integer_ops::BroadcastAdd4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::Add( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + break; + } + case kTfLiteInt16: { + if (need_broadcast) { + reference_ops::BroadcastAdd4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Add(op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + false); + } + break; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + const TfLiteTensor* input1 = GetInput(context, node, kInputTensor1); + TF_LITE_ENSURE(context, input1 != nullptr); + const TfLiteTensor* input2 = GetInput(context, node, kInputTensor2); + TF_LITE_ENSURE(context, input2 != nullptr); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE(context, output != nullptr); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + TF_LITE_ENSURE_STATUS( + CalculateOpData(context, params, input1, input2, output, data)); + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + if (output->type == kTfLiteFloat32) { + EvalAdd(context, node, params, data, input1, input2, output); + } else if (output->type == kTfLiteInt8 || output->type == kTfLiteInt16) { + TF_LITE_ENSURE_OK(context, EvalAddQuantized(context, node, params, data, + input1, input2, output)); + } else { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace add + +TfLiteRegistration Register_ADD() { + return {/*init=*/add::Init, + /*free=*/nullptr, + /*prepare=*/add::Prepare, + /*invoke=*/add::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/conv.cc new file mode 100644 index 0000000..0fed122 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/conv.cc @@ -0,0 +1,123 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/conv.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/conv.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/conv.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace { + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpDataConv)); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kConvInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kConvWeightsTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kConvBiasTensor) + : nullptr; + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kConvOutputTensor); + + TFLITE_DCHECK(node->builtin_data != nullptr); + const auto& params = + *(reinterpret_cast(node->builtin_data)); + TFLITE_DCHECK(node->user_data != nullptr); + const auto& data = *(static_cast(node->user_data)); + + TF_LITE_ENSURE_EQ(context, input->type, output->type); + TF_LITE_ENSURE_MSG( + context, + input->type == filter->type || + (input->type == kTfLiteInt16 && filter->type == kTfLiteInt8), + "Hybrid models are not supported on TFLite Micro."); + + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: { + tflite::reference_ops::Conv( + ConvParamsFloat(params, data), tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output), + tflite::micro::GetTensorShape(nullptr), nullptr); + break; + } + case kTfLiteInt16: { + reference_integer_ops::ConvPerChannel( + ConvParamsQuantized(params, data), data.per_channel_output_multiplier, + data.per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + case kTfLiteInt8: { + reference_integer_ops::ConvPerChannel( + ConvParamsQuantized(params, data), data.per_channel_output_multiplier, + data.per_channel_output_shift, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace + +TfLiteRegistration Register_CONV_2D() { + return {/*init=*/Init, + /*free=*/nullptr, + /*prepare=*/ConvPrepare, + /*invoke=*/Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/depthwise_conv.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/depthwise_conv.cc new file mode 100644 index 0000000..8a58433 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/depthwise_conv.cc @@ -0,0 +1,105 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/depthwise_conv.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/padding.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace { + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpDataConv)); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto& params = + *(reinterpret_cast(node->builtin_data)); + const OpDataConv& data = *(static_cast(node->user_data)); + + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kDepthwiseConvOutputTensor); + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kDepthwiseConvInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kDepthwiseConvWeightsTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 3) + ? tflite::micro::GetEvalInput(context, node, kDepthwiseConvBiasTensor) + : nullptr; + + switch (input->type) { // Already know in/out types are same. + case kTfLiteFloat32: { + tflite::reference_ops::DepthwiseConv( + DepthwiseConvParamsFloat(params, data), + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + case kTfLiteInt8: { + reference_integer_ops::DepthwiseConvPerChannel( + DepthwiseConvParamsQuantized(params, data), + data.per_channel_output_multiplier, data.per_channel_output_shift, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace + +TfLiteRegistration Register_DEPTHWISE_CONV_2D() { + return {/*init=*/Init, + /*free=*/nullptr, + /*prepare=*/DepthwiseConvPrepare, + /*invoke=*/Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/fully_connected.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/fully_connected.cc new file mode 100644 index 0000000..554aebb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/fully_connected.cc @@ -0,0 +1,134 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/fully_connected.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/fully_connected.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace { + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, + sizeof(OpDataFullyConnected)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + auto* data = static_cast(node->user_data); + const auto params = + static_cast(node->builtin_data); + + const TfLiteTensor* input = + GetInput(context, node, kFullyConnectedInputTensor); + TF_LITE_ENSURE(context, input != nullptr); + const TfLiteTensor* filter = + GetInput(context, node, kFullyConnectedWeightsTensor); + TF_LITE_ENSURE(context, filter != nullptr); + const TfLiteTensor* bias = + GetOptionalInputTensor(context, node, kFullyConnectedBiasTensor); + TfLiteTensor* output = GetOutput(context, node, kFullyConnectedOutputTensor); + TF_LITE_ENSURE(context, output != nullptr); + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + TF_LITE_ENSURE_MSG(context, input->type == filter->type, + "Hybrid models are not supported on TFLite Micro."); + + return CalculateOpDataFullyConnected(context, params->activation, input->type, + input, filter, bias, output, data); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + const auto* params = + static_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kFullyConnectedInputTensor); + const TfLiteEvalTensor* filter = + tflite::micro::GetEvalInput(context, node, kFullyConnectedWeightsTensor); + const TfLiteEvalTensor* bias = + tflite::micro::GetEvalInput(context, node, kFullyConnectedBiasTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kFullyConnectedOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const auto& data = + *(static_cast(node->user_data)); + + // Checks in Prepare ensure input, output and filter types are all the same. + switch (input->type) { + case kTfLiteFloat32: { + tflite::reference_ops::FullyConnected( + FullyConnectedParamsFloat(params->activation), + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + + case kTfLiteInt8: { + tflite::reference_integer_ops::FullyConnected( + FullyConnectedParamsQuantized(data), + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(filter), + tflite::micro::GetTensorData(filter), + tflite::micro::GetTensorShape(bias), + tflite::micro::GetTensorData(bias), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + } + + default: { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + } + return kTfLiteOk; +} + +} // namespace + +TfLiteRegistration Register_FULLY_CONNECTED() { + return {/*init=*/Init, + /*free=*/nullptr, + /*prepare=*/Prepare, + /*invoke=*/Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/mul.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/mul.cc new file mode 100644 index 0000000..1eaee5e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/mul.cc @@ -0,0 +1,214 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/mul.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/integer_ops/mul.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace mul { +namespace { + +constexpr int kInput1Tensor = 0; +constexpr int kInput2Tensor = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + int32_t input1_zero_point; + int32_t input2_zero_point; + + int32_t output_activation_min; + int32_t output_activation_max; + int32_t output_zero_point; + int32_t output_multiplier; + int output_shift; + + float output_activation_min_f32; + float output_activation_max_f32; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, OpData* data) { + const TfLiteTensor* input1 = GetInput(context, node, kInput1Tensor); + TF_LITE_ENSURE(context, input1 != nullptr); + const TfLiteTensor* input2 = GetInput(context, node, kInput2Tensor); + TF_LITE_ENSURE(context, input2 != nullptr); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE(context, output != nullptr); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 2); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + TF_LITE_ENSURE_TYPES_EQ(context, input1->type, input2->type); + + if (output->type == kTfLiteInt8) { + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + + double real_multiplier = static_cast(input1->params.scale) * + static_cast(input2->params.scale) / + static_cast(output->params.scale); + QuantizeMultiplier(real_multiplier, &data->output_multiplier, + &data->output_shift); + + data->input1_zero_point = input1->params.zero_point; + data->input2_zero_point = input2->params.zero_point; + data->output_zero_point = output->params.zero_point; + } else { + CalculateActivationRange(params->activation, + &data->output_activation_min_f32, + &data->output_activation_max_f32); + } + + return kTfLiteOk; +} + +} // namespace + +void EvalQuantized(TfLiteContext* context, TfLiteNode* node, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params = {}; + op_params.quantized_activation_min = data->output_activation_min; + op_params.quantized_activation_max = data->output_activation_max; + op_params.float_activation_max = data->output_activation_max_f32; + op_params.input1_offset = -data->input1_zero_point; + op_params.input2_offset = -data->input2_zero_point; + op_params.output_offset = data->output_zero_point; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + if (need_broadcast) { + reference_integer_ops::BroadcastMul4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_integer_ops::Mul(op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +void EvalFloat(TfLiteContext* context, TfLiteNode* node, + TfLiteMulParams* params, const OpData* data, + const TfLiteEvalTensor* input1, const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + tflite::ArithmeticParams op_params = {}; + op_params.float_activation_min = data->output_activation_min_f32; + op_params.float_activation_max = data->output_activation_max_f32; + + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + if (need_broadcast) { + reference_ops::BroadcastMul4DSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + reference_ops::Mul(op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + return CalculateOpData(context, node, params, data); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData* data = static_cast(node->user_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInput1Tensor); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInput2Tensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (input1->type) { + case kTfLiteInt8: + EvalQuantized(context, node, data, input1, input2, output); + break; + case kTfLiteFloat32: + EvalFloat(context, node, params, data, input1, input2, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input1->type), input1->type); + return kTfLiteError; + } + + return kTfLiteOk; +} +} // namespace mul + +TfLiteRegistration Register_MUL() { + return {/*init=*/mul::Init, + /*free=*/nullptr, + /*prepare=*/mul::Prepare, + /*invoke=*/mul::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/pooling.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/pooling.cc new file mode 100644 index 0000000..b378163 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/pooling.cc @@ -0,0 +1,112 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/pooling.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/pooling.h" + +namespace tflite { + +namespace { + +TfLiteStatus AverageEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpDataPooling* data = + static_cast(node->user_data); + + const TfLiteEvalTensor* input = + micro::GetEvalInput(context, node, kPoolingInputTensor); + TfLiteEvalTensor* output = + micro::GetEvalOutput(context, node, kPoolingOutputTensor); + + // Inputs and outputs share the same type, guaranteed by the converter. + switch (input->type) { + case kTfLiteFloat32: + AveragePoolingEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteInt8: + AveragePoolingEvalQuantized(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Input type %s is not currently supported", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus MaxEval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + auto* params = reinterpret_cast(node->builtin_data); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpDataPooling* data = + static_cast(node->user_data); + + const TfLiteEvalTensor* input = + micro::GetEvalInput(context, node, kPoolingInputTensor); + TfLiteEvalTensor* output = + micro::GetEvalOutput(context, node, kPoolingOutputTensor); + + switch (input->type) { + case kTfLiteFloat32: + MaxPoolingEvalFloat(context, node, params, data, input, output); + break; + case kTfLiteInt8: + MaxPoolingEvalQuantized(context, node, params, data, input, output); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s not currently supported.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpDataPooling)); +} + +} // namespace + +TfLiteRegistration Register_AVERAGE_POOL_2D() { + return {/*init=*/Init, + /*free=*/nullptr, + /*prepare=*/PoolingPrepare, + /*invoke=*/AverageEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +TfLiteRegistration Register_MAX_POOL_2D() { + return {/*init=*/Init, + /*free=*/nullptr, + /*prepare=*/PoolingPrepare, + /*invoke=*/MaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/softmax.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/softmax.cc new file mode 100644 index 0000000..f6a3001 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reference/softmax.cc @@ -0,0 +1,96 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/kernels/softmax.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/softmax.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace { + +void SoftmaxQuantized(const TfLiteEvalTensor* input, TfLiteEvalTensor* output, + const SoftmaxParams& op_data) { + if (input->type == kTfLiteInt8) { + if (output->type == kTfLiteInt16) { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } else { + tflite::reference_ops::SoftmaxInt16( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + TFLITE_DCHECK(node->user_data != nullptr); + SoftmaxParams op_data = *static_cast(node->user_data); + + switch (input->type) { + case kTfLiteFloat32: { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } + case kTfLiteInt8: + case kTfLiteInt16: { + SoftmaxQuantized(input, output, op_data); + return kTfLiteOk; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } +} +} // namespace + +TfLiteRegistration Register_SOFTMAX() { + return {/*init=*/SoftmaxInit, + /*free=*/nullptr, + /*prepare=*/SoftmaxPrepare, + /*invoke=*/SoftmaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reshape.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reshape.cc new file mode 100644 index 0000000..a865892 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/reshape.cc @@ -0,0 +1,116 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/memory_helpers.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace reshape { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +TfLiteStatus ReshapeOutput(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + // Tensorflow's Reshape allows one of the shape components to have the + // special -1 value, meaning it will be calculated automatically based on the + // input. Here we calculate what that dimension should be so that the number + // of output elements in the same as the number of input elements. + int num_input_elements = NumElements(input); + TfLiteIntArray* output_shape = output->dims; + + if (NumInputs(node) == 1 && // Legacy scalar supported with params. + output_shape->size == 1 && output_shape->data[0] == 0) { + // Legacy tflite models use a shape parameter of [0] to indicate scalars, + // so adjust accordingly. TODO(b/111614235): Allow zero-sized buffers during + // toco conversion. + output_shape->size = 0; + } + + int num_output_elements = 1; + int stretch_dim = -1; + for (int i = 0; i < output_shape->size; ++i) { + int value = output_shape->data[i]; + if (value == -1) { + TF_LITE_ENSURE_EQ(context, stretch_dim, -1); + stretch_dim = i; + } else { + num_output_elements *= value; + } + } + if (stretch_dim != -1) { + output_shape->data[stretch_dim] = num_input_elements / num_output_elements; + num_output_elements *= output_shape->data[stretch_dim]; + } + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + TF_LITE_ENSURE_EQ(context, num_input_elements, num_output_elements); + return kTfLiteOk; +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE(context, NumInputs(node) == 1 || NumInputs(node) == 2); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + TF_LITE_ENSURE_EQ(context, ReshapeOutput(context, node), kTfLiteOk); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + // TODO(b/162522304): storing input bytes in OpData increases some models + // significantly, possibly due to alignment issues. + size_t input_bytes; + TF_LITE_ENSURE_STATUS(TfLiteTypeSizeOf(input->type, &input_bytes)); + input_bytes *= ElementCount(*input->dims); + + // Do nothing for in-place reshape. + if (input->data.raw != output->data.raw) { + // Otherwise perform reshape with copy. + for (size_t i = 0; i < input_bytes; ++i) { + output->data.raw[i] = input->data.raw[i]; + } + } + return kTfLiteOk; +} + +} // namespace reshape + +TfLiteRegistration Register_RESHAPE() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/reshape::Prepare, + /*invoke=*/reshape::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc new file mode 100644 index 0000000..222cb3a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc @@ -0,0 +1,123 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace resize_nearest_neighbor { + +constexpr int kInputTensor = 0; +constexpr int kSizeTensor = 1; +constexpr int kOutputTensor = 0; + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { +#if defined(DEBUG) + TF_LITE_ENSURE_EQ(context, NumInputs(node), 2); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* size = GetInput(context, node, kSizeTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + // Our current implementations rely on the input being 4D, + // and the size being 1D tensor with exactly 2 elements. + TF_LITE_ENSURE_EQ(context, NumDimensions(input), 4); + TF_LITE_ENSURE_EQ(context, NumDimensions(size), 1); + TF_LITE_ENSURE_EQ(context, size->type, kTfLiteInt32); + TF_LITE_ENSURE_EQ(context, size->dims->data[0], 2); + + output->type = input->type; + + if (!IsConstantTensor(size)) { + TF_LITE_KERNEL_LOG(context, "Dynamic tensors are unsupported in tfmicro."); + return kTfLiteError; + } +#endif + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = + reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* size = + tflite::micro::GetEvalInput(context, node, kSizeTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + tflite::ResizeNearestNeighborParams op_params; + op_params.align_corners = params->align_corners; + op_params.half_pixel_centers = false; + + if (output->type == kTfLiteFloat32) { + reference_ops::ResizeNearestNeighbor( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(size), + tflite::micro::GetTensorData(size), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else if (output->type == kTfLiteUInt8) { + reference_ops::ResizeNearestNeighbor( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(size), + tflite::micro::GetTensorData(size), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else if (output->type == kTfLiteInt8) { + reference_ops::ResizeNearestNeighbor( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(size), + tflite::micro::GetTensorData(size), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + TF_LITE_KERNEL_LOG(context, + "Output type is %d, requires float, uint8_t or int8_t.", + output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} +} // namespace resize_nearest_neighbor + +TfLiteRegistration Register_RESIZE_NEAREST_NEIGHBOR() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/resize_nearest_neighbor::Prepare, + /*invoke=*/resize_nearest_neighbor::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/round.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/round.cc new file mode 100644 index 0000000..7b4adfc --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/round.cc @@ -0,0 +1,74 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/round.h" + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace round { + +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32); + TF_LITE_ENSURE_TYPES_EQ(context, output->type, input->type); + TF_LITE_ENSURE_EQ(context, output->bytes, input->bytes); + TF_LITE_ENSURE_EQ(context, output->dims->size, input->dims->size); + for (int i = 0; i < output->dims->size; ++i) { + TF_LITE_ENSURE_EQ(context, output->dims->data[i], input->dims->data[i]); + } + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + reference_ops::Round(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + + return kTfLiteOk; +} +} // namespace round + +TfLiteRegistration Register_ROUND() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/round::Prepare, + /*invoke=*/round::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.cc new file mode 100644 index 0000000..e85c1a4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.cc @@ -0,0 +1,169 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/softmax.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { + +TfLiteStatus CalculateSoftmaxParams(TfLiteContext* context, + const TfLiteTensor* input, + TfLiteTensor* output, + const TfLiteSoftmaxParams* params, + SoftmaxParams* op_data) { + if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) { + if (input->type == kTfLiteUInt8) { + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteUInt8); + TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0); + } else { + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteInt8); + if (output->type == kTfLiteInt16) { + TF_LITE_ENSURE_EQ(context, output->params.zero_point, -32768); + // NOTE: Current int16_t softmax output does not require symmetric + // scaling + // - so no need to verify scale here. + } else { + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteInt8); + TF_LITE_ENSURE_EQ(context, output->params.zero_point, -128); + TF_LITE_ENSURE(context, output->params.scale == 1.f / 256); + } + } + + static const int kScaledDiffIntegerBits = 5; + + int input_left_shift; + tflite::PreprocessSoftmaxScaling( + static_cast(params->beta), + static_cast(input->params.scale), kScaledDiffIntegerBits, + &op_data->input_multiplier, &input_left_shift); + op_data->input_left_shift = input_left_shift; + op_data->diff_min = + -1.0 * tflite::CalculateInputRadius(kScaledDiffIntegerBits, + op_data->input_left_shift); + } else { + TF_LITE_ENSURE_TYPES_EQ(context, input->type, kTfLiteFloat32); + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32); + op_data->beta = static_cast(params->beta); + } + return kTfLiteOk; +} + +} // namespace + +// Takes a tensor and performs softmax along the last dimension. +void SoftmaxFloat(const TfLiteEvalTensor* input, TfLiteEvalTensor* output, + const SoftmaxParams& op_data) { + tflite::reference_ops::Softmax(op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); +} + +void SoftmaxQuantized(const TfLiteEvalTensor* input, TfLiteEvalTensor* output, + const SoftmaxParams& op_data) { + if (input->type == kTfLiteUInt8) { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + if (output->type == kTfLiteInt16) { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + tflite::reference_ops::Softmax( + op_data, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } +} + +void* SoftmaxInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(SoftmaxParams)); +} + +TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node) { + auto* params = static_cast(node->builtin_data); + + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + const TfLiteTensor* input = GetInput(context, node, 0); + TF_LITE_ENSURE(context, NumDimensions(input) >= 1); + + TfLiteTensor* output = GetOutput(context, node, 0); + + TFLITE_DCHECK(node->user_data != nullptr); + SoftmaxParams* data = static_cast(node->user_data); + return CalculateSoftmaxParams(context, input, output, params, data); +} + +TfLiteStatus SoftmaxEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + TfLiteEvalTensor* output = tflite::micro::GetEvalOutput(context, node, 0); + + TFLITE_DCHECK(node->user_data != nullptr); + SoftmaxParams* data = static_cast(node->user_data); + + switch (input->type) { + case kTfLiteFloat32: { + SoftmaxFloat(input, output, *data); + return kTfLiteOk; + } + case kTfLiteInt8: + case kTfLiteUInt8: { + SoftmaxQuantized(input, output, *data); + return kTfLiteOk; + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } +} +} // namespace activations + +TfLiteRegistration Register_SOFTMAX() { + return {/*init=*/activations::SoftmaxInit, + /*free=*/nullptr, + /*prepare=*/activations::SoftmaxPrepare, + /*invoke=*/activations::SoftmaxEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.h b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.h new file mode 100644 index 0000000..8d605ea --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/softmax.h @@ -0,0 +1,45 @@ +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_KERNELS_SOFTMAX_H_ +#define TENSORFLOW_LITE_MICRO_KERNELS_SOFTMAX_H_ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/types.h" + +namespace tflite { + +void* SoftmaxInit(TfLiteContext* context, const char* buffer, size_t length); + +TfLiteStatus SoftmaxPrepare(TfLiteContext* context, TfLiteNode* node); + +// This is the most generic TfLiteRegistration. The actual supported types may +// still be target dependent. The only requirement is that every implementation +// (reference or optimized) must define this function. +TfLiteRegistration Register_SOFTMAX(); + +#if defined(XTENSA) +// Returns a TfLiteRegistration struct for kernel variant that only supports +// int8 input and int16 output. +TfLiteRegistration Register_SOFTMAX_INT8_INT16(); +#else +inline TfLiteRegistration Register_SOFTMAX_INT8_INT16() { + return Register_SOFTMAX(); +} +#endif + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_KERNELS_SOFTMAX_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/split.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/split.cc new file mode 100644 index 0000000..9bff0b7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/split.cc @@ -0,0 +1,134 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace split { + +template +TfLiteStatus SplitImpl(TfLiteContext* context, TfLiteNode* node, + const TfLiteEvalTensor* input, int axis_value) { + const int output_count = NumOutputs(node); + const TfLiteIntArray* input_dims = input->dims; + const TfLiteEvalTensor* output0 = + tflite::micro::GetEvalOutput(context, node, 0); + const TfLiteIntArray* output_dims = output0->dims; + + const int split_dimensions = input_dims->size; + int axis = axis_value < 0 ? axis_value + split_dimensions : axis_value; + + TFLITE_DCHECK_LT(axis, split_dimensions); + TFLITE_DCHECK_EQ(output_dims->size, split_dimensions); + + int64_t split_size = output_dims->data[axis] * output_count; + + TFLITE_DCHECK_EQ(split_size, input_dims->data[axis]); + int64_t outer_size = 1; + for (int i = 0; i < axis; ++i) { + outer_size *= input_dims->data[i]; + } + + int64_t base_inner_size = 1; + for (int i = axis + 1; i < split_dimensions; ++i) { + base_inner_size *= input_dims->data[i]; + } + + const T* input_ptr = tflite::micro::GetTensorData(input); + for (int k = 0; k < outer_size; ++k) { + for (int i = 0; i < output_count; ++i) { + TfLiteEvalTensor* t = tflite::micro::GetEvalOutput(context, node, i); + T* output_data = tflite::micro::GetTensorData(t); + const int copy_size = output_dims->data[axis] * base_inner_size; + T* output_ptr = output_data + k * copy_size; + for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; + input_ptr += copy_size; + } + } + + return kTfLiteOk; +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* axis = GetInput(context, node, 0); + + // Dynamic output tensors are needed if axis tensor is not constant. + // But Micro doesn't support dynamic memory allocation, so we only support + // constant axis tensor for now. + TF_LITE_ENSURE_MSG(context, IsConstantTensor(axis), + "Non constant axis tensor not supported"); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 0); + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 1); + + int axis_value = tflite::micro::GetTensorData(axis)[0]; + if (axis_value < 0) { + axis_value += input->dims->size; + } + + TF_LITE_ENSURE(context, axis_value >= 0); + TF_LITE_ENSURE(context, axis_value < input->dims->size); + + switch (input->type) { + case kTfLiteFloat32: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteUInt8: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt8: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt16: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt32: { + return SplitImpl(context, node, input, axis_value); + } + default: + TF_LITE_KERNEL_LOG(context, "Type %s currently not supported.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } +#undef TF_LITE_SPLIT + + return kTfLiteOk; +} + +} // namespace split + +TfLiteRegistration Register_SPLIT() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/split::Prepare, + /*invoke=*/split::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/strided_slice.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/strided_slice.cc new file mode 100644 index 0000000..2dbe6e1 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/strided_slice.cc @@ -0,0 +1,192 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/kernels/internal/reference/strided_slice.h" + +#include +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace strided_slice { + +constexpr int kInputTensor = 0; +constexpr int kBeginTensor = 1; +constexpr int kEndTensor = 2; +constexpr int kStridesTensor = 3; +constexpr int kOutputTensor = 0; + +struct StridedSliceContext { + StridedSliceContext(TfLiteContext* context, TfLiteNode* node) { + params = reinterpret_cast(node->builtin_data); + input = GetInput(context, node, kInputTensor); + begin = GetInput(context, node, kBeginTensor); + end = GetInput(context, node, kEndTensor); + strides = GetInput(context, node, kStridesTensor); + output = GetOutput(context, node, kOutputTensor); + dims = NumDimensions(input); + } + const TfLiteStridedSliceParams* params; + const TfLiteTensor* input; + const TfLiteTensor* begin; + const TfLiteTensor* end; + const TfLiteTensor* strides; + TfLiteTensor* output; + int dims; +}; + +// This Op only supports 1-4D cases and since we use the reference 4D +// implementation, the 1-3D tensors are mapped to 4D. +const int kMaxDim = 4; + +tflite::StridedSliceParams BuildStridedSliceParams( + StridedSliceContext* op_context) { + tflite::StridedSliceParams op_params; + op_params.start_indices_count = op_context->dims; + op_params.stop_indices_count = op_context->dims; + op_params.strides_count = op_context->dims; + + for (int i = 0; i < op_context->dims; ++i) { + op_params.start_indices[i] = GetTensorData(op_context->begin)[i]; + op_params.stop_indices[i] = GetTensorData(op_context->end)[i]; + op_params.strides[i] = GetTensorData(op_context->strides)[i]; + } + + op_params.begin_mask = op_context->params->begin_mask; + op_params.ellipsis_mask = 0; + op_params.end_mask = op_context->params->end_mask; + op_params.new_axis_mask = 0; + op_params.shrink_axis_mask = op_context->params->shrink_axis_mask; + return op_params; +} + +// Processes the indexing tensors (begin, end and strides) to resize the +// output tensor. This function is callable from both Prepare() and Eval() as +// long as the caller ensures the indexing tensors are present. +TfLiteStatus CheckOutputSize(TfLiteContext* context, + StridedSliceContext* op_context) { + using ::tflite::strided_slice::StartForAxis; + using ::tflite::strided_slice::StopForAxis; + TfLiteIntArray* output_shape = op_context->output->dims; + int shape_size = 0; + auto op_params = BuildStridedSliceParams(op_context); + auto input_shape = GetTensorShape(op_context->input); + for (int idx = 0; idx < op_context->dims; ++idx) { + int32_t stride = GetTensorData(op_context->strides)[idx]; + TF_LITE_ENSURE_MSG(context, stride != 0, "stride value has to be non-zero"); + int32_t begin = StartForAxis(op_params, input_shape, idx); + int32_t end = StopForAxis(op_params, input_shape, idx, begin); + + // When shrinking an axis, the end position does not matter (and can be + // incorrect when negative indexing is used, see Issue #19260). Always use + // begin + 1 to generate a length 1 slice, since begin has + // already been adjusted for negative indices by StartForAxis. + const bool shrink_axis = op_context->params->shrink_axis_mask & (1 << idx); + if (shrink_axis) { + end = begin + 1; + } + + // This is valid for both positive and negative strides + int32_t dim_shape = std::ceil((end - begin) / static_cast(stride)); + dim_shape = dim_shape < 0 ? 0 : dim_shape; + if (!shrink_axis) { + TF_LITE_ENSURE_EQ(context, output_shape->data[shape_size], dim_shape); + shape_size++; + } + } + TF_LITE_ENSURE_EQ(context, output_shape->size, shape_size); + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(StridedSliceParams)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + StridedSliceParams* op_params = + static_cast(node->user_data); + TF_LITE_ENSURE_EQ(context, NumInputs(node), 4); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + StridedSliceContext op_context(context, node); + TF_LITE_ENSURE_MSG(context, op_context.dims <= kMaxDim, + "input dim should not exceed 4"); + auto params = BuildStridedSliceParams(&op_context); + memcpy(op_params, ¶ms, sizeof(StridedSliceParams)); + return CheckOutputSize(context, &op_context); +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + const StridedSliceParams& op_params = + *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + switch (output->type) { + case kTfLiteFloat32: + reference_ops::StridedSlice(op_params, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + case kTfLiteUInt8: + reference_ops::StridedSlice( + op_params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + case kTfLiteInt8: + reference_ops::StridedSlice(op_params, + tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + break; + default: + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(input->type), input->type); + return kTfLiteError; + } + return kTfLiteOk; +} +} // namespace strided_slice + +TfLiteRegistration Register_STRIDED_SLICE() { + return {/*init=*/strided_slice::Init, + /*free=*/nullptr, + /*prepare=*/strided_slice::Prepare, + /*invoke=*/strided_slice::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/sub.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/sub.cc new file mode 100644 index 0000000..8ba1594 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/sub.cc @@ -0,0 +1,253 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/sub.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/internal/types.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace sub { + +constexpr int kInputTensor1 = 0; +constexpr int kInputTensor2 = 1; +constexpr int kOutputTensor = 0; + +struct OpData { + bool requires_broadcast; + + // These fields are used in both the general 8-bit -> 8bit quantized path, + // and the special 16-bit -> 16bit quantized path + int input1_shift; + int input2_shift; + int32_t output_activation_min; + int32_t output_activation_max; + + // These fields are used only in the general 8-bit -> 8bit quantized path + int32_t input1_multiplier; + int32_t input2_multiplier; + int32_t output_multiplier; + int output_shift; + int left_shift; + int32_t input1_offset; + int32_t input2_offset; + int32_t output_offset; +}; + +TfLiteStatus CalculateOpData(TfLiteContext* context, TfLiteSubParams* params, + const TfLiteTensor* input1, + const TfLiteTensor* input2, TfLiteTensor* output, + OpData* data) { + data->requires_broadcast = !HaveSameShapes(input1, input2); + + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + // 8bit -> 8bit general quantized path, with general rescalings + data->input1_offset = -input1->params.zero_point; + data->input2_offset = -input2->params.zero_point; + data->output_offset = output->params.zero_point; + data->left_shift = 20; + const float twice_max_input_scale = + 2 * std::max(input1->params.scale, input2->params.scale); + const double real_input1_multiplier = + static_cast(input1->params.scale / twice_max_input_scale); + const double real_input2_multiplier = + static_cast(input2->params.scale / twice_max_input_scale); + const double real_output_multiplier = + static_cast(twice_max_input_scale / + ((1 << data->left_shift) * output->params.scale)); + + QuantizeMultiplierSmallerThanOneExp( + real_input1_multiplier, &data->input1_multiplier, &data->input1_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_input2_multiplier, &data->input2_multiplier, &data->input2_shift); + + QuantizeMultiplierSmallerThanOneExp( + real_output_multiplier, &data->output_multiplier, &data->output_shift); + + TF_LITE_ENSURE_STATUS(CalculateActivationRangeQuantized( + context, params->activation, output, &data->output_activation_min, + &data->output_activation_max)); + } + + return kTfLiteOk; +} + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + TFLITE_DCHECK(node->builtin_data != nullptr); + + OpData* data = static_cast(node->user_data); + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteTensor* input1 = GetInput(context, node, kInputTensor1); + const TfLiteTensor* input2 = GetInput(context, node, kInputTensor2); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_STATUS( + CalculateOpData(context, params, input1, input2, output, data)); + return kTfLiteOk; +} + +void EvalSub(TfLiteContext* context, TfLiteNode* node, TfLiteSubParams* params, + const OpData* data, const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, TfLiteEvalTensor* output) { + float output_activation_min, output_activation_max; + CalculateActivationRange(params->activation, &output_activation_min, + &output_activation_max); + tflite::ArithmeticParams op_params; + SetActivationParams(output_activation_min, output_activation_max, &op_params); + if (data->requires_broadcast) { + tflite::reference_ops::BroadcastSubSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + tflite::reference_ops::SubWithActivation( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } +} + +TfLiteStatus EvalSubQuantized(TfLiteContext* context, TfLiteNode* node, + TfLiteSubParams* params, const OpData* data, + const TfLiteEvalTensor* input1, + const TfLiteEvalTensor* input2, + TfLiteEvalTensor* output) { + if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + tflite::ArithmeticParams op_params; + op_params.left_shift = data->left_shift; + op_params.input1_offset = data->input1_offset; + op_params.input1_multiplier = data->input1_multiplier; + op_params.input1_shift = data->input1_shift; + op_params.input2_offset = data->input2_offset; + op_params.input2_multiplier = data->input2_multiplier; + op_params.input2_shift = data->input2_shift; + op_params.output_offset = data->output_offset; + op_params.output_multiplier = data->output_multiplier; + op_params.output_shift = data->output_shift; + SetActivationParams(data->output_activation_min, + data->output_activation_max, &op_params); + bool need_broadcast = reference_ops::ProcessBroadcastShapes( + tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorShape(input2), &op_params); + + if (output->type == kTfLiteInt8) { + if (need_broadcast) { + tflite::reference_ops::BroadcastSubSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + tflite::reference_ops::Sub( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } else { + if (need_broadcast) { + tflite::reference_ops::BroadcastSubSlow( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } else { + tflite::reference_ops::Sub( + op_params, tflite::micro::GetTensorShape(input1), + tflite::micro::GetTensorData(input1), + tflite::micro::GetTensorShape(input2), + tflite::micro::GetTensorData(input2), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + } + } + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input1 = + tflite::micro::GetEvalInput(context, node, kInputTensor1); + const TfLiteEvalTensor* input2 = + tflite::micro::GetEvalInput(context, node, kInputTensor2); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + if (output->type == kTfLiteFloat32) { + EvalSub(context, node, params, &data, input1, input2, output); + } else if (output->type == kTfLiteUInt8 || output->type == kTfLiteInt8) { + TF_LITE_ENSURE_OK(context, EvalSubQuantized(context, node, params, &data, + input1, input2, output)); + } else { + TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.", + TfLiteTypeGetName(output->type), output->type); + return kTfLiteError; + } + + return kTfLiteOk; +} + +} // namespace sub + +TfLiteRegistration Register_SUB() { + return {/*init=*/sub::Init, + /*free=*/nullptr, + /*prepare=*/sub::Prepare, + /*invoke=*/sub::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/svdf.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/svdf.cc new file mode 100644 index 0000000..5cb8e06 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/svdf.cc @@ -0,0 +1,548 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/activation_utils.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace svdf { +namespace { + +struct OpData { + int32_t effective_scale_1_a; + int32_t effective_scale_2_a; + // b versions of each scale are kept at int since the numbers are just the + // shift value - typically between [-32, 32]. + int effective_scale_1_b; + int effective_scale_2_b; + int scratch_tensor_index; + int scratch_output_tensor_index; + + // Cached tensor zero point values for quantized operations. + int input_zero_point; + int output_zero_point; +}; + +/** + * This version of SVDF is specific to TFLite Micro. It contains the following + * differences between the TFLite version: + * + * 1.) Scratch tensor allocation - scratch tensors must be known ahead of time + * for the Micro interpreter. + * 2.) Output dimensions - the TFLite version determines output size and runtime + * and resizes the output tensor. Micro runtime does not support tensor + * resizing. + */ +static inline void ApplyTimeWeightsBiasAndActivation( + int batch_size, int memory_size, int num_filters, int num_units, int rank, + const float* const __restrict__ weights_time_ptr, + const float* const __restrict__ bias_ptr, TfLiteFusedActivation activation, + float* const __restrict__ state_ptr, float* const __restrict__ scratch_ptr, + float* const __restrict__ output_ptr) { + // Compute matmul(activation_state, weights_time). + for (int b = 0; b < batch_size; ++b) { + // Perform batched vector dot product: + float* scratch_ptr_batch = scratch_ptr + b * num_filters; + const float* vector1_ptr = weights_time_ptr; + const float* vector2_ptr = state_ptr + b * memory_size * num_filters; + for (int i = 0; i < num_filters; ++i) { + *scratch_ptr_batch = 0.f; + for (int j = 0; j < memory_size; ++j) { + *scratch_ptr_batch += *vector1_ptr++ * *vector2_ptr++; + } + scratch_ptr_batch++; + } + } + + // Initialize output with bias if provided. + if (bias_ptr) { + // VectorBatchVectorAssign + for (int i = 0; i < batch_size; ++i) { + float* output_data = output_ptr + i * num_units; + const float* bias_data = bias_ptr; + for (int j = 0; j < num_units; ++j) { + *output_data++ = *bias_data++; + } + } + } else { + float* output_data = output_ptr; + for (int i = 0; i < batch_size * num_units; ++i) { + *output_data++ = 0.0f; + } + } + + // Reduction sum. + for (int b = 0; b < batch_size; ++b) { + float* output_ptr_batch = output_ptr + b * num_units; + float* scratch_ptr_batch = scratch_ptr + b * num_filters; + + // Reduction sum vector + for (int i = 0; i < num_units; ++i) { + for (int j = 0; j < rank; j++) { + output_ptr_batch[i] += *scratch_ptr_batch++; + } + } + } + + // Apply activation. + for (int b = 0; b < batch_size; ++b) { + float* output_ptr_batch = output_ptr + b * num_units; + for (int i = 0; i < num_units; ++i) { + *output_ptr_batch = ActivationValFloat(activation, *output_ptr_batch); + ++output_ptr_batch; + } + } +} + +inline void EvalFloatSVDF( + TfLiteContext* context, TfLiteNode* node, const TfLiteEvalTensor* input, + const TfLiteEvalTensor* weights_feature, + const TfLiteEvalTensor* weights_time, const TfLiteEvalTensor* bias, + const TfLiteSVDFParams* params, int scratch_tensor_index, + TfLiteEvalTensor* activation_state, TfLiteEvalTensor* output) { + const int rank = params->rank; + const int batch_size = input->dims->data[0]; + const int input_size = input->dims->data[1]; + const int num_filters = weights_feature->dims->data[0]; + const int num_units = num_filters / rank; + const int memory_size = weights_time->dims->data[1]; + + const float* weights_feature_ptr = + tflite::micro::GetTensorData(weights_feature); + const float* weights_time_ptr = + tflite::micro::GetTensorData(weights_time); + const float* bias_ptr = tflite::micro::GetTensorData(bias); + const float* input_ptr = tflite::micro::GetTensorData(input); + + float* state_ptr = tflite::micro::GetTensorData(activation_state); + + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(context->GetScratchBuffer != nullptr); + + float* scratch_ptr = static_cast( + context->GetScratchBuffer(context, scratch_tensor_index)); + + float* output_ptr = tflite::micro::GetTensorData(output); + + // Left shift the activation_state. + { + float* new_state_start = state_ptr; + const float* old_state_start = state_ptr + 1; + const float* old_state_end = + state_ptr + batch_size * num_filters * memory_size; + while (old_state_start != old_state_end) { + *new_state_start++ = *old_state_start++; + } + } + + // Note: no need to clear the latest activation, matmul is not accumulative. + + // Compute conv1d(inputs, weights_feature). + // The activation_state's rightmost column is used to save current cycle + // activation. This is achieved by starting at state_ptr[memory_size - 1] and + // having the stride equal to memory_size. + + // Perform batched matrix vector multiply operation: + { + const float* matrix = weights_feature_ptr; + const float* vector = input_ptr; + float* result = &state_ptr[memory_size - 1]; + float* result_in_batch = result; + for (int i = 0; i < batch_size; ++i) { + const float* matrix_ptr = matrix; + for (int j = 0; j < num_filters; ++j) { + float dot_prod = 0.0f; + const float* vector_in_batch = vector + i * input_size; + for (int k = 0; k < input_size; ++k) { + dot_prod += *matrix_ptr++ * *vector_in_batch++; + } + *result_in_batch = dot_prod; + result_in_batch += memory_size; + } + } + } + + ApplyTimeWeightsBiasAndActivation( + batch_size, memory_size, num_filters, num_units, rank, weights_time_ptr, + bias_ptr, params->activation, state_ptr, scratch_ptr, output_ptr); +} + +void EvalIntegerSVDF(TfLiteContext* context, TfLiteNode* node, + const TfLiteEvalTensor* input_tensor, + const TfLiteEvalTensor* weights_feature_tensor, + const TfLiteEvalTensor* weights_time_tensor, + const TfLiteEvalTensor* bias_tensor, + const TfLiteSVDFParams* params, + TfLiteEvalTensor* activation_state_tensor, + TfLiteEvalTensor* output_tensor, const OpData& data) { + const int n_rank = params->rank; + const int n_batch = input_tensor->dims->data[0]; + const int n_input = input_tensor->dims->data[1]; + const int n_filter = weights_feature_tensor->dims->data[0]; + const int n_unit = n_filter / n_rank; + const int n_memory = weights_time_tensor->dims->data[1]; + + TFLITE_DCHECK(context != nullptr); + TFLITE_DCHECK(context->GetScratchBuffer != nullptr); + + int32_t* scratch_tensor = static_cast( + context->GetScratchBuffer(context, data.scratch_tensor_index)); + int32_t* scratch_output_tensor = static_cast( + context->GetScratchBuffer(context, data.scratch_output_tensor_index)); + + // Shift states. + int16_t* const state_ptr = + tflite::micro::GetTensorData(activation_state_tensor); + + // Left shift the activation_state. + { + int16_t* new_state_start = state_ptr; + const int16_t* old_state_start = state_ptr + 1; + const int16_t* old_state_end = state_ptr + n_batch * n_filter * n_memory; + while (old_state_start != old_state_end) { + *new_state_start++ = *old_state_start++; + } + } + + // Note: no need to clear the latest activation, matmul is not accumulative. + + // Feature matmul. + { + int16_t* state = + tflite::micro::GetTensorData(activation_state_tensor); + const int8_t* input = tflite::micro::GetTensorData(input_tensor); + const int8_t* weight_feature = + tflite::micro::GetTensorData(weights_feature_tensor); + const int32_t output_max = std::numeric_limits::max(); + const int32_t output_min = std::numeric_limits::min(); + int16_t* result_in_batch = state + (n_memory - 1); + for (int b = 0; b < n_batch; b++) { + const int8_t* matrix_ptr = weight_feature; + for (int r = 0; r < n_filter; r++) { + int32_t dot_prod = 0; + const int8_t* vector_in_batch = input + b * n_input; + for (int c = 0; c < n_input; c++) { + dot_prod += + *matrix_ptr++ * (*vector_in_batch++ - data.input_zero_point); + } + dot_prod = MultiplyByQuantizedMultiplier( + dot_prod, data.effective_scale_1_a, data.effective_scale_1_b); + dot_prod = std::min(std::max(output_min, dot_prod), output_max); + // This assumes state is symmetrically quantized. Otherwise last bit of + // state should be initialized to its zero point and accumulate the + // dot_prod. + // Equivalent as the following: + // result_in_batch = zero point, which happens to be zero. + // result_in_batch += dot_prod_56. + *result_in_batch = dot_prod; + result_in_batch += n_memory; + } + } + } + + // Time. + { + for (int b = 0; b < n_batch; ++b) { + int32_t* scratch_ptr_batch = scratch_tensor + b * n_filter; + + // Perform batched vector dot product: + const int16_t* vector1_ptr = + tflite::micro::GetTensorData(weights_time_tensor); + const int16_t* vector2_ptr = + tflite::micro::GetTensorData(activation_state_tensor) + + b * n_memory * n_filter; + + for (int i = 0; i < n_filter; i++) { + *scratch_ptr_batch = 0; + for (int j = 0; j < n_memory; j++) { + *scratch_ptr_batch += *vector1_ptr++ * *vector2_ptr++; + } + scratch_ptr_batch++; + } + } + } + + // Reduce, add bias, rescale, activation. + { + // Add bias. + if (bias_tensor) { + // Vector batch assign: + const int32_t* bias_data = + tflite::micro::GetTensorData(bias_tensor); + for (int i = 0; i < n_batch; ++i) { + int32_t* output_ptr = scratch_output_tensor + i * n_unit; + const int32_t* bias_ptr = bias_data; + for (int j = 0; j < n_unit; ++j) { + *output_ptr++ = *bias_ptr++; + } + } + } else { + int32_t* output_ptr = scratch_output_tensor; + for (int i = 0; i < n_batch * n_unit; ++i) { + *output_ptr++ = 0; + } + } + + // Reduce. + for (int b = 0; b < n_batch; ++b) { + int32_t* output_temp_ptr = scratch_output_tensor + b * n_unit; + int32_t* scratch_ptr_batch = scratch_tensor + b * n_filter; + + // Reduction sum vector + for (int i = 0; i < n_unit; ++i) { + for (int j = 0; j < n_rank; ++j) { + output_temp_ptr[i] += *scratch_ptr_batch++; + } + } + } + + // Rescale. + const int32_t output_max = std::numeric_limits::max(); + const int32_t output_min = std::numeric_limits::min(); + for (int i = 0; i < n_batch * n_unit; ++i) { + int32_t x1 = scratch_output_tensor[i]; + int32_t x2 = MultiplyByQuantizedMultiplier(x1, data.effective_scale_2_a, + data.effective_scale_2_b); + int32_t x3 = x2 + data.output_zero_point; + int32_t x4 = std::min(std::max(output_min, x3), output_max); + tflite::micro::GetTensorData(output_tensor)[i] = + static_cast(x4); + } + } +} + +} // namespace + +// Input tensors. +constexpr int kInputTensor = 0; +constexpr int kWeightsFeatureTensor = 1; +constexpr int kWeightsTimeTensor = 2; +constexpr int kBiasTensor = 3; +// This is a variable tensor, and will be modified by this op. +constexpr int kInputActivationStateTensor = 4; + +// Output tensor. +constexpr int kOutputTensor = 0; + +void* Init(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->builtin_data != nullptr); + + const auto* params = static_cast(node->builtin_data); + + // Validate Tensor Inputs (dtype depends on quantization): + // [0] = Input, {2, batch_size, input_size} + // [1] = Weights Feature, {2, num_filters, input_size} + // [2] = Weights Time, {2, num_filters, memory_size} + // [3] = Bias (optional), {1, num_units} + // [4] = Activation State (variable), + // {2, batch_size, memory_size * num_filters} + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const TfLiteTensor* weights_feature = + GetInput(context, node, kWeightsFeatureTensor); + const TfLiteTensor* weights_time = + GetInput(context, node, kWeightsTimeTensor); + const TfLiteTensor* bias = GetOptionalInputTensor(context, node, kBiasTensor); + const TfLiteTensor* activation_state = + GetInput(context, node, kInputActivationStateTensor); + + // Define input constants based on input tensor definition above: + const int rank = params->rank; + const int input_size = input->dims->data[1]; + const int batch_size = input->dims->data[0]; + const int num_filters = weights_feature->dims->data[0]; + TF_LITE_ENSURE_EQ(context, num_filters % rank, 0); + const int num_units = num_filters / rank; + const int memory_size = weights_time->dims->data[1]; + + // Validate Input Tensor: + TF_LITE_ENSURE(context, + input->type == kTfLiteFloat32 || input->type == kTfLiteInt8); + TF_LITE_ENSURE_EQ(context, NumDimensions(input), 2); + + // Validate Tensor Output: + // [0] = float/int8_t, {2, batch_size, num_units} + TF_LITE_ENSURE_EQ(context, node->outputs->size, 1); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + TF_LITE_ENSURE_EQ(context, NumDimensions(output), 2); + TF_LITE_ENSURE_EQ(context, output->dims->data[0], batch_size); + TF_LITE_ENSURE_EQ(context, output->dims->data[1], num_units); + + // Validate Weights Feature Input Tensor: + TF_LITE_ENSURE_EQ(context, NumDimensions(weights_feature), 2); + TF_LITE_ENSURE_EQ(context, weights_feature->dims->data[1], input_size); + + // Validate Weights Time Input Tensor: + TF_LITE_ENSURE_EQ(context, NumDimensions(weights_time), 2); + TF_LITE_ENSURE_EQ(context, weights_time->dims->data[0], num_filters); + TF_LITE_ENSURE_EQ(context, weights_time->dims->data[1], memory_size); + + // Validate Optional Bias Input Tensor: + if (bias != nullptr) { + TF_LITE_ENSURE_EQ(context, bias->dims->data[0], num_units); + } + + // Validate Activation State Input Tensor: + TF_LITE_ENSURE_EQ(context, NumDimensions(activation_state), 2); + TF_LITE_ENSURE_EQ(context, activation_state->dims->data[0], batch_size); + TF_LITE_ENSURE_EQ(context, activation_state->dims->data[1], + memory_size * num_filters); + // Since is_variable is not part of TFLiteEvalTensor, check is_variable here. + TF_LITE_ENSURE_EQ(context, activation_state->is_variable, true); + + TF_LITE_ENSURE_EQ(context, node->inputs->size, 5); + + TFLITE_DCHECK(node->user_data != nullptr); + OpData* data = static_cast(node->user_data); + + if (input->type == kTfLiteInt8) { + TF_LITE_ENSURE_EQ(context, weights_feature->type, kTfLiteInt8); + TF_LITE_ENSURE_EQ(context, weights_time->type, kTfLiteInt16); + TF_LITE_ENSURE_EQ(context, activation_state->type, kTfLiteInt16); + if (bias != nullptr) { + TF_LITE_ENSURE_EQ(context, bias->type, kTfLiteInt32); + } + + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteInt8); + + const double effective_scale_1 = static_cast( + input->params.scale * weights_feature->params.scale / + activation_state->params.scale); + const double effective_scale_2 = + static_cast(activation_state->params.scale * + weights_time->params.scale / output->params.scale); + + // TODO(b/162018098): Use TF_LITE_ENSURE_NEAR when it is ready. + TF_LITE_ENSURE( + context, + std::abs(static_cast(bias->params.scale) - + static_cast(activation_state->params.scale * + weights_time->params.scale)) < 1e-5); + + QuantizeMultiplier(effective_scale_1, &(data->effective_scale_1_a), + &(data->effective_scale_1_b)); + QuantizeMultiplier(effective_scale_2, &(data->effective_scale_2_a), + &(data->effective_scale_2_b)); + + data->input_zero_point = input->params.zero_point; + data->output_zero_point = output->params.zero_point; + + TFLITE_DCHECK(context->RequestScratchBufferInArena != nullptr); + + const TfLiteStatus scratch_status = context->RequestScratchBufferInArena( + context, batch_size * num_filters * sizeof(int32_t), + &(data->scratch_tensor_index)); + TF_LITE_ENSURE_OK(context, scratch_status); + + const TfLiteStatus scratch_output_status = + context->RequestScratchBufferInArena( + context, batch_size * num_units * sizeof(int32_t), + &(data->scratch_output_tensor_index)); + TF_LITE_ENSURE_OK(context, scratch_output_status); + } else { + TF_LITE_ENSURE_EQ(context, weights_feature->type, kTfLiteFloat32); + TF_LITE_ENSURE_EQ(context, weights_time->type, kTfLiteFloat32); + TF_LITE_ENSURE_EQ(context, activation_state->type, kTfLiteFloat32); + if (bias != nullptr) { + TF_LITE_ENSURE_EQ(context, bias->type, kTfLiteFloat32); + } + TF_LITE_ENSURE_TYPES_EQ(context, output->type, kTfLiteFloat32); + + TFLITE_DCHECK(context->RequestScratchBufferInArena != nullptr); + const TfLiteStatus scratch_status = context->RequestScratchBufferInArena( + context, batch_size * num_filters * sizeof(float), + &(data->scratch_tensor_index)); + TF_LITE_ENSURE_OK(context, scratch_status); + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + auto* params = reinterpret_cast(node->builtin_data); + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + const TfLiteEvalTensor* weights_feature = + tflite::micro::GetEvalInput(context, node, kWeightsFeatureTensor); + const TfLiteEvalTensor* weights_time = + tflite::micro::GetEvalInput(context, node, kWeightsTimeTensor); + const TfLiteEvalTensor* bias = + (NumInputs(node) == 5) + ? tflite::micro::GetEvalInput(context, node, kBiasTensor) + : nullptr; + TfLiteEvalTensor* activation_state = tflite::micro::GetMutableEvalInput( + context, node, kInputActivationStateTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + switch (weights_feature->type) { + case kTfLiteFloat32: { + EvalFloatSVDF(context, node, input, weights_feature, weights_time, bias, + params, data.scratch_tensor_index, activation_state, + output); + return kTfLiteOk; + break; + } + + case kTfLiteInt8: { + EvalIntegerSVDF(context, node, input, weights_feature, weights_time, bias, + params, activation_state, output, data); + return kTfLiteOk; + break; + } + + default: + TF_LITE_KERNEL_LOG(context, "Type %s not currently supported.", + TfLiteTypeGetName(weights_feature->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace svdf + +TfLiteRegistration Register_SVDF() { + return {/*init=*/svdf::Init, + /*free=*/nullptr, + /*prepare=*/svdf::Prepare, + /*invoke=*/svdf::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/tanh.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/tanh.cc new file mode 100644 index 0000000..5fa32f8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/tanh.cc @@ -0,0 +1,154 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h" + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/common.h" +#include "tensorflow/lite/kernels/internal/quantization_util.h" +#include "tensorflow/lite/kernels/internal/reference/tanh.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_utils.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace activations { +namespace { +constexpr int kInputTensor = 0; +constexpr int kOutputTensor = 0; + +struct OpData { + int32_t input_zero_point; + int32_t input_range_radius; + int32_t input_multiplier; + int input_left_shift; +}; + +void* TanhInit(TfLiteContext* context, const char* buffer, size_t length) { + TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr); + return context->AllocatePersistentBuffer(context, sizeof(OpData)); +} + +TfLiteStatus CalculateArithmeticOpData(TfLiteContext* context, TfLiteNode* node, + OpData* data) { + TF_LITE_ENSURE_EQ(context, NumInputs(node), 1); + TF_LITE_ENSURE_EQ(context, NumOutputs(node), 1); + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + TfLiteTensor* output = GetOutput(context, node, kOutputTensor); + + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + + if (input->type == kTfLiteUInt8 || input->type == kTfLiteInt8) { + static constexpr int kInputIntegerBits = 4; + const double input_real_multiplier = + static_cast(input->params.scale) * + static_cast(1 << (31 - kInputIntegerBits)); + + const double q = std::frexp(input_real_multiplier, &data->input_left_shift); + data->input_multiplier = static_cast(TfLiteRound(q * (1ll << 31))); + + data->input_range_radius = + CalculateInputRadius(kInputIntegerBits, data->input_left_shift, 31); + } + return kTfLiteOk; +} + +TfLiteStatus TanhPrepare(TfLiteContext* context, TfLiteNode* node) { + TFLITE_DCHECK(node->user_data != nullptr); + + OpData* data = static_cast(node->user_data); + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + data->input_zero_point = input->params.zero_point; + return CalculateArithmeticOpData(context, node, data); +} + +} // namespace + +TfLiteStatus TanhEval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + TfLiteEvalTensor* output = + tflite::micro::GetEvalOutput(context, node, kOutputTensor); + + TFLITE_DCHECK(node->user_data != nullptr); + const OpData& data = *(static_cast(node->user_data)); + + switch (input->type) { + case kTfLiteFloat32: { + reference_ops::Tanh(tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + case kTfLiteInt16: { + TanhParams params; + params.input_left_shift = data.input_left_shift; + reference_ops::Tanh(params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + case kTfLiteUInt8: { + TanhParams params; + params.input_zero_point = data.input_zero_point; + params.input_range_radius = data.input_range_radius; + params.input_multiplier = data.input_multiplier; + params.input_left_shift = data.input_left_shift; + reference_ops::Tanh(params, tflite::micro::GetTensorShape(input), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorShape(output), + tflite::micro::GetTensorData(output)); + + return kTfLiteOk; + } break; + case kTfLiteInt8: { + reference_integer_ops::Tanh( + data.input_zero_point, data.input_range_radius, data.input_multiplier, + data.input_left_shift, NumElements(input->dims), + tflite::micro::GetTensorData(input), + tflite::micro::GetTensorData(output)); + return kTfLiteOk; + } break; + default: + TF_LITE_KERNEL_LOG(context, "Input %s, output %s not supported.", + TfLiteTypeGetName(input->type), + TfLiteTypeGetName(output->type)); + return kTfLiteError; + } +} + +} // namespace activations + +TfLiteRegistration Register_TANH() { + return {/*init=*/activations::TanhInit, + /*free=*/nullptr, + /*prepare=*/activations::TanhPrepare, + /*invoke=*/activations::TanhEval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/kernels/unpack.cc b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/unpack.cc new file mode 100644 index 0000000..557cc57 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/kernels/unpack.cc @@ -0,0 +1,121 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace unpack { +namespace { + +constexpr int kInputTensor = 0; + +template +TfLiteStatus UnpackImpl(TfLiteContext* context, TfLiteNode* node, + const TfLiteEvalTensor* input, int output_count, + int axis) { + const TfLiteEvalTensor* output0 = + tflite::micro::GetEvalOutput(context, node, 0); + const TfLiteIntArray* input_dims = input->dims; + const TfLiteIntArray* output_dims = output0->dims; + const int dimensions = input_dims->size; + + if (axis < 0) { + axis += input->dims->size; + } + + TFLITE_DCHECK_LT(axis, dimensions); + + int outer_size = 1; + for (int i = 0; i < axis; ++i) { + outer_size *= input_dims->data[i]; + } + int copy_size = 1; + for (int i = axis + 1; i < dimensions; ++i) { + copy_size *= input_dims->data[i]; + } + int output_size = 1; + for (int i = 0; i < output_dims->size; ++i) { + output_size *= output_dims->data[i]; + } + TFLITE_DCHECK_EQ(output_size, copy_size * outer_size); + + const T* input_data = tflite::micro::GetTensorData(input); + + for (int i = 0; i < output_count; ++i) { + TfLiteEvalTensor* t = tflite::micro::GetEvalOutput(context, node, i); + T* output_data = tflite::micro::GetTensorData(t); + for (int k = 0; k < outer_size; ++k) { + T* output_ptr = output_data + copy_size * k; + int loc = k * output_count * copy_size + i * copy_size; + const T* input_ptr = input_data + loc; + for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; + } + } + + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + TfLiteUnpackParams* data = + reinterpret_cast(node->builtin_data); + + const TfLiteEvalTensor* input = + tflite::micro::GetEvalInput(context, node, kInputTensor); + + switch (input->type) { + case kTfLiteFloat32: { + return UnpackImpl(context, node, input, data->num, data->axis); + } + case kTfLiteInt32: { + return UnpackImpl(context, node, input, data->num, data->axis); + } + case kTfLiteUInt8: { + return UnpackImpl(context, node, input, data->num, data->axis); + } + case kTfLiteInt8: { + return UnpackImpl(context, node, input, data->num, data->axis); + } + default: { + TF_LITE_KERNEL_LOG(context, "Type '%s' is not supported by unpack.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + } + + return kTfLiteOk; +} +} // namespace +} // namespace unpack + +TfLiteRegistration Register_UNPACK() { + return {/*init=*/nullptr, + /*free=*/nullptr, + /*prepare=*/nullptr, + /*invoke=*/unpack::Eval, + /*profiling_string=*/nullptr, + /*builtin_code=*/0, + /*custom_name=*/nullptr, + /*version=*/0}; +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.cc b/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.cc new file mode 100644 index 0000000..c6180cb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.cc @@ -0,0 +1,155 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/memory_helpers.h" + +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/flatbuffer_conversions.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +uint8_t* AlignPointerUp(uint8_t* data, size_t alignment) { + std::uintptr_t data_as_uintptr_t = reinterpret_cast(data); + uint8_t* aligned_result = reinterpret_cast( + ((data_as_uintptr_t + (alignment - 1)) / alignment) * alignment); + return aligned_result; +} + +uint8_t* AlignPointerDown(uint8_t* data, size_t alignment) { + std::uintptr_t data_as_uintptr_t = reinterpret_cast(data); + uint8_t* aligned_result = + reinterpret_cast((data_as_uintptr_t / alignment) * alignment); + return aligned_result; +} + +size_t AlignSizeUp(size_t size, size_t alignment) { + size_t aligned_size = (((size + (alignment - 1)) / alignment) * alignment); + return aligned_size; +} + +TfLiteStatus TfLiteTypeSizeOf(TfLiteType type, size_t* size) { + switch (type) { + case kTfLiteFloat32: + *size = sizeof(float); + break; + case kTfLiteInt16: + *size = sizeof(int16_t); + break; + case kTfLiteInt32: + *size = sizeof(int32_t); + break; + case kTfLiteUInt8: + *size = sizeof(uint8_t); + break; + case kTfLiteInt8: + *size = sizeof(int8_t); + break; + case kTfLiteInt64: + *size = sizeof(int64_t); + break; + case kTfLiteBool: + *size = sizeof(bool); + break; + case kTfLiteComplex64: + *size = sizeof(float) * 2; + break; + case kTfLiteComplex128: + *size = sizeof(double) * 2; + break; + default: + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus BytesRequiredForTensor(const tflite::Tensor& flatbuffer_tensor, + size_t* bytes, size_t* type_size, + ErrorReporter* error_reporter) { + int element_count = 1; + // If flatbuffer_tensor.shape == nullptr, then flatbuffer_tensor is a scalar + // so has 1 element. + if (flatbuffer_tensor.shape() != nullptr) { + for (size_t n = 0; n < flatbuffer_tensor.shape()->Length(); ++n) { + element_count *= flatbuffer_tensor.shape()->Get(n); + } + } + + TfLiteType tf_lite_type; + TF_LITE_ENSURE_STATUS(ConvertTensorType(flatbuffer_tensor.type(), + &tf_lite_type, error_reporter)); + TF_LITE_ENSURE_STATUS(TfLiteTypeSizeOf(tf_lite_type, type_size)); + *bytes = element_count * (*type_size); + return kTfLiteOk; +} + +TfLiteStatus TfLiteEvalTensorByteLength(const TfLiteEvalTensor* eval_tensor, + size_t* out_bytes) { + TFLITE_DCHECK(out_bytes != nullptr); + + int element_count = 1; + // If eval_tensor->dims == nullptr, then tensor is a scalar so has 1 element. + if (eval_tensor->dims != nullptr) { + for (int n = 0; n < eval_tensor->dims->size; ++n) { + element_count *= eval_tensor->dims->data[n]; + } + } + size_t type_size; + TF_LITE_ENSURE_STATUS(TfLiteTypeSizeOf(eval_tensor->type, &type_size)); + *out_bytes = element_count * type_size; + return kTfLiteOk; +} + +TfLiteStatus AllocateOutputDimensionsFromInput(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + TfLiteTensor* output) { + const TfLiteTensor* input = nullptr; + + TF_LITE_ENSURE(context, input1->dims != nullptr); + TF_LITE_ENSURE(context, input2->dims != nullptr); + TF_LITE_ENSURE(context, output->dims->size == 0); + + input = input1->dims->size > input2->dims->size ? input1 : input2; + TF_LITE_ENSURE(context, output->type == input->type); + + size_t size = 0; + TfLiteTypeSizeOf(input->type, &size); + const int dimensions_count = tflite::GetTensorShape(input).DimensionsCount(); + for (int i = 0; i < dimensions_count; i++) { + size *= input->dims->data[i]; + } + + output->bytes = size; + + output->dims = + reinterpret_cast(context->AllocatePersistentBuffer( + context, TfLiteIntArrayGetSizeInBytes(size))); + + output->dims->size = input->dims->size; + for (int i = 0; i < dimensions_count; i++) { + output->dims->data[i] = input->dims->data[i]; + } + + return kTfLiteOk; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.h b/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.h new file mode 100644 index 0000000..8f5526c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_helpers.h @@ -0,0 +1,59 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MEMORY_HELPERS_H_ +#define TENSORFLOW_LITE_MICRO_MEMORY_HELPERS_H_ + +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +// Returns the next pointer address aligned to the given alignment. +uint8_t* AlignPointerUp(uint8_t* data, size_t alignment); + +// Returns the previous pointer address aligned to the given alignment. +uint8_t* AlignPointerDown(uint8_t* data, size_t alignment); + +// Returns an increased size that's a multiple of alignment. +size_t AlignSizeUp(size_t size, size_t alignment); + +// Returns size in bytes for a given TfLiteType. +TfLiteStatus TfLiteTypeSizeOf(TfLiteType type, size_t* size); + +// How many bytes are needed to hold a tensor's contents. +TfLiteStatus BytesRequiredForTensor(const tflite::Tensor& flatbuffer_tensor, + size_t* bytes, size_t* type_size, + ErrorReporter* error_reporter); + +// How many bytes are used in a TfLiteEvalTensor instance. The byte length is +// returned in out_bytes. +TfLiteStatus TfLiteEvalTensorByteLength(const TfLiteEvalTensor* eval_tensor, + size_t* out_bytes); + +// Deduce output dimensions from input and allocate given size. +// Useful for operators with two inputs where the largest input should equal the +// output dimension. +TfLiteStatus AllocateOutputDimensionsFromInput(TfLiteContext* context, + const TfLiteTensor* input1, + const TfLiteTensor* input2, + TfLiteTensor* output); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MEMORY_HELPERS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.cc b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.cc new file mode 100644 index 0000000..39991ab --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.cc @@ -0,0 +1,437 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/memory_planner/greedy_memory_planner.h" + +namespace tflite { + +// Simple stable in-place sort function. Not time-efficient for large arrays. +// Would normally be in an anonymous namespace to keep it private, but we want +// to be able to test it externally. +void ReverseSortInPlace(int* values, int* ids, int size) { + bool any_swapped; + do { + any_swapped = false; + for (int i = 1; i < size; ++i) { + if (values[i - 1] < values[i]) { + const int value_temp = values[i - 1]; + values[i - 1] = values[i]; + values[i] = value_temp; + const int id_temp = ids[i - 1]; + ids[i - 1] = ids[i]; + ids[i] = id_temp; + any_swapped = true; + } + } + } while (any_swapped); +} + +GreedyMemoryPlanner::GreedyMemoryPlanner(unsigned char* scratch_buffer, + int scratch_buffer_size) + : buffer_count_(0), need_to_calculate_offsets_(true) { + // Allocate the arrays we need within the scratch buffer arena. + max_buffer_count_ = scratch_buffer_size / per_buffer_size(); + + unsigned char* next_free = scratch_buffer; + requirements_ = reinterpret_cast(next_free); + next_free += sizeof(BufferRequirements) * max_buffer_count_; + + buffer_sizes_sorted_ = reinterpret_cast(next_free); + next_free += sizeof(int) * max_buffer_count_; + + buffer_ids_sorted_ = reinterpret_cast(next_free); + next_free += sizeof(int) * max_buffer_count_; + + buffers_sorted_by_offset_ = reinterpret_cast(next_free); + next_free += sizeof(ListEntry) * max_buffer_count_; + + buffer_offsets_ = reinterpret_cast(next_free); +} + +GreedyMemoryPlanner::~GreedyMemoryPlanner() { + // We don't own the scratch buffer, so don't deallocate anything. +} + +TfLiteStatus GreedyMemoryPlanner::AddBuffer( + tflite::ErrorReporter* error_reporter, int size, int first_time_used, + int last_time_used) { + if (buffer_count_ >= max_buffer_count_) { + TF_LITE_REPORT_ERROR(error_reporter, "Too many buffers (max is %d)", + max_buffer_count_); + return kTfLiteError; + } + BufferRequirements* current = &requirements_[buffer_count_]; + current->size = size; + current->first_time_used = first_time_used; + current->last_time_used = last_time_used; + current->offline_offset = kOnlinePlannedBuffer; + ++buffer_count_; + need_to_calculate_offsets_ = true; + return kTfLiteOk; +} + +TfLiteStatus GreedyMemoryPlanner::AddBuffer( + tflite::ErrorReporter* error_reporter, int size, int first_time_used, + int last_time_used, int offline_offset) { + BufferRequirements* current = &requirements_[buffer_count_]; + if (AddBuffer(error_reporter, size, first_time_used, last_time_used) != + kTfLiteOk) { + return kTfLiteError; + } + current->offline_offset = offline_offset; + return kTfLiteOk; +} + +bool GreedyMemoryPlanner::DoesEntryOverlapInTime( + const GreedyMemoryPlanner::ListEntry* entry, const int first_time_used, + const int last_time_used) const { + const BufferRequirements* entry_requirements = + &requirements_[entry->requirements_index]; + if (entry_requirements->first_time_used > last_time_used) { + return false; + } + if (first_time_used > entry_requirements->last_time_used) { + return false; + } + return true; +} + +GreedyMemoryPlanner::ListEntry* +GreedyMemoryPlanner::NextSimultaneouslyActiveBuffer( + const GreedyMemoryPlanner::ListEntry* start, const int first_time_used, + const int last_time_used) { + ListEntry* result = nullptr; + ListEntry* candidate_next_entry; + if (start == nullptr) { + candidate_next_entry = &buffers_sorted_by_offset_[first_entry_index_]; + } else { + if (start->next_entry_index == -1) { + return nullptr; + } + candidate_next_entry = &buffers_sorted_by_offset_[start->next_entry_index]; + } + do { + if (DoesEntryOverlapInTime(candidate_next_entry, first_time_used, + last_time_used)) { + result = candidate_next_entry; + break; + } + if (candidate_next_entry->next_entry_index == -1) { + break; + } + candidate_next_entry = + &buffers_sorted_by_offset_[candidate_next_entry->next_entry_index]; + } while (true); + return result; +} + +void GreedyMemoryPlanner::CalculateOffsetsIfNeeded() { + if (!need_to_calculate_offsets_ || (buffer_count_ == 0)) { + return; + } + need_to_calculate_offsets_ = false; + + // Start off by ordering the buffers in descending order of size. + // This helps find a more compact layout. Intuitively, you can think + // about putting the large buffers in place first, and then the + // smaller buffers can fit in the gaps, rather than fragmenting the + // gaps with small buffers at the beginning. Add offline planned offsets + // first in the list, since they have a predetermined offset. + int idx_from_tail = buffer_count_; + int idx_from_head = 0; + for (int i = 0; i < buffer_count_; ++i) { + if (requirements_[i].offline_offset == kOnlinePlannedBuffer) { + idx_from_tail--; + buffer_sizes_sorted_[idx_from_tail] = requirements_[i].size; + buffer_ids_sorted_[idx_from_tail] = i; + buffer_offsets_[i] = -1; + } else { + buffer_sizes_sorted_[idx_from_head] = requirements_[i].size; + buffer_ids_sorted_[idx_from_head] = i; + buffer_offsets_[i] = requirements_[i].offline_offset; + idx_from_head++; + } + } + + // This sorting algorithm is naive, and may end up taking a very long time + // with hundreds of buffers. Do not sort the offline planned offsets. + ReverseSortInPlace(&buffer_sizes_sorted_[idx_from_head], + &buffer_ids_sorted_[idx_from_head], + buffer_count_ - idx_from_head); + + // Initialize the first entry to the first buffer in + // buffer_ids_sorted_. + // - If there are no offline planned offsets, the largest buffer will be + // first, and the buffers will be handled in size order. + // - If offline offsets are present, these will be handled first in order + // for the greedy algorithm to utilized gaps in the offline plan. + first_entry_index_ = 0; + next_free_entry_ = 1; + ListEntry* first_entry = &buffers_sorted_by_offset_[first_entry_index_]; + first_entry->next_entry_index = -1; // to mark the entry as end of list + int buffer_id = buffer_ids_sorted_[0]; + first_entry->requirements_index = buffer_id; + if (requirements_[buffer_id].offline_offset == kOnlinePlannedBuffer) { + buffer_offsets_[buffer_id] = 0; + } + first_entry->offset = buffer_offsets_[buffer_id]; + + // Work through the rest of the buffers to find a good gap to place each one. + for (int i = 1; i < buffer_count_; ++i) { + // The id is the order the buffer was originally added by the client. + buffer_id = buffer_ids_sorted_[i]; + // Look at what size and time range the buffer needs to be active. + BufferRequirements* wanted_requirements = &requirements_[buffer_id]; + const int wanted_size = wanted_requirements->size; + const int wanted_first_time_used = wanted_requirements->first_time_used; + const int wanted_last_time_used = wanted_requirements->last_time_used; + + // Find the first buffer that's active in our time range. All placed + // buffers are stored in the order of their starting position in the arena + // so that it's easy to find the next buffer in memory, and so the gap. + // The candidate_entry variable holds the buffer that we're considering + // placing the current buffer after. + + int candidate_offset = 0; + // Loop through the offset-ordered list of buffers, looking for gaps. + if (wanted_requirements->offline_offset == kOnlinePlannedBuffer) { + ListEntry* prior_entry = nullptr; + while (true) { + // Find out what the next active buffer is. + ListEntry* next_entry = NextSimultaneouslyActiveBuffer( + prior_entry, wanted_first_time_used, wanted_last_time_used); + + if (prior_entry) { + BufferRequirements* candidate_requirements = + &requirements_[prior_entry->requirements_index]; + const int prior_entry_offset = + prior_entry->offset + candidate_requirements->size; + if (prior_entry_offset > candidate_offset) { + candidate_offset = prior_entry_offset; + } + } + if (next_entry == nullptr) { + // We're at the end of the list, so we can always append the buffer + // here. + break; + } + // Find out how much space there is between us and the next buffer. + const int gap = next_entry->offset - candidate_offset; + if (gap >= wanted_size) { + // This entry has a big enough gap between it and the next, so + // use it! + break; + } + // The gap wasn't big enough, so move on to another candidate. + prior_entry = next_entry; + } + } else { + // Offline planned offset are to be considered constant + candidate_offset = wanted_requirements->offline_offset; + } + // At this point, we've either found a gap (possibly at the end of the + // list) and want to place the buffer there, or there are no other active + // buffers in this time range and so we can put it at offset zero. + // Record the buffer's offset in our plan. + buffer_offsets_[buffer_id] = candidate_offset; + // Add the newly-placed buffer to our offset-ordered list, so that + // subsequent passes can fit in their buffers around it. + ListEntry* new_entry = &buffers_sorted_by_offset_[next_free_entry_]; + new_entry->offset = candidate_offset; + new_entry->requirements_index = buffer_id; + const int new_entry_index = next_free_entry_; + ++next_free_entry_; + + if (first_entry->offset > candidate_offset) { + // The new entry offset is smaller than the first entry offset => + // replace the first entry + first_entry = new_entry; + first_entry->next_entry_index = first_entry_index_; + first_entry_index_ = new_entry_index; + } else { + ListEntry* current_entry = first_entry; + // Make sure that we insert the buffer at the correct place in the + // buffer-offset-ordered list + while (true) { + const int next_entry_index = current_entry->next_entry_index; + if (next_entry_index == -1) { + // We're at the end of the list, so just add the new entry here. + current_entry->next_entry_index = new_entry_index; + new_entry->next_entry_index = -1; + break; + } + // not at the end of the list -> take a look at next entry + ListEntry* next_entry = &buffers_sorted_by_offset_[next_entry_index]; + if (next_entry->offset > candidate_offset) { + // We're at the right spot to do an insertion and retain the sorting + // order, so place the new entry here. + new_entry->next_entry_index = current_entry->next_entry_index; + current_entry->next_entry_index = new_entry_index; + break; + } + current_entry = next_entry; + } + } + } +} + +size_t GreedyMemoryPlanner::GetMaximumMemorySize() { + CalculateOffsetsIfNeeded(); + if (buffer_count_ == 0) { + return 0; + } + ListEntry* entry = &buffers_sorted_by_offset_[first_entry_index_]; + size_t max_size = 0; + while (entry) { + BufferRequirements* requirements = + &requirements_[entry->requirements_index]; + // TODO(b/148246793): Update all size and offset variables types from + // int to size_t + const size_t current_size = entry->offset + requirements->size; + if (current_size > max_size) { + max_size = current_size; + } + if (entry->next_entry_index == -1) { + break; + } + entry = &buffers_sorted_by_offset_[entry->next_entry_index]; + } + return max_size; +} + +void GreedyMemoryPlanner::PrintMemoryPlan(ErrorReporter* error_reporter) { + CalculateOffsetsIfNeeded(); + + for (int i = 0; i < buffer_count_; ++i) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Planner buffer ID: %d, calculated offset: %d, size required: %d, " + "first_time_created: %d, " + "last_time_used: %d", + i, buffer_offsets_[i], requirements_[i].size, + requirements_[i].first_time_used, requirements_[i].last_time_used); + } + + constexpr int kLineWidth = 80; + int max_size = kLineWidth; + int max_time = 0; + for (int i = 0; i < buffer_count_; ++i) { + BufferRequirements* requirements = &requirements_[i]; + const int offset = buffer_offsets_[i]; + const int last_time_used = requirements->last_time_used; + const int size = offset + requirements->size; + if (size > max_size) { + max_size = size; + } + if (last_time_used > max_time) { + max_time = last_time_used; + } + } + + char line[kLineWidth + 1]; + for (int t = 0; t <= max_time; ++t) { + for (int c = 0; c < kLineWidth; ++c) { + line[c] = '.'; + } + for (int i = 0; i < buffer_count_; ++i) { + BufferRequirements* requirements = &requirements_[i]; + if ((t < requirements->first_time_used) || + (t > requirements->last_time_used)) { + continue; + } + const int offset = buffer_offsets_[i]; + if (offset == -1) { + continue; + } + const int size = requirements->size; + const int line_start = (offset * kLineWidth) / max_size; + const int line_end = ((offset + size) * kLineWidth) / max_size; + for (int n = line_start; n < line_end; ++n) { + if (line[n] == '.') { + char display; + if (i < 10) { + display = '0' + i; + } else if (i < 36) { + display = 'a' + (i - 10); + } else if (i < 62) { + display = 'A' + (i - 36); + } else { + display = '*'; + } + line[n] = display; + } else { + line[n] = '!'; + } + } + } + line[kLineWidth] = 0; + TF_LITE_REPORT_ERROR(error_reporter, "%s", (const char*)line); + } +} + +int GreedyMemoryPlanner::GetBufferCount() { return buffer_count_; } + +TfLiteStatus GreedyMemoryPlanner::GetOffsetForBuffer( + tflite::ErrorReporter* error_reporter, int buffer_index, int* offset) { + CalculateOffsetsIfNeeded(); + if ((buffer_index < 0) || (buffer_index >= buffer_count_)) { + TF_LITE_REPORT_ERROR(error_reporter, + "buffer index %d is outside range 0 to %d", + buffer_index, buffer_count_); + return kTfLiteError; + } + *offset = buffer_offsets_[buffer_index]; + return kTfLiteOk; +} + +bool GreedyMemoryPlanner::DoAnyBuffersOverlap(ErrorReporter* error_reporter) { + CalculateOffsetsIfNeeded(); + bool were_overlaps_found = false; + for (int i = 0; i < buffer_count_; ++i) { + BufferRequirements* a_requirements = &requirements_[i]; + const int a_start_offset = buffer_offsets_[i]; + const int a_first_time_used = a_requirements->first_time_used; + const int a_last_time_used = a_requirements->last_time_used; + const int a_end_offset = a_start_offset + a_requirements->size; + for (int j = 0; j < buffer_count_; ++j) { + if (i == j) { + continue; + } + BufferRequirements* b_requirements = &requirements_[j]; + const int b_start_offset = buffer_offsets_[j]; + const int b_first_time_used = b_requirements->first_time_used; + const int b_last_time_used = b_requirements->last_time_used; + const int b_end_offset = b_start_offset + b_requirements->size; + if ((a_first_time_used > b_last_time_used) || + (b_first_time_used > a_last_time_used)) { + // Buffers don't overlap in time. + continue; + } + if ((a_start_offset >= b_end_offset) || + (b_start_offset >= a_end_offset)) { + // No overlap in memory. + continue; + } + were_overlaps_found = true; + TF_LITE_REPORT_ERROR( + error_reporter, "Overlap: %d (%d=>%d, %d->%d) vs %d (%d=>%d, %d->%d)", + i, a_first_time_used, a_last_time_used, a_start_offset, a_end_offset, + j, b_first_time_used, b_last_time_used, b_start_offset, b_end_offset); + } + } + return were_overlaps_found; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h new file mode 100644 index 0000000..f5f26a8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/greedy_memory_planner.h @@ -0,0 +1,163 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_GREEDY_MEMORY_PLANNER_H_ +#define TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_GREEDY_MEMORY_PLANNER_H_ + +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/memory_planner/memory_planner.h" + +namespace tflite { + +constexpr int kOnlinePlannedBuffer = -1; + +// A memory planner that uses a greedy algorithm to arrange buffers in memory +// to minimize the overall arena size needed. +// +// The algorithm works like this: +// - The client enters the buffer information through AddBuffer(). +// - When a function like GetOffsetForBuffer() is called, the +// CalculateOffsetsIfNeeded() method is invoked. +// - If an up to date plan is not already present, one will be calculated. +// - The buffers are sorted in descending order of size. +// - The largest buffer is placed at offset zero. +// - The rest of the buffers are looped through in descending size order. +// - The other buffers that need to be in memory at the same time are found. +// - The first gap between simultaneously active buffers that the current +// buffer fits into will be used. +// - If no large-enough gap is found, the current buffer is placed after the +// last buffer that's simultaneously active. +// - This continues until all buffers are placed, and the offsets stored. +// +// This is not guaranteed to produce the best placement, since that's an +// NP-Complete problem, but in practice it should produce one that's decent. +class GreedyMemoryPlanner : public MemoryPlanner { + public: + // You need to pass in an area of memory to be used for planning. This memory + // needs to have a lifetime as long as the planner, but isn't owned by this + // object, so management should be handled by the client. This is so it can be + // stack or globally allocated if necessary on devices without dynamic memory + // allocation. How many buffers can be planned for will depend on the size of + // this scratch memory, so you should enlarge it if you see an error when + // calling AddBuffer(). The memory can be reused once you're done with the + // planner, as long as you copy the calculated offsets to another location. + // Each buffer requires about 36 bytes of scratch. + GreedyMemoryPlanner(unsigned char* scratch_buffer, int scratch_buffer_size); + ~GreedyMemoryPlanner() override; + + // Record details of a buffer we want to place. + TfLiteStatus AddBuffer(ErrorReporter* error_reporter, int size, + int first_time_used, int last_time_used) override; + + // Record details of an offline planned buffer offset we want to place. + // offline_offset is the buffer offset from the start of the arena. + TfLiteStatus AddBuffer(ErrorReporter* error_reporter, int size, + int first_time_used, int last_time_used, + int offline_offset); + + // Returns the high-water mark of used memory. This is the minimum size of a + // memory arena you'd need to allocate to hold these buffers. + size_t GetMaximumMemorySize() override; + + // How many buffers have been recorded. + int GetBufferCount() override; + + // Where a given buffer should be placed in the memory arena. + // This information is stored in the memory arena itself, so once the arena + // is used for inference, it will be overwritten. + TfLiteStatus GetOffsetForBuffer(ErrorReporter* error_reporter, + int buffer_index, int* offset) override; + + // Prints an ascii-art diagram of the buffer layout plan. + void PrintMemoryPlan(ErrorReporter* error_reporter); + + // Debug method to check whether any buffer allocations are overlapping. This + // is an O(N^2) complexity operation, so only use for testing. + bool DoAnyBuffersOverlap(ErrorReporter* error_reporter); + + // Used to store a list of buffers ordered by their offset. + struct ListEntry { + int offset; + int requirements_index; + int next_entry_index; + }; + + // Number of bytes required in order to plan a buffer. + static size_t per_buffer_size() { + const int per_buffer_size = + sizeof(BufferRequirements) + // requirements_ + sizeof(int) + // buffer_sizes_sorted_ + sizeof(int) + // buffer_ids_sorted_ + sizeof(ListEntry) + // buffers_sorted_by_offset_ + sizeof(int); // buffer_offsets_; + return per_buffer_size; + } + + private: + // Whether a buffer is active in a given time range. + bool DoesEntryOverlapInTime(const ListEntry* entry, const int first_time_used, + const int last_time_used) const; + + // Walks the list to return the next buffer that is active in a given time + // range, or a null pointer if there are none. + ListEntry* NextSimultaneouslyActiveBuffer(const ListEntry* start, + const int first_time_used, + const int last_time_used); + + // If there isn't an up to date plan, calculate a new one. + void CalculateOffsetsIfNeeded(); + + // How many buffers we can plan for, based on the arena size we're given in + // the constructor. + int max_buffer_count_; + + // The number of buffers added so far. + int buffer_count_; + + // Records the client-provided information about each buffer. + struct BufferRequirements { + int size; + int offline_offset; + int first_time_used; + int last_time_used; + }; + + // Working arrays used during the layout algorithm. + BufferRequirements* requirements_; + // buffer_sizes_sorted_ and buffer_ids_sorted_ are sorted according to: + // { + // offline planned buffers, + // online planned buffers sorted by size + // } + int* buffer_sizes_sorted_; + int* buffer_ids_sorted_; + ListEntry* buffers_sorted_by_offset_; + int next_free_entry_; // Index of the next free entry of + // buffers_sorted_by_offset_ + int first_entry_index_; // Index of the first entry (smallest offset) of + // buffers_sorted_by_offset_ + + // Stores the outcome of the plan, the location of each buffer in the arena. + int* buffer_offsets_; + + // Whether buffers have been added since the last plan was calculated. + bool need_to_calculate_offsets_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_GREEDY_MEMORY_PLANNER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.cc b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.cc new file mode 100644 index 0000000..d25a4f2 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.cc @@ -0,0 +1,54 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/memory_planner/linear_memory_planner.h" + +namespace tflite { + +LinearMemoryPlanner::LinearMemoryPlanner() + : current_buffer_count_(0), next_free_offset_(0) {} +LinearMemoryPlanner::~LinearMemoryPlanner() {} + +TfLiteStatus LinearMemoryPlanner::AddBuffer( + tflite::ErrorReporter* error_reporter, int size, int first_time_used, + int last_time_used) { + if (current_buffer_count_ >= kMaxBufferCount) { + TF_LITE_REPORT_ERROR(error_reporter, "Too many buffers (max is %d)", + kMaxBufferCount); + return kTfLiteError; + } + buffer_offsets_[current_buffer_count_] = next_free_offset_; + next_free_offset_ += size; + ++current_buffer_count_; + return kTfLiteOk; +} + +size_t LinearMemoryPlanner::GetMaximumMemorySize() { return next_free_offset_; } + +int LinearMemoryPlanner::GetBufferCount() { return current_buffer_count_; } + +TfLiteStatus LinearMemoryPlanner::GetOffsetForBuffer( + tflite::ErrorReporter* error_reporter, int buffer_index, int* offset) { + if ((buffer_index < 0) || (buffer_index >= current_buffer_count_)) { + TF_LITE_REPORT_ERROR(error_reporter, + "buffer index %d is outside range 0 to %d", + buffer_index, current_buffer_count_); + return kTfLiteError; + } + *offset = buffer_offsets_[buffer_index]; + return kTfLiteOk; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.h b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.h new file mode 100644 index 0000000..4d77e77 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/linear_memory_planner.h @@ -0,0 +1,50 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_LINEAR_MEMORY_PLANNER_H_ +#define TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_LINEAR_MEMORY_PLANNER_H_ + +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/memory_planner/memory_planner.h" + +namespace tflite { + +// The simplest possible memory planner that just lays out all buffers at +// increasing offsets without trying to reuse memory. +class LinearMemoryPlanner : public MemoryPlanner { + public: + LinearMemoryPlanner(); + ~LinearMemoryPlanner() override; + + TfLiteStatus AddBuffer(tflite::ErrorReporter* error_reporter, int size, + int first_time_used, int last_time_used) override; + + size_t GetMaximumMemorySize() override; + int GetBufferCount() override; + TfLiteStatus GetOffsetForBuffer(tflite::ErrorReporter* error_reporter, + int buffer_index, int* offset) override; + + private: + static constexpr int kMaxBufferCount = 1024; + size_t buffer_offsets_[kMaxBufferCount]; + int current_buffer_count_; + size_t next_free_offset_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_LINEAR_MEMORY_PLANNER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/memory_planner.h b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/memory_planner.h new file mode 100644 index 0000000..2c39fbe --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/memory_planner/memory_planner.h @@ -0,0 +1,71 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_MEMORY_PLANNER_H_ +#define TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_MEMORY_PLANNER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" + +namespace tflite { + +// Interface class for planning the layout of memory buffers during the +// execution of a graph. +// It's designed to be used by a client that iterates in any order through the +// buffers it wants to lay out, and then calls the getter functions for +// information about the calculated layout. For example: +// +// SomeMemoryPlanner planner; +// planner.AddBuffer(reporter, 100, 0, 1); // Buffer 0 +// planner.AddBuffer(reporter, 50, 2, 3); // Buffer 1 +// planner.AddBuffer(reporter, 50, 2, 3); // Buffer 2 +// +// int offset0; +// TF_EXPECT_OK(planner.GetOffsetForBuffer(reporter, 0, &offset0)); +// int offset1; +// TF_EXPECT_OK(planner.GetOffsetForBuffer(reporter, 1, &offset1)); +// int offset2; +// TF_EXPECT_OK(planner.GetOffsetForBuffer(reporter, 2, &offset2)); +// const int arena_size_needed = planner.GetMaximumMemorySize(); +// +// The goal is for applications to be able to experiment with different layout +// strategies without changing their client code, by swapping out classes that +// implement this interface.= +class MemoryPlanner { + public: + MemoryPlanner() {} + virtual ~MemoryPlanner() {} + + // Pass information about a buffer's size and lifetime to the layout + // algorithm. The order this is called implicitly assigns an index to the + // result, so the buffer information that's passed into the N-th call of + // this method will be used as the buffer_index argument to + // GetOffsetForBuffer(). + virtual TfLiteStatus AddBuffer(tflite::ErrorReporter* error_reporter, + int size, int first_time_used, + int last_time_used) = 0; + + // The largest contiguous block of memory that's needed to hold the layout. + virtual size_t GetMaximumMemorySize() = 0; + // How many buffers have been added to the planner. + virtual int GetBufferCount() = 0; + // Calculated layout offset for the N-th buffer added to the planner. + virtual TfLiteStatus GetOffsetForBuffer(tflite::ErrorReporter* error_reporter, + int buffer_index, int* offset) = 0; +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MEMORY_PLANNER_MEMORY_PLANNER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.cc new file mode 100644 index 0000000..881b9b9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.cc @@ -0,0 +1,1076 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/micro_allocator.h" + +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/flatbuffer_conversions.h" +#include "tensorflow/lite/core/api/op_resolver.h" +#include "tensorflow/lite/core/api/tensor_utils.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/memory_helpers.h" +#include "tensorflow/lite/micro/memory_planner/greedy_memory_planner.h" +#include "tensorflow/lite/micro/memory_planner/memory_planner.h" +#include "tensorflow/lite/micro/micro_op_resolver.h" +#include "tensorflow/lite/micro/simple_memory_allocator.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +namespace { +// Used to hold information used during allocation calculations. +struct AllocationInfo { + size_t bytes; + void** output_ptr; + int first_created; + int last_used; + int32_t offline_offset; + bool needs_allocating; +}; + +// We align tensor buffers to 16-byte boundaries, since this is a common +// requirement for SIMD extensions. +constexpr int kBufferAlignment = 16; +constexpr char kOfflineMemAllocMetadata[] = "OfflineMemoryAllocation"; +const TfLiteIntArray kZeroLengthIntArray = {0, {}}; + +class MicroBuiltinDataAllocator : public BuiltinDataAllocator { + public: + explicit MicroBuiltinDataAllocator(SimpleMemoryAllocator* memory_allocator) + : memory_allocator_(memory_allocator) {} + + void* Allocate(size_t size, size_t alignment_hint) override { + return memory_allocator_->AllocateFromTail(size, alignment_hint); + } + void Deallocate(void* data) override { + // Do not deallocate, builtin data needs to be available for the life time + // of the model. + } + + private: + SimpleMemoryAllocator* memory_allocator_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +#if !defined(__clang__) +// Helper function to check flatbuffer metadata correctness. This function is +// not called by default. Hence it's not linked in to the final binary code. +TfLiteStatus CheckOfflinePlannedOffsets(const Model* model, + ErrorReporter* error_reporter) { + // Suppress compile warning for unused function + (void)CheckOfflinePlannedOffsets; + + if (model->metadata()) { + for (size_t i = 0; i < model->metadata()->size(); ++i) { + auto metadata = model->metadata()->Get(i); + if (strncmp(metadata->name()->c_str(), kOfflineMemAllocMetadata, + strlen(kOfflineMemAllocMetadata)) == 0) { + auto* subgraphs = model->subgraphs(); + const SubGraph* subgraph = (*subgraphs)[0]; + const flatbuffers::Vector>* tensors = + subgraph->tensors(); + const flatbuffers::Vector>* buffers = + model->buffers(); + int nbr_tflite_tensors = tensors->size(); + auto* buffer = (*buffers)[metadata->buffer()]; + auto* array = buffer->data(); + const uint32_t* metadata_buffer = (uint32_t*)array->data(); + int version = metadata_buffer[0]; + int subgraph_idx = metadata_buffer[1]; + const int nbr_offline_offsets = metadata_buffer[2]; +#ifndef TF_LITE_STRIP_ERROR_STRINGS + int* offline_planner_offsets = (int*)&metadata_buffer[3]; +#endif + + TF_LITE_REPORT_ERROR(error_reporter, "==== Model metadata info: ====="); + TF_LITE_REPORT_ERROR(error_reporter, + "Offline planner metadata found, version %d, " + "subgraph %d, nbr offline offsets %d", + version, subgraph_idx, nbr_offline_offsets); + for (int j = 0; j < nbr_offline_offsets; ++j) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Offline planner tensor index %d, offline offset: %d", j, + offline_planner_offsets[j]); + } + + if (version != 1) { + TF_LITE_REPORT_ERROR(error_reporter, "Version not supported! (%d)\n", + version); + return kTfLiteError; + } + if (subgraph_idx != 0) { + TF_LITE_REPORT_ERROR(error_reporter, + "Only 1 subgraph supported! Subgraph idx (%d)\n", + subgraph_idx); + return kTfLiteError; + } + if (nbr_tflite_tensors != nbr_offline_offsets) { + TF_LITE_REPORT_ERROR(error_reporter, + "Nbr of offline buffer offsets (%d) in metadata " + "not equal nbr tensors (%d)\n", + nbr_offline_offsets, nbr_tflite_tensors); + return kTfLiteError; + } + } + } + } + return kTfLiteOk; +} +#endif + +// A helper class to construct AllocationInfo array. This array contains the +// lifetime of tensors / scratch_buffer and will be used to calculate the memory +// plan. Methods need to be called in order from `Init`, `Add*`, to `Finish`. +class AllocationInfoBuilder { + public: + AllocationInfoBuilder(ErrorReporter* reporter, + SimpleMemoryAllocator* allocator) + : reporter_(reporter), allocator_(allocator) {} + + // Initializes the builder by allocating AllocationInfo array from the + // simple memory allocator. + TfLiteStatus Init(size_t tensor_count, size_t scratch_buffer_count) { + tensor_count_ = tensor_count; + buffer_count_ = scratch_buffer_count; + return Allocate(); + } + + // Check if model contains offline planned buffer offsets. + // - If there's no metadata available, offline_planner_offsets is not set + // - If there's metadata available, offline_planner_offsets will point to the + // first offset in the metadata buffer list. + TfLiteStatus GetOfflinePlannedOffsets( + const Model* model, const int32_t** offline_planner_offsets); + + // Add allocaiton information for the tensors. + TfLiteStatus AddTensors(const SubGraph* subgraph, + const int32_t* offline_offsets, + TfLiteEvalTensor* eval_tensors); + + // Add allocation information for the scratch buffers. + TfLiteStatus AddScratchBuffers(internal::ScratchBufferHandle* buffer_handles); + + // Returns a pointer to the built AllocationInfo array. + const AllocationInfo* Finish() const { return info_; } + size_t Size() const { return tensor_count_ + buffer_count_; } + + private: + // Allocate the output AllocationInfo array from the allocator_; + TfLiteStatus Allocate(); + + ErrorReporter* reporter_ = nullptr; + SimpleMemoryAllocator* allocator_ = nullptr; + size_t tensor_count_ = 0; + size_t buffer_count_ = 0; + AllocationInfo* info_ = nullptr; +}; + +TfLiteStatus AllocationInfoBuilder::Allocate() { + size_t bytes = sizeof(AllocationInfo) * Size(); + info_ = reinterpret_cast( + allocator_->AllocateFromTail(bytes, alignof(AllocationInfo))); + if (info_ == nullptr) { + TF_LITE_REPORT_ERROR( + reporter_, + "Failed to allocate memory for allocation_info, %d bytes required", + bytes); + return kTfLiteError; + } + return kTfLiteOk; +} + +TfLiteStatus AllocationInfoBuilder::AddTensors(const SubGraph* subgraph, + const int32_t* offline_offsets, + TfLiteEvalTensor* eval_tensors) { + TFLITE_DCHECK(eval_tensors != nullptr); + + // Set up allocation info for all tensors. + for (size_t i = 0; i < tensor_count_; ++i) { + AllocationInfo* current = &info_[i]; + current->output_ptr = &(eval_tensors[i].data.data); + + TF_LITE_ENSURE_STATUS( + TfLiteEvalTensorByteLength(&eval_tensors[i], ¤t->bytes)); + + current->first_created = -1; + current->last_used = -1; + current->needs_allocating = (eval_tensors[i].data.data == nullptr) && + (!subgraph->tensors()->Get(i)->is_variable()); + if (offline_offsets) { + current->offline_offset = offline_offsets[i]; + } else { + current->offline_offset = kOnlinePlannedBuffer; + } + } + + for (size_t i = 0; i < subgraph->inputs()->size(); ++i) { + const int tensor_index = subgraph->inputs()->Get(i); + AllocationInfo* current = &info_[tensor_index]; + current->first_created = 0; + } + + // Mark all outputs as persistent to the end of the invocation. + for (size_t i = 0; i < subgraph->outputs()->size(); ++i) { + const int tensor_index = subgraph->outputs()->Get(i); + AllocationInfo* current = &info_[tensor_index]; + current->last_used = subgraph->operators()->size() - 1; + } + + // Figure out when the first and last use of each tensor is. + for (int i = (subgraph->operators()->size() - 1); i >= 0; --i) { + const auto* op = subgraph->operators()->Get(i); + for (size_t n = 0; n < op->inputs()->size(); ++n) { + const int tensor_index = op->inputs()->Get(n); + AllocationInfo* current = &info_[tensor_index]; + if (((current->last_used == -1) || (current->last_used < i))) { + current->last_used = i; + } + } + for (size_t n = 0; n < op->outputs()->size(); ++n) { + const int tensor_index = op->outputs()->Get(n); + AllocationInfo* current = &info_[tensor_index]; + if ((current->first_created == -1) || (current->first_created > i)) { + current->first_created = i; + } + } + } + + // Work out which tensors need to be allocated. + for (size_t i = 0; i < tensor_count_; ++i) { + AllocationInfo* current = &info_[i]; + const bool is_read_only = + (current->first_created == -1) && (current->last_used != -1); + if (is_read_only) { + current->needs_allocating = false; + } + const bool has_partial_lifetime = + !is_read_only && + ((current->first_created == -1) || (current->last_used == -1)); + if (has_partial_lifetime && current->needs_allocating) { + TF_LITE_REPORT_ERROR( + reporter_, + "Logic error in memory planner, tensor %d has an invalid lifetime: " + "first_created: %d, last_used: %d", + i, current->first_created, current->last_used); + return kTfLiteError; + } + } + return kTfLiteOk; +} + +// The tensor offsets will be encoded in the metadata:[Metadata] field of the +// Model. The following encoding applies: +// +// | Metadata component | Value | +// | name:string | “OfflineMemoryAllocation” | +// | buffer:unit | Index of buffer containing memory allocation data | +// +// The buffer contents for the memory allocation is a list of 32-bit integers. +// The number of tensors, n, must be equal to the number of tensors defined in +// the model. The following encoding applies: +// +// | Offset | Value | +// | 0 | Offline allocation format version – set to 0 | +// | 1 | Subgraph index to which this allocation applies | +// | 2 | Number offsets following: n | +// | 3 | Arena byte offset of tensor #0 or -1 to allocate at runtime | +// | 4 | Arena byte offset of tensor #1 or -1 to allocate at runtime | +// | 3+(n-1) | Arena byte offset of tensor #(n-1) or -1 to allocate at runtime | +TfLiteStatus AllocationInfoBuilder::GetOfflinePlannedOffsets( + const Model* model, const int32_t** offline_planner_offsets) { + if (model->metadata()) { + for (size_t i = 0; i < model->metadata()->size(); ++i) { + auto metadata = model->metadata()->Get(i); + if (strncmp(metadata->name()->c_str(), kOfflineMemAllocMetadata, + strlen(kOfflineMemAllocMetadata)) == 0) { + const flatbuffers::Vector>* buffers = + model->buffers(); + auto* buffer = (*buffers)[metadata->buffer()]; + auto* array = buffer->data(); + const uint32_t* metadata_buffer = + reinterpret_cast(array->data()); + const size_t nbr_tensors = static_cast(metadata_buffer[2]); + *offline_planner_offsets = + reinterpret_cast(&metadata_buffer[3]); + + if (tensor_count_ != nbr_tensors) { + TF_LITE_REPORT_ERROR(reporter_, + "Nbr of offline buffer offsets (%d) in metadata " + "not equal nbr tensors (%d)\n", + nbr_tensors, tensor_count_); + return kTfLiteError; + } + } + } + } + return kTfLiteOk; +} + +TfLiteStatus AllocationInfoBuilder::AddScratchBuffers( + internal::ScratchBufferHandle* buffer_handles) { + // Set up allocation info for buffers. + for (size_t i = tensor_count_; i < tensor_count_ + buffer_count_; ++i) { + AllocationInfo* current = &info_[i]; + internal::ScratchBufferHandle* handle = + &(buffer_handles[i - tensor_count_]); + current->output_ptr = reinterpret_cast(&handle->data); + current->bytes = handle->bytes; + current->first_created = handle->node_idx; + current->last_used = handle->node_idx; + current->needs_allocating = true; + current->offline_offset = kOnlinePlannedBuffer; + } + return kTfLiteOk; +} + +TfLiteStatus CreatePlan(ErrorReporter* error_reporter, + GreedyMemoryPlanner* planner, + const AllocationInfo* allocation_info, + size_t allocation_info_size) { + // Add the tensors to our allocation plan. + for (size_t i = 0; i < allocation_info_size; ++i) { + const AllocationInfo* current = &allocation_info[i]; + if (current->needs_allocating) { + size_t aligned_bytes_required = + AlignSizeUp(current->bytes, kBufferAlignment); + if (current->offline_offset == kOnlinePlannedBuffer) { + TF_LITE_ENSURE_STATUS( + planner->AddBuffer(error_reporter, aligned_bytes_required, + current->first_created, current->last_used)); + } else { + TF_LITE_ENSURE_STATUS(planner->AddBuffer( + error_reporter, aligned_bytes_required, current->first_created, + current->last_used, current->offline_offset)); + } + } + } + return kTfLiteOk; +} + +TfLiteStatus CommitPlan(ErrorReporter* error_reporter, MemoryPlanner* planner, + uint8_t* starting_point, + const AllocationInfo* allocation_info, + size_t allocation_info_size) { + // Figure out the actual memory addresses for each buffer, based on the plan. + int planner_index = 0; + for (size_t i = 0; i < allocation_info_size; ++i) { + const AllocationInfo* current = &allocation_info[i]; + if (current->needs_allocating) { + int offset = -1; + TF_LITE_ENSURE_STATUS( + planner->GetOffsetForBuffer(error_reporter, planner_index, &offset)); + *current->output_ptr = reinterpret_cast(starting_point + offset); + ++planner_index; + } + } + return kTfLiteOk; +} +} // namespace + +namespace internal { + +// Handles architecture safe mapping of flatbuffer vectors to a TfLite*Array +// struct. Matching types are required (e.g. float and TfLiteFloatArray). +// Big-endian systems will always allocate dimension array data in the tail +// (persistent) section. +template +TfLiteStatus FlatBufferVectorToTfLiteTypeArray( + SimpleMemoryAllocator* allocator, ErrorReporter* error_reporter, + const flatbuffers::Vector* flatbuffer_array, + kTfLiteArrayType** result) { + TFLITE_DCHECK(error_reporter != nullptr); + TFLITE_DCHECK(flatbuffer_array != nullptr); + // TODO(b/159668691): Consider adding type assertion or breaking this function + // into multiple functions for each type. std::is_same is c++11 and has a + // special updated constructor in c++17 that requires a string argument. + if (FLATBUFFERS_LITTLEENDIAN) { + // On little-endian machines, TfLite*Array happens to have the same memory + // layout as flatbuffers:Vector, so we can + // reinterpret_cast the flatbuffer vector and avoid a copy and malloc. + *result = const_cast( + reinterpret_cast(flatbuffer_array)); + } else { + // Big-endian architecture can not use the same memory layout as + // flatbuffers::Vector. Allocate from the tail and + // copy values from the flatbuffer into the newly allocated chunk. + kTfLiteArrayType* array = + reinterpret_cast(allocator->AllocateFromTail( + TfLiteIntArrayGetSizeInBytes(flatbuffer_array->Length()), + alignof(kTfLiteArrayType))); + if (array == nullptr) { + TF_LITE_REPORT_ERROR( + error_reporter, + "Failed to allocate %d bytes of memory to copy an array.", + TfLiteIntArrayGetSizeInBytes(flatbuffer_array->Length())); + return kTfLiteError; + } + array->size = flatbuffer_array->Length(); + for (int i = 0; i < array->size; ++i) { + array->data[i] = flatbuffer_array->Get(i); + } + *result = array; + } + return kTfLiteOk; +} + +// Returns a pointer to any buffer associated with the flatbuffer tensor. Can +// return nullptr if no buffer is found. +void* GetFlatbufferTensorBuffer( + const tflite::Tensor& flatbuffer_tensor, + const flatbuffers::Vector>* buffers) { + // We need to figure out where the actual contents of this tensor are stored + // in memory. We'll check to see if there's a serialized buffer (pretty much + // the same as a constant op in TensorFlow) associated with this tensor first, + // and if there is update the runtime structure to point to its location in + // memory. + // First see if there's any buffer information in the serialized tensor. + // TODO(b/160894903): Add better unit tests that validate flatbuffer values. + void* out_buffer = nullptr; + if (auto* buffer = (*buffers)[flatbuffer_tensor.buffer()]) { + // If we've found a buffer, does it have any data? + if (auto* array = buffer->data()) { + // If it has any data, is the data size larger than zero? + if (array->size()) { + // We've found a buffer with valid data, so update the runtime tensor + // data structure to point to it. + out_buffer = const_cast(static_cast(array->data())); + } + } + // TODO(petewarden): It's not clear in what circumstances we could have a + // buffer in the serialized tensor, but it doesn't have any data in it. Is + // that a validly-generated file, and if so what does it mean, or is it an + // error condition? It would be good to tighten up the specification to make + // it less ambiguous. + } + return out_buffer; +} + +TfLiteStatus InitializeTfLiteTensorFromFlatbuffer( + SimpleMemoryAllocator* allocator, bool allocate_temp, + const tflite::Tensor& flatbuffer_tensor, + const flatbuffers::Vector>* buffers, + ErrorReporter* error_reporter, TfLiteTensor* result) { + TFLITE_DCHECK(result != nullptr); + + *result = {}; + // Make sure the serialized type is one we know how to deal with, and convert + // it from a flatbuffer enum into a constant used by the kernel C API. + TF_LITE_ENSURE_STATUS(ConvertTensorType(flatbuffer_tensor.type(), + &result->type, error_reporter)); + // Make sure we remember if the serialized tensor is designated as a variable. + result->is_variable = flatbuffer_tensor.is_variable(); + + result->data.data = GetFlatbufferTensorBuffer(flatbuffer_tensor, buffers); + + // TODO(petewarden): Some of these paths aren't getting enough testing + // coverage, so we should figure out some tests that exercise them. + if (result->data.data == nullptr) { + // The tensor contents haven't been set from a serialized buffer, so + // make a note that they will be allocated from memory. The actual + // allocation won't happen until later. + result->allocation_type = kTfLiteArenaRw; + } else { + // We set the data from a serialized buffer, so record tha. + result->allocation_type = kTfLiteMmapRo; + } + + // Figure out what the size in bytes of the buffer is and store it. + size_t type_size; + TF_LITE_ENSURE_STATUS(BytesRequiredForTensor( + flatbuffer_tensor, &result->bytes, &type_size, error_reporter)); + + if (flatbuffer_tensor.shape() == nullptr) { + // flatbuffer_tensor.shape() can return a nullptr in the case of a scalar + // tensor. + result->dims = const_cast(&kZeroLengthIntArray); + } else { + // TFLM doesn't allow reshaping the tensor which requires dynamic memory + // allocation so it is safe to drop the const qualifier. In the future, if + // we really want to update the tensor shape, we can always pass in a new + // TfLiteIntArray - especially we have to do so if the dimension is + TF_LITE_ENSURE_STATUS(FlatBufferVectorToTfLiteTypeArray( + allocator, error_reporter, flatbuffer_tensor.shape(), &(result->dims))); + } + + // Copy the quantization information from the serialized data. + const auto* src_quantization = flatbuffer_tensor.quantization(); + if (src_quantization && src_quantization->scale() && + (src_quantization->scale()->size() > 0) && + src_quantization->zero_point() && + (src_quantization->zero_point()->size() > 0)) { + // Always populate the TfLiteTensor.params field, even if there are + // per-channel quantization parameters. + result->params.scale = src_quantization->scale()->Get(0); + // Note that the zero_point field in the FlatBuffers schema is a 64-bit + // integer, but the zero_point field in the TfLiteQuantizationParams struct + // is a 32-bit integer. + result->params.zero_point = + static_cast(src_quantization->zero_point()->Get(0)); + + // Populate per-channel quantization params. + int channels = src_quantization->scale()->size(); + TfLiteAffineQuantization* quantization = + allocate_temp + ? reinterpret_cast( + allocator->AllocateTemp(sizeof(TfLiteAffineQuantization), + alignof(TfLiteAffineQuantization))) + : reinterpret_cast( + allocator->AllocateFromTail( + sizeof(TfLiteAffineQuantization), + alignof(TfLiteAffineQuantization))); + if (quantization == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter, + "Unable to allocate TfLiteAffineQuantization.\n"); + return kTfLiteError; + } + + // TODO(b/153688719): Reduce tail allocation by using a global zero-point + // buffer. This value can not be reused from the flatbuffer since the + // zero_point is stored as a int64_t. + quantization->zero_point = + allocate_temp + ? reinterpret_cast(allocator->AllocateTemp( + TfLiteIntArrayGetSizeInBytes(channels), + alignof(TfLiteIntArray))) + : reinterpret_cast(allocator->AllocateFromTail( + TfLiteIntArrayGetSizeInBytes(channels), + alignof(TfLiteIntArray))); + if (quantization->zero_point == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter, + "Unable to allocate quantization->zero_point.\n"); + return kTfLiteError; + } + + TF_LITE_ENSURE_STATUS(FlatBufferVectorToTfLiteTypeArray( + allocator, error_reporter, src_quantization->scale(), + &quantization->scale)); + + quantization->zero_point->size = channels; + int* zero_point_data = quantization->zero_point->data; + for (int i = 0; i < channels; i++) { + zero_point_data[i] = src_quantization->zero_point()->Get(i); + } + // TODO(rocky): Need to add a micro_allocator test case that fails when + // this is not copied: + quantization->quantized_dimension = src_quantization->quantized_dimension(); + + result->quantization = {kTfLiteAffineQuantization, quantization}; + } + return kTfLiteOk; +} + +TfLiteStatus InitializeTfLiteEvalTensorFromFlatbuffer( + SimpleMemoryAllocator* allocator, const tflite::Tensor& flatbuffer_tensor, + const flatbuffers::Vector>* buffers, + ErrorReporter* error_reporter, TfLiteEvalTensor* result) { + *result = {}; + // Make sure the serialized type is one we know how to deal with, and convert + // it from a flatbuffer enum into a constant used by the kernel C API. + TF_LITE_ENSURE_STATUS(ConvertTensorType(flatbuffer_tensor.type(), + &result->type, error_reporter)); + + result->data.data = GetFlatbufferTensorBuffer(flatbuffer_tensor, buffers); + + if (flatbuffer_tensor.shape() == nullptr) { + // flatbuffer_tensor.shape() can return a nullptr in the case of a scalar + // tensor. + result->dims = const_cast(&kZeroLengthIntArray); + } else { + TF_LITE_ENSURE_STATUS(FlatBufferVectorToTfLiteTypeArray( + allocator, error_reporter, flatbuffer_tensor.shape(), &(result->dims))); + } + return kTfLiteOk; +} + +} // namespace internal + +MicroAllocator::MicroAllocator(SimpleMemoryAllocator* memory_allocator, + ErrorReporter* error_reporter) + : memory_allocator_(memory_allocator), + error_reporter_(error_reporter), + model_is_allocating_(false) {} + +MicroAllocator::~MicroAllocator() {} + +MicroAllocator* MicroAllocator::Create(uint8_t* tensor_arena, size_t arena_size, + ErrorReporter* error_reporter) { + uint8_t* aligned_arena = AlignPointerUp(tensor_arena, kBufferAlignment); + if (aligned_arena != tensor_arena) { + TF_LITE_REPORT_ERROR( + error_reporter, + "%d bytes lost due to alignment. To avoid this loss, please make sure " + "the tensor_arena is 16 bytes aligned.", + aligned_arena - tensor_arena); + } + size_t aligned_arena_size = tensor_arena + arena_size - aligned_arena; + return Create(SimpleMemoryAllocator::Create(error_reporter, aligned_arena, + aligned_arena_size), + error_reporter); +} + +MicroAllocator* MicroAllocator::Create(SimpleMemoryAllocator* memory_allocator, + ErrorReporter* error_reporter) { + TFLITE_DCHECK(memory_allocator != nullptr); + TFLITE_DCHECK(error_reporter != nullptr); + + uint8_t* allocator_buffer = memory_allocator->AllocateFromTail( + sizeof(MicroAllocator), alignof(MicroAllocator)); + MicroAllocator* allocator = + new (allocator_buffer) MicroAllocator(memory_allocator, error_reporter); + return allocator; +} + +TfLiteStatus MicroAllocator::StartModelAllocation( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration** node_and_registrations, + TfLiteEvalTensor** eval_tensors) { + TFLITE_DCHECK(model != nullptr); + + if (model_is_allocating_) { + TF_LITE_REPORT_ERROR(error_reporter_, + "MicroAllocator: Model allocation started before " + "finishing previously allocated model"); + return kTfLiteError; + } + + model_is_allocating_ = true; + + TF_LITE_ENSURE_STATUS(AllocateTfLiteEvalTensors(model, eval_tensors)); + TF_LITE_ENSURE_STATUS( + AllocateNodeAndRegistrations(model, node_and_registrations)); + TF_LITE_ENSURE_STATUS(PrepareNodeAndRegistrationDataFromFlatbuffer( + model, op_resolver, *node_and_registrations)); + + return kTfLiteOk; +} + +TfLiteStatus MicroAllocator::FinishModelAllocation( + const Model* model, TfLiteEvalTensor* eval_tensors) { + if (!model_is_allocating_) { + TF_LITE_REPORT_ERROR(error_reporter_, + "MicroAllocator: Model allocation finished before " + "starting allocating model"); + return kTfLiteError; + } + + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + TF_LITE_ENSURE_STATUS(CommitStaticMemoryPlan(model, subgraph, eval_tensors)); + TF_LITE_ENSURE_STATUS(AllocateVariables(subgraph, eval_tensors)); + + model_is_allocating_ = false; + return kTfLiteOk; +} + +void* MicroAllocator::AllocatePersistentBuffer(size_t bytes) { + return memory_allocator_->AllocateFromTail(bytes, kBufferAlignment); +} + +TfLiteStatus MicroAllocator::RequestScratchBufferInArena(int node_id, + size_t bytes, + int* buffer_idx) { + // A consistency check to make sure scratch_buffer_handles_ is contiguous i.e. + // scratch_buffer_handles_ is pointing to the last allocation from memory + // allocator. + if (scratch_buffer_handles_ != nullptr && + reinterpret_cast(scratch_buffer_handles_) != + memory_allocator_->GetTail()) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Internal error: AllocateFromTail can not be called " + "between two RequestScratchBufferInArena calls."); + return kTfLiteError; + } + + internal::ScratchBufferHandle* handle = + reinterpret_cast( + memory_allocator_->AllocateFromTail( + sizeof(internal::ScratchBufferHandle), + alignof(internal::ScratchBufferHandle))); + if (handle == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to register scratch buffer handle for node %s", + node_id); + return kTfLiteError; + } + *handle = {}; + handle->bytes = bytes; + handle->node_idx = node_id; + *buffer_idx = scratch_buffer_count_; + scratch_buffer_count_ += 1; + // scratch_buffer_handles_ is in reverse order. The following code ensures + // that scratch_buffers[0] is pointing to the newly allocated handle. + scratch_buffer_handles_ = handle; + return kTfLiteOk; +} + +void* MicroAllocator::GetScratchBuffer(int buffer_idx) const { + if (static_cast(buffer_idx) >= scratch_buffer_count_) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Buffer %d not found. %d buffers available.", + buffer_idx, scratch_buffer_count_); + return nullptr; + } + // scratch_buffer_handles_ is in reverse order. + return scratch_buffer_handles_[scratch_buffer_count_ - buffer_idx - 1].data; +} + +size_t MicroAllocator::used_bytes() const { + return memory_allocator_->GetUsedBytes(); +} + +TfLiteStatus MicroAllocator::AllocateNodeAndRegistrations( + const Model* model, NodeAndRegistration** node_and_registrations) { + TFLITE_DCHECK(node_and_registrations); + + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + NodeAndRegistration* output = reinterpret_cast( + memory_allocator_->AllocateFromTail( + sizeof(NodeAndRegistration) * subgraph->operators()->size(), + alignof(NodeAndRegistration))); + if (output == nullptr) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Failed to allocate memory for node_and_registrations."); + return kTfLiteError; + } + *node_and_registrations = output; + return kTfLiteOk; +} + +TfLiteStatus MicroAllocator::PrepareNodeAndRegistrationDataFromFlatbuffer( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration* node_and_registrations) { + TFLITE_DCHECK(model != nullptr); + TFLITE_DCHECK(node_and_registrations != nullptr); + + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + TfLiteStatus status = kTfLiteOk; + auto* opcodes = model->operator_codes(); + MicroBuiltinDataAllocator builtin_data_allocator(memory_allocator_); + for (size_t i = 0; i < subgraph->operators()->size(); ++i) { + const auto* op = subgraph->operators()->Get(i); + const size_t index = op->opcode_index(); + if (index >= opcodes->size()) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Missing registration for opcode_index %d\n", index); + return kTfLiteError; + } + auto* opcode = (*opcodes)[index]; + status = + GetRegistrationFromOpCode(opcode, op_resolver, error_reporter_, + &(node_and_registrations[i].registration)); + if (status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to get registration from op code %s\n ", + EnumNameBuiltinOperator(opcode->builtin_code())); + return status; + } + const auto* registration = node_and_registrations[i].registration; + if (registration == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, "Skipping op for opcode_index %d\n", + index); + return kTfLiteError; + } + BuiltinOperator op_type = + static_cast(registration->builtin_code); + + const char* custom_data = nullptr; + size_t custom_data_size = 0; + unsigned char* builtin_data = nullptr; + + if (op_type == BuiltinOperator_CUSTOM) { + // Custom Ops may or may not have a non-null custom_options field. + if (op->custom_options() != nullptr) { + custom_data = + reinterpret_cast(op->custom_options()->data()); + custom_data_size = op->custom_options()->size(); + } + } else { + if (op->custom_options() != nullptr) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Unsupported behavior: found builtin operator %s with custom " + "options.\n", + EnumNameBuiltinOperator(op_type)); + return kTfLiteError; + } + + MicroOpResolver::BuiltinParseFunction parser = + op_resolver.GetOpDataParser(op_type); + if (parser == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, "Did not find a parser for %s", + EnumNameBuiltinOperator(op_type)); + + return kTfLiteError; + } + TF_LITE_ENSURE_STATUS(parser(op, error_reporter_, &builtin_data_allocator, + (void**)(&builtin_data))); + } + + TfLiteIntArray* inputs_array; + TF_LITE_ENSURE_STATUS(internal::FlatBufferVectorToTfLiteTypeArray( + memory_allocator_, error_reporter_, op->inputs(), &inputs_array)); + + TfLiteIntArray* outputs_array; + TF_LITE_ENSURE_STATUS(internal::FlatBufferVectorToTfLiteTypeArray( + memory_allocator_, error_reporter_, op->outputs(), &outputs_array)); + + TfLiteNode* node = &(node_and_registrations[i].node); + *node = {}; + node->inputs = inputs_array; + node->outputs = outputs_array; + node->builtin_data = reinterpret_cast(builtin_data); + node->custom_initial_data = custom_data; + node->custom_initial_data_size = custom_data_size; + } + + return kTfLiteOk; +} + +TfLiteTensor* MicroAllocator::AllocatePersistentTfLiteTensor( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index) { + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + // This value is allocated from persistent arena space. It is guaranteed to be + // around for the lifetime of the application. + TfLiteTensor* tensor = + AllocatePersistentTfLiteTensorInternal(model, eval_tensors, tensor_index); + + // Populate any fields from the flatbuffer, since this TfLiteTensor struct is + // allocated in the persistent section of the arena, ensure that additional + // allocations also take place in that section of the arena. + if (PopulateTfLiteTensorFromFlatbuffer(model, subgraph, tensor, tensor_index, + /*allocate_temp=*/false) != + kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to populate a persistent TfLiteTensor struct " + "from flatbuffer data!"); + return nullptr; + } + + if (eval_tensors != nullptr) { + // Tensor buffers that are allocated at runtime (e.g. non-weight buffers) + // and not located in the flatbuffer are stored on the pre-allocated list of + // TfLiteEvalTensors structs. These structs are the source of truth, simply + // point the corresponding buffer to the new TfLiteTensor data value. + tensor->data.data = eval_tensors[tensor_index].data.data; + } + return tensor; +} + +TfLiteTensor* MicroAllocator::AllocateTempTfLiteTensor( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index) { + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + // This value is allocated from temporary arena space. It is guaranteed to be + // around for at least the scope of the calling function. Since this struct + // allocation takes place in temp space, no need to own or cleanup. + TfLiteTensor* tensor = + reinterpret_cast(memory_allocator_->AllocateTemp( + sizeof(TfLiteTensor), alignof(TfLiteTensor))); + + // Populate any fields from the flatbuffer, since this TfLiteTensor struct is + // allocated in the temp section of the arena, ensure that additional + // allocations also take place in that section of the arena. + if (PopulateTfLiteTensorFromFlatbuffer(model, subgraph, tensor, tensor_index, + /*allocate_temp=*/true) != kTfLiteOk) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Failed to populate a temp TfLiteTensor struct from flatbuffer data!"); + return nullptr; + } + + if (eval_tensors != nullptr) { + // Tensor buffers that are allocated at runtime (e.g. non-weight buffers) + // and not located in the flatbuffer are stored on the pre-allocated list of + // TfLiteEvalTensors structs. These structs are the source of truth, simply + // point the corresponding buffer to the new TfLiteTensor data value. + tensor->data.data = eval_tensors[tensor_index].data.data; + } + return tensor; +} + +void MicroAllocator::ResetTempAllocations() { + memory_allocator_->ResetTempAllocations(); +} + +TfLiteStatus MicroAllocator::AllocateTfLiteEvalTensors( + const Model* model, TfLiteEvalTensor** eval_tensors) { + TFLITE_DCHECK(eval_tensors != nullptr); + + const SubGraph* subgraph = GetSubGraphFromModel(model); + TFLITE_DCHECK(subgraph != nullptr); + + size_t alloc_count = subgraph->tensors()->size(); + TfLiteEvalTensor* tensors = + reinterpret_cast(memory_allocator_->AllocateFromTail( + sizeof(TfLiteEvalTensor) * alloc_count, alignof(TfLiteEvalTensor))); + if (tensors == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to allocate memory for context->eval_tensors, " + "%d bytes required", + sizeof(TfLiteEvalTensor) * alloc_count); + return kTfLiteError; + } + + for (size_t i = 0; i < alloc_count; ++i) { + TfLiteStatus status = internal::InitializeTfLiteEvalTensorFromFlatbuffer( + memory_allocator_, *subgraph->tensors()->Get(i), model->buffers(), + error_reporter_, &tensors[i]); + if (status != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter_, "Failed to initialize tensor %d", + i); + return kTfLiteError; + } + } + *eval_tensors = tensors; + return kTfLiteOk; +} + +TfLiteStatus MicroAllocator::AllocateVariables(const SubGraph* subgraph, + TfLiteEvalTensor* eval_tensors) { + for (size_t i = 0; i < subgraph->tensors()->size(); ++i) { + auto* tensor = subgraph->tensors()->Get(i); + if (tensor->is_variable()) { + size_t buffer_size; + TF_LITE_ENSURE_STATUS( + TfLiteEvalTensorByteLength(&eval_tensors[i], &buffer_size)); + + eval_tensors[i].data.data = + memory_allocator_->AllocateFromTail(buffer_size, kBufferAlignment); + + if (eval_tensors[i].data.data == nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to allocate variable tensor of size %d", + buffer_size); + return kTfLiteError; + } + } + } + return kTfLiteOk; +} + +TfLiteTensor* MicroAllocator::AllocatePersistentTfLiteTensorInternal( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index) { + return reinterpret_cast(memory_allocator_->AllocateFromTail( + sizeof(TfLiteTensor), alignof(TfLiteTensor))); +} + +TfLiteStatus MicroAllocator::PopulateTfLiteTensorFromFlatbuffer( + const Model* model, const SubGraph* subgraph, TfLiteTensor* tensor, + int tensor_index, bool allocate_temp) { + // TODO(b/160894903): This method serves as a stub to ensure quantized + // allocations in the tail can be recorded. Once all kernels have been ported + // to the new API this can be dropped. + return internal::InitializeTfLiteTensorFromFlatbuffer( + memory_allocator_, allocate_temp, *subgraph->tensors()->Get(tensor_index), + model->buffers(), error_reporter_, tensor); +} + +ErrorReporter* MicroAllocator::error_reporter() const { + return error_reporter_; +} + +const SubGraph* MicroAllocator::GetSubGraphFromModel(const Model* model) { + auto* subgraphs = model->subgraphs(); + if (subgraphs->size() != 1) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Only 1 subgraph is currently supported.\n"); + return nullptr; + } + return (*subgraphs)[0]; +} + +TfLiteStatus MicroAllocator::CommitStaticMemoryPlan( + const Model* model, const SubGraph* subgraph, + TfLiteEvalTensor* eval_tensors) { + size_t head_usage = 0; + // Create static memory plan + // 1. Calculate AllocationInfo to know the lifetime of each tensor/buffer. + // 2. Add them into the planner (such as the GreedyMemoryPlanner). + // 3. Static memory planning using the planner. + // 4. Set tensor/buffer pointers based on the offsets from the previous step. + // Note that AllocationInfo is only needed for creating the plan. It will be + // thrown away when the child allocator (tmp_allocator) goes out of scope. + { + // TODO(b/162595810): Use temp allocation buffer instead of a stack + // instance: + SimpleMemoryAllocator tmp_allocator(error_reporter_, + memory_allocator_->GetBufferHead(), + memory_allocator_->GetTail()); + + AllocationInfoBuilder builder(error_reporter_, &tmp_allocator); + TF_LITE_ENSURE_STATUS( + builder.Init(subgraph->tensors()->size(), scratch_buffer_count_)); + + const int32_t* offline_planner_offsets = nullptr; + TF_LITE_ENSURE_STATUS( + builder.GetOfflinePlannedOffsets(model, &offline_planner_offsets)); + TF_LITE_ENSURE_STATUS( + builder.AddTensors(subgraph, offline_planner_offsets, eval_tensors)); + + TF_LITE_ENSURE_STATUS(builder.AddScratchBuffers(scratch_buffer_handles_)); + const AllocationInfo* allocation_info = builder.Finish(); + + // Remaining arena size that memory planner can use for calculating offsets. + size_t remaining_arena_size = + tmp_allocator.GetAvailableMemory(kBufferAlignment); + uint8_t* planner_arena = + tmp_allocator.AllocateTemp(remaining_arena_size, kBufferAlignment); + TF_LITE_ENSURE(error_reporter_, planner_arena != nullptr); + GreedyMemoryPlanner planner(planner_arena, remaining_arena_size); + TF_LITE_ENSURE_STATUS( + CreatePlan(error_reporter_, &planner, allocation_info, builder.Size())); + + size_t actual_available_arena_size = + memory_allocator_->GetAvailableMemory(kBufferAlignment); + // Make sure we have enough arena size. + if (planner.GetMaximumMemorySize() > actual_available_arena_size) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Arena size is too small for activation buffers. Needed %d but only " + "%d was available.", + planner.GetMaximumMemorySize(), actual_available_arena_size); + return kTfLiteError; + } + + // Commit the plan. + TF_LITE_ENSURE_STATUS(CommitPlan(error_reporter_, &planner, + memory_allocator_->GetBufferHead(), + allocation_info, builder.Size())); + head_usage = planner.GetMaximumMemorySize(); + } + + TF_LITE_ENSURE_STATUS( + memory_allocator_->EnsureHeadSize(head_usage, kBufferAlignment)); + return kTfLiteOk; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.h new file mode 100644 index 0000000..efd11b8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_allocator.h @@ -0,0 +1,250 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. +b/160894903 +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_ALLOCATOR_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_ALLOCATOR_H_ + +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/micro_op_resolver.h" +#include "tensorflow/lite/micro/simple_memory_allocator.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +// Namespace used for unittests. +namespace internal { + +// Sets up all of the data structure members for a TfLiteTensor based on the +// contents of a serialized tensor in the flatbuffer. +// TODO(b/160894903): Once all kernels have been updated to the new +// TfLiteEvalTensor API - drop the allocate_temp flag. This enables internal +// flatbuffer quantization or dimension allocations to take place in either the +// temp or tail section of the arena. +TfLiteStatus InitializeTfLiteTensorFromFlatbuffer( + SimpleMemoryAllocator* allocator, bool allocate_temp, + const tflite::Tensor& flatbuffer_tensor, + const flatbuffers::Vector>* buffers, + ErrorReporter* error_reporter, TfLiteTensor* result); + +// A handle tracking scratch buffer allocation. This handle is created by +// `RequestScratchBufferInArena`. `data` field is populated in +// `FinishModelAllocation` after static memory planning. +// TODO(b/150257460) As a future optimization, this struct could be replaced by +// a union, since once `data` is populated, `bytes` and `node_idx` is not +// needed. +typedef struct { + // Pointer to the scratch buffer. + uint8_t* data; + // Number of bytes required by the buffer. The actual allocated size might be + // greater than `bytes` due to buffer alignment. + size_t bytes; + // Node where the buffer is allocated for. This provides useful information to + // determine the lifetime of the buffer. In AllocationInfo, this buffer will + // have `before` = node_idx and `after` = node_idx. + int node_idx; +} ScratchBufferHandle; +} // namespace internal + +typedef struct { + TfLiteNode node; + const TfLiteRegistration* registration; +} NodeAndRegistration; + +// Allocator responsible for allocating memory for all intermediate tensors +// necessary to invoke a model. +// +// The lifetime of the model, tensor arena and error reporter must be at +// least as long as that of the allocator object, since the allocator needs +// them to be accessible during its entire lifetime. +// +// The MicroAllocator simply plans out additional allocations that are required +// to standup a model for inference in TF Micro. This class currently relies on +// an additional allocator - SimpleMemoryAllocator - for all allocations from an +// arena. These allocations are divided into head (non-persistent) and tail +// (persistent) regions: +// +// Memory layout to help understand how it works +// This information could change in the future version. +// ************** .memory_allocator->GetBuffer() +// Tensors/Scratch buffers (head) +// ************** .head_watermark +// unused memory +// ************** .memory_allocator->GetBuffer() + ->GetMaxBufferSize() +// - ->GetDataSize() +// persistent area (tail) +// ************** .memory_allocator->GetBuffer() + ->GetMaxBufferSize() +class MicroAllocator { + public: + // Creates a MicroAllocator instance from a given tensor arena. This arena + // will be managed by the created instance. + // Note: Please use __declspec(align(16)) to make sure tensor_arena is 16 + // bytes aligned, otherwise some head room will be wasted. + // TODO(b/157615197): Cleanup constructor + factory usage. + static MicroAllocator* Create(uint8_t* tensor_arena, size_t arena_size, + ErrorReporter* error_reporter); + + // Creates a MicroAllocator instance using the provided SimpleMemoryAllocator + // intance. This allocator instance will use the SimpleMemoryAllocator + // instance to manage allocations internally. + static MicroAllocator* Create(SimpleMemoryAllocator* memory_allocator, + ErrorReporter* error_reporter); + + // Begin allocating internal resources required for model inference. + // This method will run through the flatbuffer data supplied in the model to + // properly allocate tensor, node, and op registration data. This method is + // expected to be followed with a call to FinishModelAllocation() before + // resuming allocation with another model. All persistent tensor buffers are + // stored in the out-param eval_tensors. This value is allocated from the + // persistent memory arena and will be used to host runtime tensor buffers. + TfLiteStatus StartModelAllocation( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration** node_and_registrations, + TfLiteEvalTensor** eval_tensors); + + // Finish allocating internal resources required for model inference. + // This method will plan non-persistent buffers and commit a memory plan to + // the 'head' section of the memory arena. All variable tensor data will also + // be allocated. This method should be called after assigning model resources + // in StartModelAllocation(). The eval_tensors pointer should be the value + // passed into this class during StartModelAllocation(). + TfLiteStatus FinishModelAllocation(const Model* model, + TfLiteEvalTensor* eval_tensors); + + // Allocates a TfLiteTensor struct and populates the returned value with + // properties from the model flatbuffer. This struct is allocated from + // persistent arena memory is only guaranteed for the lifetime of the + // application. The eval_tensors pointer should be the value passed into this + // class during StartModelAllocation() and contains the source-of-truth for + // buffers. + virtual TfLiteTensor* AllocatePersistentTfLiteTensor( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index); + + // Allocates a TfLiteTensor struct and populates the returned value with + // properties from the model flatbuffer. This struct is allocated from + // temporary arena memory is only guaranteed until a call is made to + // ResetTempAllocations(). The eval_tensors pointer should be the value passed + // into this class during StartModelAllocation() and contains the + // source-of-truth for buffers. + virtual TfLiteTensor* AllocateTempTfLiteTensor(const Model* model, + TfLiteEvalTensor* eval_tensors, + int tensor_index); + + // Resets all temporary allocations. This method should be called after a + // chain of temp allocations (e.g. chain of TfLiteTensor objects via + // AllocateTfLiteTensor()). + virtual void ResetTempAllocations(); + + // Allocates persistent buffer which has the same life time as the allocator. + // The memory is immediately available and is allocated from the tail of the + // arena. + void* AllocatePersistentBuffer(size_t bytes); + + // Register a scratch buffer of size `bytes` for Node with `node_id`. + // This method only allocates a BufferHandle holding information for memory + // planning. The buffer ptr is ready after `FinishModelAllocation` and can + // be retrieved by `GetScratchBuffer` method using the returned buffer_idx. + // Note that there should be no tail allocation between two consecutive + // `RequestScratchBufferInArena` calls. + TfLiteStatus RequestScratchBufferInArena(int node_id, size_t bytes, + int* buffer_idx); + // Returns the pointer to the planned scratch buffer. + void* GetScratchBuffer(int buffer_idx) const; + + // Returns the arena usage in bytes, only available after + // `FinishModelAllocation`. Otherwise, it will return 0. + size_t used_bytes() const; + + protected: + MicroAllocator(SimpleMemoryAllocator* memory_allocator, + ErrorReporter* error_reporter); + virtual ~MicroAllocator(); + + // Allocates an array in the arena to hold pointers to the node and + // registration pointers required to represent the inference graph of the + // model. + virtual TfLiteStatus AllocateNodeAndRegistrations( + const Model* model, NodeAndRegistration** node_and_registrations); + + // Populates node and registration pointers representing the inference graph + // of the model from values inside the flatbuffer (loaded from the TfLiteModel + // instance). Persistent data (e.g. operator data) is allocated from the + // arena. + virtual TfLiteStatus PrepareNodeAndRegistrationDataFromFlatbuffer( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration* node_and_registrations); + + // Allocates the list of persistent TfLiteEvalTensors that are used for the + // "eval" phase of model inference. These structs will be the source of truth + // for all tensor buffers. Allocation results are stored in the out-param + // eval_tensors. + virtual TfLiteStatus AllocateTfLiteEvalTensors( + const Model* model, TfLiteEvalTensor** eval_tensors); + + // Allocates persistent tensor buffers for variable tensors in the subgraph. + virtual TfLiteStatus AllocateVariables(const SubGraph* subgraph, + TfLiteEvalTensor* eval_tensors); + + // TODO(b/160894903): Once all kernels have been updated to the new API drop + // this method. It is only used to record TfLiteTensor persistent allocations. + virtual TfLiteTensor* AllocatePersistentTfLiteTensorInternal( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index); + + // Populates a TfLiteTensor struct with data from the model flatbuffer. Any + // quantization data is allocated from either the tail (persistent) or temp + // sections of the arena based on the allocation flag. + // TODO(b/160894903): Once all kernels have been updated to the new API drop + // this function since all allocations for quantized data will take place in + // the temp section. + virtual TfLiteStatus PopulateTfLiteTensorFromFlatbuffer( + const Model* model, const SubGraph* subgraph, TfLiteTensor* tensor, + int tensor_index, bool allocate_temp); + + ErrorReporter* error_reporter() const; + + // Returns the first subgraph from the model. + const SubGraph* GetSubGraphFromModel(const Model* model); + + private: + // Commits a memory plan for all non-persistent buffer allocations in the + // 'head' section of the memory arena. The eval_tensors pointer is the list of + // pre-allocated TfLiteEvalTensor structs that will point to the buffers that + // will be allocated into the head section in this function call. + virtual TfLiteStatus CommitStaticMemoryPlan(const Model* model, + const SubGraph* subgraph, + TfLiteEvalTensor* eval_tensors); + + // A simple memory allocator that always allocate from the arena tail or head. + SimpleMemoryAllocator* memory_allocator_; + + ErrorReporter* error_reporter_; + bool model_is_allocating_; + + // In reverse order for efficiency. + // i.e. scratch_buffer_handles_[0] is the handle for the last buffer, + // corresponding to the last RequestScratchBufferInArena call. + internal::ScratchBufferHandle* scratch_buffer_handles_ = nullptr; + // How many scratch buffers have been allocated. + size_t scratch_buffer_count_ = 0; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite +#endif // TENSORFLOW_LITE_MICRO_MICRO_ALLOCATOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.cc new file mode 100644 index 0000000..6d8361c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.cc @@ -0,0 +1,41 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/micro_error_reporter.h" + +#include + +#ifndef TF_LITE_STRIP_ERROR_STRINGS +#include "tensorflow/lite/micro/debug_log.h" +#include "tensorflow/lite/micro/micro_string.h" +#endif + +namespace tflite { + +int MicroErrorReporter::Report(const char* format, va_list args) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + // Only pulling in the implementation of this function for builds where we + // expect to make use of it to be extra cautious about not increasing the code + // size. + static constexpr int kMaxLogLen = 256; + char log_buffer[kMaxLogLen]; + MicroVsnprintf(log_buffer, kMaxLogLen, format, args); + DebugLog(log_buffer); + DebugLog("\r\n"); +#endif + return 0; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.h new file mode 100644 index 0000000..e2c073a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_error_reporter.h @@ -0,0 +1,36 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_ERROR_REPORTER_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_ERROR_REPORTER_H_ + +#include + +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/micro/compatibility.h" + +namespace tflite { + +class MicroErrorReporter : public ErrorReporter { + public: + ~MicroErrorReporter() override {} + int Report(const char* format, va_list args) override; + + private: + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_ERROR_REPORTER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.cc new file mode 100644 index 0000000..8c2f8e0 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.cc @@ -0,0 +1,447 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/micro/micro_interpreter.h" + +#include +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/tensor_utils.h" +#include "tensorflow/lite/micro/memory_helpers.h" +#include "tensorflow/lite/micro/micro_allocator.h" +#include "tensorflow/lite/micro/micro_op_resolver.h" +#include "tensorflow/lite/micro/micro_profiler.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { +namespace { + +#ifndef TF_LITE_STRIP_ERROR_STRINGS +const char* OpNameFromRegistration(const TfLiteRegistration* registration) { + if (registration->builtin_code == BuiltinOperator_CUSTOM) { + return registration->custom_name; + } else { + return EnumNameBuiltinOperator(BuiltinOperator(registration->builtin_code)); + } +} +#endif // !defined(TF_LITE_STRIP_ERROR_STRINGS) + +} // namespace + +namespace internal { + +ContextHelper::ContextHelper(ErrorReporter* error_reporter, + MicroAllocator* allocator, const Model* model) + : allocator_(allocator), error_reporter_(error_reporter), model_(model) {} + +void* ContextHelper::AllocatePersistentBuffer(TfLiteContext* ctx, + size_t bytes) { + return reinterpret_cast(ctx->impl_) + ->allocator_->AllocatePersistentBuffer(bytes); +} + +TfLiteStatus ContextHelper::RequestScratchBufferInArena(TfLiteContext* ctx, + size_t bytes, + int* buffer_idx) { + ContextHelper* helper = reinterpret_cast(ctx->impl_); + return helper->allocator_->RequestScratchBufferInArena( + helper->current_node_idx_, bytes, buffer_idx); +} + +void* ContextHelper::GetScratchBuffer(TfLiteContext* ctx, int buffer_idx) { + return reinterpret_cast(ctx->impl_) + ->allocator_->GetScratchBuffer(buffer_idx); +} + +void ContextHelper::ReportOpError(struct TfLiteContext* context, + const char* format, ...) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + ContextHelper* helper = static_cast(context->impl_); + va_list args; + va_start(args, format); + TF_LITE_REPORT_ERROR(helper->error_reporter_, format, args); + va_end(args); +#endif +} + +TfLiteTensor* ContextHelper::GetTensor(const struct TfLiteContext* context, + int tensor_idx) { + ContextHelper* helper = static_cast(context->impl_); + return helper->allocator_->AllocateTempTfLiteTensor( + helper->model_, helper->eval_tensors_, tensor_idx); +} + +TfLiteEvalTensor* ContextHelper::GetEvalTensor( + const struct TfLiteContext* context, int tensor_idx) { + ContextHelper* helper = reinterpret_cast(context->impl_); + return &helper->eval_tensors_[tensor_idx]; +} + +void ContextHelper::SetNodeIndex(int idx) { current_node_idx_ = idx; } + +void ContextHelper::SetTfLiteEvalTensors(TfLiteEvalTensor* eval_tensors) { + eval_tensors_ = eval_tensors; +} + +} // namespace internal + +MicroInterpreter::MicroInterpreter(const Model* model, + const MicroOpResolver& op_resolver, + uint8_t* tensor_arena, + size_t tensor_arena_size, + ErrorReporter* error_reporter, + tflite::Profiler* profiler) + : model_(model), + op_resolver_(op_resolver), + error_reporter_(error_reporter), + allocator_(*MicroAllocator::Create(tensor_arena, tensor_arena_size, + error_reporter)), + tensors_allocated_(false), + initialization_status_(kTfLiteError), + eval_tensors_(nullptr), + context_helper_(error_reporter_, &allocator_, model), + input_tensor_(nullptr), + output_tensor_(nullptr) { + Init(profiler); +} + +MicroInterpreter::MicroInterpreter(const Model* model, + const MicroOpResolver& op_resolver, + MicroAllocator* allocator, + ErrorReporter* error_reporter, + tflite::Profiler* profiler) + : model_(model), + op_resolver_(op_resolver), + error_reporter_(error_reporter), + allocator_(*allocator), + tensors_allocated_(false), + initialization_status_(kTfLiteError), + eval_tensors_(nullptr), + context_helper_(error_reporter_, &allocator_, model), + input_tensor_(nullptr), + output_tensor_(nullptr) { + Init(profiler); +} + +MicroInterpreter::~MicroInterpreter() { + if (node_and_registrations_ != nullptr) { + for (size_t i = 0; i < subgraph_->operators()->size(); ++i) { + TfLiteNode* node = &(node_and_registrations_[i].node); + const TfLiteRegistration* registration = + node_and_registrations_[i].registration; + // registration is allocated outside the interpreter, so double check to + // make sure it's not nullptr; + if (registration != nullptr && registration->free != nullptr) { + registration->free(&context_, node->user_data); + } + } + } +} + +void MicroInterpreter::Init(tflite::Profiler* profiler) { + const flatbuffers::Vector>* subgraphs = + model_->subgraphs(); + if (subgraphs->size() != 1) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Only 1 subgraph is currently supported.\n"); + initialization_status_ = kTfLiteError; + return; + } + subgraph_ = (*subgraphs)[0]; + + context_.impl_ = static_cast(&context_helper_); + context_.ReportError = context_helper_.ReportOpError; + context_.GetTensor = context_helper_.GetTensor; + context_.GetEvalTensor = context_helper_.GetEvalTensor; + context_.recommended_num_threads = 1; + context_.profiler = profiler; + + initialization_status_ = kTfLiteOk; +} + +void MicroInterpreter::CorrectTensorEndianness(TfLiteEvalTensor* tensorCorr) { + int32_t tensorSize = 1; + for (int d = 0; d < tensorCorr->dims->size; ++d) + tensorSize *= reinterpret_cast(tensorCorr->dims->data)[d]; + + switch (tensorCorr->type) { + case TfLiteType::kTfLiteFloat32: + CorrectTensorDataEndianness(tensorCorr->data.f, tensorSize); + break; + case TfLiteType::kTfLiteFloat16: + CorrectTensorDataEndianness(tensorCorr->data.f16, tensorSize); + break; + case TfLiteType::kTfLiteInt64: + CorrectTensorDataEndianness(tensorCorr->data.i64, tensorSize); + break; + case TfLiteType::kTfLiteInt32: + CorrectTensorDataEndianness(tensorCorr->data.i32, tensorSize); + break; + case TfLiteType::kTfLiteInt16: + CorrectTensorDataEndianness(tensorCorr->data.i16, tensorSize); + break; + case TfLiteType::kTfLiteComplex64: + CorrectTensorDataEndianness(tensorCorr->data.c64, tensorSize); + break; + case TfLiteType::kTfLiteComplex128: + CorrectTensorDataEndianness(tensorCorr->data.c128, tensorSize); + break; + default: + // Do nothing for other data types. + break; + } +} + +template +void MicroInterpreter::CorrectTensorDataEndianness(T* data, int32_t size) { + for (int32_t i = 0; i < size; ++i) { + data[i] = flatbuffers::EndianScalar(data[i]); + } +} + +TfLiteStatus MicroInterpreter::AllocateTensors() { + if (allocator_.StartModelAllocation(model_, op_resolver_, + &node_and_registrations_, + &eval_tensors_) != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed starting model allocation.\n"); + initialization_status_ = kTfLiteError; + return kTfLiteError; + } + + // Update the pointer now that TfLiteEvalTensor allocation has completed on + // the context helper. + // TODO(b/16157777): This call would not be needed if ContextHelper rolled + // into the interpreter. + context_helper_.SetTfLiteEvalTensors(eval_tensors_); + + // If the system is big endian then convert weights from the flatbuffer from + // little to big endian on startup so that it does not need to be done during + // inference. + // NOTE: This requires that the flatbuffer is held in memory which can be + // modified by this process. + if (!FLATBUFFERS_LITTLEENDIAN) { + for (size_t t = 0; t < subgraph_->tensors()->size(); ++t) { + if (auto* buffer = + (*model_->buffers())[subgraph_->tensors()->Get(t)->buffer()]) { + // If we've found a buffer, does it have any data? + if (auto* array = buffer->data()) { + // If it has any data, is the data size larger than zero? + if (array->size()) { + // Update the endianness of the corresponding eval tensor since that + // struct holds the buffer used at inference time. + CorrectTensorEndianness(&eval_tensors_[t]); + } + } + } + } + } + + // Only allow AllocatePersistentBuffer in Init stage. + context_.AllocatePersistentBuffer = context_helper_.AllocatePersistentBuffer; + context_.RequestScratchBufferInArena = nullptr; + context_.GetScratchBuffer = nullptr; + + for (size_t i = 0; i < subgraph_->operators()->size(); ++i) { + context_helper_.SetNodeIndex(i); + auto* node = &(node_and_registrations_[i].node); + auto* registration = node_and_registrations_[i].registration; + size_t init_data_size; + const char* init_data; + if (registration->builtin_code == BuiltinOperator_CUSTOM) { + init_data = reinterpret_cast(node->custom_initial_data); + init_data_size = node->custom_initial_data_size; + } else { + init_data = reinterpret_cast(node->builtin_data); + init_data_size = 0; + } + if (registration->init) { + node->user_data = + registration->init(&context_, init_data, init_data_size); + } + } + context_helper_.SetNodeIndex(-1); + + // Both AllocatePersistentBuffer and RequestScratchBufferInArena is + // available in Prepare stage. + context_.RequestScratchBufferInArena = + context_helper_.RequestScratchBufferInArena; + for (size_t i = 0; i < subgraph_->operators()->size(); ++i) { + // Set node idx to annotate the lifetime for scratch buffers. + context_helper_.SetNodeIndex(i); + auto* node = &(node_and_registrations_[i].node); + auto* registration = node_and_registrations_[i].registration; + if (registration->prepare) { + TfLiteStatus prepare_status = registration->prepare(&context_, node); + if (prepare_status != kTfLiteOk) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Node %s (number %df) failed to prepare with status %d", + OpNameFromRegistration(registration), i, prepare_status); + return kTfLiteError; + } + } + allocator_.ResetTempAllocations(); + } + context_helper_.SetNodeIndex(-1); + + // Prepare is done, we're ready for Invoke. Memory allocation is no longer + // allowed. Kernels can only fetch scratch buffers via GetScratchBuffer. + context_.AllocatePersistentBuffer = nullptr; + context_.RequestScratchBufferInArena = nullptr; + context_.GetScratchBuffer = context_helper_.GetScratchBuffer; + + TF_LITE_ENSURE_OK(&context_, + allocator_.FinishModelAllocation(model_, eval_tensors_)); + TF_LITE_ENSURE_STATUS(ResetVariableTensors()); + + tensors_allocated_ = true; + return kTfLiteOk; +} + +TfLiteStatus MicroInterpreter::Invoke() { + if (initialization_status_ != kTfLiteOk) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Invoke() called after initialization failed\n"); + return kTfLiteError; + } + + // Ensure tensors are allocated before the interpreter is invoked to avoid + // difficult to debug segfaults. + if (!tensors_allocated_) { + TF_LITE_ENSURE_OK(&context_, AllocateTensors()); + } + + for (size_t i = 0; i < subgraph_->operators()->size(); ++i) { + auto* node = &(node_and_registrations_[i].node); + auto* registration = node_and_registrations_[i].registration; + + if (registration->invoke) { + TfLiteStatus invoke_status; +#ifndef NDEBUG // Omit profiler overhead from release builds. + // The case where profiler == nullptr is handled by + // ScopedOperatorProfile. + tflite::Profiler* profiler = + reinterpret_cast(context_.profiler); + ScopedOperatorProfile scoped_profiler( + profiler, OpNameFromRegistration(registration), i); +#endif + invoke_status = registration->invoke(&context_, node); + + // All TfLiteTensor structs used in the kernel are allocated from temp + // memory in the allocator. This creates a chain of allocations in the + // temp section. The call below resets the chain of allocations to + // prepare for the next call. + allocator_.ResetTempAllocations(); + + if (invoke_status == kTfLiteError) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Node %s (number %d) failed to invoke with status %d", + OpNameFromRegistration(registration), i, invoke_status); + return kTfLiteError; + } else if (invoke_status != kTfLiteOk) { + return invoke_status; + } + } + } + return kTfLiteOk; +} + +TfLiteTensor* MicroInterpreter::input(size_t index) { + const size_t length = inputs_size(); + if (index >= length) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Input index %d out of range (length is %d)", index, + length); + return nullptr; + } + if (index != 0) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Input tensors not at index 0 are allocated from the " + "persistent memory arena. Repeat calls will cause excess " + "allocation!"); + return allocator_.AllocatePersistentTfLiteTensor(model_, eval_tensors_, + inputs().Get(index)); + } + if (input_tensor_ == nullptr) { + input_tensor_ = allocator_.AllocatePersistentTfLiteTensor( + model_, eval_tensors_, inputs().Get(index)); + } + return input_tensor_; +} + +TfLiteTensor* MicroInterpreter::output(size_t index) { + const size_t length = outputs_size(); + if (index >= length) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Output index %d out of range (length is %d)", index, + length); + return nullptr; + } + if (index != 0) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Output tensors not at index 0 are allocated from the " + "persistent memory arena. Repeat calls will cause excess " + "allocation!"); + return allocator_.AllocatePersistentTfLiteTensor(model_, eval_tensors_, + outputs().Get(index)); + } + if (output_tensor_ == nullptr) { + // TODO(b/160894903): This API will allocate TfLiteTensor structs from + // persistent (tail) memory and cache on this pointer. + output_tensor_ = allocator_.AllocatePersistentTfLiteTensor( + model_, eval_tensors_, outputs().Get(index)); + } + return output_tensor_; +} + +TfLiteTensor* MicroInterpreter::tensor(size_t index) { + const size_t length = tensors_size(); + if (index >= length) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Tensor index %d out of range (length is %d)", index, + length); + return nullptr; + } + return allocator_.AllocatePersistentTfLiteTensor(model_, eval_tensors_, + index); +} + +TfLiteStatus MicroInterpreter::ResetVariableTensors() { + for (size_t i = 0; i < subgraph_->tensors()->size(); ++i) { + auto* tensor = subgraph_->tensors()->Get(i); + if (tensor->is_variable()) { + size_t buffer_size; + TF_LITE_ENSURE_STATUS( + TfLiteEvalTensorByteLength(&eval_tensors_[i], &buffer_size)); + + int value = 0; + if (tensor->type() == tflite::TensorType_INT8) { + value = tensor->quantization()->zero_point()->Get(0); + } + memset(eval_tensors_[i].data.raw, value, buffer_size); + } + } + + return kTfLiteOk; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.h new file mode 100644 index 0000000..67d7457 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_interpreter.h @@ -0,0 +1,208 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_INTERPRETER_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_INTERPRETER_H_ + +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/profiler.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/micro/micro_allocator.h" +#include "tensorflow/lite/micro/micro_op_resolver.h" +#include "tensorflow/lite/schema/schema_generated.h" +#include "tensorflow/lite/type_to_tflitetype.h" + +namespace tflite { + +namespace internal { + +// A helper class to encapsulate the implementation of APIs in Context. +// context->impl_ points to an instance of this class. +// Check tensorflow/lite/c/common.h for detailed descriptions. +// TODO(b/16157777): Consider rolling this class into MicroInterpreter. +class ContextHelper { + public: + explicit ContextHelper(ErrorReporter* error_reporter, + MicroAllocator* allocator, const Model* model); + + // Functions that will be assigned to function pointers on TfLiteContext: + static void* AllocatePersistentBuffer(TfLiteContext* ctx, size_t bytes); + static TfLiteStatus RequestScratchBufferInArena(TfLiteContext* ctx, + size_t bytes, + int* buffer_idx); + static void* GetScratchBuffer(TfLiteContext* ctx, int buffer_idx); + static void ReportOpError(struct TfLiteContext* context, const char* format, + ...); + static TfLiteTensor* GetTensor(const struct TfLiteContext* context, + int tensor_idx); + static TfLiteEvalTensor* GetEvalTensor(const struct TfLiteContext* context, + int tensor_idx); + + // Sets the current node index to assist with scratch buffer allocations: + void SetNodeIndex(int idx); + + // Sets the pointer to a list of TfLiteEvalTensor instances. + void SetTfLiteEvalTensors(TfLiteEvalTensor* eval_tensors); + + private: + MicroAllocator* allocator_; + ErrorReporter* error_reporter_; + const Model* model_; + TfLiteEvalTensor* eval_tensors_; + int current_node_idx_ = -1; +}; + +} // namespace internal + +class MicroInterpreter { + public: + // The lifetime of the model, op resolver, tensor arena, error reporter and + // profiler must be at least as long as that of the interpreter object, since + // the interpreter may need to access them at any time. This means that you + // should usually create them with the same scope as each other, for example + // having them all allocated on the stack as local variables through a + // top-level function. The interpreter doesn't do any deallocation of any of + // the pointed-to objects, ownership remains with the caller. + MicroInterpreter(const Model* model, const MicroOpResolver& op_resolver, + uint8_t* tensor_arena, size_t tensor_arena_size, + ErrorReporter* error_reporter, + tflite::Profiler* profiler = nullptr); + + // Create an interpreter instance using an existing MicroAllocator instance. + // This constructor should be used when creating an allocator that needs to + // have allocation handled in more than one interpreter or for recording + // allocations inside the interpreter. The lifetime of the allocator must be + // as long as that of the interpreter object. + MicroInterpreter(const Model* model, const MicroOpResolver& op_resolver, + MicroAllocator* allocator, ErrorReporter* error_reporter, + tflite::Profiler* profiler = nullptr); + + ~MicroInterpreter(); + + // Runs through the model and allocates all necessary input, output and + // intermediate tensors. + TfLiteStatus AllocateTensors(); + + // In order to support partial graph runs for strided models, this can return + // values other than kTfLiteOk and kTfLiteError. + // TODO(b/149795762): Add this to the TfLiteStatus enum. + TfLiteStatus Invoke(); + + size_t tensors_size() const { return context_.tensors_size; } + TfLiteTensor* tensor(size_t tensor_index); + template + T* typed_tensor(int tensor_index) { + if (TfLiteTensor* tensor_ptr = tensor(tensor_index)) { + if (tensor_ptr->type == typeToTfLiteType()) { + return GetTensorData(tensor_ptr); + } + } + return nullptr; + } + + TfLiteTensor* input(size_t index); + size_t inputs_size() const { return subgraph_->inputs()->Length(); } + const flatbuffers::Vector& inputs() const { + return *subgraph_->inputs(); + } + TfLiteTensor* input_tensor(size_t index) { return input(index); } + template + T* typed_input_tensor(int tensor_index) { + if (TfLiteTensor* tensor_ptr = input_tensor(tensor_index)) { + if (tensor_ptr->type == typeToTfLiteType()) { + return GetTensorData(tensor_ptr); + } + } + return nullptr; + } + + TfLiteTensor* output(size_t index); + size_t outputs_size() const { return subgraph_->outputs()->Length(); } + const flatbuffers::Vector& outputs() const { + return *subgraph_->outputs(); + } + TfLiteTensor* output_tensor(size_t index) { return output(index); } + template + T* typed_output_tensor(int tensor_index) { + if (TfLiteTensor* tensor_ptr = output_tensor(tensor_index)) { + if (tensor_ptr->type == typeToTfLiteType()) { + return GetTensorData(tensor_ptr); + } + } + return nullptr; + } + + // Reset all variable tensors to the default value. + TfLiteStatus ResetVariableTensors(); + + TfLiteStatus initialization_status() const { return initialization_status_; } + + size_t operators_size() const { return subgraph_->operators()->size(); } + + // For debugging only. + const NodeAndRegistration node_and_registration(int node_index) const { + return node_and_registrations_[node_index]; + } + + // For debugging only. + // Returns the actual used arena in bytes. This method gives the optimal arena + // size. It's only available after `AllocateTensors` has been called. + // Note that normally `tensor_arena` requires 16 bytes alignment to fully + // utilize the space. If it's not the case, the optimial arena size would be + // arena_used_bytes() + 16. + size_t arena_used_bytes() const { return allocator_.used_bytes(); } + + protected: + const MicroAllocator& allocator() const { return allocator_; } + const TfLiteContext& context() const { return context_; } + + private: + // TODO(b/158263161): Consider switching to Create() function to enable better + // error reporting during initialization. + void Init(tflite::Profiler* profiler); + + void CorrectTensorEndianness(TfLiteEvalTensor* tensorCorr); + + template + void CorrectTensorDataEndianness(T* data, int32_t size); + + NodeAndRegistration* node_and_registrations_ = nullptr; + + const Model* model_; + const MicroOpResolver& op_resolver_; + ErrorReporter* error_reporter_; + TfLiteContext context_ = {}; + MicroAllocator& allocator_; + bool tensors_allocated_; + + TfLiteStatus initialization_status_; + + const SubGraph* subgraph_; + TfLiteEvalTensor* eval_tensors_; + internal::ContextHelper context_helper_; + + // TODO(b/160894903): Clean these pointers up when all APIs are updated to new + // TfLiteEvalTensor buffers. + TfLiteTensor* input_tensor_; + TfLiteTensor* output_tensor_; +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_INTERPRETER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_mutable_op_resolver.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_mutable_op_resolver.h new file mode 100644 index 0000000..834b464 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_mutable_op_resolver.h @@ -0,0 +1,458 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_MUTABLE_OP_RESOLVER_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_MUTABLE_OP_RESOLVER_H_ + +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/flatbuffer_conversions.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/kernels/micro_ops.h" +#include "tensorflow/lite/micro/micro_op_resolver.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +template +class MicroMutableOpResolver : public MicroOpResolver { + public: + explicit MicroMutableOpResolver(ErrorReporter* error_reporter = nullptr) + : error_reporter_(error_reporter) {} + + const TfLiteRegistration* FindOp(tflite::BuiltinOperator op) const override { + if (op == BuiltinOperator_CUSTOM) return nullptr; + + for (unsigned int i = 0; i < registrations_len_; ++i) { + const TfLiteRegistration& registration = registrations_[i]; + if (registration.builtin_code == op) { + return ®istration; + } + } + return nullptr; + } + + const TfLiteRegistration* FindOp(const char* op) const override { + for (unsigned int i = 0; i < registrations_len_; ++i) { + const TfLiteRegistration& registration = registrations_[i]; + if ((registration.builtin_code == BuiltinOperator_CUSTOM) && + (strcmp(registration.custom_name, op) == 0)) { + return ®istration; + } + } + return nullptr; + } + + MicroOpResolver::BuiltinParseFunction GetOpDataParser( + BuiltinOperator op) const override { + TFLITE_DCHECK(num_buitin_ops_ <= tOpCount); + for (unsigned int i = 0; i < num_buitin_ops_; ++i) { + if (builtin_codes_[i] == op) return builtin_parsers_[i]; + } + return nullptr; + } + + // Registers a Custom Operator with the MicroOpResolver. + // + // Only the first call for a given name will be successful. i.e. if this + // function is called again for a previously added Custom Operator, the + // MicroOpResolver will be unchanged and this function will return + // kTfLiteError. + TfLiteStatus AddCustom(const char* name, TfLiteRegistration* registration) { + if (registrations_len_ >= tOpCount) { + if (error_reporter_) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Couldn't register custom op '%s', resolver size is too small (%d)", + name, tOpCount); + } + return kTfLiteError; + } + + if (FindOp(name) != nullptr) { + if (error_reporter_ != nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Calling AddCustom for the same op more than once " + "is not supported (Op: %s).", + name); + } + return kTfLiteError; + } + + TfLiteRegistration* new_registration = ®istrations_[registrations_len_]; + registrations_len_ += 1; + + *new_registration = *registration; + new_registration->builtin_code = BuiltinOperator_CUSTOM; + new_registration->custom_name = name; + return kTfLiteOk; + } + + // The Add* functions below add the various Builtin operators to the + // MicroMutableOpResolver object. + + TfLiteStatus AddAbs() { + return AddBuiltin(BuiltinOperator_ABS, tflite::ops::micro::Register_ABS(), + ParseAbs); + } + + TfLiteStatus AddAdd() { + return AddBuiltin(BuiltinOperator_ADD, tflite::ops::micro::Register_ADD(), + ParseAdd); + } + + TfLiteStatus AddArgMax() { + return AddBuiltin(BuiltinOperator_ARG_MAX, + tflite::ops::micro::Register_ARG_MAX(), ParseArgMax); + } + + TfLiteStatus AddArgMin() { + return AddBuiltin(BuiltinOperator_ARG_MIN, + tflite::ops::micro::Register_ARG_MIN(), ParseArgMin); + } + + TfLiteStatus AddAveragePool2D() { + return AddBuiltin(BuiltinOperator_AVERAGE_POOL_2D, + tflite::ops::micro::Register_AVERAGE_POOL_2D(), + ParsePool); + } + + TfLiteStatus AddCeil() { + return AddBuiltin(BuiltinOperator_CEIL, tflite::ops::micro::Register_CEIL(), + ParseCeil); + } + + TfLiteStatus AddCircularBuffer() { + return AddCustom("CIRCULAR_BUFFER", + tflite::ops::micro::Register_CIRCULAR_BUFFER()); + } + + TfLiteStatus AddConcatenation() { + return AddBuiltin(BuiltinOperator_CONCATENATION, + tflite::ops::micro::Register_CONCATENATION(), + ParseConcatenation); + } + + TfLiteStatus AddConv2D() { + return AddBuiltin(BuiltinOperator_CONV_2D, + tflite::ops::micro::Register_CONV_2D(), ParseConv2D); + } + + TfLiteStatus AddCos() { + return AddBuiltin(BuiltinOperator_COS, tflite::ops::micro::Register_COS(), + ParseCos); + } + + TfLiteStatus AddDepthwiseConv2D() { + return AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, + tflite::ops::micro::Register_DEPTHWISE_CONV_2D(), + ParseDepthwiseConv2D); + } + + TfLiteStatus AddDequantize() { + return AddBuiltin(BuiltinOperator_DEQUANTIZE, + tflite::ops::micro::Register_DEQUANTIZE(), + ParseDequantize); + } + + TfLiteStatus AddEqual() { + return AddBuiltin(BuiltinOperator_EQUAL, + tflite::ops::micro::Register_EQUAL(), ParseEqual); + } + + TfLiteStatus AddFloor() { + return AddBuiltin(BuiltinOperator_FLOOR, + tflite::ops::micro::Register_FLOOR(), ParseFloor); + } + + TfLiteStatus AddFullyConnected() { + return AddBuiltin(BuiltinOperator_FULLY_CONNECTED, + tflite::ops::micro::Register_FULLY_CONNECTED(), + ParseFullyConnected); + } + + TfLiteStatus AddGreater() { + return AddBuiltin(BuiltinOperator_GREATER, + tflite::ops::micro::Register_GREATER(), ParseGreater); + } + + TfLiteStatus AddGreaterEqual() { + return AddBuiltin(BuiltinOperator_GREATER_EQUAL, + tflite::ops::micro::Register_GREATER_EQUAL(), + ParseGreaterEqual); + } + + TfLiteStatus AddHardSwish() { + return AddBuiltin(BuiltinOperator_HARD_SWISH, + tflite::ops::micro::Register_HARD_SWISH(), + ParseHardSwish); + } + + TfLiteStatus AddL2Normalization() { + return AddBuiltin(BuiltinOperator_L2_NORMALIZATION, + tflite::ops::micro::Register_L2_NORMALIZATION(), + ParseL2Normalization); + } + + TfLiteStatus AddLess() { + return AddBuiltin(BuiltinOperator_LESS, tflite::ops::micro::Register_LESS(), + ParseLess); + } + + TfLiteStatus AddLessEqual() { + return AddBuiltin(BuiltinOperator_LESS_EQUAL, + tflite::ops::micro::Register_LESS_EQUAL(), + ParseLessEqual); + } + + TfLiteStatus AddLog() { + return AddBuiltin(BuiltinOperator_LOG, tflite::ops::micro::Register_LOG(), + ParseLog); + } + + TfLiteStatus AddLogicalAnd() { + return AddBuiltin(BuiltinOperator_LOGICAL_AND, + tflite::ops::micro::Register_LOGICAL_AND(), + ParseLogicalAnd); + } + + TfLiteStatus AddLogicalNot() { + return AddBuiltin(BuiltinOperator_LOGICAL_NOT, + tflite::ops::micro::Register_LOGICAL_NOT(), + ParseLogicalNot); + } + + TfLiteStatus AddLogicalOr() { + return AddBuiltin(BuiltinOperator_LOGICAL_OR, + tflite::ops::micro::Register_LOGICAL_OR(), + ParseLogicalOr); + } + + TfLiteStatus AddLogistic() { + return AddBuiltin(BuiltinOperator_LOGISTIC, + tflite::ops::micro::Register_LOGISTIC(), ParseLogistic); + } + + TfLiteStatus AddMaximum() { + return AddBuiltin(BuiltinOperator_MAXIMUM, + tflite::ops::micro::Register_MAXIMUM(), ParseMaximum); + } + + TfLiteStatus AddMaxPool2D() { + return AddBuiltin(BuiltinOperator_MAX_POOL_2D, + tflite::ops::micro::Register_MAX_POOL_2D(), ParsePool); + } + + TfLiteStatus AddMean() { + return AddBuiltin(BuiltinOperator_MEAN, tflite::ops::micro::Register_MEAN(), + ParseReducer); + } + + TfLiteStatus AddMinimum() { + return AddBuiltin(BuiltinOperator_MINIMUM, + tflite::ops::micro::Register_MINIMUM(), ParseMinimum); + } + + TfLiteStatus AddMul() { + return AddBuiltin(BuiltinOperator_MUL, tflite::ops::micro::Register_MUL(), + ParseMul); + } + + TfLiteStatus AddNeg() { + return AddBuiltin(BuiltinOperator_NEG, tflite::ops::micro::Register_NEG(), + ParseNeg); + } + + TfLiteStatus AddNotEqual() { + return AddBuiltin(BuiltinOperator_NOT_EQUAL, + tflite::ops::micro::Register_NOT_EQUAL(), ParseNotEqual); + } + + TfLiteStatus AddPack() { + return AddBuiltin(BuiltinOperator_PACK, tflite::ops::micro::Register_PACK(), + ParsePack); + } + + TfLiteStatus AddPad() { + return AddBuiltin(BuiltinOperator_PAD, tflite::ops::micro::Register_PAD(), + ParsePad); + } + + TfLiteStatus AddPadV2() { + return AddBuiltin(BuiltinOperator_PADV2, + tflite::ops::micro::Register_PADV2(), ParsePadV2); + } + + TfLiteStatus AddPrelu() { + return AddBuiltin(BuiltinOperator_PRELU, + tflite::ops::micro::Register_PRELU(), ParsePrelu); + } + + TfLiteStatus AddQuantize() { + return AddBuiltin(BuiltinOperator_QUANTIZE, + tflite::ops::micro::Register_QUANTIZE(), ParseQuantize); + } + + TfLiteStatus AddRelu() { + return AddBuiltin(BuiltinOperator_RELU, tflite::ops::micro::Register_RELU(), + ParseRelu); + } + + TfLiteStatus AddRelu6() { + return AddBuiltin(BuiltinOperator_RELU6, + tflite::ops::micro::Register_RELU6(), ParseRelu6); + } + + TfLiteStatus AddReshape() { + return AddBuiltin(BuiltinOperator_RESHAPE, + tflite::ops::micro::Register_RESHAPE(), ParseReshape); + } + + TfLiteStatus AddResizeNearestNeighbor() { + return AddBuiltin(BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, + tflite::ops::micro::Register_RESIZE_NEAREST_NEIGHBOR(), + ParseResizeNearestNeighbor); + } + + TfLiteStatus AddRound() { + return AddBuiltin(BuiltinOperator_ROUND, + tflite::ops::micro::Register_ROUND(), ParseRound); + } + + TfLiteStatus AddRsqrt() { + return AddBuiltin(BuiltinOperator_RSQRT, + tflite::ops::micro::Register_RSQRT(), ParseRsqrt); + } + + TfLiteStatus AddSin() { + return AddBuiltin(BuiltinOperator_SIN, tflite::ops::micro::Register_SIN(), + ParseSin); + } + + TfLiteStatus AddSoftmax() { + return AddBuiltin(BuiltinOperator_SOFTMAX, + tflite::ops::micro::Register_SOFTMAX(), ParseSoftmax); + } + + TfLiteStatus AddSplit() { + return AddBuiltin(BuiltinOperator_SPLIT, + tflite::ops::micro::Register_SPLIT(), ParseSplit); + } + + TfLiteStatus AddSqrt() { + return AddBuiltin(BuiltinOperator_SQRT, tflite::ops::micro::Register_SQRT(), + ParseSqrt); + } + + TfLiteStatus AddSquare() { + return AddBuiltin(BuiltinOperator_SQUARE, + tflite::ops::micro::Register_SQUARE(), ParseSquare); + } + + TfLiteStatus AddStridedSlice() { + return AddBuiltin(BuiltinOperator_STRIDED_SLICE, + tflite::ops::micro::Register_STRIDED_SLICE(), + ParseStridedSlice); + } + + TfLiteStatus AddSub() { + return AddBuiltin(BuiltinOperator_SUB, tflite::ops::micro::Register_SUB(), + ParseSub); + } + + TfLiteStatus AddSvdf() { + return AddBuiltin(BuiltinOperator_SVDF, tflite::ops::micro::Register_SVDF(), + ParseSvdf); + } + + TfLiteStatus AddTanh() { + return AddBuiltin(BuiltinOperator_TANH, tflite::ops::micro::Register_TANH(), + ParseTanh); + } + + TfLiteStatus AddUnpack() { + return AddBuiltin(BuiltinOperator_UNPACK, + tflite::ops::micro::Register_UNPACK(), ParseUnpack); + } + + unsigned int GetRegistrationLength() { return registrations_len_; } + + private: + TfLiteStatus AddBuiltin(tflite::BuiltinOperator op, + const TfLiteRegistration& registration, + MicroOpResolver::BuiltinParseFunction parser) { + if (op == BuiltinOperator_CUSTOM) { + if (error_reporter_ != nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Invalid parameter BuiltinOperator_CUSTOM to the " + "AddBuiltin function."); + } + return kTfLiteError; + } + + if (FindOp(op) != nullptr) { + if (error_reporter_ != nullptr) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Calling AddBuiltin with the same op more than " + "once is not supported (Op: #%d).", + op); + } + return kTfLiteError; + } + + if (registrations_len_ >= tOpCount) { + if (error_reporter_) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Couldn't register builtin op #%d, resolver size " + "is too small (%d).", + op, tOpCount); + } + return kTfLiteError; + } + + registrations_[registrations_len_] = registration; + // Strictly speaking, the builtin_code is not necessary for TFLM but filling + // it in regardless. + registrations_[registrations_len_].builtin_code = op; + registrations_len_++; + + builtin_codes_[num_buitin_ops_] = op; + builtin_parsers_[num_buitin_ops_] = parser; + num_buitin_ops_++; + + return kTfLiteOk; + } + + TfLiteRegistration registrations_[tOpCount]; + unsigned int registrations_len_ = 0; + + // Arrays (and counter) to store the builtin codes and their corresponding + // parse functions as these are registered with the Op Resolver. + BuiltinOperator builtin_codes_[tOpCount]; + MicroOpResolver::BuiltinParseFunction builtin_parsers_[tOpCount]; + unsigned int num_buitin_ops_ = 0; + + ErrorReporter* error_reporter_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +}; // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_MUTABLE_OP_RESOLVER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_op_resolver.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_op_resolver.h new file mode 100644 index 0000000..757b6b8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_op_resolver.h @@ -0,0 +1,73 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_OP_RESOLVER_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_OP_RESOLVER_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/flatbuffer_conversions.h" +#include "tensorflow/lite/core/api/op_resolver.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { + +// This is an interface for the OpResolver for TFLiteMicro. The differences from +// the TFLite OpResolver base class are to: +// * explicitly remove support for Op versions +// * allow for finer grained registration of the Builtin Ops to reduce code +// size for TFLiteMicro. +// +// We need an interface class instead of directly using MicroMutableOpResolver +// because MicroMutableOpResolver is a class template with the number of +// registered Ops as the template parameter. +class MicroOpResolver : public OpResolver { + public: + typedef TfLiteStatus (*BuiltinParseFunction)(const Operator* op, + ErrorReporter* error_reporter, + BuiltinDataAllocator* allocator, + void** builtin_data); + + // Returns the Op registration struct corresponding to the enum code from the + // flatbuffer schema. Returns nullptr if the op is not found or if op == + // BuiltinOperator_CUSTOM. + virtual const TfLiteRegistration* FindOp(BuiltinOperator op) const = 0; + + // Returns the Op registration struct corresponding to the custom operator by + // name. + virtual const TfLiteRegistration* FindOp(const char* op) const = 0; + + // This implementation exists for compatibility with the OpResolver base class + // and disregards the version parameter. + const TfLiteRegistration* FindOp(BuiltinOperator op, + int version) const final { + return FindOp(op); + } + + // This implementation exists for compatibility with the OpResolver base class + // and disregards the version parameter. + const TfLiteRegistration* FindOp(const char* op, int version) const final { + return FindOp(op); + } + + // Returns the operator specific parsing function for the OpData for a + // BuiltinOperator (if registered), else nullptr. + virtual BuiltinParseFunction GetOpDataParser(BuiltinOperator op) const = 0; + + ~MicroOpResolver() override {} +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_OP_RESOLVER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.cc new file mode 100644 index 0000000..4617b3d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.cc @@ -0,0 +1,186 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#include "tensorflow/lite/micro/micro_optional_debug_tools.h" + +// `cinttypes` requires `__STDC_FORMAT_MACROS` to be defined to expose `PRId32`. +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/memory_helpers.h" +#include "tensorflow/lite/micro/micro_allocator.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { +namespace { + +std::vector flatbuffersVector2StdVector( + const flatbuffers::Vector& fVector) { + std::vector stdVector; + stdVector.reserve(fVector.size()); + for (size_t i = 0; i < fVector.size(); i++) { + stdVector.push_back(fVector.Get(i)); + } + return stdVector; +} + +void PrintIntVector(const std::vector& v) { + for (const auto& it : v) { + printf(" %d", it); + } + printf("\n"); +} + +void PrintTfLiteIntVector(const TfLiteIntArray* v) { + if (!v) { + printf(" (null)\n"); + return; + } + for (int k = 0; k < v->size; k++) { + printf(" %d", v->data[k]); + } + printf("\n"); +} + +const char* TensorTypeName(TfLiteType type) { + switch (type) { + case kTfLiteNoType: + return "kTfLiteNoType"; + case kTfLiteFloat32: + return "kTfLiteFloat32"; + case kTfLiteInt32: + return "kTfLiteInt32"; + case kTfLiteUInt8: + return "kTfLiteUInt8"; + case kTfLiteInt8: + return "kTfLiteInt8"; + case kTfLiteInt64: + return "kTfLiteInt64"; + case kTfLiteString: + return "kTfLiteString"; + case kTfLiteBool: + return "kTfLiteBool"; + case kTfLiteInt16: + return "kTfLiteInt16"; + case kTfLiteComplex64: + return "kTfLiteComplex64"; + case kTfLiteComplex128: + return "kTfLiteComplex128"; + case kTfLiteFloat16: + return "kTfLiteFloat16"; + case kTfLiteFloat64: + return "kTfLiteFloat64"; + } + return "(invalid)"; +} + +const char* AllocTypeName(TfLiteAllocationType type) { + switch (type) { + case kTfLiteMemNone: + return "kTfLiteMemNone"; + case kTfLiteMmapRo: + return "kTfLiteMmapRo"; + case kTfLiteDynamic: + return "kTfLiteDynamic"; + case kTfLiteArenaRw: + return "kTfLiteArenaRw"; + case kTfLiteArenaRwPersistent: + return "kTfLiteArenaRwPersistent"; + case kTfLitePersistentRo: + return "kTfLitePersistentRo"; + } + return "(invalid)"; +} +} // namespace + +// Helper function to print model flatbuffer data. This function is not called +// by default. Hence it's not linked in to the final binary code. +void PrintModelData(const Model* model, ErrorReporter* error_reporter) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + auto* subgraphs = model->subgraphs(); + const SubGraph* subgraph = (*subgraphs)[0]; + const flatbuffers::Vector>* tensors = + subgraph->tensors(); + const flatbuffers::Vector>* buffers = + model->buffers(); + TF_LITE_REPORT_ERROR(error_reporter, "==== Model info: ====="); + for (size_t i = 0; i < tensors->size(); ++i) { + const tflite::Tensor& flatbuffer_tensor = *tensors->Get(i); + size_t type_size, tensor_size; + auto* buffer = (*buffers)[flatbuffer_tensor.buffer()]; + auto* array = buffer->data(); + int array_size = 0; + if (array) { + array_size = array->size(); + } + BytesRequiredForTensor(flatbuffer_tensor, &tensor_size, &type_size, + error_reporter); + TF_LITE_REPORT_ERROR( + error_reporter, "Tensor index: %d arena tensor %d size %d ", i, + !array_size && !flatbuffer_tensor.is_variable(), tensor_size); + } +#endif +} + +// Prints a dump of what tensors and what nodes are in the interpreter. +void PrintInterpreterState(MicroInterpreter* interpreter) { + printf("Interpreter has %zu tensors and %zu nodes\n", + interpreter->tensors_size(), interpreter->operators_size()); + printf("Inputs:"); + PrintIntVector(flatbuffersVector2StdVector(interpreter->inputs())); + printf("Outputs:"); + PrintIntVector(flatbuffersVector2StdVector(interpreter->outputs())); + printf("\n"); + + for (size_t tensor_index = 0; tensor_index < interpreter->tensors_size(); + tensor_index++) { + TfLiteTensor* tensor = interpreter->tensor(static_cast(tensor_index)); + printf("Tensor %3zu %10s %15s %10zu bytes (%4.1f MB) ", tensor_index, + TensorTypeName(tensor->type), AllocTypeName(tensor->allocation_type), + tensor->bytes, static_cast(tensor->bytes / (1 << 20))); + PrintTfLiteIntVector(tensor->dims); + } + printf("\n"); + + for (size_t node_index = 0; node_index < interpreter->operators_size(); + node_index++) { + const NodeAndRegistration node_and_reg = + interpreter->node_and_registration(static_cast(node_index)); + const TfLiteNode& node = node_and_reg.node; + const TfLiteRegistration* reg = node_and_reg.registration; + if (reg->custom_name != nullptr) { + printf("Node %3zu Operator Custom Name %s\n", node_index, + reg->custom_name); + } else { + printf("Node %3zu Operator Builtin Code %3" PRId32 " %s\n", node_index, + reg->builtin_code, EnumNamesBuiltinOperator()[reg->builtin_code]); + } + printf(" Inputs:"); + PrintTfLiteIntVector(node.inputs); + printf(" Outputs:"); + PrintTfLiteIntVector(node.outputs); + } +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.h new file mode 100644 index 0000000..cc9630e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_optional_debug_tools.h @@ -0,0 +1,30 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +// Optional debugging functionality. For small sized binaries, these are not +// needed. +#ifndef TENSORFLOW_LITE_MICRO_MICRO_OPTIONAL_DEBUG_TOOLS_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_OPTIONAL_DEBUG_TOOLS_H_ + +#include "tensorflow/lite/micro/micro_interpreter.h" + +namespace tflite { +// Helper function to print model flatbuffer data. This function is not called +// by default. Hence it's not linked in to the final binary code. +void PrintModelData(const Model* model, ErrorReporter* error_reporter); +// Prints a dump of what tensors and what nodes are in the interpreter. +void PrintInterpreterState(MicroInterpreter* interpreter); +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_OPTIONAL_DEBUG_TOOLS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.cc new file mode 100644 index 0000000..83fb9f6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.cc @@ -0,0 +1,42 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/micro_profiler.h" + +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/micro_time.h" + +namespace tflite { + +MicroProfiler::MicroProfiler(tflite::ErrorReporter* reporter) + : reporter_(reporter) {} + +uint32_t MicroProfiler::BeginEvent(const char* tag, EventType event_type, + int64_t event_metadata1, + int64_t event_metadata2) { + start_time_ = GetCurrentTimeTicks(); + TFLITE_DCHECK(tag != nullptr); + event_tag_ = tag; + return 0; +} + +void MicroProfiler::EndEvent(uint32_t event_handle) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + int32_t end_time = GetCurrentTimeTicks(); + TF_LITE_REPORT_ERROR(reporter_, "%s took %d cycles\n", event_tag_, + end_time - start_time_); +#endif +} +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.h new file mode 100644 index 0000000..a3144b3 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_profiler.h @@ -0,0 +1,71 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_MICRO_PROFILER_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_PROFILER_H_ + +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/core/api/profiler.h" +#include "tensorflow/lite/micro/compatibility.h" + +namespace tflite { + +// MicroProfiler creates a common way to gain fine-grained insight into runtime +// performance. Bottleck operators can be identified along with slow code +// sections. This can be used in conjunction with running the relevant micro +// benchmark to evaluate end-to-end performance. +// +// Usage example: +// MicroProfiler profiler(error_reporter); +// { +// ScopedProfile scoped_profile(profiler, tag); +// work_to_profile(); +// } +// +// This will call the following methods in order: +// int event_handle = profiler->BeginEvent(op_name, EventType::DEFAULT, 0) +// work_to_profile(); +// profiler->EndEvent(event_handle) +class MicroProfiler : public tflite::Profiler { + public: + explicit MicroProfiler(tflite::ErrorReporter* reporter); + ~MicroProfiler() override = default; + + // AddEvent is unused for Tf Micro. + void AddEvent(const char* tag, EventType event_type, uint64_t start, + uint64_t end, int64_t event_metadata1, + int64_t event_metadata2) override{}; + + // BeginEvent followed by code followed by EndEvent will profile the code + // enclosed. Multiple concurrent events are unsupported, so the return value + // is always 0. Event_metadata1 and event_metadata2 are unused. The tag + // pointer must be valid until EndEvent is called. + uint32_t BeginEvent(const char* tag, EventType event_type, + int64_t event_metadata1, + int64_t event_metadata2) override; + + // Event_handle is ignored since TF Micro does not support concurrent events. + void EndEvent(uint32_t event_handle) override; + + private: + tflite::ErrorReporter* reporter_; + int32_t start_time_; + const char* event_tag_; + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_PROFILER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.cc new file mode 100644 index 0000000..6d6495e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.cc @@ -0,0 +1,305 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Implements debug logging for numbers by converting them into strings and then +// calling the main DebugLog(char*) function. These are separated into a +// different file so that platforms can just implement the string output version +// of DebugLog() and then get the numerical variations without requiring any +// more code. + +#include "tensorflow/lite/micro/micro_string.h" + +#include +#include + +namespace { + +// Int formats can need up to 10 bytes for the value plus a single byte for the +// sign. +constexpr int kMaxIntCharsNeeded = 10 + 1; +// Hex formats can need up to 8 bytes for the value plus two bytes for the "0x". +constexpr int kMaxHexCharsNeeded = 8 + 2; + +// Float formats can need up to 7 bytes for the fraction plus 3 bytes for "x2^" +// plus 3 bytes for the exponent and a single sign bit. +constexpr float kMaxFloatCharsNeeded = 7 + 3 + 3 + 1; + +// All input buffers to the number conversion functions must be this long. +const int kFastToBufferSize = 48; + +// Reverses a zero-terminated string in-place. +char* ReverseStringInPlace(char* start, char* end) { + char* p1 = start; + char* p2 = end - 1; + while (p1 < p2) { + char tmp = *p1; + *p1++ = *p2; + *p2-- = tmp; + } + return start; +} + +// Appends a string to a string, in-place. You need to pass in the maximum +// string length as the second argument. +char* StrCatStr(char* main, int main_max_length, const char* to_append) { + char* current = main; + while (*current != 0) { + ++current; + } + char* current_end = main + (main_max_length - 1); + while ((*to_append != 0) && (current < current_end)) { + *current = *to_append; + ++current; + ++to_append; + } + *current = 0; + return current; +} + +// Populates the provided buffer with an ASCII representation of the number. +char* FastUInt32ToBufferLeft(uint32_t i, char* buffer, int base) { + char* start = buffer; + do { + int32_t digit = i % base; + char character; + if (digit < 10) { + character = '0' + digit; + } else { + character = 'a' + (digit - 10); + } + *buffer++ = character; + i /= base; + } while (i > 0); + *buffer = 0; + ReverseStringInPlace(start, buffer); + return buffer; +} + +// Populates the provided buffer with an ASCII representation of the number. +char* FastInt32ToBufferLeft(int32_t i, char* buffer) { + uint32_t u = i; + if (i < 0) { + *buffer++ = '-'; + u = -u; + } + return FastUInt32ToBufferLeft(u, buffer, 10); +} + +// Converts a number to a string and appends it to another. +char* StrCatInt32(char* main, int main_max_length, int32_t number) { + char number_string[kFastToBufferSize]; + FastInt32ToBufferLeft(number, number_string); + return StrCatStr(main, main_max_length, number_string); +} + +// Converts a number to a string and appends it to another. +char* StrCatUInt32(char* main, int main_max_length, uint32_t number, int base) { + char number_string[kFastToBufferSize]; + FastUInt32ToBufferLeft(number, number_string, base); + return StrCatStr(main, main_max_length, number_string); +} + +// Populates the provided buffer with ASCII representation of the float number. +// Avoids the use of any floating point instructions (since these aren't +// supported on many microcontrollers) and as a consequence prints values with +// power-of-two exponents. +char* FastFloatToBufferLeft(float f, char* buffer) { + char* current = buffer; + char* current_end = buffer + (kFastToBufferSize - 1); + // Access the bit fields of the floating point value to avoid requiring any + // float instructions. These constants are derived from IEEE 754. + const uint32_t sign_mask = 0x80000000; + const uint32_t exponent_mask = 0x7f800000; + const int32_t exponent_shift = 23; + const int32_t exponent_bias = 127; + const uint32_t fraction_mask = 0x007fffff; + const uint32_t u = *reinterpret_cast(&f); + const int32_t exponent = + ((u & exponent_mask) >> exponent_shift) - exponent_bias; + const uint32_t fraction = (u & fraction_mask); + // Expect ~0x2B1B9D3 for fraction. + if (u & sign_mask) { + *current = '-'; + current += 1; + } + *current = 0; + // These are special cases for infinities and not-a-numbers. + if (exponent == 128) { + if (fraction == 0) { + current = StrCatStr(current, (current_end - current), "Inf"); + return current; + } else { + current = StrCatStr(current, (current_end - current), "NaN"); + return current; + } + } + // 0x007fffff (8388607) represents 0.99... for the fraction, so to print the + // correct decimal digits we need to scale our value before passing it to the + // conversion function. This scale should be 10000000/8388608 = 1.1920928955. + // We can approximate this using multiply-adds and right-shifts using the + // values in this array. The 1. portion of the number string is printed out + // in a fixed way before the fraction, below. + const int32_t scale_shifts_size = 13; + const int8_t scale_shifts[13] = {3, 4, 8, 11, 13, 14, 17, + 18, 19, 20, 21, 22, 23}; + uint32_t scaled_fraction = fraction; + for (int i = 0; i < scale_shifts_size; ++i) { + scaled_fraction += (fraction >> scale_shifts[i]); + } + *current = '1'; + current += 1; + *current = '.'; + current += 1; + *current = 0; + + // Prepend leading zeros to fill in all 7 bytes of the fraction. Truncate + // zeros off the end of the fraction. Every fractional value takes 7 bytes. + // For example, 2500 would be written into the buffer as 0002500 since it + // represents .00025. + constexpr int kMaxFractionalDigits = 7; + + // Abort early if there is not enough space in the buffer. + if (current_end - current <= kMaxFractionalDigits) { + return current; + } + + // Pre-fill buffer with zeros to ensure zero-truncation works properly. + for (int i = 1; i < kMaxFractionalDigits; i++) { + *(current + i) = '0'; + } + + // Track how large the fraction is to add leading zeros. + char* previous = current; + current = StrCatUInt32(current, (current_end - current), scaled_fraction, 10); + int fraction_digits = current - previous; + int leading_zeros = kMaxFractionalDigits - fraction_digits; + + // Overwrite the null terminator from StrCatUInt32 to ensure zero-trunctaion + // works properly. + *current = '0'; + + // Shift fraction values and prepent zeros. + for (int i = 0; i < fraction_digits; i++) { + current--; + *(current + leading_zeros) = *current; + *current = '0'; + } + current += kMaxFractionalDigits; + + // Truncate trailing zeros for cleaner logs. Ensure we leave at least one + // fractional character for the case when scaled_fraction is 0. + while (*(current - 1) == '0' && (current - 1) > previous) { + current--; + } + *current = 0; + current = StrCatStr(current, (current_end - current), "*2^"); + current = StrCatInt32(current, (current_end - current), exponent); + return current; +} + +int FormatInt32(char* output, int32_t i) { + return static_cast(FastInt32ToBufferLeft(i, output) - output); +} + +int FormatUInt32(char* output, uint32_t i) { + return static_cast(FastUInt32ToBufferLeft(i, output, 10) - output); +} + +int FormatHex(char* output, uint32_t i) { + return static_cast(FastUInt32ToBufferLeft(i, output, 16) - output); +} + +int FormatFloat(char* output, float i) { + return static_cast(FastFloatToBufferLeft(i, output) - output); +} + +} // namespace + +extern "C" int MicroVsnprintf(char* output, int len, const char* format, + va_list args) { + int output_index = 0; + const char* current = format; + // One extra character must be left for the null terminator. + const int usable_length = len - 1; + while (*current != '\0' && output_index < usable_length) { + if (*current == '%') { + current++; + switch (*current) { + case 'd': + // Cut off log message if format could exceed log buffer length. + if (usable_length - output_index < kMaxIntCharsNeeded) { + output[output_index++] = '\0'; + return output_index; + } + output_index += + FormatInt32(&output[output_index], va_arg(args, int32_t)); + current++; + break; + case 'u': + if (usable_length - output_index < kMaxIntCharsNeeded) { + output[output_index++] = '\0'; + return output_index; + } + output_index += + FormatUInt32(&output[output_index], va_arg(args, uint32_t)); + current++; + break; + case 'x': + if (usable_length - output_index < kMaxHexCharsNeeded) { + output[output_index++] = '\0'; + return output_index; + } + output[output_index++] = '0'; + output[output_index++] = 'x'; + output_index += + FormatHex(&output[output_index], va_arg(args, uint32_t)); + current++; + break; + case 'f': + if (usable_length - output_index < kMaxFloatCharsNeeded) { + output[output_index++] = '\0'; + return output_index; + } + output_index += + FormatFloat(&output[output_index], va_arg(args, double)); + current++; + break; + case '%': + output[output_index++] = *current++; + break; + case 's': + char* string = va_arg(args, char*); + int string_idx = 0; + while (string_idx + output_index < usable_length && + string[string_idx] != '\0') { + output[output_index++] = string[string_idx++]; + } + current++; + } + } else { + output[output_index++] = *current++; + } + } + output[output_index++] = '\0'; + return output_index; +} + +extern "C" int MicroSnprintf(char* output, int len, const char* format, ...) { + va_list args; + va_start(args, format); + int bytes_written = MicroVsnprintf(output, len, format, args); + va_end(args); + return bytes_written; +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.h new file mode 100644 index 0000000..59303e8 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_string.h @@ -0,0 +1,33 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_STRING_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_STRING_H_ + +#include + +// Implements simple string formatting for numeric types. Returns the number of +// bytes written to output. +extern "C" { +// Functionally equivalent to vsnprintf, trimmed down for TFLite Micro. +// MicroSnprintf() is implemented using MicroVsnprintf(). +int MicroVsnprintf(char* output, int len, const char* format, va_list args); +// Functionally equavalent to snprintf, trimmed down for TFLite Micro. +// For example, MicroSnprintf(buffer, 10, "int %d", 10) will put the string +// "int 10" in the buffer. +// Floating point values are logged in exponent notation (1.XXX*2^N). +int MicroSnprintf(char* output, int len, const char* format, ...); +} + +#endif // TENSORFLOW_LITE_MICRO_MICRO_STRING_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.cc new file mode 100644 index 0000000..93bee20 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.cc @@ -0,0 +1,47 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Reference implementation of timer functions. Platforms are not required to +// implement these timer methods, but they are required to enable profiling. + +// On platforms that have a POSIX stack or C library, it can be written using +// methods from or clock() from . + +// To add an equivalent function for your own platform, create your own +// implementation file, and place it in a subfolder with named after the OS +// you're targeting. For example, see the Cortex M bare metal version in +// tensorflow/lite/micro/bluepill/micro_time.cc or the mbed one on +// tensorflow/lite/micro/mbed/micro_time.cc. + +#include "tensorflow/lite/micro/micro_time.h" + +namespace tflite { + +//80MHz +constexpr int kClocksPerSecond = 80e6; + +// Reference implementation of the ticks_per_second() function that's required +// for a platform to support Tensorflow Lite for Microcontrollers profiling. +// This returns 0 by default because timing is an optional feature that builds +// without errors on platforms that do not need it. +int32_t ticks_per_second() { return kClocksPerSecond; } + +// Reference implementation of the GetCurrentTimeTicks() function that's +// required for a platform to support Tensorflow Lite for Microcontrollers +// profiling. This returns 0 by default because timing is an optional feature +// that builds without errors on platforms that do not need it. +int32_t GetCurrentTimeTicks() { return 0; } + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.h new file mode 100644 index 0000000..465490a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_time.h @@ -0,0 +1,31 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_MICRO_TIME_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_TIME_H_ + +#include + +namespace tflite { + +// These functions should be implemented by each target platform, and provide an +// accurate tick count along with how many ticks there are per second. +int32_t ticks_per_second(); + +// Return time in ticks. The meaning of a tick varies per platform. +int32_t GetCurrentTimeTicks(); + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_TIME_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.cc b/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.cc new file mode 100644 index 0000000..ff885fa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.cc @@ -0,0 +1,279 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/micro_utils.h" + +#include +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/op_macros.h" + +namespace tflite { + +namespace { + +static const uint8_t kAsymmetricUInt8Min = 0; +static const uint8_t kAsymmetricUInt8Max = UINT8_MAX; +static const uint8_t kSymmetricUInt8Min = 1; +static const uint8_t kSymmetricUInt8Max = UINT8_MAX; +static const int8_t kAsymmetricInt8Min = INT8_MIN; +static const int8_t kAsymmetricInt8Max = INT8_MAX; +static const int kSymmetricInt8Scale = kAsymmetricInt8Max; + +static const int16_t kAsymmetricInt16Min = INT16_MIN; +static const int16_t kAsymmetricInt16Max = INT16_MAX; +static const int kSymmetricInt16Scale = kAsymmetricInt16Max; + +static const int32_t kAsymmetricInt32Max = INT32_MAX; +static const int kSymmetricInt32Scale = kAsymmetricInt32Max; + +} // namespace + +int ElementCount(const TfLiteIntArray& dims) { + int result = 1; + for (int i = 0; i < dims.size; ++i) { + result *= dims.data[i]; + } + return result; +} + +// Converts a float value into an unsigned eight-bit quantized value. +uint8_t FloatToAsymmetricQuantizedUInt8(const float value, const float scale, + const int zero_point) { + int32_t result = round(value / scale) + zero_point; + if (result < kAsymmetricUInt8Min) { + result = kAsymmetricUInt8Min; + } + if (result > kAsymmetricUInt8Max) { + result = kAsymmetricUInt8Max; + } + return result; +} + +uint8_t FloatToSymmetricQuantizedUInt8(const float value, const float scale) { + int32_t result = round(value / scale); + if (result < kSymmetricUInt8Min) { + result = kSymmetricUInt8Min; + } + if (result > kSymmetricUInt8Max) { + result = kSymmetricUInt8Max; + } + return result; +} + +int8_t FloatToAsymmetricQuantizedInt8(const float value, const float scale, + const int zero_point) { + int32_t result = round(value / scale) + zero_point; + if (result < kAsymmetricInt8Min) { + result = kAsymmetricInt8Min; + } + if (result > kAsymmetricInt8Max) { + result = kAsymmetricInt8Max; + } + return result; +} + +int16_t FloatToAsymmetricQuantizedInt16(const float value, const float scale, + const int zero_point) { + int32_t result = round(value / scale) + zero_point; + if (result < kAsymmetricInt16Min) { + result = kAsymmetricInt16Min; + } + if (result > kAsymmetricInt16Max) { + result = kAsymmetricInt16Max; + } + return result; +} + +int8_t FloatToSymmetricQuantizedInt8(const float value, const float scale) { + return FloatToAsymmetricQuantizedInt8(value, scale, 0.0f); +} + +int32_t FloatToSymmetricQuantizedInt32(const float value, const float scale) { + float quantized = round(value / scale); + if (static_cast(quantized) > INT_MAX) { + quantized = static_cast(INT_MAX); + } else if (quantized < INT_MIN) { + quantized = static_cast INT_MIN; + } + + return static_cast(quantized); +} + +void AsymmetricQuantize(const float* input, int8_t* output, int num_elements, + float scale, int zero_point) { + for (int i = 0; i < num_elements; i++) { + output[i] = FloatToAsymmetricQuantizedInt8(input[i], scale, zero_point); + } +} + +void AsymmetricQuantize(const float* input, uint8_t* output, int num_elements, + float scale, int zero_point) { + for (int i = 0; i < num_elements; i++) { + output[i] = FloatToAsymmetricQuantizedUInt8(input[i], scale, zero_point); + } +} + +void AsymmetricQuantize(const float* input, int16_t* output, int num_elements, + float scale, int zero_point) { + for (int i = 0; i < num_elements; i++) { + output[i] = FloatToAsymmetricQuantizedInt16(input[i], scale, zero_point); + } +} + +void SymmetricQuantize(const float* input, int32_t* output, int num_elements, + float scale) { + for (int i = 0; i < num_elements; i++) { + output[i] = FloatToSymmetricQuantizedInt32(input[i], scale); + } +} + +void SymmetricPerChannelQuantize(const float* input, int32_t* output, + int num_elements, int num_channels, + float* scales) { + int elements_per_channel = num_elements / num_channels; + for (int i = 0; i < num_channels; i++) { + for (int j = 0; j < elements_per_channel; j++) { + output[i * elements_per_channel + j] = FloatToSymmetricQuantizedInt32( + input[i * elements_per_channel + j], scales[i]); + } + } +} + +void SignedSymmetricPerChannelQuantize(const float* values, + TfLiteIntArray* dims, + int quantized_dimension, + int8_t* quantized_values, + float* scaling_factors) { + int input_size = ElementCount(*dims); + int channel_count = dims->data[quantized_dimension]; + int per_channel_size = input_size / channel_count; + + int stride; + int channel_stride; + if (quantized_dimension == 0) { + stride = 1; + channel_stride = per_channel_size; + } else if (quantized_dimension == 3) { + stride = channel_count; + channel_stride = 1; + } else { + TF_LITE_FATAL("quantized dimension must be 0 or 3"); + } + + // Calculate scales for each channel. + for (int channel = 0; channel < channel_count; channel++) { + float min = 0; + float max = 0; + + for (int i = 0; i < per_channel_size; i++) { + int idx = channel * channel_stride + i * stride; + min = fminf(min, values[idx]); + max = fmaxf(max, values[idx]); + } + scaling_factors[channel] = + fmaxf(fabs(min), fabs(max)) / kSymmetricInt8Scale; + for (int i = 0; i < per_channel_size; i++) { + int idx = channel * channel_stride + i * stride; + const int32_t quantized_value = + static_cast(roundf(values[idx] / scaling_factors[channel])); + // Clamp: just in case some odd numeric offset. + quantized_values[idx] = fminf( + kSymmetricInt8Scale, fmaxf(-kSymmetricInt8Scale, quantized_value)); + } + } +} + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int8_t* quantized_values, float* scaling_factor) { + int input_size = ElementCount(*dims); + + float min = 0; + float max = 0; + for (int i = 0; i < input_size; i++) { + min = fminf(min, values[i]); + max = fmaxf(max, values[i]); + } + *scaling_factor = fmaxf(fabs(min), fabs(max)) / kSymmetricInt8Scale; + for (int i = 0; i < input_size; i++) { + const int32_t quantized_value = + static_cast(roundf(values[i] / *scaling_factor)); + // Clamp: just in case some odd numeric offset. + quantized_values[i] = fminf(kSymmetricInt8Scale, + fmaxf(-kSymmetricInt8Scale, quantized_value)); + } +} + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int16_t* quantized_values, float* scaling_factor) { + int input_size = ElementCount(*dims); + + float min = 0; + float max = 0; + for (int i = 0; i < input_size; i++) { + min = fminf(min, values[i]); + max = fmaxf(max, values[i]); + } + *scaling_factor = fmaxf(fabs(min), fabs(max)) / kSymmetricInt16Scale; + for (int i = 0; i < input_size; i++) { + const int32_t quantized_value = + static_cast(roundf(values[i] / *scaling_factor)); + // Clamp: just in case some odd numeric offset. + quantized_values[i] = fminf(kSymmetricInt16Scale, + fmaxf(-kSymmetricInt16Scale, quantized_value)); + } +} + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int32_t* quantized_values, float* scaling_factor) { + int input_size = ElementCount(*dims); + + float min = 0; + float max = 0; + for (int i = 0; i < input_size; i++) { + min = fminf(min, values[i]); + max = fmaxf(max, values[i]); + } + + *scaling_factor = + fmaxf(fabs(min), fabs(max)) / static_cast(kSymmetricInt32Scale); + for (int i = 0; i < input_size; i++) { + const int32_t quantized_value = + static_cast(roundf(values[i] / *scaling_factor)); + // Clamp: just in case some odd numeric offset. + quantized_values[i] = fminf( + static_cast(kSymmetricInt32Scale), + fmaxf(static_cast(-kSymmetricInt32Scale), quantized_value)); + } +} + +void SymmetricQuantize(const float* values, TfLiteIntArray* dims, + uint8_t* quantized_values, float* scaling_factor) { + SignedSymmetricQuantize(values, dims, + reinterpret_cast(quantized_values), + scaling_factor); +} + +void SymmetricDequantize(const int8_t* values, const int size, + const float dequantization_scale, + float* dequantized_values) { + for (int i = 0; i < size; ++i) { + dequantized_values[i] = values[i] * dequantization_scale; + } +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.h b/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.h new file mode 100644 index 0000000..24aebad --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/micro_utils.h @@ -0,0 +1,110 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_MICRO_UTILS_H_ +#define TENSORFLOW_LITE_MICRO_MICRO_UTILS_H_ + +#include + +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +// Returns number of elements in the shape array. + +int ElementCount(const TfLiteIntArray& dims); + +uint8_t FloatToAsymmetricQuantizedUInt8(const float value, const float scale, + const int zero_point); + +uint8_t FloatToSymmetricQuantizedUInt8(const float value, const float scale); + +int8_t FloatToAsymmetricQuantizedInt8(const float value, const float scale, + const int zero_point); + +int16_t FloatToAsymmetricQuantizedInt16(const float value, const float scale, + const int zero_point); + +int8_t FloatToSymmetricQuantizedInt8(const float value, const float scale); + +// Converts a float value into a signed thirty-two-bit quantized value. Note +// that values close to max int and min int may see significant error due to +// a lack of floating point granularity for large values. +int32_t FloatToSymmetricQuantizedInt32(const float value, const float scale); + +// Helper methods to quantize arrays of floats to the desired format. +// +// There are several key flavors of quantization in TfLite: +// asymmetric symmetric per channel +// int8_t | X | X | X | +// uint8_t | X | X | | +// int16_t | X | | | +// int32_t | | X | X | +// +// The per-op quantization spec can be found here: +// https://www.tensorflow.org/lite/performance/quantization_spec + +void AsymmetricQuantize(const float* input, int8_t* output, int num_elements, + float scale, int zero_point = 0); + +void AsymmetricQuantize(const float* input, uint8_t* output, int num_elements, + float scale, int zero_point = 128); + +void AsymmetricQuantize(const float* input, int16_t* output, int num_elements, + float scale, int zero_point = 0); + +void SymmetricQuantize(const float* input, int32_t* output, int num_elements, + float scale); + +void SymmetricPerChannelQuantize(const float* input, int32_t* output, + int num_elements, int num_channels, + float* scales); + +void SignedSymmetricPerChannelQuantize(const float* values, + TfLiteIntArray* dims, + int quantized_dimension, + int8_t* quantized_values, + float* scaling_factor); + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int8_t* quantized_values, float* scaling_factor); + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int16_t* quantized_values, float* scaling_factor); + +void SignedSymmetricQuantize(const float* values, TfLiteIntArray* dims, + int32_t* quantized_values, float* scaling_factor); + +void SymmetricQuantize(const float* values, TfLiteIntArray* dims, + uint8_t* quantized_values, float* scaling_factor); + +void SymmetricDequantize(const int8_t* values, const int size, + const float dequantization_scale, + float* dequantized_values); + +template +void AsymmetricDequantize(const T* values, const int size, + const float dequantization_scale, + int dequantization_zero_point, + float* dequantized_values) { + for (int i = 0; i < size; ++i) { + dequantized_values[i] = + (values[i] - dequantization_zero_point) * dequantization_scale; + } +} + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_MICRO_UTILS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.cc b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.cc new file mode 100644 index 0000000..7e11523 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.cc @@ -0,0 +1,230 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/recording_micro_allocator.h" + +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/micro_allocator.h" +#include "tensorflow/lite/micro/recording_simple_memory_allocator.h" + +namespace tflite { + +RecordingMicroAllocator::RecordingMicroAllocator( + RecordingSimpleMemoryAllocator* recording_memory_allocator, + ErrorReporter* error_reporter) + : MicroAllocator(recording_memory_allocator, error_reporter), + recording_memory_allocator_(recording_memory_allocator) {} + +RecordingMicroAllocator* RecordingMicroAllocator::Create( + uint8_t* tensor_arena, size_t arena_size, ErrorReporter* error_reporter) { + TFLITE_DCHECK(error_reporter != nullptr); + + RecordingSimpleMemoryAllocator* simple_memory_allocator = + RecordingSimpleMemoryAllocator::Create(error_reporter, tensor_arena, + arena_size); + TFLITE_DCHECK(simple_memory_allocator != nullptr); + + uint8_t* allocator_buffer = simple_memory_allocator->AllocateFromTail( + sizeof(RecordingMicroAllocator), alignof(RecordingMicroAllocator)); + RecordingMicroAllocator* allocator = new (allocator_buffer) + RecordingMicroAllocator(simple_memory_allocator, error_reporter); + return allocator; +} + +RecordedAllocation RecordingMicroAllocator::GetRecordedAllocation( + RecordedAllocationType allocation_type) const { + switch (allocation_type) { + case RecordedAllocationType::kTfLiteEvalTensorData: + return recorded_tflite_eval_tensor_data_; + case RecordedAllocationType::kPersistentTfLiteTensorData: + return recorded_persistent_tflite_tensor_data_; + case RecordedAllocationType::kPersistentTfLiteTensorQuantizationData: + return recorded_persistent_tflite_tensor_quantization_data_; + case RecordedAllocationType::kTfLiteTensorVariableBufferData: + return recorded_tflite_tensor_variable_buffer_data_; + case RecordedAllocationType::kNodeAndRegistrationArray: + return recorded_node_and_registration_array_data_; + case RecordedAllocationType::kOpData: + return recorded_op_data_; + } + TF_LITE_REPORT_ERROR(error_reporter(), "Invalid allocation type supplied: %d", + allocation_type); + return RecordedAllocation(); +} + +const RecordingSimpleMemoryAllocator* +RecordingMicroAllocator::GetSimpleMemoryAllocator() const { + return recording_memory_allocator_; +} + +void RecordingMicroAllocator::PrintAllocations() const { + TF_LITE_REPORT_ERROR( + error_reporter(), + "[RecordingMicroAllocator] Arena allocation total %d bytes", + recording_memory_allocator_->GetUsedBytes()); + TF_LITE_REPORT_ERROR( + error_reporter(), + "[RecordingMicroAllocator] Arena allocation head %d bytes", + recording_memory_allocator_->GetHeadUsedBytes()); + TF_LITE_REPORT_ERROR( + error_reporter(), + "[RecordingMicroAllocator] Arena allocation tail %d bytes", + recording_memory_allocator_->GetTailUsedBytes()); + PrintRecordedAllocation(RecordedAllocationType::kTfLiteEvalTensorData, + "TfLiteEvalTensor data", "allocations"); + PrintRecordedAllocation(RecordedAllocationType::kPersistentTfLiteTensorData, + "Persistent TfLiteTensor data", "tensors"); + PrintRecordedAllocation( + RecordedAllocationType::kPersistentTfLiteTensorQuantizationData, + "Persistent TfLiteTensor quantization data", "allocations"); + PrintRecordedAllocation( + RecordedAllocationType::kTfLiteTensorVariableBufferData, + "TfLiteTensor variable buffer data", "allocations"); + PrintRecordedAllocation(RecordedAllocationType::kNodeAndRegistrationArray, + "NodeAndRegistration struct", + "NodeAndRegistration structs"); + PrintRecordedAllocation(RecordedAllocationType::kOpData, + "Operator runtime data", "OpData structs"); +} + +void RecordingMicroAllocator::PrintRecordedAllocation( + RecordedAllocationType allocation_type, const char* allocation_name, + const char* allocation_description) const { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + RecordedAllocation allocation = GetRecordedAllocation(allocation_type); + TF_LITE_REPORT_ERROR( + error_reporter(), + "[RecordingMicroAllocator] '%s' used %d bytes with alignment overhead " + "(requested %d bytes for %d %s)", + allocation_name, allocation.used_bytes, allocation.requested_bytes, + allocation.count, allocation_description); +#endif +} + +TfLiteStatus RecordingMicroAllocator::AllocateNodeAndRegistrations( + const Model* model, NodeAndRegistration** node_and_registrations) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteStatus status = MicroAllocator::AllocateNodeAndRegistrations( + model, node_and_registrations); + + RecordAllocationUsage(allocations, + recorded_node_and_registration_array_data_); + // The allocation count in SimpleMemoryAllocator will only be 1. To provide + // better logging, decrement by 1 and add in the actual number of operators + // used in the graph: + // The allocation for this recording will always be 1. This is because the + // parent class mallocs one large allocation for the number of nodes in the + // graph (e.g. sizeof(NodeAndRegistration) * num_nodes). + // To prevent extra overhead and potential for fragmentation, manually adjust + // the accounting by decrementing by 1 and adding the actual number of nodes + // used in the graph: + recorded_node_and_registration_array_data_.count += + GetSubGraphFromModel(model)->operators()->size() - 1; + return status; +} + +TfLiteStatus +RecordingMicroAllocator::PrepareNodeAndRegistrationDataFromFlatbuffer( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration* node_and_registrations) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteStatus status = + MicroAllocator::PrepareNodeAndRegistrationDataFromFlatbuffer( + model, op_resolver, node_and_registrations); + + RecordAllocationUsage(allocations, recorded_op_data_); + return status; +} + +TfLiteStatus RecordingMicroAllocator::AllocateTfLiteEvalTensors( + const Model* model, TfLiteEvalTensor** eval_tensors) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteStatus status = + MicroAllocator::AllocateTfLiteEvalTensors(model, eval_tensors); + + RecordAllocationUsage(allocations, recorded_tflite_eval_tensor_data_); + // The allocation for this recording will always be 1. This is because the + // parent class mallocs one large allocation for the number of tensors in the + // graph (e.g. sizeof(TfLiteEvalTensor) * num_tensors). + // To prevent extra overhead and potential for fragmentation, manually adjust + // the accounting by decrementing by 1 and adding the actual number of tensors + // used in the graph: + recorded_tflite_eval_tensor_data_.count += + GetSubGraphFromModel(model)->tensors()->size() - 1; + return status; +} + +TfLiteStatus RecordingMicroAllocator::AllocateVariables( + const SubGraph* subgraph, TfLiteEvalTensor* eval_tensors) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteStatus status = + MicroAllocator::AllocateVariables(subgraph, eval_tensors); + + RecordAllocationUsage(allocations, + recorded_tflite_tensor_variable_buffer_data_); + return status; +} + +TfLiteTensor* RecordingMicroAllocator::AllocatePersistentTfLiteTensorInternal( + const Model* model, TfLiteEvalTensor* eval_tensors, int tensor_index) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteTensor* result = MicroAllocator::AllocatePersistentTfLiteTensorInternal( + model, eval_tensors, tensor_index); + + RecordAllocationUsage(allocations, recorded_persistent_tflite_tensor_data_); + return result; +} + +TfLiteStatus RecordingMicroAllocator::PopulateTfLiteTensorFromFlatbuffer( + const Model* model, const SubGraph* subgraph, TfLiteTensor* tensor, + int tensor_index, bool allocate_temp) { + RecordedAllocation allocations = SnapshotAllocationUsage(); + + TfLiteStatus status = MicroAllocator::PopulateTfLiteTensorFromFlatbuffer( + model, subgraph, tensor, tensor_index, allocate_temp); + + RecordAllocationUsage(allocations, + recorded_persistent_tflite_tensor_quantization_data_); + return status; +} + +RecordedAllocation RecordingMicroAllocator::SnapshotAllocationUsage() const { + return {/*requested_bytes=*/recording_memory_allocator_->GetRequestedBytes(), + /*used_bytes=*/recording_memory_allocator_->GetUsedBytes(), + /*count=*/recording_memory_allocator_->GetAllocatedCount()}; +} + +void RecordingMicroAllocator::RecordAllocationUsage( + const RecordedAllocation& snapshotted_allocation, + RecordedAllocation& recorded_allocation) { + recorded_allocation.requested_bytes += + recording_memory_allocator_->GetRequestedBytes() - + snapshotted_allocation.requested_bytes; + recorded_allocation.used_bytes += + recording_memory_allocator_->GetUsedBytes() - + snapshotted_allocation.used_bytes; + recorded_allocation.count += + recording_memory_allocator_->GetAllocatedCount() - + snapshotted_allocation.count; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.h b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.h new file mode 100644 index 0000000..9243fec --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_allocator.h @@ -0,0 +1,120 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_RECORDING_MICRO_ALLOCATOR_H_ +#define TENSORFLOW_LITE_MICRO_RECORDING_MICRO_ALLOCATOR_H_ + +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/micro_allocator.h" +#include "tensorflow/lite/micro/recording_simple_memory_allocator.h" + +namespace tflite { + +// List of buckets currently recorded by this class. Each type keeps a list of +// allocated information during model initialization. +enum class RecordedAllocationType { + kTfLiteEvalTensorData, + kPersistentTfLiteTensorData, + kPersistentTfLiteTensorQuantizationData, + kTfLiteTensorVariableBufferData, + kNodeAndRegistrationArray, + kOpData, +}; + +// Container for holding information about allocation recordings by a given +// type. Each recording contains the number of bytes requested, the actual bytes +// allocated (can defer from requested by alignment), and the number of items +// allocated. +struct RecordedAllocation { + size_t requested_bytes; + size_t used_bytes; + size_t count; +}; + +// Utility subclass of MicroAllocator that records all allocations +// inside the arena. A summary of allocations can be logged through the +// ErrorReporter by invoking LogAllocations(). This special allocator requires +// an instance of RecordingSimpleMemoryAllocator to capture allocations in the +// head and tail. Arena allocation recording can be retrieved by type through +// the GetRecordedAllocation() function. This class should only be used for +// auditing memory usage or integration testing. +class RecordingMicroAllocator : public MicroAllocator { + public: + static RecordingMicroAllocator* Create(uint8_t* tensor_arena, + size_t arena_size, + ErrorReporter* error_reporter); + + // Returns the recorded allocations information for a given allocation type. + RecordedAllocation GetRecordedAllocation( + RecordedAllocationType allocation_type) const; + + const RecordingSimpleMemoryAllocator* GetSimpleMemoryAllocator() const; + + // Logs out through the ErrorReporter all allocation recordings by type + // defined in RecordedAllocationType. + void PrintAllocations() const; + + protected: + TfLiteStatus AllocateNodeAndRegistrations( + const Model* model, + NodeAndRegistration** node_and_registrations) override; + TfLiteStatus PrepareNodeAndRegistrationDataFromFlatbuffer( + const Model* model, const MicroOpResolver& op_resolver, + NodeAndRegistration* node_and_registrations) override; + TfLiteStatus AllocateTfLiteEvalTensors( + const Model* model, TfLiteEvalTensor** eval_tensors) override; + TfLiteStatus AllocateVariables(const SubGraph* subgraph, + TfLiteEvalTensor* eval_tensors) override; + // TODO(b/160894903): Once all kernels have been updated to the new API drop + // this method. It is only used to record TfLiteTensor persistent allocations. + TfLiteTensor* AllocatePersistentTfLiteTensorInternal( + const Model* model, TfLiteEvalTensor* eval_tensors, + int tensor_index) override; + // TODO(b/160894903): Once all kernels have been updated to the new API drop + // this function since all allocations for quantized data will take place in + // the temp section. + TfLiteStatus PopulateTfLiteTensorFromFlatbuffer(const Model* model, + const SubGraph* subgraph, + TfLiteTensor* tensor, + int tensor_index, + bool allocate_temp) override; + + private: + RecordingMicroAllocator(RecordingSimpleMemoryAllocator* memory_allocator, + ErrorReporter* error_reporter); + + void PrintRecordedAllocation(RecordedAllocationType allocation_type, + const char* allocation_name, + const char* allocation_description) const; + + RecordedAllocation SnapshotAllocationUsage() const; + void RecordAllocationUsage(const RecordedAllocation& snapshotted_allocation, + RecordedAllocation& recorded_allocation); + + const RecordingSimpleMemoryAllocator* recording_memory_allocator_; + + RecordedAllocation recorded_tflite_eval_tensor_data_ = {}; + RecordedAllocation recorded_persistent_tflite_tensor_data_ = {}; + RecordedAllocation recorded_persistent_tflite_tensor_quantization_data_ = {}; + RecordedAllocation recorded_tflite_tensor_variable_buffer_data_ = {}; + RecordedAllocation recorded_node_and_registration_array_data_ = {}; + RecordedAllocation recorded_op_data_ = {}; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_RECORDING_MICRO_ALLOCATOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_interpreter.h b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_interpreter.h new file mode 100644 index 0000000..0a579b0 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/recording_micro_interpreter.h @@ -0,0 +1,65 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_RECORDING_MICRO_INTERPRETER_H_ +#define TENSORFLOW_LITE_MICRO_RECORDING_MICRO_INTERPRETER_H_ + +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/recording_micro_allocator.h" + +namespace tflite { + +// Utility subclass that enables internal recordings of the MicroInterpreter. +// This class should be used to audit and analyze memory arena usage for a given +// model and interpreter. +// +// After construction and the first Invoke() or AllocateTensors() call - the +// memory usage is recorded and available through the GetMicroAllocator() +// function. See RecordingMicroAlloctor for more details on what is currently +// recorded from arena allocations. +// +// It is recommended for users to increase the tensor arena size by at least 1kb +// to ensure enough additional memory is available for internal recordings. +class RecordingMicroInterpreter : public MicroInterpreter { + public: + RecordingMicroInterpreter(const Model* model, + const MicroOpResolver& op_resolver, + uint8_t* tensor_arena, size_t tensor_arena_size, + ErrorReporter* error_reporter) + : MicroInterpreter(model, op_resolver, + RecordingMicroAllocator::Create( + tensor_arena, tensor_arena_size, error_reporter), + error_reporter), + recording_micro_allocator_( + static_cast(allocator())) {} + + RecordingMicroInterpreter(const Model* model, + const MicroOpResolver& op_resolver, + RecordingMicroAllocator* allocator, + ErrorReporter* error_reporter) + : MicroInterpreter(model, op_resolver, allocator, error_reporter), + recording_micro_allocator_(*allocator) {} + + const RecordingMicroAllocator& GetMicroAllocator() const { + return recording_micro_allocator_; + } + + private: + const RecordingMicroAllocator& recording_micro_allocator_; +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_RECORDING_MICRO_INTERPRETER_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.cc b/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.cc new file mode 100644 index 0000000..ef2e9f3 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.cc @@ -0,0 +1,83 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/recording_simple_memory_allocator.h" + +#include + +#include "tensorflow/lite/kernels/internal/compatibility.h" + +namespace tflite { + +RecordingSimpleMemoryAllocator::RecordingSimpleMemoryAllocator( + ErrorReporter* error_reporter, uint8_t* buffer_head, size_t buffer_size) + : SimpleMemoryAllocator(error_reporter, buffer_head, buffer_size), + requested_head_bytes_(0), + requested_tail_bytes_(0), + used_bytes_(0), + alloc_count_(0) {} + +RecordingSimpleMemoryAllocator::~RecordingSimpleMemoryAllocator() {} + +RecordingSimpleMemoryAllocator* RecordingSimpleMemoryAllocator::Create( + ErrorReporter* error_reporter, uint8_t* buffer_head, size_t buffer_size) { + TFLITE_DCHECK(error_reporter != nullptr); + TFLITE_DCHECK(buffer_head != nullptr); + RecordingSimpleMemoryAllocator tmp = + RecordingSimpleMemoryAllocator(error_reporter, buffer_head, buffer_size); + + uint8_t* allocator_buffer = + tmp.AllocateFromTail(sizeof(RecordingSimpleMemoryAllocator), + alignof(RecordingSimpleMemoryAllocator)); + // Use the default copy constructor to populate internal states. + return new (allocator_buffer) RecordingSimpleMemoryAllocator(tmp); +} + +size_t RecordingSimpleMemoryAllocator::GetRequestedBytes() const { + return requested_head_bytes_ + requested_tail_bytes_; +} + +size_t RecordingSimpleMemoryAllocator::GetUsedBytes() const { + return used_bytes_; +} + +size_t RecordingSimpleMemoryAllocator::GetAllocatedCount() const { + return alloc_count_; +} + +TfLiteStatus RecordingSimpleMemoryAllocator::EnsureHeadSize(size_t size, + size_t alignment) { + const uint8_t* previous_head = GetHead(); + TfLiteStatus status = SimpleMemoryAllocator::EnsureHeadSize(size, alignment); + if (status == kTfLiteOk) { + used_bytes_ += GetHead() - previous_head; + requested_head_bytes_ = size; + } + return status; +} + +uint8_t* RecordingSimpleMemoryAllocator::AllocateFromTail(size_t size, + size_t alignment) { + const uint8_t* previous_tail = GetTail(); + uint8_t* result = SimpleMemoryAllocator::AllocateFromTail(size, alignment); + if (result != nullptr) { + used_bytes_ += previous_tail - GetTail(); + requested_tail_bytes_ += size; + alloc_count_++; + } + return result; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.h b/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.h new file mode 100644 index 0000000..8d3e9fb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/recording_simple_memory_allocator.h @@ -0,0 +1,64 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_RECORDING_SIMPLE_MEMORY_ALLOCATOR_H_ +#define TENSORFLOW_LITE_MICRO_RECORDING_SIMPLE_MEMORY_ALLOCATOR_H_ + +#include "tensorflow/lite/micro/compatibility.h" +#include "tensorflow/lite/micro/simple_memory_allocator.h" + +namespace tflite { + +// Utility class used to log allocations of a SimpleMemoryAllocator. Should only +// be used in debug/evaluation settings or unit tests to evaluate allocation +// usage. +class RecordingSimpleMemoryAllocator : public SimpleMemoryAllocator { + public: + RecordingSimpleMemoryAllocator(ErrorReporter* error_reporter, + uint8_t* buffer_head, size_t buffer_size); + // TODO(b/157615197): Cleanup constructors/destructor and use factory + // functions. + ~RecordingSimpleMemoryAllocator() override; + + static RecordingSimpleMemoryAllocator* Create(ErrorReporter* error_reporter, + uint8_t* buffer_head, + size_t buffer_size); + + // Returns the number of bytes requested from the head or tail. + size_t GetRequestedBytes() const; + + // Returns the number of bytes actually allocated from the head or tail. This + // value will be >= to the number of requested bytes due to padding and + // alignment. + size_t GetUsedBytes() const; + + // Returns the number of alloc calls from the head or tail. + size_t GetAllocatedCount() const; + + TfLiteStatus EnsureHeadSize(size_t size, size_t alignment) override; + uint8_t* AllocateFromTail(size_t size, size_t alignment) override; + + private: + size_t requested_head_bytes_; + size_t requested_tail_bytes_; + size_t used_bytes_; + size_t alloc_count_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_RECORDING_SIMPLE_MEMORY_ALLOCATOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.cc b/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.cc new file mode 100644 index 0000000..bea1a9d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.cc @@ -0,0 +1,154 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/simple_memory_allocator.h" + +#include +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/memory_helpers.h" + +namespace tflite { + +SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter, + uint8_t* buffer_head, + uint8_t* buffer_tail) + : error_reporter_(error_reporter), + buffer_head_(buffer_head), + buffer_tail_(buffer_tail), + head_(buffer_head), + tail_(buffer_tail), + temp_(buffer_head_) {} + +SimpleMemoryAllocator::SimpleMemoryAllocator(ErrorReporter* error_reporter, + uint8_t* buffer, + size_t buffer_size) + : SimpleMemoryAllocator(error_reporter, buffer, buffer + buffer_size) {} + +/* static */ +SimpleMemoryAllocator* SimpleMemoryAllocator::Create( + ErrorReporter* error_reporter, uint8_t* buffer_head, size_t buffer_size) { + TFLITE_DCHECK(error_reporter != nullptr); + TFLITE_DCHECK(buffer_head != nullptr); + SimpleMemoryAllocator tmp = + SimpleMemoryAllocator(error_reporter, buffer_head, buffer_size); + + // Allocate enough bytes from the buffer to create a SimpleMemoryAllocator. + // The new instance will use the current adjusted tail buffer from the tmp + // allocator instance. + uint8_t* allocator_buffer = tmp.AllocateFromTail( + sizeof(SimpleMemoryAllocator), alignof(SimpleMemoryAllocator)); + // Use the default copy constructor to populate internal states. + return new (allocator_buffer) SimpleMemoryAllocator(tmp); +} + +SimpleMemoryAllocator::~SimpleMemoryAllocator() {} + +TfLiteStatus SimpleMemoryAllocator::EnsureHeadSize(size_t size, + size_t alignment) { + if (head_ != temp_) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Internal error: EnsureHeadSize() needs to be called after" + "ResetTempAllocations()."); + return kTfLiteError; + } + + uint8_t* const aligned_result = AlignPointerUp(buffer_head_, alignment); + if (aligned_result + size < head_) { + // Size is below the current head size, just return. + return kTfLiteOk; + } + + const size_t available_memory = tail_ - aligned_result; + if (available_memory < size) { + TF_LITE_REPORT_ERROR( + error_reporter_, + "Failed to adjust head size. Requested: %u, available %u, missing: %u", + size, available_memory, size - available_memory); + return kTfLiteError; + } + head_ = aligned_result + size; + temp_ = head_; + + return kTfLiteOk; +} + +uint8_t* SimpleMemoryAllocator::AllocateFromTail(size_t size, + size_t alignment) { + uint8_t* const aligned_result = AlignPointerDown(tail_ - size, alignment); + if (aligned_result < head_) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + const size_t missing_memory = head_ - aligned_result; + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to allocate tail memory. Requested: %u, " + "available %u, missing: %u", + size, size - missing_memory, missing_memory); +#endif + return nullptr; + } + tail_ = aligned_result; + return aligned_result; +} + +uint8_t* SimpleMemoryAllocator::AllocateTemp(size_t size, size_t alignment) { + uint8_t* const aligned_result = AlignPointerUp(temp_, alignment); + const size_t available_memory = tail_ - aligned_result; + if (available_memory < size) { + TF_LITE_REPORT_ERROR(error_reporter_, + "Failed to allocate temp memory. Requested: %u, " + "available %u, missing: %u", + size, available_memory, size - available_memory); + return nullptr; + } + temp_ = aligned_result + size; + return aligned_result; +} + +void SimpleMemoryAllocator::ResetTempAllocations() { temp_ = head_; } + +uint8_t* SimpleMemoryAllocator::GetHead() const { return head_; } + +uint8_t* SimpleMemoryAllocator::GetBufferHead() const { return buffer_head_; } + +uint8_t* SimpleMemoryAllocator::GetTail() const { return tail_; } + +size_t SimpleMemoryAllocator::GetHeadUsedBytes() const { + return head_ - buffer_head_; +} + +size_t SimpleMemoryAllocator::GetTailUsedBytes() const { + return buffer_tail_ - tail_; +} + +size_t SimpleMemoryAllocator::GetAvailableMemory(size_t alignment) const { + uint8_t* const aligned_head = AlignPointerUp(head_, alignment); + uint8_t* const aligned_tail = AlignPointerDown(tail_, alignment); + return aligned_tail - aligned_head; +} + +size_t SimpleMemoryAllocator::GetUsedBytes() const { + return GetBufferSize() - (tail_ - head_); +} + +size_t SimpleMemoryAllocator::GetBufferSize() const { + return buffer_tail_ - buffer_head_; +} + +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.h b/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.h new file mode 100644 index 0000000..8c216f4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/simple_memory_allocator.h @@ -0,0 +1,99 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_SIMPLE_MEMORY_ALLOCATOR_H_ +#define TENSORFLOW_LITE_MICRO_SIMPLE_MEMORY_ALLOCATOR_H_ + +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/micro/compatibility.h" + +namespace tflite { + +// TODO(petewarden): This allocator never frees up or reuses any memory, even +// though we have enough information about lifetimes of the tensors to do so. +// This makes it pretty wasteful, so we should use a more intelligent method. +class SimpleMemoryAllocator { + public: + // TODO(b/157615197): Cleanup constructors/destructor and use factory + // functions. + SimpleMemoryAllocator(ErrorReporter* error_reporter, uint8_t* buffer_head, + uint8_t* buffer_tail); + SimpleMemoryAllocator(ErrorReporter* error_reporter, uint8_t* buffer, + size_t buffer_size); + virtual ~SimpleMemoryAllocator(); + + // Creates a new SimpleMemoryAllocator from a given buffer head and size. + static SimpleMemoryAllocator* Create(ErrorReporter* error_reporter, + uint8_t* buffer_head, + size_t buffer_size); + + // Ensure that the head (lowest address and moving upwards) memory allocation + // is at least a given size. This function will only increase the head size if + // the passed in value is larger than the current head size. Calls to this + // method will also invalidate all temporary allocation values. This call will + // fail if a chain of allocations through AllocateTemp() have not been cleaned + // up with a call to ResetTempAllocations(). + virtual TfLiteStatus EnsureHeadSize(size_t size, size_t alignment); + + // Allocates memory starting at the tail of the arena (highest address and + // moving downwards). + virtual uint8_t* AllocateFromTail(size_t size, size_t alignment); + + // Allocates a temporary buffer from the head of the arena (lowest address and + // moving upwards) but does not update the actual head allocation size or + // position. The returned buffer is guaranteed until either + // ResetTempAllocations() is called or another call to AllocateFromHead(). + // Repeat calls to this function will create a chain of temp allocations. All + // calls to AllocateTemp() must end with a call to ResetTempAllocations(). If + // AllocateFromHead() is called before a call to ResetTempAllocations(), it + // will fail with an error message. + virtual uint8_t* AllocateTemp(size_t size, size_t alignment); + + // Resets a chain of temporary allocations back to the current head of the + // arena (lowest address). + virtual void ResetTempAllocations(); + + uint8_t* GetHead() const; + uint8_t* GetBufferHead() const; + uint8_t* GetTail() const; + + size_t GetHeadUsedBytes() const; + size_t GetTailUsedBytes() const; + + // Returns the number of bytes available with a given alignment. + size_t GetAvailableMemory(size_t alignment) const; + + size_t GetUsedBytes() const; + + private: + size_t GetBufferSize() const; + + ErrorReporter* error_reporter_; + uint8_t* buffer_head_; + uint8_t* buffer_tail_; + uint8_t* head_; + uint8_t* tail_; + uint8_t* temp_; + + TF_LITE_REMOVE_VIRTUAL_DELETE +}; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_SIMPLE_MEMORY_ALLOCATOR_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.cc b/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.cc new file mode 100644 index 0000000..23c7ca9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.cc @@ -0,0 +1,1008 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/test_helpers.h" + +#include +#include +#include +#include +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/error_reporter.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/micro/all_ops_resolver.h" +#include "tensorflow/lite/micro/micro_utils.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { +namespace testing { +namespace { + +class StackAllocator : public flatbuffers::Allocator { + public: + StackAllocator() : data_(data_backing_), data_size_(0) {} + + uint8_t* allocate(size_t size) override { + TFLITE_DCHECK((data_size_ + size) <= kStackAllocatorSize); + uint8_t* result = data_; + data_ += size; + data_size_ += size; + return result; + } + + void deallocate(uint8_t* p, size_t) override {} + + static StackAllocator& instance() { + // Avoid using true dynamic memory allocation to be portable to bare metal. + static char inst_memory[sizeof(StackAllocator)]; + static StackAllocator* inst = new (inst_memory) StackAllocator; + return *inst; + } + + static constexpr size_t kStackAllocatorSize = 8192; + + private: + uint8_t data_backing_[kStackAllocatorSize]; + uint8_t* data_; + int data_size_; +}; + +flatbuffers::FlatBufferBuilder* BuilderInstance() { + static char inst_memory[sizeof(flatbuffers::FlatBufferBuilder)]; + static flatbuffers::FlatBufferBuilder* inst = + new (inst_memory) flatbuffers::FlatBufferBuilder( + StackAllocator::kStackAllocatorSize, &StackAllocator::instance()); + return inst; +} + +// A wrapper around FlatBuffer API to help build model easily. +class ModelBuilder { + public: + typedef int32_t Tensor; + typedef int Operator; + typedef int Node; + + // `builder` needs to be available until BuildModel is called. + explicit ModelBuilder(flatbuffers::FlatBufferBuilder* builder) + : builder_(builder) {} + + // Registers an operator that will be used in the model. + Operator RegisterOp(BuiltinOperator op, const char* custom_code, + int32_t version); + + // Adds a tensor to the model. + Tensor AddTensor(TensorType type, std::initializer_list shape) { + return AddTensorImpl(type, /* is_variable */ false, shape); + } + + // Adds a variable tensor to the model. + Tensor AddVariableTensor(TensorType type, + std::initializer_list shape) { + return AddTensorImpl(type, /* is_variable */ true, shape); + } + + // Adds a node to the model with given input and output Tensors. + Node AddNode(Operator op, std::initializer_list inputs, + std::initializer_list outputs); + + void AddMetadata(const char* description_string, + const int32_t* metadata_buffer_data, size_t num_elements); + + // Constructs the flatbuffer model using `builder_` and return a pointer to + // it. The returned model has the same lifetime as `builder_`. + const Model* BuildModel(std::initializer_list inputs, + std::initializer_list outputs); + + private: + // Adds a tensor to the model. + Tensor AddTensorImpl(TensorType type, bool is_variable, + std::initializer_list shape); + + flatbuffers::FlatBufferBuilder* builder_; + + static constexpr int kMaxOperatorCodes = 10; + flatbuffers::Offset operator_codes_[kMaxOperatorCodes]; + int next_operator_code_id_ = 0; + + static constexpr int kMaxOperators = 50; + flatbuffers::Offset operators_[kMaxOperators]; + int next_operator_id_ = 0; + + static constexpr int kMaxTensors = 50; + flatbuffers::Offset tensors_[kMaxTensors]; + + static constexpr int kMaxMetadataBuffers = 10; + + static constexpr int kMaxMetadatas = 10; + flatbuffers::Offset metadata_[kMaxMetadatas]; + + flatbuffers::Offset metadata_buffers_[kMaxMetadataBuffers]; + + int nbr_of_metadata_buffers_ = 0; + + int next_tensor_id_ = 0; +}; + +ModelBuilder::Operator ModelBuilder::RegisterOp(BuiltinOperator op, + const char* custom_code, + int32_t version) { + TFLITE_DCHECK(next_operator_code_id_ <= kMaxOperatorCodes); + operator_codes_[next_operator_code_id_] = + tflite::CreateOperatorCodeDirect(*builder_, op, custom_code, version); + next_operator_code_id_++; + return next_operator_code_id_ - 1; +} + +ModelBuilder::Node ModelBuilder::AddNode( + ModelBuilder::Operator op, + std::initializer_list inputs, + std::initializer_list outputs) { + TFLITE_DCHECK(next_operator_id_ <= kMaxOperators); + operators_[next_operator_id_] = tflite::CreateOperator( + *builder_, op, builder_->CreateVector(inputs.begin(), inputs.size()), + builder_->CreateVector(outputs.begin(), outputs.size()), + BuiltinOptions_NONE); + next_operator_id_++; + return next_operator_id_ - 1; +} + +void ModelBuilder::AddMetadata(const char* description_string, + const int32_t* metadata_buffer_data, + size_t num_elements) { + metadata_[ModelBuilder::nbr_of_metadata_buffers_] = + CreateMetadata(*builder_, builder_->CreateString(description_string), + 1 + ModelBuilder::nbr_of_metadata_buffers_); + + metadata_buffers_[nbr_of_metadata_buffers_] = tflite::CreateBuffer( + *builder_, builder_->CreateVector((uint8_t*)metadata_buffer_data, + sizeof(uint32_t) * num_elements)); + + ModelBuilder::nbr_of_metadata_buffers_++; +} + +const Model* ModelBuilder::BuildModel( + std::initializer_list inputs, + std::initializer_list outputs) { + // Model schema requires an empty buffer at idx 0. + size_t buffer_size = 1 + ModelBuilder::nbr_of_metadata_buffers_; + flatbuffers::Offset buffers[kMaxMetadataBuffers]; + buffers[0] = tflite::CreateBuffer(*builder_); + + // Place the metadata buffers first in the buffer since the indices for them + // have already been set in AddMetadata() + for (int i = 1; i < ModelBuilder::nbr_of_metadata_buffers_ + 1; ++i) { + buffers[i] = metadata_buffers_[i - 1]; + } + + // TFLM only supports single subgraph. + constexpr size_t subgraphs_size = 1; + const flatbuffers::Offset subgraphs[subgraphs_size] = { + tflite::CreateSubGraph( + *builder_, builder_->CreateVector(tensors_, next_tensor_id_), + builder_->CreateVector(inputs.begin(), inputs.size()), + builder_->CreateVector(outputs.begin(), outputs.size()), + builder_->CreateVector(operators_, next_operator_id_), + builder_->CreateString("test_subgraph"))}; + + flatbuffers::Offset model_offset; + if (ModelBuilder::nbr_of_metadata_buffers_ > 0) { + model_offset = tflite::CreateModel( + *builder_, 0, + builder_->CreateVector(operator_codes_, next_operator_code_id_), + builder_->CreateVector(subgraphs, subgraphs_size), + builder_->CreateString("teset_model"), + builder_->CreateVector(buffers, buffer_size), 0, + builder_->CreateVector(metadata_, + ModelBuilder::nbr_of_metadata_buffers_)); + } else { + model_offset = tflite::CreateModel( + *builder_, 0, + builder_->CreateVector(operator_codes_, next_operator_code_id_), + builder_->CreateVector(subgraphs, subgraphs_size), + builder_->CreateString("teset_model"), + builder_->CreateVector(buffers, buffer_size)); + } + + tflite::FinishModelBuffer(*builder_, model_offset); + void* model_pointer = builder_->GetBufferPointer(); + const Model* model = flatbuffers::GetRoot(model_pointer); + return model; +} + +ModelBuilder::Tensor ModelBuilder::AddTensorImpl( + TensorType type, bool is_variable, std::initializer_list shape) { + TFLITE_DCHECK(next_tensor_id_ <= kMaxTensors); + tensors_[next_tensor_id_] = tflite::CreateTensor( + *builder_, builder_->CreateVector(shape.begin(), shape.size()), type, + /* buffer */ 0, /* name */ 0, /* quantization */ 0, + /* is_variable */ is_variable, + /* sparsity */ 0); + next_tensor_id_++; + return next_tensor_id_ - 1; +} + +const Model* BuildSimpleStatefulModel() { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* fb_builder = BuilderInstance(); + + ModelBuilder model_builder(fb_builder); + + const int op_id = + model_builder.RegisterOp(BuiltinOperator_CUSTOM, "simple_stateful_op", 0); + const int input_tensor = model_builder.AddTensor(TensorType_UINT8, {3}); + const int median_tensor = model_builder.AddTensor(TensorType_UINT8, {3}); + const int invoke_count_tensor = + model_builder.AddTensor(TensorType_INT32, {1}); + + model_builder.AddNode(op_id, {input_tensor}, + {median_tensor, invoke_count_tensor}); + return model_builder.BuildModel({input_tensor}, + {median_tensor, invoke_count_tensor}); +} + +const Model* BuildSimpleModelWithBranch() { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* fb_builder = BuilderInstance(); + + ModelBuilder model_builder(fb_builder); + /* Model structure + | t0 + +------| + | v + | +---------+ + | | n0 | + | | | + | +---------+ + v + + | + +---------+ | t1 + | n1 | | + | | | + +---------+ | + | | + t2 | v + | +---------+ + +-->| n2 | + | | + +-------|-+ + |t3 + v + */ + const int op_id = + model_builder.RegisterOp(BuiltinOperator_CUSTOM, "mock_custom", + /* version= */ 0); + const int t0 = model_builder.AddTensor(TensorType_FLOAT32, {2, 2, 3}); + const int t1 = model_builder.AddTensor(TensorType_FLOAT32, {2, 2, 3}); + const int t2 = model_builder.AddTensor(TensorType_FLOAT32, {2, 2, 3}); + const int t3 = model_builder.AddTensor(TensorType_FLOAT32, {2, 2, 3}); + model_builder.AddNode(op_id, {t0}, {t1}); // n0 + model_builder.AddNode(op_id, {t0}, {t2}); // n1 + model_builder.AddNode(op_id, {t1, t2}, {t3}); // n2 + return model_builder.BuildModel({t0}, {t3}); +} + +const Model* BuildModelWithOfflinePlanning(int number_of_tensors, + const int32_t* metadata_buffer, + NodeConnection* node_conn, + int num_conns) { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* fb_builder = BuilderInstance(); + + ModelBuilder model_builder(fb_builder); + + const int op_id = + model_builder.RegisterOp(BuiltinOperator_CUSTOM, "mock_custom", + /* version= */ 0); + + for (int i = 0; i < number_of_tensors; ++i) { + model_builder.AddTensor(TensorType_FLOAT32, {2, 2, 3}); + } + + for (int i = 0; i < num_conns; ++i) { + model_builder.AddNode(op_id, node_conn[i].input, node_conn[i].output); + } + + model_builder.AddMetadata( + "OfflineMemoryAllocation", metadata_buffer, + number_of_tensors + tflite::testing::kOfflinePlannerHeaderSize); + + return model_builder.BuildModel(node_conn[0].input, + node_conn[num_conns - 1].output); +} + +const Model* BuildSimpleMockModel() { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + + constexpr size_t buffer_data_size = 1; + const uint8_t buffer_data[buffer_data_size] = {21}; + constexpr size_t buffers_size = 2; + const Offset buffers[buffers_size] = { + CreateBuffer(*builder), + CreateBuffer(*builder, + builder->CreateVector(buffer_data, buffer_data_size))}; + constexpr size_t tensor_shape_size = 1; + const int32_t tensor_shape[tensor_shape_size] = {1}; + constexpr size_t tensors_size = 4; + const Offset tensors[tensors_size] = { + CreateTensor(*builder, + builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, + builder->CreateString("test_input_tensor"), 0, false), + CreateTensor(*builder, + builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_UINT8, 1, + builder->CreateString("test_weight_tensor"), 0, false), + CreateTensor(*builder, + builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, + builder->CreateString("test_output_tensor"), 0, false), + CreateTensor(*builder, + builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, + builder->CreateString("test_output2_tensor"), 0, false), + }; + constexpr size_t inputs_size = 1; + const int32_t inputs[inputs_size] = {0}; + constexpr size_t outputs_size = 2; + const int32_t outputs[outputs_size] = {2, 3}; + constexpr size_t operator_inputs_size = 2; + const int32_t operator_inputs[operator_inputs_size] = {0, 1}; + constexpr size_t operator_outputs_size = 1; + const int32_t operator_outputs[operator_outputs_size] = {2}; + const int32_t operator2_outputs[operator_outputs_size] = {3}; + constexpr size_t operators_size = 2; + const Offset operators[operators_size] = { + CreateOperator( + *builder, 0, + builder->CreateVector(operator_inputs, operator_inputs_size), + builder->CreateVector(operator_outputs, operator_outputs_size), + BuiltinOptions_NONE), + CreateOperator( + *builder, 0, + builder->CreateVector(operator_inputs, operator_inputs_size), + builder->CreateVector(operator2_outputs, operator_outputs_size), + BuiltinOptions_NONE), + }; + constexpr size_t subgraphs_size = 1; + const Offset subgraphs[subgraphs_size] = { + CreateSubGraph(*builder, builder->CreateVector(tensors, tensors_size), + builder->CreateVector(inputs, inputs_size), + builder->CreateVector(outputs, outputs_size), + builder->CreateVector(operators, operators_size), + builder->CreateString("test_subgraph"))}; + constexpr size_t operator_codes_size = 1; + const Offset operator_codes[operator_codes_size] = { + CreateOperatorCodeDirect(*builder, BuiltinOperator_CUSTOM, "mock_custom", + 0)}; + const Offset model_offset = CreateModel( + *builder, 0, builder->CreateVector(operator_codes, operator_codes_size), + builder->CreateVector(subgraphs, subgraphs_size), + builder->CreateString("test_model"), + builder->CreateVector(buffers, buffers_size)); + FinishModelBuffer(*builder, model_offset); + void* model_pointer = builder->GetBufferPointer(); + const Model* model = flatbuffers::GetRoot(model_pointer); + return model; +} + +const Model* BuildComplexMockModel() { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + + constexpr size_t buffer_data_size = 1; + const uint8_t buffer_data_1[buffer_data_size] = {21}; + const uint8_t buffer_data_2[buffer_data_size] = {21}; + const uint8_t buffer_data_3[buffer_data_size] = {21}; + constexpr size_t buffers_size = 7; + const Offset buffers[buffers_size] = { + // Op 1 buffers: + CreateBuffer(*builder), + CreateBuffer(*builder), + CreateBuffer(*builder, + builder->CreateVector(buffer_data_1, buffer_data_size)), + // Op 2 buffers: + CreateBuffer(*builder), + CreateBuffer(*builder, + builder->CreateVector(buffer_data_2, buffer_data_size)), + // Op 3 buffers: + CreateBuffer(*builder), + CreateBuffer(*builder, + builder->CreateVector(buffer_data_3, buffer_data_size)), + }; + constexpr size_t tensor_shape_size = 1; + const int32_t tensor_shape[tensor_shape_size] = {1}; + + constexpr size_t tensors_size = 10; + const Offset tensors[tensors_size] = { + // Op 1 inputs: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_input_tensor_1"), 0, + false /* is_variable */), + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 1, builder->CreateString("test_variable_tensor_1"), + 0, true /* is_variable */), + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_UINT8, 2, builder->CreateString("test_weight_tensor_1"), 0, + false /* is_variable */), + // Op 1 output / Op 2 input: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_output_tensor_1"), 0, + false /* is_variable */), + // Op 2 inputs: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 1, builder->CreateString("test_variable_tensor_2"), + 0, true /* is_variable */), + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_UINT8, 2, builder->CreateString("test_weight_tensor_2"), 0, + false /* is_variable */), + // Op 2 output / Op 3 input: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_output_tensor_2"), 0, + false /* is_variable */), + // Op 3 inputs: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 1, builder->CreateString("test_variable_tensor_3"), + 0, true /* is_variable */), + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_UINT8, 2, builder->CreateString("test_weight_tensor_3"), 0, + false /* is_variable */), + // Op 3 output: + CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_output_tensor_3"), 0, + false /* is_variable */), + }; + + constexpr size_t operators_size = 3; + Offset operators[operators_size]; + { + // Set Op 1 attributes: + constexpr size_t operator_inputs_size = 3; + const int32_t operator_inputs[operator_inputs_size] = {0, 1, 2}; + constexpr size_t operator_outputs_size = 1; + const int32_t operator_outputs[operator_outputs_size] = {3}; + + operators[0] = {CreateOperator( + *builder, 0, + builder->CreateVector(operator_inputs, operator_inputs_size), + builder->CreateVector(operator_outputs, operator_outputs_size), + BuiltinOptions_NONE)}; + } + + { + // Set Op 2 attributes + constexpr size_t operator_inputs_size = 3; + const int32_t operator_inputs[operator_inputs_size] = {3, 4, 5}; + constexpr size_t operator_outputs_size = 1; + const int32_t operator_outputs[operator_outputs_size] = {6}; + + operators[1] = {CreateOperator( + *builder, 0, + builder->CreateVector(operator_inputs, operator_inputs_size), + builder->CreateVector(operator_outputs, operator_outputs_size), + BuiltinOptions_NONE)}; + } + + { + // Set Op 3 attributes + constexpr size_t operator_inputs_size = 3; + const int32_t operator_inputs[operator_inputs_size] = {6, 7, 8}; + constexpr size_t operator_outputs_size = 1; + const int32_t operator_outputs[operator_outputs_size] = {9}; + + operators[2] = {CreateOperator( + *builder, 0, + builder->CreateVector(operator_inputs, operator_inputs_size), + builder->CreateVector(operator_outputs, operator_outputs_size), + BuiltinOptions_NONE)}; + } + + constexpr size_t inputs_size = 1; + const int32_t inputs[inputs_size] = {0}; + constexpr size_t outputs_size = 1; + const int32_t outputs[outputs_size] = {9}; + + constexpr size_t subgraphs_size = 1; + const Offset subgraphs[subgraphs_size] = { + CreateSubGraph(*builder, builder->CreateVector(tensors, tensors_size), + builder->CreateVector(inputs, inputs_size), + builder->CreateVector(outputs, outputs_size), + builder->CreateVector(operators, operators_size), + builder->CreateString("test_subgraph"))}; + + constexpr size_t operator_codes_size = 1; + const Offset operator_codes[operator_codes_size] = { + CreateOperatorCodeDirect(*builder, BuiltinOperator_CUSTOM, "mock_custom", + 0)}; + + const Offset model_offset = CreateModel( + *builder, 0, builder->CreateVector(operator_codes, operator_codes_size), + builder->CreateVector(subgraphs, subgraphs_size), + builder->CreateString("test_model"), + builder->CreateVector(buffers, buffers_size)); + + FinishModelBuffer(*builder, model_offset); + void* model_pointer = builder->GetBufferPointer(); + const Model* model = flatbuffers::GetRoot(model_pointer); + return model; +} + +} // namespace + +const TfLiteRegistration* SimpleStatefulOp::getRegistration() { + return GetMutableRegistration(); +} + +TfLiteRegistration* SimpleStatefulOp::GetMutableRegistration() { + static TfLiteRegistration r; + r.init = Init; + r.prepare = Prepare; + r.invoke = Invoke; + return &r; +} + +void* SimpleStatefulOp::Init(TfLiteContext* context, const char* buffer, + size_t length) { + TFLITE_DCHECK(context->AllocateBufferForEval == nullptr); + TFLITE_DCHECK(context->GetScratchBuffer == nullptr); + TFLITE_DCHECK(context->RequestScratchBufferInArena == nullptr); + + void* raw = context->AllocatePersistentBuffer(context, sizeof(OpData)); + OpData* data = reinterpret_cast(raw); + *data = {}; + return raw; +} + +TfLiteStatus SimpleStatefulOp::Prepare(TfLiteContext* context, + TfLiteNode* node) { + OpData* data = reinterpret_cast(node->user_data); + + // Make sure that the input is in uint8_t with at least 1 data entry. + const TfLiteTensor* input = tflite::GetInput(context, node, kInputTensor); + if (input->type != kTfLiteUInt8) return kTfLiteError; + if (NumElements(input->dims) == 0) return kTfLiteError; + + // Allocate a temporary buffer with the same size of input for sorting. + TF_LITE_ENSURE_STATUS(context->RequestScratchBufferInArena( + context, sizeof(uint8_t) * NumElements(input->dims), + &data->sorting_buffer)); + return kTfLiteOk; +} + +TfLiteStatus SimpleStatefulOp::Invoke(TfLiteContext* context, + TfLiteNode* node) { + OpData* data = reinterpret_cast(node->user_data); + data->invoke_count += 1; + + const TfLiteTensor* input = GetInput(context, node, kInputTensor); + const uint8_t* input_data = GetTensorData(input); + int size = NumElements(input->dims); + + uint8_t* sorting_buffer = reinterpret_cast( + context->GetScratchBuffer(context, data->sorting_buffer)); + // Copy inputs data to the sorting buffer. We don't want to mutate the input + // tensor as it might be used by a another node. + for (int i = 0; i < size; i++) { + sorting_buffer[i] = input_data[i]; + } + + // In place insertion sort on `sorting_buffer`. + for (int i = 1; i < size; i++) { + for (int j = i; j > 0 && sorting_buffer[j] < sorting_buffer[j - 1]; j--) { + std::swap(sorting_buffer[j], sorting_buffer[j - 1]); + } + } + + TfLiteTensor* median = GetOutput(context, node, kMedianTensor); + uint8_t* median_data = GetTensorData(median); + TfLiteTensor* invoke_count = GetOutput(context, node, kInvokeCount); + int32_t* invoke_count_data = GetTensorData(invoke_count); + + median_data[0] = sorting_buffer[size / 2]; + invoke_count_data[0] = data->invoke_count; + return kTfLiteOk; +} + +const TfLiteRegistration* MockCustom::getRegistration() { + return GetMutableRegistration(); +} + +TfLiteRegistration* MockCustom::GetMutableRegistration() { + static TfLiteRegistration r; + r.init = Init; + r.prepare = Prepare; + r.invoke = Invoke; + r.free = Free; + return &r; +} + +void* MockCustom::Init(TfLiteContext* context, const char* buffer, + size_t length) { + // We don't support delegate in TFL micro. This is a weak check to test if + // context struct being zero-initialized. + TFLITE_DCHECK(context->ReplaceNodeSubsetsWithDelegateKernels == nullptr); + freed_ = false; + // Do nothing. + return nullptr; +} + +void MockCustom::Free(TfLiteContext* context, void* buffer) { freed_ = true; } + +TfLiteStatus MockCustom::Prepare(TfLiteContext* context, TfLiteNode* node) { + return kTfLiteOk; +} + +TfLiteStatus MockCustom::Invoke(TfLiteContext* context, TfLiteNode* node) { + const TfLiteTensor* input = tflite::GetInput(context, node, 0); + const int32_t* input_data = input->data.i32; + const TfLiteTensor* weight = tflite::GetInput(context, node, 1); + const uint8_t* weight_data = weight->data.uint8; + TfLiteTensor* output = GetOutput(context, node, 0); + int32_t* output_data = output->data.i32; + output_data[0] = + 0; // Catch output tensor sharing memory with an input tensor + output_data[0] = input_data[0] + weight_data[0]; + return kTfLiteOk; +} + +bool MockCustom::freed_ = false; + +AllOpsResolver GetOpResolver() { + AllOpsResolver op_resolver; + op_resolver.AddCustom("mock_custom", MockCustom::GetMutableRegistration()); + op_resolver.AddCustom("simple_stateful_op", + SimpleStatefulOp::GetMutableRegistration()); + + return op_resolver; +} + +const Model* GetSimpleMockModel() { + static Model* model = nullptr; + if (!model) { + model = const_cast(BuildSimpleMockModel()); + } + return model; +} + +const Model* GetComplexMockModel() { + static Model* model = nullptr; + if (!model) { + model = const_cast(BuildComplexMockModel()); + } + return model; +} + +const Model* GetSimpleModelWithBranch() { + static Model* model = nullptr; + if (!model) { + model = const_cast(BuildSimpleModelWithBranch()); + } + return model; +} + +const Model* GetModelWithOfflinePlanning(int num_tensors, + const int32_t* metadata_buffer, + NodeConnection* node_conn, + int num_conns) { + const Model* model = BuildModelWithOfflinePlanning( + num_tensors, metadata_buffer, node_conn, num_conns); + return model; +} + +const Model* GetSimpleStatefulModel() { + static Model* model = nullptr; + if (!model) { + model = const_cast(BuildSimpleStatefulModel()); + } + return model; +} + +const Tensor* Create1dFlatbufferTensor(int size, bool is_variable) { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + constexpr size_t tensor_shape_size = 1; + const int32_t tensor_shape[tensor_shape_size] = {size}; + const Offset tensor_offset = CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_tensor"), 0, + is_variable); + builder->Finish(tensor_offset); + void* tensor_pointer = builder->GetBufferPointer(); + const Tensor* tensor = flatbuffers::GetRoot(tensor_pointer); + return tensor; +} + +const Tensor* CreateQuantizedFlatbufferTensor(int size) { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + const Offset quant_params = + CreateQuantizationParameters( + *builder, + /*min=*/builder->CreateVector({0.1f}), + /*max=*/builder->CreateVector({0.2f}), + /*scale=*/builder->CreateVector({0.3f}), + /*zero_point=*/builder->CreateVector({100ll})); + + constexpr size_t tensor_shape_size = 1; + const int32_t tensor_shape[tensor_shape_size] = {size}; + const Offset tensor_offset = CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_tensor"), quant_params, + false); + builder->Finish(tensor_offset); + void* tensor_pointer = builder->GetBufferPointer(); + const Tensor* tensor = flatbuffers::GetRoot(tensor_pointer); + return tensor; +} + +const Tensor* CreateMissingQuantizationFlatbufferTensor(int size) { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + const Offset quant_params = + CreateQuantizationParameters(*builder, 0, 0, 0, 0, + QuantizationDetails_NONE, 0, 0); + constexpr size_t tensor_shape_size = 1; + const int32_t tensor_shape[tensor_shape_size] = {size}; + const Offset tensor_offset = CreateTensor( + *builder, builder->CreateVector(tensor_shape, tensor_shape_size), + TensorType_INT32, 0, builder->CreateString("test_tensor"), quant_params, + false); + builder->Finish(tensor_offset); + void* tensor_pointer = builder->GetBufferPointer(); + const Tensor* tensor = flatbuffers::GetRoot(tensor_pointer); + return tensor; +} + +const flatbuffers::Vector>* +CreateFlatbufferBuffers() { + using flatbuffers::Offset; + flatbuffers::FlatBufferBuilder* builder = BuilderInstance(); + constexpr size_t buffers_size = 1; + const Offset buffers[buffers_size] = { + CreateBuffer(*builder), + }; + const flatbuffers::Offset>> + buffers_offset = builder->CreateVector(buffers, buffers_size); + builder->Finish(buffers_offset); + void* buffers_pointer = builder->GetBufferPointer(); + const flatbuffers::Vector>* result = + flatbuffers::GetRoot>>( + buffers_pointer); + return result; +} + +int TestStrcmp(const char* a, const char* b) { + if ((a == nullptr) || (b == nullptr)) { + return -1; + } + while ((*a != 0) && (*a == *b)) { + a++; + b++; + } + return *reinterpret_cast(a) - + *reinterpret_cast(b); +} + +// Wrapper to forward kernel errors to the interpreter's error reporter. +void ReportOpError(struct TfLiteContext* context, const char* format, ...) { +#ifndef TF_LITE_STRIP_ERROR_STRINGS + ErrorReporter* error_reporter = static_cast(context->impl_); + va_list args; + va_start(args, format); + TF_LITE_REPORT_ERROR(error_reporter, format, args); + va_end(args); +#endif +} + +// Create a TfLiteIntArray from an array of ints. The first element in the +// supplied array must be the size of the array expressed as an int. +TfLiteIntArray* IntArrayFromInts(const int* int_array) { + return const_cast( + reinterpret_cast(int_array)); +} + +// Create a TfLiteFloatArray from an array of floats. The first element in the +// supplied array must be the size of the array expressed as a float. +TfLiteFloatArray* FloatArrayFromFloats(const float* floats) { + static_assert(sizeof(float) == sizeof(int), + "assumes sizeof(float) == sizeof(int) to perform casting"); + int size = static_cast(floats[0]); + *reinterpret_cast(const_cast(floats)) = size; + return reinterpret_cast(const_cast(floats)); +} + +TfLiteTensor CreateTensor(TfLiteIntArray* dims, bool is_variable) { + TfLiteTensor result; + result.dims = dims; + result.params = {}; + result.quantization = {kTfLiteNoQuantization, nullptr}; + result.is_variable = is_variable; + result.allocation_type = kTfLiteMemNone; + return result; +} + +TfLiteTensor CreateFloatTensor(const float* data, TfLiteIntArray* dims, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteFloat32; + result.data.f = const_cast(data); + result.bytes = ElementCount(*dims) * sizeof(float); + return result; +} + +void PopulateFloatTensor(TfLiteTensor* tensor, float* begin, float* end) { + float* p = begin; + float* v = tensor->data.f; + while (p != end) { + *v++ = *p++; + } +} + +TfLiteTensor CreateBoolTensor(const bool* data, TfLiteIntArray* dims, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteBool; + result.data.b = const_cast(data); + result.bytes = ElementCount(*dims) * sizeof(bool); + return result; +} + +TfLiteTensor CreateInt32Tensor(const int32_t* data, TfLiteIntArray* dims, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt32; + result.data.i32 = const_cast(data); + result.bytes = ElementCount(*dims) * sizeof(int32_t); + return result; +} + +TfLiteTensor CreateQuantizedTensor(const uint8_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteUInt8; + result.data.uint8 = const_cast(data); + result.params = {scale, zero_point}; + result.quantization = {kTfLiteAffineQuantization, nullptr}; + result.bytes = ElementCount(*dims) * sizeof(uint8_t); + return result; +} + +TfLiteTensor CreateQuantizedTensor(const int8_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt8; + result.data.int8 = const_cast(data); + result.params = {scale, zero_point}; + result.quantization = {kTfLiteAffineQuantization, nullptr}; + result.bytes = ElementCount(*dims) * sizeof(int8_t); + return result; +} + +TfLiteTensor CreateQuantizedTensor(const int16_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable) { + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt16; + result.data.i16 = const_cast(data); + result.params = {scale, zero_point}; + result.quantization = {kTfLiteAffineQuantization, nullptr}; + result.bytes = ElementCount(*dims) * sizeof(int16_t); + return result; +} + +TfLiteTensor CreateQuantizedBiasTensor(const float* data, int32_t* quantized, + TfLiteIntArray* dims, float input_scale, + float weights_scale, bool is_variable) { + float bias_scale = input_scale * weights_scale; + tflite::SymmetricQuantize(data, quantized, ElementCount(*dims), bias_scale); + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt32; + result.data.i32 = const_cast(quantized); + // Quantized int32_t tensors always have a zero point of 0, since the range of + // int32_t values is large, and because zero point costs extra cycles during + // processing. + result.params = {bias_scale, 0}; + result.quantization = {kTfLiteAffineQuantization, nullptr}; + result.bytes = ElementCount(*dims) * sizeof(int32_t); + return result; +} + +// Quantizes int32_t bias tensor with per-channel weights determined by input +// scale multiplied by weight scale for each channel. +TfLiteTensor CreatePerChannelQuantizedBiasTensor( + const float* input, int32_t* quantized, TfLiteIntArray* dims, + float input_scale, float* weight_scales, float* scales, int* zero_points, + TfLiteAffineQuantization* affine_quant, int quantized_dimension, + bool is_variable) { + int input_size = ElementCount(*dims); + int num_channels = dims->data[quantized_dimension]; + // First element is reserved for array length + zero_points[0] = num_channels; + scales[0] = static_cast(num_channels); + float* scales_array = &scales[1]; + for (int i = 0; i < num_channels; i++) { + scales_array[i] = input_scale * weight_scales[i]; + zero_points[i + 1] = 0; + } + + SymmetricPerChannelQuantize(input, quantized, input_size, num_channels, + scales_array); + + affine_quant->scale = FloatArrayFromFloats(scales); + affine_quant->zero_point = IntArrayFromInts(zero_points); + affine_quant->quantized_dimension = quantized_dimension; + + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt32; + result.data.i32 = const_cast(quantized); + result.quantization = {kTfLiteAffineQuantization, affine_quant}; + result.bytes = ElementCount(*dims) * sizeof(int32_t); + return result; +} + +TfLiteTensor CreateSymmetricPerChannelQuantizedTensor( + const float* input, int8_t* quantized, TfLiteIntArray* dims, float* scales, + int* zero_points, TfLiteAffineQuantization* affine_quant, + int quantized_dimension, bool is_variable) { + int channel_count = dims->data[quantized_dimension]; + scales[0] = static_cast(channel_count); + zero_points[0] = channel_count; + + SignedSymmetricPerChannelQuantize(input, dims, quantized_dimension, quantized, + &scales[1]); + + for (int i = 0; i < channel_count; i++) { + zero_points[i + 1] = 0; + } + + affine_quant->scale = FloatArrayFromFloats(scales); + affine_quant->zero_point = IntArrayFromInts(zero_points); + affine_quant->quantized_dimension = quantized_dimension; + + TfLiteTensor result = CreateTensor(dims, is_variable); + result.type = kTfLiteInt8; + result.data.int8 = const_cast(quantized); + result.quantization = {kTfLiteAffineQuantization, affine_quant}; + result.bytes = ElementCount(*dims) * sizeof(int8_t); + return result; +} + +size_t GetModelTensorCount(const Model* model) { + auto* subgraphs = model->subgraphs(); + if (subgraphs) { + return (*subgraphs)[0]->tensors()->size(); + } + return 0; +} + +} // namespace testing +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.h b/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.h new file mode 100644 index 0000000..a789714 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/test_helpers.h @@ -0,0 +1,186 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_TEST_HELPERS_H_ +#define TENSORFLOW_LITE_MICRO_TEST_HELPERS_H_ + +// Useful functions for writing tests. + +#include + +#include "flatbuffers/flatbuffers.h" // from @flatbuffers +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/compatibility.h" +#include "tensorflow/lite/micro/all_ops_resolver.h" +#include "tensorflow/lite/micro/micro_utils.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace tflite { +namespace testing { + +constexpr int kOfflinePlannerHeaderSize = 3; + +struct NodeConnection_ { + std::initializer_list input; + std::initializer_list output; +}; +typedef struct NodeConnection_ NodeConnection; + +// A simple operator that returns the median of the input with the number of +// times the kernel was invoked. The implementation below is deliberately +// complicated, just to demonstrate how kernel memory planning works. +class SimpleStatefulOp { + static constexpr int kBufferNotAllocated = 0; + // Inputs: + static constexpr int kInputTensor = 0; + // Outputs: + static constexpr int kMedianTensor = 0; + static constexpr int kInvokeCount = 1; + struct OpData { + int invoke_count = 0; + int sorting_buffer = kBufferNotAllocated; + }; + + public: + static const TfLiteRegistration* getRegistration(); + static TfLiteRegistration* GetMutableRegistration(); + static void* Init(TfLiteContext* context, const char* buffer, size_t length); + static TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node); + static TfLiteStatus Invoke(TfLiteContext* context, TfLiteNode* node); +}; + +class MockCustom { + public: + static const TfLiteRegistration* getRegistration(); + static TfLiteRegistration* GetMutableRegistration(); + static void* Init(TfLiteContext* context, const char* buffer, size_t length); + static void Free(TfLiteContext* context, void* buffer); + static TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node); + static TfLiteStatus Invoke(TfLiteContext* context, TfLiteNode* node); + + static bool freed_; +}; + +// Returns an Op Resolver that can be used in the testing code. +AllOpsResolver GetOpResolver(); + +// Returns a simple example flatbuffer TensorFlow Lite model. Contains 1 input, +// 1 layer of weights, 1 output Tensor, and 1 operator. +const Model* GetSimpleMockModel(); + +// Returns a flatbuffer TensorFlow Lite model with more inputs, variable +// tensors, and operators. +const Model* GetComplexMockModel(); + +// Returns a simple flatbuffer model with two branches. +const Model* GetSimpleModelWithBranch(); + +// Returns a simple flatbuffer model with offline planned tensors +const Model* GetModelWithOfflinePlanning(int num_tensors, + const int32_t* metadata_buffer, + NodeConnection* node_conn, + int num_conns); + +// Returns a flatbuffer model with `simple_stateful_op` +const Model* GetSimpleStatefulModel(); + +// Builds a one-dimensional flatbuffer tensor of the given size. +const Tensor* Create1dFlatbufferTensor(int size, bool is_variable = false); + +// Builds a one-dimensional flatbuffer tensor of the given size with +// quantization metadata. +const Tensor* CreateQuantizedFlatbufferTensor(int size); + +// Creates a one-dimensional tensor with no quantization metadata. +const Tensor* CreateMissingQuantizationFlatbufferTensor(int size); + +// Creates a vector of flatbuffer buffers. +const flatbuffers::Vector>* +CreateFlatbufferBuffers(); + +// Performs a simple string comparison without requiring standard C library. +int TestStrcmp(const char* a, const char* b); + +// Wrapper to forward kernel errors to the interpreter's error reporter. +void ReportOpError(struct TfLiteContext* context, const char* format, ...); + +void PopulateContext(TfLiteTensor* tensors, int tensors_size, + TfLiteContext* context); + +// Create a TfLiteIntArray from an array of ints. The first element in the +// supplied array must be the size of the array expressed as an int. +TfLiteIntArray* IntArrayFromInts(const int* int_array); + +// Create a TfLiteFloatArray from an array of floats. The first element in the +// supplied array must be the size of the array expressed as a float. +TfLiteFloatArray* FloatArrayFromFloats(const float* floats); + +TfLiteTensor CreateFloatTensor(const float* data, TfLiteIntArray* dims, + bool is_variable = false); + +void PopulateFloatTensor(TfLiteTensor* tensor, float* begin, float* end); + +TfLiteTensor CreateBoolTensor(const bool* data, TfLiteIntArray* dims, + bool is_variable = false); + +TfLiteTensor CreateInt32Tensor(const int32_t*, TfLiteIntArray* dims, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(const uint8_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(const int8_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(const int16_t* data, TfLiteIntArray* dims, + float scale, int zero_point, + bool is_variable = false); + +template +TfLiteTensor CreateQuantizedTensor(const float* input, T* quantized, + TfLiteIntArray* dims, float scale, + int zero_point, bool is_variable = false) { + int input_size = ElementCount(*dims); + tflite::AsymmetricQuantize(input, quantized, input_size, scale, zero_point); + return CreateQuantizedTensor(quantized, dims, scale, zero_point, is_variable); +} + +TfLiteTensor CreateQuantizedBiasTensor(const float* data, int32_t* quantized, + TfLiteIntArray* dims, float input_scale, + float weights_scale, + bool is_variable = false); + +// Quantizes int32_t bias tensor with per-channel weights determined by input +// scale multiplied by weight scale for each channel. +TfLiteTensor CreatePerChannelQuantizedBiasTensor( + const float* input, int32_t* quantized, TfLiteIntArray* dims, + float input_scale, float* weight_scales, float* scales, int* zero_points, + TfLiteAffineQuantization* affine_quant, int quantized_dimension, + bool is_variable = false); + +TfLiteTensor CreateSymmetricPerChannelQuantizedTensor( + const float* input, int8_t* quantized, TfLiteIntArray* dims, float* scales, + int* zero_points, TfLiteAffineQuantization* affine_quant, + int quantized_dimension, bool is_variable = false); + +// Returns the number of tensors in the default subgraph for a tflite::Model. +size_t GetModelTensorCount(const Model* model); + +} // namespace testing +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_TEST_HELPERS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/testing/micro_test.h b/TensorflowLiteMicro/tensorflow/lite/micro/testing/micro_test.h new file mode 100644 index 0000000..d74d8f4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/testing/micro_test.h @@ -0,0 +1,238 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// An ultra-lightweight testing framework designed for use with microcontroller +// applications. Its only dependency is on TensorFlow Lite's ErrorReporter +// interface, where log messages are output. This is designed to be usable even +// when no standard C or C++ libraries are available, and without any dynamic +// memory allocation or reliance on global constructors. +// +// To build a test, you use syntax similar to gunit, but with some extra +// decoration to create a hidden 'main' function containing each of the tests to +// be run. Your code should look something like: +// ---------------------------------------------------------------------------- +// #include "path/to/this/header" +// +// TF_LITE_MICRO_TESTS_BEGIN +// +// TF_LITE_MICRO_TEST(SomeTest) { +// TF_LITE_LOG_EXPECT_EQ(true, true); +// } +// +// TF_LITE_MICRO_TESTS_END +// ---------------------------------------------------------------------------- +// If you compile this for your platform, you'll get a normal binary that you +// should be able to run. Executing it will output logging information like this +// to stderr (or whatever equivalent is available and written to by +// ErrorReporter): +// ---------------------------------------------------------------------------- +// Testing SomeTest +// 1/1 tests passed +// ~~~ALL TESTS PASSED~~~ +// ---------------------------------------------------------------------------- +// This is designed to be human-readable, so you can just run tests manually, +// but the string "~~~ALL TESTS PASSED~~~" should only appear if all of the +// tests do pass. This makes it possible to integrate with automated test +// systems by scanning the output logs and looking for that magic value. +// +// This framework is intended to be a rudimentary alternative to no testing at +// all on systems that struggle to run more conventional approaches, so use with +// caution! + +#ifndef TENSORFLOW_LITE_MICRO_TESTING_MICRO_TEST_H_ +#define TENSORFLOW_LITE_MICRO_TESTING_MICRO_TEST_H_ + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/micro/micro_error_reporter.h" + +namespace micro_test { +extern int tests_passed; +extern int tests_failed; +extern bool is_test_complete; +extern bool did_test_fail; +extern tflite::ErrorReporter* reporter; +} // namespace micro_test + +#define TF_LITE_MICRO_TESTS_BEGIN \ + namespace micro_test { \ + int tests_passed; \ + int tests_failed; \ + bool is_test_complete; \ + bool did_test_fail; \ + tflite::ErrorReporter* reporter; \ + } \ + \ + int main(int argc, char** argv) { \ + micro_test::tests_passed = 0; \ + micro_test::tests_failed = 0; \ + tflite::MicroErrorReporter error_reporter; \ + micro_test::reporter = &error_reporter; + +#define TF_LITE_MICRO_TESTS_END \ + micro_test::reporter->Report( \ + "%d/%d tests passed", micro_test::tests_passed, \ + (micro_test::tests_failed + micro_test::tests_passed)); \ + if (micro_test::tests_failed == 0) { \ + micro_test::reporter->Report("~~~ALL TESTS PASSED~~~\n"); \ + return kTfLiteOk; \ + } else { \ + micro_test::reporter->Report("~~~SOME TESTS FAILED~~~\n"); \ + return kTfLiteError; \ + } \ + } + +// TODO(petewarden): I'm going to hell for what I'm doing to this poor for loop. +#define TF_LITE_MICRO_TEST(name) \ + micro_test::reporter->Report("Testing " #name); \ + for (micro_test::is_test_complete = false, \ + micro_test::did_test_fail = false; \ + !micro_test::is_test_complete; micro_test::is_test_complete = true, \ + micro_test::tests_passed += (micro_test::did_test_fail) ? 0 : 1, \ + micro_test::tests_failed += (micro_test::did_test_fail) ? 1 : 0) + +#define TF_LITE_MICRO_EXPECT(x) \ + do { \ + if (!(x)) { \ + micro_test::reporter->Report(#x " failed at %s:%d", __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +// TODO(b/139142772): this macro is used with types other than ints even though +// the printf specifier is %d. +#define TF_LITE_MICRO_EXPECT_EQ(x, y) \ + do { \ + auto vx = x; \ + auto vy = y; \ + if ((vx) != (vy)) { \ + micro_test::reporter->Report(#x " == " #y " failed at %s:%d (%d vs %d)", \ + __FILE__, __LINE__, static_cast(vx), \ + static_cast(vy)); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_NE(x, y) \ + do { \ + if ((x) == (y)) { \ + micro_test::reporter->Report(#x " != " #y " failed at %s:%d", __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +// TODO(wangtz): Making it more generic once needed. +#define TF_LITE_MICRO_ARRAY_ELEMENT_EXPECT_NEAR(arr1, idx1, arr2, idx2, \ + epsilon) \ + do { \ + auto delta = ((arr1)[(idx1)] > (arr2)[(idx2)]) \ + ? ((arr1)[(idx1)] - (arr2)[(idx2)]) \ + : ((arr2)[(idx2)] - (arr1)[(idx1)]); \ + if (delta > epsilon) { \ + micro_test::reporter->Report( \ + #arr1 "[%d] (%f) near " #arr2 "[%d] (%f) failed at %s:%d", \ + static_cast(idx1), static_cast((arr1)[(idx1)]), \ + static_cast(idx2), static_cast((arr2)[(idx2)]), \ + __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_NEAR(x, y, epsilon) \ + do { \ + auto vx = (x); \ + auto vy = (y); \ + auto delta = ((vx) > (vy)) ? ((vx) - (vy)) : ((vy) - (vx)); \ + if (delta > epsilon) { \ + micro_test::reporter->Report( \ + #x " (%f) near " #y " (%f) failed at %s:%d", \ + static_cast(vx), static_cast(vy), __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_GT(x, y) \ + do { \ + if ((x) <= (y)) { \ + micro_test::reporter->Report(#x " > " #y " failed at %s:%d", __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_LT(x, y) \ + do { \ + if ((x) >= (y)) { \ + micro_test::reporter->Report(#x " < " #y " failed at %s:%d", __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_GE(x, y) \ + do { \ + if ((x) < (y)) { \ + micro_test::reporter->Report(#x " >= " #y " failed at %s:%d", __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_LE(x, y) \ + do { \ + if ((x) > (y)) { \ + micro_test::reporter->Report(#x " <= " #y " failed at %s:%d", __FILE__, \ + __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_TRUE(x) \ + do { \ + if (!(x)) { \ + micro_test::reporter->Report(#x " was not true failed at %s:%d", \ + __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_FALSE(x) \ + do { \ + if (x) { \ + micro_test::reporter->Report(#x " was not false failed at %s:%d", \ + __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } while (false) + +#define TF_LITE_MICRO_FAIL(msg) \ + do { \ + micro_test::reporter->Report("FAIL: %s", msg, __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } while (false) + +#define TF_LITE_MICRO_EXPECT_STRING_EQ(string1, string2) \ + do { \ + for (int i = 0; string1[i] != '\0' && string2[i] != '\0'; i++) { \ + if (string1[i] != string2[i]) { \ + micro_test::reporter->Report("FAIL: %s did not match %s", string1, \ + string2, __FILE__, __LINE__); \ + micro_test::did_test_fail = true; \ + } \ + } \ + } while (false) + +#endif // TENSORFLOW_LITE_MICRO_TESTING_MICRO_TEST_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.cc b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.cc new file mode 100644 index 0000000..358479c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.cc @@ -0,0 +1,1799 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/testing/test_conv_model.h" + +extern const unsigned char kTestConvModelData[] = { + 0x24, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x52, 0x00, 0x00, + 0x3c, 0x42, 0x00, 0x00, 0x24, 0x42, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xd4, 0x41, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0x64, 0x41, 0x00, 0x00, + 0xc0, 0x40, 0x00, 0x00, 0x7c, 0x40, 0x00, 0x00, 0x58, 0x40, 0x00, 0x00, + 0x44, 0x13, 0x00, 0x00, 0xa0, 0x12, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xd6, 0xbe, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x31, 0x2e, 0x35, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0xb2, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xb2, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb4, 0xb2, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xb2, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xb2, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x46, 0xbf, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x7d, 0x6a, 0x24, 0xa1, 0xf6, 0xca, 0x70, 0x2f, + 0x8e, 0xb1, 0xe8, 0x15, 0x42, 0x08, 0x32, 0xf6, 0xe9, 0xfb, 0xa0, 0xda, + 0xe4, 0xf1, 0x0a, 0x9d, 0x72, 0x66, 0x88, 0x37, 0xe9, 0x9e, 0x08, 0x54, + 0x61, 0x51, 0x40, 0x93, 0x4d, 0xcf, 0xe2, 0x08, 0x36, 0xad, 0xb1, 0x8e, + 0xfc, 0xe4, 0x02, 0xd1, 0x9a, 0x1e, 0x05, 0x67, 0xa3, 0x3b, 0xa6, 0xde, + 0x5d, 0x2a, 0xcc, 0x8c, 0x3c, 0x2e, 0xd2, 0x15, 0xc2, 0x60, 0xab, 0xea, + 0x73, 0xe4, 0x88, 0xc1, 0x66, 0x21, 0xb0, 0xe5, 0x5b, 0x55, 0xda, 0x69, + 0x2d, 0x0c, 0x66, 0x07, 0x74, 0x36, 0xcd, 0x79, 0x81, 0xf9, 0x5c, 0x2c, + 0xb5, 0x93, 0xab, 0x76, 0xa1, 0x1f, 0x20, 0x90, 0x89, 0xe1, 0x41, 0xc7, + 0x32, 0xc2, 0xa3, 0x03, 0x77, 0x86, 0x79, 0xf7, 0x89, 0xc1, 0xb1, 0x42, + 0x2a, 0x75, 0xc7, 0xc1, 0x2f, 0xbb, 0xf6, 0xe8, 0x23, 0x99, 0x9b, 0x74, + 0x9c, 0xe5, 0x91, 0x15, 0xc6, 0x08, 0x0e, 0xae, 0x7c, 0xd3, 0x27, 0x54, + 0xfb, 0xa7, 0x49, 0x65, 0x52, 0x2f, 0x63, 0x33, 0x8b, 0x5f, 0x67, 0x21, + 0x25, 0xe0, 0xcf, 0x95, 0x03, 0x05, 0x19, 0x0c, 0x3d, 0xfc, 0x95, 0x42, + 0xa9, 0x26, 0x27, 0x54, 0xa3, 0x71, 0xb4, 0x70, 0x7a, 0x40, 0x0d, 0xc1, + 0x72, 0x04, 0x81, 0x3b, 0xb9, 0xb7, 0xd2, 0xc1, 0x4e, 0xf8, 0xff, 0xca, + 0x66, 0xc1, 0xbe, 0xb9, 0x09, 0xbd, 0xb9, 0x2c, 0x5b, 0x97, 0xc3, 0xa8, + 0xf6, 0xc4, 0x23, 0x93, 0x2e, 0xf6, 0xce, 0x2e, 0xdb, 0xfb, 0x8f, 0xb0, + 0xc8, 0xba, 0xfa, 0x97, 0xfd, 0xc0, 0x0a, 0xc8, 0x2c, 0xf3, 0x4c, 0x4d, + 0x8b, 0x3b, 0x47, 0x11, 0xfb, 0xe8, 0x96, 0xe3, 0xcc, 0xef, 0xe4, 0xb5, + 0x07, 0xa1, 0xb7, 0xa9, 0xf7, 0x98, 0x71, 0x59, 0x9b, 0x5a, 0x7b, 0x88, + 0xe4, 0xcf, 0x9b, 0x55, 0x26, 0xce, 0x59, 0x73, 0x66, 0x17, 0x9c, 0x74, + 0x02, 0xfc, 0x24, 0x01, 0xde, 0x44, 0x98, 0xe3, 0x8b, 0x18, 0x02, 0x42, + 0xf5, 0x0f, 0xbc, 0xcb, 0xf7, 0x37, 0xb1, 0xd5, 0xb4, 0x7c, 0x0a, 0x6a, + 0x59, 0x59, 0xc9, 0x11, 0xd8, 0x0f, 0xf9, 0xab, 0x40, 0xdd, 0x14, 0xf9, + 0x30, 0xaa, 0xf1, 0x8c, 0x6d, 0xbc, 0x4c, 0x5b, 0x71, 0x95, 0xfd, 0x41, + 0x4c, 0xf3, 0xb4, 0x7f, 0x1c, 0xb6, 0x4b, 0x12, 0x3b, 0x6e, 0xc1, 0xce, + 0x6f, 0xf8, 0x57, 0xb7, 0x5e, 0x2a, 0x36, 0x32, 0x3d, 0x85, 0xc6, 0xbf, + 0xd7, 0xab, 0x95, 0x45, 0x62, 0xae, 0xb8, 0xa6, 0x03, 0xcc, 0x21, 0x25, + 0x18, 0x5a, 0xa8, 0x03, 0x27, 0x33, 0x47, 0xb1, 0x7e, 0x0e, 0xbd, 0xc3, + 0x24, 0x25, 0x78, 0x28, 0xa4, 0xe3, 0x5b, 0x08, 0xbf, 0x04, 0xa2, 0xae, + 0x90, 0x4c, 0x96, 0x78, 0xa8, 0xb1, 0xb8, 0x54, 0x89, 0x25, 0x2d, 0x35, + 0x93, 0x95, 0xa5, 0xd3, 0x1a, 0xe6, 0x00, 0x8b, 0xfe, 0x36, 0x0f, 0xd2, + 0x6e, 0xff, 0x86, 0x93, 0x48, 0xb8, 0x08, 0x39, 0x1f, 0x3a, 0x2d, 0xe7, + 0x47, 0x5e, 0x05, 0x66, 0x7a, 0xb8, 0xe4, 0xda, 0xbc, 0x5b, 0x57, 0xdf, + 0xd9, 0x0a, 0xb9, 0x48, 0x5d, 0x0c, 0x57, 0xed, 0x8d, 0xbb, 0x8d, 0x4b, + 0x0e, 0xb8, 0xea, 0x02, 0x06, 0x2f, 0xfd, 0x28, 0x0d, 0x0b, 0xf4, 0xf4, + 0x52, 0x81, 0x77, 0x15, 0x87, 0x53, 0x28, 0xef, 0xbe, 0xc6, 0x4c, 0x45, + 0x3e, 0x1a, 0x6e, 0xbd, 0x10, 0xd8, 0x9a, 0x72, 0x1f, 0x14, 0xe2, 0x37, + 0x08, 0xaf, 0xfa, 0xce, 0xd3, 0x84, 0x23, 0x43, 0x8c, 0x5c, 0xce, 0x1b, + 0xf7, 0xf3, 0xb0, 0x3b, 0xfd, 0x33, 0xf8, 0x09, 0xf1, 0x41, 0xa5, 0xa8, + 0x86, 0x8d, 0x56, 0xde, 0xf6, 0x68, 0xe3, 0x4c, 0x97, 0xa6, 0xc3, 0x66, + 0x9b, 0xa9, 0x8a, 0xbd, 0x59, 0x45, 0xfb, 0xdf, 0xa1, 0x42, 0x10, 0x1c, + 0x55, 0x22, 0x53, 0xe1, 0x32, 0x33, 0xf9, 0xfa, 0xc2, 0x70, 0x0f, 0x49, + 0x15, 0xa7, 0x21, 0xbc, 0x56, 0x35, 0x09, 0x06, 0xe6, 0x5e, 0xc4, 0xc1, + 0x64, 0x93, 0x59, 0x3b, 0x8e, 0xb7, 0x52, 0x6c, 0x4d, 0xa1, 0xb7, 0xee, + 0x14, 0xc2, 0x01, 0x25, 0xbb, 0x5e, 0xe0, 0xc6, 0xa4, 0x4f, 0xb5, 0x20, + 0x88, 0xe0, 0xd7, 0x5e, 0x26, 0x5b, 0x9f, 0xf7, 0xb5, 0x26, 0x5b, 0xfc, + 0xf3, 0x3e, 0xf3, 0x57, 0x6f, 0x9e, 0x9e, 0x51, 0x07, 0x6e, 0xc0, 0x53, + 0x17, 0x89, 0x79, 0xf0, 0x91, 0xb2, 0x54, 0x30, 0x1f, 0x97, 0x95, 0xfc, + 0x02, 0x2d, 0x0c, 0x06, 0xb0, 0x82, 0xad, 0x20, 0xc2, 0xdc, 0x78, 0xbc, + 0xbe, 0x5b, 0x88, 0xa0, 0xdd, 0x45, 0x49, 0x26, 0xec, 0xb4, 0xa5, 0x8b, + 0x7f, 0xdd, 0x40, 0xcf, 0x9e, 0xbe, 0x46, 0x4d, 0x36, 0xab, 0x0a, 0x34, + 0x1a, 0x2a, 0xd0, 0xd3, 0x83, 0x96, 0xff, 0x88, 0xa4, 0xd8, 0x48, 0x75, + 0x2f, 0xcb, 0x3c, 0xc3, 0xbb, 0xc7, 0x2f, 0xe9, 0xf9, 0xa3, 0xde, 0x9d, + 0xbb, 0x5e, 0x37, 0x29, 0xf6, 0x75, 0xcc, 0x85, 0xeb, 0xf9, 0x73, 0xf7, + 0xdc, 0x31, 0x8c, 0x56, 0x52, 0x4a, 0x44, 0xa4, 0x2a, 0x2a, 0x51, 0x49, + 0x77, 0x6d, 0x35, 0x0a, 0xf9, 0x44, 0xaa, 0x36, 0x05, 0xef, 0x1e, 0x6b, + 0xe5, 0x65, 0x6b, 0xaa, 0xc1, 0x41, 0x9c, 0x62, 0xd0, 0x70, 0x78, 0xff, + 0x88, 0xe8, 0x5f, 0x3c, 0x2e, 0x00, 0x6c, 0xe3, 0xdb, 0xc3, 0x54, 0x66, + 0xa9, 0xf4, 0xe2, 0x4c, 0x91, 0x11, 0xc8, 0x3c, 0x39, 0x9b, 0x31, 0x81, + 0xc7, 0x11, 0x22, 0x62, 0xb7, 0x26, 0xa0, 0x0c, 0x2e, 0x6c, 0xe7, 0x34, + 0x3b, 0x1f, 0x27, 0xb3, 0xe5, 0x4f, 0xc9, 0x71, 0xb2, 0x18, 0x99, 0x59, + 0x95, 0xc6, 0x35, 0x4c, 0x5d, 0xa3, 0x59, 0xd1, 0x8b, 0x71, 0xea, 0xe7, + 0x30, 0x3f, 0xe7, 0x8c, 0x1a, 0x59, 0xeb, 0xc5, 0x5d, 0xbd, 0xe6, 0x00, + 0x67, 0x02, 0xfb, 0xca, 0x8d, 0xdf, 0x71, 0xb6, 0xed, 0xc7, 0xd2, 0xf2, + 0x72, 0x1b, 0xd3, 0x63, 0x51, 0x1f, 0x04, 0xe9, 0xf9, 0xe2, 0x38, 0x13, + 0x48, 0x63, 0x19, 0x66, 0x2b, 0x48, 0xc8, 0x1b, 0x9d, 0x19, 0x5a, 0x57, + 0x44, 0x2d, 0x30, 0xb5, 0xce, 0x3b, 0xcc, 0xae, 0xc4, 0x5e, 0x4e, 0x96, + 0x62, 0x5c, 0x53, 0x1f, 0xbf, 0xbd, 0xc8, 0x9d, 0xcf, 0x81, 0xb3, 0x1e, + 0xb0, 0x22, 0xd5, 0xbe, 0x60, 0x65, 0xd9, 0xeb, 0x11, 0x74, 0x8c, 0x24, + 0x18, 0x67, 0x45, 0xd3, 0xf8, 0x3f, 0xc5, 0xdf, 0xac, 0x65, 0xd4, 0x0c, + 0x82, 0x63, 0xd6, 0x43, 0x94, 0xa0, 0x3b, 0xff, 0x03, 0x0f, 0xbb, 0xe4, + 0x4d, 0x3b, 0x41, 0x9f, 0xf4, 0x1a, 0xa9, 0xdb, 0x15, 0x5b, 0x9a, 0x92, + 0xcb, 0xd5, 0xb8, 0x33, 0x5e, 0xea, 0x28, 0x3d, 0x2d, 0x30, 0x20, 0xcd, + 0xb6, 0x23, 0x18, 0x0e, 0x10, 0x2a, 0xa9, 0xe1, 0xad, 0xbc, 0x96, 0xd1, + 0xf9, 0xf3, 0x95, 0x4f, 0x2a, 0x0b, 0x91, 0xff, 0xf0, 0x96, 0x14, 0x00, + 0xaa, 0xfb, 0x1a, 0x44, 0x21, 0x9b, 0xe8, 0x71, 0x31, 0x9e, 0xd6, 0x58, + 0x7f, 0x02, 0x36, 0x5e, 0x92, 0x8d, 0x93, 0x99, 0xac, 0xb6, 0x87, 0x39, + 0xda, 0x47, 0xef, 0x70, 0xd4, 0xf7, 0x8d, 0x2a, 0xbd, 0x08, 0x40, 0x4d, + 0xec, 0xeb, 0x4e, 0x1b, 0x85, 0x5d, 0x55, 0x64, 0x4c, 0xf3, 0x5e, 0x8f, + 0x68, 0x1e, 0x5e, 0x64, 0xc3, 0xb8, 0x92, 0x24, 0x41, 0x98, 0x78, 0x09, + 0x85, 0x87, 0x17, 0x2c, 0x88, 0x9e, 0x62, 0x86, 0x4f, 0x44, 0x71, 0x9c, + 0xa8, 0x73, 0xb3, 0x14, 0x1f, 0x3c, 0x96, 0x6b, 0xab, 0xad, 0x43, 0xdf, + 0x67, 0x34, 0x66, 0x30, 0x1d, 0x15, 0xd3, 0xe7, 0xd5, 0x8b, 0x00, 0xaa, + 0x11, 0x77, 0xea, 0x36, 0xc9, 0x49, 0x99, 0x93, 0x01, 0x6e, 0x00, 0x4a, + 0x93, 0x08, 0x2c, 0x44, 0x01, 0x91, 0xe0, 0x91, 0xdd, 0xab, 0x70, 0x4b, + 0xe7, 0xbf, 0x2d, 0x0f, 0xd4, 0x52, 0xa0, 0xf1, 0x5d, 0xa0, 0xcc, 0xb9, + 0x1b, 0xa2, 0x62, 0xeb, 0x23, 0x1e, 0x8e, 0xbb, 0x2b, 0xb6, 0xc5, 0x3a, + 0xdf, 0x32, 0x99, 0xde, 0x2e, 0x94, 0xcf, 0x98, 0x99, 0x34, 0x59, 0x60, + 0xcf, 0x57, 0xe0, 0xb0, 0xd9, 0x89, 0xaa, 0xc2, 0x4f, 0x1e, 0x38, 0x88, + 0xca, 0x32, 0x93, 0x9b, 0xa3, 0x2b, 0x17, 0x0b, 0x40, 0x5e, 0x69, 0xbd, + 0x14, 0x15, 0xca, 0x1a, 0x21, 0xdf, 0xa8, 0x4e, 0x14, 0x5e, 0x18, 0x40, + 0xe3, 0x4e, 0x04, 0x1f, 0xe5, 0x81, 0x53, 0x11, 0xae, 0x5e, 0x30, 0xe5, + 0xda, 0xd7, 0xf1, 0x3b, 0x72, 0x1b, 0xa5, 0xe3, 0x13, 0xad, 0x40, 0x54, + 0xae, 0xf0, 0xbc, 0x2b, 0xc1, 0x1a, 0x9c, 0xdd, 0xe1, 0xd0, 0x12, 0x10, + 0xfd, 0x59, 0xce, 0x36, 0x60, 0x86, 0xa0, 0xa7, 0xee, 0xe1, 0x02, 0xe6, + 0xf8, 0xf0, 0x5c, 0x4f, 0xa3, 0xa4, 0xe4, 0x09, 0xb9, 0xc3, 0x84, 0xe3, + 0x8d, 0x97, 0x21, 0x62, 0xf3, 0x11, 0x47, 0xb1, 0x4a, 0xce, 0x5b, 0x89, + 0xde, 0x86, 0xb5, 0x0e, 0xba, 0xbc, 0x8c, 0xcf, 0x54, 0x38, 0x3a, 0xc6, + 0xaf, 0x8c, 0x4d, 0x9d, 0xff, 0x58, 0x9b, 0xe8, 0x32, 0xb7, 0xa2, 0x29, + 0xad, 0x91, 0x3a, 0xa5, 0xc7, 0x54, 0xff, 0xd8, 0x47, 0x4f, 0x8f, 0x38, + 0x91, 0x12, 0x76, 0xa3, 0x2e, 0xf7, 0xdd, 0xba, 0xa7, 0xd4, 0x49, 0xe5, + 0xd1, 0x74, 0xe9, 0x2a, 0x29, 0xe4, 0x64, 0xb9, 0x58, 0x98, 0x0c, 0xe5, + 0x1f, 0xb2, 0x0e, 0x33, 0xea, 0xf8, 0x2e, 0xb1, 0x22, 0x46, 0xc2, 0x67, + 0x2d, 0xfe, 0x2e, 0xd3, 0xcf, 0xbc, 0x64, 0x7b, 0x75, 0x24, 0x53, 0x1c, + 0x42, 0x8c, 0x0b, 0x99, 0x9e, 0xa7, 0xa6, 0xb9, 0xfb, 0x5d, 0x86, 0x9f, + 0xe9, 0x04, 0x62, 0xb2, 0x42, 0x81, 0xa2, 0x0d, 0x60, 0x83, 0x40, 0xbb, + 0x21, 0x10, 0xdf, 0xaa, 0xe6, 0x6c, 0x72, 0xc5, 0xb1, 0xad, 0x9f, 0xd2, + 0x91, 0xf8, 0xb6, 0x56, 0xfb, 0x2e, 0xb3, 0xc4, 0x12, 0xd9, 0x86, 0x29, + 0x6c, 0x55, 0x88, 0x72, 0xba, 0xfb, 0x9b, 0xb9, 0x6f, 0x2d, 0x7d, 0x75, + 0xd0, 0x9d, 0xaf, 0x44, 0xb6, 0xbd, 0x7b, 0xec, 0x78, 0xf1, 0xbf, 0x66, + 0xe8, 0x79, 0x66, 0x16, 0x5e, 0xf9, 0x68, 0x89, 0x5b, 0xde, 0x8f, 0xf9, + 0xeb, 0x04, 0x0b, 0x6a, 0x71, 0xa1, 0x3b, 0x46, 0x03, 0xb4, 0x29, 0xa9, + 0x31, 0xf4, 0xc5, 0xd3, 0x43, 0x6d, 0x88, 0x43, 0xa8, 0xef, 0xb7, 0xd7, + 0x75, 0x6b, 0x83, 0x35, 0xb6, 0x2f, 0xe0, 0x5f, 0xf2, 0x14, 0xcd, 0xd0, + 0x06, 0xb3, 0x5e, 0x8b, 0xdb, 0x86, 0x11, 0x94, 0x2f, 0xfb, 0x92, 0x19, + 0x52, 0x7f, 0xcb, 0xe5, 0x22, 0x27, 0x5f, 0xe4, 0x68, 0xb2, 0xcb, 0xc7, + 0xb8, 0xec, 0xfd, 0x9e, 0x39, 0x9c, 0x5b, 0xe4, 0xae, 0xca, 0x83, 0x19, + 0xcf, 0xf0, 0x01, 0xe3, 0xfc, 0xb0, 0x28, 0xda, 0x79, 0x84, 0xfb, 0xfe, + 0xa5, 0xb6, 0xb3, 0xd2, 0x73, 0xd3, 0x11, 0xe5, 0xdf, 0x7a, 0xd7, 0x82, + 0x78, 0x25, 0x06, 0x5b, 0x0f, 0x89, 0x9d, 0x0b, 0x9b, 0xd1, 0x1b, 0xc5, + 0xb7, 0x67, 0xef, 0x7c, 0xa2, 0xa3, 0xca, 0x27, 0xd0, 0x59, 0xb9, 0x99, + 0x86, 0xa9, 0xf6, 0x9a, 0x28, 0xf0, 0xbb, 0x42, 0xd2, 0xa0, 0xa8, 0x01, + 0x29, 0xa1, 0x0c, 0x1b, 0x33, 0x1b, 0x9c, 0xcb, 0xe4, 0x6c, 0x61, 0x0a, + 0xc4, 0xd7, 0x6c, 0xec, 0x86, 0xb3, 0xd2, 0xaa, 0x8c, 0xab, 0x1a, 0xf4, + 0x03, 0x2e, 0x2b, 0x42, 0xbe, 0xc1, 0x31, 0x1d, 0x57, 0x47, 0xdc, 0x7b, + 0xb5, 0x8f, 0x8b, 0xdf, 0x06, 0xad, 0x3f, 0xf4, 0x4f, 0xb5, 0x52, 0x07, + 0x4e, 0x25, 0xb3, 0x73, 0x34, 0x92, 0x6a, 0x89, 0x93, 0x28, 0x8b, 0x96, + 0x9d, 0xdb, 0xb4, 0x77, 0x81, 0x76, 0x86, 0xd2, 0xa5, 0x94, 0x76, 0x35, + 0xc9, 0x66, 0x4e, 0xd8, 0xc5, 0xc3, 0xc9, 0x34, 0xaf, 0xad, 0x4a, 0x7c, + 0x92, 0x24, 0xb1, 0x7d, 0x7d, 0xac, 0xf6, 0xcb, 0x8f, 0x36, 0xc1, 0xb2, + 0x63, 0x78, 0x99, 0x33, 0x23, 0x68, 0x6e, 0x71, 0x6a, 0xcc, 0x05, 0xf9, + 0x41, 0x92, 0x30, 0xf0, 0xb1, 0xb4, 0xa6, 0x46, 0x86, 0x62, 0xd9, 0xd9, + 0x94, 0x8a, 0xb2, 0x9c, 0x68, 0xff, 0xf4, 0x3a, 0x2e, 0xaf, 0xee, 0xcf, + 0x04, 0x94, 0x53, 0x35, 0x25, 0xf9, 0xaa, 0x74, 0x93, 0xf3, 0x63, 0xc0, + 0xd2, 0x22, 0x30, 0x8c, 0xde, 0xa6, 0xb1, 0xb4, 0xa1, 0x56, 0x07, 0x06, + 0x71, 0xa2, 0x9e, 0x42, 0x31, 0xa3, 0x1e, 0xa6, 0x9a, 0xbc, 0x9f, 0x5b, + 0x12, 0x3c, 0xc2, 0x74, 0xf9, 0x61, 0x71, 0xef, 0x73, 0x86, 0xc2, 0x3b, + 0x25, 0x8a, 0x31, 0x72, 0x27, 0xac, 0xa4, 0x72, 0xf3, 0xbb, 0x78, 0x2c, + 0x94, 0xed, 0xa8, 0x3a, 0x42, 0x98, 0x34, 0xda, 0x3e, 0x60, 0x1c, 0x4a, + 0xec, 0x6b, 0x4e, 0x5f, 0x2a, 0x62, 0xb9, 0xad, 0xc9, 0xd9, 0x38, 0x90, + 0xa7, 0x3b, 0xd3, 0x1a, 0xbb, 0x81, 0x0d, 0x33, 0xd9, 0x16, 0x35, 0x8e, + 0xc3, 0x88, 0x36, 0xfa, 0x3e, 0xa8, 0x4f, 0x30, 0x9d, 0xf1, 0x08, 0xea, + 0x40, 0x1b, 0x87, 0x4d, 0x23, 0x8e, 0x8e, 0xb0, 0xe2, 0xf0, 0x27, 0xc1, + 0xdc, 0x0d, 0xe2, 0x8f, 0x93, 0xef, 0x8b, 0xd1, 0x19, 0xa5, 0xbe, 0xd7, + 0x5a, 0x8a, 0x38, 0x62, 0x43, 0xba, 0x74, 0xf8, 0xae, 0x11, 0x1f, 0x1d, + 0xa4, 0x6e, 0x70, 0x94, 0x91, 0x14, 0xf4, 0xff, 0xbe, 0x39, 0xb4, 0x33, + 0xc2, 0x87, 0x74, 0x1b, 0xfd, 0x9a, 0xa8, 0x64, 0x09, 0x4b, 0x7f, 0x95, + 0x0a, 0xcb, 0x6b, 0x15, 0x54, 0x1d, 0xc6, 0x03, 0x1d, 0x1b, 0x25, 0x56, + 0x15, 0xb5, 0xd7, 0xe5, 0xd6, 0xf3, 0x28, 0xa4, 0xde, 0x1b, 0x39, 0x0d, + 0x59, 0x26, 0x12, 0xe4, 0x32, 0xf2, 0x25, 0xeb, 0xc0, 0xdb, 0x58, 0xe5, + 0xce, 0x64, 0x6f, 0x70, 0x74, 0xc1, 0xc9, 0xbd, 0x75, 0xef, 0x16, 0x02, + 0xdf, 0x27, 0x09, 0xc8, 0xb8, 0x37, 0x8f, 0x44, 0x0d, 0x58, 0x48, 0xf5, + 0xc2, 0x53, 0x21, 0x28, 0x16, 0xa4, 0x56, 0x02, 0xdf, 0xa7, 0x97, 0xa4, + 0x5c, 0x48, 0x75, 0x51, 0x89, 0x0b, 0xa7, 0x4d, 0xd9, 0x9e, 0x04, 0x4e, + 0x5d, 0x6c, 0xe5, 0x1f, 0x68, 0x88, 0xcc, 0xb7, 0x9a, 0x20, 0x05, 0x83, + 0x82, 0x6c, 0xfd, 0xdb, 0x07, 0x6c, 0xec, 0x61, 0xaa, 0x36, 0x57, 0x68, + 0x01, 0xf2, 0x70, 0xfe, 0xe6, 0x4d, 0xe1, 0xa9, 0xb6, 0xb6, 0x52, 0xe6, + 0x20, 0x52, 0x0f, 0x27, 0x9a, 0x1c, 0x2d, 0x20, 0x9b, 0xd4, 0x07, 0xd3, + 0xf6, 0x85, 0x4b, 0xf2, 0x52, 0x4d, 0x4c, 0xd7, 0xf0, 0x32, 0x5d, 0x2e, + 0xef, 0xa2, 0xd0, 0xcd, 0x48, 0x89, 0xbc, 0x9f, 0xcb, 0x37, 0x02, 0x29, + 0xa5, 0xdb, 0xab, 0xfa, 0x1d, 0xf4, 0x53, 0x78, 0x30, 0xde, 0x2c, 0x5c, + 0x35, 0x7f, 0x3d, 0xe1, 0xe0, 0xce, 0xdb, 0x13, 0xca, 0x2a, 0xae, 0xdf, + 0x1c, 0xb1, 0xb6, 0xb9, 0x6a, 0x9f, 0x28, 0xb0, 0x54, 0x5a, 0x00, 0xdd, + 0x76, 0x14, 0xfb, 0x17, 0xc2, 0x2a, 0x45, 0xa2, 0x18, 0xbb, 0x8a, 0x3e, + 0xbe, 0x0e, 0xa5, 0x1b, 0x3c, 0x70, 0x56, 0x10, 0x98, 0xec, 0xc6, 0x3a, + 0x95, 0x2a, 0x96, 0x6a, 0x44, 0xef, 0xd9, 0x9c, 0x2a, 0x45, 0xb4, 0x15, + 0xf8, 0x2e, 0x03, 0x5d, 0x8c, 0x79, 0xfb, 0xb0, 0x53, 0x71, 0xcd, 0x0d, + 0xf4, 0xe2, 0xfc, 0x3b, 0x71, 0xee, 0x30, 0xf2, 0x29, 0xd3, 0xaa, 0x18, + 0x7a, 0x45, 0x1d, 0x99, 0x6d, 0x2f, 0x1f, 0x2d, 0x32, 0x23, 0x48, 0xc2, + 0x69, 0x33, 0x3d, 0x04, 0xa7, 0xa3, 0x96, 0xb5, 0x76, 0x5b, 0x4e, 0xb7, + 0x3c, 0x10, 0x58, 0x17, 0xf4, 0x5f, 0xec, 0x51, 0x6d, 0x5a, 0x3b, 0x7f, + 0x1e, 0x0e, 0xbb, 0xbf, 0x77, 0x43, 0xf7, 0xa4, 0x57, 0xc0, 0x33, 0xac, + 0xc1, 0xe3, 0x3e, 0x1f, 0x65, 0x3c, 0x62, 0x19, 0x46, 0x2d, 0x7b, 0x2d, + 0x07, 0x44, 0x48, 0xf4, 0x91, 0xdf, 0x59, 0x32, 0x10, 0xf7, 0x12, 0xe2, + 0xe5, 0x39, 0x70, 0x37, 0xa4, 0x79, 0x9a, 0x17, 0x19, 0xe8, 0x90, 0xe7, + 0x37, 0x0d, 0xb6, 0x6d, 0x58, 0xe6, 0x7e, 0x57, 0x76, 0x8a, 0xe8, 0xd0, + 0x76, 0x30, 0x25, 0xda, 0xb6, 0xdf, 0x59, 0x3c, 0x6c, 0x20, 0x65, 0x88, + 0xd2, 0x60, 0x5e, 0x39, 0xb6, 0x6b, 0xac, 0xa2, 0x25, 0xc6, 0xa7, 0xb1, + 0x2f, 0xbb, 0x1d, 0x23, 0xee, 0x02, 0x08, 0x1d, 0xd6, 0x6c, 0x0e, 0xbc, + 0xea, 0xd2, 0xc2, 0x70, 0x34, 0xe9, 0x96, 0xd3, 0xf3, 0xf4, 0x8e, 0x94, + 0x6f, 0x86, 0x76, 0xe7, 0x38, 0x08, 0x6f, 0x47, 0xf5, 0xcd, 0xab, 0xad, + 0x7a, 0x39, 0x10, 0x9a, 0xa8, 0x44, 0xba, 0x2d, 0x7f, 0x05, 0x1e, 0xb7, + 0x44, 0xd8, 0x10, 0x05, 0xd1, 0x8d, 0x98, 0x09, 0x14, 0xbb, 0x6b, 0x2b, + 0xf7, 0xeb, 0x9f, 0xa5, 0x65, 0x4b, 0x21, 0xff, 0xaf, 0xe8, 0x2e, 0x34, + 0x52, 0x38, 0xcf, 0xd5, 0x51, 0x29, 0x2c, 0x91, 0x43, 0x3a, 0x49, 0x42, + 0xdd, 0xfb, 0x0e, 0xd2, 0x77, 0x8f, 0x65, 0x93, 0x3e, 0x52, 0x22, 0x58, + 0xd6, 0xf9, 0xd9, 0x58, 0xd4, 0x06, 0xa9, 0x0c, 0x79, 0x9f, 0x1b, 0xa5, + 0x45, 0x61, 0xd8, 0x4e, 0xbf, 0x4b, 0x51, 0xe2, 0xfb, 0x6f, 0x58, 0xee, + 0xc5, 0xa5, 0x11, 0xbd, 0x99, 0x25, 0x14, 0xac, 0x94, 0x0e, 0xd1, 0xf7, + 0x54, 0xb6, 0x05, 0x8c, 0xc3, 0x57, 0xa5, 0x3c, 0x3c, 0xa6, 0x83, 0x47, + 0x38, 0xd1, 0x6a, 0xab, 0x12, 0xc0, 0xd3, 0x7f, 0x96, 0x55, 0xd7, 0xf4, + 0x3a, 0xd0, 0x08, 0x85, 0x5f, 0x3d, 0x65, 0x8e, 0xbb, 0xea, 0x34, 0xf3, + 0x53, 0x96, 0x71, 0x08, 0x9b, 0x50, 0xe9, 0x4b, 0xce, 0x8a, 0x2f, 0xef, + 0xe4, 0xb2, 0x72, 0x68, 0xcb, 0x88, 0xa8, 0xd9, 0xd9, 0xa2, 0xfc, 0x62, + 0xe8, 0x8b, 0x23, 0x2b, 0xbc, 0xf0, 0x9e, 0xb4, 0xd0, 0x40, 0x8b, 0x45, + 0xff, 0x6d, 0x37, 0x01, 0xa6, 0x4b, 0x62, 0xe0, 0x3b, 0x4e, 0x18, 0x67, + 0xb3, 0x97, 0x04, 0xa0, 0x2a, 0xf2, 0x11, 0x79, 0x38, 0xb4, 0xb2, 0xed, + 0x64, 0xc1, 0x1e, 0xfe, 0xc4, 0xf4, 0xe2, 0x4d, 0x94, 0xb4, 0x17, 0x52, + 0x1a, 0x63, 0xe6, 0x56, 0x8a, 0x41, 0x0a, 0x5b, 0xa2, 0x1c, 0x59, 0xef, + 0x17, 0x64, 0xf9, 0xf7, 0x2c, 0xa4, 0xfd, 0x66, 0xf7, 0xe3, 0xae, 0xa0, + 0x54, 0x36, 0x64, 0x26, 0x84, 0x51, 0x49, 0xd5, 0x3a, 0x5e, 0x2c, 0xc5, + 0xca, 0xde, 0x8e, 0xe7, 0x25, 0x59, 0xb3, 0x9a, 0xb2, 0xf0, 0xff, 0xf1, + 0x83, 0xe5, 0x70, 0xc3, 0xef, 0x63, 0x66, 0x31, 0x04, 0x4d, 0x42, 0xf1, + 0xd9, 0x4c, 0x5e, 0x29, 0x92, 0x37, 0x8d, 0xd1, 0x18, 0x2a, 0x9e, 0x3c, + 0xcc, 0x05, 0xb9, 0xc4, 0xb6, 0xe7, 0x2a, 0x09, 0x3a, 0x68, 0xb5, 0x61, + 0x60, 0x36, 0x11, 0x02, 0x92, 0xf8, 0xa0, 0x56, 0x9b, 0xe8, 0xfe, 0xac, + 0x87, 0xcc, 0xaf, 0xb9, 0x62, 0xa7, 0x1e, 0x99, 0xb8, 0x9f, 0x47, 0xf7, + 0xa5, 0x12, 0x47, 0x66, 0xeb, 0xd6, 0x3a, 0x6f, 0xb3, 0x26, 0x63, 0xe2, + 0xec, 0x0c, 0xba, 0x7d, 0xc2, 0x9b, 0xb2, 0x10, 0x62, 0x03, 0x3f, 0x20, + 0xed, 0x7a, 0xce, 0x47, 0xd0, 0x50, 0x5b, 0x5c, 0x66, 0xbf, 0x01, 0x09, + 0x84, 0x0b, 0x71, 0xa8, 0x1f, 0x8d, 0xe1, 0x05, 0x09, 0xb4, 0xd5, 0x34, + 0xf1, 0xba, 0x31, 0xc6, 0x76, 0x8e, 0x00, 0x96, 0x3d, 0x6b, 0xe4, 0x66, + 0x3a, 0x22, 0xcd, 0x7f, 0x9d, 0xf8, 0x64, 0xfc, 0x76, 0x42, 0x88, 0x0e, + 0x32, 0xa5, 0xd0, 0x69, 0x56, 0xe2, 0xa5, 0x6f, 0xbb, 0xfa, 0xd8, 0xde, + 0xb4, 0x23, 0xa9, 0xc7, 0x9a, 0xc1, 0x99, 0xa7, 0x7f, 0x79, 0x58, 0xe1, + 0xe7, 0xc5, 0x56, 0x36, 0xc0, 0xfb, 0x8d, 0x8f, 0xe4, 0x6c, 0x96, 0x89, + 0xcb, 0xb0, 0xb0, 0x6e, 0xee, 0x20, 0x46, 0xd3, 0x43, 0x83, 0xac, 0x39, + 0x7c, 0x25, 0xba, 0x69, 0x3a, 0x58, 0x8a, 0x48, 0x0a, 0xf7, 0xb7, 0xfc, + 0x58, 0x7b, 0x93, 0x8b, 0xcd, 0x81, 0x7e, 0x94, 0xe0, 0xdf, 0xb1, 0xca, + 0xf6, 0x60, 0x54, 0xa9, 0x6e, 0xc6, 0x7f, 0xac, 0xfb, 0x62, 0xfe, 0xd9, + 0xd5, 0xf4, 0x6c, 0x62, 0x65, 0xf6, 0x0b, 0x24, 0x49, 0x1d, 0x55, 0xd6, + 0x4c, 0x0b, 0x5a, 0xf1, 0x2e, 0x78, 0x7a, 0x4e, 0xc1, 0xd0, 0xdb, 0xfe, + 0xd2, 0x84, 0x60, 0x68, 0x51, 0x8e, 0x3f, 0xf1, 0xa8, 0x90, 0xbf, 0xda, + 0x86, 0xda, 0x41, 0xd8, 0x90, 0x7b, 0xc3, 0xc8, 0x9e, 0xa5, 0x77, 0x06, + 0x56, 0x02, 0x13, 0x59, 0xaa, 0x89, 0xf9, 0xd5, 0x3c, 0x1d, 0xe2, 0xa9, + 0xb1, 0xc8, 0x02, 0x5a, 0x1c, 0xae, 0x72, 0x66, 0xdf, 0xb4, 0x1a, 0xb7, + 0xd2, 0x4d, 0xda, 0x4f, 0xc9, 0xed, 0x88, 0x7d, 0x9b, 0xc4, 0x4a, 0x8c, + 0x5e, 0x77, 0xaf, 0xd6, 0xd3, 0xbb, 0x38, 0xd2, 0xfa, 0x85, 0xe4, 0xdd, + 0xe7, 0x6e, 0xcb, 0x0b, 0x34, 0x1e, 0xa8, 0xfd, 0xf4, 0xd2, 0xc3, 0xdd, + 0xe0, 0xa6, 0xb1, 0x78, 0x16, 0x85, 0x2b, 0x1b, 0x22, 0xa6, 0xd5, 0x93, + 0x4f, 0xa1, 0xd5, 0x10, 0x96, 0xab, 0x38, 0xa7, 0x3c, 0xf2, 0xbd, 0xd9, + 0x7c, 0x59, 0x71, 0x25, 0x6f, 0x7c, 0xce, 0x73, 0x8e, 0x4e, 0xfb, 0x5a, + 0x30, 0x24, 0x53, 0xc5, 0xa3, 0x20, 0x13, 0x03, 0xfc, 0x7a, 0xaf, 0x1f, + 0x71, 0x5d, 0x6b, 0xce, 0x2e, 0x92, 0x16, 0x4d, 0xab, 0x96, 0x10, 0xc0, + 0xf6, 0x3c, 0xfe, 0x51, 0x89, 0x4d, 0x39, 0x45, 0x2c, 0x92, 0x5a, 0x86, + 0x24, 0xce, 0xbc, 0x75, 0xc6, 0x7f, 0x0e, 0xc2, 0xd1, 0xe7, 0x6a, 0x75, + 0x30, 0x59, 0xfb, 0xbf, 0x6b, 0xcf, 0x60, 0x90, 0x07, 0x73, 0xb1, 0x47, + 0x6e, 0x5d, 0xcd, 0x44, 0xac, 0xee, 0x2a, 0xdb, 0x16, 0x5a, 0x1a, 0xaf, + 0xba, 0xf8, 0x64, 0xdd, 0xdd, 0xed, 0x46, 0x4b, 0x67, 0xf3, 0xf8, 0x2d, + 0x22, 0xe9, 0x25, 0x74, 0x4c, 0x70, 0xe0, 0x3d, 0xbc, 0x11, 0xd3, 0x56, + 0xec, 0x86, 0x39, 0x89, 0x4c, 0xf2, 0xbc, 0x39, 0xdc, 0xde, 0x5f, 0x3b, + 0x42, 0xcb, 0xf6, 0x0c, 0x49, 0x8c, 0x66, 0x76, 0x58, 0x28, 0xe8, 0x47, + 0x59, 0x40, 0x11, 0xef, 0xb5, 0x9d, 0x93, 0xe5, 0x39, 0x56, 0x62, 0x0d, + 0xd0, 0xdd, 0xbb, 0x51, 0xff, 0x87, 0xa3, 0xd1, 0x9e, 0x0e, 0x0c, 0xbd, + 0x8e, 0xfc, 0xa5, 0x44, 0xc7, 0x6d, 0x35, 0x1d, 0x69, 0x14, 0x5b, 0x0d, + 0x45, 0xff, 0x85, 0x2d, 0xd1, 0x14, 0xf4, 0x5e, 0x5b, 0x49, 0x85, 0xad, + 0x69, 0xf1, 0x34, 0x9e, 0x7a, 0xf3, 0xed, 0x2d, 0xf2, 0x5f, 0x70, 0x5a, + 0xc1, 0xca, 0x63, 0xb5, 0xec, 0x49, 0xfc, 0x88, 0xcb, 0x0f, 0x81, 0x1d, + 0xd4, 0x2f, 0x18, 0xf6, 0xfe, 0x71, 0x51, 0xe2, 0x25, 0x71, 0x48, 0xa4, + 0xb2, 0x9f, 0x4f, 0xc0, 0xa5, 0x24, 0x12, 0x5b, 0xf8, 0xf2, 0xcf, 0x6e, + 0x52, 0x52, 0x6a, 0xee, 0x7d, 0xa5, 0x9b, 0xdb, 0x9c, 0xc9, 0x35, 0x30, + 0x1a, 0xf0, 0x7d, 0xcc, 0x98, 0x73, 0x09, 0x16, 0x8c, 0x05, 0x8d, 0x70, + 0xa3, 0x15, 0xd6, 0x7a, 0xa0, 0x7c, 0xd5, 0xcc, 0xd3, 0x29, 0x32, 0x2e, + 0xa5, 0xde, 0xf6, 0xd3, 0xa4, 0x03, 0x59, 0x6c, 0x05, 0x2d, 0x0e, 0x8b, + 0xb7, 0x1f, 0xa0, 0x57, 0x5c, 0x76, 0xde, 0x81, 0xcb, 0x64, 0xb9, 0x73, + 0xc1, 0x3b, 0x26, 0xba, 0x16, 0xdb, 0xe6, 0x40, 0x23, 0xa4, 0xe9, 0x24, + 0x48, 0xb8, 0x73, 0x23, 0x67, 0xbf, 0x26, 0xca, 0x95, 0x4f, 0xa0, 0x60, + 0x95, 0xa2, 0x0f, 0x29, 0xed, 0x5d, 0x71, 0x66, 0x94, 0xa3, 0xd0, 0x2a, + 0x4e, 0x17, 0x32, 0x18, 0xe6, 0xd6, 0x75, 0x84, 0xa5, 0x2a, 0x72, 0x18, + 0x60, 0x85, 0xde, 0x66, 0x22, 0x52, 0xf6, 0x45, 0xd6, 0xf0, 0xed, 0x93, + 0x0f, 0x5a, 0xa9, 0x12, 0x2a, 0xc4, 0xa8, 0x3d, 0x97, 0xc9, 0xc7, 0x84, + 0x71, 0x14, 0xb3, 0x54, 0xb6, 0xf7, 0x92, 0x7a, 0xc0, 0x6e, 0x02, 0xf7, + 0x48, 0xdb, 0x7c, 0xc1, 0x45, 0x21, 0xdb, 0x1b, 0x51, 0xc3, 0xea, 0xc0, + 0x19, 0x31, 0xe4, 0x6c, 0x20, 0x5f, 0x08, 0xe7, 0x88, 0xf7, 0xc0, 0x6e, + 0xee, 0x5f, 0x20, 0x33, 0x68, 0xef, 0xc5, 0x33, 0x1b, 0x40, 0x66, 0xc5, + 0xa3, 0x68, 0xdb, 0xbc, 0x8a, 0xb7, 0x54, 0xdb, 0xc7, 0xc5, 0x2c, 0x42, + 0x65, 0x51, 0xab, 0x56, 0x94, 0x73, 0xec, 0xd9, 0x95, 0xfa, 0x6a, 0x56, + 0xef, 0x22, 0x95, 0xa4, 0x75, 0x46, 0xee, 0x60, 0x8b, 0x25, 0xa6, 0x92, + 0x0a, 0x8e, 0xc1, 0x39, 0x97, 0x69, 0xa9, 0x19, 0x97, 0xf1, 0x0f, 0x61, + 0xc2, 0x40, 0x7d, 0x62, 0xe9, 0x5e, 0x22, 0x1f, 0x27, 0xe5, 0xc7, 0xe7, + 0xa4, 0x35, 0x5d, 0x90, 0xc7, 0x38, 0x38, 0x2d, 0xb0, 0x1e, 0x29, 0x0f, + 0x4f, 0x08, 0x8b, 0xdd, 0x69, 0x3c, 0x5c, 0x03, 0xbe, 0x9a, 0x76, 0xba, + 0x91, 0xf5, 0x57, 0x07, 0x39, 0xfe, 0x09, 0xfc, 0x01, 0x7b, 0x37, 0xc4, + 0x73, 0x7f, 0x76, 0x50, 0x76, 0xae, 0x6e, 0x4b, 0x22, 0x2c, 0x3b, 0xe7, + 0x77, 0x19, 0x9a, 0x92, 0x26, 0xdf, 0xc4, 0xe6, 0xd8, 0x57, 0xc1, 0x7f, + 0x65, 0x0b, 0xfb, 0xfa, 0xdd, 0xd2, 0x8c, 0xc7, 0xb1, 0x72, 0x2a, 0xb2, + 0x5a, 0xfa, 0xb2, 0x84, 0xb1, 0xec, 0x79, 0x9e, 0xde, 0xd8, 0x2f, 0xdf, + 0x3b, 0x39, 0x0b, 0xac, 0xfa, 0xb8, 0x07, 0x38, 0xff, 0x2e, 0x22, 0x2b, + 0xc9, 0x31, 0x3b, 0x09, 0x05, 0xd2, 0x06, 0xc4, 0x2d, 0x22, 0x1c, 0x21, + 0x70, 0x03, 0x93, 0xd1, 0x3a, 0x8d, 0x94, 0x60, 0xfe, 0x99, 0x13, 0xc3, + 0x00, 0x03, 0x41, 0xfa, 0x50, 0x79, 0x31, 0xeb, 0xf0, 0xf4, 0x06, 0x7a, + 0x19, 0xe8, 0x90, 0xdf, 0x61, 0x4d, 0x5f, 0xe3, 0x99, 0x1b, 0xca, 0xbf, + 0xcf, 0xae, 0xca, 0xfa, 0x84, 0x63, 0x88, 0x56, 0x1d, 0x52, 0x5a, 0x21, + 0xf9, 0xcd, 0xa3, 0x30, 0x16, 0xb9, 0x0d, 0xe1, 0x87, 0x08, 0x78, 0xa2, + 0xdb, 0x7e, 0x16, 0x82, 0x48, 0x48, 0x17, 0x1a, 0xa8, 0x3f, 0xc7, 0x4d, + 0xfd, 0x99, 0x2b, 0x36, 0xbf, 0x08, 0xb9, 0xeb, 0xa6, 0xbf, 0xb6, 0xa0, + 0x9e, 0x26, 0x15, 0xac, 0xd2, 0x65, 0xc9, 0x36, 0x41, 0xe3, 0x59, 0x4e, + 0xdc, 0x7b, 0x58, 0x3b, 0x47, 0x0b, 0xc9, 0xf3, 0xb3, 0xf9, 0x81, 0x33, + 0x39, 0xca, 0xf8, 0x97, 0x2d, 0x9b, 0x24, 0x33, 0x69, 0xbe, 0x1b, 0x81, + 0x59, 0x59, 0x17, 0xed, 0x7d, 0x5b, 0xbe, 0xda, 0xeb, 0x4e, 0x5d, 0x5d, + 0x70, 0x13, 0x3c, 0x4b, 0x4a, 0xfc, 0xa4, 0xbe, 0xa0, 0x5d, 0xa2, 0xed, + 0xe8, 0x8d, 0xf8, 0xf2, 0xa5, 0xdd, 0xd4, 0x49, 0x45, 0x04, 0xef, 0x18, + 0x9f, 0xa1, 0xf7, 0xc4, 0x3b, 0xc2, 0x6b, 0xe0, 0x45, 0xa8, 0x76, 0x39, + 0x49, 0x32, 0xec, 0xc3, 0xcb, 0x45, 0x46, 0xd2, 0x4b, 0x3a, 0x55, 0xe5, + 0xce, 0x08, 0xc4, 0x84, 0xe5, 0xd9, 0xb3, 0xf3, 0xc4, 0xa8, 0xe9, 0x88, + 0x83, 0xd5, 0x56, 0xe1, 0xa6, 0xef, 0x41, 0x55, 0xb0, 0x3f, 0xa3, 0xc1, + 0xbe, 0x3b, 0x83, 0xd6, 0x92, 0x90, 0x38, 0xd3, 0xf3, 0x75, 0xf6, 0x49, + 0x95, 0xee, 0xa9, 0xed, 0xaa, 0xf8, 0xb9, 0x14, 0x0e, 0x6a, 0x48, 0x9d, + 0xc5, 0x48, 0x3b, 0x5e, 0x61, 0xd3, 0x8c, 0x4a, 0x10, 0x12, 0x7c, 0x0a, + 0xf7, 0xaf, 0x62, 0x2d, 0xd3, 0x89, 0x8d, 0x75, 0x19, 0x6b, 0x62, 0x4b, + 0x1a, 0x04, 0xc7, 0xd3, 0x32, 0x17, 0x2f, 0x5f, 0x29, 0xfa, 0xb1, 0x8d, + 0x78, 0xe7, 0x27, 0xf6, 0x67, 0x7e, 0x17, 0xa3, 0x18, 0xdc, 0x13, 0x08, + 0x1e, 0x4b, 0xc7, 0x8e, 0xf6, 0xba, 0x90, 0xb3, 0x32, 0x42, 0x37, 0x6b, + 0x60, 0xa9, 0x23, 0xb5, 0x89, 0x57, 0x7b, 0xdb, 0x98, 0x35, 0x1f, 0x95, + 0x86, 0xa5, 0x83, 0x36, 0xd1, 0x8c, 0x8e, 0xc0, 0x77, 0x5c, 0x40, 0x8e, + 0xec, 0xdf, 0x25, 0x69, 0x0a, 0x83, 0x8f, 0xdf, 0x91, 0x52, 0x31, 0xab, + 0xd5, 0x61, 0x37, 0xbd, 0x83, 0x1d, 0x4c, 0x8b, 0xa1, 0x4a, 0x81, 0x8b, + 0xa0, 0xf4, 0x41, 0xbd, 0x54, 0x36, 0x36, 0x56, 0x6d, 0x4c, 0xe7, 0xd9, + 0xc7, 0x09, 0xd9, 0x4b, 0xf0, 0x54, 0x45, 0x3c, 0x62, 0x47, 0x17, 0x54, + 0x1f, 0x55, 0x2f, 0x74, 0xdc, 0x11, 0xe9, 0xa3, 0xb5, 0x75, 0xe9, 0x10, + 0xde, 0x62, 0xa9, 0x24, 0x39, 0xd4, 0x17, 0xbb, 0x15, 0xe4, 0x48, 0x09, + 0x26, 0x6a, 0xbd, 0x3b, 0x10, 0xa1, 0x55, 0xe5, 0x99, 0x53, 0x1e, 0xd2, + 0xee, 0x7c, 0x54, 0xd8, 0x06, 0x8b, 0x1e, 0xe7, 0x3f, 0x08, 0x38, 0x9b, + 0x2e, 0x41, 0xdf, 0x0b, 0x7e, 0x83, 0x7f, 0x04, 0x38, 0xa5, 0x1f, 0x46, + 0x8b, 0x94, 0x28, 0x9f, 0xb8, 0x8c, 0x41, 0xfe, 0x96, 0xe2, 0x24, 0xd1, + 0x97, 0xa4, 0xcb, 0xba, 0xfa, 0x19, 0xc9, 0x57, 0x30, 0x0f, 0x88, 0x58, + 0xa9, 0x67, 0x31, 0x74, 0x51, 0x34, 0x03, 0xbc, 0xff, 0x3b, 0x12, 0x61, + 0x84, 0x63, 0x74, 0xec, 0x4d, 0xda, 0xa3, 0x56, 0xc3, 0xe5, 0x5e, 0x4a, + 0x03, 0x26, 0x88, 0x1a, 0x1d, 0x7f, 0xe8, 0x3f, 0x61, 0x78, 0xb6, 0xc5, + 0x66, 0xb7, 0xb4, 0xc1, 0xe7, 0x82, 0xc1, 0x44, 0xdf, 0xf9, 0x30, 0x30, + 0xe1, 0xd0, 0xf8, 0xf5, 0x40, 0x5a, 0x72, 0x29, 0xef, 0x30, 0xe1, 0x01, + 0xca, 0x1b, 0xb0, 0xa6, 0xa3, 0x17, 0x2b, 0x58, 0x03, 0xda, 0x25, 0x0f, + 0xdc, 0x49, 0x7c, 0xc5, 0x8f, 0x2d, 0x83, 0xca, 0x43, 0x08, 0xc0, 0x36, + 0x70, 0x1e, 0x42, 0xfd, 0xac, 0x4d, 0x31, 0xcf, 0x68, 0x4a, 0xda, 0xd8, + 0xcb, 0xee, 0xaa, 0xfc, 0xcf, 0xcc, 0xe6, 0xb2, 0x77, 0x8b, 0x83, 0x5b, + 0xd5, 0x3d, 0x55, 0xba, 0x03, 0x45, 0xce, 0x51, 0x78, 0x36, 0xcb, 0xcd, + 0x9a, 0x0f, 0x58, 0xbe, 0x15, 0x10, 0xdb, 0x3f, 0x1d, 0x28, 0x27, 0x11, + 0x69, 0xca, 0x95, 0x68, 0xa8, 0xc8, 0xff, 0x0c, 0x3f, 0xd5, 0x11, 0x91, + 0x35, 0x45, 0x35, 0x9d, 0x1c, 0x58, 0xa2, 0xe5, 0xab, 0x83, 0x95, 0x10, + 0x44, 0xd4, 0xc0, 0x27, 0xf4, 0xc2, 0x72, 0x0f, 0x1a, 0x3d, 0x1c, 0xf2, + 0x7f, 0xb9, 0x54, 0xf2, 0x41, 0x24, 0xa8, 0x67, 0x30, 0xa0, 0x57, 0x67, + 0x00, 0xa8, 0x06, 0x60, 0xc3, 0x74, 0x6d, 0x54, 0x90, 0x5e, 0xad, 0x71, + 0x41, 0x50, 0xab, 0x9d, 0xba, 0x34, 0x1a, 0xfd, 0x19, 0x21, 0x0e, 0x87, + 0xb7, 0x22, 0xe6, 0xca, 0xb9, 0x0d, 0x3c, 0x4f, 0xad, 0x16, 0xf1, 0xa5, + 0x6d, 0xba, 0x6d, 0x7b, 0xbe, 0x7b, 0xe3, 0x95, 0xec, 0x1b, 0x8b, 0x6e, + 0xb0, 0xdc, 0x5c, 0xfd, 0x31, 0x73, 0x85, 0x02, 0x63, 0xc6, 0xcc, 0x04, + 0x29, 0xa5, 0xf4, 0x1f, 0xcb, 0x90, 0xf7, 0x83, 0x0d, 0x36, 0xbf, 0x31, + 0xc0, 0xfc, 0x26, 0x15, 0x87, 0xc8, 0x15, 0x88, 0xc9, 0x79, 0x11, 0x67, + 0x23, 0x53, 0xca, 0x03, 0x7a, 0x02, 0xe5, 0xfc, 0xb3, 0x38, 0xf3, 0x5d, + 0xfc, 0x91, 0x6f, 0x59, 0x26, 0xae, 0xd8, 0x45, 0xfa, 0xc4, 0x5b, 0xa2, + 0xfb, 0x2c, 0xc5, 0x36, 0xc6, 0x0d, 0x7b, 0x4e, 0xd2, 0x7f, 0x61, 0xc5, + 0xcc, 0x74, 0xd3, 0x41, 0xd4, 0x8a, 0xaf, 0xcb, 0x32, 0x50, 0xca, 0xeb, + 0x59, 0x0a, 0x05, 0x25, 0xe0, 0x5f, 0x30, 0x2b, 0x5d, 0x9b, 0xf7, 0xe8, + 0x14, 0x14, 0xb5, 0xfe, 0xd5, 0x2f, 0x94, 0x84, 0x5b, 0xc7, 0x4f, 0x82, + 0x01, 0x50, 0xbf, 0x54, 0xe2, 0x7d, 0xeb, 0x0c, 0x85, 0xc8, 0x99, 0x45, + 0x50, 0x8e, 0x4e, 0x10, 0x12, 0x01, 0x17, 0x41, 0xf3, 0x21, 0x4a, 0xee, + 0xaf, 0x0f, 0x76, 0x44, 0xe2, 0x8e, 0xf8, 0x36, 0x25, 0xab, 0x0d, 0x8f, + 0xb1, 0x0a, 0xbf, 0x63, 0x0e, 0xf2, 0x0c, 0x9d, 0x39, 0xa1, 0x98, 0x98, + 0x69, 0x91, 0xd1, 0x9b, 0xe8, 0xcf, 0x16, 0x65, 0x02, 0xc9, 0x67, 0x72, + 0x71, 0x7c, 0xfb, 0x41, 0x2d, 0xe4, 0xd3, 0xfb, 0x44, 0x8a, 0x7a, 0x88, + 0x32, 0x62, 0x26, 0x63, 0xfe, 0x5b, 0x0c, 0x4f, 0x6c, 0xad, 0x2f, 0x64, + 0x6f, 0xc9, 0xda, 0x95, 0x10, 0xbe, 0xd1, 0xfa, 0x8b, 0x67, 0x64, 0x35, + 0x2d, 0xed, 0xca, 0xf3, 0x12, 0xb7, 0x06, 0xc3, 0xa9, 0x8e, 0x3f, 0x09, + 0x4d, 0x1f, 0x50, 0x3a, 0x97, 0xb7, 0xa7, 0xce, 0x4d, 0x46, 0xf1, 0x61, + 0xc1, 0x06, 0x95, 0x0d, 0x07, 0xa2, 0xbc, 0xed, 0xeb, 0x45, 0xb4, 0x69, + 0x05, 0x7a, 0x30, 0x47, 0xa3, 0xbf, 0x81, 0xa9, 0xa7, 0xf0, 0x53, 0x36, + 0x31, 0x37, 0x13, 0xe5, 0x0e, 0xd6, 0xe6, 0xc7, 0x17, 0x17, 0x21, 0x6d, + 0x36, 0xd0, 0xf6, 0x2a, 0xea, 0x2d, 0x32, 0x0e, 0x90, 0x03, 0x30, 0x4d, + 0x30, 0x31, 0xaa, 0x79, 0x2d, 0xae, 0x2e, 0xb0, 0x13, 0xad, 0x63, 0x69, + 0x67, 0xd8, 0xf3, 0x6e, 0xa4, 0x34, 0xcf, 0x02, 0x10, 0xdd, 0x76, 0xfa, + 0xa7, 0xb0, 0x92, 0xea, 0x47, 0xbd, 0xff, 0xf9, 0xac, 0x8a, 0x1f, 0x31, + 0xf8, 0x05, 0xd4, 0xce, 0x23, 0xad, 0x32, 0x8c, 0x6c, 0x92, 0x85, 0xb9, + 0x74, 0xa6, 0xab, 0x6e, 0x76, 0xfd, 0x3e, 0x8a, 0xac, 0xa3, 0xd1, 0xb7, + 0x40, 0x53, 0x87, 0x28, 0xfc, 0xbc, 0x8a, 0x52, 0x8e, 0x2e, 0x59, 0x2c, + 0x5f, 0x3f, 0xcb, 0xd8, 0xbe, 0x37, 0xfd, 0xdc, 0xc0, 0x34, 0x85, 0x67, + 0x28, 0x9f, 0x1d, 0x05, 0x05, 0x94, 0xed, 0x6f, 0x54, 0x7a, 0x51, 0x9a, + 0xaa, 0xca, 0xe1, 0x41, 0x10, 0xf0, 0x9d, 0x38, 0x9c, 0x5e, 0x95, 0xe3, + 0x7e, 0x62, 0xe2, 0x31, 0x81, 0x28, 0x4a, 0x3c, 0x5e, 0x04, 0x11, 0xe2, + 0x6a, 0x45, 0x6f, 0x68, 0x96, 0x5b, 0xbf, 0x22, 0xd8, 0x29, 0x91, 0x76, + 0xe1, 0xb2, 0x5f, 0xfc, 0x89, 0x90, 0x87, 0xf8, 0xb8, 0x3f, 0xd5, 0x11, + 0xe7, 0x36, 0x47, 0x71, 0xb9, 0x52, 0x97, 0x8e, 0x62, 0x8b, 0x05, 0x31, + 0xe5, 0xd9, 0xa2, 0xc3, 0x1a, 0xb5, 0xda, 0xc7, 0xa5, 0x37, 0x06, 0x67, + 0x41, 0x1f, 0x6e, 0xa3, 0xc2, 0xb4, 0x96, 0x64, 0xfc, 0x46, 0x85, 0x95, + 0x4e, 0xd8, 0x2a, 0x4b, 0xaa, 0x1e, 0xec, 0xd5, 0xed, 0x81, 0x23, 0x68, + 0x0f, 0x5d, 0x0b, 0x95, 0x29, 0xd4, 0x36, 0x4d, 0x8c, 0x32, 0x73, 0x6a, + 0xb7, 0xad, 0xb8, 0x9c, 0xad, 0x76, 0x09, 0xad, 0xb9, 0xea, 0x2d, 0x17, + 0x3c, 0x33, 0x87, 0x7f, 0x62, 0x74, 0x77, 0xc9, 0xd6, 0x3d, 0x17, 0xbc, + 0xff, 0x57, 0x10, 0xec, 0x7a, 0xb7, 0x89, 0x05, 0x26, 0xf1, 0xb2, 0x53, + 0xa1, 0x91, 0xc5, 0x2a, 0xfb, 0x5a, 0xce, 0x5d, 0xd1, 0x6b, 0xbc, 0xb7, + 0x39, 0x09, 0x43, 0xdf, 0x20, 0xd3, 0xc1, 0x74, 0x8d, 0xf4, 0x0b, 0x2a, + 0xc7, 0xe8, 0xa1, 0x5f, 0xb2, 0xfe, 0x1a, 0x96, 0x3a, 0x92, 0xbc, 0x8f, + 0x85, 0xe2, 0x22, 0x73, 0x3f, 0x49, 0xb3, 0x6b, 0x90, 0xbd, 0xcb, 0x3f, + 0x36, 0x6c, 0x3d, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x56, 0xd1, 0xff, 0xff, + 0x04, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1f, 0x05, 0x81, 0x3f, + 0x25, 0x68, 0xde, 0x72, 0x88, 0x26, 0x66, 0x2d, 0xe4, 0xc8, 0x81, 0xf8, + 0x5d, 0x98, 0xa2, 0xc2, 0x02, 0x62, 0x63, 0x47, 0xe6, 0x61, 0x7f, 0xee, + 0xca, 0x3f, 0x81, 0xd7, 0x1e, 0xa9, 0xbf, 0x66, 0x59, 0x7f, 0xc3, 0x35, + 0x03, 0xae, 0xe5, 0xf2, 0x4d, 0x81, 0x82, 0x78, 0x5e, 0xaf, 0xaa, 0xd1, + 0x27, 0x41, 0x19, 0x93, 0xa8, 0x9b, 0x78, 0x4e, 0x95, 0x89, 0x7f, 0xce, + 0x49, 0xd0, 0x45, 0xb5, 0x7f, 0x1d, 0xe9, 0xee, 0x7f, 0x91, 0xf4, 0x0a, + 0x67, 0x7d, 0x75, 0xff, 0x38, 0x81, 0x27, 0x90, 0x14, 0xa5, 0x99, 0x40, + 0x5b, 0xe6, 0x9a, 0x81, 0x75, 0x22, 0x5f, 0x18, 0x81, 0x34, 0xb7, 0x54, + 0x2e, 0x8d, 0x81, 0x36, 0x0e, 0x5e, 0xc0, 0x5f, 0xd4, 0xc6, 0x34, 0x81, + 0xc8, 0xb9, 0xe2, 0xa9, 0x77, 0x81, 0x44, 0xb4, 0x06, 0x24, 0x81, 0x74, + 0x1c, 0xeb, 0xfb, 0xdd, 0x25, 0x81, 0x14, 0x09, 0x2d, 0xba, 0x11, 0x4b, + 0x07, 0x13, 0xf1, 0xae, 0x81, 0xaf, 0xa3, 0x87, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0xd1, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, + 0x8a, 0x29, 0x03, 0xe6, 0x24, 0x2a, 0xd6, 0x21, 0xb6, 0xb1, 0x2d, 0x3a, + 0xff, 0xd6, 0x27, 0xd7, 0x18, 0x42, 0xc1, 0xb4, 0xf8, 0xfd, 0xdf, 0x45, + 0x09, 0x91, 0xcb, 0xfe, 0xe9, 0xb5, 0x24, 0xf1, 0xc0, 0x69, 0xd0, 0x64, + 0xa8, 0xeb, 0x12, 0x71, 0xe3, 0xb4, 0xbe, 0xb4, 0x93, 0xbf, 0x8a, 0x8b, + 0xf3, 0x4d, 0x13, 0x3b, 0x6f, 0x6f, 0x32, 0x12, 0x98, 0x95, 0xb9, 0x63, + 0xcd, 0xa5, 0x23, 0xa4, 0xb8, 0x2e, 0x74, 0x75, 0xbc, 0xe4, 0xc7, 0x46, + 0x96, 0xd4, 0x47, 0xa0, 0x65, 0xec, 0xea, 0xcf, 0xd0, 0xdc, 0xe9, 0x8b, + 0xcc, 0x1d, 0x2f, 0x0d, 0x0a, 0x9c, 0x6e, 0x99, 0x97, 0x97, 0xcc, 0x00, + 0xd2, 0x8e, 0xbc, 0x3c, 0x9a, 0xf1, 0x32, 0x0e, 0xf3, 0xd6, 0x27, 0x1c, + 0xea, 0xab, 0xca, 0x4d, 0x69, 0x32, 0x30, 0x5f, 0x18, 0xd7, 0xb7, 0x4a, + 0xcb, 0x8e, 0xb2, 0x96, 0x39, 0xa3, 0xc7, 0x42, 0xca, 0x60, 0x9b, 0xad, + 0x8e, 0xb7, 0x54, 0x32, 0xea, 0xfd, 0x58, 0xfa, 0xf8, 0x02, 0xef, 0x2f, + 0xec, 0x3c, 0x2a, 0x1a, 0x6a, 0x08, 0xa4, 0x4b, 0xec, 0x30, 0x90, 0xaf, + 0x13, 0x98, 0xcd, 0x48, 0xfd, 0x5f, 0x56, 0x68, 0x17, 0x9e, 0x87, 0xb1, + 0x2b, 0x16, 0xd3, 0x3c, 0xe0, 0xe8, 0x0e, 0xa6, 0xc4, 0x24, 0xd3, 0x05, + 0x75, 0xda, 0x22, 0x44, 0xb5, 0x41, 0xd2, 0xa5, 0x99, 0xf1, 0x5e, 0xbe, + 0x15, 0xb7, 0x33, 0x54, 0x9a, 0x97, 0x5b, 0x35, 0x77, 0x2b, 0x18, 0x46, + 0x2f, 0x92, 0xc5, 0x97, 0x2d, 0x4c, 0xa6, 0xf8, 0x9e, 0xc3, 0xe0, 0x0a, + 0x52, 0xf9, 0x97, 0xc7, 0xd6, 0x36, 0xdd, 0x38, 0xaa, 0xf3, 0x05, 0x30, + 0xc3, 0xe5, 0xaf, 0x54, 0xdc, 0xc4, 0xf2, 0x01, 0x9e, 0xe6, 0xc1, 0x89, + 0xee, 0xd8, 0x5f, 0xfe, 0xf0, 0x70, 0x3c, 0xc4, 0x40, 0xa4, 0xd4, 0xee, + 0xaf, 0x3d, 0xe6, 0xcd, 0x31, 0x16, 0x31, 0x3b, 0xa0, 0x0e, 0xc4, 0x71, + 0xbf, 0xbd, 0x39, 0x89, 0x0f, 0x36, 0xba, 0xd8, 0xa2, 0x49, 0x01, 0xab, + 0xf4, 0x07, 0x99, 0xc7, 0xb1, 0x0c, 0x33, 0x9d, 0x71, 0xf1, 0x15, 0x4b, + 0x60, 0xe0, 0xed, 0x59, 0x0a, 0x34, 0xd9, 0xa2, 0x45, 0x99, 0x4a, 0x60, + 0xd3, 0xdc, 0x37, 0x56, 0x32, 0x4c, 0xea, 0xdc, 0xcf, 0xe6, 0x22, 0x27, + 0x17, 0xea, 0x75, 0x3f, 0x69, 0xd4, 0xcf, 0x53, 0x92, 0x98, 0xf4, 0xfe, + 0x13, 0xa8, 0xe2, 0xb2, 0x48, 0x5f, 0x64, 0xab, 0x2b, 0x61, 0x97, 0xf5, + 0xc5, 0xb6, 0xef, 0x32, 0x4e, 0x47, 0x26, 0x42, 0x48, 0x9c, 0x5b, 0x24, + 0xa3, 0xcb, 0x70, 0xc7, 0x31, 0x6c, 0xc8, 0x4d, 0x5c, 0x02, 0xca, 0x71, + 0x1e, 0x56, 0xdb, 0x27, 0x66, 0x5d, 0x4f, 0x0b, 0x09, 0x57, 0xbe, 0x72, + 0x17, 0x3b, 0xce, 0xdd, 0xd2, 0x20, 0x13, 0x67, 0x32, 0x04, 0xee, 0xc4, + 0x66, 0x23, 0x0e, 0x97, 0x5e, 0x21, 0x30, 0xb2, 0xe4, 0x16, 0x06, 0x57, + 0xc3, 0x9b, 0x29, 0x5b, 0x76, 0xd0, 0x36, 0xac, 0xe6, 0xa2, 0x91, 0x57, + 0x96, 0x4e, 0x1c, 0x6f, 0x4a, 0x03, 0x50, 0x55, 0x6d, 0xaf, 0x9a, 0x29, + 0xc9, 0x61, 0x6c, 0x18, 0x4c, 0xb9, 0xd5, 0x41, 0xf8, 0x75, 0x2b, 0xc3, + 0x0e, 0x69, 0x9f, 0x45, 0x93, 0x2f, 0xa6, 0xf9, 0x30, 0x65, 0x05, 0x13, + 0xe3, 0x00, 0x54, 0x0e, 0xa4, 0xb5, 0x89, 0x6d, 0x4d, 0x11, 0x3d, 0x2a, + 0x29, 0x99, 0xd9, 0xdf, 0x75, 0xce, 0x01, 0x21, 0xbc, 0x26, 0xb3, 0x22, + 0xf9, 0xb0, 0x45, 0x5c, 0xf8, 0xea, 0xb2, 0x08, 0x1a, 0xf7, 0xa0, 0x70, + 0x65, 0xa8, 0xab, 0xe1, 0x92, 0xcc, 0xcc, 0x1f, 0x0e, 0x36, 0x60, 0xb7, + 0xea, 0xcb, 0x3d, 0xf6, 0x98, 0xbf, 0xcd, 0x00, 0xc9, 0x16, 0x1e, 0xdb, + 0x58, 0x24, 0xb1, 0xd8, 0xaf, 0x01, 0x00, 0xfa, 0x15, 0xf4, 0x37, 0x05, + 0xd7, 0x17, 0x2a, 0xd2, 0xe8, 0xe4, 0x0c, 0x50, 0xfa, 0xe8, 0xd6, 0x99, + 0xa9, 0x58, 0x61, 0x38, 0xee, 0x22, 0x3c, 0x53, 0xcf, 0x64, 0x8e, 0xad, + 0x4d, 0xd6, 0xc3, 0xc3, 0xdd, 0xb0, 0xb3, 0xf7, 0xdd, 0x37, 0xfd, 0xf3, + 0x2b, 0x6a, 0xe2, 0xd4, 0xfc, 0x0c, 0x74, 0xca, 0x37, 0x2f, 0xd2, 0xf8, + 0x5b, 0xf1, 0x8c, 0x32, 0xa0, 0xdc, 0x2c, 0xa8, 0x36, 0x2f, 0xbe, 0x45, + 0x9b, 0x42, 0x95, 0x15, 0x5e, 0x08, 0xb1, 0x61, 0xec, 0xa2, 0xdf, 0x5f, + 0xca, 0xf8, 0x62, 0x73, 0xfd, 0x66, 0xc8, 0x51, 0x2a, 0x69, 0x3c, 0x8f, + 0x75, 0xa4, 0x6f, 0xbe, 0xc1, 0x5c, 0x66, 0xe2, 0x60, 0x92, 0xd7, 0x0e, + 0xee, 0x1b, 0xc7, 0x39, 0x8b, 0x56, 0x6c, 0xc6, 0x20, 0xfa, 0xec, 0x96, + 0xa5, 0x0f, 0x74, 0x42, 0x32, 0x12, 0x11, 0xdf, 0x02, 0xfe, 0x42, 0x1c, + 0xfe, 0xf1, 0x72, 0xaf, 0x47, 0x3b, 0x62, 0xe3, 0x27, 0x29, 0xf0, 0xec, + 0x39, 0xd2, 0xdd, 0xb6, 0xe9, 0xbe, 0x5f, 0x66, 0x67, 0x6c, 0xc9, 0xa1, + 0xf0, 0x25, 0x9a, 0x1b, 0xa8, 0xa0, 0x15, 0xcb, 0x61, 0x98, 0x98, 0xfd, + 0xef, 0xba, 0x74, 0x9b, 0x54, 0xf3, 0x6d, 0xe1, 0xa4, 0xcf, 0xb5, 0xe7, + 0xba, 0x0f, 0xd1, 0x41, 0xd8, 0x63, 0x94, 0x09, 0xcd, 0x4f, 0xb1, 0x31, + 0x49, 0x5e, 0x54, 0xb1, 0x28, 0x39, 0x8e, 0x13, 0x48, 0x2e, 0x20, 0xb0, + 0xf7, 0x18, 0x9a, 0xea, 0xf2, 0x9b, 0xde, 0x8f, 0x16, 0xc8, 0x9e, 0x31, + 0xca, 0x94, 0x28, 0x26, 0x0d, 0x8c, 0x0f, 0x09, 0x69, 0xc5, 0x2a, 0x38, + 0xae, 0x6b, 0xfb, 0x4f, 0xbb, 0xf4, 0x14, 0xea, 0x8d, 0x13, 0xc0, 0x09, + 0xe2, 0xfb, 0xfb, 0x09, 0xa1, 0xfc, 0x49, 0xff, 0x0f, 0x52, 0x3e, 0xe8, + 0xda, 0xfe, 0xe1, 0x67, 0x8f, 0x21, 0xcf, 0xaf, 0xb7, 0xe2, 0xcf, 0x09, + 0x15, 0x10, 0x51, 0x72, 0x8f, 0x42, 0x09, 0x9d, 0xea, 0x27, 0x2d, 0x25, + 0x9f, 0x54, 0x50, 0xfa, 0xdf, 0x9f, 0x41, 0xe8, 0xd2, 0x66, 0xd8, 0x28, + 0xfb, 0x8b, 0xe4, 0x42, 0x03, 0x92, 0xf9, 0xcd, 0xcc, 0xb0, 0xc0, 0x52, + 0x53, 0x6d, 0xcd, 0xed, 0x16, 0xad, 0x3c, 0x3d, 0xf9, 0x3b, 0x05, 0xbb, + 0xac, 0x9e, 0xa3, 0x4b, 0x17, 0xb4, 0xc7, 0xdd, 0xd4, 0xd3, 0x0c, 0x10, + 0x0d, 0xd8, 0x9c, 0xdb, 0xa4, 0x60, 0x06, 0x89, 0x4b, 0x06, 0x4c, 0x9f, + 0xc4, 0x47, 0xc8, 0xaf, 0xab, 0x02, 0x23, 0x89, 0x6e, 0xf2, 0x9d, 0x2b, + 0x6b, 0x9a, 0xa4, 0xee, 0x16, 0x0b, 0x3c, 0x76, 0xd4, 0xf0, 0x17, 0x90, + 0xca, 0xf5, 0xc8, 0xbf, 0xcb, 0xb1, 0x02, 0x69, 0x34, 0x71, 0x59, 0x5d, + 0x0e, 0x56, 0xd8, 0x41, 0x0a, 0xa5, 0x0a, 0x16, 0xbc, 0x93, 0x63, 0xf9, + 0xd9, 0xab, 0x3e, 0x75, 0x1e, 0xd3, 0xf3, 0x56, 0xf5, 0x14, 0xee, 0x65, + 0xf3, 0x2f, 0x72, 0x03, 0xcb, 0x69, 0x90, 0x91, 0x0d, 0x31, 0x8e, 0x3e, + 0xe9, 0xb0, 0xe6, 0x2e, 0x37, 0x5d, 0xb0, 0x38, 0x52, 0xe6, 0x23, 0x24, + 0x36, 0xb2, 0xe9, 0xa5, 0xa0, 0xae, 0xed, 0xfd, 0x95, 0xa5, 0xcf, 0x4a, + 0xe3, 0xbd, 0xe7, 0x29, 0xd0, 0x57, 0x3e, 0xf1, 0xdf, 0xc8, 0xc7, 0x26, + 0xf6, 0xc7, 0x4b, 0xc8, 0x6a, 0x4a, 0xed, 0x49, 0x60, 0x2d, 0x1c, 0xe3, + 0x8b, 0x10, 0x24, 0xfc, 0xef, 0xbb, 0x1e, 0x24, 0xbb, 0x40, 0xeb, 0x99, + 0xba, 0xe1, 0x4a, 0xd4, 0x1f, 0x69, 0x47, 0xa4, 0x8f, 0x48, 0x05, 0x17, + 0xcb, 0xee, 0x55, 0xca, 0xe5, 0xe3, 0x60, 0xec, 0xfa, 0xe6, 0xd1, 0x28, + 0xc5, 0xa8, 0x04, 0xd8, 0xce, 0x13, 0x2b, 0x99, 0x2b, 0xc7, 0x94, 0x9d, + 0xda, 0xd7, 0x6f, 0x31, 0xfe, 0xee, 0x6c, 0x9b, 0xf1, 0x70, 0xd2, 0xee, + 0xc4, 0xba, 0xb7, 0xbe, 0xd3, 0x37, 0xdc, 0x43, 0x4e, 0x30, 0x4a, 0x67, + 0xf2, 0x45, 0x29, 0xe1, 0x8b, 0xb8, 0x6d, 0xca, 0xec, 0xb9, 0xd6, 0xd3, + 0xdd, 0xcb, 0xde, 0xdb, 0xa9, 0x4d, 0xdd, 0x3d, 0x41, 0xae, 0x99, 0x89, + 0xce, 0x70, 0x50, 0x61, 0x07, 0xf3, 0xca, 0x24, 0x56, 0x76, 0x3f, 0xe0, + 0x6e, 0xbe, 0xa7, 0xc6, 0xac, 0x6c, 0xf1, 0x8c, 0xa2, 0x0e, 0xc4, 0x2a, + 0x48, 0x30, 0x8b, 0xc9, 0xc0, 0x5a, 0xb2, 0x2b, 0xbd, 0xa2, 0xcc, 0xf7, + 0x25, 0x16, 0xc3, 0xde, 0x1b, 0x8d, 0x23, 0x8c, 0xb6, 0xc4, 0xaa, 0x4a, + 0x0b, 0x66, 0x25, 0x35, 0xb3, 0x9a, 0x74, 0x27, 0x63, 0xea, 0xef, 0x92, + 0x12, 0x8c, 0x58, 0xd9, 0x3a, 0x55, 0xd6, 0x61, 0x29, 0x9f, 0xbc, 0x28, + 0xbd, 0x30, 0xcd, 0x43, 0xe6, 0x36, 0x36, 0x66, 0x20, 0x8c, 0x9e, 0x23, + 0xfe, 0x6d, 0xf0, 0xbc, 0x61, 0xcd, 0x58, 0xd8, 0xe0, 0x2e, 0xe4, 0xcf, + 0x61, 0xf7, 0xd5, 0x6b, 0x54, 0x33, 0xb3, 0x2c, 0x60, 0xa8, 0x59, 0x21, + 0x5d, 0xaa, 0x65, 0x9e, 0xdc, 0xa3, 0xc9, 0xc4, 0x9d, 0x4d, 0x95, 0x29, + 0xf6, 0x2b, 0xcd, 0xc9, 0xb9, 0x9d, 0x46, 0xa0, 0x89, 0xf4, 0x4e, 0x52, + 0x55, 0xe2, 0x13, 0x98, 0xf0, 0xef, 0x27, 0xc3, 0xc9, 0xd1, 0xe1, 0xee, + 0x07, 0x1b, 0x9d, 0x8a, 0x5b, 0x9d, 0x06, 0x26, 0x61, 0x2a, 0x55, 0x6f, + 0x54, 0x22, 0xd5, 0x06, 0x20, 0xed, 0x06, 0x4d, 0xa2, 0xb3, 0xaa, 0x4f, + 0x1f, 0x3e, 0xd2, 0x0d, 0x6a, 0xab, 0x6d, 0xee, 0x8f, 0x09, 0xb2, 0xd9, + 0x39, 0x46, 0x0f, 0xe7, 0x51, 0x70, 0x51, 0xdb, 0x09, 0xf8, 0x8e, 0xbb, + 0x06, 0x98, 0x49, 0x69, 0xb7, 0x9e, 0xa0, 0xbc, 0x16, 0x5f, 0x96, 0xad, + 0xe9, 0x76, 0x9f, 0x71, 0xe2, 0x1b, 0x91, 0x73, 0xd9, 0x74, 0x6a, 0x70, + 0x48, 0x71, 0x47, 0x3b, 0x0c, 0xd5, 0x96, 0xe3, 0x6e, 0xdb, 0xbb, 0x9c, + 0x44, 0x5c, 0xe5, 0x07, 0x73, 0x31, 0xd1, 0x55, 0x07, 0xff, 0x5f, 0xb1, + 0x55, 0x9d, 0x0d, 0xbf, 0x32, 0x53, 0xf9, 0xfe, 0xcd, 0xc8, 0xe0, 0x56, + 0x18, 0x8f, 0x4b, 0x51, 0xd1, 0x23, 0x2e, 0x9f, 0xb9, 0xee, 0xf3, 0xfd, + 0x26, 0x02, 0xf6, 0x54, 0xd5, 0x3e, 0x13, 0xc1, 0xc1, 0xe4, 0xa8, 0xb4, + 0x5f, 0x5c, 0xa0, 0x9f, 0xb5, 0x19, 0xbb, 0x4e, 0xd6, 0xf8, 0x18, 0x9b, + 0xeb, 0x9e, 0x58, 0x9d, 0x00, 0x51, 0x24, 0x28, 0x70, 0x55, 0xf7, 0xb9, + 0x5a, 0x59, 0x50, 0xc5, 0x72, 0xab, 0x6b, 0x13, 0x95, 0xfb, 0xe4, 0xc2, + 0x05, 0x96, 0xf3, 0x48, 0xef, 0x02, 0x67, 0xd5, 0x8f, 0x5b, 0x8e, 0xb6, + 0xbe, 0xc1, 0x3d, 0x8e, 0x22, 0xee, 0x49, 0xc7, 0xbe, 0xfb, 0x2d, 0x51, + 0x45, 0x44, 0xca, 0x94, 0x8e, 0xce, 0xb5, 0x9a, 0x29, 0xc7, 0x52, 0xde, + 0x2c, 0xdf, 0xcc, 0x43, 0xc7, 0xd7, 0x51, 0xb7, 0x07, 0xf0, 0x9b, 0x9d, + 0x33, 0x98, 0x62, 0xfa, 0xc9, 0x13, 0x0b, 0xcd, 0xdf, 0xbd, 0xff, 0x8e, + 0x13, 0x44, 0xda, 0x62, 0xc0, 0xd1, 0x8d, 0x57, 0x0e, 0xec, 0x53, 0x8a, + 0x04, 0xcf, 0x0f, 0x5a, 0xd7, 0x3c, 0x4b, 0x17, 0xda, 0x3b, 0xf0, 0x30, + 0xbf, 0xea, 0x40, 0xa6, 0x36, 0xed, 0xda, 0xf7, 0x40, 0x6b, 0xf1, 0x1e, + 0x61, 0xa0, 0x8b, 0x5d, 0xfa, 0xa8, 0x6a, 0xca, 0xfd, 0x6a, 0x06, 0xb4, + 0xf5, 0xb6, 0xc7, 0xbe, 0xdf, 0xac, 0x17, 0x00, 0x4a, 0x91, 0x8d, 0x97, + 0x5b, 0xc8, 0xcb, 0xd4, 0xc8, 0x20, 0x0b, 0x53, 0xee, 0x2b, 0x25, 0xb8, + 0xa1, 0x24, 0xa1, 0xa0, 0x17, 0x60, 0xd9, 0xf7, 0x2d, 0x00, 0x6c, 0x70, + 0x44, 0x0d, 0x60, 0xe7, 0x95, 0x1e, 0x8a, 0x1b, 0x29, 0xcf, 0xb5, 0xc1, + 0xbe, 0xd0, 0xe5, 0xeb, 0xd8, 0x71, 0x88, 0x34, 0xcb, 0xbd, 0x32, 0x52, + 0xa7, 0xcf, 0x6d, 0x9b, 0xef, 0xf2, 0xe4, 0x68, 0x6f, 0xfe, 0xb9, 0x17, + 0x31, 0xa0, 0x3e, 0xfc, 0xae, 0xf6, 0x54, 0xe3, 0x33, 0x24, 0xd1, 0xfc, + 0xb7, 0x37, 0x8f, 0xd3, 0x4f, 0xf2, 0x59, 0x53, 0xea, 0xaf, 0x71, 0xc5, + 0xb1, 0xdb, 0xf9, 0xed, 0xc0, 0x46, 0x56, 0xfc, 0x09, 0x90, 0xf7, 0x09, + 0x5a, 0x12, 0x71, 0xad, 0xa6, 0x0f, 0xba, 0x4c, 0x2f, 0xd7, 0x61, 0xcb, + 0xf2, 0xab, 0x44, 0x67, 0x43, 0xd0, 0x41, 0xd5, 0xba, 0xff, 0x26, 0x50, + 0x5b, 0x97, 0x91, 0xc4, 0x8f, 0x2a, 0x64, 0x3c, 0x06, 0x2e, 0x26, 0x8e, + 0x5f, 0xb1, 0xba, 0x74, 0x16, 0xeb, 0xee, 0x6e, 0xe1, 0x68, 0xcc, 0x09, + 0xed, 0xa5, 0x5d, 0xf7, 0xef, 0xd6, 0xfa, 0x9f, 0x39, 0xe1, 0x5c, 0x38, + 0xbd, 0x1b, 0xe6, 0x8a, 0xfa, 0xea, 0xbc, 0x14, 0x4c, 0x31, 0xa8, 0x9d, + 0x64, 0xa6, 0xec, 0xf0, 0xf8, 0xa2, 0x0a, 0x6c, 0xb9, 0xc5, 0x3d, 0x40, + 0x48, 0x41, 0x1d, 0xf2, 0xab, 0xd4, 0xdf, 0xfb, 0x55, 0x9e, 0xa5, 0xac, + 0xe9, 0xf0, 0x46, 0x96, 0xc5, 0x4d, 0x5f, 0x5f, 0x64, 0x00, 0x69, 0x48, + 0x0e, 0xa3, 0xb5, 0x5d, 0x45, 0xce, 0x57, 0xc4, 0x45, 0xdb, 0xc6, 0x13, + 0x4b, 0xa7, 0xa0, 0xd5, 0x31, 0xb4, 0xd4, 0x0f, 0x4f, 0x29, 0x40, 0xc0, + 0xaa, 0xb7, 0x54, 0x21, 0xd5, 0x3a, 0x01, 0xbc, 0xa8, 0x58, 0xb5, 0x3f, + 0xa6, 0x1a, 0x06, 0xb5, 0x07, 0xd3, 0xb6, 0xff, 0x6e, 0x74, 0x08, 0x16, + 0x45, 0xaf, 0xd9, 0xc5, 0x4a, 0x0d, 0xd2, 0x8a, 0xd1, 0x6c, 0xba, 0x5a, + 0xd0, 0xee, 0x57, 0x10, 0xa4, 0x1a, 0xf4, 0x92, 0x97, 0xe0, 0xd7, 0xa8, + 0xff, 0x47, 0xed, 0x56, 0x6b, 0x91, 0x77, 0x5d, 0xa6, 0xcf, 0xed, 0x96, + 0xc5, 0x5a, 0xe3, 0x0b, 0x1d, 0xc0, 0xcc, 0xa1, 0x71, 0x95, 0xa8, 0xec, + 0xef, 0x33, 0x91, 0xd6, 0x53, 0x1f, 0xef, 0x43, 0xa9, 0x42, 0x2a, 0xc7, + 0xf6, 0x15, 0x60, 0xc2, 0xde, 0xeb, 0xac, 0xf8, 0x55, 0x27, 0x14, 0xf1, + 0xf8, 0x69, 0x55, 0xc8, 0x69, 0x1f, 0xf3, 0xc2, 0x71, 0xe8, 0x75, 0xa9, + 0x1a, 0x91, 0xc5, 0x1e, 0xe3, 0x52, 0x24, 0x5f, 0x60, 0xb5, 0xf1, 0xe6, + 0xdd, 0x4b, 0x1b, 0xdd, 0x3a, 0xad, 0x58, 0x36, 0x9c, 0xb3, 0x25, 0x9e, + 0x28, 0xd4, 0x3b, 0x6a, 0x64, 0xe7, 0x57, 0x54, 0xad, 0x4d, 0x44, 0xfc, + 0x54, 0xd3, 0xa3, 0x96, 0x4e, 0xee, 0xde, 0x23, 0x30, 0x30, 0x1f, 0x57, + 0x2f, 0xd6, 0xb4, 0xfa, 0x5c, 0x1b, 0x4a, 0x1b, 0x96, 0x58, 0x9a, 0xc7, + 0x25, 0xd0, 0x9c, 0xf3, 0x2b, 0x16, 0x58, 0x62, 0x0c, 0x5b, 0x45, 0x96, + 0xb0, 0xc2, 0x3e, 0xca, 0x0a, 0xb5, 0x0f, 0x06, 0xa8, 0xa3, 0xb2, 0x0a, + 0x6a, 0xc5, 0xb7, 0xf8, 0x69, 0xfa, 0xc1, 0xa8, 0xbc, 0x17, 0x6c, 0x92, + 0x06, 0x50, 0x74, 0x4b, 0x02, 0xc8, 0x4d, 0x9c, 0x3e, 0x94, 0x6f, 0xef, + 0x3e, 0xd9, 0x71, 0xa6, 0x3a, 0x70, 0x6a, 0x14, 0x0e, 0x06, 0xbe, 0x40, + 0x2b, 0xa1, 0xbb, 0x05, 0x71, 0x05, 0xbd, 0xd5, 0x2d, 0xd9, 0xe2, 0xf6, + 0xb4, 0x32, 0x33, 0xac, 0x0f, 0x9a, 0xe3, 0xaf, 0xf4, 0x44, 0x21, 0x59, + 0x91, 0x0d, 0xd0, 0xf1, 0x47, 0x9e, 0x00, 0x38, 0xa2, 0x1d, 0x61, 0x54, + 0xd2, 0x18, 0x9d, 0xe4, 0x4f, 0xf3, 0xbd, 0x04, 0xdb, 0x4d, 0x59, 0x8c, + 0xfa, 0x12, 0xdd, 0xe4, 0xb5, 0x32, 0x3b, 0xf8, 0x93, 0xae, 0x3b, 0xa9, + 0xb3, 0xe9, 0x57, 0x30, 0x49, 0x6d, 0xaa, 0x35, 0x12, 0xce, 0x16, 0x98, + 0x3c, 0xd0, 0xed, 0xe8, 0xa6, 0xbc, 0xa6, 0xe6, 0x66, 0x0f, 0xb3, 0x12, + 0x95, 0x19, 0x56, 0x23, 0xb1, 0x30, 0x5d, 0xb3, 0x4c, 0x5f, 0x0c, 0xef, + 0x24, 0x12, 0xe0, 0x97, 0xf3, 0x3e, 0x9c, 0x49, 0xff, 0xa6, 0x6f, 0xa6, + 0xd2, 0x58, 0xbe, 0x3f, 0x30, 0xdd, 0x65, 0xd0, 0x40, 0xe1, 0xaf, 0x09, + 0xf1, 0xf4, 0x0f, 0x1a, 0xe5, 0xef, 0x51, 0x50, 0x38, 0x5d, 0xb0, 0x1e, + 0xed, 0x19, 0x8d, 0x4e, 0x20, 0xa1, 0x65, 0x07, 0x5b, 0x23, 0x0c, 0x14, + 0xd3, 0x18, 0xa3, 0xda, 0x58, 0x9f, 0x10, 0x00, 0xbd, 0xb5, 0x95, 0x07, + 0x1d, 0x0f, 0xf9, 0x2a, 0xe4, 0x35, 0x3c, 0x60, 0xad, 0xb2, 0x13, 0x3b, + 0xd5, 0x9e, 0xeb, 0xc7, 0x09, 0x6e, 0x53, 0xff, 0x95, 0xf3, 0xc1, 0x9b, + 0xcd, 0x21, 0x15, 0x3b, 0x5f, 0xfe, 0x4e, 0xaf, 0x3f, 0xf8, 0xe3, 0xa8, + 0x35, 0xee, 0x44, 0x33, 0xc7, 0x8c, 0x9c, 0x1c, 0x33, 0x55, 0x3c, 0x4a, + 0xa4, 0x35, 0xf6, 0xf0, 0x32, 0x8e, 0xed, 0x6d, 0x06, 0xff, 0x8d, 0x24, + 0x05, 0x72, 0x4c, 0xa2, 0x97, 0x25, 0x93, 0x3d, 0x79, 0x18, 0x22, 0x15, + 0xec, 0x5c, 0xc4, 0x10, 0x65, 0xec, 0x90, 0x6d, 0x28, 0xba, 0x93, 0xb5, + 0x2f, 0x53, 0xe4, 0x00, 0x9c, 0x39, 0xf5, 0x4c, 0xde, 0x51, 0x39, 0xc3, + 0xd8, 0x03, 0xc3, 0x97, 0xe1, 0xa8, 0x3e, 0x06, 0x26, 0x4d, 0xd9, 0x49, + 0x75, 0xbb, 0xd5, 0x69, 0x20, 0xfb, 0x85, 0x12, 0xc9, 0xac, 0xfc, 0x05, + 0xad, 0x57, 0xa9, 0x58, 0xcd, 0xfd, 0xbe, 0x64, 0x31, 0x50, 0x4d, 0xa4, + 0x93, 0xb6, 0x23, 0x3b, 0xfd, 0xd9, 0xdb, 0x46, 0xdd, 0x1f, 0x07, 0x54, + 0xc2, 0xc2, 0xd6, 0xad, 0xf6, 0x21, 0x39, 0xa1, 0x96, 0x53, 0x12, 0x46, + 0x5a, 0xc8, 0xf3, 0xf8, 0xe2, 0xa3, 0xd0, 0x29, 0x3f, 0x30, 0xca, 0x0b, + 0x57, 0xab, 0xcf, 0x1e, 0x08, 0x59, 0x3d, 0x41, 0x6a, 0xf7, 0xb2, 0xfc, + 0xff, 0x33, 0x46, 0xd1, 0x1a, 0xa6, 0x91, 0x54, 0xca, 0x27, 0x5a, 0x94, + 0x13, 0xf4, 0xf0, 0xcf, 0x58, 0xe0, 0x96, 0x50, 0xda, 0xe6, 0x91, 0xc7, + 0x8d, 0x14, 0x5b, 0xc1, 0xeb, 0x4a, 0x96, 0xf1, 0xa5, 0x43, 0xf6, 0x29, + 0x91, 0xb9, 0xb9, 0x67, 0x3f, 0x31, 0xd7, 0x08, 0xe6, 0x2b, 0xfb, 0x43, + 0x56, 0x39, 0x4e, 0xf9, 0x02, 0x8e, 0x96, 0x1f, 0xa3, 0x3c, 0xae, 0x55, + 0x03, 0x05, 0x9a, 0x39, 0xbe, 0xf7, 0x67, 0xa1, 0x6b, 0x2f, 0x42, 0x45, + 0x9b, 0x45, 0x8f, 0x53, 0x1f, 0x96, 0x42, 0x54, 0xd2, 0x5b, 0xf0, 0x17, + 0x94, 0x41, 0xaf, 0xd4, 0xc6, 0x37, 0x5f, 0xc0, 0xbd, 0xe3, 0x44, 0x8d, + 0xc1, 0x69, 0x64, 0x2a, 0xe7, 0x08, 0xe5, 0x18, 0x92, 0x53, 0xfc, 0xed, + 0xd3, 0x69, 0x94, 0x6b, 0x10, 0x0b, 0x5e, 0x91, 0x38, 0x4b, 0xa5, 0x19, + 0x3a, 0x6a, 0x2e, 0x5a, 0xa2, 0x6f, 0x34, 0x2c, 0x7b, 0x5d, 0x53, 0x33, + 0x77, 0x46, 0xf8, 0x4a, 0xa2, 0x8d, 0x55, 0x67, 0xa8, 0xbd, 0xc6, 0x3c, + 0x5d, 0x47, 0xeb, 0x99, 0xed, 0xdc, 0xae, 0xcf, 0xec, 0xbe, 0x40, 0x60, + 0xfc, 0x36, 0x5c, 0x93, 0x95, 0x64, 0xd8, 0x47, 0x14, 0xe2, 0x1e, 0xa2, + 0xd4, 0xd4, 0xdf, 0xd9, 0x23, 0x18, 0xf2, 0x99, 0xe8, 0xe4, 0x2a, 0x3b, + 0xec, 0x2e, 0x28, 0xa8, 0x04, 0x74, 0x04, 0xa4, 0x32, 0xa6, 0x49, 0xf9, + 0x33, 0x6c, 0xa8, 0x1d, 0xb2, 0xbb, 0x57, 0xe4, 0xcf, 0xf2, 0x9e, 0x74, + 0x8d, 0xf7, 0x22, 0xaa, 0x0d, 0x8a, 0x2f, 0x34, 0x72, 0x33, 0xec, 0xdf, + 0x46, 0x57, 0x6c, 0x97, 0x94, 0xad, 0x06, 0x88, 0xeb, 0x20, 0xec, 0x79, + 0x44, 0xe1, 0xbc, 0xf8, 0xbd, 0xeb, 0x99, 0xe3, 0xaf, 0xfe, 0xc5, 0xb5, + 0xfa, 0x31, 0x75, 0x62, 0xff, 0x2a, 0x2a, 0x1b, 0xce, 0xad, 0xa8, 0xc8, + 0x3c, 0x54, 0x23, 0xf9, 0x9e, 0x2d, 0xe2, 0xa4, 0x4f, 0x5b, 0x4d, 0xb8, + 0x4f, 0xc6, 0xb3, 0xc6, 0xef, 0x66, 0x54, 0x31, 0xab, 0xd3, 0xf0, 0xb9, + 0xfa, 0xb6, 0x15, 0xe6, 0xdb, 0x4b, 0x51, 0x4d, 0x77, 0xa5, 0x3d, 0x4e, + 0xd9, 0xc9, 0xdb, 0x95, 0x31, 0x1d, 0x4d, 0x37, 0xe0, 0x34, 0xd3, 0xf3, + 0x20, 0x6b, 0xb8, 0x16, 0x0b, 0x4e, 0x55, 0x96, 0x56, 0x1e, 0xa7, 0xe8, + 0xc6, 0x3a, 0x08, 0x49, 0xa1, 0x16, 0x46, 0xc9, 0x43, 0xcb, 0x8f, 0x28, + 0x4a, 0x78, 0xaa, 0xf9, 0x6c, 0x74, 0xc8, 0x0b, 0xce, 0x13, 0x2c, 0xef, + 0xfe, 0x73, 0x42, 0xa7, 0xbc, 0x3d, 0xc9, 0xf2, 0xaf, 0x1c, 0x32, 0xdb, + 0xb2, 0x15, 0x70, 0x6b, 0x9b, 0x6e, 0x6f, 0x6e, 0xf7, 0x95, 0xea, 0x3e, + 0xd0, 0xb1, 0x2a, 0xbe, 0x8c, 0x66, 0x4e, 0xe9, 0x29, 0xe3, 0x35, 0xde, + 0xbf, 0x44, 0xbc, 0x5e, 0x56, 0x8b, 0xb3, 0xd4, 0xdf, 0xf5, 0x4e, 0x2e, + 0xeb, 0xe6, 0x8e, 0x58, 0xe2, 0xfd, 0xe7, 0x27, 0xff, 0x07, 0x49, 0x20, + 0xdd, 0xcf, 0xe4, 0xd7, 0x5c, 0x5f, 0x1f, 0xcc, 0xeb, 0x29, 0xeb, 0x34, + 0xac, 0xd6, 0xb6, 0xf8, 0xae, 0xdf, 0x11, 0x58, 0xd5, 0xea, 0xf1, 0x76, + 0xe5, 0x4d, 0x51, 0x72, 0xd4, 0x5e, 0x1e, 0x0f, 0xfd, 0x2e, 0xbe, 0x8e, + 0x07, 0x1a, 0x1f, 0x99, 0x4d, 0x73, 0x70, 0xe1, 0x41, 0xb4, 0x20, 0x10, + 0x75, 0x0f, 0xc8, 0x69, 0x5f, 0x6c, 0x20, 0x2b, 0xc8, 0xfd, 0xe9, 0x4c, + 0xf4, 0x6f, 0x6a, 0xe0, 0x1a, 0xb5, 0xec, 0x2e, 0xf5, 0x25, 0x6d, 0x56, + 0x56, 0xb9, 0x42, 0xca, 0x70, 0x72, 0xe5, 0x41, 0x07, 0x4f, 0x41, 0x25, + 0xea, 0x0a, 0x5d, 0xe1, 0x0a, 0xd5, 0x6f, 0x35, 0x50, 0xcc, 0x27, 0x53, + 0x5f, 0x31, 0x1c, 0xee, 0xae, 0x26, 0xc8, 0xc4, 0x4f, 0x9b, 0xf5, 0xf6, + 0x4d, 0x19, 0xb9, 0xc4, 0x55, 0xcd, 0xe5, 0x8a, 0xe9, 0x45, 0xec, 0xf2, + 0xf9, 0x33, 0x4d, 0xba, 0x57, 0x8f, 0xd6, 0xf5, 0xf7, 0x92, 0xb3, 0xd3, + 0x65, 0x39, 0x07, 0x04, 0x92, 0x2f, 0x70, 0x99, 0x97, 0x96, 0x60, 0xe5, + 0x92, 0x60, 0xc3, 0x72, 0x1e, 0xc7, 0xe6, 0x1d, 0xbb, 0x5b, 0xd5, 0x64, + 0x1b, 0x36, 0x45, 0xb8, 0xcb, 0x42, 0xe7, 0x26, 0x45, 0x65, 0xc8, 0x04, + 0x1c, 0x05, 0x9b, 0x48, 0xe3, 0x93, 0x8e, 0xb2, 0x1c, 0x6a, 0xab, 0x60, + 0xc2, 0xa6, 0x1a, 0x71, 0xd5, 0x2c, 0xb8, 0xe9, 0x9e, 0x66, 0x8d, 0xb6, + 0xb1, 0x99, 0x90, 0x9c, 0x1b, 0xc9, 0x44, 0x6d, 0x31, 0xbb, 0x62, 0x6e, + 0x46, 0xcc, 0xd7, 0x47, 0x3a, 0x40, 0x63, 0x33, 0x34, 0x4f, 0x50, 0x3c, + 0x94, 0x97, 0xe9, 0xe8, 0x3a, 0xf7, 0x2d, 0x2d, 0x9c, 0xb6, 0x5d, 0x52, + 0xbd, 0xa9, 0x2d, 0x42, 0xfc, 0xe8, 0x70, 0x09, 0x48, 0xd0, 0x36, 0x0b, + 0x3d, 0x2b, 0x9f, 0xe2, 0x4c, 0xdf, 0xf3, 0x57, 0x73, 0x55, 0xf7, 0x34, + 0xb8, 0x6b, 0x44, 0x6f, 0xf6, 0x6d, 0xcf, 0x93, 0x09, 0x14, 0xac, 0x8f, + 0xde, 0xce, 0x5f, 0x05, 0x04, 0x9f, 0xc7, 0x05, 0x5f, 0xdd, 0x2e, 0xfc, + 0x53, 0xec, 0x9e, 0xdb, 0xa8, 0xa2, 0xc7, 0x53, 0x5c, 0x9a, 0x4d, 0xb6, + 0x6f, 0xa5, 0xc6, 0xf3, 0xc5, 0xa4, 0x56, 0x62, 0xdc, 0x75, 0xe4, 0x0b, + 0xb0, 0xcc, 0x38, 0xde, 0x2d, 0xbb, 0xbc, 0x0b, 0xc6, 0xab, 0xac, 0xac, + 0x46, 0xce, 0x1e, 0xe6, 0x47, 0x6c, 0x6e, 0x8e, 0x00, 0x00, 0xa0, 0xae, + 0x1e, 0x1d, 0xaa, 0x22, 0xaf, 0x34, 0xc7, 0x26, 0x37, 0x01, 0x46, 0x25, + 0x9c, 0x5f, 0x92, 0xef, 0xda, 0x07, 0x64, 0x62, 0xe4, 0xf7, 0x4c, 0xa2, + 0x41, 0xf1, 0x10, 0xe0, 0xe5, 0x73, 0x72, 0xe1, 0xf8, 0x66, 0x19, 0x58, + 0xa9, 0xdf, 0xb1, 0x41, 0xcb, 0xb3, 0xc4, 0xe6, 0x21, 0xbe, 0x17, 0x26, + 0xa9, 0x68, 0x96, 0xde, 0x5d, 0xba, 0x8f, 0x1b, 0x09, 0x00, 0x39, 0x0e, + 0xc2, 0x8d, 0x31, 0x61, 0xfe, 0x9e, 0x60, 0x05, 0xf3, 0x72, 0xdf, 0x78, + 0x14, 0x5a, 0x1b, 0x74, 0xa1, 0x23, 0xa7, 0x6e, 0x93, 0x76, 0xfa, 0x4a, + 0x73, 0xa1, 0x3b, 0xda, 0x0b, 0x06, 0xdd, 0xfc, 0x2f, 0xef, 0x0a, 0x38, + 0x03, 0xbf, 0xbb, 0x12, 0x29, 0x6b, 0xec, 0x68, 0xc7, 0xa6, 0xf9, 0x72, + 0xbc, 0xdb, 0xeb, 0x4e, 0x8f, 0x5f, 0x3a, 0xa9, 0x06, 0x4e, 0x3c, 0xf4, + 0x3b, 0xe0, 0x98, 0x9b, 0x77, 0x57, 0x0f, 0x39, 0x08, 0x43, 0x3f, 0x9b, + 0x76, 0x11, 0xd3, 0x38, 0xb6, 0x1f, 0x1e, 0xfe, 0xbb, 0x16, 0x37, 0x24, + 0x15, 0xf7, 0x8e, 0x61, 0x3d, 0xf5, 0x60, 0xab, 0x46, 0x49, 0xd6, 0xb2, + 0x8e, 0x35, 0xd5, 0x66, 0x20, 0x1f, 0xad, 0xf5, 0x95, 0xc3, 0x3e, 0xaa, + 0xda, 0x12, 0x1f, 0x33, 0xf4, 0xc0, 0xd9, 0x9e, 0x09, 0x76, 0x8b, 0x2f, + 0x35, 0xe2, 0x58, 0x09, 0x36, 0xf1, 0x03, 0xbc, 0xc2, 0x54, 0x67, 0x29, + 0x00, 0x3b, 0xf0, 0x24, 0xdf, 0xa0, 0x92, 0x71, 0xc3, 0x98, 0xe8, 0x5d, + 0xbe, 0xc7, 0xe8, 0x6f, 0x2f, 0x05, 0x89, 0x9f, 0xa1, 0x63, 0x29, 0x12, + 0x94, 0xff, 0xc7, 0x4c, 0xec, 0x98, 0x0e, 0xb8, 0xeb, 0x9e, 0x6d, 0x1e, + 0x4f, 0x4a, 0x1e, 0x41, 0xb0, 0xf9, 0x40, 0x8b, 0xdd, 0xd9, 0xa6, 0x1b, + 0xd4, 0x6d, 0xaf, 0x5b, 0x14, 0x68, 0xfd, 0x96, 0x5d, 0x0d, 0xad, 0x46, + 0x03, 0xf8, 0xd7, 0x13, 0x1d, 0xf3, 0x47, 0xbe, 0x46, 0x3d, 0xc7, 0xdd, + 0xa9, 0x60, 0x05, 0x15, 0xef, 0x9d, 0xa4, 0xb8, 0xde, 0xf2, 0x41, 0xe2, + 0x07, 0x1d, 0xcb, 0xe8, 0xf3, 0x9c, 0x9c, 0x5e, 0xcd, 0xec, 0x53, 0x39, + 0xf2, 0x62, 0x3b, 0x69, 0x3a, 0x29, 0xc7, 0xb3, 0x57, 0xce, 0x58, 0xd6, + 0x55, 0xf8, 0xc2, 0xf1, 0x16, 0xf3, 0x33, 0x3f, 0xf2, 0xaa, 0x63, 0x42, + 0x27, 0x01, 0x22, 0x5a, 0x1e, 0x8d, 0xa5, 0x33, 0x34, 0x29, 0x12, 0xf6, + 0x07, 0x22, 0xfd, 0xbb, 0x72, 0x60, 0x2a, 0xf5, 0xec, 0x71, 0xfe, 0xd7, + 0xc1, 0xf5, 0xdf, 0x97, 0x3e, 0x4a, 0x9a, 0x97, 0x6f, 0x56, 0xf1, 0xd4, + 0xba, 0x29, 0x09, 0x46, 0x3f, 0x10, 0xdc, 0x2d, 0xb2, 0x04, 0x32, 0x38, + 0xa3, 0xc7, 0x75, 0x95, 0x16, 0xd6, 0x12, 0x44, 0x7a, 0xd3, 0x18, 0xb3, + 0x51, 0x72, 0x63, 0xb8, 0xae, 0x9b, 0xf1, 0xec, 0x17, 0xe4, 0x2d, 0xed, + 0x29, 0x05, 0x63, 0xd7, 0x01, 0xf4, 0xf5, 0xc1, 0x6d, 0x13, 0x5f, 0x5c, + 0x73, 0x11, 0xc9, 0x53, 0xf4, 0xda, 0x90, 0xa2, 0x1c, 0x0b, 0x1d, 0x37, + 0x28, 0xa1, 0x06, 0x65, 0xd3, 0x49, 0x5d, 0x07, 0x1f, 0x93, 0xa9, 0x98, + 0xc5, 0xa5, 0x13, 0xc5, 0xac, 0xda, 0x64, 0x25, 0x77, 0x9a, 0xd5, 0xa9, + 0xe9, 0x3a, 0x77, 0x62, 0xac, 0xf2, 0x76, 0xf4, 0x03, 0xb6, 0x03, 0x6e, + 0xef, 0x97, 0x13, 0x1c, 0xd1, 0xb9, 0x73, 0x12, 0xf7, 0x10, 0xbd, 0x1c, + 0xa1, 0xe7, 0xed, 0xd7, 0xa0, 0xd7, 0x53, 0xa1, 0x21, 0xf1, 0x5f, 0x1e, + 0xec, 0x36, 0x0d, 0x2c, 0xce, 0x74, 0x4a, 0x0c, 0x97, 0x5a, 0x76, 0x62, + 0x18, 0x9c, 0xc3, 0xc1, 0xc4, 0x5e, 0xf1, 0xfa, 0xe6, 0x4b, 0x15, 0xda, + 0xfa, 0xfd, 0xe9, 0x98, 0x09, 0xc3, 0x67, 0x63, 0x1f, 0x28, 0x37, 0xf0, + 0x59, 0x4b, 0x4b, 0xa3, 0xd1, 0x41, 0x94, 0xa6, 0x05, 0xb0, 0x93, 0xee, + 0x41, 0xa4, 0xce, 0xee, 0xea, 0xc4, 0x43, 0x6e, 0xab, 0x65, 0x70, 0xe3, + 0x4d, 0xf1, 0x02, 0xf5, 0x0f, 0xd5, 0x5e, 0xfd, 0x03, 0xcd, 0x22, 0x27, + 0x90, 0xf4, 0x98, 0xa2, 0xc0, 0xb4, 0xd5, 0x04, 0xfa, 0x75, 0x22, 0x4c, + 0xe7, 0xdd, 0xef, 0x3a, 0x1d, 0xb6, 0x00, 0x58, 0xcd, 0x5a, 0xbc, 0x12, + 0xea, 0x5a, 0xda, 0xa9, 0x18, 0x0e, 0xff, 0x51, 0xc4, 0xaf, 0xc8, 0x95, + 0xfb, 0x92, 0xdf, 0x99, 0xc9, 0x4e, 0xfe, 0xb1, 0xb0, 0xca, 0xa1, 0xba, + 0x90, 0xc8, 0x07, 0x34, 0x52, 0x6d, 0xd8, 0x05, 0x72, 0x2e, 0xee, 0x98, + 0xc0, 0x1e, 0x25, 0xb3, 0xa2, 0xb4, 0x9c, 0xa5, 0xdc, 0xd3, 0xb1, 0xdf, + 0x17, 0xd9, 0xda, 0xe9, 0x5d, 0x41, 0xca, 0xc7, 0xe4, 0x94, 0x0d, 0x67, + 0xba, 0x9c, 0xcf, 0x52, 0xf0, 0x00, 0x54, 0xe0, 0xbd, 0x3c, 0xc7, 0xb9, + 0x6a, 0x11, 0xc6, 0xd1, 0x62, 0xc3, 0xcf, 0xc2, 0x6a, 0x44, 0xeb, 0x41, + 0x43, 0x54, 0xe2, 0xf5, 0xc4, 0x11, 0xd7, 0x6a, 0xf2, 0x76, 0xa9, 0x16, + 0xae, 0xe2, 0x11, 0xfb, 0x04, 0x3d, 0xee, 0xd1, 0x98, 0x30, 0x0b, 0x6b, + 0x8a, 0x6f, 0x45, 0xb7, 0x01, 0x64, 0x46, 0x32, 0x61, 0xd5, 0x05, 0xfa, + 0xb1, 0x14, 0x54, 0x39, 0x13, 0x9b, 0xd5, 0x1d, 0x5c, 0xad, 0xd0, 0x5e, + 0x6d, 0xb3, 0xa1, 0xb3, 0xc5, 0x8d, 0xf8, 0x12, 0xd9, 0x5f, 0x94, 0x27, + 0xdf, 0x30, 0xc8, 0x0e, 0x3a, 0x46, 0x70, 0x5c, 0x4c, 0xaa, 0x24, 0xc3, + 0x50, 0x62, 0x52, 0xc8, 0x63, 0x64, 0xc9, 0x49, 0x74, 0x1c, 0xd2, 0x49, + 0x0f, 0x20, 0x69, 0x53, 0x97, 0x34, 0xc0, 0x92, 0x48, 0x28, 0x7b, 0x64, + 0xca, 0xea, 0x07, 0x6c, 0x63, 0x3e, 0xb6, 0xdb, 0xd5, 0x52, 0x9d, 0x7a, + 0x5f, 0x46, 0xc1, 0xb9, 0x3e, 0xe2, 0xe9, 0xeb, 0x04, 0x65, 0xc0, 0x74, + 0x4b, 0x07, 0x6a, 0x19, 0x4a, 0x9d, 0x05, 0xa0, 0xba, 0xae, 0x74, 0xef, + 0x62, 0x09, 0x57, 0x36, 0xe5, 0x9c, 0x54, 0x59, 0x3d, 0x04, 0xf0, 0xfb, + 0x6f, 0x89, 0x13, 0x1f, 0x1f, 0x88, 0x03, 0x6b, 0x0c, 0xeb, 0x53, 0xac, + 0x3a, 0x18, 0xa4, 0x93, 0xcc, 0x4f, 0xf5, 0x92, 0x44, 0x23, 0x9e, 0x67, + 0xf0, 0xf5, 0x2f, 0xb9, 0xc9, 0x34, 0x76, 0x97, 0x1d, 0x94, 0x75, 0x3f, + 0x47, 0x97, 0xe0, 0x30, 0xcc, 0xff, 0xd2, 0x7a, 0x3b, 0x04, 0xa7, 0xa5, + 0x62, 0x9e, 0xe4, 0x8f, 0xd8, 0x62, 0xee, 0x1d, 0x1c, 0xff, 0xad, 0x18, + 0xc9, 0x66, 0x47, 0x36, 0xfb, 0x2e, 0x74, 0x2a, 0xe7, 0x5f, 0xb2, 0x12, + 0xd2, 0x9e, 0xae, 0x2b, 0x92, 0xb8, 0x53, 0x66, 0x22, 0x5c, 0xa8, 0xaf, + 0x4f, 0x29, 0xab, 0x64, 0x50, 0x09, 0xe9, 0x2f, 0x2e, 0x62, 0x2e, 0x0e, + 0x8a, 0xd6, 0xeb, 0xa7, 0x5d, 0x3e, 0x9e, 0xe1, 0x39, 0x52, 0x13, 0x57, + 0x54, 0x5c, 0x78, 0xed, 0xb3, 0xfc, 0x5f, 0xa1, 0xf3, 0x2a, 0x77, 0x90, + 0xa9, 0x09, 0xa1, 0x05, 0x3b, 0xa9, 0x6a, 0xf5, 0xc4, 0xfa, 0x97, 0x79, + 0x64, 0x57, 0x1a, 0xf1, 0x74, 0xe5, 0x16, 0x93, 0xa9, 0xef, 0xe6, 0xdf, + 0x36, 0xd2, 0xd0, 0xe6, 0xb8, 0xdd, 0xe9, 0x13, 0x4c, 0xcd, 0x22, 0x98, + 0xc1, 0x94, 0xbb, 0x04, 0x2a, 0x4a, 0x69, 0x10, 0x5a, 0xcb, 0x1d, 0x9e, + 0xc4, 0x3d, 0x6d, 0x0e, 0xe0, 0x12, 0xb4, 0xe1, 0x6c, 0x55, 0x6f, 0xa3, + 0xf5, 0x1b, 0x0c, 0xe5, 0x1c, 0x99, 0x8b, 0x23, 0x23, 0xbc, 0x33, 0xe4, + 0xd4, 0x15, 0xfd, 0xcc, 0x90, 0x87, 0xb5, 0x0e, 0x24, 0xba, 0x20, 0x1b, + 0xcf, 0x67, 0x98, 0x1a, 0x35, 0xe7, 0xc3, 0x95, 0x29, 0xd6, 0xd2, 0x4f, + 0xe4, 0x14, 0xd5, 0xa1, 0x93, 0xff, 0x24, 0x0e, 0xfc, 0xb7, 0xd6, 0xde, + 0x05, 0xc5, 0x2f, 0xaa, 0x92, 0xd4, 0xd8, 0xac, 0x8f, 0x67, 0x45, 0xdb, + 0x36, 0x19, 0x15, 0x09, 0x9a, 0x3f, 0x2a, 0x56, 0xd5, 0xa9, 0x26, 0xb6, + 0xcb, 0x19, 0xf3, 0x6a, 0xbb, 0xba, 0xba, 0xa3, 0x68, 0x90, 0x0f, 0xb1, + 0x98, 0x14, 0x33, 0xd8, 0x12, 0xdf, 0xef, 0xe5, 0x01, 0x93, 0xab, 0xf8, + 0x93, 0x40, 0xbd, 0xa0, 0x01, 0x34, 0x54, 0xfd, 0xa0, 0xc4, 0xc3, 0xf3, + 0x6b, 0x90, 0x30, 0xc1, 0xbe, 0xd8, 0xbb, 0xab, 0x71, 0xaa, 0xe5, 0x3b, + 0x2d, 0x5d, 0x6e, 0x00, 0x34, 0xa8, 0x02, 0x34, 0xa9, 0x67, 0x95, 0xcd, + 0xed, 0xa2, 0x25, 0x55, 0xc9, 0x03, 0x1c, 0x30, 0xe7, 0xdf, 0xe6, 0xe7, + 0x2b, 0x5a, 0x9a, 0xcd, 0xa8, 0xf0, 0x4e, 0xe4, 0xd7, 0x90, 0x5f, 0x4e, + 0xbf, 0x5d, 0x68, 0x12, 0x1c, 0x4c, 0x68, 0x03, 0x9c, 0x49, 0xcb, 0xe6, + 0xc4, 0xfd, 0xad, 0xd5, 0xa8, 0xd8, 0xda, 0x2f, 0x13, 0xbc, 0x42, 0x61, + 0xa5, 0x0a, 0x1a, 0xe9, 0x5e, 0x5c, 0x01, 0x7c, 0xca, 0x73, 0x6f, 0x32, + 0xc1, 0x96, 0x24, 0x9d, 0x12, 0x20, 0x11, 0x6a, 0xf6, 0xbc, 0xff, 0x6a, + 0xc1, 0x58, 0x0d, 0xb9, 0xad, 0xc5, 0xde, 0x69, 0x37, 0xbe, 0xd9, 0x93, + 0xcc, 0x2b, 0xe9, 0x13, 0x45, 0xa0, 0x6c, 0x3f, 0x44, 0x34, 0xaf, 0x43, + 0x6d, 0xae, 0xef, 0xb2, 0x65, 0x03, 0xc1, 0xef, 0x10, 0x1e, 0xd8, 0x6e, + 0xb5, 0xb9, 0x03, 0xd8, 0x6e, 0x2f, 0x53, 0xe6, 0xc0, 0xaf, 0x44, 0xd2, + 0xd8, 0x15, 0x56, 0x15, 0x59, 0xd6, 0xd4, 0xe4, 0x1a, 0x25, 0xd5, 0xcf, + 0xe7, 0x6a, 0x55, 0xd4, 0xf8, 0x42, 0x4c, 0xcb, 0x9a, 0x48, 0x4d, 0x27, + 0x61, 0x4c, 0x36, 0x2b, 0xcb, 0x10, 0xba, 0xf7, 0xe3, 0x23, 0x27, 0xc5, + 0x6a, 0x1b, 0x94, 0x69, 0x64, 0xb1, 0x8c, 0xdb, 0xd4, 0x0d, 0x32, 0x3e, + 0x58, 0x73, 0xa8, 0x2f, 0x3d, 0x22, 0xd9, 0x0d, 0x2a, 0x52, 0xf0, 0xdd, + 0xeb, 0x21, 0x42, 0xc7, 0x59, 0x96, 0x09, 0x93, 0x5a, 0x70, 0xc3, 0x21, + 0x5f, 0xce, 0xc2, 0xdd, 0xcf, 0x61, 0xed, 0x1c, 0xfb, 0x2f, 0x57, 0xf7, + 0x31, 0xb8, 0x3e, 0x92, 0x29, 0xd4, 0x47, 0x6a, 0x19, 0x66, 0x00, 0xc2, + 0xc4, 0x6c, 0xb5, 0xc5, 0x68, 0x24, 0xa8, 0x64, 0x26, 0x72, 0x43, 0x20, + 0x9f, 0xf1, 0x3f, 0xac, 0x64, 0xb5, 0x12, 0x26, 0x13, 0x76, 0x52, 0x05, + 0xda, 0x57, 0xe3, 0x53, 0x73, 0x30, 0x21, 0x27, 0x75, 0x8d, 0x37, 0xd1, + 0x77, 0x40, 0x97, 0x2a, 0xb7, 0x0b, 0x2e, 0x9e, 0x4c, 0x36, 0x75, 0x44, + 0x15, 0xdb, 0x96, 0x70, 0xf9, 0x33, 0x9a, 0x1e, 0x6e, 0x13, 0x05, 0x38, + 0x2c, 0xbf, 0x0a, 0xdd, 0x2b, 0x2b, 0x38, 0x77, 0xa9, 0x00, 0x2d, 0x5e, + 0xee, 0x4b, 0xf3, 0x20, 0x7a, 0x90, 0x97, 0x44, 0xdf, 0x55, 0xfd, 0x50, + 0xe3, 0x24, 0x25, 0xa9, 0xd9, 0x3f, 0x6d, 0x09, 0x32, 0x67, 0xb5, 0x43, + 0xf1, 0xc7, 0xa7, 0xfb, 0x92, 0xde, 0xc3, 0xbf, 0x64, 0x6b, 0x35, 0xda, + 0x08, 0x94, 0x68, 0xb0, 0xc8, 0x3f, 0xb5, 0x9f, 0x15, 0x05, 0xff, 0x6c, + 0xbc, 0x22, 0x61, 0xf4, 0x67, 0xf8, 0x1f, 0x2e, 0x91, 0xc8, 0x12, 0xdc, + 0xcb, 0x22, 0x05, 0xb8, 0xab, 0x0d, 0x0e, 0xd7, 0x04, 0x8e, 0x32, 0x0e, + 0xfe, 0x72, 0x79, 0xc3, 0xba, 0xd8, 0x68, 0x3e, 0x5d, 0xab, 0xa0, 0xf8, + 0x26, 0x57, 0xe4, 0x20, 0x91, 0x0a, 0xde, 0x52, 0x95, 0xbc, 0xb7, 0x71, + 0x50, 0xe4, 0x3f, 0x07, 0x4c, 0xa8, 0x6a, 0xb6, 0xa0, 0x95, 0xe2, 0x31, + 0x8f, 0x5f, 0xfa, 0xdd, 0xee, 0x02, 0x23, 0x56, 0xf1, 0xdd, 0x1a, 0xa6, + 0xa0, 0x2d, 0x46, 0x36, 0x6c, 0x79, 0xe8, 0x67, 0x43, 0xdd, 0xe7, 0x2e, + 0x25, 0xda, 0x35, 0x6f, 0x63, 0xf1, 0x2c, 0x6c, 0x61, 0xaa, 0xb7, 0x51, + 0x91, 0xa1, 0x7c, 0x54, 0x9a, 0xf6, 0x3c, 0x3f, 0xa8, 0xba, 0x4d, 0xee, + 0xb6, 0xab, 0xa5, 0x05, 0xc6, 0xb6, 0xe8, 0x2f, 0x1b, 0x99, 0xb0, 0x45, + 0x3e, 0xc3, 0x50, 0x26, 0x0b, 0x10, 0x61, 0x5a, 0xc6, 0x25, 0x2d, 0x07, + 0xb6, 0x28, 0x59, 0xf3, 0xb4, 0x02, 0x61, 0xa0, 0xd0, 0x0a, 0xae, 0xd6, + 0x3c, 0xcc, 0x5f, 0xfb, 0xc0, 0xfd, 0xeb, 0x7b, 0xe2, 0x66, 0xc5, 0x98, + 0x70, 0x50, 0x31, 0x3a, 0x12, 0x45, 0xf4, 0x1c, 0xba, 0xa6, 0x92, 0x51, + 0xae, 0x68, 0xec, 0xb0, 0x1a, 0xd9, 0x45, 0x00, 0xd6, 0x9e, 0xad, 0x64, + 0xfe, 0xd9, 0xfb, 0xcc, 0x57, 0xff, 0x9e, 0xa3, 0x71, 0xe7, 0x7a, 0xaf, + 0x26, 0x31, 0x31, 0x6a, 0x41, 0xa4, 0x4d, 0x68, 0xbc, 0xcb, 0xfa, 0xb4, + 0x3a, 0x1c, 0x3a, 0x8f, 0xcd, 0xc1, 0x95, 0xb2, 0x46, 0x72, 0xf7, 0xfc, + 0x20, 0xe2, 0x2f, 0x0f, 0xbd, 0x74, 0xe1, 0x2a, 0xd5, 0xf6, 0xe9, 0xe1, + 0x45, 0x7d, 0x95, 0xb0, 0x49, 0xce, 0xe8, 0x53, 0x69, 0x46, 0x9d, 0x03, + 0x5f, 0x15, 0x2e, 0x92, 0x4c, 0xb7, 0xf1, 0x43, 0x67, 0x8a, 0x43, 0xc6, + 0x90, 0xec, 0xb5, 0x5d, 0xd5, 0x64, 0x16, 0x6e, 0xf0, 0xad, 0x4e, 0xf0, + 0x56, 0xe8, 0x77, 0xd5, 0x47, 0x47, 0x41, 0xc9, 0x98, 0x3a, 0xcb, 0xe0, + 0x01, 0x77, 0x93, 0x15, 0xe0, 0xd3, 0x93, 0xbe, 0xe1, 0x97, 0xe0, 0x21, + 0x60, 0x2b, 0xf1, 0x4a, 0x62, 0x29, 0x11, 0xe9, 0x61, 0x55, 0xc4, 0x57, + 0x04, 0xa8, 0xb3, 0xb3, 0x61, 0xd7, 0xa6, 0xce, 0x50, 0xd2, 0xc3, 0x38, + 0xda, 0xc2, 0x23, 0x67, 0x37, 0x09, 0xa7, 0xfd, 0x29, 0xdc, 0xcc, 0x52, + 0x65, 0xea, 0x3f, 0xcc, 0x67, 0x5e, 0x3b, 0xd4, 0x59, 0x59, 0x12, 0x9b, + 0xf1, 0xd2, 0x43, 0x46, 0x54, 0xcd, 0xb9, 0xbe, 0x71, 0xb6, 0x6d, 0x6a, + 0x62, 0xc5, 0x59, 0xc1, 0x21, 0xf7, 0x4c, 0x91, 0x64, 0xe0, 0xd7, 0xd9, + 0x34, 0x60, 0x0d, 0xb2, 0x93, 0xd8, 0xd3, 0x01, 0x8b, 0xf3, 0x9c, 0x6c, + 0xff, 0x63, 0xca, 0xd2, 0xf4, 0x76, 0xe3, 0x60, 0x52, 0x5c, 0x0e, 0xa3, + 0x13, 0xc8, 0xd9, 0xa7, 0x13, 0x6d, 0x1b, 0x29, 0xc0, 0xb1, 0x54, 0x31, + 0x33, 0x55, 0x44, 0x0a, 0x0a, 0x96, 0x3f, 0xf0, 0xb2, 0x64, 0x23, 0xa1, + 0xc8, 0x08, 0x01, 0x94, 0x2f, 0xc8, 0x0a, 0xfb, 0x93, 0x38, 0xe4, 0xc1, + 0xd9, 0xea, 0x46, 0x96, 0xdd, 0x5d, 0x62, 0xfc, 0xb0, 0x4d, 0x17, 0xe8, + 0xa0, 0xd4, 0x35, 0x98, 0x65, 0xb0, 0x27, 0x97, 0xbc, 0xe8, 0x48, 0x38, + 0x90, 0x9b, 0x6e, 0xf1, 0xd2, 0x17, 0x1b, 0xbf, 0x03, 0xc6, 0xa3, 0x42, + 0xaf, 0xdc, 0x44, 0x9d, 0x9e, 0x69, 0x67, 0x33, 0x61, 0xfb, 0x96, 0xfa, + 0xff, 0xf4, 0xa8, 0x3c, 0xb6, 0x42, 0xd2, 0x4c, 0xc0, 0xa8, 0x2a, 0x4b, + 0x37, 0x78, 0x41, 0x94, 0xf6, 0x04, 0xb9, 0x54, 0xe4, 0x2b, 0xfc, 0xed, + 0xf5, 0xf7, 0x62, 0x23, 0x44, 0xc4, 0xd7, 0x5a, 0xeb, 0xc2, 0x3d, 0x4c, + 0x41, 0x22, 0xa0, 0xe3, 0x22, 0xbc, 0x91, 0x69, 0x37, 0x3f, 0x94, 0xfd, + 0x07, 0xa7, 0x6e, 0x53, 0x27, 0xdc, 0xb0, 0x14, 0x8d, 0x0a, 0x08, 0x31, + 0xba, 0xf0, 0xd0, 0xda, 0xa6, 0x7a, 0xc0, 0x4c, 0x9d, 0x3b, 0x8f, 0xee, + 0x11, 0xc7, 0x9f, 0xc9, 0xcc, 0x4c, 0x26, 0x51, 0xb4, 0x10, 0xde, 0xc2, + 0xa3, 0xe0, 0xaa, 0x7c, 0x9c, 0x27, 0x8d, 0x04, 0x8e, 0xfc, 0xe4, 0x68, + 0x93, 0xf9, 0x67, 0x28, 0xa0, 0xe6, 0xca, 0xbd, 0x5a, 0x64, 0x98, 0x9f, + 0xe3, 0x7b, 0x16, 0x5d, 0x61, 0xcc, 0x4c, 0x64, 0x04, 0x1b, 0xcc, 0xa6, + 0xa2, 0x31, 0x28, 0xa2, 0xac, 0xd0, 0xce, 0x40, 0x19, 0xe7, 0xf9, 0xea, + 0xc5, 0x98, 0x50, 0x16, 0x38, 0xad, 0x58, 0x21, 0x2e, 0x10, 0x48, 0x4f, + 0xe7, 0xc0, 0xc0, 0x6c, 0xcd, 0xe2, 0xc3, 0xcd, 0xc5, 0xfc, 0x26, 0x91, + 0xea, 0xcf, 0x52, 0x97, 0x9f, 0xdc, 0x2c, 0x45, 0xd8, 0x50, 0xf8, 0x75, + 0xa2, 0x93, 0x52, 0x2b, 0x23, 0xd3, 0x30, 0x9d, 0xa7, 0xf7, 0xbb, 0xc2, + 0xd2, 0xb7, 0x9d, 0xec, 0xf9, 0x9a, 0xec, 0x3e, 0xc0, 0xce, 0x64, 0xb8, + 0xf5, 0x41, 0x4e, 0x06, 0xa1, 0x25, 0xf2, 0x40, 0xee, 0x07, 0xec, 0x6d, + 0x9a, 0xd0, 0x5c, 0xdd, 0xe9, 0xf5, 0x56, 0xf9, 0x2e, 0xf5, 0xdb, 0x69, + 0xc9, 0x3e, 0xb5, 0x0c, 0xbc, 0x29, 0xa4, 0xa9, 0x55, 0x9b, 0xf6, 0xab, + 0x1f, 0x55, 0x9d, 0x25, 0xd2, 0xde, 0x3f, 0xa0, 0xe5, 0x1c, 0xb3, 0x90, + 0x2f, 0x6c, 0xaf, 0xb5, 0x6d, 0x23, 0x15, 0xab, 0x91, 0x55, 0x5f, 0x02, + 0x20, 0x22, 0x8e, 0xc1, 0x4a, 0x63, 0xa6, 0x5e, 0x85, 0x99, 0x58, 0xdc, + 0xde, 0xb0, 0x76, 0x9f, 0x21, 0x4d, 0xe9, 0x47, 0xcc, 0x3f, 0x02, 0x91, + 0x75, 0x67, 0xe5, 0x6a, 0x2c, 0xc3, 0x69, 0x95, 0x2d, 0x74, 0x77, 0xf7, + 0x1d, 0xe1, 0x12, 0x2b, 0xcf, 0x4c, 0x7b, 0xcf, 0xbe, 0x24, 0x1d, 0x07, + 0x34, 0xd3, 0x67, 0xa8, 0xb9, 0x76, 0x2a, 0x3e, 0xfd, 0xb5, 0xcd, 0xf6, + 0x29, 0x07, 0x4e, 0x17, 0xcf, 0x28, 0xdd, 0x90, 0x4b, 0x17, 0x24, 0x55, + 0xdc, 0x78, 0xe5, 0xf4, 0x97, 0x31, 0x3d, 0xfa, 0x96, 0xe2, 0x99, 0x61, + 0xb1, 0xcb, 0xa4, 0x7b, 0x4e, 0x5d, 0x6a, 0xf8, 0xb2, 0x79, 0xfc, 0xa9, + 0xd9, 0x27, 0x46, 0xdd, 0x52, 0xdf, 0x24, 0x66, 0x1c, 0xa6, 0xbc, 0x18, + 0x13, 0x72, 0x38, 0x53, 0xac, 0x1b, 0x67, 0x1f, 0x30, 0xae, 0x5a, 0xf3, + 0x55, 0xd0, 0xe1, 0x23, 0x9a, 0x46, 0xa4, 0xbb, 0x68, 0x73, 0x30, 0xda, + 0xb7, 0x3b, 0xff, 0xd1, 0x0d, 0xe0, 0xf7, 0xda, 0x36, 0x3a, 0x7a, 0x19, + 0xf5, 0x2e, 0xf4, 0xda, 0xa4, 0x09, 0x94, 0xb8, 0x18, 0xad, 0x6b, 0xf6, + 0x64, 0xbf, 0x2a, 0x04, 0xc6, 0xde, 0x0f, 0x45, 0x27, 0x3a, 0x3d, 0x61, + 0xf5, 0xde, 0x38, 0x1d, 0x23, 0x23, 0x70, 0x00, 0xfc, 0x0c, 0x5c, 0x96, + 0xc1, 0x21, 0x78, 0x25, 0x24, 0x71, 0xd1, 0xe2, 0xe9, 0x1a, 0x2f, 0x48, + 0x4d, 0x09, 0x24, 0x27, 0xe4, 0xe7, 0x42, 0x76, 0x92, 0x93, 0x7a, 0x62, + 0x76, 0xc6, 0xd7, 0xdf, 0xe4, 0x5e, 0x0e, 0xfc, 0x4e, 0x0a, 0x65, 0x63, + 0x51, 0x90, 0xfd, 0x92, 0x5f, 0x9a, 0x49, 0xa9, 0x6c, 0xb1, 0xb6, 0xe6, + 0xab, 0xf7, 0xb9, 0x39, 0xc0, 0xed, 0x1d, 0x65, 0x9c, 0x24, 0x21, 0xc1, + 0x0d, 0xd6, 0x9a, 0xbe, 0xd4, 0x74, 0xa2, 0x70, 0xab, 0x0b, 0x45, 0xf0, + 0xc9, 0xaa, 0xf1, 0x49, 0x0b, 0x6c, 0x20, 0xdc, 0x37, 0x2b, 0x13, 0x68, + 0x48, 0x0e, 0xd8, 0xd1, 0x67, 0xd8, 0xa3, 0x7e, 0xd7, 0xb7, 0x50, 0xc8, + 0x14, 0x58, 0x6a, 0x04, 0xa5, 0x70, 0x22, 0x2d, 0x41, 0xea, 0x28, 0xb7, + 0xf0, 0xde, 0xc4, 0xe4, 0x5b, 0x4d, 0xc1, 0x33, 0x9e, 0x14, 0x32, 0xa8, + 0x9b, 0xc8, 0xd9, 0x5b, 0x95, 0x2a, 0x91, 0x9d, 0xe8, 0x15, 0x19, 0x9b, + 0x38, 0xf3, 0x35, 0x69, 0x3e, 0xd3, 0x4b, 0xcc, 0xf2, 0x94, 0x5a, 0xaf, + 0x91, 0xa4, 0xa1, 0x03, 0x48, 0x5f, 0x6d, 0x16, 0x56, 0x03, 0x5a, 0xcb, + 0x99, 0x19, 0x45, 0x9c, 0xba, 0xc9, 0xbc, 0x5b, 0x0f, 0xf5, 0xde, 0x70, + 0xa3, 0x70, 0x0d, 0x3f, 0x3e, 0x5c, 0x4d, 0x5a, 0x1a, 0x46, 0x1b, 0x44, + 0x4a, 0x73, 0xfa, 0xb1, 0xc4, 0x42, 0x7b, 0x0c, 0x15, 0x0d, 0x35, 0xc4, + 0xa3, 0xea, 0x17, 0xa0, 0x0b, 0xfb, 0x4d, 0x1b, 0x2f, 0x96, 0x1f, 0xaa, + 0xc0, 0xad, 0xdc, 0xf3, 0xb2, 0xb1, 0x44, 0x1f, 0x39, 0xc7, 0x33, 0x18, + 0xad, 0xe1, 0x50, 0x7d, 0xf9, 0x2a, 0x90, 0xf2, 0x06, 0xce, 0x07, 0xae, + 0x9f, 0xbc, 0x4d, 0xae, 0x30, 0xdd, 0x47, 0xa2, 0xd3, 0x6d, 0x0c, 0xc6, + 0xb7, 0xae, 0xf5, 0x38, 0xa3, 0x00, 0x59, 0x6a, 0x00, 0x04, 0xd2, 0x77, + 0x0a, 0x58, 0xc9, 0xaf, 0x1b, 0x59, 0x29, 0xf3, 0xdd, 0x58, 0xcf, 0xa1, + 0x6d, 0xb4, 0x66, 0x23, 0x9f, 0x9b, 0x41, 0x2a, 0xc8, 0x28, 0x34, 0x77, + 0x3a, 0x1f, 0xa5, 0xde, 0x4b, 0x3f, 0xc7, 0x19, 0xf5, 0xdb, 0x98, 0xc4, + 0x6c, 0x2f, 0x34, 0x20, 0xc9, 0x52, 0x16, 0x60, 0xbc, 0x04, 0xd5, 0xff, + 0x4b, 0x07, 0x28, 0x5a, 0x3a, 0x48, 0x5b, 0x96, 0xee, 0x1f, 0xf1, 0xb4, + 0x9b, 0xb5, 0x64, 0xde, 0x1c, 0xd5, 0x3c, 0x1b, 0x98, 0x11, 0xc7, 0x0b, + 0x97, 0x00, 0x2f, 0x8f, 0xf9, 0x24, 0x4d, 0xba, 0x75, 0x6a, 0xce, 0xd8, + 0x7a, 0xee, 0x02, 0xd5, 0x19, 0xd6, 0x26, 0x40, 0xa7, 0x78, 0x76, 0x1a, + 0x17, 0xc2, 0xe6, 0x5a, 0x6e, 0x24, 0xb1, 0x17, 0xf8, 0x9f, 0xdc, 0x64, + 0xf0, 0x59, 0xc5, 0xfc, 0x4c, 0xbb, 0x3d, 0x3f, 0x70, 0x2c, 0x0d, 0xf5, + 0x6c, 0x96, 0x46, 0x1a, 0x1e, 0x5f, 0xd1, 0x3a, 0x00, 0x9a, 0x9d, 0x63, + 0xe6, 0xd1, 0xa2, 0x5a, 0x4a, 0x50, 0xa8, 0xd5, 0x91, 0x90, 0x69, 0x58, + 0x65, 0x00, 0xc7, 0xf1, 0xa6, 0x45, 0xfd, 0x5a, 0xe6, 0x05, 0x4b, 0xb2, + 0x3a, 0xdf, 0xa9, 0xd9, 0xe5, 0xa6, 0xe5, 0xe2, 0x5b, 0x3b, 0x2f, 0x57, + 0x6c, 0xc4, 0x06, 0xe1, 0x8e, 0x15, 0x98, 0xc8, 0x5e, 0x63, 0xba, 0x37, + 0xe6, 0x91, 0x5f, 0x1c, 0x5b, 0x77, 0xb5, 0x91, 0x07, 0x3a, 0xa6, 0x67, + 0x6d, 0xdf, 0x15, 0x62, 0x6b, 0x3b, 0xed, 0xa2, 0xc7, 0x46, 0x52, 0x8f, + 0xf2, 0x9f, 0x69, 0x00, 0xb8, 0x49, 0xcf, 0xd4, 0xf0, 0x95, 0x51, 0xda, + 0x0f, 0x4e, 0x0d, 0x11, 0x2f, 0x27, 0x73, 0xe9, 0x13, 0xcb, 0xa1, 0xfc, + 0x6b, 0x45, 0xf0, 0xfd, 0xc7, 0x17, 0xaa, 0x0c, 0xac, 0x98, 0xc4, 0x6c, + 0xf0, 0x32, 0x45, 0x67, 0xfe, 0x6f, 0x2e, 0xfb, 0xec, 0x19, 0xda, 0xbd, + 0x93, 0x5f, 0x50, 0xc2, 0x22, 0x9a, 0x3a, 0x5b, 0x31, 0xf5, 0x4e, 0x91, + 0xa6, 0xea, 0x67, 0xdd, 0x69, 0xf4, 0xd7, 0xea, 0x02, 0xbe, 0x55, 0x52, + 0xb9, 0x30, 0x21, 0xe5, 0xfc, 0x9a, 0x93, 0xd6, 0x6c, 0x33, 0x06, 0xb9, + 0xe3, 0xb0, 0x6a, 0xff, 0x9e, 0xc2, 0x5e, 0x1d, 0xd6, 0xdb, 0xa1, 0x60, + 0x34, 0x5d, 0x08, 0xf9, 0xeb, 0xd6, 0x1f, 0x90, 0xf1, 0xf4, 0x07, 0x47, + 0xbf, 0xd9, 0xc9, 0xe8, 0xcf, 0xce, 0xa5, 0x1d, 0xb0, 0xd9, 0xbe, 0xc7, + 0xfb, 0xcc, 0xac, 0x3e, 0x92, 0x59, 0x0d, 0x1d, 0x65, 0x16, 0xa3, 0xdc, + 0x9b, 0x72, 0x22, 0x46, 0x04, 0xca, 0xb3, 0x5a, 0x2f, 0x3d, 0x99, 0x5c, + 0xb5, 0xb9, 0x30, 0xe3, 0xde, 0x8c, 0xba, 0xc7, 0x4c, 0xe5, 0x34, 0x6e, + 0xf4, 0x75, 0xf4, 0x38, 0x01, 0xf1, 0x61, 0xb8, 0x2b, 0xc3, 0x6f, 0xae, + 0xd1, 0x0a, 0x9d, 0x48, 0xc9, 0xe7, 0xc3, 0xe7, 0xc9, 0xe1, 0x6f, 0x96, + 0xa0, 0xc2, 0x91, 0xfd, 0xad, 0x99, 0x48, 0xde, 0xfc, 0xa3, 0x6e, 0xe3, + 0x94, 0x0e, 0xb5, 0xf6, 0x24, 0x8b, 0xce, 0x70, 0x3c, 0xdc, 0xe2, 0x66, + 0x9f, 0xe3, 0x6b, 0xc5, 0xd1, 0x97, 0x38, 0x12, 0x46, 0x37, 0xd6, 0x9a, + 0x4c, 0x6d, 0x4a, 0x2d, 0xc3, 0x28, 0x20, 0x2f, 0x55, 0x67, 0x17, 0x71, + 0xd3, 0x5c, 0xdc, 0xa3, 0x23, 0x60, 0x25, 0x2d, 0xe0, 0xc2, 0xed, 0xee, + 0x67, 0x9f, 0x26, 0xfb, 0x2f, 0x63, 0xf2, 0x6a, 0x23, 0x45, 0x26, 0x2c, + 0x33, 0x8a, 0xf2, 0xd1, 0xb2, 0x77, 0x99, 0x98, 0xd6, 0x18, 0xfe, 0xf3, + 0xff, 0xa4, 0x36, 0x03, 0xf4, 0xf5, 0xb1, 0xca, 0xa3, 0x5f, 0xe2, 0xc6, + 0xb2, 0x55, 0x2c, 0xaa, 0x64, 0xef, 0x28, 0x3a, 0x9e, 0x98, 0x01, 0x57, + 0x49, 0x98, 0x61, 0x4f, 0x42, 0x57, 0x00, 0x19, 0xb9, 0xa8, 0xec, 0xed, + 0x2b, 0x63, 0xf3, 0x0c, 0x3a, 0x1f, 0x10, 0xab, 0xe9, 0x6e, 0x61, 0x69, + 0xd1, 0x2d, 0xf3, 0x1f, 0xaa, 0x00, 0x57, 0xe2, 0xab, 0x74, 0xcd, 0xff, + 0x97, 0x2c, 0x3b, 0x67, 0xae, 0xa3, 0xfc, 0x69, 0xa9, 0x4e, 0x42, 0x07, + 0xfc, 0xbf, 0x36, 0x1a, 0xef, 0x6d, 0x6d, 0x14, 0x61, 0x30, 0x27, 0x98, + 0xfa, 0xf8, 0xc9, 0x70, 0xb4, 0xaa, 0x53, 0x48, 0x72, 0x3f, 0x58, 0x69, + 0x8d, 0x08, 0xc8, 0x09, 0x2b, 0xfc, 0x1d, 0xa1, 0x92, 0xae, 0x62, 0xa0, + 0xea, 0x05, 0x40, 0xac, 0x9c, 0xaf, 0x0e, 0xf4, 0x1e, 0x45, 0x33, 0xee, + 0x31, 0x39, 0x08, 0x4b, 0x54, 0x02, 0x2d, 0x03, 0x1c, 0xe6, 0x2d, 0x0c, + 0xd0, 0x92, 0x44, 0xd6, 0xa1, 0x57, 0x4e, 0x17, 0xde, 0xe6, 0x4f, 0x6a, + 0x07, 0x9f, 0x58, 0xe2, 0x27, 0xdb, 0xa9, 0x0c, 0x19, 0x56, 0xa3, 0xb4, + 0xc4, 0xe8, 0xa3, 0x52, 0x9f, 0x6a, 0xc9, 0xb1, 0xda, 0xe9, 0xef, 0x12, + 0xc1, 0x6d, 0x5b, 0x04, 0x20, 0x93, 0xac, 0xf4, 0x38, 0x95, 0xdb, 0x50, + 0xa6, 0x2e, 0x5c, 0x3f, 0x2d, 0x32, 0x50, 0x03, 0x73, 0x64, 0x3a, 0xd5, + 0xfd, 0x98, 0x1c, 0x57, 0xc3, 0xe7, 0xf7, 0x14, 0x13, 0x15, 0x2a, 0xa2, + 0x5f, 0xa0, 0x67, 0xdd, 0x67, 0x00, 0x09, 0xc6, 0xfe, 0xad, 0x06, 0x4c, + 0x5e, 0x9a, 0x5b, 0x55, 0x06, 0x8c, 0x9a, 0x2a, 0x51, 0x0e, 0x4f, 0x15, + 0xcc, 0xe1, 0x53, 0x9c, 0x43, 0x37, 0xc1, 0x3e, 0x02, 0x4b, 0x98, 0x6f, + 0x9b, 0x60, 0x31, 0x2c, 0x2b, 0x9d, 0xda, 0xe0, 0x1d, 0xe4, 0x49, 0x66, + 0x65, 0x18, 0xfb, 0x24, 0x97, 0xe0, 0x2d, 0xf5, 0x44, 0x23, 0x09, 0x01, + 0xf9, 0xf5, 0x29, 0xff, 0x01, 0x36, 0xb9, 0x0e, 0x9b, 0xb3, 0x23, 0x1e, + 0xe5, 0x12, 0xbb, 0x3a, 0x04, 0x14, 0xb8, 0x23, 0x43, 0x95, 0xc1, 0x9d, + 0x57, 0x45, 0x46, 0x4c, 0x8f, 0x35, 0x25, 0x5f, 0x2b, 0xd9, 0xc6, 0xdd, + 0x61, 0xb8, 0xbb, 0x4d, 0x49, 0xef, 0x6e, 0x0c, 0x50, 0x07, 0xc9, 0x9b, + 0x2e, 0xb7, 0xbe, 0x23, 0xc3, 0xcf, 0x9d, 0xeb, 0x13, 0xc8, 0xeb, 0x72, + 0x51, 0x71, 0x69, 0x35, 0xf3, 0xce, 0x35, 0x45, 0x02, 0xba, 0x44, 0x5d, + 0xaf, 0xd0, 0xe5, 0x1d, 0x9b, 0x18, 0xbb, 0x62, 0xce, 0xaf, 0x40, 0x48, + 0x40, 0x2a, 0x5d, 0xcd, 0xa7, 0x2b, 0x8f, 0xf4, 0x4a, 0x4c, 0xe1, 0x59, + 0x40, 0x63, 0x33, 0xae, 0xd8, 0x9d, 0x4d, 0x11, 0x3d, 0x2d, 0x11, 0xc6, + 0x8c, 0xa9, 0xab, 0xa2, 0x08, 0xb8, 0xbf, 0x09, 0x66, 0xbc, 0xd7, 0xab, + 0xce, 0x0d, 0xe0, 0x9e, 0x51, 0x2f, 0x5c, 0xc7, 0x21, 0xb9, 0xcf, 0xc4, + 0x8b, 0xc0, 0x4b, 0x04, 0x1b, 0xfd, 0x43, 0xcf, 0xa4, 0x72, 0x62, 0x04, + 0x0b, 0x1f, 0x9f, 0x35, 0x9d, 0xa9, 0x19, 0x71, 0x06, 0xda, 0x03, 0x0f, + 0xcc, 0x3a, 0xf4, 0x3a, 0xaf, 0x07, 0x0f, 0xf2, 0x3e, 0x4a, 0xd3, 0x41, + 0x6a, 0x90, 0x35, 0x39, 0x4c, 0x1d, 0x2f, 0x05, 0xff, 0xcf, 0xc0, 0xbe, + 0x0f, 0xaf, 0x90, 0x4e, 0x45, 0x8c, 0x78, 0x4d, 0x6b, 0xf2, 0x47, 0x26, + 0xe9, 0x0d, 0xee, 0xd3, 0x97, 0x44, 0xaf, 0x6f, 0x95, 0x30, 0x9c, 0x08, + 0xe5, 0x18, 0x9e, 0xad, 0xd2, 0x2a, 0x0c, 0x21, 0x67, 0x50, 0x28, 0x4f, + 0x31, 0x9c, 0xee, 0xb2, 0x95, 0xbd, 0xef, 0xc0, 0xd0, 0x0d, 0xd4, 0x6e, + 0xff, 0x93, 0x12, 0xc3, 0x51, 0x41, 0xe4, 0x6c, 0x19, 0x09, 0xd7, 0x0a, + 0xe0, 0xea, 0x0a, 0xe7, 0xa8, 0x4b, 0x60, 0xd6, 0x0c, 0x4d, 0xb5, 0x29, + 0x01, 0x74, 0xf9, 0x40, 0x8c, 0x6b, 0x11, 0xf6, 0xe4, 0xc9, 0x3c, 0x1a, + 0xf7, 0xce, 0x2c, 0xd8, 0xe3, 0x0e, 0xc5, 0xb9, 0x6c, 0x40, 0x44, 0xc9, + 0x04, 0xf6, 0x5c, 0xe1, 0x9f, 0xc7, 0xe0, 0x68, 0xe7, 0x6a, 0x92, 0xe7, + 0xb2, 0x12, 0x72, 0x3f, 0xfd, 0xc3, 0x06, 0xeb, 0x0a, 0xab, 0x6d, 0xad, + 0x03, 0x0b, 0x5d, 0xcc, 0x49, 0x04, 0x52, 0x19, 0xd4, 0x9d, 0x67, 0xbf, + 0xd3, 0xf4, 0x22, 0x76, 0x99, 0x52, 0xf5, 0xb5, 0x15, 0x38, 0x58, 0x57, + 0x9a, 0xa2, 0xd1, 0xbb, 0x3a, 0x07, 0xe2, 0xd6, 0x8d, 0x69, 0x9e, 0x5c, + 0xf4, 0xba, 0xda, 0x4a, 0x4d, 0x73, 0xdc, 0x32, 0xfd, 0xe1, 0x3a, 0x16, + 0xf1, 0x09, 0x26, 0x3b, 0x2a, 0xa9, 0xa7, 0x2c, 0xd3, 0xcf, 0x6b, 0xc5, + 0xb5, 0xbc, 0x71, 0xb6, 0x9e, 0xa0, 0x6a, 0x69, 0xa5, 0xeb, 0x54, 0x87, + 0xe9, 0x4f, 0x69, 0x39, 0xc5, 0x54, 0x28, 0x55, 0xb9, 0xff, 0x5d, 0x9e, + 0x17, 0x8e, 0x8c, 0xd5, 0x14, 0x5c, 0xa7, 0x33, 0x5a, 0x2f, 0x2d, 0x37, + 0x0e, 0xf2, 0x54, 0x64, 0x9d, 0xdf, 0x49, 0xab, 0xd3, 0x0f, 0xbd, 0xad, + 0x19, 0xb9, 0xcf, 0x0f, 0x40, 0x62, 0x4b, 0x93, 0xd7, 0xf4, 0x3b, 0xee, + 0x2b, 0x97, 0xe3, 0x55, 0xb3, 0x5b, 0x3f, 0x93, 0xa5, 0xf1, 0x40, 0x99, + 0xa1, 0x69, 0xbd, 0xf3, 0xf0, 0xb1, 0x6e, 0x5c, 0xba, 0x4a, 0xc4, 0x51, + 0x8e, 0xe1, 0x5c, 0xb8, 0x92, 0xb5, 0x43, 0xc4, 0x9e, 0x38, 0x0d, 0xfb, + 0x60, 0xb3, 0xe6, 0x0f, 0x55, 0x94, 0x01, 0xaf, 0xaa, 0xc3, 0x6d, 0xea, + 0xb2, 0xfc, 0xb0, 0x06, 0x29, 0x0f, 0xd3, 0x95, 0xb9, 0xf1, 0x8b, 0xce, + 0xd3, 0x5d, 0x16, 0xbf, 0x5c, 0x24, 0xc5, 0x36, 0x98, 0x8c, 0x5b, 0x43, + 0xe7, 0xfe, 0x77, 0xda, 0xc5, 0xd8, 0xf6, 0x72, 0xba, 0xcf, 0x9c, 0x18, + 0x58, 0xb8, 0xe4, 0x1d, 0xf6, 0xfb, 0x3b, 0xb4, 0x1f, 0xea, 0xa3, 0xe3, + 0xd5, 0xbe, 0x3f, 0xd5, 0xf9, 0xc4, 0x00, 0x8e, 0x17, 0x22, 0x3d, 0x96, + 0xd8, 0xb6, 0xa5, 0xf6, 0xcd, 0x55, 0x48, 0x8b, 0x1b, 0x38, 0x9c, 0xd7, + 0x6d, 0x40, 0x2a, 0x5f, 0xcf, 0xcb, 0x67, 0xa4, 0x8c, 0xf4, 0x8f, 0x70, + 0x34, 0xeb, 0x70, 0xcd, 0xee, 0x1c, 0xbd, 0xae, 0xd1, 0xc1, 0xf8, 0x62, + 0x45, 0xb5, 0x5d, 0xe6, 0x0b, 0xd4, 0x3d, 0x23, 0xf0, 0x27, 0x44, 0x56, + 0x32, 0x4d, 0xb1, 0x6c, 0x5d, 0x33, 0x94, 0x77, 0xe3, 0xac, 0x54, 0x56, + 0x24, 0x05, 0x26, 0x4a, 0xf0, 0x59, 0xfb, 0x1f, 0xa4, 0x0f, 0xbe, 0x9e, + 0xbc, 0x76, 0x9d, 0x5a, 0xed, 0x15, 0x97, 0x4e, 0x05, 0x8a, 0x8b, 0xff, + 0xc7, 0x9b, 0x67, 0x32, 0x12, 0x41, 0x04, 0xcb, 0x24, 0xae, 0x9e, 0xcc, + 0xd6, 0xc6, 0x67, 0x53, 0xfa, 0x29, 0x37, 0x73, 0xc6, 0xdf, 0xf2, 0x56, + 0x72, 0x06, 0x03, 0xaa, 0x5d, 0x07, 0xac, 0x38, 0xb9, 0x2a, 0x61, 0x02, + 0x24, 0xcf, 0x54, 0x3f, 0x98, 0xb0, 0x5c, 0xba, 0xe3, 0x15, 0x27, 0x52, + 0x63, 0x43, 0x12, 0x62, 0x33, 0x02, 0xb8, 0x69, 0x52, 0x70, 0x6c, 0xc0, + 0x23, 0x37, 0x65, 0x4b, 0xc9, 0xea, 0x98, 0x06, 0xde, 0x3d, 0x59, 0x72, + 0x94, 0x48, 0x60, 0xeb, 0xe7, 0xaa, 0x68, 0x72, 0x22, 0x15, 0x39, 0xf0, + 0x47, 0x43, 0xeb, 0x37, 0xb1, 0x3b, 0x9e, 0x05, 0x12, 0xdb, 0x74, 0x18, + 0xfe, 0x11, 0xcb, 0xae, 0xe0, 0xed, 0x1c, 0xe3, 0x19, 0x71, 0x56, 0xa6, + 0x04, 0xe6, 0x20, 0x62, 0xfd, 0xb1, 0x57, 0x44, 0xca, 0x3f, 0xdf, 0x51, + 0x23, 0x76, 0x3b, 0x70, 0x27, 0x33, 0x62, 0x74, 0x94, 0xff, 0x70, 0xcc, + 0xd4, 0xbf, 0x67, 0x12, 0x17, 0x5f, 0x71, 0xf8, 0x8f, 0x09, 0xca, 0xb5, + 0x49, 0x38, 0xcf, 0x1f, 0x94, 0x9a, 0xe6, 0x76, 0x0e, 0xa6, 0x5a, 0x2c, + 0x36, 0x61, 0x41, 0x2d, 0x14, 0x2f, 0x35, 0xa2, 0xaa, 0x2d, 0xd5, 0x54, + 0x3c, 0x4e, 0xa0, 0x63, 0xa9, 0x9e, 0xe9, 0x65, 0x62, 0xcf, 0x5a, 0x1a, + 0xb9, 0x70, 0xf7, 0xf1, 0x8a, 0xc7, 0x19, 0x6e, 0x34, 0xa0, 0xbb, 0x1b, + 0x76, 0x9b, 0x60, 0x20, 0xfd, 0xff, 0xe1, 0x40, 0x5e, 0xd7, 0x49, 0xd3, + 0x3c, 0x0f, 0x52, 0xae, 0x37, 0x38, 0x1d, 0xd5, 0xd0, 0xe7, 0xd6, 0xfc, + 0x06, 0x3b, 0x50, 0x06, 0x9c, 0xb4, 0x37, 0x9a, 0x53, 0x09, 0x56, 0xa4, + 0xa8, 0x64, 0x70, 0xa7, 0xaf, 0xb9, 0xd9, 0x19, 0xbc, 0x5b, 0x04, 0x07, + 0x68, 0xc0, 0xa4, 0xc0, 0x3d, 0x32, 0x36, 0x94, 0x24, 0xd3, 0x36, 0x1f, + 0xfc, 0xd8, 0x26, 0x49, 0x94, 0xd2, 0x1e, 0x8b, 0x0c, 0x70, 0x6e, 0xd7, + 0xd2, 0x37, 0x8f, 0x13, 0xef, 0x41, 0xdb, 0x53, 0xb5, 0xba, 0xe5, 0xe3, + 0x0c, 0xcd, 0xa3, 0xfa, 0x74, 0x16, 0xd9, 0x42, 0x10, 0xa3, 0xe6, 0x26, + 0xd6, 0x74, 0xbc, 0x17, 0x9b, 0x2e, 0x4c, 0xe2, 0x13, 0x49, 0x0f, 0xc9, + 0xc2, 0x34, 0xae, 0x5b, 0x6b, 0x46, 0xbc, 0xc4, 0x62, 0xa0, 0x4a, 0x18, + 0x62, 0x69, 0x1c, 0xc3, 0x78, 0x36, 0xfa, 0xd9, 0x8d, 0xd0, 0xf9, 0x4f, + 0x56, 0x90, 0x4b, 0xca, 0xc4, 0xdd, 0x64, 0x2c, 0xd1, 0x3c, 0xa8, 0xbe, + 0x62, 0x8f, 0x2a, 0x11, 0x93, 0x71, 0x75, 0x70, 0x43, 0xd0, 0x5f, 0xfb, + 0x36, 0x2b, 0x35, 0x26, 0xda, 0xda, 0x25, 0x3c, 0x17, 0xf2, 0xb7, 0x36, + 0xd7, 0x8d, 0xd1, 0xbc, 0x2f, 0xe7, 0xf8, 0x55, 0x42, 0x2e, 0xe1, 0xc0, + 0x4a, 0xee, 0x3d, 0x5b, 0xc9, 0x69, 0x15, 0xc5, 0x42, 0x03, 0x2c, 0x46, + 0x02, 0x94, 0x91, 0xfb, 0x0f, 0x98, 0x8d, 0x32, 0xdf, 0x0b, 0x19, 0xda, + 0x9f, 0x96, 0x6e, 0x2d, 0xc4, 0xa1, 0x92, 0xc1, 0x73, 0x2f, 0x23, 0x9f, + 0x55, 0xc5, 0xb4, 0x8c, 0xef, 0xf3, 0xa2, 0x94, 0x8f, 0x6c, 0xd8, 0xb1, + 0x9d, 0x0d, 0x17, 0x93, 0x21, 0xd7, 0xae, 0xa8, 0x41, 0xd3, 0xf1, 0x9a, + 0xe3, 0x36, 0xca, 0x5f, 0xa4, 0xd9, 0xaf, 0x34, 0xbf, 0xe6, 0x9e, 0x4c, + 0xf0, 0xd1, 0xb0, 0x8c, 0x8e, 0x76, 0x3d, 0xb3, 0xf7, 0xd9, 0xfb, 0xbf, + 0x72, 0xae, 0xa8, 0x39, 0x00, 0xe5, 0x53, 0x17, 0x6c, 0x4e, 0x06, 0x22, + 0xc0, 0x10, 0xe7, 0x4d, 0xff, 0x75, 0x03, 0x01, 0x18, 0x46, 0xfd, 0xde, + 0x1e, 0x95, 0x46, 0xb8, 0x5b, 0x36, 0xbc, 0x1d, 0x95, 0x05, 0x8f, 0x5d, + 0x38, 0x41, 0x25, 0x2c, 0x9b, 0x34, 0x75, 0x9b, 0xf0, 0x8b, 0xaf, 0x0d, + 0x2e, 0xc2, 0x1a, 0x03, 0x61, 0xbe, 0xe8, 0x49, 0xbc, 0x9b, 0x45, 0xfb, + 0x35, 0x2b, 0x6c, 0xa1, 0x96, 0xa0, 0x08, 0x0e, 0xca, 0x01, 0xc0, 0x97, + 0xfa, 0xdf, 0x11, 0x1a, 0x0d, 0xf9, 0xc2, 0x5a, 0xe1, 0x4c, 0xb5, 0x37, + 0xff, 0x91, 0xb6, 0x96, 0xbf, 0x62, 0x04, 0x59, 0x69, 0x01, 0x68, 0x66, + 0x52, 0x66, 0x4a, 0x49, 0xe9, 0xe6, 0xe4, 0x44, 0x92, 0x5e, 0xaf, 0xf5, + 0x24, 0xdb, 0x6f, 0x21, 0xf9, 0x21, 0x58, 0x5f, 0xc4, 0xf0, 0x30, 0x90, + 0x68, 0xff, 0x58, 0x5c, 0xbd, 0x6f, 0x58, 0x77, 0xe0, 0x03, 0x68, 0x2a, + 0x1a, 0xa4, 0xd6, 0x9d, 0xd0, 0x38, 0x5a, 0xbd, 0x52, 0xa8, 0xc5, 0xf0, + 0xbc, 0xf2, 0x04, 0x49, 0x0e, 0x1b, 0x1b, 0x93, 0xc0, 0x65, 0xca, 0x05, + 0x42, 0x11, 0x03, 0xd6, 0xd5, 0x2c, 0x4c, 0xcd, 0xed, 0xb4, 0x54, 0xa4, + 0x3d, 0x46, 0x64, 0x4c, 0xc4, 0x8f, 0x0a, 0x95, 0x6a, 0x4f, 0xfb, 0x2e, + 0x1d, 0x5a, 0x8a, 0xcb, 0x31, 0x94, 0x21, 0x54, 0x51, 0xf5, 0x4e, 0x3e, + 0x32, 0x00, 0x12, 0x8e, 0x4c, 0x8c, 0x17, 0x90, 0xea, 0x8d, 0xfe, 0xc3, + 0xfe, 0x69, 0x10, 0xd9, 0x1c, 0x60, 0x91, 0xb6, 0xbb, 0x11, 0xb7, 0x77, + 0x1c, 0x69, 0xec, 0xb5, 0x28, 0x1e, 0x4b, 0xc8, 0xac, 0xe2, 0xe7, 0xe4, + 0xca, 0x1c, 0x6a, 0x16, 0xb8, 0x0a, 0x1c, 0xcb, 0xbd, 0x0e, 0x61, 0xf6, + 0x30, 0xa0, 0xb0, 0x11, 0x57, 0xd0, 0xa0, 0xe5, 0x63, 0xb4, 0x5e, 0x65, + 0x54, 0xbd, 0x2b, 0xcf, 0x92, 0xb3, 0xe2, 0xad, 0xba, 0x6b, 0xd8, 0x8b, + 0xd4, 0xc9, 0x49, 0x6b, 0xe9, 0x6f, 0x30, 0x9a, 0x8d, 0x1a, 0xd2, 0x73, + 0xed, 0x01, 0x20, 0x76, 0x59, 0x3b, 0x63, 0x15, 0xf7, 0x4a, 0x93, 0xf5, + 0xe8, 0xaa, 0x77, 0xf7, 0xee, 0x16, 0x26, 0x6d, 0x6d, 0x1e, 0xb3, 0x04, + 0xd1, 0x36, 0x6d, 0xdb, 0xe1, 0xee, 0xdf, 0x69, 0x0e, 0x28, 0x3b, 0x5a, + 0x37, 0x51, 0x61, 0x10, 0x58, 0xd0, 0x58, 0x75, 0x63, 0x5b, 0x76, 0x3e, + 0x55, 0x0a, 0x07, 0x3e, 0xfe, 0xb9, 0x6e, 0x4c, 0xfc, 0x1b, 0x8a, 0xa5, + 0x03, 0x1a, 0xb9, 0x04, 0x22, 0x60, 0x33, 0x66, 0xda, 0xb7, 0x1c, 0x3a, + 0xb6, 0x92, 0x45, 0x01, 0xc2, 0x73, 0x49, 0x6a, 0x9a, 0x54, 0x10, 0xe2, + 0x36, 0x45, 0xbd, 0x1d, 0x33, 0x2a, 0xd2, 0xc9, 0x70, 0x63, 0x39, 0xcf, + 0xf7, 0x76, 0x70, 0x37, 0xde, 0x23, 0x4c, 0xd2, 0xa1, 0x37, 0x2c, 0x52, + 0xae, 0xa3, 0xfb, 0x45, 0xd0, 0xb9, 0x46, 0x3e, 0x2a, 0xe8, 0xe9, 0x64, + 0xe1, 0x16, 0x30, 0x08, 0x36, 0xcd, 0x9e, 0x15, 0x44, 0xdd, 0x27, 0xa9, + 0x1c, 0x29, 0xf1, 0xa7, 0x20, 0x21, 0x59, 0x61, 0x4c, 0xbe, 0x5e, 0x20, + 0x36, 0xca, 0xb8, 0x6d, 0xb5, 0x0c, 0x29, 0x41, 0xa1, 0xd3, 0x8a, 0x2b, + 0x34, 0xd2, 0x5b, 0x92, 0x12, 0x1f, 0x36, 0x9f, 0x5d, 0x02, 0x2a, 0xca, + 0xac, 0x5b, 0x29, 0x8b, 0x51, 0x3a, 0x65, 0xf5, 0xdf, 0x60, 0x6c, 0x0c, + 0xa7, 0x95, 0x3d, 0x52, 0x13, 0xb4, 0xbd, 0x8c, 0xf1, 0xac, 0xba, 0x3c, + 0x24, 0x6c, 0xc0, 0xdb, 0xa8, 0x5b, 0xd4, 0xdb, 0xf5, 0xcd, 0xaf, 0xdf, + 0x2f, 0xe2, 0x71, 0xcc, 0x00, 0x3a, 0x87, 0xdc, 0x23, 0xdf, 0xa7, 0xb0, + 0xb6, 0xcb, 0xff, 0x1c, 0xe7, 0xfe, 0xa8, 0xa8, 0xea, 0xad, 0x37, 0x58, + 0xfd, 0x58, 0x01, 0xa5, 0xe4, 0x5d, 0xdf, 0x4a, 0x10, 0x0b, 0xc3, 0x5e, + 0xd1, 0x0d, 0x4c, 0x21, 0x0e, 0x51, 0x95, 0x99, 0x58, 0xdf, 0x6d, 0xa8, + 0x8e, 0xf7, 0x51, 0xa6, 0x53, 0x44, 0x6b, 0xb3, 0x00, 0x64, 0xe1, 0x6f, + 0x3d, 0x19, 0x40, 0x30, 0x46, 0x95, 0x9b, 0x39, 0xa5, 0x0d, 0x77, 0xaa, + 0xb1, 0x57, 0x57, 0x08, 0xe0, 0xab, 0xd1, 0xd5, 0x25, 0x59, 0x11, 0x2f, + 0x62, 0xbf, 0x50, 0x95, 0x02, 0x18, 0xdb, 0x2d, 0xbc, 0xdb, 0xfa, 0x3d, + 0x45, 0xab, 0xb5, 0x2e, 0x8e, 0x9b, 0x49, 0xe5, 0x50, 0xbd, 0x1f, 0x1c, + 0x64, 0xd8, 0x9d, 0x0c, 0x0c, 0xe8, 0xf3, 0x54, 0x49, 0x95, 0x3d, 0x71, + 0xa1, 0x16, 0x98, 0x08, 0x16, 0x37, 0x6a, 0x95, 0xa3, 0xaa, 0xb6, 0xf7, + 0x0e, 0x99, 0x2a, 0x0b, 0x68, 0x49, 0xd1, 0xa4, 0x33, 0x3e, 0x57, 0xfc, + 0xc3, 0x5a, 0xa9, 0x1e, 0xbf, 0xf1, 0x19, 0x2d, 0xee, 0xfa, 0x01, 0xa8, + 0x64, 0x0d, 0x74, 0x54, 0xed, 0x4d, 0xab, 0xad, 0x23, 0x25, 0xde, 0xef, + 0xb4, 0x54, 0xfe, 0x3f, 0xba, 0xe0, 0x0e, 0x76, 0x1b, 0x1a, 0xa9, 0xe3, + 0x53, 0xbd, 0xde, 0x65, 0x6b, 0x08, 0x6d, 0x71, 0x45, 0xb4, 0xf8, 0x9a, + 0x06, 0x3d, 0xae, 0x87, 0x25, 0x51, 0x9d, 0x46, 0x33, 0xf3, 0x77, 0x6d, + 0xb6, 0x5d, 0xbe, 0x08, 0xfc, 0xf5, 0x31, 0xa1, 0xd5, 0x22, 0x19, 0xcd, + 0x66, 0x82, 0x19, 0xf5, 0xf5, 0x29, 0x28, 0x83, 0xa5, 0xa3, 0x30, 0x50, + 0xa1, 0xfb, 0xf6, 0x36, 0x31, 0xbf, 0xb5, 0xc4, 0xe7, 0x99, 0xd5, 0x4f, + 0xf5, 0xb0, 0xf5, 0x9a, 0x12, 0x4e, 0x1b, 0xdb, 0x4d, 0x21, 0x6d, 0xda, + 0xeb, 0x6a, 0x11, 0x55, 0xa2, 0xe2, 0x6a, 0xe9, 0xe8, 0x01, 0xa1, 0x97, + 0x68, 0xc2, 0x30, 0xd2, 0xfa, 0x60, 0xec, 0x4d, 0x54, 0x5b, 0x9e, 0x2d, + 0x97, 0xca, 0x1b, 0xc2, 0xb2, 0x14, 0x3f, 0xaf, 0x23, 0x54, 0xe8, 0x0c, + 0x3c, 0xed, 0x50, 0x32, 0xff, 0x3a, 0x8c, 0xe6, 0xdc, 0x17, 0xad, 0x65, + 0x05, 0x35, 0x28, 0xc9, 0x77, 0x21, 0xb1, 0x9a, 0xec, 0xf1, 0xd6, 0x53, + 0xb9, 0xb3, 0xe0, 0x41, 0x11, 0x85, 0x2e, 0x1a, 0xb5, 0xad, 0xab, 0x9b, + 0xae, 0x69, 0xa0, 0xb1, 0xa0, 0x07, 0x72, 0x8f, 0x4a, 0xd9, 0x5e, 0x1f, + 0x29, 0x9e, 0x4d, 0x0b, 0x9a, 0x82, 0xfe, 0x26, 0xc5, 0x17, 0x5b, 0x51, + 0x46, 0xf2, 0xf7, 0x27, 0xba, 0x06, 0x91, 0x0e, 0xc2, 0x07, 0xb3, 0x1b, + 0x54, 0xad, 0xb5, 0xf5, 0x02, 0xc1, 0x39, 0x6a, 0x2a, 0xd7, 0x46, 0xbf, + 0x3d, 0x39, 0x4e, 0x8e, 0xb1, 0x58, 0xf4, 0x90, 0xa7, 0x08, 0x0e, 0x99, + 0x64, 0x33, 0x3e, 0x1e, 0x09, 0xb7, 0x88, 0xa0, 0x29, 0xb2, 0x0b, 0x5c, + 0x15, 0xd4, 0x36, 0x55, 0x42, 0x48, 0xe7, 0x47, 0xf9, 0xb5, 0x05, 0xcd, + 0x40, 0xde, 0x92, 0x27, 0x11, 0x3b, 0xad, 0x3e, 0x9b, 0x95, 0x38, 0xad, + 0x11, 0xd5, 0x9d, 0x1d, 0x38, 0x60, 0xde, 0x31, 0xe3, 0x40, 0xb2, 0xf2, + 0x8e, 0xb4, 0x03, 0xaa, 0x51, 0x15, 0xe4, 0x36, 0x4d, 0x43, 0x05, 0xbc, + 0x36, 0x82, 0xdf, 0xfc, 0xfd, 0x23, 0x4d, 0xad, 0x9f, 0xf4, 0xce, 0xfb, + 0xaf, 0x46, 0xb3, 0x59, 0x98, 0x91, 0x85, 0x4a, 0xa7, 0x67, 0x70, 0xbd, + 0xca, 0x12, 0x9b, 0x6b, 0x00, 0xe5, 0x82, 0x3c, 0x37, 0x99, 0x8d, 0x6b, + 0x32, 0xaf, 0x08, 0x05, 0x36, 0xd6, 0xd7, 0xfb, 0x65, 0xce, 0x4e, 0x9f, + 0xd5, 0xd1, 0x3a, 0x42, 0xb0, 0x31, 0x62, 0xd0, 0xe2, 0xe5, 0x37, 0xc1, + 0x6d, 0x8a, 0x24, 0xa4, 0x19, 0xc2, 0x59, 0x3c, 0x44, 0xef, 0x96, 0xf6, + 0x35, 0x00, 0xe7, 0xe6, 0x2e, 0x82, 0xa5, 0x4a, 0x2f, 0xa2, 0xfe, 0x1f, + 0x53, 0x52, 0x31, 0x97, 0x47, 0x37, 0x15, 0x26, 0xa7, 0x8d, 0xd3, 0x21, + 0x6a, 0x98, 0x6d, 0xf1, 0xe6, 0x29, 0xf8, 0x9d, 0xaf, 0x5f, 0x3e, 0x3a, + 0xbc, 0x65, 0xb2, 0xd8, 0x41, 0xbc, 0xd6, 0x39, 0x3c, 0xc7, 0x2f, 0x2e, + 0xa3, 0x08, 0x9a, 0x21, 0x05, 0xe0, 0x4c, 0x06, 0x4d, 0x82, 0x68, 0x5d, + 0x4a, 0x9e, 0xca, 0xee, 0x3d, 0x28, 0x45, 0x0e, 0xff, 0xdd, 0xe6, 0x46, + 0xbc, 0xf8, 0x19, 0x5b, 0xda, 0xf4, 0x14, 0xd1, 0x4f, 0x02, 0x6e, 0xf6, + 0x01, 0x2d, 0xd6, 0xb6, 0x8b, 0xf5, 0x9c, 0x4e, 0xee, 0xe7, 0xc8, 0x10, + 0x05, 0xb6, 0x6d, 0x8d, 0x49, 0xe2, 0x04, 0xec, 0x4d, 0x61, 0x67, 0xc2, + 0x19, 0x27, 0xab, 0xe1, 0x0d, 0x29, 0xab, 0xf2, 0xa0, 0xf9, 0x69, 0x0d, + 0x81, 0x29, 0x4d, 0x40, 0x6d, 0xd7, 0xda, 0xb7, 0x9e, 0x0b, 0x90, 0x9c, + 0x9b, 0xeb, 0x59, 0x2c, 0xc9, 0xa4, 0x85, 0x95, 0xe2, 0xda, 0x2d, 0xe4, + 0x60, 0x9a, 0x64, 0x21, 0xbf, 0x1d, 0x57, 0x4d, 0x3e, 0xa0, 0x35, 0x0f, + 0xce, 0xd7, 0xe1, 0x44, 0x63, 0x9e, 0xe8, 0x8e, 0xbd, 0xc8, 0xc1, 0x65, + 0xe1, 0xd2, 0x09, 0x45, 0xd3, 0xbd, 0x13, 0xb2, 0x1f, 0x46, 0x32, 0xa6, + 0xcd, 0xa3, 0x44, 0x4c, 0x52, 0xa7, 0xe7, 0x54, 0xea, 0xe6, 0xa0, 0xce, + 0x02, 0x8b, 0x69, 0xdb, 0xde, 0xef, 0x5f, 0xcb, 0x6f, 0x6e, 0x0f, 0xf5, + 0x68, 0x42, 0xf4, 0x37, 0x08, 0x1f, 0x87, 0x55, 0xb4, 0xbc, 0x8a, 0x84, + 0x84, 0x10, 0xc6, 0x36, 0x3e, 0x8a, 0x6b, 0x4e, 0xd5, 0xc8, 0x64, 0xcb, + 0xb5, 0xc0, 0xfe, 0x99, 0x66, 0xaa, 0xb1, 0x50, 0xa7, 0x70, 0xd9, 0xa6, + 0x17, 0x2d, 0xd4, 0xad, 0xdf, 0xf2, 0x2f, 0xac, 0xae, 0xae, 0x12, 0xcf, + 0x5b, 0x09, 0xf2, 0x2d, 0xb4, 0x21, 0xc9, 0xd1, 0x58, 0xdb, 0x4e, 0x9b, + 0xe0, 0x32, 0x08, 0xe4, 0x4a, 0xe6, 0x9c, 0x61, 0x25, 0x90, 0x08, 0xf2, + 0xb1, 0xc1, 0x3c, 0x25, 0x0b, 0x5a, 0x03, 0x40, 0xdb, 0x06, 0x5f, 0xd2, + 0x60, 0x8e, 0x0a, 0x5b, 0xc8, 0xa2, 0xcd, 0xac, 0xb3, 0x54, 0x0b, 0xb6, + 0x05, 0x45, 0xd7, 0xa8, 0x8a, 0xfa, 0x8a, 0xba, 0x09, 0x53, 0x81, 0xd7, + 0xf5, 0x40, 0x61, 0x46, 0xf2, 0x22, 0xe4, 0x21, 0xb4, 0x26, 0x41, 0x10, + 0x25, 0x4d, 0x93, 0xc2, 0xa2, 0xae, 0xc3, 0xaa, 0xbe, 0x71, 0xa6, 0xaa, + 0xf7, 0xb1, 0xbf, 0x02, 0x22, 0xe9, 0xd7, 0xfb, 0xaa, 0x1d, 0x5d, 0xf5, + 0xe7, 0x5b, 0x63, 0xf2, 0xe6, 0x5c, 0xd6, 0x24, 0x6d, 0xb5, 0xca, 0xa3, + 0xe7, 0x57, 0x1a, 0xa5, 0xf7, 0x95, 0xc5, 0x92, 0x51, 0x65, 0x68, 0xc5, + 0xe6, 0x27, 0xa9, 0x94, 0x8a, 0xb6, 0xec, 0x0d, 0x9c, 0x51, 0xdf, 0x22, + 0xca, 0xdf, 0x5a, 0xf5, 0xe4, 0xad, 0xf4, 0xfc, 0x1f, 0x68, 0x9f, 0xdb, + 0x40, 0x4e, 0x6a, 0x1e, 0x5a, 0xd8, 0x6c, 0xd6, 0xef, 0xad, 0x64, 0xe7, + 0xcb, 0xfc, 0x44, 0xae, 0xa5, 0x62, 0x65, 0xad, 0x2e, 0x6a, 0x46, 0xcf, + 0x0d, 0xd0, 0x46, 0x5e, 0x87, 0x37, 0xb6, 0xab, 0x70, 0x52, 0xee, 0x5a, + 0xa7, 0x13, 0xa3, 0xc3, 0x4b, 0x62, 0xe7, 0x31, 0x10, 0xed, 0x39, 0x1c, + 0x4a, 0xe3, 0xc1, 0x57, 0xcb, 0x45, 0xe4, 0x89, 0xee, 0x0e, 0x24, 0xc1, + 0xa6, 0xac, 0xd4, 0x0e, 0x9b, 0xe0, 0x26, 0x28, 0x08, 0x2b, 0xe1, 0xc9, + 0x42, 0x37, 0xa3, 0x46, 0xcc, 0x5d, 0x89, 0x10, 0x1f, 0x23, 0xcb, 0x1c, + 0x67, 0xe2, 0x6d, 0xaa, 0x66, 0xa5, 0xf5, 0xea, 0x94, 0x2b, 0x8c, 0xf6, + 0xf4, 0xd3, 0xfb, 0x9c, 0x96, 0x0a, 0x87, 0xaf, 0x5c, 0x19, 0xb4, 0x3b, + 0x26, 0xb2, 0x48, 0x55, 0x97, 0xfd, 0x3a, 0xec, 0x06, 0xe4, 0x58, 0x99, + 0x9a, 0x26, 0x4f, 0xe0, 0x9c, 0x67, 0x09, 0x05, 0x5b, 0x72, 0x8e, 0xd6, + 0xe4, 0x4e, 0xe2, 0x63, 0xb0, 0x9c, 0xf6, 0x92, 0xd3, 0x05, 0x3f, 0xb0, + 0x04, 0x5f, 0x02, 0x97, 0xf4, 0x42, 0x1d, 0x3b, 0x5c, 0x44, 0x00, 0x95, + 0x8b, 0xf5, 0x06, 0x40, 0xbd, 0xb8, 0xf7, 0x4b, 0x4a, 0xfa, 0xf0, 0x04, + 0x04, 0xd0, 0xa5, 0xb9, 0x3a, 0xa0, 0x2d, 0x0c, 0x1b, 0xec, 0x5a, 0x14, + 0xc8, 0x1d, 0x93, 0x86, 0xfd, 0x16, 0x68, 0xf8, 0x16, 0x9b, 0xb4, 0x88, + 0x99, 0x63, 0x0e, 0xd5, 0x20, 0x07, 0x43, 0x28, 0x26, 0xba, 0xf9, 0x97, + 0xed, 0x6b, 0x40, 0xb8, 0x07, 0x73, 0x59, 0xd5, 0x55, 0xa8, 0x64, 0x14, + 0x1c, 0xc5, 0xc0, 0x1f, 0x8d, 0x09, 0xae, 0x9c, 0x66, 0xa1, 0x94, 0xca, + 0x14, 0x46, 0xed, 0x46, 0x46, 0x25, 0x63, 0x5b, 0x2b, 0x95, 0x85, 0x05, + 0xc2, 0xb7, 0xeb, 0x06, 0x30, 0x5a, 0xf6, 0x22, 0x4e, 0x47, 0x1e, 0x0e, + 0x0c, 0xad, 0xd5, 0x11, 0xa8, 0x6a, 0x89, 0xd5, 0x49, 0xd4, 0xfa, 0x43, + 0xb0, 0x32, 0xb0, 0xb9, 0xb3, 0xda, 0x3f, 0x4f, 0xac, 0x4c, 0xc1, 0xa7, + 0x9f, 0xc2, 0xc2, 0x04, 0x70, 0xa2, 0x08, 0x01, 0xeb, 0x10, 0xa4, 0xa5, + 0x4c, 0xcd, 0xb3, 0x81, 0x4e, 0xbe, 0x6c, 0x51, 0x44, 0xf8, 0x82, 0xbd, + 0x42, 0x34, 0xfb, 0xdb, 0xb4, 0x32, 0xd2, 0x93, 0x63, 0x5e, 0xf6, 0x07, + 0x6e, 0x2c, 0xc2, 0xcf, 0xf4, 0x5d, 0x84, 0xe9, 0x5e, 0x5c, 0xa8, 0x39, + 0x28, 0x4a, 0xed, 0x15, 0x1b, 0xea, 0xe6, 0xde, 0x85, 0x92, 0x86, 0xe7, + 0x83, 0x4b, 0x87, 0xf7, 0x23, 0x60, 0xe2, 0x22, 0xd3, 0x32, 0x16, 0x4e, + 0x2f, 0xde, 0x01, 0x8b, 0x48, 0xea, 0xcd, 0x8a, 0x8b, 0xbc, 0xc6, 0x64, + 0xb2, 0x67, 0x47, 0xf5, 0x98, 0xf8, 0xca, 0xf1, 0x83, 0x66, 0xd7, 0x9a, + 0xef, 0xca, 0x20, 0xc2, 0xec, 0x8c, 0x38, 0xb1, 0x37, 0x13, 0x93, 0x92, + 0xba, 0xa1, 0xee, 0x6a, 0x57, 0x43, 0xaa, 0xdc, 0xdf, 0xa4, 0x3f, 0xc6, + 0xb6, 0xd6, 0x68, 0x54, 0xab, 0x36, 0xe9, 0x0f, 0x6f, 0xd5, 0xa1, 0x1b, + 0xa1, 0x02, 0xc9, 0x41, 0xef, 0x4f, 0x86, 0xcc, 0x1a, 0xfa, 0xd2, 0xdd, + 0x87, 0x04, 0xe0, 0x27, 0x38, 0xcf, 0x91, 0x95, 0xb4, 0x02, 0x10, 0x1d, + 0xc3, 0xcc, 0x6f, 0xaf, 0xbc, 0x94, 0x64, 0x47, 0xbc, 0x37, 0xde, 0xe3, + 0x2e, 0x89, 0x03, 0xb6, 0xd3, 0x28, 0x4a, 0x5e, 0x6d, 0x1e, 0xc5, 0x1a, + 0xa5, 0x0c, 0x92, 0xf7, 0xe2, 0x19, 0xe7, 0x39, 0xf0, 0xf2, 0x49, 0x8b, + 0xe6, 0x99, 0xd8, 0x4b, 0x0d, 0x6e, 0x3f, 0x57, 0x89, 0x9e, 0x0d, 0x34, + 0x4b, 0x52, 0xcd, 0x18, 0x57, 0xc7, 0x8e, 0x48, 0x03, 0x65, 0xd4, 0xdd, + 0xdf, 0x04, 0xf5, 0x39, 0x5e, 0x97, 0xbc, 0xc0, 0xc5, 0x91, 0xe7, 0x9d, + 0xbe, 0x28, 0x4c, 0xe7, 0xf4, 0xa0, 0x34, 0xee, 0xba, 0xa7, 0x8d, 0x52, + 0xc4, 0x07, 0x14, 0xd2, 0x93, 0xb0, 0x1d, 0x61, 0x53, 0x23, 0xc3, 0xe1, + 0xd2, 0xbf, 0xe1, 0xd6, 0x1f, 0x27, 0xcc, 0x8c, 0xe7, 0x0b, 0x09, 0x4f, + 0xe6, 0xa2, 0x41, 0xf4, 0x31, 0xbe, 0x95, 0x17, 0xfb, 0x50, 0xa4, 0xa4, + 0x51, 0x3c, 0x6f, 0xf8, 0x6a, 0xba, 0xac, 0xe4, 0x1e, 0x38, 0x78, 0x18, + 0x58, 0x31, 0x69, 0xc9, 0x52, 0xb0, 0xfc, 0x71, 0x54, 0xad, 0xe2, 0x8e, + 0xa2, 0xf2, 0x8e, 0x58, 0x11, 0x1d, 0xcc, 0x30, 0x74, 0x55, 0x41, 0x02, + 0x9b, 0x2a, 0x2f, 0x17, 0x97, 0xe4, 0x1a, 0xd0, 0xd5, 0x8f, 0x60, 0x10, + 0xdb, 0xc2, 0x69, 0x94, 0x0d, 0xaf, 0x44, 0xd0, 0x95, 0x3d, 0x50, 0xf4, + 0x27, 0x5e, 0xdc, 0x56, 0x5f, 0xa7, 0x4c, 0x41, 0xe5, 0x9e, 0xc8, 0x31, + 0xb0, 0x8e, 0x3f, 0xde, 0xdc, 0x42, 0x24, 0x93, 0x98, 0xce, 0x69, 0x90, + 0x98, 0x73, 0x06, 0xb9, 0x8e, 0xa4, 0x8d, 0x97, 0xb1, 0x41, 0x33, 0x64, + 0x5a, 0xae, 0xe8, 0x2f, 0x5f, 0x99, 0x64, 0x3e, 0xea, 0xd4, 0xbe, 0xa2, + 0x52, 0x2d, 0xc7, 0x56, 0x46, 0xfb, 0x33, 0xd8, 0xde, 0xe6, 0x74, 0xf6, + 0x2e, 0x2a, 0x26, 0xa1, 0x07, 0xcd, 0x3c, 0xca, 0x39, 0x74, 0x61, 0x4a, + 0x53, 0xf7, 0x8c, 0xd7, 0x3c, 0x4f, 0x4f, 0xd9, 0x14, 0x74, 0x56, 0xa8, + 0x3b, 0x3b, 0xe4, 0xe5, 0x70, 0x2e, 0xda, 0xde, 0xcd, 0x65, 0x4f, 0x2e, + 0xb6, 0x76, 0x17, 0x59, 0x6a, 0xaf, 0x0a, 0x24, 0x8c, 0x99, 0x0b, 0x2a, + 0xac, 0x46, 0x74, 0x2c, 0x3b, 0x40, 0x20, 0xad, 0x30, 0xab, 0x63, 0x34, + 0x8f, 0x30, 0x22, 0x50, 0x5c, 0xf8, 0x73, 0x21, 0x3e, 0xeb, 0x16, 0x44, + 0x30, 0xb9, 0x59, 0x0f, 0xf0, 0xe5, 0xb6, 0x6a, 0xde, 0x32, 0x03, 0x28, + 0x3c, 0xc8, 0xc2, 0x8d, 0x6b, 0x72, 0x2f, 0x3e, 0x2b, 0x99, 0xc1, 0xa6, + 0xdf, 0x5a, 0x91, 0x2d, 0x40, 0x39, 0xb2, 0x24, 0x27, 0x25, 0x26, 0x51, + 0xbb, 0xb5, 0x6a, 0x47, 0x38, 0x94, 0x2c, 0x3e, 0xa0, 0x96, 0x19, 0xf7, + 0x99, 0x0c, 0x34, 0x41, 0xb9, 0x0d, 0xad, 0x37, 0xa6, 0x0c, 0x38, 0x9c, + 0xee, 0x03, 0x68, 0x62, 0x76, 0x64, 0x18, 0x63, 0x62, 0x10, 0xd6, 0x2a, + 0xca, 0xdb, 0x73, 0x9b, 0x93, 0x35, 0x29, 0xb0, 0xec, 0x6c, 0xa8, 0x1f, + 0xa6, 0xac, 0xf8, 0xd8, 0xfa, 0x98, 0xc3, 0x02, 0xf0, 0xf5, 0x66, 0x2c, + 0xfc, 0x75, 0xc7, 0xb0, 0x76, 0xfe, 0x0f, 0x92, 0x9b, 0xce, 0xc5, 0xe8, + 0x9a, 0x5e, 0x8f, 0x16, 0x26, 0x8c, 0x97, 0x20, 0x97, 0x36, 0xca, 0x56, + 0xed, 0xf2, 0x05, 0x53, 0xf7, 0x9f, 0x23, 0xbb, 0x1e, 0xdc, 0x5a, 0x94, + 0x0b, 0x1d, 0x0e, 0x55, 0xc7, 0x34, 0xff, 0xd9, 0xa3, 0x37, 0x69, 0x63, + 0x9f, 0x00, 0x0f, 0xa1, 0x5c, 0x1f, 0x50, 0x56, 0x25, 0xf0, 0xb8, 0x0e, + 0x92, 0x70, 0xcd, 0xa0, 0xca, 0x2a, 0xce, 0xa5, 0x21, 0xe7, 0x5b, 0x10, + 0x13, 0xd5, 0x9b, 0x9f, 0x60, 0x1b, 0x3f, 0x21, 0xa9, 0x27, 0xd9, 0xeb, + 0xdc, 0xe8, 0x05, 0x8e, 0x09, 0x27, 0x4b, 0x8b, 0xb1, 0x3b, 0x07, 0xb1, + 0xe9, 0x55, 0xc4, 0xab, 0x5d, 0x74, 0x11, 0xcf, 0x98, 0x5d, 0x47, 0x58, + 0x9d, 0x08, 0xec, 0x0b, 0x31, 0x69, 0x98, 0xad, 0xd0, 0x93, 0x09, 0xc7, + 0xcc, 0xe3, 0x64, 0x67, 0xef, 0xce, 0x98, 0xf3, 0xc2, 0x69, 0xd4, 0x47, + 0x4d, 0xf7, 0x1a, 0x10, 0xa9, 0x18, 0x35, 0x94, 0xc8, 0xe1, 0xd2, 0xf5, + 0xb5, 0xb4, 0x0b, 0xd7, 0x28, 0xa8, 0x97, 0x9b, 0xbf, 0x90, 0xe5, 0xc6, + 0xde, 0xf7, 0x4f, 0x33, 0xaf, 0x36, 0xe2, 0xa8, 0x65, 0x56, 0xdd, 0xe8, + 0x79, 0xae, 0x68, 0xc1, 0xf3, 0x5b, 0x26, 0x59, 0x53, 0x00, 0x43, 0x4c, + 0x3e, 0xf9, 0x24, 0xc4, 0x8d, 0x73, 0x00, 0x6c, 0xb2, 0x97, 0x56, 0x90, + 0x42, 0xde, 0xba, 0xd6, 0x3a, 0x6d, 0x39, 0x9d, 0xbe, 0x1c, 0xca, 0x24, + 0xbb, 0xba, 0x06, 0xf0, 0x59, 0x74, 0x32, 0x99, 0x1b, 0x02, 0xad, 0xc1, + 0x8b, 0xd4, 0x0b, 0xd8, 0xb7, 0xe7, 0xbd, 0xbd, 0x68, 0x56, 0xc1, 0x1e, + 0xda, 0xa4, 0xfe, 0x6b, 0x94, 0xf3, 0xda, 0x9a, 0x33, 0x01, 0x97, 0xb6, + 0x39, 0xc4, 0xe7, 0x57, 0xee, 0xcf, 0x0e, 0xce, 0x40, 0x7a, 0xd4, 0x4d, + 0x30, 0x6a, 0x57, 0x8f, 0x97, 0x92, 0x59, 0xeb, 0xf2, 0x18, 0x8c, 0x77, + 0xd9, 0x8f, 0x72, 0xff, 0xd5, 0xb2, 0x1f, 0x2e, 0xba, 0xb6, 0x46, 0x1a, + 0x33, 0xe0, 0x74, 0x2a, 0xd7, 0xdb, 0xc7, 0x07, 0x37, 0x2f, 0x55, 0xe2, + 0x70, 0x43, 0xc2, 0xbc, 0x33, 0x03, 0xc9, 0xd4, 0x4e, 0x6e, 0x3e, 0xc9, + 0x67, 0x55, 0xf8, 0x6d, 0x63, 0x9f, 0x6b, 0x3f, 0x5b, 0xc7, 0xe9, 0xb8, + 0x31, 0x04, 0x0b, 0x71, 0x15, 0xcd, 0x34, 0xe4, 0xaf, 0x74, 0x73, 0xea, + 0xbf, 0x20, 0x00, 0x75, 0xd7, 0xa7, 0xf7, 0x9c, 0xf5, 0xa1, 0x28, 0xc7, + 0xfe, 0x6b, 0xa2, 0x36, 0xdc, 0xd4, 0xf0, 0xd7, 0x42, 0x4e, 0xe4, 0x3f, + 0x00, 0x09, 0x3c, 0x5e, 0x1f, 0xc8, 0xfd, 0xb9, 0xd8, 0x90, 0xdb, 0xf4, + 0x41, 0x0b, 0xda, 0x68, 0xe1, 0xe4, 0xb9, 0xfb, 0x36, 0x37, 0xa9, 0x5f, + 0xc9, 0xb6, 0xb8, 0xa4, 0xda, 0x41, 0xaa, 0xab, 0xa8, 0xc8, 0xd3, 0xc6, + 0x6a, 0xbe, 0x03, 0x77, 0xcc, 0x1a, 0x8d, 0x0d, 0xe8, 0xcc, 0x58, 0x46, + 0x71, 0x33, 0x19, 0x62, 0xe5, 0xc4, 0xe3, 0x4a, 0x1d, 0xf7, 0x96, 0xd4, + 0x08, 0xe5, 0xa8, 0x18, 0x40, 0x2d, 0xc5, 0xd7, 0xa7, 0x31, 0xa2, 0x5f, + 0x60, 0xde, 0x21, 0xe5, 0xaa, 0x65, 0x93, 0x0d, 0xdb, 0x55, 0x54, 0x88, + 0xbd, 0x53, 0x8e, 0xe0, 0xa6, 0x23, 0xcd, 0x1d, 0xb7, 0xbd, 0x2a, 0x8c, + 0x0e, 0x67, 0x65, 0xab, 0xda, 0xe9, 0x3b, 0x12, 0xf6, 0x97, 0x4b, 0xe8, + 0x16, 0xf7, 0x09, 0xb6, 0x45, 0x97, 0x16, 0xec, 0xd9, 0xdc, 0x8d, 0x01, + 0xba, 0xb0, 0xb6, 0xdd, 0x59, 0x60, 0xbf, 0x92, 0x92, 0xc3, 0x21, 0x41, + 0x46, 0xcb, 0x5e, 0x6e, 0x99, 0x10, 0x41, 0x45, 0x9a, 0xb9, 0xe0, 0x6d, + 0x22, 0x68, 0xd3, 0x5a, 0xaa, 0x6e, 0xb4, 0xc6, 0x42, 0xa2, 0xad, 0xf1, + 0xf7, 0x0b, 0x3d, 0x29, 0x38, 0xa2, 0x11, 0xf8, 0x57, 0x25, 0xb8, 0x8f, + 0xbc, 0x65, 0xac, 0x0d, 0xf0, 0xb7, 0x5c, 0x95, 0xfb, 0x5d, 0xdb, 0x54, + 0x3d, 0x3e, 0xd6, 0x4f, 0x2a, 0xfe, 0x43, 0xfc, 0x1c, 0xca, 0xb9, 0xb3, + 0x95, 0x06, 0x90, 0xd9, 0x5d, 0x43, 0xc4, 0xe9, 0xbb, 0x17, 0xd6, 0xaf, + 0xf2, 0xb0, 0x24, 0x9d, 0x27, 0xdf, 0xaf, 0xf7, 0x6f, 0xd1, 0x4c, 0xbe, + 0xd0, 0x1d, 0x16, 0x3f, 0xf5, 0x23, 0xdb, 0x52, 0xc4, 0x3b, 0x99, 0x3d, + 0xd5, 0xdc, 0x0b, 0x54, 0x3b, 0xfd, 0x9d, 0x36, 0xf6, 0xd9, 0x63, 0xd4, + 0xc0, 0x8f, 0x9d, 0x00, 0xa6, 0x1e, 0x41, 0x72, 0x18, 0xa6, 0xc5, 0xd0, + 0xb6, 0xdd, 0x10, 0x61, 0x45, 0xe0, 0xdc, 0xcc, 0x92, 0xd3, 0x05, 0x54, + 0x26, 0x2c, 0xcf, 0x94, 0x67, 0xa5, 0xae, 0x62, 0x97, 0x4e, 0x10, 0x2b, + 0xf4, 0x65, 0x89, 0x21, 0x98, 0xad, 0x25, 0x6a, 0x01, 0xa9, 0x4f, 0x57, + 0x2b, 0xbe, 0x3b, 0xcc, 0x34, 0x89, 0xc3, 0xd2, 0xa0, 0xc5, 0x72, 0xd9, + 0x39, 0x3f, 0x45, 0x62, 0x73, 0xda, 0xf3, 0xe7, 0xbf, 0xfd, 0xfe, 0x5b, + 0xe0, 0xc5, 0x9f, 0xf9, 0xbe, 0x2b, 0x9a, 0xf7, 0xc2, 0xe9, 0x59, 0x73, + 0xc4, 0x0a, 0xfe, 0x73, 0x5b, 0x34, 0xb9, 0xfc, 0x45, 0xb7, 0x4d, 0x39, + 0xc2, 0xcd, 0x5f, 0x33, 0x91, 0xab, 0x48, 0x57, 0x0a, 0x27, 0xf3, 0xd4, + 0xf3, 0xb4, 0x57, 0x04, 0xeb, 0x8a, 0xb2, 0xd4, 0x06, 0x60, 0x09, 0x48, + 0x58, 0xf8, 0x1f, 0x06, 0x8c, 0x2d, 0x55, 0x2b, 0x8d, 0xbb, 0x37, 0xbb, + 0xc5, 0xa3, 0x05, 0x38, 0xf7, 0x47, 0x0a, 0xd9, 0xa8, 0x5a, 0x5b, 0x75, + 0x58, 0xa3, 0x35, 0x01, 0x1a, 0x5c, 0xe3, 0x97, 0xef, 0x04, 0xd9, 0x28, + 0x93, 0xc9, 0x59, 0xfc, 0xc1, 0x9b, 0x25, 0xe8, 0x44, 0x05, 0x17, 0xdc, + 0xe1, 0xb2, 0x06, 0xd6, 0x08, 0xe0, 0x00, 0xe0, 0x06, 0xaf, 0xb6, 0xf8, + 0x63, 0x6c, 0x54, 0x29, 0x7a, 0x25, 0x0c, 0xc4, 0xe7, 0x6c, 0x2b, 0xe8, + 0xe9, 0x06, 0xa4, 0x9e, 0xb0, 0x38, 0xd4, 0xf1, 0x46, 0xb3, 0x93, 0x54, + 0xa7, 0xa1, 0xcd, 0x65, 0x43, 0xe8, 0xc3, 0x03, 0x60, 0x9c, 0x39, 0x02, + 0xea, 0xc5, 0x0c, 0x96, 0xd2, 0x05, 0x0d, 0x1f, 0xc7, 0x04, 0xc4, 0xa3, + 0xc4, 0xc0, 0xa9, 0x0b, 0xc7, 0xa1, 0x3f, 0xdc, 0x35, 0x51, 0x4d, 0xc8, + 0xc2, 0x87, 0x99, 0x3c, 0x46, 0xb3, 0x4e, 0xc9, 0xbf, 0xb3, 0x34, 0x8b, + 0xb7, 0x6f, 0xe5, 0x95, 0x9b, 0x17, 0x20, 0x56, 0xa6, 0x64, 0x4c, 0x77, + 0xdc, 0x0e, 0x28, 0xc3, 0xef, 0xf4, 0x28, 0x47, 0xd4, 0x0c, 0x6a, 0xe1, + 0x75, 0x63, 0xc9, 0xae, 0xe9, 0x36, 0x57, 0xfd, 0x08, 0x2f, 0xb2, 0x0b, + 0x48, 0xd4, 0x04, 0x24, 0x2f, 0x17, 0x03, 0x9e, 0xfe, 0xfd, 0x67, 0x0e, + 0xbe, 0x66, 0xcf, 0x2c, 0xaa, 0x4f, 0x1c, 0x32, 0x2e, 0xa0, 0xfb, 0x55, + 0x40, 0x15, 0x5d, 0x51, 0xca, 0xbe, 0xff, 0xb2, 0xb2, 0x2b, 0x47, 0xee, + 0x37, 0xc8, 0x65, 0xad, 0xda, 0xb9, 0x3a, 0x75, 0x3a, 0x98, 0x1f, 0xcf, + 0xd7, 0x48, 0x56, 0xa2, 0xed, 0xb4, 0x46, 0x60, 0x30, 0x6a, 0x19, 0x5b, + 0x38, 0xc8, 0x0d, 0x3a, 0xc3, 0xe1, 0x34, 0x6e, 0x39, 0x5f, 0xf2, 0x4d, + 0x78, 0x02, 0xba, 0x3c, 0x71, 0x70, 0x75, 0x6c, 0xb0, 0xfa, 0x38, 0xe3, + 0x6b, 0x42, 0x1e, 0x23, 0xcd, 0xe6, 0xf8, 0xc5, 0x9c, 0x24, 0x3d, 0x98, + 0xa8, 0xbb, 0x4a, 0x07, 0x8c, 0xb6, 0xfa, 0x13, 0xd0, 0xfc, 0xc5, 0xdc, + 0xb2, 0xcd, 0x65, 0x59, 0xc2, 0x3a, 0x24, 0x47, 0x1c, 0x53, 0x92, 0x57, + 0x21, 0xf3, 0x26, 0x9b, 0xe9, 0xa5, 0x95, 0x9a, 0xd6, 0xa5, 0xe2, 0xda, + 0x0e, 0xb7, 0xab, 0x9e, 0xee, 0xe3, 0xef, 0x59, 0xd2, 0x88, 0x32, 0x1f, + 0x0d, 0xbf, 0xf2, 0xa4, 0x3b, 0xd7, 0xd5, 0xf2, 0xa4, 0xae, 0x65, 0xab, + 0xb3, 0x72, 0xf6, 0x3b, 0xe8, 0xc5, 0x2b, 0xad, 0xcc, 0xbe, 0x02, 0x95, + 0x63, 0x95, 0x2c, 0x22, 0x74, 0x3a, 0x1b, 0xd5, 0xd1, 0x1d, 0xf8, 0x69, + 0x03, 0x98, 0x70, 0x66, 0x43, 0xb5, 0x6d, 0xd0, 0x27, 0x6a, 0x1c, 0xfc, + 0xf9, 0xaf, 0x71, 0x9b, 0x8c, 0xcb, 0xf8, 0xbd, 0x18, 0xad, 0x5f, 0xb7, + 0xbc, 0xfb, 0xbd, 0xde, 0xb9, 0xdc, 0x54, 0x65, 0x3b, 0xaf, 0xa7, 0x92, + 0xbe, 0x62, 0xdc, 0x25, 0x50, 0x48, 0x78, 0xd4, 0xed, 0xed, 0x96, 0x3f, + 0x53, 0xc5, 0xb5, 0x5f, 0xac, 0xa7, 0x5c, 0x92, 0xd9, 0xfe, 0x3b, 0xcd, + 0xbb, 0x29, 0xa0, 0xe0, 0x1e, 0xb0, 0x92, 0xad, 0x6b, 0x45, 0x29, 0x59, + 0xff, 0x5d, 0x5a, 0xfe, 0x8f, 0x63, 0x86, 0x6d, 0xa4, 0x4a, 0x53, 0xc4, + 0x3e, 0x39, 0xbf, 0xe5, 0x20, 0xbc, 0xd1, 0xdf, 0x59, 0x9c, 0x3a, 0x72, + 0x3b, 0x8f, 0xb2, 0x40, 0xe5, 0x9e, 0xa5, 0x02, 0x35, 0xd0, 0x4d, 0x6f, + 0x7d, 0xd5, 0x4c, 0xde, 0x51, 0x0a, 0x9a, 0x57, 0x43, 0x43, 0xe5, 0x97, + 0x95, 0x4b, 0xb2, 0x6c, 0xaf, 0x92, 0x4e, 0x52, 0x06, 0x0b, 0x72, 0x60, + 0x9e, 0x5c, 0xa1, 0xe3, 0x9b, 0xb3, 0x8c, 0x32, 0xcd, 0xc1, 0x4a, 0x88, + 0xd6, 0x3d, 0xed, 0xe8, 0x42, 0x5d, 0x53, 0xdd, 0x00, 0x52, 0x26, 0x2e, + 0xd5, 0x41, 0xf2, 0xfc, 0x51, 0x40, 0x45, 0xe4, 0x00, 0xe3, 0x1c, 0xfb, + 0x32, 0x33, 0x22, 0xed, 0x15, 0x12, 0x9b, 0xc4, 0x89, 0xd0, 0x0e, 0x95, + 0xad, 0xfd, 0x04, 0x2e, 0xee, 0x73, 0x06, 0xee, 0x23, 0xe2, 0xd3, 0x3d, + 0x44, 0x62, 0x35, 0xdc, 0x18, 0x9d, 0xf4, 0x9d, 0x92, 0x00, 0x4e, 0x8e, + 0x4e, 0x24, 0xa1, 0x2c, 0xb2, 0xb2, 0x3f, 0xfc, 0xe4, 0x27, 0x43, 0x3b, + 0x59, 0xb4, 0x13, 0xff, 0x57, 0xdf, 0x3d, 0xee, 0x1a, 0xab, 0x8c, 0x51, + 0xd9, 0x96, 0x1f, 0x2b, 0x66, 0x67, 0x42, 0xb6, 0x91, 0xfe, 0x8f, 0x4d, + 0xa6, 0xd3, 0x3b, 0x51, 0x45, 0x35, 0xab, 0xe5, 0x6e, 0x07, 0xed, 0x24, + 0x95, 0x3d, 0x6a, 0x47, 0x3f, 0x4e, 0xe4, 0x13, 0x5f, 0xfc, 0x19, 0xe8, + 0x09, 0x4b, 0x3d, 0xdf, 0x4f, 0xb4, 0xb4, 0xc1, 0x74, 0x31, 0xff, 0x13, + 0x00, 0xaf, 0x07, 0x16, 0xb6, 0x57, 0xfe, 0x6a, 0x37, 0x05, 0x62, 0x01, + 0xa0, 0xfa, 0xe2, 0xe5, 0x57, 0xcb, 0xa4, 0x5a, 0x57, 0xee, 0xd1, 0x5f, + 0x14, 0x23, 0xbe, 0xef, 0x9b, 0x91, 0x0f, 0x97, 0xa8, 0xf2, 0x36, 0xf7, + 0xc3, 0xb6, 0xbe, 0xe5, 0x59, 0x2b, 0x3c, 0xb3, 0x5d, 0x9f, 0x1e, 0x3b, + 0xd3, 0xf7, 0xee, 0x2e, 0xc0, 0x73, 0x6f, 0x2e, 0xfd, 0xc7, 0x3f, 0xfd, + 0x9c, 0xac, 0xbd, 0xa1, 0x8e, 0xcc, 0x59, 0x41, 0xa4, 0x41, 0xd3, 0x39, + 0x28, 0x67, 0x96, 0x14, 0x42, 0xc3, 0x38, 0x96, 0x0d, 0xfc, 0x68, 0x3d, + 0x2e, 0x2f, 0x46, 0x24, 0x66, 0x0d, 0xa6, 0x72, 0xc7, 0x27, 0x66, 0x3c, + 0xad, 0x55, 0xae, 0xbd, 0x34, 0xb4, 0x3b, 0x60, 0x73, 0xa5, 0xaa, 0xd4, + 0x56, 0x0b, 0x61, 0xf5, 0x5c, 0x66, 0x2e, 0x9d, 0x33, 0xfe, 0xfe, 0x7b, + 0x21, 0xbc, 0x36, 0xec, 0x0f, 0x03, 0x28, 0xa4, 0xd6, 0x05, 0x21, 0x30, + 0xf8, 0x3c, 0xd9, 0x3b, 0xaf, 0x5d, 0x92, 0x25, 0xce, 0xac, 0x28, 0xe1, + 0xd1, 0x02, 0x3c, 0x49, 0xe6, 0xed, 0xb7, 0x0e, 0xe7, 0xe7, 0x1e, 0x56, + 0xbf, 0x5d, 0xfd, 0xed, 0xdb, 0x4d, 0x63, 0x03, 0x8c, 0x06, 0x30, 0xfa, + 0x62, 0x78, 0x3f, 0x6e, 0x63, 0x1e, 0xa6, 0x4b, 0x96, 0xe9, 0xe4, 0x2d, + 0x16, 0x51, 0xf2, 0xf1, 0xa7, 0x2a, 0xeb, 0x15, 0xb5, 0xb1, 0x04, 0x9a, + 0xde, 0x77, 0xde, 0xcf, 0xcc, 0x21, 0xd9, 0x30, 0xf1, 0xea, 0xb9, 0xb0, + 0x39, 0xe1, 0x6f, 0xc7, 0x0a, 0xbd, 0x64, 0x75, 0x59, 0xbf, 0x3c, 0xbf, + 0xd0, 0xdb, 0x00, 0xfa, 0x2e, 0x36, 0xcc, 0xb5, 0xd1, 0x20, 0x46, 0xb0, + 0xd7, 0xfc, 0xb1, 0x5b, 0x54, 0x9f, 0xe2, 0xe1, 0xd0, 0x18, 0xa3, 0x51, + 0x62, 0x24, 0x0f, 0xa1, 0xa1, 0x9a, 0x47, 0x33, 0xca, 0xb9, 0x26, 0xb6, + 0x0b, 0x46, 0xd4, 0xb5, 0xc6, 0xbb, 0x72, 0x1e, 0x60, 0xeb, 0xb4, 0x9d, + 0x9f, 0x09, 0x10, 0x12, 0xce, 0x68, 0xa3, 0xb6, 0x8c, 0xce, 0xd7, 0x26, + 0x55, 0xb5, 0x90, 0x08, 0x9f, 0xf2, 0xa8, 0xc0, 0x56, 0xd8, 0xf6, 0x29, + 0x60, 0xe0, 0x73, 0x52, 0x22, 0x6f, 0x35, 0x4e, 0xe7, 0xc5, 0xa3, 0x95, + 0xcd, 0xd0, 0x8e, 0xd3, 0x95, 0xe3, 0x03, 0x04, 0x00, 0x54, 0xeb, 0xef, + 0x27, 0x11, 0xef, 0x38, 0x56, 0x6f, 0xa0, 0xe5, 0x72, 0x2a, 0x97, 0x23, + 0x56, 0xe2, 0x93, 0x21, 0x3f, 0xe2, 0xd6, 0x12, 0xcd, 0x61, 0x50, 0x44, + 0xd3, 0xe3, 0x8d, 0x3f, 0x24, 0x90, 0x6c, 0x53, 0xad, 0x1c, 0xad, 0x03, + 0x0f, 0x89, 0x63, 0xf9, 0xb9, 0xbc, 0xe2, 0x56, 0xdd, 0x16, 0xcf, 0x2d, + 0xa1, 0xda, 0xf9, 0x3f, 0xec, 0xbf, 0xb1, 0xb6, 0xe1, 0xdf, 0x3f, 0x11, + 0x02, 0x76, 0xe9, 0xe2, 0x9f, 0xa2, 0x02, 0xce, 0x3e, 0xf9, 0xcf, 0x4f, + 0xd9, 0x5f, 0x72, 0x5d, 0x51, 0xa7, 0x1d, 0x98, 0xeb, 0x8e, 0x97, 0x98, + 0x39, 0x58, 0x52, 0x11, 0xed, 0x95, 0x3c, 0x94, 0xf0, 0x6c, 0xa2, 0x3e, + 0x5f, 0x5f, 0x05, 0x98, 0xf1, 0x73, 0xab, 0xc7, 0xa8, 0x4b, 0x92, 0x73, + 0xda, 0x59, 0x1d, 0x56, 0x11, 0xc2, 0x38, 0x43, 0xdb, 0x4b, 0xbe, 0x08, + 0xdd, 0xf2, 0x5d, 0x47, 0x26, 0xdc, 0x16, 0xf9, 0x62, 0xf8, 0x92, 0x19, + 0x5c, 0x6f, 0x2b, 0xe1, 0x15, 0x66, 0xfa, 0xdb, 0x3a, 0xe0, 0x92, 0x9c, + 0x70, 0x91, 0x3f, 0xb8, 0xb0, 0x01, 0xc1, 0x44, 0xf6, 0x62, 0x47, 0x37, + 0xe9, 0xd9, 0x4c, 0x0f, 0x99, 0x6a, 0xc4, 0x60, 0x26, 0x2f, 0xc6, 0x43, + 0x50, 0x62, 0xee, 0x44, 0x21, 0xbd, 0xad, 0x50, 0x2d, 0x58, 0x78, 0xea, + 0x5a, 0x5f, 0x5c, 0xf7, 0x28, 0xa9, 0xdf, 0x0e, 0xd3, 0x67, 0xdf, 0x1f, + 0x4c, 0xd3, 0xe9, 0x5e, 0x0f, 0xa3, 0xb7, 0x56, 0xa5, 0x4e, 0x5f, 0x2a, + 0xb6, 0x14, 0x5e, 0x2f, 0x16, 0x71, 0x48, 0x59, 0x77, 0x6b, 0xf9, 0x6c, + 0x79, 0xba, 0xc4, 0x26, 0x30, 0x44, 0x61, 0x62, 0x60, 0xef, 0x35, 0x95, + 0xe3, 0x77, 0xd5, 0xc8, 0x44, 0xa4, 0xf8, 0x95, 0xba, 0xd1, 0x73, 0x6f, + 0x92, 0xf2, 0xd3, 0x98, 0x4c, 0x8f, 0xe0, 0x2e, 0x27, 0xaa, 0x2f, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x0e, 0xfe, 0xff, 0xff, 0xbb, 0xfd, 0xff, 0xff, 0xe1, 0x05, 0x00, 0x00, + 0x4b, 0x0f, 0x00, 0x00, 0x8e, 0x15, 0x00, 0x00, 0x7f, 0x04, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x53, 0xe6, 0xff, 0xff, 0xa6, 0x04, 0x00, 0x00, + 0xdf, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x7f, 0xfd, 0xff, 0xff, 0x3e, 0xf8, 0xff, 0xff, + 0xae, 0x03, 0x00, 0x00, 0x5c, 0xfe, 0xff, 0xff, 0x82, 0xfa, 0xff, 0xff, + 0xbd, 0xf8, 0xff, 0xff, 0x04, 0xfe, 0xff, 0xff, 0x8c, 0xfe, 0xff, 0xff, + 0x9b, 0xf8, 0xff, 0xff, 0x51, 0x02, 0x00, 0x00, 0x19, 0xfe, 0xff, 0xff, + 0x54, 0xfe, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xe7, 0xfd, 0xff, 0xff, + 0xc2, 0x07, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x57, 0xfd, 0xff, 0xff, + 0xa3, 0x03, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00, 0x00, + 0x9b, 0xf7, 0xff, 0xff, 0xc7, 0x04, 0x00, 0x00, 0xbf, 0x06, 0x00, 0x00, + 0x86, 0xfe, 0xff, 0xff, 0x20, 0xfb, 0xff, 0xff, 0x90, 0xfc, 0xff, 0xff, + 0x16, 0x00, 0x00, 0x00, 0x8e, 0xff, 0xff, 0xff, 0xa0, 0x03, 0x00, 0x00, + 0xc7, 0xff, 0xff, 0xff, 0x51, 0x01, 0x00, 0x00, 0x24, 0xf8, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xee, 0x01, 0x00, 0x00, + 0xda, 0x02, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xc4, 0xfe, 0xff, 0xff, 0xfa, 0xfc, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, + 0x6a, 0xff, 0xff, 0xff, 0x92, 0x02, 0x00, 0x00, 0xa4, 0xff, 0xff, 0xff, + 0xfd, 0xfe, 0xff, 0xff, 0x4e, 0xfd, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, + 0x19, 0xfe, 0xff, 0xff, 0x17, 0xff, 0xff, 0xff, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf4, 0xf3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0xf4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x4d, 0x4c, 0x49, 0x52, + 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, + 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xec, 0x01, 0x00, 0x00, + 0xe0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x82, 0xfe, 0xff, 0xff, + 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x07, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc8, 0xf4, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xe6, 0xfe, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x07, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xc2, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb4, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x00, + 0x07, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x06, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xb8, 0x0d, 0x00, 0x00, + 0x64, 0x0c, 0x00, 0x00, 0x64, 0x0a, 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, + 0x9c, 0x09, 0x00, 0x00, 0x20, 0x09, 0x00, 0x00, 0x6c, 0x07, 0x00, 0x00, + 0x78, 0x04, 0x00, 0x00, 0x74, 0x03, 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, + 0xbc, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc8, 0xff, 0xff, 0xff, + 0x28, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x30, 0xf3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0x6c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x14, 0xf3, 0xff, 0xff, + 0x2c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0xc2, 0x47, 0x3b, + 0x01, 0x00, 0x00, 0x00, 0x8d, 0xf4, 0xad, 0x3e, 0x01, 0x00, 0x00, 0x00, + 0x15, 0x00, 0xe0, 0xbe, 0x0d, 0x00, 0x00, 0x00, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x38, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0xb0, 0xf3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x7c, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x04, 0x00, 0x00, 0x94, 0xf3, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6c, 0x02, 0xa5, 0x3a, + 0x01, 0x00, 0x00, 0x00, 0x6a, 0x5d, 0xa4, 0x3e, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x66, 0x6c, 0x61, 0x74, 0x74, + 0x65, 0x6e, 0x2f, 0x52, 0x65, 0x73, 0x68, 0x61, 0x70, 0x65, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, + 0x40, 0xf4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x8c, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x2c, 0xf4, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x02, 0xa5, 0x3a, 0x01, 0x00, 0x00, 0x00, + 0x6a, 0x5d, 0xa4, 0x3e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x69, + 0x6e, 0x67, 0x32, 0x64, 0x2f, 0x4d, 0x61, 0x78, 0x50, 0x6f, 0x6f, 0x6c, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0xe8, 0xf4, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xec, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0xd4, 0xf4, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x02, 0xa5, 0x3a, 0x01, 0x00, 0x00, 0x00, + 0x6a, 0x5d, 0xa4, 0x3e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x2f, + 0x52, 0x65, 0x6c, 0x75, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, + 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, 0x3b, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, + 0x32, 0x64, 0x5f, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x3b, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x2f, 0x42, 0x69, 0x61, 0x73, + 0x41, 0x64, 0x64, 0x2f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0xf0, 0xf5, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0xe4, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xdc, 0xf5, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x15, 0xa1, 0x10, 0x3b, 0x01, 0x00, 0x00, 0x00, + 0x74, 0x10, 0x10, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x2f, 0x52, 0x65, + 0x6c, 0x75, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, + 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x2f, 0x42, 0x69, 0x61, + 0x73, 0x41, 0x64, 0x64, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x2f, 0x43, + 0x6f, 0x6e, 0x76, 0x32, 0x44, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x2f, + 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, 0x2f, 0x52, 0x65, 0x61, 0x64, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x70, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x3a, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, + 0xd4, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xc4, 0xf6, 0xff, 0xff, 0x1c, 0x02, 0x00, 0x00, + 0x94, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0xb9, 0x37, 0x74, 0x3a, 0x8b, 0xfe, 0x77, 0x3a, 0x54, 0xc7, 0x75, 0x3a, + 0xc4, 0x11, 0x78, 0x3a, 0xb9, 0x90, 0x74, 0x3a, 0x3b, 0x97, 0x7b, 0x3a, + 0xe8, 0x57, 0x75, 0x3a, 0x0c, 0x0e, 0x74, 0x3a, 0x76, 0x8b, 0x79, 0x3a, + 0x2b, 0x7b, 0x6d, 0x3a, 0x17, 0xad, 0x71, 0x3a, 0xe4, 0x9b, 0x77, 0x3a, + 0x0b, 0xab, 0x7a, 0x3a, 0x9e, 0x12, 0x75, 0x3a, 0x8c, 0xcf, 0x79, 0x3a, + 0xa0, 0x5a, 0x79, 0x3a, 0x74, 0xc3, 0x78, 0x3a, 0x0e, 0xa9, 0x74, 0x3a, + 0x6b, 0xf8, 0x6f, 0x3a, 0x53, 0xeb, 0x72, 0x3a, 0xff, 0xe2, 0x73, 0x3a, + 0x3b, 0x38, 0x78, 0x3a, 0xed, 0x9e, 0x76, 0x3a, 0x77, 0xbc, 0x6d, 0x3a, + 0x4f, 0xf5, 0x71, 0x3a, 0x17, 0xc9, 0x74, 0x3a, 0x87, 0x84, 0x6b, 0x3a, + 0x4b, 0xc5, 0x78, 0x3a, 0xdd, 0x02, 0x75, 0x3a, 0x0e, 0xcf, 0x78, 0x3a, + 0x14, 0x40, 0x75, 0x3a, 0x2e, 0xca, 0x72, 0x3a, 0x20, 0x00, 0x00, 0x00, + 0x95, 0x2f, 0xef, 0x3d, 0x47, 0x1c, 0xf0, 0x3d, 0xc5, 0xdb, 0xf3, 0x3d, + 0x2e, 0x57, 0xe7, 0x3d, 0x98, 0xa7, 0xf2, 0x3d, 0x98, 0x89, 0xe4, 0x3d, + 0x38, 0x6d, 0xf3, 0x3d, 0x3f, 0x38, 0xe2, 0x3d, 0x91, 0x6f, 0xf0, 0x3d, + 0x35, 0xa0, 0xeb, 0x3d, 0x42, 0x3d, 0xeb, 0x3d, 0xed, 0x89, 0xe7, 0x3d, + 0xb5, 0xb5, 0xf8, 0x3d, 0x79, 0x28, 0xf3, 0x3d, 0xed, 0xdb, 0xf7, 0x3d, + 0xeb, 0x67, 0xf7, 0x3d, 0xed, 0xd1, 0xf6, 0x3d, 0xbc, 0xbf, 0xf2, 0x3d, + 0x7a, 0x18, 0xee, 0x3d, 0x7c, 0x05, 0xf1, 0x3d, 0x63, 0x69, 0xe8, 0x3d, + 0xbb, 0xc0, 0xf1, 0x3d, 0xaf, 0xb1, 0xf4, 0x3d, 0xfe, 0xe0, 0xeb, 0x3d, + 0xb6, 0x60, 0xec, 0x3d, 0x8c, 0x32, 0xf0, 0x3d, 0x7e, 0xad, 0xe9, 0x3d, + 0xc0, 0xd3, 0xf6, 0x3d, 0xd7, 0x18, 0xf3, 0x3d, 0x40, 0x53, 0xf0, 0x3d, + 0x2c, 0xdc, 0xf1, 0x3d, 0x9a, 0xe4, 0xf0, 0x3d, 0x20, 0x00, 0x00, 0x00, + 0x4a, 0x4f, 0xf2, 0xbd, 0x8e, 0x0e, 0xf6, 0xbd, 0x74, 0x46, 0xec, 0xbd, + 0xa0, 0x21, 0xf6, 0xbd, 0x8e, 0x27, 0xf0, 0xbd, 0x0d, 0xa0, 0xf9, 0xbd, + 0x0c, 0x97, 0xec, 0xbd, 0xf0, 0x25, 0xf2, 0xbd, 0x5f, 0x98, 0xf7, 0xbd, + 0x27, 0x8d, 0xe8, 0xbd, 0xbd, 0xc9, 0xef, 0xbd, 0xac, 0xac, 0xf5, 0xbd, + 0x5a, 0x94, 0xed, 0xbd, 0x5a, 0x64, 0xf1, 0xbd, 0x2a, 0xa7, 0xe9, 0xbd, + 0x3c, 0x93, 0xf3, 0xbd, 0xf8, 0x2b, 0xf3, 0xbd, 0xf6, 0x35, 0xed, 0xbd, + 0x94, 0xf4, 0xed, 0xbd, 0x70, 0x94, 0xe9, 0xbd, 0x39, 0xfb, 0xf1, 0xbd, + 0xcb, 0x47, 0xf6, 0xbd, 0x88, 0xb9, 0xe7, 0xbd, 0x49, 0x62, 0xe9, 0xbd, + 0x64, 0x11, 0xf0, 0xbd, 0x85, 0xdf, 0xf2, 0xbd, 0x5c, 0x61, 0xe8, 0xbd, + 0x22, 0x46, 0xf3, 0xbd, 0x5a, 0x8e, 0xf0, 0xbd, 0x70, 0xdd, 0xf6, 0xbd, + 0x94, 0x55, 0xf3, 0xbd, 0x57, 0xba, 0xf0, 0xbd, 0x1a, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x2f, 0x43, 0x6f, 0x6e, 0x76, + 0x32, 0x44, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x2a, 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x94, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xb4, 0xf9, 0xff, 0xff, 0x1c, 0x01, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xe6, 0x69, 0xc5, 0x3a, 0xa0, 0x8d, 0xa8, 0x3a, 0xfe, 0x5c, 0xc1, 0x3a, + 0x84, 0x01, 0xcb, 0x3a, 0xa2, 0xc2, 0xb5, 0x3a, 0x42, 0x01, 0xd1, 0x3a, + 0xd7, 0x01, 0xcc, 0x3a, 0x20, 0xd8, 0xc7, 0x3a, 0x28, 0x80, 0xa4, 0x3a, + 0xd9, 0x25, 0xbe, 0x3a, 0x39, 0x6f, 0xc4, 0x3a, 0x59, 0x6c, 0xcb, 0x3a, + 0xb8, 0x0a, 0xc2, 0x3a, 0x73, 0x3f, 0xca, 0x3a, 0xb9, 0xed, 0xc5, 0x3a, + 0xe9, 0x9f, 0xc1, 0x3a, 0x10, 0x00, 0x00, 0x00, 0x5b, 0x2e, 0x2f, 0x3e, + 0x3e, 0xd9, 0x06, 0x3e, 0x44, 0xda, 0x3f, 0x3e, 0xd3, 0x09, 0x22, 0x3e, + 0x1d, 0x57, 0x34, 0x3e, 0xa4, 0xb6, 0x44, 0x3e, 0xd3, 0x69, 0x4a, 0x3e, + 0x70, 0x48, 0x46, 0x3e, 0x28, 0x37, 0x23, 0x3e, 0xe6, 0xdb, 0x06, 0x3e, + 0x3c, 0x1d, 0x34, 0x3e, 0x36, 0xba, 0x16, 0x3e, 0x24, 0xa4, 0x34, 0x3e, + 0xf4, 0xfb, 0x37, 0x3e, 0xd6, 0x7b, 0x8a, 0x3d, 0x00, 0x85, 0xe3, 0x3d, + 0x10, 0x00, 0x00, 0x00, 0x12, 0xdf, 0x43, 0xbe, 0x85, 0x3c, 0x27, 0xbe, + 0x54, 0xcd, 0x0d, 0xbe, 0x81, 0x6b, 0x49, 0xbe, 0x33, 0xb1, 0xe7, 0xbd, + 0x3f, 0x5f, 0x4f, 0xbe, 0xa1, 0x63, 0x3e, 0xbe, 0xbb, 0xa7, 0xea, 0xbd, + 0x2d, 0x8c, 0x0e, 0xbe, 0x8d, 0xa9, 0x3c, 0xbe, 0x5b, 0xe6, 0x42, 0xbe, + 0x80, 0xd5, 0x49, 0xbe, 0xa3, 0x86, 0x40, 0xbe, 0xf4, 0xaa, 0x48, 0xbe, + 0xde, 0x61, 0x44, 0xbe, 0xa9, 0x1c, 0x40, 0xbe, 0x18, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x2f, 0x43, 0x6f, 0x6e, 0x76, 0x32, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xda, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x09, 0x64, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x64, 0xfb, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x72, 0x1e, 0x3a, 0x01, 0x00, 0x00, 0x00, 0x32, 0xe2, 0x9b, 0x3d, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x35, 0x9d, 0xbd, 0x17, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x64, + 0x65, 0x6e, 0x73, 0x65, 0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, + 0x52, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x38, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x66, + 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x9a, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x68, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x8c, 0xfd, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xfc, 0x41, 0x4c, 0x35, 0x30, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x64, + 0x65, 0x6e, 0x73, 0x65, 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, + 0x2f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x4f, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x12, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xdc, 0x01, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0xfe, 0xff, 0xff, 0x0c, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x03, 0xf9, 0x09, 0x36, 0x3a, 0x1b, 0x0c, 0x36, 0xc6, 0xda, 0x0a, 0x36, + 0x16, 0x26, 0x0c, 0x36, 0x4b, 0x2b, 0x0a, 0x36, 0x60, 0x23, 0x0e, 0x36, + 0xd3, 0x9b, 0x0a, 0x36, 0x78, 0xe1, 0x09, 0x36, 0x78, 0xfb, 0x0c, 0x36, + 0xb6, 0x2a, 0x06, 0x36, 0x6f, 0x89, 0x08, 0x36, 0x7e, 0xe3, 0x0b, 0x36, + 0xf0, 0x9d, 0x0d, 0x36, 0xae, 0x74, 0x0a, 0x36, 0xef, 0x21, 0x0d, 0x36, + 0xe0, 0xdf, 0x0c, 0x36, 0x79, 0x8a, 0x0c, 0x36, 0x0a, 0x39, 0x0a, 0x36, + 0xbb, 0x92, 0x07, 0x36, 0x39, 0x3d, 0x09, 0x36, 0x25, 0xc9, 0x09, 0x36, + 0xd1, 0x3b, 0x0c, 0x36, 0x93, 0x54, 0x0b, 0x36, 0x9a, 0x4f, 0x06, 0x36, + 0x3c, 0xb2, 0x08, 0x36, 0x23, 0x4b, 0x0a, 0x36, 0xbe, 0x0e, 0x05, 0x36, + 0x83, 0x8b, 0x0c, 0x36, 0xc7, 0x6b, 0x0a, 0x36, 0x07, 0x91, 0x0c, 0x36, + 0x5d, 0x8e, 0x0a, 0x36, 0x7f, 0x2a, 0x09, 0x36, 0x33, 0x00, 0x00, 0x00, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, + 0x6f, 0x6e, 0x76, 0x32, 0x64, 0x5f, 0x31, 0x2f, 0x42, 0x69, 0x61, 0x73, + 0x41, 0x64, 0x64, 0x2f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, + 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x2c, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xe1, 0x22, 0xc6, 0x36, 0x90, 0x2b, 0xa9, 0x36, 0x2d, 0x12, 0xc2, 0x36, + 0xbc, 0xbf, 0xcb, 0x36, 0xf2, 0x6c, 0xb6, 0x36, 0x19, 0xc5, 0xd1, 0x36, + 0xff, 0xc0, 0xcc, 0x36, 0x62, 0x93, 0xc8, 0x36, 0x4c, 0x1a, 0xa5, 0x36, + 0x05, 0xd8, 0xbe, 0x36, 0x49, 0x27, 0xc5, 0x36, 0xf5, 0x2a, 0xcc, 0x36, + 0x8a, 0xc0, 0xc2, 0x36, 0xf5, 0xfc, 0xca, 0x36, 0x2f, 0xa7, 0xc6, 0x36, + 0x57, 0x55, 0xc2, 0x36, 0x31, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x32, + 0x64, 0x2f, 0x42, 0x69, 0x61, 0x73, 0x41, 0x64, 0x64, 0x2f, 0x52, 0x65, + 0x61, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x70, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x1c, 0x00, + 0x08, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x77, 0x80, 0x3b, + 0x01, 0x00, 0x00, 0x00, 0xf0, 0xee, 0x7f, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6e, 0x76, + 0x32, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x74, + 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xca, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x06, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xe6, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0a, 0x00, + 0x0e, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, + 0x0c, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00}; + +const unsigned int kTestConvModelDataSize = 21344; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.h b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.h new file mode 100644 index 0000000..2103196 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_conv_model.h @@ -0,0 +1,23 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_MICRO_TESTING_TEST_CONV_MODEL_H_ +#define TENSORFLOW_LITE_MICRO_TESTING_TEST_CONV_MODEL_H_ + +// See generate_test_models.py for updating the contents of this model: +extern const unsigned char kTestConvModelData[]; +extern const unsigned int kTestConvModelDataSize; + +#endif // TENSORFLOW_LITE_MICRO_TESTING_TEST_CONV_MODEL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.cc b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.cc new file mode 100644 index 0000000..4d931bd --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.cc @@ -0,0 +1,240 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/micro/testing/test_utils.h" + +#include "tensorflow/lite/micro/simple_memory_allocator.h" + +namespace tflite { +namespace testing { + +namespace { +// TODO(b/141330728): Refactor out of test_utils.cc +// The variables below (and the AllocatePersistentBuffer function) are only +// needed for the kernel tests and benchmarks, i.e. where we do not have an +// interpreter object, and the fully featured MicroAllocator. +// Currently, these need to be sufficient for all the kernel_tests. If that +// becomes problematic, we can investigate allowing the arena_size to be +// specified for each call to PopulatContext. +constexpr size_t kArenaSize = 10000; +uint8_t raw_arena_[kArenaSize]; +SimpleMemoryAllocator* simple_memory_allocator_ = nullptr; +constexpr size_t kBufferAlignment = 16; + +// We store the pointer to the ith scratch buffer to implement the Request/Get +// ScratchBuffer API for the tests. scratch_buffers_[i] will be the ith scratch +// buffer and will still be allocated from within raw_arena_. +constexpr int kNumScratchBuffers = 5; +uint8_t* scratch_buffers_[kNumScratchBuffers]; +int scratch_buffer_count_ = 0; + +// Note that the context parameter in this function is only needed to match the +// signature of TfLiteContext::AllocatePersistentBuffer and isn't needed in the +// implementation because we are assuming a single global +// simple_memory_allocator_ +void* AllocatePersistentBuffer(TfLiteContext* context, size_t bytes) { + TFLITE_DCHECK(simple_memory_allocator_ != nullptr); + return simple_memory_allocator_->AllocateFromTail(bytes, kBufferAlignment); +} + +TfLiteStatus RequestScratchBufferInArena(TfLiteContext* context, size_t bytes, + int* buffer_index) { + TFLITE_DCHECK(simple_memory_allocator_ != nullptr); + TFLITE_DCHECK(buffer_index != nullptr); + + if (scratch_buffer_count_ == kNumScratchBuffers) { + TF_LITE_REPORT_ERROR( + static_cast(context->impl_), + "Exceeded the maximum number of scratch tensors allowed (%d).", + kNumScratchBuffers); + return kTfLiteError; + } + + // For tests, we allocate scratch buffers from the tail and keep them around + // for the lifetime of model. This means that the arena size in the tests will + // be more than what we would have if the scratch buffers could share memory. + scratch_buffers_[scratch_buffer_count_] = + simple_memory_allocator_->AllocateFromTail(bytes, kBufferAlignment); + TFLITE_DCHECK(scratch_buffers_[scratch_buffer_count_] != nullptr); + + *buffer_index = scratch_buffer_count_++; + return kTfLiteOk; +} + +void* GetScratchBuffer(TfLiteContext* context, int buffer_index) { + TFLITE_DCHECK(scratch_buffer_count_ <= kNumScratchBuffers); + if (buffer_index >= scratch_buffer_count_) { + return nullptr; + } + return scratch_buffers_[buffer_index]; +} + +TfLiteTensor* GetTensor(const struct TfLiteContext* context, int subgraph_idx) { + // TODO(b/160894903): Return this value from temp allocated memory. + return &context->tensors[subgraph_idx]; +} + +} // namespace + +uint8_t F2Q(float value, float min, float max) { + int32_t result = ZeroPointFromMinMax(min, max) + + (value / ScaleFromMinMax(min, max)) + 0.5f; + if (result < std::numeric_limits::min()) { + result = std::numeric_limits::min(); + } + if (result > std::numeric_limits::max()) { + result = std::numeric_limits::max(); + } + return result; +} + +// Converts a float value into a signed eight-bit quantized value. +int8_t F2QS(float value, float min, float max) { + return F2Q(value, min, max) + std::numeric_limits::min(); +} + +int32_t F2Q32(float value, float scale) { + double quantized = static_cast(value / scale); + if (quantized > std::numeric_limits::max()) { + quantized = std::numeric_limits::max(); + } else if (quantized < std::numeric_limits::min()) { + quantized = std::numeric_limits::min(); + } + return static_cast(quantized); +} + +// TODO(b/141330728): Move this method elsewhere as part clean up. +void PopulateContext(TfLiteTensor* tensors, int tensors_size, + ErrorReporter* error_reporter, TfLiteContext* context) { + simple_memory_allocator_ = + SimpleMemoryAllocator::Create(error_reporter, raw_arena_, kArenaSize); + TFLITE_DCHECK(simple_memory_allocator_ != nullptr); + scratch_buffer_count_ = 0; + + context->tensors_size = tensors_size; + context->tensors = tensors; + context->impl_ = static_cast(error_reporter); + context->GetExecutionPlan = nullptr; + context->ResizeTensor = nullptr; + context->ReportError = ReportOpError; + context->AddTensors = nullptr; + context->GetNodeAndRegistration = nullptr; + context->ReplaceNodeSubsetsWithDelegateKernels = nullptr; + context->recommended_num_threads = 1; + context->GetExternalContext = nullptr; + context->SetExternalContext = nullptr; + + context->GetTensor = GetTensor; + context->GetEvalTensor = nullptr; + + context->AllocatePersistentBuffer = AllocatePersistentBuffer; + context->RequestScratchBufferInArena = RequestScratchBufferInArena; + context->GetScratchBuffer = GetScratchBuffer; + + for (int i = 0; i < tensors_size; ++i) { + if (context->tensors[i].is_variable) { + ResetVariableTensor(&context->tensors[i]); + } + } +} + +TfLiteTensor CreateQuantizedTensor(const uint8_t* data, TfLiteIntArray* dims, + float min, float max, bool is_variable) { + TfLiteTensor result; + result.type = kTfLiteUInt8; + result.data.uint8 = const_cast(data); + result.dims = dims; + result.params = {ScaleFromMinMax(min, max), + ZeroPointFromMinMax(min, max)}; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(uint8_t); + result.is_variable = false; + return result; +} + +TfLiteTensor CreateQuantizedTensor(const int8_t* data, TfLiteIntArray* dims, + float min, float max, bool is_variable) { + TfLiteTensor result; + result.type = kTfLiteInt8; + result.data.int8 = const_cast(data); + result.dims = dims; + result.params = {ScaleFromMinMax(min, max), + ZeroPointFromMinMax(min, max)}; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(int8_t); + result.is_variable = is_variable; + return result; +} + +TfLiteTensor CreateQuantizedTensor(float* data, uint8_t* quantized_data, + TfLiteIntArray* dims, bool is_variable) { + TfLiteTensor result; + SymmetricQuantize(data, dims, quantized_data, &result.params.scale); + result.data.uint8 = quantized_data; + result.type = kTfLiteUInt8; + result.dims = dims; + result.params.zero_point = 128; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(uint8_t); + result.is_variable = is_variable; + return result; +} + +TfLiteTensor CreateQuantizedTensor(float* data, int8_t* quantized_data, + TfLiteIntArray* dims, bool is_variable) { + TfLiteTensor result; + SignedSymmetricQuantize(data, dims, quantized_data, &result.params.scale); + result.data.int8 = quantized_data; + result.type = kTfLiteInt8; + result.dims = dims; + result.params.zero_point = 0; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(int8_t); + result.is_variable = is_variable; + return result; +} + +TfLiteTensor CreateQuantizedTensor(float* data, int16_t* quantized_data, + TfLiteIntArray* dims, bool is_variable) { + TfLiteTensor result; + SignedSymmetricQuantize(data, dims, quantized_data, &result.params.scale); + result.data.i16 = quantized_data; + result.type = kTfLiteInt16; + result.dims = dims; + result.params.zero_point = 0; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(int16_t); + result.is_variable = is_variable; + return result; +} + +TfLiteTensor CreateQuantized32Tensor(const int32_t* data, TfLiteIntArray* dims, + float scale, bool is_variable) { + TfLiteTensor result; + result.type = kTfLiteInt32; + result.data.i32 = const_cast(data); + result.dims = dims; + // Quantized int32_t tensors always have a zero point of 0, since the range of + // int32_t values is large, and because zero point costs extra cycles during + // processing. + result.params = {scale, 0}; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(int32_t); + result.is_variable = is_variable; + return result; +} + +} // namespace testing +} // namespace tflite diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.h b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.h new file mode 100644 index 0000000..e83ac80 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/testing/test_utils.h @@ -0,0 +1,116 @@ +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_MICRO_TESTING_TEST_UTILS_H_ +#define TENSORFLOW_LITE_MICRO_TESTING_TEST_UTILS_H_ + +#include +#include +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/core/api/tensor_utils.h" +#include "tensorflow/lite/micro/micro_utils.h" +#include "tensorflow/lite/micro/test_helpers.h" +#include "tensorflow/lite/micro/testing/micro_test.h" + +namespace tflite { +namespace testing { + +// Note: These methods are deprecated, do not use. See b/141332970. + + +// Derives the quantization range max from scaling factor and zero point. +template +inline float MaxFromZeroPointScale(const int zero_point, const float scale) { + return (std::numeric_limits::max() - zero_point) * scale; +} + +// Derives the quantization range min from scaling factor and zero point. +template +inline float MinFromZeroPointScale(const int zero_point, const float scale) { + return (std::numeric_limits::min() - zero_point) * scale; +} + +// Derives the quantization scaling factor from a min and max range. +template +inline float ScaleFromMinMax(const float min, const float max) { + return (max - min) / + static_cast((std::numeric_limits::max() * 1.0) - + std::numeric_limits::min()); +} + +// Derives the quantization zero point from a min and max range. +template +inline int ZeroPointFromMinMax(const float min, const float max) { + return static_cast(std::numeric_limits::min()) + + static_cast(-min / ScaleFromMinMax(min, max) + 0.5f); +} + +// Converts a float value into an unsigned eight-bit quantized value. +uint8_t F2Q(float value, float min, float max); + +// Converts a float value into a signed eight-bit quantized value. +int8_t F2QS(const float value, const float min, const float max); + +// Converts a float value into a signed thirty-two-bit quantized value. Note +// that values close to max int and min int may see significant error due to +// a lack of floating point granularity for large values. +int32_t F2Q32(const float value, const float scale); + +// TODO(b/141330728): Move this method elsewhere as part clean up. +void PopulateContext(TfLiteTensor* tensors, int tensors_size, + ErrorReporter* error_reporter, TfLiteContext* context); + +TfLiteTensor CreateQuantizedTensor(const uint8_t* data, TfLiteIntArray* dims, + float min, float max, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(const int8_t* data, TfLiteIntArray* dims, + float min, float max, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(float* data, uint8_t* quantized_data, + TfLiteIntArray* dims, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(float* data, int8_t* quantized_data, + TfLiteIntArray* dims, + bool is_variable = false); + +TfLiteTensor CreateQuantizedTensor(float* data, int16_t* quantized_data, + TfLiteIntArray* dims, + bool is_variable = false); + +TfLiteTensor CreateQuantized32Tensor(const int32_t* data, TfLiteIntArray* dims, + float scale, bool is_variable = false); + +template +inline TfLiteTensor CreateTensor(const input_type* data, TfLiteIntArray* dims, + bool is_variable = false) { + TfLiteTensor result; + result.type = tensor_input_type; + result.data.raw = reinterpret_cast(const_cast(data)); + result.dims = dims; + result.allocation_type = kTfLiteMemNone; + result.bytes = ElementCount(*dims) * sizeof(input_type); + result.is_variable = is_variable; + return result; +} + +} // namespace testing +} // namespace tflite + +#endif // TENSORFLOW_LITE_MICRO_TESTING_TEST_UTILS_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_common_tables.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_common_tables.h new file mode 100644 index 0000000..e82e62d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_common_tables.h @@ -0,0 +1,528 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + /* Double Precision Float CFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024) + extern const uint16_t armBitRevTable[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_16) + extern const uint64_t twiddleCoefF64_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_32) + extern const uint64_t twiddleCoefF64_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_64) + extern const uint64_t twiddleCoefF64_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_128) + extern const uint64_t twiddleCoefF64_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_256) + extern const uint64_t twiddleCoefF64_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_512) + extern const uint64_t twiddleCoefF64_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_1024) + extern const uint64_t twiddleCoefF64_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_2048) + extern const uint64_t twiddleCoefF64_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_4096) + extern const uint64_t twiddleCoefF64_4096[8192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) + extern const float32_t twiddleCoef_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + extern const float32_t twiddleCoef_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) + extern const float32_t twiddleCoef_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + extern const float32_t twiddleCoef_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) + extern const float32_t twiddleCoef_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + extern const float32_t twiddleCoef_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) + extern const float32_t twiddleCoef_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + extern const float32_t twiddleCoef_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) + extern const float32_t twiddleCoef_4096[8192]; + #define twiddleCoef twiddleCoef_4096 + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + /* Q31 */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) + extern const q31_t twiddleCoef_16_q31[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + extern const q31_t twiddleCoef_32_q31[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) + extern const q31_t twiddleCoef_64_q31[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + extern const q31_t twiddleCoef_128_q31[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) + extern const q31_t twiddleCoef_256_q31[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + extern const q31_t twiddleCoef_512_q31[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) + extern const q31_t twiddleCoef_1024_q31[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + extern const q31_t twiddleCoef_2048_q31[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) + extern const q31_t twiddleCoef_4096_q31[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) + extern const q15_t twiddleCoef_16_q15[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + extern const q15_t twiddleCoef_32_q15[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) + extern const q15_t twiddleCoef_64_q15[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + extern const q15_t twiddleCoef_128_q15[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) + extern const q15_t twiddleCoef_256_q15[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + extern const q15_t twiddleCoef_512_q15[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) + extern const q15_t twiddleCoef_1024_q15[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + extern const q15_t twiddleCoef_2048_q15[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) + extern const q15_t twiddleCoef_4096_q15[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + /* Double Precision Float RFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_32) + extern const uint64_t twiddleCoefF64_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_64) + extern const uint64_t twiddleCoefF64_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_128) + extern const uint64_t twiddleCoefF64_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_256) + extern const uint64_t twiddleCoefF64_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_512) + extern const uint64_t twiddleCoefF64_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_1024) + extern const uint64_t twiddleCoefF64_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_2048) + extern const uint64_t twiddleCoefF64_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_4096) + extern const uint64_t twiddleCoefF64_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32) + extern const float32_t twiddleCoef_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64) + extern const float32_t twiddleCoef_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128) + extern const float32_t twiddleCoef_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256) + extern const float32_t twiddleCoef_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512) + extern const float32_t twiddleCoef_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024) + extern const float32_t twiddleCoef_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048) + extern const float32_t twiddleCoef_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096) + extern const float32_t twiddleCoef_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* Double precision floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_16) + #define ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTableF64_16[ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_32) + #define ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTableF64_32[ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_64) + #define ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTableF64_64[ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_128) + #define ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTableF64_128[ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_256) + #define ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTableF64_256[ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_512) + #define ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTableF64_512[ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_1024) + #define ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTableF64_1024[ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_2048) + #define ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTableF64_2048[ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_4096) + #define ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTableF64_4096[ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + /* floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16) + #define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) + extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32) + #define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) + extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64) + #define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128) + #define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) + extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256) + #define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) + extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512) + #define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) + extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024) + #define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) + extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048) + #define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) + extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096) + #define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* fixed-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16) + #define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32) + #define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64) + #define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128) + #define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256) + #define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512) + #define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024) + #define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048) + #define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096) + #define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32) + extern const float32_t realCoefA[8192]; + extern const float32_t realCoefB[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31) + extern const q31_t realCoefAQ31[8192]; + extern const q31_t realCoefBQ31[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15) + extern const q15_t realCoefAQ15[8192]; + extern const q15_t realCoefBQ15[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128) + extern const float32_t Weights_128[256]; + extern const float32_t cos_factors_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512) + extern const float32_t Weights_512[1024]; + extern const float32_t cos_factors_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048) + extern const float32_t Weights_2048[4096]; + extern const float32_t cos_factors_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192) + extern const float32_t Weights_8192[16384]; + extern const float32_t cos_factors_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128) + extern const q15_t WeightsQ15_128[256]; + extern const q15_t cos_factorsQ15_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512) + extern const q15_t WeightsQ15_512[1024]; + extern const q15_t cos_factorsQ15_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048) + extern const q15_t WeightsQ15_2048[4096]; + extern const q15_t cos_factorsQ15_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192) + extern const q15_t WeightsQ15_8192[16384]; + extern const q15_t cos_factorsQ15_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128) + extern const q31_t WeightsQ31_128[256]; + extern const q31_t cos_factorsQ31_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512) + extern const q31_t WeightsQ31_512[1024]; + extern const q31_t cos_factorsQ31_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048) + extern const q31_t WeightsQ31_2048[4096]; + extern const q31_t cos_factorsQ31_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192) + extern const q31_t WeightsQ31_8192[16384]; + extern const q31_t cos_factorsQ31_8192[8192]; + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */ + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES) + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15) + extern const q15_t armRecipTableQ15[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31) + extern const q31_t armRecipTableQ31[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + /* Tables for Fast Math Sine and Cosine */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32) + extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31) + extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15) + extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE) + extern const q31_t sqrtTable_Q31[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE) + extern const q15_t sqrtTable_Q15[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */ + +#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) + extern const float32_t exp_tab[8]; + extern const float32_t __logf_lut_f32[8]; +#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) */ + +#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) +extern const unsigned char hwLUT[256]; +#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */ + +#ifdef __cplusplus +} +#endif + +#endif /* ARM_COMMON_TABLES_H */ + diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_math.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_math.h new file mode 100644 index 0000000..a5eb4ff --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/arm_math.h @@ -0,0 +1,8955 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.7.0 + * @date 18. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * \section intro Introduction + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M and Cortex-A processor + * based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filtering functions + * - Matrix functions + * - Transform functions + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * - Support Vector Machine functions (SVM) + * - Bayes classifier functions + * - Distance functions + * + * The library has generally separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * \section using Using the Library + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * + * Here is the list of pre-built libraries : + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * + * + * \section example Examples + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * \section toolchain Toolchain Support + * + * The library is now tested on Fast Models building with cmake. + * Core M0, M7, A5 are tested. + * + * + * + * \section building Building the Library + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP\\Projects\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * There is also a work in progress cmake build. The README file is giving more details. + * + * \section preprocessor Preprocessor Macros + * + * Each library project have different preprocessor macros. + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_LOOPUNROLL: + * + * Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions + * + * - ARM_MATH_NEON: + * + * Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions. + * It is not enabled by default when Neon is available because performances are + * dependent on the compiler and target architecture. + * + * - ARM_MATH_NEON_EXPERIMENTAL: + * + * Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of + * of some DSP functions. Experimental Neon versions currently do not have better + * performances than the scalar versions. + * + * - ARM_MATH_HELIUM: + * + * It implies the flags ARM_MATH_MVEF and ARM_MATH_MVEI and ARM_MATH_FLOAT16. + * + * - ARM_MATH_MVEF: + * + * Select Helium versions of the f32 algorithms. + * It implies ARM_MATH_FLOAT16 and ARM_MATH_MVEI. + * + * - ARM_MATH_MVEI: + * + * Select Helium versions of the int and fixed point algorithms. + * + * - ARM_MATH_MVE_FLOAT16: + * + * MVE Float16 implementations of some algorithms (Requires MVE extension). + * + *
+ * \section pack CMSIS-DSP in ARM::CMSIS Pack + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |---------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP\\DSP_Lib_TestSuite | DSP_Lib test suite | + * |\b CMSIS\\DSP\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP\\Include | DSP_Lib include files | + * |\b CMSIS\\DSP\\Lib | DSP_Lib binaries | + * |\b CMSIS\\DSP\\Projects | Projects to rebuild DSP_Lib binaries | + * |\b CMSIS\\DSP\\Source | DSP_Lib source files | + * + *
+ * \section rev Revision History of CMSIS-DSP + * Please refer to \ref ChangeLog_pg. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to \ref arm_mat_init_f32(), \ref arm_mat_init_q31() and \ref arm_mat_init_q15() + * for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ + +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ + +/** + * @defgroup groupSVM SVM Functions + * This set of functions is implementing SVM classification on 2 classes. + * The training must be done from scikit-learn. The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/SVM.py + * + * If more than 2 classes are needed, the functions in this folder + * will have to be used, as building blocks, to do multi-class classification. + * + * No multi-class classification is provided in this SVM folder. + * + */ + + +/** + * @defgroup groupBayes Bayesian estimators + * + * Implement the naive gaussian Bayes estimator. + * The training must be done from scikit-learn. + * + * The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/Bayes.py + */ + +/** + * @defgroup groupDistance Distance functions + * + * Distance functions for use with clustering algorithms. + * There are distance functions for float vectors and boolean vectors. + * + */ + + +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" + #pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + + +/* Included for instrinsics definitions */ +#if defined (_MSC_VER ) +#include +#define __STATIC_FORCEINLINE static __forceinline +#define __STATIC_INLINE static __inline +#define __ALIGNED(x) __declspec(align(x)) + +#elif defined (__GNUC_PYTHON__) +#include +#define __ALIGNED(x) __attribute__((aligned(x))) +#define __STATIC_FORCEINLINE static __attribute__((inline)) +#define __STATIC_INLINE static __attribute__((inline)) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wattributes" + +#else +#include "cmsis_compiler.h" +#endif + + + +#include +#include +#include +#include + +/* evaluate ARM DSP feature */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + #define ARM_MATH_DSP 1 +#endif + +#if defined(ARM_MATH_NEON) +#include +#if __ARM_FEATURE_FP16_VECTOR_ARITHMETIC + #if !defined(ARM_MATH_NEON_FLOAT16) + #define ARM_MATH_NEON_FLOAT16 + #endif +#endif +#endif + +#if !defined(ARM_MATH_AUTOVECTORIZE) + +#if __ARM_FEATURE_MVE + #if !defined(ARM_MATH_MVEI) + #define ARM_MATH_MVEI + #endif +#endif + +#if (__ARM_FEATURE_MVE & 2) + #if !defined(ARM_MATH_MVEF) + #define ARM_MATH_MVEF + #endif + #if !defined(ARM_MATH_MVE_FLOAT16) + /* HW Float16 not yet well supported on gcc for M55 */ + #if !defined(__CMSIS_GCC_H) + #define ARM_MATH_MVE_FLOAT16 + #endif + #endif +#endif + +#endif /*!defined(ARM_MATH_AUTOVECTORIZE)*/ + + +#if defined (ARM_MATH_HELIUM) + #if !defined(ARM_MATH_MVEF) + #define ARM_MATH_MVEF + #endif + + #if !defined(ARM_MATH_MVEI) + #define ARM_MATH_MVEI + #endif + + #if !defined(ARM_MATH_MVE_FLOAT16) + /* HW Float16 not yet well supported on gcc for M55 */ + #if !defined(__CMSIS_GCC_H) + #define ARM_MATH_MVE_FLOAT16 + #endif + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#if __ARM_FEATURE_MVE +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief vector types + */ +#if defined(ARM_MATH_NEON) || defined (ARM_MATH_MVEI) + /** + * @brief 64-bit fractional 128-bit vector data type in 1.63 format + */ + typedef int64x2_t q63x2_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 1.31 format. + */ + typedef int32x4_t q31x4_t; + + /** + * @brief 16-bit fractional 128-bit vector data type with 16-bit alignement in 1.15 format. + */ + typedef __ALIGNED(2) int16x8_t q15x8_t; + + /** + * @brief 8-bit fractional 128-bit vector data type with 8-bit alignement in 1.7 format. + */ + typedef __ALIGNED(1) int8x16_t q7x16_t; + + /** + * @brief 32-bit fractional 128-bit vector pair data type in 1.31 format. + */ + typedef int32x4x2_t q31x4x2_t; + + /** + * @brief 32-bit fractional 128-bit vector quadruplet data type in 1.31 format. + */ + typedef int32x4x4_t q31x4x4_t; + + /** + * @brief 16-bit fractional 128-bit vector pair data type in 1.15 format. + */ + typedef int16x8x2_t q15x8x2_t; + + /** + * @brief 16-bit fractional 128-bit vector quadruplet data type in 1.15 format. + */ + typedef int16x8x4_t q15x8x4_t; + + /** + * @brief 8-bit fractional 128-bit vector pair data type in 1.7 format. + */ + typedef int8x16x2_t q7x16x2_t; + + /** + * @brief 8-bit fractional 128-bit vector quadruplet data type in 1.7 format. + */ + typedef int8x16x4_t q7x16x4_t; + + /** + * @brief 32-bit fractional data type in 9.23 format. + */ + typedef int32_t q23_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 9.23 format. + */ + typedef int32x4_t q23x4_t; + + /** + * @brief 64-bit status 128-bit vector data type. + */ + typedef int64x2_t status64x2_t; + + /** + * @brief 32-bit status 128-bit vector data type. + */ + typedef int32x4_t status32x4_t; + + /** + * @brief 16-bit status 128-bit vector data type. + */ + typedef int16x8_t status16x8_t; + + /** + * @brief 8-bit status 128-bit vector data type. + */ + typedef int8x16_t status8x16_t; + + +#endif + +#if defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF) /* floating point vector*/ + /** + * @brief 32-bit floating-point 128-bit vector type + */ + typedef float32x4_t f32x4_t; + + /** + * @brief 32-bit floating-point 128-bit vector pair data type + */ + typedef float32x4x2_t f32x4x2_t; + + /** + * @brief 32-bit floating-point 128-bit vector quadruplet data type + */ + typedef float32x4x4_t f32x4x4_t; + + /** + * @brief 32-bit ubiquitous 128-bit vector data type + */ + typedef union _any32x4_t + { + float32x4_t f; + int32x4_t i; + } any32x4_t; + +#endif + +#if defined(ARM_MATH_NEON) + /** + * @brief 32-bit fractional 64-bit vector data type in 1.31 format. + */ + typedef int32x2_t q31x2_t; + + /** + * @brief 16-bit fractional 64-bit vector data type in 1.15 format. + */ + typedef __ALIGNED(2) int16x4_t q15x4_t; + + /** + * @brief 8-bit fractional 64-bit vector data type in 1.7 format. + */ + typedef __ALIGNED(1) int8x8_t q7x8_t; + + /** + * @brief 32-bit float 64-bit vector data type. + */ + typedef float32x2_t f32x2_t; + + /** + * @brief 32-bit floating-point 128-bit vector triplet data type + */ + typedef float32x4x3_t f32x4x3_t; + + + /** + * @brief 32-bit fractional 128-bit vector triplet data type in 1.31 format + */ + typedef int32x4x3_t q31x4x3_t; + + /** + * @brief 16-bit fractional 128-bit vector triplet data type in 1.15 format + */ + typedef int16x8x3_t q15x8x3_t; + + /** + * @brief 8-bit fractional 128-bit vector triplet data type in 1.7 format + */ + typedef int8x16x3_t q7x16x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector pair data type + */ + typedef float32x2x2_t f32x2x2_t; + + /** + * @brief 32-bit floating-point 64-bit vector triplet data type + */ + typedef float32x2x3_t f32x2x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector quadruplet data type + */ + typedef float32x2x4_t f32x2x4_t; + + + /** + * @brief 32-bit fractional 64-bit vector pair data type in 1.31 format + */ + typedef int32x2x2_t q31x2x2_t; + + /** + * @brief 32-bit fractional 64-bit vector triplet data type in 1.31 format + */ + typedef int32x2x3_t q31x2x3_t; + + /** + * @brief 32-bit fractional 64-bit vector quadruplet data type in 1.31 format + */ + typedef int32x4x3_t q31x2x4_t; + + /** + * @brief 16-bit fractional 64-bit vector pair data type in 1.15 format + */ + typedef int16x4x2_t q15x4x2_t; + + /** + * @brief 16-bit fractional 64-bit vector triplet data type in 1.15 format + */ + typedef int16x4x2_t q15x4x3_t; + + /** + * @brief 16-bit fractional 64-bit vector quadruplet data type in 1.15 format + */ + typedef int16x4x3_t q15x4x4_t; + + /** + * @brief 8-bit fractional 64-bit vector pair data type in 1.7 format + */ + typedef int8x8x2_t q7x8x2_t; + + /** + * @brief 8-bit fractional 64-bit vector triplet data type in 1.7 format + */ + typedef int8x8x3_t q7x8x3_t; + + /** + * @brief 8-bit fractional 64-bit vector quadruplet data type in 1.7 format + */ + typedef int8x8x4_t q7x8x4_t; + + /** + * @brief 32-bit ubiquitous 64-bit vector data type + */ + typedef union _any32x2_t + { + float32x2_t f; + int32x2_t i; + } any32x2_t; + + + /** + * @brief 32-bit status 64-bit vector data type. + */ + typedef int32x4_t status32x2_t; + + /** + * @brief 16-bit status 64-bit vector data type. + */ + typedef int16x8_t status16x4_t; + + /** + * @brief 8-bit status 64-bit vector data type. + */ + typedef int8x16_t status8x8_t; + +#endif + + + + + +#define F64_MAX ((float64_t)DBL_MAX) +#define F32_MAX ((float32_t)FLT_MAX) + + + +#define F64_MIN (-DBL_MAX) +#define F32_MIN (-FLT_MAX) + + + +#define F64_ABSMAX ((float64_t)DBL_MAX) +#define F32_ABSMAX ((float32_t)FLT_MAX) + + + +#define F64_ABSMIN ((float64_t)0.0) +#define F32_ABSMIN ((float32_t)0.0) + + +#define Q31_MAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_MAX ((q15_t)(0x7FFF)) +#define Q7_MAX ((q7_t)(0x7F)) +#define Q31_MIN ((q31_t)(0x80000000L)) +#define Q15_MIN ((q15_t)(0x8000)) +#define Q7_MIN ((q7_t)(0x80)) + +#define Q31_ABSMAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_ABSMAX ((q15_t)(0x7FFF)) +#define Q7_ABSMAX ((q7_t)(0x7F)) +#define Q31_ABSMIN ((q31_t)0) +#define Q15_ABSMIN ((q15_t)0) +#define Q7_ABSMIN ((q7_t)0) + + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 ((q31_t)(0x100)) +#define DELTA_Q15 ((q15_t)0x5) +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macros for complex numbers + */ + + /* Dimension C vector space */ + #define CMPLX_DIM 2 + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + +/** + @brief definition to read/write two 16 bit values. + @deprecated + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __un(aligned) int32_t +#elif defined(_MSC_VER ) + #define __SIMD32_TYPE int32_t +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr)) +#define __SIMD64(addr) (*( int64_t **) & (addr)) + +#define STEP(x) (x) <= 0 ? 0 : 1 +#define SQ(x) ((x) * (x)) + +/* SIMD replacement */ + + +/** + @brief Read 2 Q15 from Q15 pointer. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2 ( + q15_t * pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, pQ15, 4); +#else + val = (pQ15[1] << 16) | (pQ15[0] & 0x0FFFF) ; +#endif + + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_ia ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 += 2; + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_da ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 -= 2; + return (val); +} + +/** + @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2_ia ( + q15_t ** pQ15, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ15, &val, 4); +#else + (*pQ15)[0] = (val & 0x0FFFF); + (*pQ15)[1] = (val >> 16) & 0x0FFFF; +#endif + + *pQ15 += 2; +} + +/** + @brief Write 2 Q15 to Q15 pointer. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2 ( + q15_t * pQ15, + q31_t value) +{ + q31_t val = value; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (pQ15, &val, 4); +#else + pQ15[0] = val & 0x0FFFF; + pQ15[1] = val >> 16; +#endif +} + + +/** + @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_ia ( + q7_t ** pQ7) +{ + q31_t val; + + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val =(((*pQ7)[3] & 0x0FF) << 24) | (((*pQ7)[2] & 0x0FF) << 16) | (((*pQ7)[1] & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + + *pQ7 += 4; + + return (val); +} + +/** + @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_da ( + q7_t ** pQ7) +{ + q31_t val; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val = ((((*pQ7)[3]) & 0x0FF) << 24) | ((((*pQ7)[2]) & 0x0FF) << 16) | ((((*pQ7)[1]) & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + *pQ7 -= 4; + + return (val); +} + +/** + @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q7x4_ia ( + q7_t ** pQ7, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ7, &val, 4); +#else + (*pQ7)[0] = val & 0x0FF; + (*pQ7)[1] = (val >> 8) & 0x0FF; + (*pQ7)[2] = (val >> 16) & 0x0FF; + (*pQ7)[3] = (val >> 24) & 0x0FF; + +#endif + *pQ7 += 4; +} + +/* + +Normally those kind of definitions are in a compiler file +in Core or Core_A. + +But for MSVC compiler it is a bit special. The goal is very specific +to CMSIS-DSP and only to allow the use of this library from other +systems like Python or Matlab. + +MSVC is not going to be used to cross-compile to ARM. So, having a MSVC +compiler file in Core or Core_A would not make sense. + +*/ +#if defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#ifndef ARM_MATH_DSP + /** + * @brief definition to pack two 16 bit values. + */ + #define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) + #define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) +#endif + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_FORCEINLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_FORCEINLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + __STATIC_FORCEINLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y) ) ); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + const q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + const q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + +/** + * @brief Integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32_t arm_exponent_f32(float32_t x, int32_t nb) +{ + float32_t r = x; + nb --; + while(nb > 0) + { + r = r * x; + nb--; + } + return(r); +} + +/** + * @brief 64-bit to 32-bit unsigned normalization + * @param[in] in is input unsigned long long value + * @param[out] normalized is the 32-bit normalized value + * @param[out] norm is norm scale + */ +__STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm) +{ + int32_t n1; + int32_t hi = (int32_t) (in >> 32); + int32_t lo = (int32_t) ((in << 32) >> 32); + + n1 = __CLZ(hi) - 32; + if (!n1) + { + /* + * input fits in 32-bit + */ + n1 = __CLZ(lo); + if (!n1) + { + /* + * MSB set, need to scale down by 1 + */ + *norm = -1; + *normalized = (((uint32_t) lo) >> 1); + } else + { + if (n1 == 32) + { + /* + * input is zero + */ + *norm = 0; + *normalized = 0; + } else + { + /* + * 32-bit normalization + */ + *norm = n1 - 1; + *normalized = lo << *norm; + } + } + } else + { + /* + * input fits in 64-bit + */ + n1 = 1 - n1; + *norm = -n1; + /* + * 64 bit normalization + */ + *normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1)); + } +} + +__STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den) +{ + q31_t result; + uint64_t absNum; + int32_t normalized; + int32_t norm; + + /* + * if sum fits in 32bits + * avoid costly 64-bit division + */ + absNum = num > 0 ? num : -num; + arm_norm_64_to_32u(absNum, &normalized, &norm); + if (norm > 0) + /* + * 32-bit division + */ + result = (q31_t) num / den; + else + /* + * 64-bit division + */ + result = (q31_t) (num / den); + + return result; +} + + +/* + * @brief C custom defined intrinsic functions + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 + */ + __STATIC_FORCEINLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 + */ + __STATIC_FORCEINLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 + */ + __STATIC_FORCEINLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 + */ + __STATIC_FORCEINLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 + */ + __STATIC_FORCEINLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 + */ + __STATIC_FORCEINLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX + */ + __STATIC_FORCEINLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX + */ + __STATIC_FORCEINLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX + */ + __STATIC_FORCEINLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX + */ + __STATIC_FORCEINLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX + */ + __STATIC_FORCEINLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX + */ + __STATIC_FORCEINLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD + */ + __STATIC_FORCEINLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB + */ + __STATIC_FORCEINLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD + */ + __STATIC_FORCEINLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX + */ + __STATIC_FORCEINLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX + */ + __STATIC_FORCEINLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD + */ + __STATIC_FORCEINLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX + */ + __STATIC_FORCEINLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD + */ + __STATIC_FORCEINLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD + */ + __STATIC_FORCEINLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 + */ + __STATIC_FORCEINLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA + */ + __STATIC_FORCEINLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + * + * For the MVE version, the coefficient length must be a multiple of 16. + * You can pad with zeros if you have less coefficients. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter (fast version). + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns either + * ARM_MATH_SUCCESS if initialization was successful or + * ARM_MATH_ARGUMENT_ERROR if numTaps is not a supported value. + * + * For the MVE version, the coefficient length must be a multiple of 8. + * You can pad with zeros if you have less coefficients. + * + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter (fast version). + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * + * For the MVE version, the coefficient length must be a multiple of 4. + * You can pad with zeros if you have less coefficients. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + /** + * @brief Instance structure for the modified Biquad coefs required by vectorized code. + */ + typedef struct + { + float32_t coeffs[8][4]; /**< Points to the array of modified coefficients. The array is of length 32. There is one per stage */ + } arm_biquad_mod_coef_f32; +#endif + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + const q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pCoeffsMod points to the modified filter coefficients (only MVE version). + * @param[in] pState points to the state buffer. + */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + void arm_biquad_cascade_df1_mve_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + arm_biquad_mod_coef_f32 * pCoeffsMod, + float32_t * pState); +#endif + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u16( + const uint16_t * pSrc, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u32( + const uint32_t * pSrc, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u8( + const uint8_t * pSrc, + uint8_t * pDst, + uint32_t blockSize); + +/** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_BITONIC = 0, + /**< Bitonic sort */ + ARM_SORT_BUBBLE = 1, + /**< Bubble sort */ + ARM_SORT_HEAP = 2, + /**< Heap sort */ + ARM_SORT_INSERTION = 3, + /**< Insertion sort */ + ARM_SORT_QUICK = 4, + /**< Quick sort */ + ARM_SORT_SELECTION = 5 + /**< Selection sort */ + } arm_sort_alg; + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_DESCENDING = 0, + /**< Descending order (9 to 0) */ + ARM_SORT_ASCENDING = 1 + /**< Ascending order (0 to 9) */ + } arm_sort_dir; + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_alg alg; /**< Sorting algorithm selected */ + arm_sort_dir dir; /**< Sorting order (direction) */ + } arm_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_sort_f32( + const arm_sort_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] alg Selected algorithm. + * @param[in] dir Sorting order. + */ + void arm_sort_init_f32( + arm_sort_instance_f32 * S, + arm_sort_alg alg, + arm_sort_dir dir); + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_dir dir; /**< Sorting order (direction) */ + float32_t * buffer; /**< Working buffer */ + } arm_merge_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in,out] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_merge_sort_f32( + const arm_merge_sort_instance_f32 * S, + float32_t *pSrc, + float32_t *pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] dir Sorting order. + * @param[in] buffer Working buffer. + */ + void arm_merge_sort_init_f32( + arm_merge_sort_instance_f32 * S, + arm_sort_dir dir, + float32_t * buffer); + + /** + * @brief Struct for specifying cubic spline type + */ + typedef enum + { + ARM_SPLINE_NATURAL = 0, /**< Natural spline */ + ARM_SPLINE_PARABOLIC_RUNOUT = 1 /**< Parabolic runout spline */ + } arm_spline_type; + + /** + * @brief Instance structure for the floating-point cubic spline interpolation. + */ + typedef struct + { + arm_spline_type type; /**< Type (boundary conditions) */ + const float32_t * x; /**< x values */ + const float32_t * y; /**< y values */ + uint32_t n_x; /**< Number of known data points */ + float32_t * coeffs; /**< Coefficients buffer (b,c, and d) */ + } arm_spline_instance_f32; + + /** + * @brief Processing function for the floating-point cubic spline interpolation. + * @param[in] S points to an instance of the floating-point spline structure. + * @param[in] xq points to the x values ot the interpolated data points. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples of output data. + */ + void arm_spline_f32( + arm_spline_instance_f32 * S, + const float32_t * xq, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point cubic spline interpolation. + * @param[in,out] S points to an instance of the floating-point spline structure. + * @param[in] type type of cubic spline interpolation (boundary conditions) + * @param[in] x points to the x values of the known data points. + * @param[in] y points to the y values of the known data points. + * @param[in] n number of known data points. + * @param[in] coeffs coefficients array for b, c, and d + * @param[in] tempBuffer buffer array for internal computations + */ + void arm_spline_init_f32( + arm_spline_instance_f32 * S, + arm_spline_type type, + const float32_t * x, + const float32_t * y, + uint32_t n, + float32_t * coeffs, + float32_t * tempBuffer); + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + + + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q15_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q15_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q15_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q15; + +arm_status arm_cfft_init_q15( + arm_cfft_instance_q15 * S, + uint16_t fftLen); + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q31_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q31_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q31_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q31; + +arm_status arm_cfft_init_q31( + arm_cfft_instance_q31 * S, + uint16_t fftLen); + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const float32_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const float32_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const float32_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_f32; + + + + arm_status arm_cfft_init_f32( + arm_cfft_instance_f32 * S, + uint16_t fftLen); + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + /** + * @brief Instance structure for the Double Precision Floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float64_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f64; + + arm_status arm_cfft_init_f64( + arm_cfft_instance_f64 * S, + uint16_t fftLen); + + void arm_cfft_f64( + const arm_cfft_instance_f64 * S, + float64_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q15 cfftInst; +#else + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q31 cfftInst; +#else + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the Double Precision Floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f64 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float64_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f64 ; + +arm_status arm_rfft_fast_init_f64 ( + arm_rfft_fast_instance_f64 * S, + uint16_t fftLen); + + +void arm_rfft_fast_f64( + arm_rfft_fast_instance_f64 * S, + float64_t * p, float64_t * pOut, + uint8_t ifftFlag); + + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + + + void arm_rfft_fast_f32( + const arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + const float32_t *pTwiddle; /**< points to the twiddle factor table. */ + const float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + const float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + const q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + const q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + +/** + @brief Instance structure for floating-point FIR decimator. + */ +typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + +/** + @brief Processing function for floating-point FIR decimator. + @param[in] S points to an instance of the floating-point FIR decimator structure + @param[in] pSrc points to the block of input data + @param[out] pDst points to the block of output data + @param[in] blockSize number of samples to process + */ +void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + @brief Initialization function for the floating-point FIR decimator. + @param[in,out] S points to an instance of the floating-point FIR decimator structure + @param[in] numTaps number of coefficients in the filter + @param[in] M decimation factor + @param[in] pCoeffs points to the filter coefficients + @param[in] pState points to the state buffer + @param[in] blockSize number of input samples to process per call + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + */ +arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + const float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + +#if defined(ARM_MATH_NEON) +void arm_biquad_cascade_df2T_compute_coefs_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs); +#endif + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + const float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + @brief Correlation of Q15 sequences + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +*/ +void arm_correlate_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ +void arm_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence. + @param[in] srcALen length of the first input sequence. + @param[in] pSrcB points to the second input sequence. + @param[in] srcBLen length of the second input sequence. + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ +void arm_correlate_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + @brief Correlation of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void arm_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd
+   * 
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return processed output sample. + */ + __STATIC_FORCEINLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + +/** + @brief Process function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around rather than clip. + In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ +__STATIC_FORCEINLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + +/** + @brief Process function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ +__STATIC_FORCEINLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @return none + */ + __STATIC_FORCEINLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = (0.57735026919f * Ia + 1.15470053838f * Ib); + } + + +/** + @brief Clarke transform for Q31 version + @param[in] Ia input three-phase coordinate a + @param[in] Ib input three-phase coordinate b + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + +/** + @brief Inverse Clarke transform for Q31 version + @param[in] Ialpha input two-phase orthogonal vector axis alpha + @param[in] Ibeta input two-phase orthogonal vector axis beta + @param[out] pIa points to output three-phase coordinate a + @param[out] pIb points to output three-phase coordinate b + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + * + * The function implements the forward Park transform. + * + */ + __STATIC_FORCEINLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + +/** + @brief Park transform for Q31 version + @param[in] Ialpha input two-phase vector coordinate alpha + @param[in] Ibeta input two-phase vector coordinate beta + @param[out] pId points to output rotor reference frame d + @param[out] pIq points to output rotor reference frame q + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + +/** + @brief Inverse Park transform for Q31 version + @param[in] Id input coordinate of rotor reference frame d + @param[in] Iq input coordinate of rotor reference frame q + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + __STATIC_FORCEINLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= (S->nValues - 1)) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + __STATIC_FORCEINLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + +/** + @brief Floating-point vector of log values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vlog_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + @brief Floating-point vector of exp values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vexp_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + +/** + @brief Floating-point square root function. + @param[in] in input value + @param[out] pOut square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +__STATIC_FORCEINLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + *pOut = __sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); + #else + *pOut = sqrtf(in); + #endif + +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + +/** + @brief Q31 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + +/** + @brief Q15 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @brief Vector Floating-point square root function. + * @param[in] pIn input vector. + * @param[out] pOut vector of square roots of input elements. + * @param[in] len length of input vector. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + void arm_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len); + + void arm_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len); + + void arm_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset; + int32_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q15_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q7_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + @brief Maximum value of a floating-point vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult maximum value returned here + @return none + */ + void arm_max_no_idx_f32( + const float32_t *pSrc, + uint32_t blockSize, + float32_t *pResult); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Struct for specifying SVM Kernel + */ +typedef enum +{ + ARM_ML_KERNEL_LINEAR = 0, + /**< Linear kernel */ + ARM_ML_KERNEL_POLYNOMIAL = 1, + /**< Polynomial kernel */ + ARM_ML_KERNEL_RBF = 2, + /**< Radial Basis Function kernel */ + ARM_ML_KERNEL_SIGMOID = 3 + /**< Sigmoid kernel */ +} arm_ml_kernel_type; + + +/** + * @brief Instance structure for linear SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ +} arm_svm_linear_instance_f32; + + +/** + * @brief Instance structure for polynomial SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + int32_t degree; /**< Polynomial degree */ + float32_t coef0; /**< Polynomial constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_polynomial_instance_f32; + +/** + * @brief Instance structure for rbf SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_rbf_instance_f32; + +/** + * @brief Instance structure for sigmoid SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t coef0; /**< Independant constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_sigmoid_instance_f32; + +/** + * @brief SVM linear instance init function + * @param[in] S Parameters for SVM functions + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @return none. + * + */ + + +void arm_svm_linear_init_f32(arm_svm_linear_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes); + +/** + * @brief SVM linear prediction + * @param[in] S Pointer to an instance of the linear SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ + +void arm_svm_linear_predict_f32(const arm_svm_linear_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM polynomial instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] degree Polynomial degree + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + + +void arm_svm_polynomial_init_f32(arm_svm_polynomial_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + int32_t degree, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM polynomial prediction + * @param[in] S Pointer to an instance of the polynomial SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_polynomial_predict_f32(const arm_svm_polynomial_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM radial basis function instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_rbf_init_f32(arm_svm_rbf_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t gamma + ); + +/** + * @brief SVM rbf prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult decision value + * @return none. + * + */ +void arm_svm_rbf_predict_f32(const arm_svm_rbf_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + +/** + * @brief SVM sigmoid instance init function + * @param[in] S points to an instance of the rbf SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_sigmoid_init_f32(arm_svm_sigmoid_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM sigmoid prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_sigmoid_predict_f32(const arm_svm_sigmoid_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + + +/** + * @brief Instance structure for Naive Gaussian Bayesian estimator. + */ +typedef struct +{ + uint32_t vectorDimension; /**< Dimension of vector space */ + uint32_t numberOfClasses; /**< Number of different classes */ + const float32_t *theta; /**< Mean values for the Gaussians */ + const float32_t *sigma; /**< Variances for the Gaussians */ + const float32_t *classPriors; /**< Class prior probabilities */ + float32_t epsilon; /**< Additive value to variances */ +} arm_gaussian_naive_bayes_instance_f32; + +/** + * @brief Naive Gaussian Bayesian Estimator + * + * @param[in] S points to a naive bayes instance structure + * @param[in] in points to the elements of the input vector. + * @param[in] pBuffer points to a buffer of length numberOfClasses + * @return The predicted class + * + */ + + +uint32_t arm_gaussian_naive_bayes_predict_f32(const arm_gaussian_naive_bayes_instance_f32 *S, + const float32_t * in, + float32_t *pBuffer); + +/** + * @brief Computation of the LogSumExp + * + * In probabilistic computations, the dynamic of the probability values can be very + * wide because they come from gaussian functions. + * To avoid underflow and overflow issues, the values are represented by their log. + * In this representation, multiplying the original exp values is easy : their logs are added. + * But adding the original exp values is requiring some special handling and it is the + * goal of the LogSumExp function. + * + * If the values are x1...xn, the function is computing: + * + * ln(exp(x1) + ... + exp(xn)) and the computation is done in such a way that + * rounding issues are minimised. + * + * The max xm of the values is extracted and the function is computing: + * xm + ln(exp(x1 - xm) + ... + exp(xn - xm)) + * + * @param[in] *in Pointer to an array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return LogSumExp + * + */ + + +float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize); + +/** + * @brief Dot product with log arithmetic + * + * Vectors are containing the log of the samples + * + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[in] pTmpBuffer temporary buffer of length blockSize + * @return The log of the dot product . + * + */ + + +float32_t arm_logsumexp_dot_prod_f32(const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t *pTmpBuffer); + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize); + + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float32_t arm_kullback_leibler_f32(const float32_t * pSrcA + ,const float32_t * pSrcB + ,uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float64_t arm_kullback_leibler_f64(const float64_t * pSrcA, + const float64_t * pSrcB, + uint32_t blockSize); + + +/** + * @brief Weighted sum + * + * + * @param[in] *in Array of input values. + * @param[in] *weigths Weights + * @param[in] blockSize Number of samples in the input array. + * @return Weighted sum + * + */ +float32_t arm_weighted_sum_f32(const float32_t *in + , const float32_t *weigths + , uint32_t blockSize); + + +/** + * @brief Barycenter + * + * + * @param[in] in List of vectors + * @param[in] weights Weights of the vectors + * @param[out] out Barycenter + * @param[in] nbVectors Number of vectors + * @param[in] vecDim Dimension of space (vector dimension) + * @return None + * + */ +void arm_barycenter_f32(const float32_t *in + , const float32_t *weights + , float32_t *out + , uint32_t nbVectors + , uint32_t vecDim); + +/** + * @brief Euclidean distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Bray-Curtis distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Canberra distance between two vectors + * + * This function may divide by zero when samples pA[i] and pB[i] are both zero. + * The result of the computation will be correct. So the division per zero may be + * ignored. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Chebyshev distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Cityblock (Manhattan) distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Correlation distance between two vectors + * + * The input vectors are modified in place ! + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize); + +/** + * @brief Cosine distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Jensen-Shannon distance between two vectors + * + * This function is assuming that elements of second vector are > 0 + * and 0 only when the corresponding element of first vector is 0. + * Otherwise the result of the computation does not make sense + * and for speed reasons, the cases returning NaN or Infinity are not + * managed. + * + * When the function is computing x log (x / y) with x 0 and y 0, + * it will compute the right value (0) but a division per zero will occur + * and shoudl be ignored in client code. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize); + +/** + * @brief Minkowski distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] n Norm order (>= 2) + * @param[in] blockSize vector length + * @return distance + * + */ + + + +float32_t arm_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize); + +/** + * @brief Dice distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] order Distance order + * @param[in] blockSize Number of samples + * @return distance + * + */ + + +float32_t arm_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Hamming distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Jaccard distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Kulsinski distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Roger Stanimoto distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Russell-Rao distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Michener distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Sneath distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Yule distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numCols - 2) || yIndex < 0 || yIndex > (S->numRows - 2)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex ) + (yIndex ) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex ) + (yIndex+1) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0x0FFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0x0FFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0x0FFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0x0FFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT +#endif + + + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armcc.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armcc.h new file mode 100644 index 0000000..237ff6e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armcc.h @@ -0,0 +1,885 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.2.1 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang.h new file mode 100644 index 0000000..90de9db --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang.h @@ -0,0 +1,1467 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.3.1 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang_ltm.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang_ltm.h new file mode 100644 index 0000000..0e5c734 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_armclang_ltm.h @@ -0,0 +1,1893 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.3.0 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2018-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_compiler.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_gcc.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_gcc.h new file mode 100644 index 0000000..a2778f5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/DSP/Include/cmsis_gcc.h @@ -0,0 +1,2177 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.3.0 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_tables.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_tables.h new file mode 100644 index 0000000..d688069 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_tables.h @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_tables.h + * Description: Extern declaration for NN tables + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_NN_TABLES_H +#define _ARM_NN_TABLES_H + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" + +/** +* @brief tables for various activation functions +* +*/ + +extern const q15_t sigmoidTable_q15[256]; +extern const q7_t sigmoidTable_q7[256]; + +extern const q7_t tanhTable_q7[256]; +extern const q15_t tanhTable_q15[256]; + + /** + * @brief 2-way tables for various activation functions + * + * 2-way table, H table for value larger than 1/4 + * L table for value smaller than 1/4, H table for remaining + * We have this only for the q15_t version. It does not make + * sense to have it for q7_t type + */ +extern const q15_t sigmoidHTable_q15[192]; +extern const q15_t sigmoidLTable_q15[128]; + +#endif /* ARM_NN_TABLES_H */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_types.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_types.h new file mode 100644 index 0000000..4b216c9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nn_types.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_types.h + * Description: Public header file to contain the CMSIS-NN structs for the + * TensorFlowLite micro compliant functions + * + * $Date: April 23, 2020 + * $Revision: V.0.5.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + + +#ifndef _ARM_NN_TYPES_H +#define _ARM_NN_TYPES_H + +/** CMSIS-NN object to contain the width and height of a tile */ +typedef struct +{ + int32_t w; /**< Width */ + int32_t h; /**< Height */ +} cmsis_nn_tile; + +/** CMSIS-NN object used for the function context. */ +typedef struct +{ + void *buf; /**< Pointer to a buffer needed for the optimization */ + int32_t size; /**< Buffer size */ +} cmsis_nn_context; + +/** CMSIS-NN object to contain the dimensions of the tensors */ +typedef struct +{ + int32_t n; /**< Generic dimension to contain either the batch size or output channels. Please refer to the function documentation for more information */ + int32_t h; /**< Height */ + int32_t w; /**< Width */ + int32_t c; /**< Input channels */ +} cmsis_nn_dims; + +/** CMSIS-NN object for the per-channel quantization parameters */ +typedef struct +{ + int32_t *multiplier; /**< Multiplier values */ + int32_t *shift; /**< Shift values */ +} cmsis_nn_per_channel_quant_params; + +/** CMSIS-NN object for the per-tensor quantization parameters */ +typedef struct +{ + int32_t multiplier; /**< Multiplier value */ + int32_t shift; /**< Shift value */ +} cmsis_nn_per_tensor_quant_params; + +/** CMSIS-NN object for the quantized Relu activation */ +typedef struct +{ + int32_t min; /**< Min value used to clamp the result */ + int32_t max; /**< Max value used to clamp the result */ +} cmsis_nn_activation; + +/** CMSIS-NN object for the convolution layer parameters */ +typedef struct +{ + int32_t input_offset; /**< Zero value for the input tensor */ + int32_t output_offset; /**< Zero value for the output tensor */ + cmsis_nn_tile stride; + cmsis_nn_tile padding; + cmsis_nn_tile dilation; + cmsis_nn_activation activation; +} cmsis_nn_conv_params; + +/** CMSIS-NN object for Depthwise convolution layer parameters */ +typedef struct +{ + int32_t input_offset; /**< Zero value for the input tensor */ + int32_t output_offset; /**< Zero value for the output tensor */ + int32_t ch_mult; /**< Channel Multiplier. ch_mult * in_ch = out_ch */ + cmsis_nn_tile stride; + cmsis_nn_tile padding; + cmsis_nn_tile dilation; + cmsis_nn_activation activation; +} cmsis_nn_dw_conv_params; +/** CMSIS-NN object for pooling layer parameters */ +typedef struct +{ + cmsis_nn_tile stride; + cmsis_nn_tile padding; + cmsis_nn_activation activation; +} cmsis_nn_pool_params; + +/** CMSIS-NN object for Fully Connected layer parameters */ +typedef struct +{ + int32_t input_offset; /**< Zero value for the input tensor */ + int32_t filter_offset; /**< Zero value for the filter tensor */ + int32_t output_offset; /**< Zero value for the output tensor */ + cmsis_nn_activation activation; +} cmsis_nn_fc_params; + +#endif // _ARM_NN_TYPES_H + + diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnfunctions.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnfunctions.h new file mode 100644 index 0000000..1ddc46f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnfunctions.h @@ -0,0 +1,2068 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nnfunctions.h + * Description: Public header file for CMSIS NN Library + * + * $Date: June 11, 2020 + * $Revision: V.6.0.1 + * + * Target Processor: Cortex-M CPUs + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS NN Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS NN software library, + * a collection of efficient neural network kernels developed to maximize the + * performance and minimize the memory footprint of neural networks on Cortex-M processor cores. + * + * The library is divided into a number of functions each covering a specific category: + * - Convolution Functions + * - Activation Functions + * - Fully-connected Layer Functions + * - Pooling Functions + * - Softmax Functions + * - Basic math Functions + * + * The library has separate functions for operating on different weight and activation data + * types including 8-bit integers (q7_t) and 16-bit integers (q15_t). The descrition of the + * kernels are included in the function description. The implementation details are also + * described in this paper [1]. + * + * Function Classification + * -------- + * The functions can be classified into two segments + * - Legacy functions supporting ARM's internal symmetric quantization(8 bits). + * - Functions that support TensorFlow Lite framework with symmetric quantization(8 bits). + * + * The legacy functions can be identified with their suffix of _q7 or _q15 and are no new development is done there. The article in [2] describes in detail + * how to run a network using the legacy functions. + * + * The functions supporting TensorFlow Lite framework is identified by the _s8 suffix and can be invoked from TFL micro. The functions are bit exact to + * TensorFlow Lite. Refer to the TensorFlow's documentation in [3] on how to run a TensorFlow Lite model using optimized CMSIS-NN kernels. + * + * Block Diagram + * -------- + * \image html CMSIS-NN-OVERVIEW.PNG + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Pre-processor Macros + * ------------ + * + * Each library project have different pre-processor macros. + * + * - ARM_MATH_DSP: + * + * Define macro ARM_MATH_DSP, If the silicon supports DSP instructions(DSP extension). + * + * - ARM_MATH_MVEI: + * + * Define macro ARM_MATH_MVEI, If the silicon supports M-Profile Vector Extension. + + * - ARM_MATH_AUTOVECTORIZE + * Used in conjucture with ARM_MATH_MVEI to let the compiler auto vectorize for the functions that uses inline assembly. + * It does not affect functions that use C or intrinsics. + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. This is supported only for the legacy functions i.e, functions targetted at + * TensorFlow Lite do not support big endianness. By default library builds for little endian targets. + * + * - ARM_NN_TRUNCATE: + * + * Define macro ARM_NN_TRUNCATE to use floor instead of round-to-the-nearest-int for the computation. + * + * Upcoming Interface Change + * -------- + * Starting from the 1.4.0 next release, CMSIS-NN will gradually switch to a new API interface to: + * + * -# have a stable API + * -# avoid passing many variables by value + * -# improve security + * -# improve validation + * -# improve code readability + * + * The upcoming API interface change will be based on "struct" and only affect the TensorFlowLite micro compliant APIs [4] (functions with _s8 suffix) + * + * Below you can find a snapshot of how the new API interface will look like (names can change) + * + * i.e. arm_convolve_1x1_s8_fast + * + * Current API interface | New API interface proposal + * ------------- | ------------- + * const q7_t *input | const cmsis_nn_context &ctx + * const uint16_t input_x | const cmsis_nn_conv_params ¶ms + * const uint16_t input_y | const cmsis_nn_dims &input_dims + * const uint16_t input_ch | const q7_t *input_data + * const uint16_t input_batches | const cmsis_nn_dims &filter_dims + * const q7_t *kernel | const q7_t *filter_data + * const uint16_t output_ch | const cmsis_nn_dims &bias_dims + * const uint16_t pad_x | const q31_t *bias_data + * const uint16_t pad_y | const cmsis_nn_dims &output_dims + * const uint16_t stride_x | q7_t *output_data + * const uint16_t stride_y |
+ * const int32_t *bias |
+ * q7_t *output |
+ * const int32_t *output_shift |
+ * const int32_t *output_mult |
+ * const int32_t out_offset |
+ * const int32_t input_offset |
+ * const int32_t out_activation_min |
+ * const int32_t out_activation_max |
+ * const uint16_t output_x |
+ * const uint16_t output_y |
+ * q15_t *buffer_a |
+ * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2019 Arm Limited. All rights reserved. + * + * [1] CMSIS-NN: Efficient Neural Network Kernels for Arm Cortex-M CPUs https://arxiv.org/abs/1801.06601 + * + * [2] Converting a Neural Network for Arm Cortex-M with CMSIS-NN + * https://developer.arm.com/solutions/machine-learning-on-arm/developer-material/how-to-guides/converting-a-neural-network-for-arm-cortex-m-with-cmsis-nn/single-page + * [3] https://www.tensorflow.org/lite/microcontrollers/library + * + * [4] https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/NN#legacy-vs-tfl-micro-compliant-apis + */ + +/** + * @defgroup groupNN Neural Network Functions + * A collection of functions to perform basic operations for neural network layers. Functions with a _s8 suffix support + * TensorFlow Lite framework. + */ + +#ifndef _ARM_NNFUNCTIONS_H +#define _ARM_NNFUNCTIONS_H + +#include "arm_nnsupportfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nn_tables.h" +#include "arm_nn_types.h" + +#define USE_INTRINSIC + +//#define ARM_NN_TRUNCATE /* This config the rounding model to floor or round to the nearest int */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup NNConv Convolution Functions + * + * Collection of convolution, depthwise convolution functions and their variants. + * + * The convolution is implemented in 2 steps: im2col and GEMM + * + * im2col is a process of converting each patch of image data into + * a column. After im2col, the convolution is computed as matrix-matrix + * multiplication. + * + * To reduce the memory footprint, the im2col is performed partially. + * Each iteration, only a few column (i.e., patches) are generated and + * computed with GEMM kernels similar to CMSIS-DSP arm_mat_mult functions. + * + */ + + /** + * @brief s8 convolution layer wrapper function with the main purpose to call the optimal kernel available in cmsis-nn to perform the convolution. + * + * @param[in, out] ctx Function context that contains the additional buffer if required by the implementation. + arm_convolve_wrapper_s8_get_buffer_size will return the buffer_size if required + * @param[in] conv_params Convolution parameters (e.g. strides, dilations, pads,...). + * Range of conv_params->input_offset : [-127, 128] + * Range of conv_params->output_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, HK, WK, C_IN] where HK and WK are the spatial filter dimensions + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT] + * @param[out] output_data Output data pointer. Data type: int8 + * + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH if argument constraints fail. or, + * ARM_MATH_SUCCESS on successful completion. + * + */ + arm_status arm_convolve_wrapper_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for arm_convolve_wrapper_s8 + * + * @param[in] conv_params Convolution parameters (e.g. strides, dilations, pads,...). + * Range of conv_params->input_offset : [-127, 128] + * Range of conv_params->output_offset : [-128, 127] + * @param[in] input_dims Input (activation) dimensions. Format: [N, H, W, C_IN] + * @param[in] filter_dims Filter dimensions. Format: [C_OUT, HK, WK, C_IN] where HK and WK are the spatial filter dimensions + * @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT] + * + * @return The function returns required buffer size(bytes) + * + */ + int32_t arm_convolve_wrapper_s8_get_buffer_size(const cmsis_nn_conv_params* conv_params, + const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims, + const cmsis_nn_dims* output_dims); + + /** + * @brief Basic s8 convolution function + * @param[in, out] ctx Function context that contains the additional buffer if required by the implementation. + arm_convolve_s8_get_buffer_size will return the buffer_size if required + * @param[in] conv_params Convolution parameters (e.g. strides, dilations, pads,...). + * Range of conv_params->input_offset : [-127, 128] + * Range of conv_params->output_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, HK, WK, C_IN] where HK and WK are the spatial filter dimensions + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT] + * @param[out] output_data Output data pointer. Data type: int8 + + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * 1. Supported framework: TensorFlow Lite micro + * 2. q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs. + * 3. Additional memory is required for optimization. Refer to argument 'ctx' for details. + * + */ + arm_status arm_convolve_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for s8 convolution function + * + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, HK, WK, C_IN] where HK and WK are the spatial filter dimensions + * @return The function returns required buffer size(bytes) + * + */ + int32_t arm_convolve_s8_get_buffer_size(const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims); + + /** + * @brief Basic Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + */ + arm_status arm_convolve_HWC_q7_basic(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Basic Q7 convolution function (non-square shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimension x + * @param[in] dim_im_in_y input tensor dimension y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + */ + arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Basic Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + */ + arm_status arm_convolve_HWC_q15_basic(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + arm_status arm_convolve_HWC_q7_fast(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimension x + * @param[in] dim_im_in_y input tensor dimension y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + + arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 version of 1x1 convolution (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimension x + * @param[in] dim_im_in_y input tensor dimension y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH if argument constraints fail. or, + * ARM_MATH_SUCCESS on successful completion. + * + * This function implement convolution with 1x1 kernel size (i.e., dim_kernel_x=1 + * and dim_kernel_y=1). It can be used for + * second half of MobileNets after depthwise separable convolution. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast s8 version for 1x1 convolution (non-square shape) + * + * @param[in, out] ctx Function context that contains the additional buffer if required by the implementation. + arm_convolve_1x1_s8_fast_get_buffer_size will return the buffer_size if required + * @param[in] conv_params Convolution parameters (e.g. strides, dilations, pads,...). + * Range of conv_params->input_offset : [-127, 128] + * Range of conv_params->output_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, 1, 1, C_IN] + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT] + * @param[out] output_data Output data pointer. Data type: int8 + * + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH if argument constraints fail. or, + * ARM_MATH_SUCCESS on successful completion. + * + * @details + * - Supported framework : TensorFlow Lite Micro + * - The following constrains on the arguments apply + * -# input_dims->c is a multiple of 4 + * -# conv_params->padding.w = conv_params->padding.h = 0 + * -# conv_params->stride.w = conv_params->stride.h = 1 + * + */ + arm_status arm_convolve_1x1_s8_fast(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for arm_convolve_1x1_s8_fast + * + * @param[in] input_dims Input (activation) dimensions + * @return The function returns the required buffer size in bytes + * + */ + int32_t arm_convolve_1x1_s8_fast_get_buffer_size(const cmsis_nn_dims* input_dims); + + /** + * @brief 1xn convolution + * + * @param[in, out] ctx Function context that contains the additional buffer if required by the implementation. + arm_convolve_1_x_n_s8_get_buffer_size will return the buffer_size if required + * @param[in] conv_params Convolution parameters (e.g. strides, dilations, pads,...). + * Range of conv_params->input_offset : [-127, 128] + * Range of conv_params->output_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, 1, WK, C_IN] where WK is the horizontal spatial filter dimension + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT] + * @param[out] output_data Output data pointer. Data type: int8 + * + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH if argument constraints fail. or, + * ARM_MATH_SUCCESS on successful completion. + * + * @details + * - Supported framework : TensorFlow Lite Micro + * - The following constrains on the arguments apply + * -# input_dims->n equals 1 + * -# ouput_dims->w is a multiple of 4 + * -# Explicit constraints(since it is for 1xN convolution) + * -## input_dims->h equals 1 + * -## output_dims->h equals 1 + * -## filter_dims->h equals 1 + *@todo Remove constraint on output_dims->w to make the function generic. + * + */ + arm_status arm_convolve_1_x_n_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data); + + /** + * @brief Get the required additional buffer size for 1xn convolution + * + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * @param[in] filter_dims Filter tensor dimensions. Format: [C_OUT, 1, WK, C_IN] where WK is the horizontal spatial filter dimension + * @return The function returns required buffer size(bytes) + * + */ + int32_t arm_convolve_1_x_n_s8_get_buffer_size(const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims); + + /** + * @brief Q7 version of convolution for RGB image + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This kernel is written exclusively for convolution with ch_im_in + * equals 3. This applies on the first layer of CNNs which has input + * image with RGB format. + */ + + arm_status arm_convolve_HWC_q7_RGB(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + + arm_status arm_convolve_HWC_q15_fast(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q15 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimension x + * @param[in] dim_im_in_y input tensor dimension y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + + arm_status + arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Q7 depthwise separable convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + + arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Q7 depthwise separable convolution function (non-square shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimension x + * @param[in] dim_im_in_y input tensor dimension y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding sizes x + * @param[in] padding_y padding sizes y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Wrapper function to pick the right optimized s8 depthwise convolution function + * + * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function + * definition file to see if an additional buffer is required. + * Optional function {API}_get_buffer_size() provides the buffer + * size if required. + * @param[in] dw_conv_params Depthwise convolution parameters (e.g. strides, dilations, pads,...) + * dw_conv_params->dilation is not used. + * Range of dw_conv_params->input_offset : [-127, 128] + * Range of dw_conv_params->output_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each + * output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN] + * Batch argument N is not used and assumed to be 1. + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [1, H, W, C_OUT] + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [1, H, W, C_OUT] + * @param[in, out] output_data Output data pointer. Data type: int8 + * @return The function returns + * ARM_MATH_SUCCESS - Successful completion. + * + * @details + * - Supported framework: TensorFlow Lite + * - Picks one of the the following functions + * -# arm_depthwise_conv_s8() + * -# arm_depthwise_conv_3x3_s8() - Cortex-M CPUs with DSP extension only + * -# arm_depthwise_conv_s8_opt() + * - q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs. + * - Check details of arm_depthwise_conv_s8_opt() for potential data that can be accessed outside of the boundary. + */ + arm_status arm_depthwise_conv_wrapper_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Get size of additional buffer required by arm_depthwise_conv_wrapper_s8() + * + * @param[in] dw_conv_params Depthwise convolution parameters (e.g. strides, dilations, pads,...) + * dw_conv_params->dilation is not used. + * Range of dw_conv_params->input_offset : [-127, 128] + * Range of dw_conv_params->input_offset : [-128, 127] + * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN] + * Batch argument N is not used and assumed to be 1. + * @param[in] filter_dims Filter tensor dimensions. Format: [1, H, W, C_OUT] + * @param[in] output_dims Output tensor dimensions. Format: [1, H, W, C_OUT] + * @return Size of additional memory required for optimizations in bytes. + * + */ + int32_t arm_depthwise_conv_wrapper_s8_get_buffer_size(const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_dims *input_dims, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims); + + /** + * @brief Basic s8 depthwise convolution function that doesn't have any constraints on the input dimensions. + * + * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function + * definition file to see if an additional buffer is required. + * Optional function {API}_get_buffer_size() provides the buffer + * size if an additional buffer is required. + * exists if additional memory is. + * @param[in] dw_conv_params Depthwise convolution parameters (e.g. strides, dilations, pads,...) + * dw_conv_params->dilation is not used. + * Range of dw_conv_params->input_offset : [-127, 128] + * Range of dw_conv_params->input_offset : [-128, 127] + * @param[in] quant_params Per-channel quantization info. + * It contains the multiplier and shift values to be applied to each + * output channel + * @param[in] input_dims Input (activation) tensor dimensions. Format: [1, H, W, C_IN] + * Batch argument N is not used. + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [1, H, W, C_OUT] + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [1, H, W, C_OUT] + * @param[in, out] output_data Output data pointer. Data type: int8 + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * - Supported framework: TensorFlow Lite + * - q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs. + */ + arm_status arm_depthwise_conv_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Optimized s8 depthwise convolution function for 3x3 kernel size with some constraints on + * the input arguments(documented below). Refer arm_depthwise_conv_s8() for function + * argument details. + * + * @return The function returns one of the following + * ARM_MATH_SIZE_MISMATCH - Unsupported dimension of tensors + * ARM_MATH_ARGUMENT_ERROR - Unsupported pad size along the x axis + * ARM_MATH_SUCCESS - Successful operation + * + * @details + * - Supported framework : TensorFlow Lite Micro + * - The following constrains on the arguments apply + * -# Number of input channel equals number of output channels + * -# Filter height and width equals 3 + * -# Padding along x is either 0 or 1. + * + */ + arm_status arm_depthwise_conv_3x3_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Optimized s8 depthwise convolution function with constraint that in_channel equals out_channel. + * Refer arm_depthwise_conv_s8() for function argument details. + * + * @return The function returns one of the following + * ARM_MATH_SIZE_MISMATCH - input channel != output channel or + * ch_mult != 1 + * ARM_MATH_SUCCESS - Successful operation + * + * @note If number of channels is not a multiple of 4, upto 3 elements outside the boundary will be read out + * for the following if MVE optimizations(Arm Helium Technology) are used. + * - Output shift + * - Output multiplier + * - Output bias + * - kernel + * @details + * - Supported framework: TensorFlow Lite + * - The following constrains on the arguments apply + * -# Number of input channel equals number of output channels or ch_mult equals 1 + * - q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs. + * - Reccomended when number of channels is 4 or greater. + * + */ + arm_status arm_depthwise_conv_s8_opt(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for optimized s8 depthwise convolution + * function with constraint that in_channel equals out_channel. + * @param[in] input_dims Input (activation) tensor dimensions. Format: [1, H, W, C_IN] + * Batch argument N is not used. + * @param[in] filter_dims Filter tensor dimensions. Format: [1, H, W, C_OUT] + * @return The function returns required buffer size in bytes + * + */ + int32_t arm_depthwise_conv_s8_opt_get_buffer_size(const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims); + + /** + * @defgroup FC Fully-connected Layer Functions + * + * Collection of fully-connected and matrix multiplication functions. + * + * Fully-connected layer is basically a matrix-vector multiplication + * with bias. The matrix is the weights and the input/output vectors + * are the activation values. Supported {weight, activation} precisions + * include {8-bit, 8-bit}, {16-bit, 16-bit}, and {8-bit, 16-bit}. + * + * Here we have two types of kernel functions. The basic function + * implements the function using regular GEMV approach. The opt functions + * operates with weights in interleaved formats. + * + */ + + /** + * @brief Q7 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q7(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Basic s8 Fully Connected function. + * + * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function + * definition file to see if an additional buffer is required. + * Optional function {API}_get_buffer_size() provides the buffer + * size if an additional buffer is required. + * @param[in] fc_params Fully Connected layer parameters (e.g. strides, dilations, pads,...) + * Range of fc_params->input_offset : [-127, 128] + * Range of fc_params->filter_offset : [-127, 128] + * Range of fc_params->output_offset : [-128, 127] + * @param[in] quant_params Per-tensor quantization info. + * It contains the multiplier and shift values to be applied to the output tensor. + * @param[in] input_dims Input (activation) tensor dimensions. Format: [N, H, W, C_IN] + * Input dimension is taken as Nx(H * W * C_IN) + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Two dimensional filter dimensions. Format: [N, C] + * N : accumulation depth and equals (H * W * C_IN) from input_dims + * C : output depth and equals C_OUT in output_dims + * H & W : Not used + * @param[in] filter_data Filter data pointer. Data type: int8 + * @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT] + * N, H, W : Not used + * @param[in] bias_data Bias data pointer. Data type: int32 + * @param[in] output_dims Output tensor dimensions. Format: [N, C_OUT] + * N : Batches + * C_OUT : Output depth + * H & W : Not used. + * @param[in, out] output_data Output data pointer. Data type: int8 + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * - Supported framework: TensorFlow Lite + * - q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs. + */ + arm_status + arm_fully_connected_s8(const cmsis_nn_context *ctx, + const cmsis_nn_fc_params *fc_params, + const cmsis_nn_per_tensor_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for S8 basic fully-connected and + * matrix multiplication layer function for TF Lite + * @param[in] filter_dims dimension of filter + * @return The function returns required buffer size in bytes + * + */ + int32_t arm_fully_connected_s8_get_buffer_size(const cmsis_nn_dims *filter_dims); + + /** + * @brief Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q7_opt(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Q15 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q15(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q15_opt(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Mixed Q15-Q7 fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_mat_q7_vec_q15(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Mixed Q15-Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_mat_q7_vec_q15_opt(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + +/** + * @brief Matrix-Multiplication Kernels for Convolution + * + * These functions are used within convolution layer functions for + * matrix multiplication. + * + * The implementation is similar to CMSIS-DSP arm_mat_mult functions + * with one Q7 and one Q15 operands. The Q15 operand is the im2col + * output which is always with 2 columns. + * + */ + + /** + * @brief Matrix-multiplication function for convolution + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + */ + + q7_t *arm_nn_mat_mult_kernel_q7_q15(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut); + /** + * @brief Matrix-multiplication function for convolution with per-channel requantization. + * @param[in] input_a pointer to operand A + * @param[in] input_b pointer to operand B, always consists of 2 vectors. + * @param[in] output_ch number of rows of A + * @param[in] out_shift pointer to per output channel requantization shift parameter. + * @param[in] out_mult pointer to per output channel requantization multiplier parameter. + * @param[in] out_offset output tensor offset. + * @param[in] activation_min minimum value to clamp the output to. Range : int8 + * @param[in] activation_max maximum value to clamp the output to. Range : int8 + * @param[in] num_col_a number of columns of A + * @param[in] output_bias per output channel bias. Range : int32 + * @param[in,out] out_0 pointer to output + * @return The function returns one of the two + * 1. The incremented output pointer for a successful operation or + * 2. NULL if implementation is not available. + * + * @details This function does the matrix multiplication of weight matrix for all output channels + * with 2 columns from im2col and produces two elements/output_channel. The outputs are + * clamped in the range provided by activation min and max. + * Supported framework: TensorFlow Lite micro. + */ + q7_t *arm_nn_mat_mult_kernel_s8_s16(const q7_t *input_a, + const q15_t *input_b, + const uint16_t output_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int16_t activation_min, + const int16_t activation_max, + const uint16_t num_col_a, + const int32_t *const output_bias, + q7_t *out_0); + + /** + * @brief Matrix-multiplication of re-ordered input B with A. + * + * @details For arguments, refer arm_nn_mat_mult_kernel_s8_s16. The re-ordering is a consequence + * of sign extension done by the SXTB16 command on input_b. The outputs are clamped in the range + * provided by activation min and max. + * * @details + * - Supported framework : TensorFlow Lite Micro + * - The following constrains on the arguments apply + * -# num_col_a is a multiple of 4 + * -# output_ch is a multiple of 2 + * + */ + q7_t *arm_nn_mat_mult_kernel_s8_s16_reordered(const q7_t *input_a, + const q15_t *input_b, + const uint16_t output_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int16_t activation_min, + const int16_t activation_max, + const uint16_t num_col_a, + const int32_t *const output_bias, + q7_t *out_0); + + /** + * @brief Matrix-multiplication function for convolution with reordered columns + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + * + * @details This function assumes that data in pInBuffer are reordered + */ + q7_t *arm_nn_mat_mult_kernel_q7_q15_reordered(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut); + +#ifdef __cplusplus +} +#endif + +/* + * Other functions + * These layers are typically not timing critical + * Basic implementation is supported here + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup BasicMath Basic math functions + * + * Element wise add and multiplication functions. + * + */ + +/** + * @brief s8 element wise add of two vectors + * @param[in] input_1_vect pointer to input vector 1 + * @param[in] input_2_vect pointer to input vector 2 + * @param[in] input_1_offset offset for input 1. Range: Range: -127 to 128 + * @param[in] input_1_mult multiplier for input 1 + * @param[in] input_1_shift shift for input 1 + * @param[in] input_2_offset offset for input 2. Range: Range: -127 to 128 + * @param[in] input_2_mult multiplier for input 2 + * @param[in] input_2_shift shift for input 2 + * @param[in] left_shift input left shift + * @param[in,out] output pointer to output vector + * @param[in] out_offset output offset + * @param[in] out_mult output multiplier + * @param[in] out_shift output shift + * @param[in] out_activation_min minimum value to clamp output to + * @param[in] out_activation_max maximum value to clamp output to + * @param[in] block_size number of samples + * @return The function returns ARM_MATH_SUCCESS + */ + arm_status arm_elementwise_add_s8(const int8_t *input_1_vect, + const int8_t *input_2_vect, + const int32_t input_1_offset, + const int32_t input_1_mult, + const int32_t input_1_shift, + const int32_t input_2_offset, + const int32_t input_2_mult, + const int32_t input_2_shift, + const int32_t left_shift, + int8_t *output, + const int32_t out_offset, + const int32_t out_mult, + const int32_t out_shift, + const int32_t out_activation_min, + const int32_t out_activation_max, + const uint32_t block_size); + +/** + * @brief s8 element wise multiplication + * @param[in] input_1_vect pointer to input vector 1 + * @param[in] input_2_vect pointer to input vector 2 + * @param[in] input_1_offset offset for input 1. Range: Range: -127 to 128 + * @param[in] input_2_offset offset for input 2. Range: Range: -127 to 128 + * @param[in,out] output pointer to output vector + * @param[in] out_offset output offset + * @param[in] out_mult output multiplier + * @param[in] out_shift output shift + * @param[in] out_activation_min minimum value to clamp output to + * @param[in] out_activation_max maximum value to clamp output to + * @param[in] block_size number of samples + * @return The function returns ARM_MATH_SUCCESS + * + * @details Supported framework: TensorFlow Lite micro + */ + arm_status arm_elementwise_mul_s8(const int8_t *input_1_vect, + const int8_t *input_2_vect, + const int32_t input_1_offset, + const int32_t input_2_offset, + int8_t *output, + const int32_t out_offset, + const int32_t out_mult, + const int32_t out_shift, + const int32_t out_activation_min, + const int32_t out_activation_max, + const uint32_t block_size); +/** + * @defgroup Acti Activation Functions + * + * Perform activation layers, including ReLU (Rectified Linear Unit), + * sigmoid and tanh + * + */ + + /** + * @brief Q7 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + */ + + void arm_relu_q7(q7_t *data, uint16_t size); + + /** + * @brief s8 ReLU6 function + * @param[in,out] data pointer to input + * @param[in] size number of elements + */ + + void arm_relu6_s8(q7_t *data, uint16_t size); + + /** + * @brief Q15 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + */ + + void arm_relu_q15(q15_t *data, uint16_t size); + + /** + * @brief Q7 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + */ + + void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width, + arm_nn_activation_type type); + + /** + * @brief Q15 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + * + * @details + * + * This is the direct table look-up approach. + * + * Assume here the integer part of the fixed-point is <= 3. + * More than 3 just not making much sense, makes no difference with + * saturation followed by any of these activation functions. + */ + + void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width, + arm_nn_activation_type type); + +/** + * @defgroup Pooling Pooling Functions + * + * Perform pooling functions, including max pooling and average pooling + * + */ + + /** + * @brief Q7 max pooling function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + */ + + void arm_maxpool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const uint16_t dim_im_out, + q7_t * bufferA, + q7_t * Im_out); + + /** + * @brief Q7 average pooling function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimension + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + */ + + void arm_avepool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const uint16_t dim_im_out, + q7_t * bufferA, + q7_t * Im_out); + + /** + * @brief s8 average pooling function. + * + * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function + * definition file to see if an additional buffer is required. + * Optional function {API}_get_buffer_size() provides the buffer + * size if an additional buffer is required. + * @param[in] pool_params Pooling parameters + * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN] + * Argument 'N' is not used. + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [H, W] + * Argument N and C are not used. + * @param[in] output_dims Output tensor dimensions. Format: [H, W, C_OUT] + * Argument N is not used. + * C_OUT equals C_IN. + * @param[in, out] output_data Output data pointer. Data type: int8 + * @return The function returns + * ARM_MATH_SUCCESS - Successful operation + * + * @details + * - Supported Framework: TensorFlow Lite + * + */ + arm_status arm_avgpool_s8(const cmsis_nn_context *ctx, + const cmsis_nn_pool_params *pool_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims, + q7_t *output_data); + + /** + * @brief Get the required buffer size for S8 average pooling function + * @param[in] dim_dst_width output tensor dimension + * @param[in] ch_src number of input tensor channels + * @return The function returns required buffer size in bytes + * + */ + int32_t arm_avgpool_s8_get_buffer_size(const int dim_dst_width, + const int ch_src); + + /** + * @brief s8 max pooling function. + * + * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function + * definition file to see if an additional buffer is required. + * Optional function {API}_get_buffer_size() provides the buffer + * size if an additional buffer is required. + * @param[in] pool_params Pooling parameters + * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN] + * Argument 'N' is not used. + * @param[in] input_data Input (activation) data pointer. Data type: int8 + * @param[in] filter_dims Filter tensor dimensions. Format: [H, W] + * Argument N and C are not used. + * @param[in] output_dims Output tensor dimensions. Format: [H, W, C_OUT] + * Argument N is not used. + * C_OUT equals C_IN. + * @param[in, out] output_data Output data pointer. Data type: int8 + * @return The function returns + * ARM_MATH_SUCCESS - Successful operation + * + * @details + * - Supported Framework: TensorFlow Lite + * + */ + arm_status arm_max_pool_s8(const cmsis_nn_context *ctx, + const cmsis_nn_pool_params *pool_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims, + q7_t *output_data); +/** + * @defgroup Softmax Softmax Functions + * + * EXP(2) based softmax functions. + * + */ + + /** + * @brief Q7 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimension + * @param[out] p_out pointer to output vector + * + * @note This function is an optimized version which is not bit-accurate with + * TensorFlow Lite's kernel + * + */ + +void arm_softmax_q7(const q7_t * vec_in, const uint16_t dim_vec, q7_t * p_out); + + /** + * @brief Q7 softmax function with batch parameter + * @param[in] vec_in pointer to input vector + * @param[in] nb_batches number of batches + * @param[in] dim_vec input vector dimension + * @param[out] p_out pointer to output vector + * @return none. + * + * @note This function is an optimized version which is not bit-accurate with + * TensorFlow Lite's kernel + * + */ + +void arm_softmax_with_batch_q7(const q7_t * vec_in, const uint16_t nb_batches,const uint16_t dim_vec, q7_t * p_out ); + /** + * @brief Q15 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimension + * @param[out] p_out pointer to output vector + * @return none. + * + * @note This function is an optimized version which is not bit-accurate with + * TensorFlow Lite's kernel + * + */ + +void arm_softmax_q15(const q15_t * vec_in, const uint16_t dim_vec, q15_t * p_out); + + /** + * @brief S8 softmax function + * @param[in] input Pointer to the input tensor + * @param[in] num_rows Number of rows in the input tensor + * @param[in] row_size Number of elements in each input row + * @param[in] mult Input quantization multiplier + * @param[in] shift Input quantization shift within the range [0, 31] + * @param[in] diff_min Minimum difference with max in row. Used to check if + * the quantized exponential operation can be performed + * @param[out] output Pointer to the output tensor + * + * @note Supported framework: TensorFlow Lite micro (bit-accurate) + * + */ + +void arm_softmax_s8(const int8_t *input, + const int32_t num_rows, + const int32_t row_size, + const int32_t mult, + const int32_t shift, + const int32_t diff_min, + int8_t *output); + + /** + * @brief U8 softmax function + * @param[in] input Pointer to the input tensor + * @param[in] num_rows Number of rows in the input tensor + * @param[in] row_size Number of elements in each input row + * @param[in] mult Input quantization multiplier + * @param[in] shift Input quantization shift within the range [0, 31] + * @param[in] diff_min Minimum difference with max in row. Used to check if + * the quantized exponential operation can be performed + * @param[out] output Pointer to the output tensor + * + * @note Supported framework: TensorFlow Lite micro (bit-accurate) + * + */ + +void arm_softmax_u8(const uint8_t *input, + const int32_t num_rows, + const int32_t row_size, + const int32_t mult, + const int32_t shift, + const int32_t diff_min, + uint8_t *output); + + /** + * @brief uint8 depthwise convolution function with asymmetric quantization + * Unless specified otherwise, arguments are mandatory. + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_ch Channels in input tensor + * @param[in] kernel Pointer to kernel weights + * @param[in] kernel_x Width of kernel + * @param[in] kernel_y Height of kernel + * @param[in] ch_mult Number of channel multiplier + * @param[in] pad_x Padding sizes x + * @param[in] pad_y Padding sizes y + * @param[in] stride_x stride along the width + * @param[in] stride_y stride along the height + * @param[in] dilation_x Dilation along width. Not used and intended for future enhancement. + * @param[in] dilation_y Dilation along height. Not used and intended for future enhancement. + * @param[in] bias Pointer to optional bias values. If no bias is + * availble, NULL is expected + * @param[in] input_offset Input tensor zero offset + * @param[in] filter_offset Kernel tensor zero offset + * @param[in] output_offset Output tensor zero offset + * @param[in,out] output Pointer to output tensor + * @param[in] output_x Width of output tensor + * @param[in] output_y Height of output tensor + * @param[in] output_activation_min Minimum value to clamp the output to. Range : {0, 255} + * @param[in] output_activation_max Minimum value to clamp the output to. Range : {0, 255} + * @param[in] out_shift Amount of right-shift for output + * @param[in] out_mult Output multiplier for requantization + * @return The function returns the following + * ARM_MATH_SUCCESS - Successful operation + * + */ + arm_status arm_depthwise_conv_u8_basic_ver1(const uint8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_ch, + const uint8_t *kernel, + const uint16_t kernel_x, + const uint16_t kernel_y, + const int16_t ch_mult, + const int16_t pad_x, + const int16_t pad_y, + const int16_t stride_x, + const int16_t stride_y, + const int16_t dilation_x, + const int16_t dilation_y, + const int32_t *bias, + const int32_t input_offset, + const int32_t filter_offset, + const int32_t output_offset, + uint8_t *output, + const uint16_t output_x, + const uint16_t output_y, + const int32_t output_activation_min, + const int32_t output_activation_max, + const int32_t out_shift, + const int32_t out_mult); + +/** + * @defgroup Reshape Reshape Functions + * + */ + + /** + * @brief Reshape a s8 vector into another with different shape + * @param[in] input points to the s8 input vector + * @param[out] output points to the s8 output vector + * @param[in] total_size total size of the input and output vectors in bytes + * + * @note The output is expected to be in a memory area that does not overlap with the input's + * + */ + void arm_reshape_s8(const int8_t *input, + int8_t *output, + const uint32_t total_size); + +/** + * @defgroup Concatenation Concatenation Functions + * + */ + + /** + * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the X axis + * This function should be called for each input tensor to concatenate. The argument offset_x + * will be used to store the input tensor in the correct position in the output tensor + * + * i.e. offset_x = 0 + * for(i = 0 i < num_input_tensors; ++i) + * { + * arm_concatenation_s8_x(&input[i], ..., &output, ..., ..., offset_x) + * offset_x += input_x[i] + * } + * + * This function assumes that the output tensor has: + * -# The same height of the input tensor + * -# The same number of channels of the input tensor + * -# The same batch size of the input tensor + * + * Unless specified otherwise, arguments are mandatory. + * + * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_z Channels in input tensor + * @param[in] input_w Batch size in input tensor + * @param[out] output Pointer to output tensor + * @param[in] output_x Width of output tensor + * @param[in] offset_x The offset (in number of elements) on the X axis to start concatenating the input tensor + * It is user responsibility to provide the correct value + * + * Input constraints + * offset_x is less than output_x + * + */ + void arm_concatenation_s8_x(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_x, + const uint32_t offset_x); + + /** + * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the Y axis + * This function should be called for each input tensor to concatenate. The argument offset_y + * will be used to store the input tensor in the correct position in the output tensor + * + * i.e. offset_y = 0 + * for(i = 0 i < num_input_tensors; ++i) + * { + * arm_concatenation_s8_y(&input[i], ..., &output, ..., ..., offset_y) + * offset_y += input_y[i] + * } + * + * This function assumes that the output tensor has: + * -# The same width of the input tensor + * -# The same number of channels of the input tensor + * -# The same batch size of the input tensor + * + * Unless specified otherwise, arguments are mandatory. + * + * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_z Channels in input tensor + * @param[in] input_w Batch size in input tensor + * @param[out] output Pointer to output tensor + * @param[in] output_y Height of output tensor + * @param[in] offset_y The offset on the Y axis to start concatenating the input tensor + * It is user responsibility to provide the correct value + * + * Input constraints + * offset_y is less than output_y + * + */ + void arm_concatenation_s8_y(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_y, + const uint32_t offset_y); + + /** + * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the Z axis + * This function should be called for each input tensor to concatenate. The argument offset_z + * will be used to store the input tensor in the correct position in the output tensor + * + * i.e. offset_z = 0 + * for(i = 0 i < num_input_tensors; ++i) + * { + * arm_concatenation_s8_z(&input[i], ..., &output, ..., ..., offset_z) + * offset_z += input_z[i] + * } + * + * This function assumes that the output tensor has: + * -# The same width of the input tensor + * -# The same height of the input tensor + * -# The same batch size of the input tensor + * + * Unless specified otherwise, arguments are mandatory. + * + * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_z Channels in input tensor + * @param[in] input_w Batch size in input tensor + * @param[out] output Pointer to output tensor + * @param[in] output_z Channels in output tensor + * @param[in] offset_z The offset on the Z axis to start concatenating the input tensor + * It is user responsibility to provide the correct value + * + * Input constraints + * offset_z is less than output_z + * + */ + void arm_concatenation_s8_z(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_z, + const uint32_t offset_z); + + /** + * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the W axis (Batch size) + * This function should be called for each input tensor to concatenate. The argument offset_w + * will be used to store the input tensor in the correct position in the output tensor + * + * i.e. offset_w = 0 + * for(i = 0 i < num_input_tensors; ++i) + * { + * arm_concatenation_s8_w(&input[i], ..., &output, ..., ..., offset_w) + * offset_w += input_w[i] + * } + * + * This function assumes that the output tensor has: + * -# The same width of the input tensor + * -# The same height of the input tensor + * -# The same number o channels of the input tensor + * + * Unless specified otherwise, arguments are mandatory. + * + * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_z Channels in input tensor + * @param[in] input_w Batch size in input tensor + * @param[out] output Pointer to output tensor + * @param[in] offset_w The offset on the W axis to start concatenating the input tensor + * It is user responsibility to provide the correct value + * + */ + void arm_concatenation_s8_w(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint32_t offset_w); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h new file mode 100644 index 0000000..c14f382 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h @@ -0,0 +1,905 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nnsupportfunctions.h + * Description: Public header file of support functions for CMSIS NN Library + * + * $Date: May 11, 2020 + * $Revision: V.4.0.4 + * + * Target Processor: Cortex-M CPUs + * -------------------------------------------------------------------- */ + +#ifndef _ARM_NNSUPPORTFUNCTIONS_H_ +#define _ARM_NNSUPPORTFUNCTIONS_H_ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/DSP/Include/arm_common_tables.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define LEFT_SHIFT(_shift) (_shift > 0 ? _shift : 0) +#define RIGHT_SHIFT(_shift) (_shift > 0 ? 0 : -_shift) +#define MASK_IF_ZERO(x) (x) == 0 ? ~0 : 0 +#define MASK_IF_NON_ZERO(x) (x) != 0 ? ~0 : 0 +#define SELECT_USING_MASK(mask, a, b) ((mask) & (a)) ^ (~(mask) & (b)) + +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define CLAMP(x, h, l) MAX(MIN((x), (h)), (l)) + +/** + * @brief Union for SIMD access of q31/q15/q7 types + */ +union arm_nnword +{ + q31_t word; + /**< q31 type */ + q15_t half_words[2]; + /**< q15 type */ + q7_t bytes[4]; + /**< q7 type */ +}; + +/** + * @brief Struct for specifying activation function types + * + */ +typedef enum +{ + ARM_SIGMOID = 0, + /**< Sigmoid activation function */ + ARM_TANH = 1, + /**< Tanh activation function */ +} arm_nn_activation_type; + +/** + * @defgroup nndata_convert Neural Network Data Conversion Functions + * + * Perform data type conversion in-between neural network operations + * + */ + +/** + * @brief Converts the elements of the q7 vector to q15 vector without left-shift + * @param[in] *pSrc points to the q7 input vector + * @param[out] *pDst points to the q15 output vector + * @param[in] blockSize length of the input vector + * + */ +void arm_q7_to_q15_no_shift(const q7_t *pSrc, q15_t *pDst, uint32_t blockSize); + +/** + * @brief Non-saturating addition of elements of a q7 vector + * @param[in] *input Pointer to the q7 input vector + * @param[out] *output Pointer to the q31 output variable. + * @param[in] block_size length of the input vector + * \par Description: + * + * 2^24 samples can be added without saturating the result. + * + * The equation used for the conversion process is: + * + *
+ *  sum = input[0] + input[1] + .. + input[block_size -1]
+ * 
+ * + * */ +void arm_nn_add_q7(const q7_t *input, q31_t *output, uint32_t block_size); + +/** + * @brief Converts the elements of the q7 vector to reordered q15 vector without left-shift + * @param[in] *pSrc points to the q7 input vector + * @param[out] *pDst points to the q15 output vector + * @param[in] blockSize length of the input vector + * @return none. + * + */ +void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize); + +/** + * @brief Converts the elements from a q7 vector to a q15 vector with an added offset + * @param[in] src pointer to the q7 input vector + * @param[out] dst pointer to the q15 output vector + * @param[in] block_size length of the input vector + * @param[in] offset q7 offset to be added to each input vector element. + * + * \par Description: + * + * The equation used for the conversion process is: + * + *
+ *  dst[n] = (q15_t) src[n] + offset;   0 <= n < block_size.
+ * 
+ * + */ +void arm_q7_to_q15_with_offset(const q7_t *src, q15_t *dst, uint32_t block_size, q15_t offset); + +/** + * @brief Converts the elements of the q7 vector to reordered q15 vector with an added offset + * @param[in] src pointer to the q7 input vector + * @param[out] dst pointer to the q15 output vector + * @param[in] block_size length of the input vector + * @param[in] offset offset to be added to each input vector element. + * @return none. + * + * @details This function does the q7 to q15 expansion with re-ordering of bytes. Re-ordering is a consequence of + * the sign extension intrinsic(DSP extension). The tail (i.e., last (N % 4) elements) retains its original + * order. + * + */ +void arm_q7_to_q15_reordered_with_offset(const q7_t *src, q15_t *dst, uint32_t block_size, q15_t offset); + +/** + * @brief Converts the elements from a q7 vector and accumulate to a q15 vector + * @param[in] *src points to the q7 input vector + * @param[out] *dst points to the q15 output vector + * @param[in] block_size length of the input vector + * + * \par Description: + * + * The equation used for the conversion process is: + * + *
+ *  dst[n] += (q15_t) src[n] ;   0 <= n < block_size.
+ * 
+ * + */ +void arm_nn_accumulate_q7_to_q15(q15_t *dst, const q7_t *src, uint32_t block_size); + +/** + * @brief Depthwise conv on an im2col buffer where the input channel equals output channel. + * @param[in] row pointer to row + * @param[in] col pointer to im2col buffer, always consists of 2 columns. + * @param[in] num_ch number of channels + * @param[in] out_shift pointer to per output channel requantization shift parameter. + * @param[in] out_mult pointer to per output channel requantization multiplier parameter. + * @param[in] out_offset output tensor offset. + * @param[in] activation_min minimum value to clamp the output to. Range : int8 + * @param[in] activation_max maximum value to clamp the output to. Range : int8 + * @param[in] kernel_size number of elements in one column. + * @param[in] output_bias per output channel bias. Range : int32 + * @param[out] out pointer to output + * @return The function returns one of the two + * 1. The incremented output pointer for a successful operation or + * 2. NULL if implementation is not available. + * + * @details Supported framework: TensorFlow Lite micro. + */ +q7_t *arm_nn_depthwise_conv_s8_core(const q7_t *row, + const q15_t *col, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t kernel_size, + const int32_t *const output_bias, + q7_t *out); + +/** + * @brief General Matrix-multiplication function with per-channel requantization. + * @param[in] input_row pointer to row operand + * @param[in] input_col pointer to col operand + * @param[in] output_ch number of rows of input_row + * @param[in] col_batches number of column batches. Range: 1 to 4 + * @param[in] output_shift pointer to per output channel requantization shift parameter. + * @param[in] output_mult pointer to per output channel requantization multiplier parameter. + * @param[in] out_offset output tensor offset. + * @param[in] col_offset input tensor(col) offset. + * @param[in] row_offset kernel offset(row). Not used. + * @param[in] out_activation_min minimum value to clamp the output to. Range : int8 + * @param[in] out_activation_max maximum value to clamp the output to. Range : int8 + * @param[in] row_len number of elements in each row + * @param[in] bias per output channel bias. Range : int32 + * @param[in,out] out pointer to output + * @return The function returns one of the two + * 1. The incremented output pointer for a successful operation or + * 2. NULL if implementation is not available. + * + * @details Supported framework: TensorFlow Lite +*/ +q7_t *arm_nn_mat_mult_s8(const q7_t *input_row, + const q7_t *input_col, + const uint16_t output_ch, + const uint16_t col_batches, + const int32_t *output_shift, + const int32_t *output_mult, + const int32_t out_offset, + const int32_t col_offset, + const int32_t row_offset, + const int16_t out_activation_min, + const int16_t out_activation_max, + const uint16_t row_len, + const int32_t *const bias, + q7_t *out); + +/** + * @brief General Matrix-multiplication without requantization for one row & one column + * @param[in] row_elements number of row elements + * @param[in] row_base pointer to row operand + * @param[in] col_base pointer to col operand + * @param[out] sum_col pointer to store sum of column elements + * @param[out] output pointer to store result of multiply-accumulate + * @return The function returns the multiply-accumulated result of the row by column. + * + * @details Pseudo-code + * *output = 0 + * sum_col = 0 + * for (i = 0; i < row_elements; i++) + * *output += row_base[i] * col_base[i] + * sum_col += col_base[i] + * +*/ +arm_status arm_nn_mat_mul_core_1x_s8(int32_t row_elements, + const int8_t *row_base, + const int8_t *col_base, + int32_t *const sum_col, + int32_t *const output); + +/** + * @brief General Matrix-multiplication without requantization for four rows and one column + * @param[in] row_elements number of row elements + * @param[in] offset offset between rows. Can be the same as row_elements. + * For e.g, in a 1x1 conv scenario with stride as 1. + * @param[in] row_base pointer to row operand + * @param[in] col_base pointer to col operand + * @param[out] sum_col pointer to store sum of column elements + * @param[out] output pointer to store result(4 int32's) of multiply-accumulate + * @return The function returns the multiply-accumulated result of the row by column + * + * @details Pseudo-code + * output[0] = 0 + * .. + * output[3] = 0 + * sum_col = 0 + * for (i = 0; i < row_elements; i++) + * output[0] += row_base[i] * col_base[i] + * .. + * output[3] += row_base[i + (row_elements * 3)] * col_base[i] + * sum_col += col_base[i] +*/ +arm_status arm_nn_mat_mul_core_4x_s8(const int32_t row_elements, + const int32_t offset, + const int8_t *row_base, + const int8_t *col_base, + int32_t *const sum_col, + int32_t *const output); + +/** +* @brief General Matrix-multiplication function with per-channel requantization. +* This function assumes: +* - LHS input matrix NOT transposed (nt) +* - RHS input matrix transposed (t) +* +* @note This operation also performs the broadcast bias addition before the requantization +* +* @param[in] lhs Pointer to the LHS input matrix +* @param[in] rhs Pointer to the RHS input matrix +* @param[in] bias Pointer to the bias vector. The length of this vector is equal to the number of output columns (or RHS input rows) +* @param[out] dst Pointer to the output matrix with "m" rows and "n" columns +* @param[in] dst_multipliers Pointer to the multipliers vector needed for the per-channel requantization. The length of this vector is equal to +* the number of output columns (or RHS input rows) +* @param[in] dst_shifts Pointer to the shifts vector needed for the per-channel requantization. The length of this vector is equal to +* the number of output columns (or RHS input rows) +* @param[in] lhs_rows Number of LHS input rows +* @param[in] rhs_rows Number of RHS input rows +* @param[in] rhs_cols Number of LHS/RHS input columns +* @param[in] lhs_offset Offset to be applied to the LHS input value +* @param[in] dst_offset Offset to be applied the output result +* @param[in] activation_min Minimum value to clamp down the output. Range : int8 +* @param[in] activation_max Maximum value to clamp up the output. Range : int8 +* +* @return The function returns ARM_MATH_SUCCESS +* +*/ +arm_status arm_nn_mat_mult_nt_t_s8(const q7_t *lhs, + const q7_t *rhs, + const q31_t *bias, + q7_t *dst, + const int32_t *dst_multipliers, + const int32_t *dst_shifts, + const int32_t lhs_rows, + const int32_t rhs_rows, + const int32_t rhs_cols, + const int32_t lhs_offset, + const int32_t dst_offset, + const int32_t activation_min, + const int32_t activation_max); + +/** + * @brief s8 Vector by Matrix (transposed) multiplication + * + * @param[in] lhs Input left-hand side vector + * @param[in] rhs Input right-hand side matrix (transposed) + * @param[in] bias Input bias + * @param[out] dst Output vector + * @param[in] lhs_offset Offset to be added to the input values of the left-hand side vector. Range: -127 to 128 + * @param[in] rhs_offset Offset to be added to the input values of the right-hand side matrix. Range: -127 to 128 + * @param[in] dst_offset Offset to be added to the output values. Range: -127 to 128 + * @param[in] dst_multiplier Output multiplier + * @param[in] dst_shift Output shift + * @param[in] rhs_cols Number of columns in the right-hand side input matrix + * @param[in] rhs_rows Number of rows in the right-hand side input matrix + * @param[in] activation_min Minimum value to clamp the output to. Range: int8 + * @param[in] activation_max Maximum value to clamp the output to. Range: int8 + * + * @return The function returns ARM_MATH_SUCCESS + * + */ +arm_status arm_nn_vec_mat_mult_t_s8(const q7_t *lhs, + const q7_t *rhs, + const q31_t *bias, + q7_t *dst, + const int32_t lhs_offset, + const int32_t rhs_offset, + const int32_t dst_offset, + const int32_t dst_multiplier, + const int32_t dst_shift, + const int32_t rhs_cols, + const int32_t rhs_rows, + const int32_t activation_min, + const int32_t activation_max); + +/** + * @brief Depthwise convolution of transposed rhs matrix with 4 lhs matrices. To be used in padded cases where + * the padding is -lhs_offset(Range: int8). Dimensions are the same for lhs and rhs. + * + * @param[in] lhs Input left-hand side matrix + * @param[in] rhs Input right-hand side matrix (transposed) + * @param[in] lhs_offset LHS matrix offset(input offset). Range: -127 to 128 + * @param[in] num_ch Number of channels in LHS/RHS + * @param[in] out_shift Per channel output shift. Length of vector is equal to number of channels + * @param[in] out_mult Per channel output multiplier. Length of vector is equal to number of channels + * @param[in] out_offset Offset to be added to the output values. Range: -127 to 128 + * @param[in] activation_min Minimum value to clamp the output to. Range: int8 + * @param[in] activation_max Maximum value to clamp the output to. Range: int8 + * @param[in] row_x_col (row_dimension * col_dimension) of LHS/RHS matrix + * @param[in] output_bias Per channel output bias. Length of vector is equal to number of channels + * @param[in] out Output pointer + * + * @return The function returns one of the two + * - Updated output pointer if an implementaiton is available + * - NULL if no implementation is available. + * + * @note If number of channels is not a multiple of 4, upto 3 elements outside the boundary will be read out + * for the following. + * - Output shift + * - Output multiplier + * - Output bias + * - rhs + */ +q7_t *arm_nn_depthwise_conv_nt_t_padded_s8(const q7_t *lhs, + const q7_t *rhs, + const int32_t lhs_offset, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t row_x_col, + const int32_t *const output_bias, + q7_t *out); + +/** + * @brief Depthwise convolution of transposed rhs matrix with 4 lhs matrices. To be used in non-padded cases. + * Dimensions are the same for lhs and rhs. + * + * @param[in] lhs Input left-hand side matrix + * @param[in] rhs Input right-hand side matrix (transposed) + * @param[in] lhs_offset LHS matrix offset(input offset). Range: -127 to 128 + * @param[in] num_ch Number of channels in LHS/RHS + * @param[in] out_shift Per channel output shift. Length of vector is equal to number of channels. + * @param[in] out_mult Per channel output multiplier. Length of vector is equal to number of channels. + * @param[in] out_offset Offset to be added to the output values. Range: -127 to 128 + * @param[in] activation_min Minimum value to clamp the output to. Range: int8 + * @param[in] activation_max Maximum value to clamp the output to. Range: int8 + * @param[in] row_x_col (row_dimension * col_dimension) of LHS/RHS matrix + * @param[in] output_bias Per channel output bias. Length of vector is equal to number of channels. + * @param[in] out Output pointer + * + * @return The function returns one of the two + * - Updated output pointer if an implementaiton is available + * - NULL if no implementation is available. + * + * @note If number of channels is not a multiple of 4, upto 3 elements outside the boundary will be read out + * for the following. + * - Output shift + * - Output multiplier + * - Output bias + * - rhs + */ +q7_t *arm_nn_depthwise_conv_nt_t_s8(const q7_t *lhs, + const q7_t *rhs, + const int32_t lhs_offset, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t row_x_col, + const int32_t *const output_bias, + q7_t *out); + +/** + @brief Read 2 q15 elements and post increment pointer. + @param[in] in_q15 Pointer to pointer that holds address of input. + @return q31 value + */ +__STATIC_FORCEINLINE q31_t arm_nn_read_q15x2_ia(const q15_t **in_q15) +{ + q31_t val; + + memcpy(&val, *in_q15, 4); + *in_q15 += 2; + + return (val); +} + +/** + @brief Read 4 q7 from q7 pointer and post increment pointer. + @param[in] in_q7 Pointer to pointer that holds address of input. + @return q31 value + */ +__STATIC_FORCEINLINE q31_t arm_nn_read_q7x4_ia(const q7_t **in_q7) +{ + q31_t val; + memcpy(&val, *in_q7, 4); + *in_q7 += 4; + + return (val); +} + +/** + @brief Read 2 q15 from q15 pointer. + @param[in] in_q15 pointer to address of input. + @return q31 value + */ +__STATIC_FORCEINLINE q31_t arm_nn_read_q15x2(const q15_t *in_q15) +{ + q31_t val; + memcpy(&val, in_q15, 4); + + return (val); +} + +/** + @brief Read 4 q7 values. + @param[in] in_q7 pointer to address of input. + @return q31 value + */ +__STATIC_FORCEINLINE q31_t arm_nn_read_q7x4(const q7_t *in_q7) +{ + q31_t val; + memcpy(&val, in_q7, 4); + + return (val); +} + +/** + * @brief memset optimized for MVE + * @param[in, out] dst Destination pointer + * @param[in] val Value to set + * @param[in] block_size Number of bytes to copy. + * + */ +__STATIC_FORCEINLINE void arm_memset_q7(q7_t *dst, + const q7_t val, + uint32_t block_size) +{ +#if defined(ARM_MATH_MVEI) + __asm volatile ( + " vdup.8 q0, %[set_val] \n" + " wlstp.8 lr, %[cnt], 1f \n" + "2: \n" + " vstrb.8 q0, [%[in]], 16 \n" + " letp lr, 2b \n" + "1: \n" + :[in] "+r"(dst) + :[cnt] "r"(block_size), [set_val] "r"(val) + :"q0", "memory", "r14"); +#else + memset(dst, val, block_size); +#endif +} + +#if defined (ARM_MATH_DSP) + +/** + * @brief read and expand one q7 word into two q15 words + */ + +__STATIC_FORCEINLINE const q7_t *read_and_pad(const q7_t *source, q31_t * out1, q31_t * out2) +{ + q31_t inA = arm_nn_read_q7x4_ia(&source); + q31_t inAbuf1 = __SXTB16(__ROR((uint32_t)inA, 8)); + q31_t inAbuf2 = __SXTB16(inA); + +#ifndef ARM_MATH_BIG_ENDIAN + *out2 = (int32_t) (__PKHTB (inAbuf1, inAbuf2, 16)); + *out1 = (int32_t) (__PKHBT (inAbuf2, inAbuf1, 16)); +#else + *out1 = (int32_t) (__PKHTB(inAbuf1, inAbuf2, 16)); + *out2 = (int32_t) (__PKHBT(inAbuf2, inAbuf1, 16)); +#endif + + return source; +} + +/** + * @brief read and expand one q7 word into two q15 words with reordering + */ + +__STATIC_FORCEINLINE const q7_t *read_and_pad_reordered(const q7_t *source, q31_t * out1, q31_t * out2) +{ + q31_t inA = arm_nn_read_q7x4_ia(&source); +#ifndef ARM_MATH_BIG_ENDIAN + *out2 = __SXTB16(__ROR((uint32_t)inA, 8)); + *out1 = __SXTB16(inA); +#else + *out1 = __SXTB16(__ROR((uint32_t)inA, 8)); + *out2 = __SXTB16(inA); +#endif + + return source; +} + +/** + * @brief read and expand one q7 word into two q15 words with reordering and add an offset + */ +__STATIC_FORCEINLINE const q7_t *read_and_pad_reordered_with_offset(const q7_t *source, q31_t * out1, q31_t * out2, q31_t offset) +{ + q31_t inA = arm_nn_read_q7x4_ia(&source); + +#ifndef ARM_MATH_BIG_ENDIAN + *out2 = __SXTB16(__ROR((uint32_t)inA, 8)); + *out1 = __SXTB16(inA); +#else + *out1 = __SXTB16(__ROR((uint32_t)inA, 8)); + *out2 = __SXTB16(inA); +#endif + *out1 = __QADD16(*out1,offset); + *out2 = __QADD16(*out2,offset); + + return source; +} + +#endif + + + +/** + * @defgroup NNBasicMath Basic Math Functions for Neural Network Computation + * + * Basic Math Functions for Neural Network Computation + * + */ + +/** + * @brief q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable q15 range [0x8000 0x7FFF] will be saturated. + */ + +void arm_nn_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + const uint16_t out_shift, + uint32_t blockSize); + +/** + * @brief q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable q7 range [0x80 0x7F] will be saturated. + */ + +void arm_nn_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + const uint16_t out_shift, + uint32_t blockSize); + +/** + * @brief macro for adding rounding offset + */ +#ifndef ARM_NN_TRUNCATE + #define NN_ROUND(out_shift) ( (0x1u << out_shift) >> 1 ) +#else + #define NN_ROUND(out_shift) 0 +#endif + +// Macros for shortening quantization functions' names and avoid long lines +#define MUL_SAT(a, b) arm_nn_sat_doubling_high_mult((a), (b)) +#define MUL_SAT_MVE(a, b) arm_sat_doubling_high_mult_mve_32x4((a), (b)) +#define MUL_POW2(a, b) arm_nn_mult_by_power_of_two((a), (b)) + + +#define DIV_POW2(a, b) arm_nn_divide_by_power_of_two((a), (b)) +#define DIV_POW2_MVE(a, b) arm_divide_by_power_of_two_mve((a), (b)) + + +#define EXP_ON_NEG(x) arm_nn_exp_on_negative_values((x)) +#define ONE_OVER1(x) arm_nn_one_over_one_plus_x_for_x_in_0_1((x)) + +/** + * @brief Saturating doubling high multiply. Result matches + * NEON instruction VQRDMULH. + * @param[in] m1 Multiplicand + * @param[in] m2 Multiplier + * @return Result of multiplication. + * + */ +__STATIC_FORCEINLINE q31_t arm_nn_sat_doubling_high_mult(const q31_t m1, const q31_t m2) +{ + q31_t result = 0; + // Rounding offset to add for a right shift of 31 + q63_t mult = 1 << 30; + + if ((m1 < 0) ^ (m2 < 0)) + { + mult = 1 - mult; + } + // Gets resolved as a SMLAL instruction + mult = mult + (q63_t)m1 * m2; + + // Utilize all of the upper 32 bits. This is the doubling step + // as well. + result = (int32_t) (mult / (1ll << 31)); + + if ((m1 == m2) && (m1 == (int32_t)Q31_MIN)) + { + result = Q31_MAX; + } + return result; +} + +/** + * @brief Rounding divide by power of two. + * @param[in] dividend - Dividend + * @param[in] exponent - Divisor = power(2, exponent) + * Range: [0, 31] + * @return Rounded result of division. Midpoint is rounded away from zero. + * + */ +__STATIC_FORCEINLINE q31_t arm_nn_divide_by_power_of_two(const q31_t dividend, const q31_t exponent) +{ + q31_t result = 0; + const q31_t remainder_mask = (1 << exponent) - 1; + int32_t remainder = remainder_mask & dividend; + + // Basic division + result = dividend >> exponent; + + // Adjust 'result' for rounding (mid point away from zero) + q31_t threshold = remainder_mask >> 1; + if (result < 0) + { + threshold++; + } + if (remainder > threshold) + { + result++; + } + + return result; +} + +/** + * @brief Requantize a given value. + * @param[in] val Value to be requantized + * @param[in] multiplier multiplier + * @param[in] shift left or right shift for 'val * multiplier' + * + * @return Returns (val * multiplier)/(2 ^ shift) + * + */ +__STATIC_FORCEINLINE q31_t arm_nn_requantize(const q31_t val, const q31_t multiplier, const q31_t shift) +{ + return arm_nn_divide_by_power_of_two(arm_nn_sat_doubling_high_mult(val * (1 << LEFT_SHIFT(shift)), multiplier), + RIGHT_SHIFT(shift)); +} + +/** + * @brief memcpy optimized for MVE + * @param[in, out] dst Destination pointer + * @param[in] src Source pointer. + * @param[in] block_size Number of bytes to copy. + * + */ +__STATIC_FORCEINLINE void arm_memcpy_q7(q7_t *__RESTRICT dst, + const q7_t *__RESTRICT src, + uint32_t block_size) +{ +#if defined(ARM_MATH_MVEI) + __asm volatile ( + " wlstp.8 lr, %[cnt], 1f \n" + "2: \n" + " vldrb.8 q0, [%[in]], 16 \n" + " vstrb.8 q0, [%[out]], 16 \n" + " letp lr, 2b \n" + "1: \n" + :[in] "+r"(src) + ,[out] "+r"(dst) + :[cnt] "r"(block_size) + :"q0", "memory", "r14"); +#else + memcpy(dst, src, block_size); +#endif +} + +#if defined(ARM_MATH_MVEI) +/** + * @brief Vector saturating doubling high multiply returning high half. + * @param[in] m1 Multiplicand + * @param[in] m2 Multiplier + * @return Result of multiplication. + * + */ +__STATIC_FORCEINLINE int32x4_t arm_sat_doubling_high_mult_mve(const int32x4_t m1, const q31_t m2) +{ + return vqrdmulhq_n_s32(m1, m2); +} + +/** + * @brief Vector rounding divide by power of two. + * @param[in] dividend - Dividend vector + * @param[in] exponent - Divisor = power(2, exponent) + * Range: [0, 31] + * @return Rounded result of division. Midpoint is rounded away from zero. + * + */ +__STATIC_FORCEINLINE int32x4_t arm_divide_by_power_of_two_mve(const int32x4_t dividend, const q31_t exponent) +{ + const int32x4_t shift = vdupq_n_s32(-exponent); + const int32x4_t fixup = vshrq_n_s32(vandq_s32(dividend, shift), 31); + const int32x4_t fixed_up_dividend = vqaddq_s32(dividend, fixup); + return vrshlq_s32(fixed_up_dividend, shift); +} + +/** + * @brief Requantize a given vector. + * @param[in] val Vector to be requantized + * @param[in] multiplier multiplier + * @param[in] shift shift + * + * @return Returns (val * multiplier)/(2 ^ shift) + * + */ +__STATIC_FORCEINLINE int32x4_t arm_requantize_mve(const int32x4_t val, const q31_t multiplier, const q31_t shift) +{ + return arm_divide_by_power_of_two_mve( + arm_sat_doubling_high_mult_mve(vshlq_s32(val, vdupq_n_s32(LEFT_SHIFT(shift))), multiplier), + RIGHT_SHIFT(shift)); +} + +__STATIC_FORCEINLINE int32x4_t arm_sat_doubling_high_mult_mve_32x4(const int32x4_t m1, const int32x4_t m2) +{ + return vqrdmulhq_s32(m1, m2); +} + +__STATIC_FORCEINLINE int32x4_t arm_divide_by_power_of_two_mve_32x4(const int32x4_t dividend, const int32x4_t exponent) +{ + const int32x4_t shift = -exponent; + const int32x4_t fixup = vshrq_n_s32(vandq_s32(dividend, shift), 31); + const int32x4_t fixed_up_dividend = vqaddq_s32(dividend, fixup); + return vrshlq_s32(fixed_up_dividend, shift); +} + +__STATIC_FORCEINLINE int32x4_t arm_requantize_mve_32x4(const int32x4_t val, const int32x4_t multiplier, const int32x4_t shift) +{ + const int32x4_t zz = vdupq_n_s32(0); + const mve_pred16_t p = vcmpgtq_n_s32(shift, 0); + + const int32x4_t left_shift = vpselq_s32(shift, zz, p); + const int32x4_t right_shift = -vpselq_s32(zz, shift, p); + + return arm_divide_by_power_of_two_mve_32x4(arm_sat_doubling_high_mult_mve_32x4(vshlq_s32(val, left_shift), multiplier), right_shift); +} +#endif + +// @note The following functions are used only for softmax layer, scaled bits = 5 assumed + +__STATIC_FORCEINLINE int32_t arm_nn_exp_on_negative_values(int32_t val) +{ + int32_t mask = 0; + int32_t shift = 24; + + const int32_t val_mod_minus_quarter = (val & ((1 << shift) - 1)) - (1 << shift); + const int32_t remainder = val_mod_minus_quarter - val; + const int32_t x = (val_mod_minus_quarter << 5) + (1 << 28); + const int32_t x2 = MUL_SAT(x, x); + + int32_t result = 1895147668 + MUL_SAT(1895147668, x + + DIV_POW2(MUL_SAT(DIV_POW2(MUL_SAT(x2, x2), 2) + MUL_SAT(x2, x), 715827883) + x2, 1)); + +#define SELECT_IF_NON_ZERO(x) \ +{ \ + mask = MASK_IF_NON_ZERO(remainder & (1 << shift++)); \ + result = SELECT_USING_MASK(mask, MUL_SAT(result, x), result); \ +} + + SELECT_IF_NON_ZERO(1672461947) + SELECT_IF_NON_ZERO(1302514674) + SELECT_IF_NON_ZERO(790015084) + SELECT_IF_NON_ZERO(290630308) + SELECT_IF_NON_ZERO(39332535) + SELECT_IF_NON_ZERO(720401) + SELECT_IF_NON_ZERO(242) + +#undef SELECT_IF_NON_ZERO + + mask = MASK_IF_ZERO(val); + return SELECT_USING_MASK(mask, Q31_MAX, result); +} + +__STATIC_FORCEINLINE q31_t arm_nn_mult_by_power_of_two(const int32_t val, const int32_t exp) +{ + const int32_t thresh = ((1 << (31 - exp)) - 1); + int32_t result = val << exp; + result = SELECT_USING_MASK(MASK_IF_NON_ZERO(val > thresh), Q31_MAX, result); + result = SELECT_USING_MASK(MASK_IF_NON_ZERO(val < -thresh), Q31_MIN, result); + return result; +} + +__STATIC_FORCEINLINE int32_t arm_nn_one_over_one_plus_x_for_x_in_0_1(int32_t val) +{ + const int64_t sum = (int64_t)val + (int64_t)Q31_MAX; + const int32_t half_denominator = (int32_t)((sum + (sum >= 0 ? 1 : -1)) / 2L); + int32_t x = 1515870810 + MUL_SAT(half_denominator, -1010580540); + + const int32_t shift = (1 << 29); + x += MUL_POW2(MUL_SAT(x, shift - MUL_SAT(half_denominator, x)), 2); + x += MUL_POW2(MUL_SAT(x, shift - MUL_SAT(half_denominator, x)), 2); + x += MUL_POW2(MUL_SAT(x, shift - MUL_SAT(half_denominator, x)), 2); + + return MUL_POW2(x, 1); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c new file mode 100644 index 0000000..69c6877 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_activations_q15.c + * Description: Q15 neural network activation function using direct table look-up + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/DSP/Include/arm_common_tables.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + +/** + * @brief neural network activation function using direct table look-up + * + * @note Refer header file for details. + * + */ + +void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type) +{ + uint16_t i = size; + q15_t *pIn = data; + q15_t *pOut = data; + uint16_t shift_size = 8 + 3 - int_width; + uint32_t bit_mask = 0x7FF >> int_width; + uint32_t full_frac = bit_mask + 1; + const q15_t *lookup_table; + + switch (type) + { + case ARM_SIGMOID: + lookup_table = sigmoidTable_q15; + break; + case ARM_TANH: + default: + lookup_table = tanhTable_q15; + break; + } + + while (i) + { + q15_t out; + q15_t in = *pIn++; + q15_t frac = (uint32_t) in & bit_mask; + q15_t value = lookup_table[(uint8_t)(in >> shift_size)]; + if ((in >> shift_size) != 0x7f) + { + q15_t value2 = lookup_table[(uint8_t)(1 + ((uint8_t)(in >> shift_size)))]; + /* doing the interpolation here for better accuracy */ + out = ((q31_t) (full_frac - frac) * value + (q31_t) value2 * frac) >> shift_size; + } else + { + /* the largest positive value does not have a right side for linear interpolation */ + out = value; + } + + *pOut++ = out; + i--; + } + +} + +/** + * @} end of Acti group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c new file mode 100644 index 0000000..19476ed --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_activations_q7.c + * Description: Q7 neural network activation function using direct table look-up + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/DSP/Include/arm_common_tables.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q7 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * + * @details + * + * This is the direct table look-up approach. + * + * Assume here the integer part of the fixed-point is <= 3. + * More than 3 just not making much sense, makes no difference with + * saturation followed by any of these activation functions. + */ + +void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type) +{ + uint16_t i = size; + q7_t *pIn = data; + q7_t *pOut = data; + q7_t in; + q7_t out; + uint16_t shift_size = 3 - int_width; + const q7_t *lookup_table; + switch (type) + { + case ARM_SIGMOID: + lookup_table = sigmoidTable_q7; + break; + case ARM_TANH: + default: + lookup_table = tanhTable_q7; + break; + } + while (i) + { + in = *pIn++; + out = lookup_table[(uint8_t) (in >> shift_size)]; + *pOut++ = out; + i--; + } +} + +/** + * @} end of Acti group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu6_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu6_s8.c new file mode 100644 index 0000000..63f29f4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu6_s8.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_relu6_s8.c + * Description: Basic s8 version of ReLU6 + * + * $Date: Spetember 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /* + * Basic ReLU6 function + * + * Refer to header file for details. + * + */ + +void arm_relu6_s8(q7_t *data, uint16_t size) +{ + int32_t i; + + for (i = 0; i < size; i++) + { + int32_t ip = data[i]; + + ip = MAX(ip, 0); + data[i] = MIN(ip, 6); + } +} + +/** + * @} end of Acti group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c new file mode 100644 index 0000000..be5450d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_relu_q15.c + * Description: Q15 version of ReLU + * + * $Date: February 27, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + +/** + * @brief Q15 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * + * @details + * + * Optimized relu with QSUB instructions. + * + */ + +void arm_relu_q15(q15_t *data, uint16_t size) +{ + +#if defined(ARM_MATH_DSP) + /* Run the following code for M cores with DSP extension */ + + uint16_t i = size >> 1; + q15_t *input = data; + q15_t *output = data; + q31_t in; + q31_t buf; + q31_t mask; + + while (i) + { + in = read_q15x2_ia(&input); + + /* extract the first bit */ + buf = __ROR(in & 0x80008000, 15); + + /* if MSB=1, mask will be 0xFF, 0x0 otherwise */ + mask = __QSUB16(0x00000000, buf); + + write_q15x2_ia(&output, in & (~mask)); + i--; + } + + if (size & 0x1) + { + if (*input < 0) + { + *input = 0; + } + input++; + } +#else + /* Run the following code as reference implementation for M cores without DSP extension */ + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } + +#endif /* ARM_MATH_DSP */ +} + +/** + * @} end of Acti group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c new file mode 100644 index 0000000..724d7b4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_relu_q7.c + * Description: Q7 version of ReLU + * + * $Date: May 29, 2020 + * $Revision: V.1.0.2 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q7 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * + * @details + * + * Optimized relu with QSUB instructions. + * + */ + +void arm_relu_q7(q7_t *data, uint16_t size) +{ + +#if defined(ARM_MATH_DSP) + /* Run the following code for M cores with DSP extension */ + + uint16_t i = size >> 2; + q7_t *input = data; + q7_t *output = data; + q31_t in; + q31_t buf; + q31_t mask; + + while (i) + { + in = read_q7x4_ia(&input); + + /* extract the first bit */ + buf = (int32_t)__ROR((uint32_t)in & 0x80808080, 7); + + /* if MSB=1, mask will be 0xFF, 0x0 otherwise */ + mask = __QSUB8(0x00000000, buf); + + write_q7x4_ia(&output, in & (~mask)); + + i--; + } + + i = size & 0x3; + while (i) + { + if (*input < 0) + { + *input = 0; + } + input++; + i--; + } + +#else + /* Run the following code as reference implementation for cores without DSP extension */ + + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } + +#endif +} + +/** + * @} end of Acti group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_add_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_add_s8.c new file mode 100644 index 0000000..0ab9e97 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_add_s8.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_elementwise_add_s8 + * Description: Element wise add + * + * $Date: February 27, 2020 + * $Revision: V.2.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" +#if defined(ARM_MATH_MVEI) +#include "arm_helium_utils.h" +#endif + +#if defined(ARM_MATH_MVEI) +#define SAT_INPUT_VECT(__INPUT_V, __MULT, __SHIFT) \ + __INPUT_V = arm_sat_doubling_high_mult_mve(__INPUT_V, __MULT); \ + __INPUT_V = arm_divide_by_power_of_two_mve(__INPUT_V, -__SHIFT); +#endif + +#define SAT_INPUT(__INPUT, __MULT, __SHIFT) \ + __INPUT = arm_nn_sat_doubling_high_mult(__INPUT, __MULT); \ + __INPUT = arm_nn_divide_by_power_of_two(__INPUT, -__SHIFT); + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup BasicMath + * @{ + */ + +/* + * s8 element wise add + * + * Refer header file for details. + * + */ + +/* Note: __SHIFT is expected to be <=0 */ + + +arm_status +arm_elementwise_add_s8(const int8_t *input_1_vect, + const int8_t *input_2_vect, + const int32_t input_1_offset, + const int32_t input_1_mult, + const int32_t input_1_shift, + const int32_t input_2_offset, + const int32_t input_2_mult, + const int32_t input_2_shift, + const int32_t left_shift, + int8_t *output, + const int32_t out_offset, + const int32_t out_mult, + const int32_t out_shift, + const int32_t out_activation_min, + const int32_t out_activation_max, + const uint32_t block_size) +{ +#if defined(ARM_MATH_MVEI) + int32_t count = (int32_t)block_size; + + while (count > 0) + { + int32x4_t vect_1; + int32x4_t vect_2; + + mve_pred16_t p = vctp32q((uint32_t)count); + + vect_1 = vldrbq_z_s32(input_1_vect, p); + vect_2 = vldrbq_z_s32(input_2_vect, p); + + vect_1 = vaddq_s32(vect_1, vdupq_n_s32(input_1_offset)); + vect_2 = vaddq_s32(vect_2, vdupq_n_s32(input_2_offset)); + + vect_1 = vshlq_r_s32(vect_1, left_shift); + vect_2 = vshlq_r_s32(vect_2, left_shift); + + SAT_INPUT_VECT(vect_1, input_1_mult, input_1_shift); + SAT_INPUT_VECT(vect_2, input_2_mult, input_2_shift); + + vect_1 = vaddq_s32(vect_1, vect_2); + SAT_INPUT_VECT(vect_1, out_mult, out_shift); + + vect_1 = vaddq_n_s32(vect_1, out_offset); + + vect_1 = vmaxq_s32(vect_1, vdupq_n_s32(out_activation_min)); + vect_1 = vminq_s32(vect_1, vdupq_n_s32(out_activation_max)); + + input_1_vect += 4; + input_2_vect += 4; + vstrbq_p_s32(output, vect_1, p); + + output += 4; + count -= 4; + } +#else + uint32_t loop_count; + int32_t input_1; + int32_t input_2; + int32_t sum; + +#if defined(ARM_MATH_DSP) + int32_t a_1, b_1, a_2, b_2; + + int32_t offset_1_packed, offset_2_packed; + + int8_t r1, r2, r3, r4; + + offset_1_packed = (input_1_offset << 16U) | (input_1_offset & 0x0FFFFL); + offset_2_packed = (input_2_offset << 16U) | (input_2_offset & 0x0FFFFL); + + loop_count = block_size >> 2; + + while (loop_count > 0U) + { + /* 4 outputs are calculated in one loop. The order of calculation is follows the order of output sign extension + intrinsic */ + input_1_vect = read_and_pad_reordered(input_1_vect, &b_1, &a_1); + input_2_vect = read_and_pad_reordered(input_2_vect, &b_2, &a_2); + + a_1 = __SADD16(a_1, offset_1_packed); + b_1 = __SADD16(b_1, offset_1_packed); + + a_2 = __SADD16(a_2, offset_2_packed); + b_2 = __SADD16(b_2, offset_2_packed); + + /* Sum 1 */ + input_1 = (int16_t)(b_1 & 0x0FFFFL) << left_shift; + SAT_INPUT(input_1, input_1_mult, input_1_shift); + + input_2 = (int16_t)(b_2 & 0x0FFFFL) << left_shift; + SAT_INPUT(input_2, input_2_mult, input_2_shift); + + sum = input_1 + input_2; + SAT_INPUT(sum, out_mult, out_shift); + sum += out_offset; + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + r1 = (q7_t)sum; + + /* Sum 3 */ + input_1 = (int16_t)((b_1 >> 16) & 0x0FFFFL) << left_shift; + SAT_INPUT(input_1, input_1_mult, input_1_shift); + + input_2 = (int16_t)((b_2 >> 16) & 0x0FFFFL) << left_shift; + SAT_INPUT(input_2, input_2_mult, input_2_shift); + + sum = input_1 + input_2; + SAT_INPUT(sum, out_mult, out_shift); + sum += out_offset; + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + r3 = (q7_t)sum; + + /* Sum 2 */ + input_1 = (int16_t)(a_1 & 0x0FFFFL) << left_shift; + SAT_INPUT(input_1, input_1_mult, input_1_shift); + + input_2 = (int16_t)(a_2 & 0x0FFFFL) << left_shift; + SAT_INPUT(input_2, input_2_mult, input_2_shift); + + sum = input_1 + input_2; + SAT_INPUT(sum, out_mult, out_shift); + sum += out_offset; + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + r2 = (q7_t)sum; + + /* Sum 4 */ + input_1 = (int16_t)((a_1 >> 16) & 0x0FFFFL) << left_shift; + SAT_INPUT(input_1, input_1_mult, input_1_shift); + + input_2 = (int16_t)((a_2 >> 16) & 0x0FFFFL) << left_shift; + SAT_INPUT(input_2, input_2_mult, input_2_shift); + + sum = input_1 + input_2; + SAT_INPUT(sum, out_mult, out_shift); + sum += out_offset; + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + r4 = (q7_t)sum; + + write_q7x4_ia(&output, __PACKq7(r1, r2, r3, r4)); + + loop_count--; + } + + loop_count = block_size & 0x3; +#else + loop_count = block_size; +#endif + + while (loop_count > 0U) + { + /* C = A + B */ + + input_1 = (*input_1_vect++ + input_1_offset) << left_shift; + input_2 = (*input_2_vect++ + input_2_offset) << left_shift; + + input_1 = arm_nn_sat_doubling_high_mult(input_1, input_1_mult); + input_1 = arm_nn_divide_by_power_of_two(input_1, -input_1_shift); + + input_2 = arm_nn_sat_doubling_high_mult(input_2, input_2_mult); + input_2 = arm_nn_divide_by_power_of_two(input_2, -input_2_shift); + + sum = input_1 + input_2; + SAT_INPUT(sum, out_mult, out_shift); + sum += out_offset; + + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + + *output++ = (q7_t)sum; + + /* Decrement loop counter */ + loop_count--; + } + +#endif /* ARM_MATH_MVEI */ + + return (ARM_MATH_SUCCESS); +} + +/** + * @} end of BasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_mul_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_mul_s8.c new file mode 100644 index 0000000..55303b7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_mul_s8.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_elementwise_mul_s8 + * Description: Element wise multiplication + * + * $Date: May 29, 2020 + * $Revision: V.1.0.3 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup BasicMath + * @{ + */ + +/** + * @brief s8 element wise multiplication of two vectors + * + * @note Refer header file for details. + * + */ + +arm_status +arm_elementwise_mul_s8(const int8_t *input_1_vect, + const int8_t *input_2_vect, + const int32_t input_1_offset, + const int32_t input_2_offset, + int8_t *output, + const int32_t out_offset, + const int32_t out_mult, + const int32_t out_shift, + const int32_t out_activation_min, + const int32_t out_activation_max, + const uint32_t block_size) +{ + + int32_t loop_count; +#if defined(ARM_MATH_MVEI) + + loop_count = (block_size + 3) / 4; + uint32_t num_elements = block_size; + + for (int i = 0; i < loop_count; i++) + { + mve_pred16_t p = vctp32q(num_elements); + + int32x4_t input_1 = vldrbq_z_s32(input_1_vect, p); + input_1 = vaddq_n_s32(input_1, input_1_offset); + + int32x4_t input_2 = vldrbq_z_s32(input_2_vect, p); + input_2 = vaddq_n_s32(input_2, input_2_offset); + + int32x4_t res_0 = vmulq_s32(input_1, input_2); + + res_0 = arm_requantize_mve_32x4(res_0, vdupq_n_s32(out_mult), vdupq_n_s32(out_shift)); + + res_0 += vdupq_n_s32(out_offset); + + res_0 = vmaxq_s32(res_0, vdupq_n_s32(out_activation_min)); + res_0 = vminq_s32(res_0, vdupq_n_s32(out_activation_max)); + + vstrbq_p_s32(output, res_0, p); + input_1_vect += 4; + input_2_vect += 4; + output += 4; + num_elements -= 4; + } + +#else + int32_t input_1; + int32_t input_2; + int32_t mul_res; + +#if defined(ARM_MATH_DSP) + int32_t a_1, b_1, a_2, b_2; + + int32_t offset_1_packed, offset_2_packed; + + int8_t r1, r2, r3, r4; + + offset_1_packed = (input_1_offset << 16U) | (input_1_offset & 0x0FFFFL); + offset_2_packed = (input_2_offset << 16U) | (input_2_offset & 0x0FFFFL); + + loop_count = block_size >> 2; + + while (loop_count > 0U) + { + /* 4 outputs are calculated in one loop. The order of calculation is follows the order of output sign extension + intrinsic */ + input_1_vect = read_and_pad_reordered(input_1_vect, &b_1, &a_1); + input_2_vect = read_and_pad_reordered(input_2_vect, &b_2, &a_2); + + a_1 = __SADD16(a_1, offset_1_packed); + b_1 = __SADD16(b_1, offset_1_packed); + + a_2 = __SADD16(a_2, offset_2_packed); + b_2 = __SADD16(b_2, offset_2_packed); + + /* Mul 1 */ + input_1 = (int16_t)(b_1 & 0x0FFFFL); + input_2 = (int16_t)(b_2 & 0x0FFFFL); + + mul_res = input_1 * input_2; + mul_res = arm_nn_requantize(mul_res, out_mult, out_shift) + out_offset; + + mul_res = MAX(mul_res, out_activation_min); + mul_res = MIN(mul_res, out_activation_max); + r1 = (q7_t)mul_res; + + /* Mul 3 */ + input_1 = (int16_t)((b_1 >> 16U) & 0x0FFFFL); + input_2 = (int16_t)((b_2 >> 16U) & 0x0FFFFL); + + mul_res = input_1 * input_2; + mul_res = arm_nn_requantize(mul_res, out_mult, out_shift) + out_offset; + mul_res = MAX(mul_res, out_activation_min); + mul_res = MIN(mul_res, out_activation_max); + r3 = (q7_t)mul_res; + + /* Mul 2 */ + input_1 = (int16_t)(a_1 & 0x0FFFFL); + input_2 = (int16_t)(a_2 & 0x0FFFFL); + + mul_res = input_1 * input_2; + mul_res = arm_nn_requantize(mul_res, out_mult, out_shift) + out_offset; + mul_res = MAX(mul_res, out_activation_min); + mul_res = MIN(mul_res, out_activation_max); + r2 = (q7_t)mul_res; + + /* Mul 4 */ + input_1 = (int16_t)((a_1 >> 16U) & 0x0FFFFL); + input_2 = (int16_t)((a_2 >> 16U) & 0x0FFFFL); + + mul_res = input_1 * input_2; + mul_res = arm_nn_requantize(mul_res, out_mult, out_shift) + out_offset; + mul_res = MAX(mul_res, out_activation_min); + mul_res = MIN(mul_res, out_activation_max); + r4 = (q7_t)mul_res; + + write_q7x4_ia(&output, __PACKq7(r1, r2, r3, r4)); + + loop_count--; + } + + loop_count = block_size & 0x3; +#else + loop_count = block_size; +#endif + + while (loop_count > 0U) + { + /* C = A * B */ + + input_1 = *input_1_vect++ + input_1_offset; + input_2 = *input_2_vect++ + input_2_offset; + + mul_res = input_1 * input_2; + mul_res = arm_nn_requantize(mul_res, out_mult, out_shift) + out_offset; + + mul_res = MAX(mul_res, out_activation_min); + mul_res = MIN(mul_res, out_activation_max); + + *output++ = (q7_t)mul_res; + + /* Decrement loop counter */ + loop_count--; + } +#endif + return ARM_MATH_SUCCESS; +} + +/** + * @} end of BasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_w.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_w.c new file mode 100644 index 0000000..20b68bc --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_w.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_concatenation_s8_w.c + * Description: s8 version of concatenation along the W axis + * + * $Date: October 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Concatenation + * @{ + */ + + /* + * s8 version of concatenation along the W axis + * + * Refer to header file for details. + * + */ +void arm_concatenation_s8_w(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint32_t offset_w) +{ + const uint32_t input_copy_size = input_x * input_y * input_z * input_w; + + output += offset_w * (input_x * input_y * input_z); + + memcpy(output, input, input_copy_size); +} + +/** + * @} end of Concatenation group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_x.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_x.c new file mode 100644 index 0000000..b1ff364 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_x.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_concatenation_s8_x.c + * Description: s8 version of concatenation along the X axis + * + * $Date: October 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Concatenation + * @{ + */ + + /* + * s8 version of concatenation along the X axis + * + * Refer to header file for details. + * + */ +void arm_concatenation_s8_x(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_x, + const uint32_t offset_x) +{ + const uint32_t num_iterations = input_y * input_z * input_w; + + output += offset_x; + + uint32_t i; + + // Copy per row + for (i = 0; i < num_iterations; ++i) + { + memcpy(output, input, input_x); + input += input_x; + output += output_x; + } +} + +/** + * @} end of Concatenation group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_y.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_y.c new file mode 100644 index 0000000..4791368 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_y.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_concatenation_s8_y.c + * Description: s8 version of concatenation along the Y axis + * + * $Date: October 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Concatenation + * @{ + */ + + /* + * s8 version of concatenation along the Y axis + * + * Refer to header file for details. + * + */ +void arm_concatenation_s8_y(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_y, + const uint32_t offset_y) +{ + const uint32_t num_iterations = input_z * input_w; + const uint32_t input_copy_size = input_x * input_y; + const uint32_t output_stride = input_x * output_y; + + output += offset_y * input_x; + uint32_t i; + + // Copy per tile + for (i = 0; i < num_iterations; ++i) + { + memcpy(output, input, input_copy_size); + input += input_copy_size; + output += output_stride; + } +} + +/** + * @} end of Concatenation group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_z.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_z.c new file mode 100644 index 0000000..0d0bf50 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_z.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_concatenation_s8_z.c + * Description: s8 version of concatenation along the Z axis + * + * $Date: October 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Concatenation + * @{ + */ + + /* + * s8 version of concatenation along the Z axis + * + * Refer to header file for details. + * + */ +void arm_concatenation_s8_z(const int8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_z, + const uint16_t input_w, + int8_t *output, + const uint16_t output_z, + const uint32_t offset_z) +{ + const uint32_t input_copy_size = input_x * input_y * input_z; + const uint32_t output_stride = input_x * input_y * output_z; + + output += offset_z * (input_x * input_y); + + uint32_t i; + + for (i = 0; i < input_w; ++i) + { + memcpy(output, input, input_copy_size); + input += input_copy_size; + output += output_stride; + } +} + +/** + * @} end of Concatenation group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1_x_n_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1_x_n_s8.c new file mode 100644 index 0000000..f2af65b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1_x_n_s8.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_1_x_n_s8.c + * Description: s8 version of 1xN convolution using symmetric quantization. + * + * $Date: May 18, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nn_types.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * 1xN s8 convolution function. + * + * Refer header file for details. + * + */ + +arm_status arm_convolve_1_x_n_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data) +{ + (void)bias_dims; + arm_status status = ARM_MATH_SUCCESS; + if (output_dims->w % 4 != 0) + { + status = ARM_MATH_SIZE_MISMATCH; + goto out; + } + +#if defined(ARM_MATH_MVEI) + q15_t *buffer_a = (q15_t *)ctx->buf; + + const uint16_t input_x = input_dims->w; + const uint16_t kernel_x = filter_dims->w; + const uint16_t output_x = output_dims->w; + const uint16_t output_ch = output_dims->c; + const uint16_t input_ch = input_dims->c; + const uint16_t pad_x = conv_params->padding.w; + const uint16_t stride_x = conv_params->stride.w; + + const int32_t input_offset = conv_params->input_offset; + const int32_t out_offset = conv_params->output_offset; + const int32_t out_activation_min = conv_params->activation.min; + const int32_t out_activation_max = conv_params->activation.max; + int32_t *output_mult = quant_params->multiplier; + int32_t *output_shift = quant_params->shift; + + for (int i_out_x = 0; i_out_x <= (output_x - 4); i_out_x += 4) + { + int32_t input_begin_idx[4]; + int32_t ker_begin_idx[4]; + int32_t ker_end_idx[4]; + + for (int i = 0; i < 4; i++) + { + const int32_t est_input_x_idx = stride_x * (i_out_x + i) - pad_x; + input_begin_idx[i] = MAX(0, est_input_x_idx); + ker_begin_idx[i] = MAX(0, -est_input_x_idx); + ker_end_idx[i] = MIN(kernel_x, input_x - est_input_x_idx); + } + + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32x4_t s_offset; + int32_t acc[4]; + if ((ker_begin_idx[0] != 0) || (ker_end_idx[3] != kernel_x)) + { + int32_t sum_row[4]; + + (void)arm_nn_mat_mul_core_1x_s8((ker_end_idx[0] - ker_begin_idx[0]) * input_ch, + input_data + input_begin_idx[0] * input_ch, + filter_data + (input_ch * kernel_x * i_out_ch) + (ker_begin_idx[0] * input_ch), + &sum_row[0], + &acc[0]); + (void)arm_nn_mat_mul_core_1x_s8((ker_end_idx[1] - ker_begin_idx[1]) * input_ch, + input_data + input_begin_idx[1] * input_ch, + filter_data + (input_ch * kernel_x * i_out_ch) + (ker_begin_idx[1] * input_ch), + &sum_row[1], + &acc[1]); + + (void)arm_nn_mat_mul_core_1x_s8((ker_end_idx[2] - ker_begin_idx[2]) * input_ch, + input_data + input_begin_idx[2] * input_ch, + filter_data + (input_ch * kernel_x * i_out_ch) + (ker_begin_idx[2] * input_ch), + &sum_row[2], + &acc[2]); + + (void)arm_nn_mat_mul_core_1x_s8((ker_end_idx[3] - ker_begin_idx[3]) * input_ch, + input_data + input_begin_idx[3] * input_ch, + filter_data + (input_ch * kernel_x * i_out_ch) + (ker_begin_idx[3] * input_ch), + &sum_row[3], + &acc[3]); + + s_offset = vldrwq_s32(sum_row); + } + else + { + int32_t sum_row; + (void)arm_nn_mat_mul_core_4x_s8(kernel_x * input_ch, + stride_x * input_ch, + input_data + input_begin_idx[0] * input_ch, + filter_data + (input_ch * kernel_x * i_out_ch), + &sum_row, + acc); + + s_offset = vdupq_n_s32(sum_row); + } + int32x4_t res = vldrwq_s32(acc); + s_offset = vmulq_n_s32(s_offset, input_offset); + + res = vaddq_n_s32(res, bias_data[i_out_ch]); + res = vaddq_s32(res, s_offset); + res = arm_requantize_mve(res, output_mult[i_out_ch], output_shift[i_out_ch]); + res = vaddq_n_s32(res, out_offset); + + res = vmaxq_s32(res, vdupq_n_s32(out_activation_min)); + res = vminq_s32(res, vdupq_n_s32(out_activation_max)); + + const uint32x4_t scatter_offset = {0, output_ch, output_ch * 2, output_ch * 3}; + vstrbq_scatter_offset_s32(output_data, scatter_offset, res); + output_data++; + } + output_data += (3 * output_ch); + } + +#else + status = arm_convolve_s8(ctx, + conv_params, + quant_params, + input_dims, + input_data, + filter_dims, + filter_data, + bias_dims, + bias_data, + output_dims, + output_data); +#endif + +out: + /* Return to application */ + return status; +} + +int32_t arm_convolve_1_x_n_s8_get_buffer_size(const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims) +{ +#if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI) + return (2 * input_dims->c * filter_dims->w * filter_dims->h) * sizeof(int16_t); +#else + (void)input_dims; + (void)filter_dims; + return 0; +#endif +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c new file mode 100644 index 0000000..0725e61 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_1x1_HWC_q7_fast_nonsquare.c + * Description: Fast Q7 version of 1x1 convolution (non-square shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Fast Q7 version of 1x1 convolution (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is optimized for convolution with 1x1 kernel size (i.e., dim_kernel_x=1 + * and dim_kernel_y=1). It can be used for the second half of MobileNets [1] after depthwise + * separable convolution. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + * + * [1] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications + * https://arxiv.org/abs/1704.04861 + */ + +arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + (void)dim_im_in_y; + int16_t i_out_y, i_out_x; + int16_t i_ch_out; + + /* ----------------------- + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1 + || padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_out_y * dim_im_in_x + i_out_x) * ch_im_in, pBuffer, + ch_im_in); + pBuffer += ch_im_in; + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + q31_t sum = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + const q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad_reordered(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia(&pB); + + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1 + || padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_y + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_s8_fast.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_s8_fast.c new file mode 100644 index 0000000..75e4c8e --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_s8_fast.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_1x1_s8_fast.c + * Description: Fast q7 version of 1x1 convolution (non-square shape) + * + * $Date: May 29, 2020 + * $Revision: V.2.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nn_types.h" + +#define DIM_KER_X (1U) +#define DIM_KER_Y (1U) + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * Fast s8 version for 1x1 convolution (non-square shape) + * + * Refer header file for details. + * + */ + +arm_status arm_convolve_1x1_s8_fast(const cmsis_nn_context *ctx, + const cmsis_nn_conv_params *conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input_data, + const cmsis_nn_dims *filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims *bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims *output_dims, + q7_t *output_data) +{ + if (input_dims->c % 4 != 0 || + conv_params->padding.w != 0 || conv_params->padding.h != 0 || + conv_params->stride.w != 1 || conv_params->stride.h != 1) + { + return ARM_MATH_SIZE_MISMATCH; + } + + (void)ctx; + (void)filter_dims; + (void)bias_dims; + +#if defined(ARM_MATH_MVEI) + + const int32_t col_len = input_dims->w * input_dims->h * input_dims->n; + const int32_t output_ch = output_dims->c; + const int32_t input_ch = input_dims->c; + const int32_t input_offset = conv_params->input_offset; + const int32_t out_offset = conv_params->output_offset; + const int32_t out_activation_min = conv_params->activation.min; + const int32_t out_activation_max = conv_params->activation.max; + int32_t *output_mult = quant_params->multiplier; + int32_t *output_shift = quant_params->shift; + + for (int i_items = 0; i_items <= (col_len - 4); i_items += 4) + { + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32_t sum_row = 0; + int32_t temp_out[4]; + + (void)arm_nn_mat_mul_core_4x_s8(input_ch, + input_ch, + input_data + i_items * input_ch, + filter_data + i_out_ch * input_ch, + &sum_row, + temp_out); + int32x4_t res = vldrwq_s32(temp_out); + + res = vaddq_n_s32(res, bias_data[i_out_ch]); + sum_row = sum_row * input_offset; + res = vaddq_n_s32(res, sum_row); + res = arm_requantize_mve(res, output_mult[i_out_ch], output_shift[i_out_ch]); + res = vaddq_n_s32(res, out_offset); + + res = vmaxq_s32(res, vdupq_n_s32(out_activation_min)); + res = vminq_s32(res, vdupq_n_s32(out_activation_max)); + + const uint32x4_t scatter_offset = {0, (uint32_t)output_ch, + (uint32_t)output_ch * 2, + (uint32_t)output_ch * 3}; + vstrbq_scatter_offset_s32(output_data, scatter_offset, res); + output_data++; + } + output_data += (3 * output_ch); + } + + /* Handle left over elements */ + for (int i_items = (col_len & ~0x3); i_items < col_len; i_items++) + { + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32_t sum_row = 0; + + int32_t acc; + (void)arm_nn_mat_mul_core_1x_s8(input_ch, + input_data + i_items * input_ch, + filter_data + i_out_ch * input_ch, + &sum_row, + &acc); + + acc += bias_data[i_out_ch]; + sum_row = (sum_row * input_offset); + acc += sum_row; + acc = arm_nn_requantize(acc, output_mult[i_out_ch], output_shift[i_out_ch]); + acc += out_offset; + + acc = MAX(acc, out_activation_min); + acc = MIN(acc, out_activation_max); + *output_data++ = acc; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M processors with or without DSP extension */ + + const int32_t lhs_rows = input_dims->w * input_dims->h * input_dims->n; + const int32_t rhs_rows = output_dims->c; + const int32_t rhs_cols = input_dims->c; + + arm_nn_mat_mult_nt_t_s8(input_data, + filter_data, + bias_data, + output_data, + quant_params->multiplier, + quant_params->shift, + lhs_rows, + rhs_rows, + rhs_cols, + conv_params->input_offset, + conv_params->output_offset, + conv_params->activation.min, + conv_params->activation.max); + +#endif + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +int32_t arm_convolve_1x1_s8_fast_get_buffer_size(const cmsis_nn_dims *input_dims) +{ + (void)input_dims; + return 0; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c new file mode 100644 index 0000000..d7d25f4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_basic.c + * Description: Q15 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * bufferA size: ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * This basic version is designed to work for any input tensor and weight + * dimension. + */ + +arm_status +arm_convolve_HWC_q15_basic(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + uint16_t im2col_out_pixel_index = 0; + q15_t *pBuffer = bufferA; + q15_t *pOut = Im_out; + q15_t *im_buffer = bufferA; + const q15_t *pA; + int i; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + pA = wt; + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + const q15_t *pB = im_buffer; + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + while (colCnt) + { + q31_t inA1 = arm_nn_read_q15x2_ia(&pA); + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inA2 = arm_nn_read_q15x2_ia(&pA); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB); + + sum = __SMLAD(inA1, inB1, sum); + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q15_t) __SSAT((sum >> out_shift), 16); + pOut++; + } + + /* counter reset */ + pBuffer = im_buffer; + im2col_out_pixel_index++; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c new file mode 100644 index 0000000..221d64f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_fast.c + * Description: Fast Q15 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + +arm_status +arm_convolve_HWC_q15_fast(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + q15_t *pBuffer = bufferA; + q15_t *im_buffer = bufferA; + q15_t *pOut = Im_out; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (i_out_x & 0x1) + { + int i; + /* initialize the matrix pointers for A */ + const q15_t *pA = wt; + + /* set up the second output pointers */ + q15_t *pOut2 = pOut + ch_im_out; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + const q15_t *pB = im_buffer; + const q15_t *pB2 = pB + ch_im_in * dim_kernel * dim_kernel; + + /* aling the second pointer for A */ + const q15_t *pA2 = pA + ch_im_in * dim_kernel * dim_kernel; + + /* init the sum with bias */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 1; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA1 = arm_nn_read_q15x2_ia(&pA); + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inA2 = arm_nn_read_q15x2_ia(&pA2); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB2); + + sum = __SMLAD(inA1, inB1, sum); + sum2 = __SMLAD(inA1, inB2, sum2); + sum3 = __SMLAD(inA2, inB1, sum3); + sum4 = __SMLAD(inA2, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x1; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q15_t) __SSAT(sum >> out_shift, 16); + *pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16); + + /* skip the row computed with A2 */ + pA += ch_im_in * dim_kernel * dim_kernel; + } /* for over ch_im_out */ + + pOut += ch_im_out; + /* counter reset */ + pBuffer = im_buffer; + } + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c new file mode 100644 index 0000000..8b1fdc7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_fast.c + * Description: Fast Q15 version of convolution + * + * $Date: 24. May 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q15 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + +arm_status +arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + q15_t *pBuffer = bufferA; + q15_t *im_buffer = bufferA; + q15_t *pOut = Im_out; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (i_out_x & 0x1) + { + int i; + /* initialize the matrix pointers for A */ + const q15_t *pA = wt; + + /* set up the second output pointers */ + q15_t *pOut2 = pOut + ch_im_out; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + const q15_t *pB = im_buffer; + const q15_t *pB2 = pB + ch_im_in * dim_kernel_y * dim_kernel_x; + + /* aling the second pointer for A */ + const q15_t *pA2 = pA + ch_im_in * dim_kernel_y * dim_kernel_x; + + /* init the sum with bias */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 1; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA1 = arm_nn_read_q15x2_ia(&pA); + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inA2 = arm_nn_read_q15x2_ia(&pA2); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB2); + + sum = __SMLAD(inA1, inB1, sum); + sum2 = __SMLAD(inA1, inB2, sum2); + sum3 = __SMLAD(inA2, inB1, sum3); + sum4 = __SMLAD(inA2, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x1; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q15_t) __SSAT(sum >> out_shift, 16); + *pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16); + + /* skip the row computed with A2 */ + pA += ch_im_in * dim_kernel_y * dim_kernel_x; + } /* for over ch_im_out */ + + pOut += ch_im_out; + /* counter reset */ + pBuffer = im_buffer; + } + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel_x * dim_kernel_y + (m * dim_kernel_x + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c new file mode 100644 index 0000000..912f834 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_RGB.c + * Description: Q7 version of convolution for RGB image + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Q7 convolution function for RGB image + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in equals 3 + * + * This kernel is written exclusively for convolution with ch_im_in + * equals 3. This applies on the first layer of CNNs which has input + * image with RGB format. + */ + +arm_status +arm_convolve_HWC_q7_RGB(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, const uint16_t dim_im_out, q15_t * bufferA, q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + // check if number of input channels is 3 + if (ch_im_in != 3) + { + return ARM_MATH_SIZE_MISMATCH; + } + // This part implements the im2col function + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Equivalent to arm_fill_q15(0, pBuffer, ch_im_in) with assumption: ch_im_in = 3 */ + *__SIMD32(pBuffer) = 0x0; + *(pBuffer + 2) = 0; + pBuffer += 3; + } else + { + /* + * Equivalent to: + * arm_q7_to_q15_no_shift( (q7_t*)Im_in+(i_ker_y*dim_im_in+i_ker_x)*3, pBuffer, 3); + */ + + const q7_t *pPixel = Im_in + (i_ker_y * dim_im_in + i_ker_x) * 3; + q31_t buf = arm_nn_read_q7x4(pPixel); + + union arm_nnword top; + union arm_nnword bottom; + + top.word = __SXTB16(buf); + bottom.word = __SXTB16(__ROR(buf, 8)); + +#ifndef ARM_MATH_BIG_ENDIAN + /* + * little-endian, | omit | 3rd | 2nd | 1st | + * MSB LSB + * top | 3rd | 1st |; bottom | omit | 2nd | + * + * version 1, need to swap 2nd and 3rd weight + * *__SIMD32(pBuffer) = top.word; + * *(pBuffer+2) = bottom.half_words[0]; + * + * version 2, no weight shuffling required + */ + *pBuffer++ = top.half_words[0]; + *__SIMD32(pBuffer) = __PKHBT(bottom.word, top.word, 0); +#else + /* + * big-endian, | 1st | 2nd | 3rd | omit | + * MSB LSB + * top | 2nd | omit |; bottom | 1st | 3rd | + * + * version 1, need to swap 2nd and 3rd weight + * *__SIMD32(pBuffer) = bottom.word; + * *(pBuffer+2) = top.half_words[1]; + * + * version 2, no weight shuffling required + */ + *pBuffer++ = bottom.half_words[0]; + *__SIMD32(pBuffer) = __PKHTB(top.word, bottom.word, 0); +#endif + pBuffer += 2; + } + } + } + + if (pBuffer == bufferA + 2 * 3 * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + 3 * dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = 3 * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia((const q15_t **)&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia((const q15_t **)&pB); + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = 3 * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + // check if number of input channels is 3 + if (ch_im_in != 3) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + /* if-for implementation */ + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return (ARM_MATH_SUCCESS); +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c new file mode 100644 index 0000000..2e6147b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_basic.c + * Description: Q7 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * This basic version is designed to work for any input tensor and weight + * dimension. + */ + +arm_status +arm_convolve_HWC_q7_basic(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* Copying the pixel data to column */ + arm_q7_to_q15_no_shift((q7_t *) + Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* Computation is filed for every 2 columns */ + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + ch_im_in * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + /* Load the accumulator with bias first */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + + /* Point to the beging of the im2col buffer */ + const q15_t *pB = bufferA; + + /* Each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia(&pB); + + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + // if-for implementation + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c new file mode 100644 index 0000000..d50318d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_basic.c + * Description: Q7 version of convolution + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + */ + +arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* Copying the pixel data to column */ + arm_q7_to_q15_no_shift((q7_t *) + Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* Computation is filed for every 2 columns */ + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_y * dim_kernel_x) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + ch_im_in * + dim_kernel_y * dim_kernel_x, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + /* Load the accumulator with bias first */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + + /* Point to the beging of the im2col buffer */ + const q15_t *pB = bufferA; + + /* Each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 2; + + while (colCnt) + { + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia(&pB); + + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + + (m * dim_kernel_x + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c new file mode 100644 index 0000000..0352d6f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_fast.c + * Description: Fast Q7 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 4 ( because of the SIMD32 read and swap ) + * + * ch_im_out is multipe of 2 ( bacause 2x2 mat_mult kernel ) + * + * The im2col converts the Q7 tensor input into Q15 column, which is stored in + * bufferA. There is reordering happenning during this im2col process with + * arm_q7_to_q15_reordered_no_shift. For every four elements, the second and + * third elements are swapped. + * + * The computation kernel arm_nn_mat_mult_kernel_q7_q15_reordered does the + * GEMM computation with the reordered columns. + * + * To speed-up the determination of the padding condition, we split the + * computation into 3x3 parts, i.e., {top, mid, bottom} X {left, mid, right}. + * This reduces the total number of boundary condition checks and improves + * the data copying performance. + */ + +arm_status +arm_convolve_HWC_q7_fast(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* + * Here we split the entire matrix into three regions depending on the padding situation + * Top: i_out_y from 0 to padding - 1 + * Middle: i_out_y from padding to dim_im_out-padding-1 + * Bottom: i_out_y from dim_im_out-padding to dim_im_out-1 + */ + + /* top part */ + for (i_out_y = 0; i_out_y < padding; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* middle part, here we also divide the x into left, mid and right */ + for (; i_out_y < dim_im_out - padding; i_out_y++) + { + + /* left part */ + for (i_out_x = 0; i_out_x < padding; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* mid part */ + for (; i_out_x < dim_im_out - padding; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + + + (i_ker_y * + dim_im_in + + i_out_x * + stride - padding) * ch_im_in, pBuffer, ch_im_in * dim_kernel); + pBuffer += ch_im_in * dim_kernel; + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* right part */ + for (; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + for (; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + const q15_t *pB = bufferA; + /* each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad_reordered(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + // if-for implementation + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c new file mode 100644 index 0000000..31b4fdc --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_fast_nonsquare.c + * Description: Fast Q7 version of convolution (non-sqaure shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Fast Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + +arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* ----------------------- + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* + * Here we split the entire matrix into three regions depending on the padding situation + * Top: i_out_y from 0 to padding - 1 + * Middle: i_out_y from padding to dim_im_out-padding-1 + * Bottom: i_out_y from dim_im_out-padding to dim_im_out-1 + */ + + /* top part */ + for (i_out_y = 0; i_out_y < padding_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* middle part, here we also divide the x into left, mid and right */ + for (; i_out_y < dim_im_out_y - padding_y; i_out_y++) + { + + /* left part */ + for (i_out_x = 0; i_out_x < padding_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* mid part */ + for (; i_out_x < dim_im_out_x - padding_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + + (i_ker_y * dim_im_in_x + i_out_x * stride_x - padding_x) * ch_im_in, + pBuffer, ch_im_in * dim_kernel_x); + pBuffer += ch_im_in * dim_kernel_x; + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* right part */ + for (; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + for (; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + const q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = read_and_pad_reordered(pA, &inA1, &inA2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA1, inB1, sum); + inB2 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = (ch_im_in * dim_kernel_y * dim_kernel_x) & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + /* if-for implementation */ + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_s8.c new file mode 100644 index 0000000..fd30473 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_s8.c @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_s8.c + * Description: s8 version of convolution using symmetric quantization. + * + * $Date: May 29, 2020 + * $Revision: V.2.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nn_types.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * Basic s8 convolution function. + * + * Refer header file for details. Optimal use case for the DSP/MVE implementation is when input and output channels + * are multiples of 4 or atleast greater than 4. + * + */ + +arm_status arm_convolve_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data) +{ + q15_t *buffer_a = (q15_t *)ctx->buf; + + const uint16_t input_batches = input_dims->n; + const uint16_t input_x = input_dims->w; + const uint16_t input_y = input_dims->h; + const uint16_t input_ch = input_dims->c; + const uint16_t kernel_x = filter_dims->w; + const uint16_t kernel_y = filter_dims->h; + const uint16_t output_x = output_dims->w; + const uint16_t output_y = output_dims->h; + const uint16_t output_ch = output_dims->c; + + const uint16_t pad_x = conv_params->padding.w; + const uint16_t pad_y = conv_params->padding.h; + const uint16_t stride_x = conv_params->stride.w; + const uint16_t stride_y = conv_params->stride.h; + + const int32_t input_offset = conv_params->input_offset; + const int32_t out_offset = conv_params->output_offset; + const int32_t out_activation_min = conv_params->activation.min; + const int32_t out_activation_max = conv_params->activation.max; + int32_t *output_mult = quant_params->multiplier; + int32_t *output_shift = quant_params->shift; + + int i_batch; + for (i_batch = 0; i_batch < input_batches; i_batch++) + { +#if defined(ARM_MATH_MVEI) + (void)bias_dims; + /* Generate upto four columns from the input tensor a GEMM computation */ + q7_t *im2col_buf = (q7_t *)buffer_a; + q7_t *out = output_data; + int32_t buffer_fill_cnt = 0; + int32_t padded = 0; + const int32_t num_elem = kernel_x * kernel_y * input_ch; + + /* This part implements the im2col function */ + for (int i_out_y = 0; i_out_y < output_y; i_out_y++) + { + for (int i_out_x = 0; i_out_x < output_x; i_out_x++) + { + for (int i_ker_y = i_out_y * stride_y - pad_y; i_ker_y < i_out_y * stride_y - pad_y + kernel_y; i_ker_y++) + { + for (int i_ker_x = i_out_x * stride_x - pad_x; i_ker_x < i_out_x * stride_x - pad_x + kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= input_y || i_ker_x < 0 || i_ker_x >= input_x) + { + memset(im2col_buf, (int8_t)-input_offset, sizeof(q7_t) * input_ch); + padded = 1; + } + else + { + arm_memcpy_q7(im2col_buf, input_data + (i_ker_y * input_x + i_ker_x) * input_ch, input_ch); + } + im2col_buf += input_ch; + } + } + + buffer_fill_cnt++; + + /* Computation is filed for every 4 columns */ + if (buffer_fill_cnt == 4 && (padded == 0)) + { + buffer_fill_cnt = 0; + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32_t sum_row; + int32_t acc[4]; + + (void)arm_nn_mat_mul_core_4x_s8(num_elem, + num_elem, + (q7_t *)buffer_a, + filter_data + num_elem * i_out_ch, + &sum_row, + acc); + int32x4_t s_offset = vdupq_n_s32(sum_row); + + int32x4_t res = vldrwq_s32(acc); + s_offset = vmulq_n_s32(s_offset, input_offset); + + res = vaddq_n_s32(res, bias_data[i_out_ch]); + res = vaddq_s32(res, s_offset); + res = arm_requantize_mve(res, output_mult[i_out_ch], output_shift[i_out_ch]); + res = vaddq_n_s32(res, out_offset); + + res = vmaxq_s32(res, vdupq_n_s32(out_activation_min)); + res = vminq_s32(res, vdupq_n_s32(out_activation_max)); + + const uint32x4_t scatter_offset = {0, output_ch, output_ch * 2, output_ch * 3}; + vstrbq_scatter_offset_s32(out, scatter_offset, res); + out++; + } + out += (3 * output_ch); + im2col_buf = (q7_t *)buffer_a; + } + else if (buffer_fill_cnt == 4 && (padded != 0)) + { + buffer_fill_cnt = 0; + out = arm_nn_mat_mult_s8(filter_data, + (q7_t *)buffer_a, + output_ch, + 4, + output_shift, + output_mult, + out_offset, + input_offset, + 0, + out_activation_min, + out_activation_max, + num_elem, + bias_data, + out); + + im2col_buf = (q7_t *)buffer_a; + padded = 0; + } + } + } + /* Handle left over columns */ + if (buffer_fill_cnt != 0) + { + out = arm_nn_mat_mult_s8(filter_data, + (q7_t *)buffer_a, + output_ch, + buffer_fill_cnt, + output_shift, + output_mult, + out_offset, + input_offset, + 0, + out_activation_min, + out_activation_max, + num_elem, + bias_data, + out); + } + +#elif defined(ARM_MATH_DSP) + (void)bias_dims; + int32_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* Generate two columns from the input tensor a GEMM computation */ + q15_t *two_column_buf = buffer_a; + q7_t *out = output_data; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < output_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < output_x; i_out_x++) + { + for (i_ker_y = i_out_y * stride_y - pad_y; i_ker_y < i_out_y * stride_y - pad_y + kernel_y; i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - pad_x; i_ker_x < i_out_x * stride_x - pad_x + kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= input_y || i_ker_x < 0 || i_ker_x >= input_x) + { + /* Filling 0 for out-of-bound paddings */ + memset(two_column_buf, 0, sizeof(q15_t) * input_ch); + } + else + { + /* Copying the pixel data to column */ + arm_q7_to_q15_with_offset(input_data + (i_ker_y * input_x + i_ker_x) * input_ch, two_column_buf, input_ch, input_offset); + } + two_column_buf += input_ch; + } + } + + /* Computation is filed for every 2 columns */ + if (two_column_buf == buffer_a + 2 * input_ch * kernel_y * kernel_x) + { + out = + arm_nn_mat_mult_kernel_s8_s16(filter_data, + buffer_a, + output_ch, + output_shift, + output_mult, + out_offset, + out_activation_min, + out_activation_max, + input_ch * kernel_y * kernel_x, + bias_data, + out); + + /* counter reset */ + two_column_buf = buffer_a; + } + } + } + + /* left-over because odd number of output pixels */ + if (two_column_buf != buffer_a) + { + const q7_t *ker_a = filter_data; + int i; + + for (i = 0; i < output_ch; i++) + { + /* Load the accumulator with bias first */ + q31_t sum = bias_data[i]; + + /* Point to the beginning of the im2col buffer where the input is available as a rearranged column */ + const q15_t *ip_as_col = buffer_a; + + /* 4 multiply and accumulates are done in one loop. */ + uint16_t col_count = (input_ch * kernel_y * kernel_x) >> 2; + + while (col_count) + { + q31_t ker_a1, ker_a2; + q31_t ip_b1, ip_b2; + + ker_a = read_and_pad(ker_a, &ker_a1, &ker_a2); + + ip_b1 = arm_nn_read_q15x2_ia(&ip_as_col); + sum = __SMLAD(ker_a1, ip_b1, sum); + ip_b2 = arm_nn_read_q15x2_ia(&ip_as_col); + sum = __SMLAD(ker_a2, ip_b2, sum); + + col_count--; + } + /* Handle left over mac */ + col_count = input_ch * kernel_y * kernel_x & 0x3; + while (col_count) + { + q7_t ker_a1 = *ker_a++; + q15_t ip_b1 = *ip_as_col++; + sum += ker_a1 * ip_b1; + col_count--; + } + + sum = arm_nn_requantize(sum, output_mult[i], output_shift[i]); + sum += out_offset; + sum = MAX(sum, out_activation_min); + sum = MIN(sum, out_activation_max); + *out++ = (q7_t)sum; + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + (void)buffer_a; + int32_t i_out_ch, i_out_y, i_out_x, i_input_ch, i_ker_y, i_ker_x; + int32_t conv_out; + + for (i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + for (i_out_y = 0; i_out_y < output_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < output_x; i_out_x++) + { + conv_out = bias_data[i_out_ch]; + + const int32_t base_idx_y = stride_y * i_out_y - pad_y; + const int32_t base_idx_x = stride_x * i_out_x - pad_x; + + const int32_t ker_y_start = MAX(0, -base_idx_y); + const int32_t ker_x_start = MAX(0, -base_idx_x); + + const int32_t ker_y_end = MIN(kernel_y, input_y - base_idx_y); + const int32_t ker_x_end = MIN(kernel_x, input_x - base_idx_x); + + for (i_ker_y = ker_y_start; i_ker_y < ker_y_end; i_ker_y++) + { + for (i_ker_x = ker_x_start; i_ker_x < ker_x_end; i_ker_x++) + { + const int32_t in_row = base_idx_y + i_ker_y; + const int32_t in_col = base_idx_x + i_ker_x; + for (i_input_ch = 0; i_input_ch < input_ch; i_input_ch++) + { + conv_out += + (input_data[(in_row * input_x + in_col) * input_ch + i_input_ch] + input_offset) * + filter_data[i_out_ch * input_ch * kernel_y * kernel_x + + (i_ker_y * kernel_x + i_ker_x) * input_ch + i_input_ch]; + } + } + } + conv_out = arm_nn_requantize(conv_out, output_mult[i_out_ch], output_shift[i_out_ch]); + conv_out += out_offset; + conv_out = MAX(conv_out, out_activation_min); + conv_out = MIN(conv_out, out_activation_max); + output_data[i_out_ch + (i_out_y * output_x + i_out_x) * output_ch] = (int8_t)conv_out; + } + } + } +#endif + /* Advance to the next batch */ + input_data += (input_x * input_y * input_ch); + output_data += (output_x * output_y * output_ch); + } + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +int32_t arm_convolve_s8_get_buffer_size(const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims) +{ +#if defined(ARM_MATH_DSP) + return (2 * input_dims->c * filter_dims->w * filter_dims->h) * (int32_t)sizeof(int16_t); +#else + (void)input_dims; + (void)filter_dims; + return 0; +#endif +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_wrapper_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_wrapper_s8.c new file mode 100644 index 0000000..5cef066 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_wrapper_s8.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_wrapper_s8.c + * Description: s8 convolution layer wrapper function with the main purpose to call the optimal kernel available in cmsis-nn to perform the convolution. + * + * $Date: May 18, 2020 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nn_types.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * Convolution layer + * + * Refer header file for details. + * + */ + +arm_status arm_convolve_wrapper_s8(const cmsis_nn_context* ctx, + const cmsis_nn_conv_params* conv_params, + const cmsis_nn_per_channel_quant_params* quant_params, + const cmsis_nn_dims* input_dims, + const q7_t *input_data, + const cmsis_nn_dims* filter_dims, + const q7_t *filter_data, + const cmsis_nn_dims* bias_dims, + const int32_t *bias_data, + const cmsis_nn_dims* output_dims, + q7_t *output_data) +{ + if ((conv_params->padding.w == 0) && + (conv_params->padding.h == 0) && + (input_dims->c % 4 == 0) && + (conv_params->stride.w == 1) && + (conv_params->stride.h == 1) && + (filter_dims->w == 1) && + (filter_dims->h == 1)) + { + return arm_convolve_1x1_s8_fast(ctx, + conv_params, + quant_params, + input_dims, + input_data, + filter_dims, + filter_data, + bias_dims, + bias_data, + output_dims, + output_data); + } + else if ((output_dims->h == 1) && + (input_dims->h == 1) && + (filter_dims->h == 1) && + (output_dims->w % 4 == 0) && + (input_dims->n == 1)) + { + return arm_convolve_1_x_n_s8(ctx, + conv_params, + quant_params, + input_dims, + input_data, + filter_dims, + filter_data, + bias_dims, + bias_data, + output_dims, + output_data); + } + else + { + return arm_convolve_s8(ctx, + conv_params, + quant_params, + input_dims, + input_data, + filter_dims, + filter_data, + bias_dims, + bias_data, + output_dims, + output_data); + } +} + +int32_t arm_convolve_wrapper_s8_get_buffer_size(const cmsis_nn_conv_params* conv_params, + const cmsis_nn_dims* input_dims, + const cmsis_nn_dims* filter_dims, + const cmsis_nn_dims* output_dims) +{ + if ((conv_params->padding.w == 0) && + (conv_params->padding.h == 0) && + (input_dims->c % 4 == 0) && + (conv_params->stride.w == 1) && + (conv_params->stride.h == 1) && + (filter_dims->w == 1) && + (filter_dims->h == 1)) + { + return arm_convolve_1x1_s8_fast_get_buffer_size(input_dims); + } + else if ((output_dims->h == 1) && + (input_dims->h == 1) && + (filter_dims->h == 1) && + (output_dims->w % 4 == 0) && + (input_dims->n == 1)) + { + return arm_convolve_1_x_n_s8_get_buffer_size(input_dims, filter_dims); + } + else + { + return arm_convolve_s8_get_buffer_size(input_dims, filter_dims); + } +} + +/** + * @} end of NNConv group + */ + diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_3x3_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_3x3_s8.c new file mode 100644 index 0000000..5705b4b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_3x3_s8.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_conv_3x3_s8.c + * Description: Optimized s8 depthwise convolution function for channel + * multiplier of 1 and 3x3 kernel size. + * + * $Date: May 14, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * Optimized s8 depthwise convolution function with constraint that + * in_channel == out_channel and kernel_x == kernel_y == 3 with pads at most 1 + * + * Refer prototype header file for details. + * + */ + +arm_status arm_depthwise_conv_3x3_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input, + const cmsis_nn_dims *filter_dims, + const q7_t *kernel, + const cmsis_nn_dims *bias_dims, + const int32_t *bias, + const cmsis_nn_dims *output_dims, + q7_t *output) +{ + (void)ctx; + (void)bias_dims; + + const int32_t input_x = input_dims->w; + const int32_t input_y = input_dims->h; + const int32_t input_ch = input_dims->c; + const int32_t output_ch = output_dims->c; + const int32_t pad_x = dw_conv_params->padding.w; + const int32_t pad_y = dw_conv_params->padding.h; + const int32_t stride_x = dw_conv_params->stride.w; + const int32_t stride_y = dw_conv_params->stride.h; + const int32_t *output_shift = quant_params->shift; + const int32_t *output_mult = quant_params->multiplier; + const int32_t output_x = output_dims->w; + const int32_t output_y = output_dims->h; + const int32_t output_offset = dw_conv_params->output_offset; + const int32_t input_offset = dw_conv_params->input_offset; + const int32_t output_activation_min = dw_conv_params->activation.min; + const int32_t output_activation_max = dw_conv_params->activation.max; + + /* Check input constraints input_ch == output_ch */ + if (input_ch != output_ch) + { + return ARM_MATH_SIZE_MISMATCH; + } + /* Check input constraints pad_x <= 1 */ + if (pad_x > 1 || filter_dims->w != 3 || filter_dims->h != 3) + { + return ARM_MATH_ARGUMENT_ERROR; + } + + for (int32_t in_h = -pad_y, out_h = 0, out_idx = 0; out_h < output_y; in_h += stride_y, ++out_h) + { + for (int32_t in_w = -pad_x, out_w = 0, ker_h_start = MAX(0, -in_h); out_w < output_x; in_w += stride_x, ++out_w) + { + int32_t in_ch = 0; + int32_t ker_w_start = MAX(0, -in_w); + + for (; in_ch <= (input_ch - 4); in_ch += 4) + { + int32_t out_buff0 = bias[in_ch + 0]; + int32_t out_buff1 = bias[in_ch + 1]; + int32_t out_buff2 = bias[in_ch + 2]; + int32_t out_buff3 = bias[in_ch + 3]; + + const int8_t *input_ptr = input + (in_h + ker_h_start) * (input_ch * input_x) + in_w * input_ch + in_ch; + const int8_t *kernel_ptr = kernel + ker_h_start * (input_ch * 3) + in_ch; + + for (int32_t ker_h = ker_h_start; ker_h < MIN(3, input_y - in_h); ++ker_h) + { + int32_t in_val = 0; + int32_t ker_val = 0; + + if (ker_w_start == 0) + { + in_val = arm_nn_read_q7x4(input_ptr); + ker_val = arm_nn_read_q7x4(kernel_ptr); + + out_buff0 += ((int8_t)in_val + input_offset) * (int8_t)ker_val; + out_buff1 += ((int8_t)(in_val >> 8) + input_offset) * (int8_t)(ker_val >> 8); + out_buff2 += ((int8_t)(in_val >> 16) + input_offset) * (int8_t)(ker_val >> 16); + out_buff3 += ((int8_t)(in_val >> 24) + input_offset) * (int8_t)(ker_val >> 24); + } + + in_val = arm_nn_read_q7x4(input_ptr + input_ch); + ker_val = arm_nn_read_q7x4(kernel_ptr + input_ch); + + out_buff0 += ((int8_t)in_val + input_offset) * (int8_t)ker_val; + out_buff1 += ((int8_t)(in_val >> 8) + input_offset) * (int8_t)(ker_val >> 8); + out_buff2 += ((int8_t)(in_val >> 16) + input_offset) * (int8_t)(ker_val >> 16); + out_buff3 += ((int8_t)(in_val >> 24) + input_offset) * (int8_t)(ker_val >> 24); + + if ((input_x - in_w) >= 3) + { + in_val = arm_nn_read_q7x4(input_ptr + (input_ch << 1)); + ker_val = arm_nn_read_q7x4(kernel_ptr + (input_ch << 1)); + + out_buff0 += ((int8_t)in_val + input_offset) * (int8_t)ker_val; + out_buff1 += ((int8_t)(in_val >> 8) + input_offset) * (int8_t)(ker_val >> 8); + out_buff2 += ((int8_t)(in_val >> 16) + input_offset) * (int8_t)(ker_val >> 16); + out_buff3 += ((int8_t)(in_val >> 24) + input_offset) * (int8_t)(ker_val >> 24); + } + + input_ptr += (input_ch * input_x); + kernel_ptr += (input_ch * 3); + } + + out_buff0 = arm_nn_requantize(out_buff0, output_mult[in_ch + 0], output_shift[in_ch + 0]); + out_buff1 = arm_nn_requantize(out_buff1, output_mult[in_ch + 1], output_shift[in_ch + 1]); + out_buff2 = arm_nn_requantize(out_buff2, output_mult[in_ch + 2], output_shift[in_ch + 2]); + out_buff3 = arm_nn_requantize(out_buff3, output_mult[in_ch + 3], output_shift[in_ch + 3]); + + out_buff0 += output_offset; + out_buff1 += output_offset; + out_buff2 += output_offset; + out_buff3 += output_offset; + + out_buff0 = MIN(MAX(out_buff0, output_activation_min), output_activation_max); + out_buff1 = MIN(MAX(out_buff1, output_activation_min), output_activation_max); + out_buff2 = MIN(MAX(out_buff2, output_activation_min), output_activation_max); + out_buff3 = MIN(MAX(out_buff3, output_activation_min), output_activation_max); + + output[out_idx++] = (int8_t)out_buff0; + output[out_idx++] = (int8_t)out_buff1; + output[out_idx++] = (int8_t)out_buff2; + output[out_idx++] = (int8_t)out_buff3; + } + + // Leftover + for (; in_ch < input_ch; ++in_ch) + { + int32_t out_buff = bias[in_ch]; + + const int8_t *input_ptr = input + (in_h + ker_h_start) * (input_ch * input_x) + in_w * input_ch + in_ch; + const int8_t *kernel_ptr = kernel + ker_h_start * (input_ch * 3) + in_ch; + + for (int32_t ker_h = ker_h_start; ker_h < MIN(3, input_y - in_h); ++ker_h) + { + if (ker_w_start == 0) + { + out_buff += (*(input_ptr) + input_offset) * *(kernel_ptr); + } + + out_buff += (*(input_ptr + input_ch) + input_offset) * *(kernel_ptr + input_ch); + + if ((input_x - in_w) >= 3) + { + out_buff += (*(input_ptr + (input_ch << 1)) + input_offset) * *(kernel_ptr + (input_ch << 1)); + } + + input_ptr += (input_ch * input_x); + kernel_ptr += (input_ch * 3); + } + + out_buff = arm_nn_requantize(out_buff, output_mult[in_ch], output_shift[in_ch]); + out_buff += output_offset; + out_buff = MIN(MAX(out_buff, output_activation_min), output_activation_max); + output[out_idx++] = (int8_t)out_buff; + } + } + } + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8.c new file mode 100644 index 0000000..4819a0c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_conv_s8.c + * Description: s8 version of depthwise convolution. + * + * $Date: May 14, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +static void depthwise_conv_s8_mult_4(const int8_t *input, + const int32_t input_x, + const int32_t input_y, + const int32_t input_ch, + const int8_t *kernel, + const int32_t output_ch, + const int32_t ch_mult, + const int32_t kernel_x, + const int32_t kernel_y, + const int32_t pad_x, + const int32_t pad_y, + const int32_t stride_x, + const int32_t stride_y, + const int32_t *bias, + int8_t *output, + const int32_t *output_shift, + const int32_t *output_mult, + const int32_t output_x, + const int32_t output_y, + const int32_t output_offset, + const int32_t input_offset, + const int32_t output_activation_min, + const int32_t output_activation_max) +{ + for (int32_t in_h = -pad_y, out_h = 0, out_idx = 0; out_h < output_y; in_h += stride_y, ++out_h) + { + for (int32_t in_w = -pad_x, out_w = 0, ker_h_start = MAX(0, -in_h); out_w < output_x; in_w += stride_x, ++out_w) + { + for (int32_t in_ch = 0, out_ch = 0, ker_w_start = MAX(0, -in_w); out_ch < output_ch; ++in_ch, out_ch += ch_mult) + { + for (int mult_tile = 0; mult_tile < ch_mult; mult_tile += 4) + { + int32_t out_buff[4]; + + out_buff[0] = bias[out_ch + 0 + mult_tile]; + out_buff[1] = bias[out_ch + 1 + mult_tile]; + out_buff[2] = bias[out_ch + 2 + mult_tile]; + out_buff[3] = bias[out_ch + 3 + mult_tile]; + + for (int32_t ker_h = ker_h_start; ker_h < MIN(kernel_y, input_y - in_h); ++ker_h) + { + int32_t ker_idx = ker_h * (output_ch * kernel_x) + ker_w_start * output_ch + out_ch; + int32_t in_idx = (in_h + ker_h) * (input_ch * input_x) + in_w * input_ch + in_ch; + + for (int32_t ker_w = ker_w_start; ker_w < MIN(kernel_x, input_x - in_w); ++ker_w, ker_idx += output_ch) + { + int32_t in_val = input[in_idx + ker_w * input_ch] + input_offset; + out_buff[0] += in_val * kernel[ker_idx + 0 + mult_tile]; + out_buff[1] += in_val * kernel[ker_idx + 1 + mult_tile]; + out_buff[2] += in_val * kernel[ker_idx + 2 + mult_tile]; + out_buff[3] += in_val * kernel[ker_idx + 3 + mult_tile]; + } + } +#if defined(ARM_MATH_MVEI) + (void)out_idx; + int32x4_t res = vldrwq_s32(out_buff); + res = arm_requantize_mve_32x4(res, vldrwq_s32(&output_mult[out_ch + mult_tile]), vldrwq_s32(&output_shift[out_ch + mult_tile])); + res = vaddq_n_s32(res, output_offset); + + res = vmaxq_s32(res, vdupq_n_s32(output_activation_min)); + res = vminq_s32(res, vdupq_n_s32(output_activation_max)); + vstrbq_s32(output, res); + output += 4; +#else + out_buff[0] = arm_nn_requantize(out_buff[0], output_mult[out_ch + 0 + mult_tile], output_shift[out_ch + 0 + mult_tile]); + out_buff[1] = arm_nn_requantize(out_buff[1], output_mult[out_ch + 1 + mult_tile], output_shift[out_ch + 1 + mult_tile]); + out_buff[2] = arm_nn_requantize(out_buff[2], output_mult[out_ch + 2 + mult_tile], output_shift[out_ch + 2 + mult_tile]); + out_buff[3] = arm_nn_requantize(out_buff[3], output_mult[out_ch + 3 + mult_tile], output_shift[out_ch + 3 + mult_tile]); + + out_buff[0] += output_offset; + out_buff[1] += output_offset; + out_buff[2] += output_offset; + out_buff[3] += output_offset; + + out_buff[0] = MIN(MAX(out_buff[0], output_activation_min), output_activation_max); + out_buff[1] = MIN(MAX(out_buff[1], output_activation_min), output_activation_max); + out_buff[2] = MIN(MAX(out_buff[2], output_activation_min), output_activation_max); + out_buff[3] = MIN(MAX(out_buff[3], output_activation_min), output_activation_max); + + output[out_idx++] = (int8_t)out_buff[0]; + output[out_idx++] = (int8_t)out_buff[1]; + output[out_idx++] = (int8_t)out_buff[2]; + output[out_idx++] = (int8_t)out_buff[3]; + +#endif + } + } + } + } +} + +static void depthwise_conv_s8_generic(const q7_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_ch, + const q7_t *kernel, + const uint16_t output_ch, + const uint16_t ch_mult, + const uint16_t kernel_x, + const uint16_t kernel_y, + const uint16_t pad_x, + const uint16_t pad_y, + const uint16_t stride_x, + const uint16_t stride_y, + const int32_t *bias, + q7_t *output, + const int32_t *output_shift, + const int32_t *output_mult, + const uint16_t output_x, + const uint16_t output_y, + const int32_t output_offset, + const int32_t input_offset, + const int32_t output_activation_min, + const int32_t output_activation_max) +{ + (void)output_ch; + int i_out = 0; + for (int i_out_y = 0; i_out_y < output_y; i_out_y++) + { + const int16_t base_idx_y = (i_out_y * stride_y) - pad_y; + for (int i_out_x = 0; i_out_x < output_x; i_out_x++) + { + const int16_t base_idx_x = (i_out_x * stride_x) - pad_x; + for (int i_input_ch = 0; i_input_ch < input_ch; i_input_ch++) + { + for (int i_ch_mult = 0; i_ch_mult < ch_mult; i_ch_mult++) + { + const int idx_out_ch = i_ch_mult + i_input_ch * ch_mult; + int32_t acc_0; + /* Condition for kernel start dimension: (base_idx_ + ker__start) >= 0 */ + const int ker_y_start = MAX(0, -base_idx_y); + const int ker_x_start = MAX(0, -base_idx_x); + /* Condition for kernel end dimension: (base_idx_ + ker__end) < input_ */ + const int ker_y_end = MIN(kernel_y, input_y - base_idx_y); + const int ker_x_end = MIN(kernel_x, input_x - base_idx_x); + acc_0 = bias[idx_out_ch]; + + for (int i_ker_y = ker_y_start; i_ker_y < ker_y_end; i_ker_y++) + { + const int32_t idx_y = base_idx_y + i_ker_y; + for (int i_ker_x = ker_x_start; i_ker_x < ker_x_end; i_ker_x++) + { + const int32_t idx_x = base_idx_x + i_ker_x; + int32_t idx_0 = (idx_y * input_x + idx_x) * input_ch + i_input_ch; + int32_t ker_idx_0 = (i_ker_y * kernel_x + i_ker_x) * (input_ch * ch_mult) + idx_out_ch; + + acc_0 += (input[idx_0] + input_offset) * kernel[ker_idx_0]; + } + } + + /* Requantize and clamp output to provided range */ + acc_0 = arm_nn_requantize(acc_0, output_mult[idx_out_ch], output_shift[idx_out_ch]); + acc_0 += output_offset; + acc_0 = MAX(acc_0, output_activation_min); + acc_0 = MIN(acc_0, output_activation_max); + + output[i_out++] = acc_0; + } + } + } + } +} + +/* + * Basic s8 depthwise convolution function. + * + * Refer header file for details. + * Optimization using DSP extension is not available for the generic case where channel multiplier is > 1. + * + */ +arm_status arm_depthwise_conv_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input, + const cmsis_nn_dims *filter_dims, + const q7_t *kernel, + const cmsis_nn_dims *bias_dims, + const int32_t *bias, + const cmsis_nn_dims *output_dims, + q7_t *output) +{ + (void)dw_conv_params->dilation; + (void)ctx; + + if (dw_conv_params->ch_mult % 4 == 0) + { + depthwise_conv_s8_mult_4(input, input_dims->w, input_dims->h, input_dims->c, kernel, output_dims->c, dw_conv_params->ch_mult, filter_dims->w, filter_dims->h, + dw_conv_params->padding.w, dw_conv_params->padding.h, dw_conv_params->stride.w, dw_conv_params->stride.h, bias, output, + quant_params->shift, quant_params->multiplier, output_dims->w, output_dims->h, dw_conv_params->output_offset, + dw_conv_params->input_offset, dw_conv_params->activation.min, dw_conv_params->activation.max); + } + else + { + depthwise_conv_s8_generic(input, input_dims->w, input_dims->h, input_dims->c, kernel, output_dims->c, dw_conv_params->ch_mult, filter_dims->w, filter_dims->h, + dw_conv_params->padding.w, dw_conv_params->padding.h, dw_conv_params->stride.w, dw_conv_params->stride.h, bias, output, + quant_params->shift, quant_params->multiplier, output_dims->w, output_dims->h, dw_conv_params->output_offset, + dw_conv_params->input_offset, dw_conv_params->activation.min, dw_conv_params->activation.max); + } + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8_opt.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8_opt.c new file mode 100644 index 0000000..3587b9c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_s8_opt.c @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_conv_s8_opt.c + * Description: Optimized s8 depthwise separable convolution function for + * channel multiplier of 1. + * + * $Date: May 29, 2020 + * $Revision: V.2.0.1 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * Optimized s8 depthwise convolution function with constraint that in_channel equals out_channel + * + * Refer prototype header file for details. + * + */ + +arm_status arm_depthwise_conv_s8_opt(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input, + const cmsis_nn_dims *filter_dims, + const q7_t *kernel, + const cmsis_nn_dims *bias_dims, + const int32_t *bias, + const cmsis_nn_dims *output_dims, + q7_t *output) +{ + const int32_t input_x = input_dims->w; + const int32_t input_y = input_dims->h; + const int32_t input_ch = input_dims->c; + const int32_t output_ch = output_dims->c; + const int32_t kernel_x = filter_dims->w; + const int32_t kernel_y = filter_dims->h; + const int32_t pad_x = dw_conv_params->padding.w; + const int32_t pad_y = dw_conv_params->padding.h; + const int32_t stride_x = dw_conv_params->stride.w; + const int32_t stride_y = dw_conv_params->stride.h; + const int32_t *output_shift = quant_params->shift; + const int32_t *output_mult = quant_params->multiplier; + const int32_t output_x = output_dims->w; + const int32_t output_y = output_dims->h; + const int32_t output_offset = dw_conv_params->output_offset; + const int32_t input_offset = dw_conv_params->input_offset; + const int32_t output_activation_min = dw_conv_params->activation.min; + const int32_t output_activation_max = dw_conv_params->activation.max; + q15_t *buffer_a = (q15_t *)ctx->buf; + + /* Check input constraints input_ch == output_ch */ + if (input_ch != output_ch) + { + return ARM_MATH_SIZE_MISMATCH; + } +#ifdef ARM_MATH_MVEI + (void)bias_dims; + /* Generate two columns from the input tensor */ + q7_t *lhs_buffer = (q7_t *)buffer_a; + q7_t *out = output; + int padded = 0; + int buffer_count = 0; + const int32_t kernel_size = kernel_x * kernel_y; + + /* This part implements the im2col function */ + for (int i_out_y = 0, base_idx_y = -pad_y; i_out_y < output_y; base_idx_y += stride_y, i_out_y++) + { + for (int i_out_x = 0, base_idx_x = -pad_x; i_out_x < output_x; base_idx_x += stride_x, i_out_x++) + { + for (int i_ker_y = base_idx_y; i_ker_y < base_idx_y + kernel_y; i_ker_y++) + { + for (int i_ker_x = base_idx_x; i_ker_x < base_idx_x + kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= input_y || i_ker_x < 0 || i_ker_x >= input_x) + { + arm_memset_q7(lhs_buffer, (int8_t)-input_offset, (uint32_t)input_ch); + padded = 1; + } + else + { + arm_memcpy_q7(lhs_buffer, input + (i_ker_y * input_x + i_ker_x) * input_ch, (uint32_t)input_ch); + } + lhs_buffer += input_ch; + } + } + buffer_count++; + + if (buffer_count == 4) + { + lhs_buffer = (q7_t *)buffer_a; + if (padded == 0) + { + out = arm_nn_depthwise_conv_nt_t_s8(lhs_buffer, + kernel, + input_offset, + input_ch, + output_shift, + output_mult, + output_offset, + output_activation_min, + output_activation_max, + kernel_size, + bias, + out); + } + else + { + out = arm_nn_depthwise_conv_nt_t_padded_s8(lhs_buffer, + kernel, + input_offset, + input_ch, + output_shift, + output_mult, + output_offset, + output_activation_min, + output_activation_max, + kernel_size, + bias, + out); + padded = 0; + } + buffer_count = 0; + } + } + } + + /* Handle left over buffers */ + lhs_buffer = (q7_t *)buffer_a; + + for (int i_buf = 0; i_buf < buffer_count; i_buf++) + { + int32_t loop_count = (input_ch + 3) / 4; + + int32_t num_ch_to_process = input_ch; + for (int i_loop_cnt = 0, offset = 0; i_loop_cnt < loop_count; + num_ch_to_process -= 4, offset += 4, i_loop_cnt++) + { + const int8_t *col_0 = lhs_buffer + (kernel_size * input_ch * i_buf) + offset; + const int8_t *row_0 = kernel + offset; + int32x4_t out_0 = vldrwq_s32(&bias[offset]); + + for (int i_ker = 0; i_ker < kernel_size; i_ker++) + { + const int32x4_t ker_0 = vldrbq_s32(row_0); + + int32x4_t ip_0 = vldrbq_s32(col_0); + ip_0 = vaddq_n_s32(ip_0, input_offset); + out_0 += vmulq_s32(ip_0, ker_0); + + col_0 += input_ch; + row_0 += input_ch; + } + + const int32x4_t mult = vldrwq_s32(&output_mult[offset]); + const int32x4_t shift = vldrwq_s32(&output_shift[offset]); + + out_0 = arm_requantize_mve_32x4(out_0, mult, shift); + out_0 = vaddq_n_s32(out_0, output_offset); + out_0 = vmaxq_s32(out_0, vdupq_n_s32(output_activation_min)); + out_0 = vminq_s32(out_0, vdupq_n_s32(output_activation_max)); + mve_pred16_t p = vctp32q((uint32_t)num_ch_to_process); + vstrbq_p_s32(out, out_0, p); + + out += 4; + } + + const int tail_ch = input_ch & 0x3; + if (tail_ch != 0) + { + out -= (4 - tail_ch); + } + } + +#elif defined(ARM_MATH_DSP) + (void)bias_dims; + /* Run the following code in cores using DSP extension */ + q15_t *const col_buffer_start = buffer_a; + q15_t *col_buffer = col_buffer_start; + const int32_t *const bias_start_pos = bias; + const q31_t *const out_mult_start_pos = output_mult; + const q31_t *const out_shift_start_pos = output_shift; + uint16_t row_count; + uint16_t row_shift; + + for (int i_out_y = 0; i_out_y < output_y; i_out_y++) + { + const int16_t base_idx_y = (i_out_y * stride_y) - pad_y; + for (int i_out_x = 0; i_out_x < output_x; i_out_x++) + { + const int16_t base_idx_x = (i_out_x * stride_x) - pad_x; + + /* Out of bounds is only considered for the y axis as it provides a contiguous zero'ing opportunity than along + the x axis */ + const int ker_y_start = MAX(0, -base_idx_y); + /* Condition for kernel end dimension: (base_idx_y + ker_y_end) < input_y */ + const int ker_y_end = MIN(kernel_y, input_y - base_idx_y); + + int32_t index = 0; + if (ker_y_start != 0) + { + memset(&col_buffer[index], 0, (kernel_x * input_ch) * ker_y_start * sizeof(q15_t)); + index += (kernel_x * input_ch) * ker_y_start; + } + + for (int i_ker_y = ker_y_start; i_ker_y < ker_y_end; i_ker_y++) + { + const int32_t idx_y = base_idx_y + i_ker_y; + + for (int i_ker_x = 0; i_ker_x < kernel_x; i_ker_x++) + { + const int32_t idx_x = base_idx_x + i_ker_x; + if (idx_x < 0 || idx_x >= input_x) + { + memset(&col_buffer[index], 0, input_ch * sizeof(q15_t)); + } + else + { + arm_q7_to_q15_with_offset((q7_t *)input + (idx_y * input_x + idx_x) * input_ch, &col_buffer[index], input_ch, input_offset); + } + index += input_ch; + } + } + + const int diff = kernel_y - ker_y_end; + if (diff != 0) + { + memset(&col_buffer[index], 0, (kernel_x * input_ch) * diff * sizeof(q15_t)); + } + + row_count = output_ch / 4; + row_shift = 0; + bias = bias_start_pos; + output_mult = out_mult_start_pos; + output_shift = out_shift_start_pos; + + while (row_count) + { + q31_t sum = *bias++; + q31_t sum_2 = *bias++; + q31_t sum_3 = *bias++; + q31_t sum_4 = *bias++; + + uint16_t col_count = (kernel_x * kernel_y) / 2; + q15_t *col_pos = col_buffer_start + row_shift; + const q7_t *row_pos = kernel + row_shift; + row_shift += 4; + + while (col_count) + { + /* General idea is to read 4 + 4 (input, kernel) pair and re-arrange them in the right order to + use in a SMLAD instruction . One run of this loop produces 4 partial outputs with 8 MACs. */ + /* Note: variable names can be improved here to align with rows and columns. */ + q31_t ip_a1, ip_a2, ip_b1, ip_b2, op_a, op_b, op_c; + /* Read 4 weights */ + ip_b1 = arm_nn_read_q7x4(row_pos); + ip_a1 = arm_nn_read_q7x4(row_pos + input_ch); + op_a = arm_nn_read_q15x2(col_pos); + op_b = arm_nn_read_q15x2(col_pos + input_ch); + + ip_a2 = __SXTB16(ip_b1); + ip_b1 = __SXTB16(__ROR(ip_b1, 8)); + + ip_b2 = __SXTB16(ip_a1); + ip_a1 = __SXTB16(__ROR(ip_a1, 8)); + + op_c = __PKHBT(op_b, op_a, 16); + op_a = __PKHTB(op_b, op_a, 16); + op_b = __PKHBT(ip_b2, ip_a2, 16); + sum = __SMLAD(op_c, op_b, sum); + + op_b = __PKHBT(ip_b1, ip_a1, 16); + sum_2 = __SMLAD(op_a, op_b, sum_2); + + op_a = arm_nn_read_q15x2(col_pos + 2); + op_b = arm_nn_read_q15x2(col_pos + input_ch + 2); + + op_c = __PKHBT(op_b, op_a, 16); + op_a = __PKHTB(op_b, op_a, 16); + op_b = __PKHTB(ip_a2, ip_b2, 16); + sum_3 = __SMLAD(op_c, op_b, sum_3); + + op_b = __PKHTB(ip_a1, ip_b1, 16); + sum_4 = __SMLAD(op_a, op_b, sum_4); + + row_pos += input_ch << 1; + col_pos += input_ch << 1; + col_count--; + } + + col_count = (kernel_x * kernel_y) & 0x1; + while (col_count) + { + sum += row_pos[0] * col_pos[0]; + sum_2 += row_pos[1] * col_pos[1]; + sum_3 += row_pos[2] * col_pos[2]; + sum_4 += row_pos[3] * col_pos[3]; + + row_pos += input_ch; + col_pos += input_ch; + + col_count--; + } + sum = arm_nn_requantize(sum, *output_mult++, *output_shift++); + sum += output_offset; + sum = MAX(sum, output_activation_min); + sum = MIN(sum, output_activation_max); + *output++ = (q7_t)sum; + + sum_2 = arm_nn_requantize(sum_2, *output_mult++, *output_shift++); + sum_2 += output_offset; + sum_2 = MAX(sum_2, output_activation_min); + sum_2 = MIN(sum_2, output_activation_max); + *output++ = (q7_t)sum_2; + sum_3 = arm_nn_requantize(sum_3, *output_mult++, *output_shift++); + sum_3 += output_offset; + sum_3 = MAX(sum_3, output_activation_min); + sum_3 = MIN(sum_3, output_activation_max); + *output++ = (q7_t)sum_3; + + sum_4 = arm_nn_requantize(sum_4, *output_mult++, *output_shift++); + sum_4 += output_offset; + sum_4 = MAX(sum_4, output_activation_min); + sum_4 = MIN(sum_4, output_activation_max); + *output++ = (q7_t)sum_4; + + row_count--; + } + + row_count = output_ch & 0x3; + while (row_count) + { + q15_t *col_pos = col_buffer_start + row_shift; + const q7_t *row_pos = kernel + row_shift; + q31_t sum = *bias++; + const uint16_t col_count = (kernel_x * kernel_y); + row_shift += 1; + + for (int i = 0; i < col_count; i++) + { + sum += row_pos[i * input_ch] * col_pos[i * input_ch]; + } + sum = arm_nn_requantize(sum, *output_mult++, *output_shift++); + sum += output_offset; + sum = MAX(sum, output_activation_min); + sum = MIN(sum, output_activation_max); + *output++ = (q7_t)sum; + + row_count--; + } + + // clear counter and pointers + col_buffer = col_buffer_start; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + return arm_depthwise_conv_s8(ctx, + dw_conv_params, + quant_params, + input_dims, + input, + filter_dims, + kernel, + bias_dims, + bias, + output_dims, + output); +#endif /* ARM_MATH_MVEI | ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +int32_t arm_depthwise_conv_s8_opt_get_buffer_size(const cmsis_nn_dims *input_dims, + const cmsis_nn_dims *filter_dims) +{ +#if defined(ARM_MATH_MVEI) + /* The + 4 accounts for out of bounds read of the lhs buffers in the *_nt_t_* functions. */ + return (2 * input_dims->c * filter_dims->w * filter_dims->h) * (int32_t)sizeof(int16_t) + 4; +#elif defined(ARM_MATH_DSP) + return (input_dims->c * filter_dims->w * filter_dims->h) * sizeof(int16_t); +#else + (void)input_dims; + (void)filter_dims; + return 0; +#endif +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_u8_basic_ver1.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_u8_basic_ver1.c new file mode 100644 index 0000000..d5fa36c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_u8_basic_ver1.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_conv_u8_basic_ver1.c + * Description: u8 depthwise convolution function + * + * $Date: May 29, 2020 + * $Revision: V.1.1.0 + * + * Target : Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +static void depthwise_conv_u8_mult_4(const uint8_t *input, + const int32_t input_x, + const int32_t input_y, + const int32_t input_ch, + const uint8_t *kernel, + const int32_t output_ch, + const int32_t ch_mult, + const int32_t kernel_x, + const int32_t kernel_y, + const int32_t pad_x, + const int32_t pad_y, + const int32_t stride_x, + const int32_t stride_y, + const int32_t *bias, + uint8_t *output, + const int32_t output_shift, + const int32_t output_mult, + const int32_t output_x, + const int32_t output_y, + const int32_t output_offset, + const int32_t input_offset, + const int32_t filter_offset, + const int32_t output_activation_min, + const int32_t output_activation_max) +{ + for (int32_t in_h = -pad_y, out_h = 0, out_idx = 0; out_h < output_y; in_h += stride_y, ++out_h) + { + for (int32_t in_w = -pad_x, out_w = 0, ker_h_start = MAX(0, -in_h); out_w < output_x; in_w += stride_x, ++out_w) + { + for (int32_t in_ch = 0, out_ch = 0, ker_w_start = MAX(0, -in_w); out_ch < output_ch; ++in_ch, out_ch += ch_mult) + { + for (int mult_tile = 0; mult_tile < ch_mult; mult_tile += 4) + { + int32_t out_buff[4]; + + out_buff[0] = 0; + out_buff[1] = 0; + out_buff[2] = 0; + out_buff[3] = 0; + + for (int32_t ker_h = ker_h_start; ker_h < MIN(kernel_y, input_y - in_h); ++ker_h) + { + int32_t ker_idx = ker_h * (output_ch * kernel_x) + ker_w_start * output_ch + out_ch; + int32_t in_idx = (in_h + ker_h) * (input_ch * input_x) + in_w * input_ch + in_ch; + + for (int32_t ker_w = ker_w_start; ker_w < MIN(kernel_x, input_x - in_w); ++ker_w, ker_idx += output_ch) + { + int32_t in_val = input[in_idx + ker_w * input_ch] + input_offset; + out_buff[0] += in_val * (kernel[ker_idx + 0 + mult_tile] + filter_offset); + out_buff[1] += in_val * (kernel[ker_idx + 1 + mult_tile] + filter_offset); + out_buff[2] += in_val * (kernel[ker_idx + 2 + mult_tile] + filter_offset); + out_buff[3] += in_val * (kernel[ker_idx + 3 + mult_tile] + filter_offset); + } + } + + if (bias != NULL) + { + out_buff[0] += bias[out_ch + 0 + mult_tile]; + out_buff[1] += bias[out_ch + 1 + mult_tile]; + out_buff[2] += bias[out_ch + 2 + mult_tile]; + out_buff[3] += bias[out_ch + 3 + mult_tile]; + } + out_buff[0] = arm_nn_requantize(out_buff[0], output_mult, output_shift); + out_buff[1] = arm_nn_requantize(out_buff[1], output_mult, output_shift); + out_buff[2] = arm_nn_requantize(out_buff[2], output_mult, output_shift); + out_buff[3] = arm_nn_requantize(out_buff[3], output_mult, output_shift); + + out_buff[0] += output_offset; + out_buff[1] += output_offset; + out_buff[2] += output_offset; + out_buff[3] += output_offset; + + out_buff[0] = MIN(MAX(out_buff[0], output_activation_min), output_activation_max); + out_buff[1] = MIN(MAX(out_buff[1], output_activation_min), output_activation_max); + out_buff[2] = MIN(MAX(out_buff[2], output_activation_min), output_activation_max); + out_buff[3] = MIN(MAX(out_buff[3], output_activation_min), output_activation_max); + + output[out_idx++] = (uint8_t)out_buff[0]; + output[out_idx++] = (uint8_t)out_buff[1]; + output[out_idx++] = (uint8_t)out_buff[2]; + output[out_idx++] = (uint8_t)out_buff[3]; + } + } + } + } +} + +static void depthwise_conv_u8_generic(const uint8_t *input, + const int32_t input_x, + const int32_t input_y, + const int32_t input_ch, + const uint8_t *kernel, + const int32_t output_ch, + const int32_t ch_mult, + const int32_t kernel_x, + const int32_t kernel_y, + const int32_t pad_x, + const int32_t pad_y, + const int32_t stride_x, + const int32_t stride_y, + const int32_t *bias, + uint8_t *output, + const int32_t output_shift, + const int32_t output_mult, + const int32_t output_x, + const int32_t output_y, + const int32_t output_offset, + const int32_t input_offset, + const int32_t filter_offset, + const int32_t output_activation_min, + const int32_t output_activation_max) +{ + (void)output_ch; + int i_out = 0; + for (int i_out_y = 0; i_out_y < output_y; i_out_y++) + { + const int16_t base_idx_y = (i_out_y * stride_y) - pad_y; + for (int i_out_x = 0; i_out_x < output_x; i_out_x++) + { + const int16_t base_idx_x = (i_out_x * stride_x) - pad_x; + for (int i_input_ch = 0; i_input_ch < input_ch; i_input_ch++) + { + for (int i_ch_mult = 0; i_ch_mult < ch_mult; i_ch_mult++) + { + const int idx_out_ch = i_ch_mult + i_input_ch * ch_mult; + int32_t acc_0; + /* Condition for kernel start dimension: (base_idx_ + ker__start) >= 0 */ + const int ker_y_start = MAX(0, -base_idx_y); + const int ker_x_start = MAX(0, -base_idx_x); + /* Condition for kernel end dimension: (base_idx_ + ker__end) < input_ */ + const int ker_y_end = MIN(kernel_y, input_y - base_idx_y); + const int ker_x_end = MIN(kernel_x, input_x - base_idx_x); + acc_0 = 0; + + for (int i_ker_y = ker_y_start; i_ker_y < ker_y_end; i_ker_y++) + { + const int32_t idx_y = base_idx_y + i_ker_y; + for (int i_ker_x = ker_x_start; i_ker_x < ker_x_end; i_ker_x++) + { + const int32_t idx_x = base_idx_x + i_ker_x; + int32_t idx_0 = (idx_y * input_x + idx_x) * input_ch + i_input_ch; + int32_t ker_idx_0 = (i_ker_y * kernel_x + i_ker_x) * (input_ch * ch_mult) + idx_out_ch; + + acc_0 += (input[idx_0] + input_offset) * (kernel[ker_idx_0] + filter_offset); + } + } + if (bias != NULL) + { + acc_0 += bias[idx_out_ch]; + } + + /* Requantize and clamp output to provided range */ + acc_0 = arm_nn_requantize(acc_0, output_mult, output_shift); + acc_0 += output_offset; + acc_0 = MAX(acc_0, output_activation_min); + acc_0 = MIN(acc_0, output_activation_max); + + output[i_out++] = acc_0; + } + } + } + } +} + +/** + * @brief uint8 depthwise convolution function with asymmetric quantization + * + * @param[in] input Pointer to input tensor + * @param[in] input_x Width of input tensor + * @param[in] input_y Height of input tensor + * @param[in] input_ch Channels in input tensor + * @param[in] kernel Pointer to kernel weights + * @param[in] kernel_x Width of kernel + * @param[in] kernel_y Height of kernel + * @param[in] ch_mult Number of channel multiplier + * @param[in] pad_x Padding sizes x + * @param[in] pad_y Padding sizes y + * @param[in] stride_x Convolution stride along the width + * @param[in] stride_y Convolution stride along the height + * @param[in] dilation_x Dilation along width. Not used and intended for future enhancement. + * @param[in] dilation_y Dilation along height. Not used and intended for future enhancement. + * @param[in] bias Pointer to optional bias values. If no bias is + * availble, NULL is expected + * @param[in] input_offset Input tensor zero offset + * @param[in] filter_offset Kernel tensor zero offset + * @param[in] output_offset Output tensor zero offset + * @param[in,out] output Pointer to output tensor + * @param[in] output_x Width of output tensor + * @param[in] output_y Height of output tensor + * @param[in] output_activation_min Minimum value to clamp the output to. Range : {0, 255} + * @param[in] output_activation_max Minimum value to clamp the output to. Range : {0, 255} + * @param[in] output_shift Amount of right-shift for output + * @param[in] output_mult Output multiplier for requantization + * @return The function returns one of the following + * ARM_MATH_SIZE_MISMATCH - Not supported dimension of tensors + * ARM_MATH_SUCCESS - Successful operation + * ARM_MATH_ARGUMENT_ERROR - Implementation not available + * + * + */ + +arm_status arm_depthwise_conv_u8_basic_ver1(const uint8_t *input, + const uint16_t input_x, + const uint16_t input_y, + const uint16_t input_ch, + const uint8_t *kernel, + const uint16_t kernel_x, + const uint16_t kernel_y, + const int16_t ch_mult, + const int16_t pad_x, + const int16_t pad_y, + const int16_t stride_x, + const int16_t stride_y, + const int16_t dilation_x, + const int16_t dilation_y, + const int32_t *bias, + const int32_t input_offset, + const int32_t filter_offset, + const int32_t output_offset, + uint8_t *output, + const uint16_t output_x, + const uint16_t output_y, + const int32_t output_activation_min, + const int32_t output_activation_max, + const int32_t output_shift, + const int32_t output_mult) +{ + (void)dilation_x; + (void)dilation_y; + + if (ch_mult % 4 == 0) + { + depthwise_conv_u8_mult_4(input, input_x, input_y, input_ch, kernel, ch_mult * input_ch, ch_mult, + kernel_x, kernel_y, pad_x, pad_y, stride_x, stride_y, bias, output, + output_shift, output_mult, output_x, output_y, output_offset, input_offset, + filter_offset, output_activation_min, output_activation_max); + } + else + { + depthwise_conv_u8_generic(input, input_x, input_y, input_ch, kernel, ch_mult * input_ch, ch_mult, + kernel_x, kernel_y, pad_x, pad_y, stride_x, stride_y, bias, + output, output_shift, output_mult, output_x, output_y, output_offset, + input_offset, filter_offset, output_activation_min, output_activation_max); + } + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_wrapper_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_wrapper_s8.c new file mode 100644 index 0000000..42d425f --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_conv_wrapper_s8.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_conv_wrapper_s8.c + * Description: Wrapper API to select appropriate depthwise conv API based + * on dimensions. + * + * $Date: May 29, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/* + * s8 Depthwise conv wrapper function + * + * Refer header file for details. + * + */ +arm_status arm_depthwise_conv_wrapper_s8(const cmsis_nn_context *ctx, + const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_per_channel_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input, + const cmsis_nn_dims *filter_dims, + const q7_t *filter, + const cmsis_nn_dims *bias_dims, + const int32_t *bias, + const cmsis_nn_dims *output_dims, + q7_t *output) +{ + arm_status status = ARM_MATH_SUCCESS; + if (1 == dw_conv_params->ch_mult) + { +#if !defined(ARM_MATH_MVEI) + if ((filter_dims->w == 3) && (filter_dims->h == 3) && (dw_conv_params->padding.h <= 1)) + { + status = arm_depthwise_conv_3x3_s8(ctx, + dw_conv_params, + quant_params, + input_dims, + input, + filter_dims, + filter, + bias_dims, + bias, + output_dims, + output); + } + else +#endif + { + status = arm_depthwise_conv_s8_opt(ctx, + dw_conv_params, + quant_params, + input_dims, + input, + filter_dims, + filter, + bias_dims, + bias, + output_dims, + output); + } + } + else + { + status = arm_depthwise_conv_s8(ctx, + dw_conv_params, + quant_params, + input_dims, + input, + filter_dims, + filter, + bias_dims, + bias, + output_dims, + output); + } + + /* Return to application */ + return status; +} + +int32_t arm_depthwise_conv_wrapper_s8_get_buffer_size(const cmsis_nn_dw_conv_params *dw_conv_params, + const cmsis_nn_dims *input_dims, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims) +{ + (void)dw_conv_params; + int32_t size = 0; + + if (input_dims->c == output_dims->c) + { + size = arm_depthwise_conv_s8_opt_get_buffer_size(input_dims, filter_dims); + } + + return size; +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c new file mode 100644 index 0000000..2767ff4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_separable_conv_HWC_q7.c + * Description: Q7 depthwise separable convolution function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Q7 depthwise separable convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in equals ch_im_out + * + * Implementation: + * There are 3 nested loop here: + * Inner loop: calculate each output value with MAC instruction over an accumulator + * Mid loop: loop over different output channel + * Outer loop: loop over different output (x, y) + */ + +arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + (void)bufferB; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x; + int16_t i_ker_y, i_ker_x; + q7_t *colBuffer = (q7_t *) bufferA; + q7_t *pBuffer = colBuffer; + const q7_t *pBias = bias; + q7_t *pOut = Im_out; + uint16_t rowCnt; + uint16_t row_shift; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* we first do im2col here */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q7(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, ch_im_in); + } else + { + /* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* we will do the computation here for each channel */ + rowCnt = ch_im_out >> 2; + row_shift = 0; + pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = (dim_kernel * dim_kernel) >> 1; + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + row_shift += 4; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = arm_nn_read_q7x4(pB); + pB += ch_im_in; + opB = arm_nn_read_q7x4(pB); + pB += ch_im_in; + inB2 = __PKHTB(opB, inB1, 16); + inB1 = __PKHBT(inB1, opB, 16); + inA1 = arm_nn_read_q7x4(pA); + pA += ch_im_in; + opB = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inA2 = __PKHTB(opB, inA1, 16); + inA1 = __PKHBT(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum3 = __SMLAD(opA, opB, sum3); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum4 = __SMLAD(opA, opB, sum4); + colCnt--; + } +#else + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = arm_nn_read_q7x4(pB); + pB += ch_im_in; + opB = arm_nn_read_q7x4(pB); + pB += ch_im_in; + inB2 = __PKHBT(opB, inB1, 16); + inB1 = __PKHTB(inB1, opB, 16); + inA1 = arm_nn_read_q7x4(pA); + pA += ch_im_in; + opB = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inA2 = __PKHBT(opB, inA1, 16); + inA1 = __PKHTB(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum4 = __SMLAD(opA, opB, sum4); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum3 = __SMLAD(opA, opB, sum3); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + +#ifndef ARM_MATH_BIG_ENDIAN + /* + * r0 r1 r2 r3 r4 r5 + * inA1, inA2, inB1, inB2, opA, opB + */ + + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhtb r3, r5, r2, ASR #16\n" + "pkhbt r2, r2, r5, LSL #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhtb r1, r5, r0, ASR #16\n" + "pkhbt r0, r0, r5, LSL #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum], r4, r5, %[sum]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] + "+r"(sum),[sum2] "+r"(sum2), + [sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB), + [pA] "+r"(pA):[colCnt] + "r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#else + /* + * r0 r1 r2 r3 r4 r5 + * inA1, inA2, inB1, inB2, opA, opB + */ + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhbt r3, r5, r2, LSL #16\n" + "pkhtb r2, r2, r5, ASR #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhbt r1, r5, r0, LSL #16\n" + "pkhtb r0, r0, r5, ASR #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum], r4, r5, %[sum]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] + "+r"(sum),[sum2] "+r"(sum2), + [sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB), + [pA] "+r"(pA):[colCnt] + "r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = (dim_kernel * dim_kernel) & 0x1; + while (colCnt) + { + union arm_nnword inA, inB; + inA.word = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inB.word = arm_nn_read_q7x4(pB); + pB += ch_im_in; + sum += inA.bytes[0] * inB.bytes[0]; + sum2 += inA.bytes[1] * inB.bytes[1]; + sum3 += inA.bytes[2] * inB.bytes[2]; + sum4 += inA.bytes[3] * inB.bytes[3]; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = ch_im_out & 0x3; + while (rowCnt) + { + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = (dim_kernel * dim_kernel); + + row_shift += 1; + + while (colCnt) + { + q7_t A1 = *pA; + q7_t B1 = *pB; + pA += ch_im_in; + pB += ch_im_in; + sum += A1 * B1; + + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + rowCnt--; + } + + /* clear counter and pointers */ + pBuffer = colBuffer; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i_out_y, i_out_x, i_ch_out, i_ker_x, i_ker_y; + int conv_out; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output + conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + for (i_ker_y = 0; i_ker_y < dim_kernel; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel; i_ker_x++) + { + int in_row = stride * i_out_y + i_ker_y - padding; + int in_col = stride * i_out_x + i_ker_x - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + conv_out += + Im_in[(in_row * + dim_im_in + + in_col) * + ch_im_in + + i_ch_out] * wt[(i_ker_y * dim_kernel + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out + + i_out_x) * ch_im_out + i_ch_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; + +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c new file mode 100644 index 0000000..adeb8c4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_separable_conv_HWC_q7_nonsquare.c + * Description: Q7 depthwise separable convolution function (non-square shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Q7 depthwise separable convolution function (non-square shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding sizes x + * @param[in] padding_y padding sizes y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is equal to ch_im_out + * + */ + +arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + + (void)bufferB; + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + +/* + * Implementation: + * There are 3 nested loop here: + * Inner loop: calculate each output value with MAC instruction over an accumulator + * Mid loop: loop over different output channel + * Outer loop: loop over different output (x, y) + * + */ + + int16_t i_out_y, i_out_x; + int16_t i_ker_y, i_ker_x; + q7_t *colBuffer = (q7_t *) bufferA; + q7_t *pBuffer = colBuffer; + const q7_t *pBias = bias; + q7_t *pOut = Im_out; + uint16_t rowCnt; + uint16_t row_shift; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* we first do im2col here */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q7(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, ch_im_in); + } else + { + /* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* we will do the computation here for each channel */ + rowCnt = ch_im_out >> 2; + row_shift = 0; + pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = (dim_kernel_x * dim_kernel_y) >> 1; + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + row_shift += 4; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = arm_nn_read_q7x4(pB); + pB += ch_im_in; + opB = arm_nn_read_q7x4(pB); + pB += ch_im_in; + inB2 = __PKHTB(opB, inB1, 16); + inB1 = __PKHBT(inB1, opB, 16); + inA1 = arm_nn_read_q7x4(pA); + pA += ch_im_in; + opB = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inA2 = __PKHTB(opB, inA1, 16); + inA1 = __PKHBT(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum3 = __SMLAD(opA, opB, sum3); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum4 = __SMLAD(opA, opB, sum4); + colCnt--; + } +#else + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = arm_nn_read_q7x4(pB); + pB += ch_im_in; + opB = arm_nn_read_q7x4(pB); + pB += ch_im_in; + inB2 = __PKHBT(opB, inB1, 16); + inB1 = __PKHTB(inB1, opB, 16); + inA1 = arm_nn_read_q7x4(pA); + pA += ch_im_in; + opB = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inA2 = __PKHBT(opB, inA1, 16); + inA1 = __PKHTB(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum4 = __SMLAD(opA, opB, sum4); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum3 = __SMLAD(opA, opB, sum3); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + +#ifndef ARM_MATH_BIG_ENDIAN + // r0 r1 r2 r3 r4 r5 + // inA1, inA2, inB1, inB2, opA, opB + asm volatile ("COL_LOOP:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhtb r3, r5, r2, ASR #16\n" + "pkhbt r2, r2, r5, LSL #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhtb r1, r5, r0, ASR #16\n" + "pkhbt r0, r0, r5, LSL #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum], r4, r5, %[sum]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt), + [ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#else + // r0 r1 r2 r3 r4 r5 + // inA1, inA2, inB1, inB2, opA, opB + asm volatile ("COL_LOOP:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhbt r3, r5, r2, LSL #16\n" + "pkhtb r2, r2, r5, ASR #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhbt r1, r5, r0, LSL #16\n" + "pkhtb r0, r0, r5, ASR #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum], r4, r5, %[sum]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt), + [ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#endif /*ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = (dim_kernel_x * dim_kernel_y) & 0x1; + while (colCnt) + { + union arm_nnword inA, inB; + inA.word = arm_nn_read_q7x4(pA); + pA += ch_im_in; + inB.word = arm_nn_read_q7x4(pB); + pB += ch_im_in; + sum += inA.bytes[0] * inB.bytes[0]; + sum2 += inA.bytes[1] * inB.bytes[1]; + sum3 += inA.bytes[2] * inB.bytes[2]; + sum4 += inA.bytes[3] * inB.bytes[3]; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = ch_im_out & 0x3; + while (rowCnt) + { + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = (dim_kernel_x * dim_kernel_y); + + row_shift += 1; + + while (colCnt) + { + q7_t A1 = *pA; + q7_t B1 = *pB; + pA += ch_im_in; + pB += ch_im_in; + sum += A1 * B1; + + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + rowCnt--; + } + + // clear counter and pointers + pBuffer = colBuffer; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i_out_y, i_out_x, i_ch_out; + int i_ker_y, i_ker_x; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output + int conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + for (i_ker_y = 0; i_ker_y < dim_kernel_y; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel_x; i_ker_x++) + { + int in_row = stride_y * i_out_y + i_ker_y - padding_y; + int in_col = stride_x * i_out_x + i_ker_x - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + i_ch_out] * + wt[(i_ker_y * dim_kernel_x + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out_x + i_out_x) * ch_im_out + i_ch_out] = + (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + + /* Return to application */ + return ARM_MATH_SUCCESS; + +} + +/** + * @} end of NNConv group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_depthwise_conv_s8_core.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_depthwise_conv_s8_core.c new file mode 100644 index 0000000..f910634 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_depthwise_conv_s8_core.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_depthwise_conv_s8_core.c + * Description: Depthwise convolution on im2col buffers. + * + * $Date: May 29, 2020 + * $Revision: V.1.0.3 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/* + * Depthwise conv on an im2col buffer where the input channel equals + * output channel. + * + * Refer header file for details. + * + */ + +q7_t *arm_nn_depthwise_conv_s8_core(const q7_t *row, + const q15_t *col, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t kernel_size, + const int32_t *const output_bias, + q7_t *out) +{ +#if defined(ARM_MATH_MVEI) + int32_t ch_per_loop = num_ch / 4; + + const int32_t *bias = output_bias; + int8_t *out_tmp = out; + + int32_t idx = 0; + + while (ch_per_loop > 0) + { + int32x4_t ip_0; + int32x4_t ip_1; + int32_t ker_loop = kernel_size / 3; + int32x4_t out_0 = vldrwq_s32(bias); + int32x4_t out_1 = out_0; + bias += 4; + + const int32_t offset = idx * 4; + const int8_t *row_0 = row + offset; + const int16_t *col_0 = col + offset; + const int16_t *col_1 = col + kernel_size * num_ch + offset; + + int32x4_t ker_0 = vldrbq_s32(row_0); + + while (ker_loop > 0) + { + const int8_t *row_1 = row_0 + num_ch; + const int8_t *row_2 = row_0 + 2 * num_ch; + const int32x4_t ker_1 = vldrbq_s32(row_1); + const int32x4_t ker_2 = vldrbq_s32(row_2); + + ip_0 = vldrhq_s32(col_0); + ip_1 = vldrhq_s32(col_1); + col_0 += num_ch; + col_1 += num_ch; + + out_0 += vmulq_s32(ip_0, ker_0); + out_1 += vmulq_s32(ip_1, ker_0); + + ip_0 = vldrhq_s32(col_0); + ip_1 = vldrhq_s32(col_1); + col_0 += num_ch; + col_1 += num_ch; + + out_0 += vmulq_s32(ip_0, ker_1); + out_1 += vmulq_s32(ip_1, ker_1); + + ip_0 = vldrhq_s32(col_0); + ip_1 = vldrhq_s32(col_1); + col_0 += num_ch; + col_1 += num_ch; + + out_0 += vmulq_s32(ip_0, ker_2); + out_1 += vmulq_s32(ip_1, ker_2); + row_0 += 3 * num_ch; + + ker_0 = vldrbq_s32(row_0); + ker_loop--; + } + + idx++; + /* Handle tail kernel elements */ + ker_loop = kernel_size - ((kernel_size / 3) * 3); + while (ker_loop > 0) + { + ip_0 = vldrhq_s32(col_0); + ip_1 = vldrhq_s32(col_1); + + out_0 += vmulq_s32(ip_0, ker_0); + out_1 += vmulq_s32(ip_1, ker_0); + + col_0 += num_ch; + col_1 += num_ch; + + ip_0 = vldrhq_s32(col_0); + ip_1 = vldrhq_s32(col_1); + + row_0 += num_ch; + ker_0 = vldrbq_s32(row_0); + ker_loop--; + } + const int32x4_t mult = vldrwq_s32(out_mult); + const int32x4_t shift = vldrwq_s32(out_shift); + out_mult += 4; + out_shift += 4; + + out_0 = arm_requantize_mve_32x4(out_0, mult, shift); + out_1 = arm_requantize_mve_32x4(out_1, mult, shift); + + out_0 = vaddq_n_s32(out_0, out_offset); + out_0 = vmaxq_s32(out_0, vdupq_n_s32(activation_min)); + out_0 = vminq_s32(out_0, vdupq_n_s32(activation_max)); + vstrbq_s32(out_tmp, out_0); + + out_1 = vaddq_n_s32(out_1, out_offset); + out_1 = vmaxq_s32(out_1, vdupq_n_s32(activation_min)); + out_1 = vminq_s32(out_1, vdupq_n_s32(activation_max)); + vstrbq_s32(out_tmp + num_ch, out_1); + + out_tmp += 4; + ch_per_loop--; + } + + int32_t tail_ch = num_ch & 3; + if (tail_ch != 0) + { + int32_t ch_idx = (num_ch & ~3); + int32x4_t col_0_sum; + int32x4_t col_1_sum; + + const int32_t single_buffer_size = kernel_size * num_ch; + for (int i = 0; i < tail_ch; i++) + { + const int16_t *col_pos_0 = col + ch_idx; + const int16_t *col_pos_1 = col_pos_0 + single_buffer_size; + + const int8_t *row_pos = row + ch_idx; + int32_t sum_0 = bias[i]; + int32_t sum_1 = bias[i]; + + for (int j = 0; j < kernel_size; j++) + { + const int8_t row_val = row_pos[j * num_ch]; + sum_0 += row_val * col_pos_0[j * num_ch]; + sum_1 += row_val * col_pos_1[j * num_ch]; + } + col_0_sum[i] = sum_0; + col_1_sum[i] = sum_1; + + ch_idx++; + } + const mve_pred16_t p = vctp32q((uint32_t)tail_ch); + const int32x4_t mult = vldrwq_z_s32(out_mult, p); + const int32x4_t shift = vldrwq_z_s32(out_shift, p); + + col_0_sum = arm_requantize_mve_32x4(col_0_sum, mult, shift); + col_1_sum = arm_requantize_mve_32x4(col_1_sum, mult, shift); + + col_0_sum = vaddq_n_s32(col_0_sum, out_offset); + col_0_sum = vmaxq_s32(col_0_sum, vdupq_n_s32(activation_min)); + col_0_sum = vminq_s32(col_0_sum, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out_tmp, col_0_sum, p); + + col_1_sum = vaddq_n_s32(col_1_sum, out_offset); + col_1_sum = vmaxq_s32(col_1_sum, vdupq_n_s32(activation_min)); + col_1_sum = vminq_s32(col_1_sum, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out_tmp + num_ch, col_1_sum, p); + + out_tmp += tail_ch; + } + + return out_tmp + num_ch; +#else + (void)row; + (void)col; + (void)num_ch; + (void)out_shift; + (void)out_mult; + (void)out_offset; + (void)activation_min; + (void)activation_max; + (void)kernel_size; + (void)output_bias; + (void)out; + return NULL; +#endif +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c new file mode 100644 index 0000000..49b3ba4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_q7_q15.c + * Description: Matrix-multiplication function for convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + + /** + * @brief Matrix-multiplication function for convolution. + * + * @details Refer to header file for details. + * + */ + +q7_t *arm_nn_mat_mult_kernel_q7_q15(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut) +{ +#if defined (ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *pOut2 = pOut + ch_im_out; + const q7_t *pBias = bias; + + uint16_t rowCnt = ch_im_out >> 1; + /* this loop over rows in A */ + while (rowCnt) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* align the second pointer for A */ + const q7_t *pA2 = pA + numCol_A; + + /* init the sum with bias */ + q31_t sum = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA11, inA12, inA21, inA22; + + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB2); + + pA = read_and_pad(pA, &inA11, &inA12); + pA2 = read_and_pad(pA2, &inA21, &inA22); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + sum3 = __SMLAD(inA21, inB1, sum3); + sum4 = __SMLAD(inA21, inB2, sum4); + + inB1 = arm_nn_read_q15x2_ia(&pB); + inB2 = arm_nn_read_q15x2_ia(&pB2); + + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + sum3 = __SMLAD(inA22, inB1, sum3); + sum4 = __SMLAD(inA22, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q7_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + /* skip the row computed with A2 */ + pA += numCol_A; + rowCnt--; + } /* for over ch_im_out */ + + /* compute left-over row if any */ + if (ch_im_out & 0x1) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* load the bias */ + q31_t sum = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + while (colCnt) + { + q31_t inA11, inA12; + + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB2); + + pA = read_and_pad(pA, &inA11, &inA12); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + + inB1 = arm_nn_read_q15x2_ia(&pB); + inB2 = arm_nn_read_q15x2_ia(&pB2); + + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + + colCnt--; + } + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + } + + pOut += ch_im_out; + + /* return the new output pointer with offset */ + return pOut; +#else + /* To be completed */ + return NULL; +#endif /* ARM_MATH_DSP */ + +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c new file mode 100644 index 0000000..b5bbc39 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_q7_q15_reordered.c + * Description: Matrix-multiplication function for convolution with reordered columns + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/DSP/Include/arm_math.h" + + /** + * @brief Matrix-multiplication function for convolution with re-ordered input. + * + * @details Refer to header file for details. + * + */ + +q7_t *arm_nn_mat_mult_kernel_q7_q15_reordered(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut) +{ + +#if defined (ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *pOut2 = pOut + ch_im_out; + int i; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* align the second pointer for A */ + const q7_t *pA2 = pA + numCol_A; + + /* init the sum with bias */ + q31_t sum = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(bias[i + 1]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(bias[i + 1]) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA11, inA12, inA21, inA22; + + q31_t inB1 = arm_nn_read_q15x2_ia(&pB); + q31_t inB2 = arm_nn_read_q15x2_ia(&pB2); + + pA = read_and_pad_reordered(pA, &inA11, &inA12); + pA2 = read_and_pad_reordered(pA2, &inA21, &inA22); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + sum3 = __SMLAD(inA21, inB1, sum3); + sum4 = __SMLAD(inA21, inB2, sum4); + + inB1 = arm_nn_read_q15x2_ia(&pB); + inB2 = arm_nn_read_q15x2_ia(&pB2); + + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + sum3 = __SMLAD(inA22, inB1, sum3); + sum4 = __SMLAD(inA22, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q7_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + /* skip the row computed with A2 */ + pA += numCol_A; + } /* for over ch_im_out */ + + pOut += ch_im_out; + + /* return the new output pointer with offset */ + return pOut; +#else + /* To be completed */ + return NULL; +#endif /* ARM_MATH_DSP */ +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16.c new file mode 100644 index 0000000..9aa17c9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16.c @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_s8_s16.c + * Description: Matrix-multiplication function for convolution + * + * $Date: May 29, 2020 + * $Revision: V.1.0.2 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/* + * Matrix-multiplication function for convolution with per-channel requantization. + * + * Refer header file for details. + * + */ + +q7_t *arm_nn_mat_mult_kernel_s8_s16(const q7_t *input_a, + const q15_t *input_b, + const uint16_t output_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int16_t activation_min, + const int16_t activation_max, + const uint16_t num_col_a, + const int32_t *const output_bias, + q7_t *out_0) +{ +#if defined(ARM_MATH_MVEI) +#define ROW_PER_LOOP (4) +#define COL_PER_LOOP (8) + + const q7_t *ip_a0_s8 = input_a; + q7_t *out_1 = out_0 + output_ch; + + const int32_t *bias = output_bias; + + int32_t row_count = output_ch / ROW_PER_LOOP; + + while (row_count) + { + const q15_t *ip_b0_s16 = input_b; + const q15_t *ip_b1_s16 = input_b + num_col_a; + + const q7_t *ip_a1_s8 = ip_a0_s8 + num_col_a; + const q7_t *ip_a2_s8 = ip_a0_s8 + num_col_a * 2; + const q7_t *ip_a3_s8 = ip_a0_s8 + num_col_a * 3; + + q31_t ch_0_out_n = bias[0]; + q31_t ch_1_out_n = bias[1]; + q31_t ch_2_out_n = bias[2]; + q31_t ch_3_out_n = bias[3]; + + q31_t ch_0_out_n1 = ch_0_out_n; + q31_t ch_1_out_n1 = ch_1_out_n; + q31_t ch_2_out_n1 = ch_2_out_n; + q31_t ch_3_out_n1 = ch_3_out_n; + bias += 4; + + int32_t col_count = num_col_a / COL_PER_LOOP; + + while (col_count) + { + // Load inputs + const int16x8_t ip_b0 = vld1q_s16(ip_b0_s16); + ip_b0_s16 += COL_PER_LOOP; + const int16x8_t ip_b1 = vld1q_s16(ip_b1_s16); + ip_b1_s16 += COL_PER_LOOP; + + // Load filters + const int16x8_t ip_a0 = vldrbq_s16(ip_a0_s8); + ip_a0_s8 += COL_PER_LOOP; + const int16x8_t ip_a1 = vldrbq_s16(ip_a1_s8); + ip_a1_s8 += COL_PER_LOOP; + const int16x8_t ip_a2 = vldrbq_s16(ip_a2_s8); + ip_a2_s8 += COL_PER_LOOP; + const int16x8_t ip_a3 = vldrbq_s16(ip_a3_s8); + ip_a3_s8 += COL_PER_LOOP; + + // MAC + ch_0_out_n += vmladavq_s16(ip_b0, ip_a0); + ch_1_out_n += vmladavq_s16(ip_b0, ip_a1); + ch_2_out_n += vmladavq_s16(ip_b0, ip_a2); + ch_3_out_n += vmladavq_s16(ip_b0, ip_a3); + ch_0_out_n1 += vmladavq_s16(ip_b1, ip_a0); + ch_1_out_n1 += vmladavq_s16(ip_b1, ip_a1); + ch_2_out_n1 += vmladavq_s16(ip_b1, ip_a2); + ch_3_out_n1 += vmladavq_s16(ip_b1, ip_a3); + + col_count--; + } + + /* Handle tail */ + col_count = (num_col_a & (COL_PER_LOOP - 1)) - 1; + while (col_count >= 0) + { + const int32_t b0 = ip_b0_s16[col_count]; + const int32_t b1 = ip_b1_s16[col_count]; + + ch_0_out_n += b0 * ip_a0_s8[col_count]; + ch_1_out_n += b0 * ip_a1_s8[col_count]; + ch_2_out_n += b0 * ip_a2_s8[col_count]; + ch_3_out_n += b0 * ip_a3_s8[col_count]; + + ch_0_out_n1 += b1 * ip_a0_s8[col_count]; + ch_1_out_n1 += b1 * ip_a1_s8[col_count]; + ch_2_out_n1 += b1 * ip_a2_s8[col_count]; + ch_3_out_n1 += b1 * ip_a3_s8[col_count]; + col_count--; + } + ip_a0_s8 += (num_col_a & (COL_PER_LOOP - 1)); + + int32x4_t out_vec_0; + int32x4_t out_vec_1; + out_vec_0[0] = ch_0_out_n; + out_vec_0[1] = ch_1_out_n; + out_vec_0[2] = ch_2_out_n; + out_vec_0[3] = ch_3_out_n; + + out_vec_1[0] = ch_0_out_n1; + out_vec_1[1] = ch_1_out_n1; + out_vec_1[2] = ch_2_out_n1; + out_vec_1[3] = ch_3_out_n1; + + int32x4_t mult = vldrwq_s32(out_mult); + int32x4_t shift = vldrwq_s32(out_shift); + out_mult += ROW_PER_LOOP; + out_shift += ROW_PER_LOOP; + + out_vec_0 = arm_requantize_mve_32x4(out_vec_0, mult, shift); + out_vec_1 = arm_requantize_mve_32x4(out_vec_1, mult, shift); + + out_vec_0 = vaddq_n_s32(out_vec_0, out_offset); + out_vec_0 = vmaxq_s32(out_vec_0, vdupq_n_s32(activation_min)); + out_vec_0 = vminq_s32(out_vec_0, vdupq_n_s32(activation_max)); + vstrbq_s32(out_0, out_vec_0); + out_0 += ROW_PER_LOOP; + + out_vec_1 = vaddq_n_s32(out_vec_1, out_offset); + out_vec_1 = vmaxq_s32(out_vec_1, vdupq_n_s32(activation_min)); + out_vec_1 = vminq_s32(out_vec_1, vdupq_n_s32(activation_max)); + vstrbq_s32(out_1, out_vec_1); + out_1 += ROW_PER_LOOP; + row_count--; + ip_a0_s8 += (num_col_a * 3); + } + + row_count = output_ch & (ROW_PER_LOOP - 1); + + if (row_count) + { + ip_a0_s8 = input_a + num_col_a * (output_ch & ~3); + const mve_pred16_t p = vctp32q((uint32_t)row_count); + int32x4_t out_vec_0 = vdupq_n_s32(0); + int32x4_t out_vec_1 = vdupq_n_s32(0); + int32x4_t mult_tail; + int32x4_t shift_tail; + + for (int i_ch = 0; i_ch < row_count; i_ch++) + { + int32_t output_0 = bias[i_ch]; + int32_t output_1 = bias[i_ch]; + const q15_t *ip_b0_s16 = input_b; + const q15_t *ip_b1_s16 = input_b + num_col_a; + + for (int i_idx = 0; i_idx < num_col_a; i_idx++) + { + output_0 += ip_b0_s16[i_idx] * ip_a0_s8[i_idx]; + output_1 += ip_b1_s16[i_idx] * ip_a0_s8[i_idx]; + } + + ip_a0_s8 += num_col_a; + out_vec_0[i_ch] = output_0; + out_vec_1[i_ch] = output_1; + mult_tail[i_ch] = out_mult[i_ch]; + shift_tail[i_ch] = out_shift[i_ch]; + } + out_vec_0 = arm_requantize_mve_32x4(out_vec_0, mult_tail, shift_tail); + out_vec_1 = arm_requantize_mve_32x4(out_vec_1, mult_tail, shift_tail); + + out_vec_0 = vaddq_n_s32(out_vec_0, out_offset); + out_vec_0 = vmaxq_s32(out_vec_0, vdupq_n_s32(activation_min)); + out_vec_0 = vminq_s32(out_vec_0, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out_0, out_vec_0, p); + + out_vec_1 = vaddq_n_s32(out_vec_1, out_offset); + out_vec_1 = vmaxq_s32(out_vec_1, vdupq_n_s32(activation_min)); + out_vec_1 = vminq_s32(out_vec_1, vdupq_n_s32(activation_max)); + + vstrbq_p_s32(out_1, out_vec_1, p); + out_1 += row_count; + } + + return out_1; + +#elif defined(ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *out_1 = out_0 + output_ch; + const int32_t *bias = output_bias; + + uint16_t row_count = output_ch / 2; + const q7_t *ip_a0 = input_a; + /* this loop over rows in A */ + while (row_count) + { + /* setup pointers for B */ + const q15_t *ip_b0 = input_b; + const q15_t *ip_b1 = ip_b0 + num_col_a; + + /* align the second pointer for A */ + const q7_t *ip_a1 = ip_a0 + num_col_a; + + /* Init accumulator with bias for channel N and N + 1 */ + q31_t ch_0_out_0 = *bias; + q31_t ch_0_out_1 = *bias++; + q31_t ch_1_out_0 = *bias; + q31_t ch_1_out_1 = *bias++; + + uint16_t col_count = num_col_a / 4; + /* accumulate over the vector */ + while (col_count) + { + q31_t a01, a02, a11, a12; + q31_t b0 = arm_nn_read_q15x2_ia(&ip_b0); + q31_t b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ip_a0 = read_and_pad(ip_a0, &a01, &a02); + ip_a1 = read_and_pad(ip_a1, &a11, &a12); + + ch_0_out_0 = __SMLAD(a01, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a01, b1, ch_0_out_1); + ch_1_out_0 = __SMLAD(a11, b0, ch_1_out_0); + ch_1_out_1 = __SMLAD(a11, b1, ch_1_out_1); + + b0 = arm_nn_read_q15x2_ia(&ip_b0); + b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ch_0_out_0 = __SMLAD(a02, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a02, b1, ch_0_out_1); + ch_1_out_0 = __SMLAD(a12, b0, ch_1_out_0); + ch_1_out_1 = __SMLAD(a12, b1, ch_1_out_1); + + col_count--; + } /* while over col_count */ + col_count = num_col_a & 0x3; + while (col_count) + { + q7_t a0 = *ip_a0++; + q15_t b0 = *ip_b0++; + q7_t a1 = *ip_a1++; + q15_t b1 = *ip_b1++; + + ch_0_out_0 += a0 * b0; + ch_0_out_1 += a0 * b1; + ch_1_out_0 += a1 * b0; + ch_1_out_1 += a1 * b1; + col_count--; + } /* while over col_count */ + + ch_0_out_0 = arm_nn_requantize(ch_0_out_0, *out_mult, *out_shift); + ch_0_out_0 += out_offset; + ch_0_out_0 = MAX(ch_0_out_0, activation_min); + ch_0_out_0 = MIN(ch_0_out_0, activation_max); + *out_0++ = (q7_t)ch_0_out_0; + + ch_0_out_1 = arm_nn_requantize(ch_0_out_1, *out_mult, *out_shift); + ch_0_out_1 += out_offset; + ch_0_out_1 = MAX(ch_0_out_1, activation_min); + ch_0_out_1 = MIN(ch_0_out_1, activation_max); + *out_1++ = (q7_t)ch_0_out_1; + out_mult++; + out_shift++; + + ch_1_out_0 = arm_nn_requantize(ch_1_out_0, *out_mult, *out_shift); + ch_1_out_0 += out_offset; + ch_1_out_0 = MAX(ch_1_out_0, activation_min); + ch_1_out_0 = MIN(ch_1_out_0, activation_max); + *out_0++ = (q7_t)ch_1_out_0; + + ch_1_out_1 = arm_nn_requantize(ch_1_out_1, *out_mult, *out_shift); + ch_1_out_1 += out_offset; + ch_1_out_1 = MAX(ch_1_out_1, activation_min); + ch_1_out_1 = MIN(ch_1_out_1, activation_max); + *out_1++ = (q7_t)ch_1_out_1; + out_mult++; + out_shift++; + + /* skip row */ + ip_a0 += num_col_a; + row_count--; + } + + /* compute the last odd numbered row if any */ + if (output_ch & 0x1) + { + /* setup pointers for B */ + const q15_t *ip_b0 = input_b; + const q15_t *ip_b1 = ip_b0 + num_col_a; + + /* load the bias */ + q31_t ch_0_out_0 = *bias; + q31_t ch_0_out_1 = *bias++; + + uint16_t col_count = num_col_a >> 2; + while (col_count) + { + q31_t a01, a02; + q31_t b0 = arm_nn_read_q15x2_ia(&ip_b0); + q31_t b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ip_a0 = read_and_pad(ip_a0, &a01, &a02); + + ch_0_out_0 = __SMLAD(a01, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a01, b1, ch_0_out_1); + + b0 = arm_nn_read_q15x2_ia(&ip_b0); + b1 = arm_nn_read_q15x2_ia(&ip_b1); + ch_0_out_0 = __SMLAD(a02, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a02, b1, ch_0_out_1); + + col_count--; + } + col_count = num_col_a & 0x3; + while (col_count) + { + q7_t a0 = *ip_a0++; + q15_t b0 = *ip_b0++; + q15_t b1 = *ip_b1++; + + ch_0_out_0 += a0 * b0; + ch_0_out_1 += a0 * b1; + col_count--; + } + ch_0_out_0 = arm_nn_requantize(ch_0_out_0, *out_mult, *out_shift); + ch_0_out_0 += out_offset; + ch_0_out_0 = MAX(ch_0_out_0, activation_min); + ch_0_out_0 = MIN(ch_0_out_0, activation_max); + *out_0++ = (q7_t)ch_0_out_0; + + ch_0_out_1 = arm_nn_requantize(ch_0_out_1, *out_mult, *out_shift); + ch_0_out_1 += out_offset; + ch_0_out_1 = MAX(ch_0_out_1, activation_min); + ch_0_out_1 = MIN(ch_0_out_1, activation_max); + *out_1++ = (q7_t)ch_0_out_1; + out_mult++; + out_shift++; + } + + out_0 += output_ch; + + /* return the new output pointer with offset */ + return out_0; +#else + (void)input_a; + (void)input_b; + (void)output_ch; + (void)out_shift; + (void)out_mult; + (void)out_offset; + (void)activation_min; + (void)activation_max; + (void)num_col_a; + (void)output_bias; + (void)out_0; + /* To be completed */ + return NULL; +#endif +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16_reordered.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16_reordered.c new file mode 100644 index 0000000..dc5d36d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_s8_s16_reordered.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_s8_s16_reordered.c + * Description: Matrix-multiplication function for convolution with reordered columns + * + * $Date: February 27, 2020 + * $Revision: V.1.0.2 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/DSP/Include/arm_math.h" + +/* + * Matrix-multiplication with re-ordered input and bias inputs for convolution with per-channel + * requantization. The re-ordering is a consequence of sign extension is done by the SXTB16 command. + * + * Refer header file for details. This function differs from arm_nn_mat_mult_kernel_s8_s16(), in that it uses + * read_and_pad_reordered() instead of arm_nn_mat_mult_kernel_s8_s16(). Investigating the cycles impact and + * unifying these two functions is a potential future improvement. + * + */ + +q7_t *arm_nn_mat_mult_kernel_s8_s16_reordered(const q7_t *input_a, + const q15_t *input_b, + const uint16_t output_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int16_t activation_min, + const int16_t activation_max, + const uint16_t num_col_a, + const int32_t *const output_bias, + q7_t *out_0) +{ +#if defined(ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *out_1 = out_0 + output_ch; + const int32_t *bias = output_bias; + + uint16_t row_count = output_ch / 2; + const q7_t *ip_a0 = input_a; + /* this loop over rows in A */ + while (row_count) + { + /* setup pointers for B */ + const q15_t *ip_b0 = input_b; + const q15_t *ip_b1 = ip_b0 + num_col_a; + + /* align the second pointer for A */ + const q7_t *ip_a1 = ip_a0 + num_col_a; + + /* Init accumulator with bias for channel N and N + 1 */ + q31_t ch_0_out_0 = *bias; + q31_t ch_0_out_1 = *bias++; + q31_t ch_1_out_0 = *bias; + q31_t ch_1_out_1 = *bias++; + + uint16_t col_count = num_col_a / 4; + /* accumulate over the vector */ + while (col_count) + { + q31_t a01, a02, a11, a12; + q31_t b0 = arm_nn_read_q15x2_ia(&ip_b0); + q31_t b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ip_a0 = read_and_pad_reordered(ip_a0, &a01, &a02); + ip_a1 = read_and_pad_reordered(ip_a1, &a11, &a12); + + ch_0_out_0 = __SMLAD(a01, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a01, b1, ch_0_out_1); + ch_1_out_0 = __SMLAD(a11, b0, ch_1_out_0); + ch_1_out_1 = __SMLAD(a11, b1, ch_1_out_1); + + b0 = arm_nn_read_q15x2_ia(&ip_b0); + b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ch_0_out_0 = __SMLAD(a02, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a02, b1, ch_0_out_1); + ch_1_out_0 = __SMLAD(a12, b0, ch_1_out_0); + ch_1_out_1 = __SMLAD(a12, b1, ch_1_out_1); + + col_count--; + } /* while over col_count */ + + ch_0_out_0 = arm_nn_requantize(ch_0_out_0, *out_mult, *out_shift); + ch_0_out_0 += out_offset; + ch_0_out_0 = MAX(ch_0_out_0, activation_min); + ch_0_out_0 = MIN(ch_0_out_0, activation_max); + *out_0++ = (q7_t)ch_0_out_0; + + ch_0_out_1 = arm_nn_requantize(ch_0_out_1, *out_mult, *out_shift); + ch_0_out_1 += out_offset; + ch_0_out_1 = MAX(ch_0_out_1, activation_min); + ch_0_out_1 = MIN(ch_0_out_1, activation_max); + *out_1++ = (q7_t)ch_0_out_1; + out_mult++; + out_shift++; + + ch_1_out_0 = arm_nn_requantize(ch_1_out_0, *out_mult, *out_shift); + ch_1_out_0 += out_offset; + ch_1_out_0 = MAX(ch_1_out_0, activation_min); + ch_1_out_0 = MIN(ch_1_out_0, activation_max); + *out_0++ = (q7_t)ch_1_out_0; + + ch_1_out_1 = arm_nn_requantize(ch_1_out_1, *out_mult, *out_shift); + ch_1_out_1 += out_offset; + ch_1_out_1 = MAX(ch_1_out_1, activation_min); + ch_1_out_1 = MIN(ch_1_out_1, activation_max); + *out_1++ = (q7_t)ch_1_out_1; + out_mult++; + out_shift++; + + /* skip row */ + ip_a0 += num_col_a; + row_count--; + } + + if (output_ch & 1) + { + /* setup pointers for B */ + const q15_t *ip_b0 = input_b; + const q15_t *ip_b1 = ip_b0 + num_col_a; + + /* Init accumulator with bias for channel N + 1 */ + q31_t ch_0_out_0 = *bias; + q31_t ch_0_out_1 = ch_0_out_0; + + int32_t col_count = num_col_a / 4; + while (col_count) + { + q31_t a01, a02; + q31_t b0 = arm_nn_read_q15x2_ia(&ip_b0); + q31_t b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ip_a0 = read_and_pad_reordered(ip_a0, &a01, &a02); + + ch_0_out_0 = __SMLAD(a01, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a01, b1, ch_0_out_1); + + b0 = arm_nn_read_q15x2_ia(&ip_b0); + b1 = arm_nn_read_q15x2_ia(&ip_b1); + + ch_0_out_0 = __SMLAD(a02, b0, ch_0_out_0); + ch_0_out_1 = __SMLAD(a02, b1, ch_0_out_1); + + col_count--; + } /* while over col_count */ + + ch_0_out_0 = arm_nn_requantize(ch_0_out_0, *out_mult, *out_shift); + ch_0_out_0 += out_offset; + ch_0_out_0 = MAX(ch_0_out_0, activation_min); + ch_0_out_0 = MIN(ch_0_out_0, activation_max); + *out_0++ = (q7_t)ch_0_out_0; + + ch_0_out_1 = arm_nn_requantize(ch_0_out_1, *out_mult, *out_shift); + ch_0_out_1 += out_offset; + ch_0_out_1 = MAX(ch_0_out_1, activation_min); + ch_0_out_1 = MIN(ch_0_out_1, activation_max); + *out_1++ = (q7_t)ch_0_out_1; + } + + out_0 += output_ch; + + /* return the new output pointer with offset */ + return out_0; +#else + (void)input_a; + (void)input_b; + (void)output_ch; + (void)out_shift; + (void)out_mult; + (void)out_offset; + (void)activation_min; + (void)activation_max; + (void)num_col_a; + (void)output_bias; + (void)out_0; + /* To be completed */ + return NULL; +#endif +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_s8.c new file mode 100644 index 0000000..d0271d0 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_s8.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_s8.c + * Description: General Matrix-multiplication function + * + * $Date: May 29, 2020 + * $Revision: V.2.0.3 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/* + * s8 General matrix multiplication function with per-channel requantization for upto 4 column batches. + * + * Refer header file for details. + * + */ + +q7_t *arm_nn_mat_mult_s8(const q7_t *input_row, + const q7_t *input_col, + const uint16_t output_ch, + const uint16_t col_batches, + const int32_t *output_shift, + const int32_t *output_mult, + const int32_t out_offset, + const int32_t col_offset, + const int32_t row_offset, + const int16_t activation_min, + const int16_t activation_max, + const uint16_t row_len, + const int32_t *const bias, + q7_t *out) +{ +#if defined(ARM_MATH_MVEI) + (void)row_offset; + if (col_batches == 4) + { + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32_t row_len_tmp = row_len; + const int8_t *ip_r0 = input_row + (i_out_ch * row_len); + const int8_t *ip_c0 = input_col; + const int8_t *ip_c1 = input_col + row_len; + const int8_t *ip_c2 = input_col + (2 * row_len); + const int8_t *ip_c3 = input_col + (3 * row_len); + + int32_t acc_0 = bias[i_out_ch]; + int32_t acc_1 = bias[i_out_ch]; + int32_t acc_2 = bias[i_out_ch]; + int32_t acc_3 = bias[i_out_ch]; + const int32_t row_loop_cnt = (row_len + 7) / 8; + + for (int i_row_loop = 0; i_row_loop < row_loop_cnt; i_row_loop++) + { + mve_pred16_t p = vctp16q((uint32_t)row_len_tmp); + const int16x8_t offset = vdupq_m_n_s16(vuninitializedq_s16(), col_offset, p); + row_len_tmp -= 8; + + int16x8_t r0 = vldrbq_z_s16(ip_r0, p); + ip_r0 += 8; + + int16x8_t c0 = vldrbq_z_s16(ip_c0, p); + ip_c0 += 8; + c0 = vaddq_m_s16(vuninitializedq_s16(), c0, offset, p); + + int16x8_t c1 = vldrbq_z_s16(ip_c1, p); + ip_c1 += 8; + c1 = vaddq_m_s16(vuninitializedq_s16(), c1, offset, p); + + int16x8_t c2 = vldrbq_z_s16(ip_c2, p); + ip_c2 += 8; + c2 = vaddq_m_s16(vuninitializedq_s16(), c2, offset, p); + + int16x8_t c3 = vldrbq_z_s16(ip_c3, p); + ip_c3 += 8; + c3 = vaddq_m_s16(vuninitializedq_s16(), c3, offset, p); + + acc_0 = vmladavaq_p_s16(acc_0, r0, c0, p); + acc_1 = vmladavaq_p_s16(acc_1, r0, c1, p); + acc_2 = vmladavaq_p_s16(acc_2, r0, c2, p); + acc_3 = vmladavaq_p_s16(acc_3, r0, c3, p); + } + + int32x4_t res = {acc_0, acc_1, acc_2, acc_3}; + res = arm_requantize_mve(res, output_mult[i_out_ch], output_shift[i_out_ch]); + res = vaddq_n_s32(res, out_offset); + + res = vmaxq_s32(res, vdupq_n_s32(activation_min)); + res = vminq_s32(res, vdupq_n_s32(activation_max)); + + const uint32x4_t scatter_offset = {0, output_ch, output_ch * 2, output_ch * 3}; + vstrbq_scatter_offset_s32(&out[i_out_ch], scatter_offset, res); + } + out += 4 * output_ch; + } + else + { + for (int i_col_batch = (col_batches & ~0x3); i_col_batch < (col_batches & 0x3); i_col_batch++) + { + for (int i_out_ch = 0; i_out_ch < output_ch; i_out_ch++) + { + int32_t row_len_tmp = row_len; + + const int8_t *ip_r0 = input_row + (i_out_ch * row_len); + const int8_t *ip_c0 = input_col + (i_col_batch * row_len); + int32_t acc_0 = bias[i_out_ch]; + const int32_t row_loop_cnt = (row_len + 7) / 8; + + for (int i_row_loop = 0; i_row_loop < row_loop_cnt; i_row_loop++) + { + const mve_pred16_t p = vctp16q((uint32_t)row_len_tmp); + const int16x8_t offset = vdupq_m_n_s16(vuninitializedq_s16(), col_offset, p); + row_len_tmp -= 8; + + int16x8_t r0 = vldrbq_z_s16(ip_r0, p); + ip_r0 += 8; + int16x8_t c0 = vldrbq_z_s16(ip_c0, p); + ip_c0 += 8; + + c0 = vaddq_m_s16(vuninitializedq_s16(), c0, offset, p); + acc_0 = vmladavaq_p_s16(acc_0, r0, c0, p); + } + + acc_0 = arm_nn_requantize(acc_0, output_mult[i_out_ch], output_shift[i_out_ch]); + acc_0 += out_offset; + acc_0 = MAX(acc_0, activation_min); + acc_0 = MIN(acc_0, activation_max); + out[i_out_ch] = (q7_t)acc_0; + } + out += output_ch; + } + } + return out; + +#else + (void)input_row; + (void)input_col; + (void)output_ch; + (void)col_batches; + (void)output_shift; + (void)output_mult; + (void)out_offset; + (void)col_offset; + (void)row_offset; + (void)activation_min; + (void)activation_max; + (void)row_len; + (void)bias; + (void)out; + return NULL; +#endif +} diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c new file mode 100644 index 0000000..92bffbf --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_mat_q7_vec_q15.c + * Description: Mixed Q15-Q7 fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Mixed Q15-Q7 fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Q7_Q15 version of the fully connected layer + * + * Weights are in q7_t and Activations are in q15_t + * + */ + +arm_status +arm_fully_connected_mat_q7_vec_q15(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + (void)vec_buffer; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + const q7_t *pB2; + q15_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 1; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV, inM11, inM12, inM21, inM22; + pB = read_and_pad(pB, &inM11, &inM12); + pB2 = read_and_pad(pB2, &inM21, &inM22); + + inV = arm_nn_read_q15x2_ia(&pA); + + sum = __SMLAD(inV, inM11, sum); + sum2 = __SMLAD(inV, inM21, sum2); + + inV = arm_nn_read_q15x2_ia(&pA); + + sum = __SMLAD(inV, inM12, sum); + sum2 = __SMLAD(inV, inM22, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + + /*adjust the pointers and counters */ + pB += dim_vec; + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x1; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = read_and_pad(pB, &inM11, &inM12); + + inV1 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV1, inM11, sum); + + inV2 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + int i, j; + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c new file mode 100644 index 0000000..f2debef --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_mat_q7_vec_q15_opt.c + * Description: Mixed Q15-Q7 opt fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Mixed Q15-Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Q7_Q15 version of the fully connected layer + * + * Weights are in q7_t and Activations are in q15_t + * + * Limitation: x4 version requires weight reordering to work + * + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original q7_t matrix looks like this: + * + * | a11 | a12 | a13 | a14 | a15 | a16 | a17 | + * + * | a21 | a22 | a23 | a24 | a25 | a26 | a27 | + * + * | a31 | a32 | a33 | a34 | a35 | a36 | a37 | + * + * | a41 | a42 | a43 | a44 | a45 | a46 | a47 | + * + * | a51 | a52 | a53 | a54 | a55 | a56 | a57 | + * + * | a61 | a62 | a63 | a64 | a65 | a66 | a67 | + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a21 | a12 | a22 | a31 | a41 | a32 | a42 | + * + * | a13 | a23 | a14 | a24 | a33 | a43 | a34 | a44 | + * + * | a15 | a25 | a16 | a26 | a35 | a45 | a36 | a46 | + * + * The column left over will be in-order. + * which is: + * | a17 | a27 | a37 | a47 | + * + * For the left-over rows, we do 1x1 computation, so the data remains + * as its original order. + * + * So the stored weight matrix looks like this: + * + * | a11 | a21 | a12 | a22 | a31 | a41 | + * + * | a32 | a42 | a13 | a23 | a14 | a24 | + * + * | a33 | a43 | a34 | a44 | a15 | a25 | + * + * | a16 | a26 | a35 | a45 | a36 | a46 | + * + * | a17 | a27 | a37 | a47 | a51 | a52 | + * + * | a53 | a54 | a55 | a56 | a57 | a61 | + * + * | a62 | a63 | a64 | a65 | a66 | a67 | + * + */ + +arm_status +arm_fully_connected_mat_q7_vec_q15_opt(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, const q7_t * bias, q15_t * pOut, q15_t * vec_buffer) +{ + + (void)vec_buffer; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + q15_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 2; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + colCnt--; + } + +#else + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + +#ifndef ARM_MATH_BIG_ENDIAN + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r1, [%[pB]], #8\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#else + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r1, [%[pB]], #8\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB++; + q7_t inM3 = *pB++; + q7_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum3 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum4 >> out_shift), 16)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = read_and_pad(pB, &inM11, &inM12); + + inV1 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV1, inM11, sum); + + inV2 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + colCnt--; + } + + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c new file mode 100644 index 0000000..79413cb --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q15.c + * Description: Q15 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + */ + +arm_status +arm_fully_connected_q15(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + (void)vec_buffer; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q15_t *pB = pM; + const q15_t *pB2 = pB + dim_vec; + q15_t *pO = pOut; + const q15_t *pA; + const q15_t *pBias = bias; + uint16_t rowCnt = num_of_rows >> 1; + + /* this loop loops over different output */ + while (rowCnt) { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV1, inM1, inM2; + inV1 = arm_nn_read_q15x2_ia(&pA); + inM1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inV1, inM1, sum); + inM2 = arm_nn_read_q15x2_ia(&pB2); + sum2 = __SMLAD(inV1, inM2, sum2); + + inV1 = arm_nn_read_q15x2_ia(&pA); + inM1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inV1, inM1, sum); + inM2 = arm_nn_read_q15x2_ia(&pB2); + sum2 = __SMLAD(inV1, inM2, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2>> out_shift), 16)); + + /* adjust the pointers and counters */ + pB = pB + dim_vec; + rowCnt --; + } + + rowCnt = num_of_rows & 0x1; + + while (rowCnt) { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) { + q31_t inV1, inM1; + inV1 = arm_nn_read_q15x2_ia(&pA); + inM1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inV1, inM1, sum); + + inV1 = arm_nn_read_q15x2_ia(&pA); + inM1 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inV1, inM1, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while(colCnt) { + q15_t inV = *pA++; + q15_t inM = *pB++; + + sum += inV * inM; + + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt --; + } + +#else + int i, j; + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c new file mode 100644 index 0000000..d495342 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q15_opt.c + * Description: Q15 opt fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original matrix looks like this: + * + * | a11 | a12 | a13 | + * + * | a21 | a22 | a23 | + * + * | a31 | a32 | a33 | + * + * | a41 | a42 | a43 | + * + * | a51 | a52 | a53 | + * + * | a61 | a62 | a63 | + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a12 | a21 | a22 | a31 | a32 | a41 | a42 | + * + * | a13 | a23 | a33 | a43 | + * + * Remaining rows are kept the same original order. + * + * So the stored weight matrix looks like this: + * + * + * | a11 | a12 | a21 | a22 | a31 | a32 | a41 | a42 | + * + * | a13 | a23 | a33 | a43 | a51 | a52 | a53 | a61 | + * + * | a62 | a63 | + */ + +arm_status +arm_fully_connected_q15_opt(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + (void)vec_buffer; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q15_t *pB = pM; + q15_t *pO = pOut; + const q15_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 2; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + +#ifdef USE_INTRINSIC + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q15x2_ia(&pB); + sum = __SMLAD(inV, inM11, sum); + inM12 = arm_nn_read_q15x2_ia(&pB); + sum2 = __SMLAD(inV, inM12, sum2); + inM13 = arm_nn_read_q15x2_ia(&pB); + sum3 = __SMLAD(inV, inM13, sum3); + inM14 = arm_nn_read_q15x2_ia(&pB); + sum4 = __SMLAD(inV, inM14, sum4); + colCnt--; + } + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r0, [%[pB]], #16\n" + "smlad %[sum], r4, r0, %[sum]\n" + "ldr.w r1, [%[pB] , #-12]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r2, [%[pB] , #-8]\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "ldr.w r3, [%[pB] , #-4]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x1; + while (colCnt) + { + + q15_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB++; + q15_t inM3 = *pB++; + q15_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum3 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum4 >> out_shift), 16)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM1, inM2; + + inM1 = arm_nn_read_q15x2_ia(&pB); + inV1 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV1, inM1, sum); + + inM2 = arm_nn_read_q15x2_ia(&pB); + inV2 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV2, inM2, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q15_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q15_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q15_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q15_t inB1 = *pB++; + q15_t inB2 = *pB++; + sum += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum2 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum3 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum4 += inA1 * inB1 + inA2 * inB2; + + colCnt--; + } + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c new file mode 100644 index 0000000..12dc6f1 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q7.c + * Description: Q7 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q7 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: dim_vec + * + * This basic function is designed to work with regular weight + * matrix without interleaving. + * + */ + +arm_status +arm_fully_connected_q7(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, const q7_t * bias, q7_t * pOut, q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + const q7_t *pB2; + q7_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA; + uint16_t rowCnt = num_of_rows >> 1; + + /* expand the vector into the buffer */ + arm_q7_to_q15_reordered_no_shift(pV, vec_buffer, dim_vec); + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV, inM11, inM12, inM21, inM22; + pB = read_and_pad_reordered(pB, &inM11, &inM12); + pB2 = read_and_pad_reordered(pB2, &inM21, &inM22); + + inV = arm_nn_read_q15x2_ia(&pA); + + sum = __SMLAD(inV, inM11, sum); + sum2 = __SMLAD(inV, inM21, sum2); + + inV = arm_nn_read_q15x2_ia(&pA); + + sum = __SMLAD(inV, inM12, sum); + sum2 = __SMLAD(inV, inM22, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum2 >> out_shift), 8)); + + /* adjust the pointers and counters */ + pB += dim_vec; + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x1; + + while (rowCnt) + { + uint16_t colCnt = dim_vec >> 2; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + pA = vec_buffer; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = read_and_pad_reordered(pB, &inM11, &inM12); + + inV1 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV1, inM11, sum); + + inV2 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inV = *pA++; + q15_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + + rowCnt--; + } + +#else + int i, j; + + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q7_t) __SSAT((ip_out >> out_shift), 8); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c new file mode 100644 index 0000000..ee7faa9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q7_opt.c + * Description: Q7 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: dim_vec + * + * This opt function is designed to work with interleaved weight + * matrix. The vector input is assumed in q7_t format, we call + * arm_q7_to_q15_no_shift_shuffle function to expand into + * q15_t format with certain weight re-ordering, refer to the function + * comments for more details. + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original q7_t matrix looks like this: + * + * | a11 | a12 | a13 | a14 | a15 | a16 | a17 | + * + * | a21 | a22 | a23 | a24 | a25 | a26 | a27 | + * + * | a31 | a32 | a33 | a34 | a35 | a36 | a37 | + * + * | a41 | a42 | a43 | a44 | a45 | a46 | a47 | + * + * | a51 | a52 | a53 | a54 | a55 | a56 | a57 | + * + * | a61 | a62 | a63 | a64 | a65 | a66 | a67 | + * + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a21 | a13 | a23 | a31 | a41 | a33 | a43 | + * + * | a12 | a22 | a14 | a24 | a32 | a42 | a34 | a44 | + * + * | a15 | a25 | a35 | a45 | a16 | a26 | a36 | a46 | + * + * So within the kernel, we first read the re-ordered vector in as: + * + * | b1 | b3 | and | b2 | b4 | + * + * the four q31_t weights will look like + * + * | a11 | a13 |, | a21 | a23 |, | a31 | a33 |, | a41 | a43 | + * + * | a12 | a14 |, | a22 | a24 |, | a32 | a34 |, | a42 | a44 | + * + * The column left over will be in-order. + * which is: + * + * | a17 | a27 | a37 | a47 | + * + * For the left-over rows, we do 1x1 computation, so the data remains + * as its original order. + * + * So the stored weight matrix looks like this: + * + * | a11 | a21 | a13 | a23 | a31 | a41 | + * + * | a33 | a43 | a12 | a22 | a14 | a24 | + * + * | a32 | a42 | a34 | a44 | a15 | a25 | + * + * | a35 | a45 | a16 | a26 | a36 | a46 | + * + * | a17 | a27 | a37 | a47 | a51 | a52 | + * + * | a53 | a54 | a55 | a56 | a57 | a61 | + * + * | a62 | a63 | a64 | a65 | a66 | a67 | + * + * + */ + +arm_status +arm_fully_connected_q7_opt(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + q7_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA; + uint16_t rowCnt = num_of_rows >> 2; + + arm_q7_to_q15_reordered_no_shift(pV, vec_buffer, dim_vec); + + while (rowCnt) + { + + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + colCnt--; + } +#else + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + + inV = arm_nn_read_q15x2_ia(&pA); + inM11 = arm_nn_read_q7x4_ia(&pB); + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = arm_nn_read_q7x4_ia(&pB); + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + colCnt--; + } +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + +#ifndef ARM_MATH_BIG_ENDIAN + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #8\n" + "ldr.w r1, [%[pB]], #16\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-12]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "ldr.w r4, [%[pA], #-4]\n" + "ldr.w r1, [%[pB], #-8]\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#else + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #8\n" + "ldr.w r1, [%[pB]], #16\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-12]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "ldr.w r4, [%[pA], #-4]\n" + "ldr.w r1, [%[pB], #-8]\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB++; + q7_t inM3 = *pB++; + q7_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum2 >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum3 >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum4 >> out_shift), 8)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = read_and_pad_reordered(pB, &inM11, &inM12); + + inV1 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV1, inM11, sum); + + inV2 = arm_nn_read_q15x2_ia(&pA); + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q7_t *pA; + q7_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q7_t inA1 = *pA++; + q7_t inA3 = *pA++; + q7_t inA2 = *pA++; + q7_t inA4 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum += inA3 * inB1 + inA4 * inB2; + sum2 += inA3 * inB3 + inA4 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA3 * inB1 + inA4 * inB2; + sum4 += inA3 * inB3 + inA4 * inB4; + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q7_t) __SSAT((ip_out >> out_shift), 8); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_s8.c new file mode 100644 index 0000000..9775aaa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_s8.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_s8 + * Description: Fully connected function compatible with TF Lite. + * + * $Date: May 2, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M and Cortex-A cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + +/* + * S8 basic fully-connected and matrix multiplication layer function for TensorFlow Lite + * + * Refer header file for details. + * + */ + +arm_status +arm_fully_connected_s8(const cmsis_nn_context *ctx, + const cmsis_nn_fc_params *fc_params, + const cmsis_nn_per_tensor_quant_params *quant_params, + const cmsis_nn_dims *input_dims, + const q7_t *input, + const cmsis_nn_dims *filter_dims, + const q7_t *kernel, + const cmsis_nn_dims *bias_dims, + const int32_t *bias, + const cmsis_nn_dims *output_dims, + q7_t *output) +{ + (void)bias_dims; + (void)ctx; + int32_t batch_cnt = input_dims->n; + + while (batch_cnt) + { + arm_nn_vec_mat_mult_t_s8(input, + kernel, + bias, + output, + fc_params->input_offset, + fc_params->filter_offset, + fc_params->output_offset, + quant_params->multiplier, + quant_params->shift, + filter_dims->n, /* col_dim or accum_depth */ + output_dims->c, /* row_dim or output_depth */ + fc_params->activation.min, + fc_params->activation.max); + input += filter_dims->n; + output += output_dims->c; + batch_cnt--; + } + return (ARM_MATH_SUCCESS); +} + +int32_t arm_fully_connected_s8_get_buffer_size(const cmsis_nn_dims *filter_dims) +{ + (void)filter_dims; + return 0; +} + +/** + * @} end of FC group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_accumulate_q7_to_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_accumulate_q7_to_q15.c new file mode 100644 index 0000000..7d14834 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_accumulate_q7_to_q15.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_accumulate_q7_to_q15.c + * Description: Accumulate q7 vector into q15 one. + * + * $Date: May 29, 2020 + * $Revision: V.1.0.1 + * + * pSrc Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +void arm_nn_accumulate_q7_to_q15(q15_t *pDst, const q7_t *pSrc, uint32_t length) +{ + q15_t *pCnt = pDst; + const q7_t *pV = pSrc; + q31_t v1, v2, vo1, vo2; + int32_t cnt = length >> 2; + q31_t in; + + while (cnt > 0l) + { + q31_t value = arm_nn_read_q7x4_ia(&pV); + v1 = __SXTB16(__ROR((uint32_t)value, 8)); + v2 = __SXTB16(value); +#ifndef ARM_MATH_BIG_ENDIAN + vo2 = (q31_t)__PKHTB(v1, v2, 16); + vo1 = (q31_t)__PKHBT(v2, v1, 16); +#else + vo1 = (q31_t)__PKHTB(v1, v2, 16); + vo2 = (q31_t)__PKHBT(v2, v1, 16); +#endif + + in = arm_nn_read_q15x2(pCnt); + write_q15x2_ia(&pCnt, __QADD16(vo1, in)); + + in = arm_nn_read_q15x2(pCnt); + write_q15x2_ia(&pCnt, __QADD16(vo2, in)); + + cnt--; + } + cnt = length & 0x3; + while (cnt > 0l) + { + *pCnt++ += *pV++; + cnt--; + } +} + +/** + * @} end of NNBasicMath group + */ \ No newline at end of file diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_add_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_add_q7.c new file mode 100644 index 0000000..ea549f9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_add_q7.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_add_q7.c + * Description: Non saturating addition of elements of a q7 vector. + * + * $Date: July 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +void arm_nn_add_q7(const q7_t *input, q31_t *output, uint32_t block_size) +{ + uint32_t block_count; + q31_t result = 0; +#if defined(ARM_MATH_DSP) + /* Loop unrolling: Compute 4 outputs at a time */ + block_count = block_size >> 2U; + + while (block_count > 0U) + { + const int32_t mult_q15x2 = (1UL << 16) | 1UL; + q31_t in_q7x4 = arm_nn_read_q7x4_ia(&input); + q31_t temp_q15x2 = __SXTAB16(__SXTB16(in_q7x4), + __ROR((uint32_t)in_q7x4, 8)); + + result = __SMLAD(temp_q15x2, mult_q15x2, result); + + /* Decrement loop counter */ + block_count--; + } + + /* Loop unrolling: Compute remaining outputs */ + block_count = block_size & 0x3; +#else + block_count = block_size; +#endif + while (block_count > 0U) + { + /* Add and store result in destination buffer. */ + result += *input++; + + /* Decrement loop counter */ + block_count--; + } + + *output = result; +} + +/** + * @} end of NNBasicMath group + */ \ No newline at end of file diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_padded_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_padded_s8.c new file mode 100644 index 0000000..15e6b6d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_padded_s8.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_depthwise_conv_nt_t_padded_s8.c + * Description: Depthwise convolution with padded matrices. + * + * $Date: March 17, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M processors with MVE extension + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * Depthwise convolution of transposed rhs matrix with 4 lhs matrices. One or more of the rhs matrices are padded. + * Dimensions are the same for lhs and rhs. + * + * Refer header file for details. + * + */ + +q7_t *arm_nn_depthwise_conv_nt_t_padded_s8(const q7_t *lhs, + const q7_t *rhs, + const int32_t input_offset, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t row_x_col, + const int32_t *const output_bias, + q7_t *out) +{ +#if defined(ARM_MATH_MVEI) + int32_t loop_count = (num_ch + 3) / 4; + const int32_t *bias = output_bias; + uint32_t num_ch_to_process = num_ch; + + for (int i_loop_cnt = 0, offset = 0; i_loop_cnt < loop_count; + num_ch_to_process -= 4, out += 4, offset += 4, i_loop_cnt++) + { + int32x4_t out_0 = vldrwq_s32(bias); + int32x4_t out_1 = out_0; + int32x4_t out_2 = out_0; + int32x4_t out_3 = out_0; + bias += 4; + + const int8_t *rhs_0 = rhs + offset; + const int8_t *lhs_0 = lhs + offset; + const int8_t *lhs_1 = lhs + row_x_col * num_ch + offset; + const int8_t *lhs_2 = lhs + (row_x_col * num_ch * 2) + offset; + const int8_t *lhs_3 = lhs + (row_x_col * num_ch * 3) + offset; + + for (int i_row_x_col = 0; i_row_x_col < row_x_col; i_row_x_col++) + { + const int32x4_t ker_0 = vldrbq_s32(rhs_0); + + int32x4_t ip_0 = vldrbq_s32(lhs_0); + ip_0 = vaddq_n_s32(ip_0, input_offset); + out_0 += vmulq_s32(ip_0, ker_0); + + int32x4_t ip_1 = vldrbq_s32(lhs_1); + ip_1 = vaddq_n_s32(ip_1, input_offset); + out_1 += vmulq_s32(ip_1, ker_0); + + int32x4_t ip_2 = vldrbq_s32(lhs_2); + ip_2 = vaddq_n_s32(ip_2, input_offset); + out_2 += vmulq_s32(ip_2, ker_0); + + int32x4_t ip_3 = vldrbq_s32(lhs_3); + ip_3 = vaddq_n_s32(ip_3, input_offset); + + out_3 += vmulq_s32(ip_3, ker_0); + + lhs_0 += num_ch; + lhs_1 += num_ch; + lhs_2 += num_ch; + lhs_3 += num_ch; + + rhs_0 += num_ch; + } + + const int32x4_t mult = vldrwq_s32(out_mult); + const int32x4_t shift = vldrwq_s32(out_shift); + out_mult += 4; + out_shift += 4; + + out_0 = arm_requantize_mve_32x4(out_0, mult, shift); + out_0 = vaddq_n_s32(out_0, out_offset); + out_0 = vmaxq_s32(out_0, vdupq_n_s32(activation_min)); + out_0 = vminq_s32(out_0, vdupq_n_s32(activation_max)); + mve_pred16_t p = vctp32q(num_ch_to_process); + vstrbq_p_s32(out, out_0, p); + + out_1 = arm_requantize_mve_32x4(out_1, mult, shift); + out_1 = vaddq_n_s32(out_1, out_offset); + out_1 = vmaxq_s32(out_1, vdupq_n_s32(activation_min)); + out_1 = vminq_s32(out_1, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + num_ch, out_1, p); + + out_2 = arm_requantize_mve_32x4(out_2, mult, shift); + out_2 = vaddq_n_s32(out_2, out_offset); + out_2 = vmaxq_s32(out_2, vdupq_n_s32(activation_min)); + out_2 = vminq_s32(out_2, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + 2 * num_ch, out_2, p); + + out_3 = arm_requantize_mve_32x4(out_3, mult, shift); + out_3 = vaddq_n_s32(out_3, out_offset); + out_3 = vmaxq_s32(out_3, vdupq_n_s32(activation_min)); + out_3 = vminq_s32(out_3, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + 3 * num_ch, out_3, p); + } + + const int tail_ch = num_ch & 0x3; + if (tail_ch != 0) + { + out -= (4 - tail_ch); + } + return out + (3 * num_ch); + +#else + (void)lhs; + (void)rhs; + (void)input_offset; + (void)num_ch; + (void)out_shift; + (void)out_mult; + (void)out_offset; + (void)activation_min; + (void)activation_max; + (void)row_x_col; + (void)output_bias; + (void)out; + return NULL; +#endif +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_s8.c new file mode 100644 index 0000000..2cfdef4 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_depthwise_conv_nt_t_s8.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_depthwise_conv_nt_t_s8.c + * Description: Depthwise convolution on matrices with no padding. + * + * $Date: March 17, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M processors with MVE extension. + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * Depthwise convolution of rhs matrix with 4 lhs matrices with no padding. Dimensions are the same for lhs and rhs. + * + * Refer header file for details. + * + */ + +q7_t *arm_nn_depthwise_conv_nt_t_s8(const q7_t *lhs, + const q7_t *rhs, + const int32_t input_offset, + const uint16_t num_ch, + const int32_t *out_shift, + const int32_t *out_mult, + const int32_t out_offset, + const int32_t activation_min, + const int32_t activation_max, + const uint16_t row_x_col, + const int32_t *const output_bias, + q7_t *out) +{ +#if defined(ARM_MATH_MVEI) + const int32_t *bias = output_bias; + int32_t loop_count = (num_ch + 3) / 4; + uint32_t num_ch_to_process = num_ch; + + for (int i_loop_cnt = 0, offset = 0; i_loop_cnt < loop_count; + num_ch_to_process -= 4, offset += 4, out += 4, i_loop_cnt++) + { + int32x4_t out_0 = vldrwq_s32(bias); + int32x4_t out_1 = out_0; + int32x4_t out_2 = out_0; + int32x4_t out_3 = out_0; + bias += 4; + + const int8_t *rhs_0 = rhs + offset; + const int8_t *lhs_0 = lhs + offset; + const int8_t *lhs_1 = lhs + row_x_col * num_ch + offset; + const int8_t *lhs_2 = lhs + (row_x_col * num_ch * 2) + offset; + const int8_t *lhs_3 = lhs + (row_x_col * num_ch * 3) + offset; + int32x4_t ker_sum = vdupq_n_s32(0); + + for (int i_row_x_col = 0; i_row_x_col < row_x_col; i_row_x_col++) + { + const int32x4_t ker_0 = vldrbq_s32(rhs_0); + ker_sum = vaddq_s32(ker_sum, ker_0); + + int32x4_t ip_0 = vldrbq_s32(lhs_0); + out_0 += vmulq_s32(ip_0, ker_0); + + int32x4_t ip_1 = vldrbq_s32(lhs_1); + out_1 += vmulq_s32(ip_1, ker_0); + + int32x4_t ip_2 = vldrbq_s32(lhs_2); + out_2 += vmulq_s32(ip_2, ker_0); + + int32x4_t ip_3 = vldrbq_s32(lhs_3); + out_3 += vmulq_s32(ip_3, ker_0); + + lhs_0 += num_ch; + lhs_1 += num_ch; + lhs_2 += num_ch; + lhs_3 += num_ch; + + rhs_0 += num_ch; + } + + ker_sum = vmulq_n_s32(ker_sum, input_offset); + out_0 = ker_sum + out_0; + out_1 = ker_sum + out_1; + out_2 = ker_sum + out_2; + out_3 = ker_sum + out_3; + + const int32x4_t mult = vldrwq_s32(out_mult); + const int32x4_t shift = vldrwq_s32(out_shift); + out_mult += 4; + out_shift += 4; + mve_pred16_t p = vctp32q(num_ch_to_process); + + out_0 = arm_requantize_mve_32x4(out_0, mult, shift); + out_0 = vaddq_n_s32(out_0, out_offset); + out_0 = vmaxq_s32(out_0, vdupq_n_s32(activation_min)); + out_0 = vminq_s32(out_0, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out, out_0, p); + + out_1 = arm_requantize_mve_32x4(out_1, mult, shift); + out_1 = vaddq_n_s32(out_1, out_offset); + out_1 = vmaxq_s32(out_1, vdupq_n_s32(activation_min)); + out_1 = vminq_s32(out_1, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + num_ch, out_1, p); + + out_2 = arm_requantize_mve_32x4(out_2, mult, shift); + out_2 = vaddq_n_s32(out_2, out_offset); + out_2 = vmaxq_s32(out_2, vdupq_n_s32(activation_min)); + out_2 = vminq_s32(out_2, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + 2 * num_ch, out_2, p); + + out_3 = arm_requantize_mve_32x4(out_3, mult, shift); + out_3 = vaddq_n_s32(out_3, out_offset); + out_3 = vmaxq_s32(out_3, vdupq_n_s32(activation_min)); + out_3 = vminq_s32(out_3, vdupq_n_s32(activation_max)); + vstrbq_p_s32(out + 3 * num_ch, out_3, p); + } + + const int tail_ch = num_ch & 0x3; + if (tail_ch != 0) + { + out -= (4 - tail_ch); + } + + return out + (3 * num_ch); +#else + (void)lhs; + (void)rhs; + (void)input_offset; + (void)num_ch; + (void)out_shift; + (void)out_mult; + (void)out_offset; + (void)activation_min; + (void)activation_max; + (void)row_x_col; + (void)output_bias; + (void)out; + return NULL; +#endif +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_1x_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_1x_s8.c new file mode 100644 index 0000000..f57ee07 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_1x_s8.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mul_core_1x_s8.c + * Description: General Matrix-multiplication function + * + * $Date: January 20, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * s8 matrix multiplication to process 1 row + * + * Refer header file for details. + * + */ + +arm_status arm_nn_mat_mul_core_1x_s8(int32_t row_elements, + const int8_t *row_base, + const int8_t *col_base, + int32_t *const sum_col, + int32_t *const output) +{ + int32_t acc_n0 = 0; + int32_t sum_tmp = 0; + +#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE) + + __asm volatile ( + " vldrb.8 q0, [%[col]], 16 \n" + " wlstp.8 lr, %[cnt], 1f \n" + "2: \n" + " vaddva.s8 %[sum], q0 \n" + " vldrb.8 q1, [%[row0]], 16 \n" + " vmladava.s8 %[out0], q0, q1 \n" + " vldrb.8 q0, [%[col]], 16 \n" + " letp lr, 2b \n" + "1: \n" + :[col] "+r"(col_base) + ,[sum] "+Te"(sum_tmp) + ,[row0] "+r"(row_base) + ,[out0] "+Te"(acc_n0) + :[cnt] "r"(row_elements) + :"q0","q1", "memory", "r14"); +#else + for (int i = 0; i < row_elements; i++) + { + sum_tmp += col_base[i]; + acc_n0 += row_base[i] * col_base[i]; + } +#endif + + *sum_col = sum_tmp; + *output = acc_n0; + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_4x_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_4x_s8.c new file mode 100644 index 0000000..0b240b7 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mul_core_4x_s8.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mul_core_4x_s8.c + * Description: General matrix multiplication function for MVE extension + * + * $Date: January 20, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * s8 matrix multiplication to process 4 rows and one column + * + * Refer header file for details. + * + */ +arm_status arm_nn_mat_mul_core_4x_s8(const int32_t row_elements, + const int32_t offset, + const int8_t *row_base, + const int8_t *col_base, + int32_t *const sum_col, + int32_t *const output) +{ + int32_t acc_n0 = 0; + int32_t acc_n1 = 0; + int32_t acc_n2 = 0; + int32_t acc_n3 = 0; + + const int8_t *ip_row_0 = row_base; + const int8_t *ip_row_1 = row_base + offset; + const int8_t *ip_row_2 = row_base + (2 * offset); + const int8_t *ip_row_3 = row_base + (3 * offset); + int32_t sum_tmp = 0; + +#if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE) + __asm volatile( + " vldrb.8 q0, [%[col]], 16 \n" + " wlstp.8 lr, %[cnt], 1f \n" + "2: \n" + " vaddva.s8 %[sum], q0 \n" + " vldrb.8 q1, [%[row0]], 16 \n" + " vmladava.s8 %[out0], q0, q1 \n" + " vldrb.8 q2, [%[row1]], 16 \n" + " vmladava.s8 %[out1], q0, q2 \n" + " vldrb.8 q3, [%[row2]], 16 \n" + " vmladava.s8 %[out2], q0, q3 \n" + " vldrb.8 q4, [%[row3]], 16 \n" + " vmladava.s8 %[out3], q0, q4 \n" + " vldrb.8 q0, [%[col]], 16 \n" + " letp lr, 2b \n" + "1: \n" + :[col] "+r"(col_base) + ,[sum] "+Te"(sum_tmp) + ,[row0] "+r"(ip_row_0) + ,[row1] "+r"(ip_row_1) + ,[row2] "+r"(ip_row_2) + ,[row3] "+r"(ip_row_3) + ,[out0] "+Te"(acc_n0) + ,[out1] "+Te"(acc_n1) + ,[out2] "+Te"(acc_n2) + ,[out3] "+Te"(acc_n3) + : [cnt] "r"(row_elements) + : "q0", "q1", "q2", "q3", "q4", "memory", "r14"); +#else + for (int i = 0; i < row_elements; i++) + { + int32_t col = col_base[i]; + sum_tmp += col; + acc_n0 += ip_row_0[i] * col; + acc_n1 += ip_row_1[i] * col; + acc_n2 += ip_row_2[i] * col; + acc_n3 += ip_row_3[i] * col; + } +#endif + output[0] = acc_n0; + output[1] = acc_n1; + output[2] = acc_n2; + output[3] = acc_n3; + + *sum_col = sum_tmp; + + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mult_nt_t_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mult_nt_t_s8.c new file mode 100644 index 0000000..db02a33 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mat_mult_nt_t_s8.c @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_s8_nt_t_s8 + * Description: Matrix multiplication support function with the right-hand-side (rhs) matrix transposed + * + * $Date: March 17 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +// Work around for https://github.com/ARMmbed/mbed-os/issues/12568 +#define __patched_SXTB16_RORn(op1, rotate) \ +({ \ + uint32_t result; \ + __ASM ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); \ + result; \ +}) + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * s8 matrix multiplication with the right-hand-side matrix transposed + * + * Refer header file for details. + * + */ +arm_status arm_nn_mat_mult_nt_t_s8(const q7_t *lhs, + const q7_t *rhs, + const q31_t *bias, + q7_t *dst, + const int32_t *dst_multipliers, + const int32_t *dst_shifts, + const int32_t lhs_rows, + const int32_t rhs_rows, + const int32_t rhs_cols, + const int32_t lhs_offset, + const int32_t dst_offset, + const int32_t activation_min, + const int32_t activation_max) +{ +#if defined(ARM_MATH_DSP) + const int32_t off0 = rhs_cols - 4; + + for (int32_t rhs_rows_idx = 0; rhs_rows_idx <= (rhs_rows - 2); rhs_rows_idx += 2) + { + const q7_t *lhs_ptr = &lhs[0]; + q7_t *dst_ptr = &dst[0]; + + q31_t lhs_offset_contribution0 = 0; + q31_t lhs_offset_contribution1 = 0; + + for (int32_t x = 0; x < rhs_cols; ++x) + { + lhs_offset_contribution0 += rhs[x]; + lhs_offset_contribution1 += rhs[x + rhs_cols]; + } + + lhs_offset_contribution0 *= lhs_offset; + lhs_offset_contribution1 *= lhs_offset; + + lhs_offset_contribution0 += bias[rhs_rows_idx]; + lhs_offset_contribution1 += bias[rhs_rows_idx + 1]; + + int32_t lhs_rows_idx = lhs_rows >> 1; + + while (lhs_rows_idx) + { + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = lhs_offset_contribution0; + q31_t res01 = lhs_offset_contribution1; + q31_t res10 = lhs_offset_contribution0; + q31_t res11 = lhs_offset_contribution1; + + int32_t rhs_cols_idx = 0; + + q31_t val0, val1, val2, val3, val4, val5; + + for (; rhs_cols_idx <= (rhs_cols - 16); rhs_cols_idx += 16) + { + val1 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val2 = __SXTB16(val1); + val0 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val4 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val1 = __patched_SXTB16_RORn(val1, 8); + val0 = __patched_SXTB16_RORn(val0, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTB16(val4); + res00 = __SMLAD(val0, val1, res00); + val4 = __patched_SXTB16_RORn(val4, 8); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val0, val4, res01); + + // 4 x MAC res10, res11 + val0 = arm_nn_read_q7x4((const q7_t *)&lhs_ptr[off0]); + val3 = __SXTB16(val0); + val0 = __patched_SXTB16_RORn(val0, 8); + res10 = __SMLAD(val3, val2, res10); + res11 = __SMLAD(val3, val5, res11); + res10 = __SMLAD(val0, val1, res10); + val1 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res11 = __SMLAD(val0, val4, res11); + + val4 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = __SXTB16(val1); + val0 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val1 = __patched_SXTB16_RORn(val1, 8); + val0 = __patched_SXTB16_RORn(val0, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTB16(val4); + res00 = __SMLAD(val0, val1, res00); + val4 = __patched_SXTB16_RORn(val4, 8); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val0, val4, res01); + + // 4 x MAC res10, res11 + val0 = arm_nn_read_q7x4((const q7_t *)&lhs_ptr[off0]); + val3 = __SXTB16(val0); + val0 = __patched_SXTB16_RORn(val0, 8); + res10 = __SMLAD(val3, val2, res10); + res11 = __SMLAD(val3, val5, res11); + res10 = __SMLAD(val0, val1, res10); + val1 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res11 = __SMLAD(val0, val4, res11); + + val4 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = __SXTB16(val1); + val0 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val1 = __patched_SXTB16_RORn(val1, 8); + val0 = __patched_SXTB16_RORn(val0, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTB16(val4); + res00 = __SMLAD(val0, val1, res00); + val4 = __patched_SXTB16_RORn(val4, 8); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val0, val4, res01); + + // 4 x MAC res10, res11 + val0 = arm_nn_read_q7x4((const q7_t *)&lhs_ptr[off0]); + val3 = __SXTB16(val0); + val0 = __patched_SXTB16_RORn(val0, 8); + res10 = __SMLAD(val3, val2, res10); + res11 = __SMLAD(val3, val5, res11); + res10 = __SMLAD(val0, val1, res10); + val1 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res11 = __SMLAD(val0, val4, res11); + + val4 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = __SXTB16(val1); + val0 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val1 = __patched_SXTB16_RORn(val1, 8); + val0 = __patched_SXTB16_RORn(val0, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTB16(val4); + res00 = __SMLAD(val0, val1, res00); + val4 = __patched_SXTB16_RORn(val4, 8); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val0, val4, res01); + + // 4 x MAC res10, res11 + val0 = arm_nn_read_q7x4((const q7_t *)&lhs_ptr[off0]); + val3 = __SXTB16(val0); + val0 = __patched_SXTB16_RORn(val0, 8); + res10 = __SMLAD(val3, val2, res10); + res11 = __SMLAD(val3, val5, res11); + res10 = __SMLAD(val0, val1, res10); + res11 = __SMLAD(val0, val4, res11); + } + + for (; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q7_t rhs_value0 = rhs_ptr[0]; + q7_t rhs_value1 = rhs_ptr[rhs_cols]; + q7_t lhs_value = lhs_ptr[0]; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + lhs_value = lhs_ptr[rhs_cols]; + res10 += lhs_value * rhs_value0; + res11 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res01 = arm_nn_requantize(res01, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + res10 = arm_nn_requantize(res10, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res11 = arm_nn_requantize(res11, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + res10 += dst_offset; + res11 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + res10 = MAX(res10, activation_min); + res10 = MIN(res10, activation_max); + res11 = MAX(res11, activation_min); + res11 = MIN(res11, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr[1] = (q7_t)res01; + dst_ptr += rhs_rows; + dst_ptr[0] = (q7_t)res10; + dst_ptr[1] = (q7_t)res11; + dst_ptr += rhs_rows; + + lhs_ptr += rhs_cols; + + lhs_rows_idx--; + } + + // Left-over rows + if (lhs_rows % 2) + { + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = lhs_offset_contribution0; + q31_t res01 = lhs_offset_contribution1; + + int32_t rhs_cols_idx = 0; + + q31_t val0, val1, val2, val3, val4, val5; + for (; rhs_cols_idx <= (rhs_cols - 16); rhs_cols_idx += 16) + { + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val5 = __SXTB16(val2); + val4 = __SXTB16(val1); + val0 = __patched_SXTB16_RORn(val0, 8); + val2 = __patched_SXTB16_RORn(val2, 8); + val1 = __patched_SXTB16_RORn(val1, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val5, val3, res00); + res00 = __SMLAD(val2, val0, res00); + res01 = __SMLAD(val5, val4, res01); + res01 = __SMLAD(val2, val1, res01); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val5 = __SXTB16(val2); + val4 = __SXTB16(val1); + val0 = __patched_SXTB16_RORn(val0, 8); + val2 = __patched_SXTB16_RORn(val2, 8); + val1 = __patched_SXTB16_RORn(val1, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val5, val3, res00); + res00 = __SMLAD(val2, val0, res00); + res01 = __SMLAD(val5, val4, res01); + res01 = __SMLAD(val2, val1, res01); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val5 = __SXTB16(val2); + val4 = __SXTB16(val1); + val0 = __patched_SXTB16_RORn(val0, 8); + val2 = __patched_SXTB16_RORn(val2, 8); + val1 = __patched_SXTB16_RORn(val1, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val5, val3, res00); + res00 = __SMLAD(val2, val0, res00); + res01 = __SMLAD(val5, val4, res01); + res01 = __SMLAD(val2, val1, res01); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = arm_nn_read_q7x4((const q7_t *)&rhs_ptr[off0]); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val3 = __SXTB16(val0); + val5 = __SXTB16(val2); + val4 = __SXTB16(val1); + val0 = __patched_SXTB16_RORn(val0, 8); + val2 = __patched_SXTB16_RORn(val2, 8); + val1 = __patched_SXTB16_RORn(val1, 8); + + // 4 x MAC res00, res01 + res00 = __SMLAD(val5, val3, res00); + res00 = __SMLAD(val2, val0, res00); + res01 = __SMLAD(val5, val4, res01); + res01 = __SMLAD(val2, val1, res01); + } + + // Left-over accumulations + for (; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q7_t rhs_value0 = rhs_ptr[0]; + q7_t rhs_value1 = rhs_ptr[rhs_cols]; + q7_t lhs_value = lhs_ptr[0]; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res01 = arm_nn_requantize(res01, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr[1] = (q7_t)res01; + } + + rhs += 2 * rhs_cols; + dst += 2; + } + + if (rhs_rows % 2) + { + const q7_t *lhs_ptr = &lhs[0]; + q7_t *dst_ptr = &dst[0]; + + for (int32_t lhs_rows_idx = 0; lhs_rows_idx < lhs_rows; ++lhs_rows_idx) + { + const q7_t *rhs_ptr = &rhs[0]; + q31_t res00 = bias[rhs_rows - 1]; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value = rhs_ptr[0]; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows - 1], dst_shifts[rhs_rows - 1]); + + // Add offset + res00 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr += rhs_rows; + } + } +#else + for (int32_t rhs_rows_idx = 0; rhs_rows_idx <= (rhs_rows - 2); rhs_rows_idx += 2) + { + const q7_t *lhs_ptr = &lhs[0]; + q7_t *dst_ptr = &dst[0]; + + q31_t lhs_offset_contribution0 = 0; + q31_t lhs_offset_contribution1 = 0; + + for (int32_t x = 0; x < rhs_cols; ++x) + { + lhs_offset_contribution0 += rhs[x]; + lhs_offset_contribution1 += rhs[x + rhs_cols]; + } + + lhs_offset_contribution0 *= lhs_offset; + lhs_offset_contribution1 *= lhs_offset; + + lhs_offset_contribution0 += bias[rhs_rows_idx]; + lhs_offset_contribution1 += bias[rhs_rows_idx + 1]; + + int32_t lhs_rows_idx = lhs_rows >> 1; + + while (lhs_rows_idx) + { + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = lhs_offset_contribution0; + q31_t res01 = lhs_offset_contribution1; + q31_t res10 = lhs_offset_contribution0; + q31_t res11 = lhs_offset_contribution1; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q7_t rhs_value0 = rhs_ptr[0]; + q7_t rhs_value1 = rhs_ptr[rhs_cols]; + q7_t lhs_value = lhs_ptr[0]; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + lhs_value = lhs_ptr[rhs_cols]; + res10 += lhs_value * rhs_value0; + res11 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res01 = arm_nn_requantize(res01, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + res10 = arm_nn_requantize(res10, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res11 = arm_nn_requantize(res11, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + res10 += dst_offset; + res11 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + res10 = MAX(res10, activation_min); + res10 = MIN(res10, activation_max); + res11 = MAX(res11, activation_min); + res11 = MIN(res11, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr[1] = (q7_t)res01; + dst_ptr += rhs_rows; + dst_ptr[0] = (q7_t)res10; + dst_ptr[1] = (q7_t)res11; + dst_ptr += rhs_rows; + + lhs_ptr += rhs_cols; + + lhs_rows_idx--; + } + + // Left-over rows + if (lhs_rows % 2) + { + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = lhs_offset_contribution0; + q31_t res01 = lhs_offset_contribution1; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q7_t rhs_value0 = rhs_ptr[0]; + q7_t rhs_value1 = rhs_ptr[rhs_cols]; + q7_t lhs_value = lhs_ptr[0]; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows_idx], dst_shifts[rhs_rows_idx]); + res01 = arm_nn_requantize(res01, dst_multipliers[rhs_rows_idx + 1], dst_shifts[rhs_rows_idx + 1]); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr[1] = (q7_t)res01; + } + + rhs += 2 * rhs_cols; + dst += 2; + } + + if (rhs_rows % 2) + { + const q7_t *lhs_ptr = &lhs[0]; + q7_t *dst_ptr = &dst[0]; + + for (int32_t lhs_rows_idx = 0; lhs_rows_idx < lhs_rows; ++lhs_rows_idx) + { + const q7_t *rhs_ptr = &rhs[0]; + q31_t res00 = bias[rhs_rows - 1]; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value = rhs_ptr[0]; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multipliers[rhs_rows - 1], dst_shifts[rhs_rows - 1]); + + // Add offset + res00 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + + dst_ptr[0] = (q7_t)res00; + dst_ptr += rhs_rows; + } + } +#endif + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c new file mode 100644 index 0000000..d84bc18 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mult_q15.c + * Description: Q15 vector multiplication with variable output shifts + * + * $Date: 29. April 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated. + */ + +void arm_nn_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) +{ + uint32_t blkCnt; /* loop counters */ + +#if defined (ARM_MATH_DSP) + +/* Run the below code for Cortex-M4 and Cortex-M3 */ + q31_t inA1, inA2, inB1, inB2; /* temporary input variables */ + q15_t out1, out2, out3, out4; /* temporary output variables */ + q31_t mul1, mul2, mul3, mul4; /* temporary variables */ + + /* loop Unrolling */ + blkCnt = blockSize >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0U) + { + /* read two samples at a time from sourceA */ + inA1 = arm_nn_read_q15x2_ia((const q15_t **)&pSrcA); + /* read two samples at a time from sourceB */ + inB1 = arm_nn_read_q15x2_ia((const q15_t **)&pSrcB); + /* read two samples at a time from sourceA */ + inA2 = arm_nn_read_q15x2_ia((const q15_t **)&pSrcA); + /* read two samples at a time from sourceB */ + inB2 = arm_nn_read_q15x2_ia((const q15_t **)&pSrcB); + + /* multiply mul = sourceA * sourceB */ + mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16)); + mul2 = (q31_t) ((q15_t) inA1 * (q15_t) inB1); + mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16)); + mul4 = (q31_t) ((q15_t) inA2 * (q15_t) inB2); + + /* saturate result to 16 bit */ + out1 = (q15_t) __SSAT((q31_t) (mul1 + NN_ROUND(out_shift)) >> out_shift, 16); + out2 = (q15_t) __SSAT((q31_t) (mul2 + NN_ROUND(out_shift)) >> out_shift, 16); + out3 = (q15_t) __SSAT((q31_t) (mul3 + NN_ROUND(out_shift)) >> out_shift, 16); + out4 = (q15_t) __SSAT((q31_t) (mul4 + NN_ROUND(out_shift)) >> out_shift, 16); + + /* store the result */ +#ifndef ARM_MATH_BIG_ENDIAN + + *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16); + *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16); + +#else + + *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16); + *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16); + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement the blockSize loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4U; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_DSP) */ + + + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the result in the destination buffer */ + *pDst++ = (q15_t) __SSAT(((q31_t) ((q31_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 16); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c new file mode 100644 index 0000000..d99c42a --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mult_q7.c + * Description: Q7 vector multiplication with variable output shifts + * + * $Date: 29. April 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated. + */ + +void arm_nn_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) +{ + uint32_t blkCnt; /* loop counters */ + +#if defined (ARM_MATH_DSP) + +/* Run the below code for Cortex-M4 and Cortex-M3 */ + q7_t out1, out2, out3, out4; /* Temporary variables to store the product */ + + /* loop Unrolling */ + blkCnt = blockSize >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the results in temporary variables */ + out1 = (q7_t) __SSAT(((q15_t) ((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out2 = (q7_t) __SSAT(((q15_t) ((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out3 = (q7_t) __SSAT(((q15_t) ((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out4 = (q7_t) __SSAT(((q15_t) ((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + + /* Store the results of 4 inputs in the destination buffer in single cycle by packing */ + *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4U; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_DSP) */ + + + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the result in the destination buffer */ + *pDst++ = (q7_t) __SSAT(((q15_t) ((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_vec_mat_mult_t_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_vec_mat_mult_t_s8.c new file mode 100644 index 0000000..2551b18 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nn_vec_mat_mult_t_s8.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_vec_mat_mult_t_s8 + * Description: s8 vector by matrix (transposed) multiplication + * + * $Date: April 2, 2020 + * $Revision: V.1.5.0 + * + * Target Processor: Cortex-M + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/* + * s8 vector(lhs) by matrix (transposed) multiplication + * + * Refer header file for details. + * + */ +arm_status arm_nn_vec_mat_mult_t_s8(const q7_t *lhs, + const q7_t *rhs, + const q31_t *bias, + q7_t *dst, + const int32_t lhs_offset, + const int32_t rhs_offset, + const int32_t dst_offset, + const int32_t dst_multiplier, + const int32_t dst_shift, + const int32_t rhs_cols, + const int32_t rhs_rows, + const int32_t activation_min, + const int32_t activation_max) +{ +#if defined(ARM_MATH_MVEI) + + const int16x8_t rhs_offset_vec = vdupq_n_s16((int16_t)rhs_offset); + const int16x8_t lhs_offset_vec = vdupq_n_s16((int16_t)lhs_offset); + + int32_t row_loop_cnt = rhs_rows / 4; + + for (int i_row_loop_cnt = 0; i_row_loop_cnt < row_loop_cnt; i_row_loop_cnt++) + { + int32_t acc1 = bias[0]; + int32_t acc2 = bias[1]; + int32_t acc3 = bias[2]; + int32_t acc4 = bias[3]; + bias += 4; + + int32x4_t acc; + const int32_t col_loop_cnt = (rhs_cols + 7) / 8; + + const int8_t *vec = lhs; + const int8_t *rhs_0 = rhs; + const int8_t *rhs_1 = rhs + rhs_cols; + const int8_t *rhs_2 = rhs + 2 * rhs_cols; + const int8_t *rhs_3 = rhs + 3 * rhs_cols; + + uint32_t col_cnt = (uint32_t)rhs_cols; + + for (int i = 0; i < col_loop_cnt; i++) + { + mve_pred16_t p = vctp16q(col_cnt); + col_cnt -= 8; + const int16x8_t tmp_b = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(vec, p), lhs_offset_vec, p); + + const int16x8_t tmp_a0 = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(rhs_0, p), rhs_offset_vec, p); + acc1 = vmladavaq_p_s16(acc1, tmp_a0, tmp_b, p); + + const int16x8_t tmp_a1 = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(rhs_1, p), rhs_offset_vec, p); + acc2 = vmladavaq_p_s16(acc2, tmp_a1, tmp_b, p); + + const int16x8_t tmp_a2 = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(rhs_2, p), rhs_offset_vec, p); + acc3 = vmladavaq_p_s16(acc3, tmp_a2, tmp_b, p); + + const int16x8_t tmp_a3 = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(rhs_3, p), rhs_offset_vec, p); + acc4 = vmladavaq_p_s16(acc4, tmp_a3, tmp_b, p); + + vec += 8; + rhs_0 += 8; + rhs_1 += 8; + rhs_2 += 8; + rhs_3 += 8; + } + rhs += 4 * rhs_cols; + + acc[0] = acc1; + acc[1] = acc2; + acc[2] = acc3; + acc[3] = acc4; + + acc = arm_requantize_mve(acc, dst_multiplier, dst_shift); + acc = vaddq_s32(acc, vdupq_n_s32(dst_offset)); + acc = vmaxq_s32(acc, vdupq_n_s32(activation_min)); + acc = vminq_s32(acc, vdupq_n_s32(activation_max)); + + vstrbq_s32(dst, acc); + dst += 4; + } + + row_loop_cnt = rhs_rows & 3; + + for (int i_row_loop_cnt = 0; i_row_loop_cnt < row_loop_cnt; + i_row_loop_cnt++) + { + int32_t acc = *bias++; + const int32_t col_loop_cnt = (rhs_cols + 7) / 8; + const int8_t *vec = lhs; + const int8_t *kernel_cur = rhs; + + uint32_t col_cnt = (uint32_t)rhs_cols; + + for (int i = 0; i < col_loop_cnt; i++) + { + mve_pred16_t p = vctp16q(col_cnt); + col_cnt -= 8; + const int16x8_t tmp_b = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(vec, p), lhs_offset_vec, p); + + const int16x8_t tmp_a = vaddq_m_s16(vuninitializedq_s16(), + vldrbq_z_s16(kernel_cur, p), rhs_offset_vec, p); + acc = vmladavaq_p_s16(acc, tmp_a, tmp_b, p); + vec += 8; + kernel_cur += 8; + } + rhs += rhs_cols; + + acc = arm_nn_requantize(acc, dst_multiplier, dst_shift); + acc += dst_offset; + + acc = MAX(acc, activation_min); + acc = MIN(acc, activation_max); + *dst++ = (int8_t)(acc); + } + +#elif defined(ARM_MATH_DSP) + const int32_t off0 = rhs_cols - 4; + const int16_t lhs_offset_s16 = lhs_offset; + const int16_t rhs_offset_s16 = rhs_offset; + + const uint32_t lhs_offset_s16x2 = __PKHBT(lhs_offset_s16, lhs_offset_s16, 16); + const uint32_t rhs_offset_s16x2 = __PKHBT(rhs_offset_s16, rhs_offset_s16, 16); + + for (int32_t rhs_rows_idx = 0; rhs_rows_idx <= (rhs_rows - 2); rhs_rows_idx += 2) + { + const q7_t *lhs_ptr = &lhs[0]; + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = *bias++; + q31_t res01 = *bias++; + + int32_t rhs_cols_idx = 0; + + q31_t val0, val1, val2, val3, val4, val5; + for (; rhs_cols_idx <= (rhs_cols - 16); rhs_cols_idx += 16) + { + // Read 4 x int8 values from the RHS matrix + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val2 = __SXTAB16(rhs_offset_s16x2, val0); + // Read 4 x int8 values from the LHS vector + val1 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val1); + // Read 4 x int8 values from the RHS matrix + val4 = arm_nn_read_q7x4((const q7_t *)rhs_ptr + off0); + val1 = __SXTAB16(lhs_offset_s16x2, __ROR(val1, 8)); + + // Perform the accumulations + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTAB16(rhs_offset_s16x2, val4); + res00 = __SMLAD(val1, val0, res00); + val4 = __SXTAB16(rhs_offset_s16x2, __ROR(val4, 8)); + // Read 4 x int8 values from the RHS matrix + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val1, val4, res01); + + val2 = __SXTAB16(rhs_offset_s16x2, val0); + // Read 4 x int8 values from the LHS vector + val1 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val1); + // Read 4 x int8 values from the RHS matrix + val4 = arm_nn_read_q7x4((const q7_t *)rhs_ptr + off0); + val1 = __SXTAB16(lhs_offset_s16x2, __ROR(val1, 8)); + + // Perform the accumulations + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTAB16(rhs_offset_s16x2, val4); + res00 = __SMLAD(val1, val0, res00); + val4 = __SXTAB16(rhs_offset_s16x2, __ROR(val4, 8)); + // Read 4 x int8 values from the RHS matrix + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val1, val4, res01); + + val2 = __SXTAB16(rhs_offset_s16x2, val0); + // Read 4 x int8 values from the LHS vector + val1 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val1); + // Read 4 x int8 values from the RHS matrix + val4 = arm_nn_read_q7x4((const q7_t *)rhs_ptr + off0); + val1 = __SXTAB16(lhs_offset_s16x2, __ROR(val1, 8)); + + // Perform the accumulations + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTAB16(rhs_offset_s16x2, val4); + res00 = __SMLAD(val1, val0, res00); + val4 = __SXTAB16(rhs_offset_s16x2, __ROR(val4, 8)); + // Read 4 x int8 values from the RHS matrix + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val1, val4, res01); + + val2 = __SXTAB16(rhs_offset_s16x2, val0); + // Read 4 x int8 values from the LHS vector + val1 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val1); + // Read 4 x int8 values from the RHS matrix + val4 = arm_nn_read_q7x4((const q7_t *)rhs_ptr + off0); + val1 = __SXTAB16(lhs_offset_s16x2, __ROR(val1, 8)); + + // Perform the accumulations + res00 = __SMLAD(val3, val2, res00); + val5 = __SXTAB16(rhs_offset_s16x2, val4); + res00 = __SMLAD(val1, val0, res00); + val4 = __SXTAB16(rhs_offset_s16x2, __ROR(val4, 8)); + res01 = __SMLAD(val3, val5, res01); + res01 = __SMLAD(val1, val4, res01); + } + + for (; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value0 = rhs_ptr[0] + rhs_offset; + q31_t rhs_value1 = rhs_ptr[rhs_cols] + rhs_offset; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multiplier, dst_shift); + res01 = arm_nn_requantize(res01, dst_multiplier, dst_shift); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + + *dst++ = (q7_t)res00; + *dst++ = (q7_t)res01; + + rhs += 2 * rhs_cols; + } + + if (rhs_rows % 2) + { + const q7_t *lhs_ptr = &lhs[0]; + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = *bias++; + + int32_t rhs_cols_idx = 0; + + q31_t val0, val1, val2, val3; + for (; rhs_cols_idx <= (rhs_cols - 16); rhs_cols_idx += 16) + { + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = __SXTAB16(rhs_offset_s16x2, val0); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val2); + val2 = __SXTAB16(lhs_offset_s16x2, __ROR(val2, 8)); + + // Partial accumulations + res00 = __SMLAD(val3, val1, res00); + res00 = __SMLAD(val2, val0, res00); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = __SXTAB16(rhs_offset_s16x2, val0); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val2); + val2 = __SXTAB16(lhs_offset_s16x2, __ROR(val2, 8)); + + // Partial accumulations + res00 = __SMLAD(val3, val1, res00); + res00 = __SMLAD(val2, val0, res00); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = __SXTAB16(rhs_offset_s16x2, val0); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val2); + val2 = __SXTAB16(lhs_offset_s16x2, __ROR(val2, 8)); + + // Partial accumulations + res00 = __SMLAD(val3, val1, res00); + res00 = __SMLAD(val2, val0, res00); + + val0 = arm_nn_read_q7x4_ia((const q7_t **)&rhs_ptr); + val1 = __SXTAB16(rhs_offset_s16x2, val0); + val2 = arm_nn_read_q7x4_ia((const q7_t **)&lhs_ptr); + val0 = __SXTAB16(rhs_offset_s16x2, __ROR(val0, 8)); + val3 = __SXTAB16(lhs_offset_s16x2, val2); + val2 = __SXTAB16(lhs_offset_s16x2, __ROR(val2, 8)); + + // Partial accumulations + res00 = __SMLAD(val3, val1, res00); + res00 = __SMLAD(val2, val0, res00); + } + + for (; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value0 = rhs_ptr[0] + rhs_offset; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value0; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multiplier, dst_shift); + + // Add offset + res00 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + + *dst = (q7_t)res00; + } + +#else + + for (int32_t rhs_rows_idx = 0; rhs_rows_idx <= (rhs_rows - 2); rhs_rows_idx += 2) + { + const q7_t *lhs_ptr = &lhs[0]; + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = *bias++; + q31_t res01 = *bias++; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value0 = rhs_ptr[0] + rhs_offset; + q31_t rhs_value1 = rhs_ptr[rhs_cols] + rhs_offset; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value0; + res01 += lhs_value * rhs_value1; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multiplier, dst_shift); + res01 = arm_nn_requantize(res01, dst_multiplier, dst_shift); + + // Add offset + res00 += dst_offset; + res01 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + res01 = MAX(res01, activation_min); + res01 = MIN(res01, activation_max); + + *dst++ = (q7_t)res00; + *dst++ = (q7_t)res01; + + rhs += 2 * rhs_cols; + } + + if (rhs_rows % 2) + { + const q7_t *lhs_ptr = &lhs[0]; + const q7_t *rhs_ptr = &rhs[0]; + + q31_t res00 = *bias++; + + for (int32_t rhs_cols_idx = 0; rhs_cols_idx < rhs_cols; ++rhs_cols_idx) + { + q31_t rhs_value0 = rhs_ptr[0] + rhs_offset; + q31_t lhs_value = lhs_ptr[0] + lhs_offset; + + res00 += lhs_value * rhs_value0; + + ++rhs_ptr; + ++lhs_ptr; + } + + // Quantize down + res00 = arm_nn_requantize(res00, dst_multiplier, dst_shift); + + // Add offset + res00 += dst_offset; + + // Clamp the result + res00 = MAX(res00, activation_min); + res00 = MIN(res00, activation_max); + + *dst = (q7_t)res00; + } +#endif + + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNBasicMath group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c new file mode 100644 index 0000000..57f97f6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nntables.c + * Description: Converts the elements of the Q7 vector to Q15 vector without left-shift + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @brief tables for various activation functions + * + * This file include the declaration of common tables. + * Most of them are used for activation functions + * + * Assumption: + * Unified table: input is 3.x format, i.e, range of [-8, 8) + * sigmoid(8) = 0.9996646498695336 + * tanh(8) = 0.9999997749296758 + * The accuracy here should be good enough + * + * 2-stage HL table: + * + * The entire input range is divided into two parts: + * + * Low range table: 0x000x xxxx or 0x111x xxxx + * table entry will be the binary number excluding the first + * two digits, i.e., 0x0x xxxx or 0x1x xxxx + * + * + * + * High range table 0x0010 0000 -- 0x0111 1111 + * 0x1000 0000 -- 0x1101 1111 + * + * For positive numbers, table entry will be + * 0x0010 0000 -- 0x0111 1111 minus 0x0010 0000 + * i.e., 0x0000 0000 - 0x0101 11111 + * + * same thing for the negative numbers, table entry will be + * 0x1000 0000 -- 0x1101 1111 minux 0x0010 0000 + * i.e., 0x0110 0000 - 0x1011 1111 + */ + +const q7_t sigmoidTable_q7[256] = { + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, + 0x50, 0x52, 0x53, 0x55, 0x57, 0x59, 0x5a, 0x5c, + 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x65, 0x66, 0x67, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x75, 0x76, + 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, + 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, + 0x0a, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x19, 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x21, + 0x22, 0x24, 0x26, 0x27, 0x29, 0x2b, 0x2d, 0x2e, + 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, +}; + +const q15_t sigmoidTable_q15[256] = { + 0x4000, 0x4200, 0x43ff, 0x45fc, 0x47f5, 0x49eb, 0x4bdc, 0x4dc8, + 0x4fad, 0x518a, 0x5360, 0x552c, 0x56ef, 0x58a8, 0x5a57, 0x5bfb, + 0x5d93, 0x5f20, 0x60a1, 0x6216, 0x637f, 0x64db, 0x662b, 0x676f, + 0x68a6, 0x69d2, 0x6af1, 0x6c05, 0x6d0d, 0x6e09, 0x6efb, 0x6fe2, + 0x70be, 0x7190, 0x7258, 0x7316, 0x73cc, 0x7478, 0x751b, 0x75b7, + 0x764a, 0x76d6, 0x775b, 0x77d8, 0x784f, 0x78c0, 0x792a, 0x798f, + 0x79ee, 0x7a48, 0x7a9d, 0x7aed, 0x7b39, 0x7b80, 0x7bc4, 0x7c03, + 0x7c3f, 0x7c78, 0x7cad, 0x7ce0, 0x7d0f, 0x7d3c, 0x7d66, 0x7d8d, + 0x7db3, 0x7dd6, 0x7df7, 0x7e16, 0x7e33, 0x7e4f, 0x7e69, 0x7e81, + 0x7e98, 0x7eae, 0x7ec2, 0x7ed5, 0x7ee7, 0x7ef8, 0x7f08, 0x7f17, + 0x7f25, 0x7f32, 0x7f3e, 0x7f4a, 0x7f55, 0x7f5f, 0x7f69, 0x7f72, + 0x7f7b, 0x7f83, 0x7f8a, 0x7f91, 0x7f98, 0x7f9e, 0x7fa4, 0x7faa, + 0x7faf, 0x7fb4, 0x7fb8, 0x7fbd, 0x7fc1, 0x7fc5, 0x7fc8, 0x7fcc, + 0x7fcf, 0x7fd2, 0x7fd5, 0x7fd7, 0x7fda, 0x7fdc, 0x7fde, 0x7fe0, + 0x7fe2, 0x7fe4, 0x7fe6, 0x7fe7, 0x7fe9, 0x7fea, 0x7feb, 0x7fed, + 0x7fee, 0x7fef, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff4, + 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0015, 0x0016, 0x0017, 0x0019, 0x001a, 0x001c, + 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002b, 0x002e, + 0x0031, 0x0034, 0x0038, 0x003b, 0x003f, 0x0043, 0x0048, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0068, 0x006f, 0x0076, 0x007d, + 0x0085, 0x008e, 0x0097, 0x00a1, 0x00ab, 0x00b6, 0x00c2, 0x00ce, + 0x00db, 0x00e9, 0x00f8, 0x0108, 0x0119, 0x012b, 0x013e, 0x0152, + 0x0168, 0x017f, 0x0197, 0x01b1, 0x01cd, 0x01ea, 0x0209, 0x022a, + 0x024d, 0x0273, 0x029a, 0x02c4, 0x02f1, 0x0320, 0x0353, 0x0388, + 0x03c1, 0x03fd, 0x043c, 0x0480, 0x04c7, 0x0513, 0x0563, 0x05b8, + 0x0612, 0x0671, 0x06d6, 0x0740, 0x07b1, 0x0828, 0x08a5, 0x092a, + 0x09b6, 0x0a49, 0x0ae5, 0x0b88, 0x0c34, 0x0cea, 0x0da8, 0x0e70, + 0x0f42, 0x101e, 0x1105, 0x11f7, 0x12f3, 0x13fb, 0x150f, 0x162e, + 0x175a, 0x1891, 0x19d5, 0x1b25, 0x1c81, 0x1dea, 0x1f5f, 0x20e0, + 0x226d, 0x2405, 0x25a9, 0x2758, 0x2911, 0x2ad4, 0x2ca0, 0x2e76, + 0x3053, 0x3238, 0x3424, 0x3615, 0x380b, 0x3a04, 0x3c01, 0x3e00, +}; + +const q15_t sigmoidLTable_q15[128] = { + 0x4000, 0x4100, 0x4200, 0x42ff, 0x43ff, 0x44fd, 0x45fc, 0x46f9, + 0x47f5, 0x48f1, 0x49eb, 0x4ae5, 0x4bdc, 0x4cd3, 0x4dc8, 0x4ebb, + 0x4fad, 0x509c, 0x518a, 0x5276, 0x5360, 0x5447, 0x552c, 0x560f, + 0x56ef, 0x57cd, 0x58a8, 0x5981, 0x5a57, 0x5b2a, 0x5bfb, 0x5cc9, + 0x5d93, 0x5e5b, 0x5f20, 0x5fe2, 0x60a1, 0x615d, 0x6216, 0x62cc, + 0x637f, 0x642e, 0x64db, 0x6584, 0x662b, 0x66ce, 0x676f, 0x680c, + 0x68a6, 0x693d, 0x69d2, 0x6a63, 0x6af1, 0x6b7c, 0x6c05, 0x6c8a, + 0x6d0d, 0x6d8d, 0x6e09, 0x6e84, 0x6efb, 0x6f70, 0x6fe2, 0x7051, + 0x0f42, 0x0faf, 0x101e, 0x1090, 0x1105, 0x117c, 0x11f7, 0x1273, + 0x12f3, 0x1376, 0x13fb, 0x1484, 0x150f, 0x159d, 0x162e, 0x16c3, + 0x175a, 0x17f4, 0x1891, 0x1932, 0x19d5, 0x1a7c, 0x1b25, 0x1bd2, + 0x1c81, 0x1d34, 0x1dea, 0x1ea3, 0x1f5f, 0x201e, 0x20e0, 0x21a5, + 0x226d, 0x2337, 0x2405, 0x24d6, 0x25a9, 0x267f, 0x2758, 0x2833, + 0x2911, 0x29f1, 0x2ad4, 0x2bb9, 0x2ca0, 0x2d8a, 0x2e76, 0x2f64, + 0x3053, 0x3145, 0x3238, 0x332d, 0x3424, 0x351b, 0x3615, 0x370f, + 0x380b, 0x3907, 0x3a04, 0x3b03, 0x3c01, 0x3d01, 0x3e00, 0x3f00, +}; + +const q15_t sigmoidHTable_q15[192] = { + 0x70be, 0x7190, 0x7258, 0x7316, 0x73cc, 0x7478, 0x751b, 0x75b7, + 0x764a, 0x76d6, 0x775b, 0x77d8, 0x784f, 0x78c0, 0x792a, 0x798f, + 0x79ee, 0x7a48, 0x7a9d, 0x7aed, 0x7b39, 0x7b80, 0x7bc4, 0x7c03, + 0x7c3f, 0x7c78, 0x7cad, 0x7ce0, 0x7d0f, 0x7d3c, 0x7d66, 0x7d8d, + 0x7db3, 0x7dd6, 0x7df7, 0x7e16, 0x7e33, 0x7e4f, 0x7e69, 0x7e81, + 0x7e98, 0x7eae, 0x7ec2, 0x7ed5, 0x7ee7, 0x7ef8, 0x7f08, 0x7f17, + 0x7f25, 0x7f32, 0x7f3e, 0x7f4a, 0x7f55, 0x7f5f, 0x7f69, 0x7f72, + 0x7f7b, 0x7f83, 0x7f8a, 0x7f91, 0x7f98, 0x7f9e, 0x7fa4, 0x7faa, + 0x7faf, 0x7fb4, 0x7fb8, 0x7fbd, 0x7fc1, 0x7fc5, 0x7fc8, 0x7fcc, + 0x7fcf, 0x7fd2, 0x7fd5, 0x7fd7, 0x7fda, 0x7fdc, 0x7fde, 0x7fe0, + 0x7fe2, 0x7fe4, 0x7fe6, 0x7fe7, 0x7fe9, 0x7fea, 0x7feb, 0x7fed, + 0x7fee, 0x7fef, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff4, + 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0015, 0x0016, 0x0017, 0x0019, 0x001a, 0x001c, + 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002b, 0x002e, + 0x0031, 0x0034, 0x0038, 0x003b, 0x003f, 0x0043, 0x0048, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0068, 0x006f, 0x0076, 0x007d, + 0x0085, 0x008e, 0x0097, 0x00a1, 0x00ab, 0x00b6, 0x00c2, 0x00ce, + 0x00db, 0x00e9, 0x00f8, 0x0108, 0x0119, 0x012b, 0x013e, 0x0152, + 0x0168, 0x017f, 0x0197, 0x01b1, 0x01cd, 0x01ea, 0x0209, 0x022a, + 0x024d, 0x0273, 0x029a, 0x02c4, 0x02f1, 0x0320, 0x0353, 0x0388, + 0x03c1, 0x03fd, 0x043c, 0x0480, 0x04c7, 0x0513, 0x0563, 0x05b8, + 0x0612, 0x0671, 0x06d6, 0x0740, 0x07b1, 0x0828, 0x08a5, 0x092a, + 0x09b6, 0x0a49, 0x0ae5, 0x0b88, 0x0c34, 0x0cea, 0x0da8, 0x0e70, +}; + +const q7_t tanhTable_q7[256] = { + 0x00, 0x08, 0x10, 0x18, 0x1f, 0x27, 0x2e, 0x35, + 0x3b, 0x41, 0x47, 0x4c, 0x51, 0x56, 0x5a, 0x5e, + 0x61, 0x65, 0x68, 0x6a, 0x6d, 0x6f, 0x71, 0x72, + 0x74, 0x75, 0x76, 0x78, 0x78, 0x79, 0x7a, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x84, 0x84, + 0x85, 0x85, 0x86, 0x87, 0x88, 0x88, 0x8a, 0x8b, + 0x8c, 0x8e, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9b, + 0x9f, 0xa2, 0xa6, 0xaa, 0xaf, 0xb4, 0xb9, 0xbf, + 0xc5, 0xcb, 0xd2, 0xd9, 0xe1, 0xe8, 0xf0, 0xf8, +}; + +const q15_t tanhTable_q15[256] = { + 0x0000, 0x07fd, 0x0feb, 0x17b9, 0x1f59, 0x26bf, 0x2ddf, 0x34ae, + 0x3b27, 0x4142, 0x46fd, 0x4c56, 0x514d, 0x55e2, 0x5a1a, 0x5df6, + 0x617c, 0x64b0, 0x6797, 0x6a37, 0x6c95, 0x6eb5, 0x709e, 0x7254, + 0x73dc, 0x753a, 0x7672, 0x7788, 0x787f, 0x795b, 0x7a1e, 0x7acb, + 0x7b65, 0x7bee, 0x7c66, 0x7cd1, 0x7d30, 0x7d84, 0x7dce, 0x7e0f, + 0x7e49, 0x7e7d, 0x7eaa, 0x7ed2, 0x7ef5, 0x7f14, 0x7f30, 0x7f48, + 0x7f5e, 0x7f71, 0x7f82, 0x7f91, 0x7f9e, 0x7fa9, 0x7fb3, 0x7fbc, + 0x7fc4, 0x7fcb, 0x7fd1, 0x7fd7, 0x7fdc, 0x7fe0, 0x7fe4, 0x7fe7, + 0x7fea, 0x7fed, 0x7fef, 0x7ff1, 0x7ff3, 0x7ff4, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffc, 0x7ffd, + 0x7ffd, 0x7ffd, 0x7ffe, 0x7ffe, 0x7ffe, 0x7ffe, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8002, 0x8002, 0x8002, 0x8002, 0x8003, + 0x8003, 0x8003, 0x8004, 0x8004, 0x8005, 0x8006, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800c, 0x800d, 0x800f, 0x8011, 0x8013, + 0x8016, 0x8019, 0x801c, 0x8020, 0x8024, 0x8029, 0x802f, 0x8035, + 0x803c, 0x8044, 0x804d, 0x8057, 0x8062, 0x806f, 0x807e, 0x808f, + 0x80a2, 0x80b8, 0x80d0, 0x80ec, 0x810b, 0x812e, 0x8156, 0x8183, + 0x81b7, 0x81f1, 0x8232, 0x827c, 0x82d0, 0x832f, 0x839a, 0x8412, + 0x849b, 0x8535, 0x85e2, 0x86a5, 0x8781, 0x8878, 0x898e, 0x8ac6, + 0x8c24, 0x8dac, 0x8f62, 0x914b, 0x936b, 0x95c9, 0x9869, 0x9b50, + 0x9e84, 0xa20a, 0xa5e6, 0xaa1e, 0xaeb3, 0xb3aa, 0xb903, 0xbebe, + 0xc4d9, 0xcb52, 0xd221, 0xd941, 0xe0a7, 0xe847, 0xf015, 0xf803, +}; + +const q15_t tanhLTable_q15[128] = { + 0x0000, 0x0400, 0x07fd, 0x0bf7, 0x0feb, 0x13d7, 0x17b9, 0x1b90, + 0x1f59, 0x2314, 0x26bf, 0x2a58, 0x2ddf, 0x3151, 0x34ae, 0x37f6, + 0x3b27, 0x3e40, 0x4142, 0x442c, 0x46fd, 0x49b6, 0x4c56, 0x4edd, + 0x514d, 0x53a3, 0x55e2, 0x580a, 0x5a1a, 0x5c13, 0x5df6, 0x5fc4, + 0x617c, 0x6320, 0x64b0, 0x662d, 0x6797, 0x68f0, 0x6a37, 0x6b6e, + 0x6c95, 0x6dac, 0x6eb5, 0x6fb0, 0x709e, 0x717f, 0x7254, 0x731e, + 0x73dc, 0x7490, 0x753a, 0x75da, 0x7672, 0x7701, 0x7788, 0x7807, + 0x787f, 0x78f0, 0x795b, 0x79bf, 0x7a1e, 0x7a77, 0x7acb, 0x7b1b, + 0x849b, 0x84e5, 0x8535, 0x8589, 0x85e2, 0x8641, 0x86a5, 0x8710, + 0x8781, 0x87f9, 0x8878, 0x88ff, 0x898e, 0x8a26, 0x8ac6, 0x8b70, + 0x8c24, 0x8ce2, 0x8dac, 0x8e81, 0x8f62, 0x9050, 0x914b, 0x9254, + 0x936b, 0x9492, 0x95c9, 0x9710, 0x9869, 0x99d3, 0x9b50, 0x9ce0, + 0x9e84, 0xa03c, 0xa20a, 0xa3ed, 0xa5e6, 0xa7f6, 0xaa1e, 0xac5d, + 0xaeb3, 0xb123, 0xb3aa, 0xb64a, 0xb903, 0xbbd4, 0xbebe, 0xc1c0, + 0xc4d9, 0xc80a, 0xcb52, 0xceaf, 0xd221, 0xd5a8, 0xd941, 0xdcec, + 0xe0a7, 0xe470, 0xe847, 0xec29, 0xf015, 0xf409, 0xf803, 0xfc00, +}; + +const q15_t tanhHTable_q15[192] = { + 0x7b65, 0x7bee, 0x7c66, 0x7cd1, 0x7d30, 0x7d84, 0x7dce, 0x7e0f, + 0x7e49, 0x7e7d, 0x7eaa, 0x7ed2, 0x7ef5, 0x7f14, 0x7f30, 0x7f48, + 0x7f5e, 0x7f71, 0x7f82, 0x7f91, 0x7f9e, 0x7fa9, 0x7fb3, 0x7fbc, + 0x7fc4, 0x7fcb, 0x7fd1, 0x7fd7, 0x7fdc, 0x7fe0, 0x7fe4, 0x7fe7, + 0x7fea, 0x7fed, 0x7fef, 0x7ff1, 0x7ff3, 0x7ff4, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffc, 0x7ffd, + 0x7ffd, 0x7ffd, 0x7ffe, 0x7ffe, 0x7ffe, 0x7ffe, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8002, 0x8002, 0x8002, 0x8002, 0x8003, + 0x8003, 0x8003, 0x8004, 0x8004, 0x8005, 0x8006, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800c, 0x800d, 0x800f, 0x8011, 0x8013, + 0x8016, 0x8019, 0x801c, 0x8020, 0x8024, 0x8029, 0x802f, 0x8035, + 0x803c, 0x8044, 0x804d, 0x8057, 0x8062, 0x806f, 0x807e, 0x808f, + 0x80a2, 0x80b8, 0x80d0, 0x80ec, 0x810b, 0x812e, 0x8156, 0x8183, + 0x81b7, 0x81f1, 0x8232, 0x827c, 0x82d0, 0x832f, 0x839a, 0x8412, +}; diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c new file mode 100644 index 0000000..5cdac6c --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_no_shift.c + * Description: Converts the elements of the Q7 vector to Q15 vector without left-shift + * + * $Date: May 29, 2020 + * $Revision: V.1.0.2 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +/** + * @brief Converts the elements of the Q7 vector to Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * + * \par Description: + * + * The equation used for the conversion process is: + * + *
+ * 	pDst[n] = (q15_t) pSrc[n];   0 <= n < blockSize.
+ * 
+ * + */ + +void arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize) +{ + const q7_t *pIn = pSrc; + uint32_t blkCnt; + +#if defined(ARM_MATH_DSP) + q31_t in; + q31_t in1, in2; + q31_t out1, out2; + + /*loop Unrolling */ + blkCnt = blockSize >> 2u; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. */ + while (blkCnt > 0u) + { + in = arm_nn_read_q7x4_ia(&pIn); + + /* rotatate in by 8 and extend two q7_t values to q15_t values */ + in1 = __SXTB16(__ROR((uint32_t)in, 8)); + + /* extend remaining two q7_t values to q15_t values */ + in2 = __SXTB16(in); + +#ifndef ARM_MATH_BIG_ENDIAN + out2 = (int32_t)__PKHTB(in1, in2, 16); + out1 = (int32_t)__PKHBT(in2, in1, 16); +#else + out1 = (int32_t)__PKHTB(in1, in2, 16); + out2 = (int32_t)__PKHBT(in2, in1, 16); +#endif + write_q15x2_ia(&pDst, out1); + write_q15x2_ia(&pDst, out2); + + /* Decrement the loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4u; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Loop over blockSize number of values */ + blkCnt = blockSize; + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + + while (blkCnt > 0u) + { + /* convert from q7 to q15 and then store the results in the destination buffer */ + *pDst++ = (q15_t)*pIn++; + + /* Decrement the loop counter */ + blkCnt--; + } + +} + +/** + * @} end of nndata_convert group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c new file mode 100644 index 0000000..8128aaa --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_reordered_no_shift.c + * Description: Converts the elements of the Q7 vector to reordered Q15 vector without left-shift + * + * $Date: May 29, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +/** + * @brief Converts the elements of the Q7 vector to reordered Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * + * @details + * + * This function does the q7 to q15 expansion with re-ordering + * + *
+ *                          |   A1   |   A2   |   A3   |   A4   |
+ *
+ *                           0      7 8     15 16    23 24    31
+ * 
+ * + * is converted into: + * + *
+ *  |       A1       |       A3       |   and  |       A2       |       A4       |
+ *
+ *   0             15 16            31          0             15 16            31
+ * 
+ * + * + * This looks strange but is natural considering how sign-extension is done at + * assembly level. + * + * The expansion of other other oprand will follow the same rule so that the end + * results are the same. + * + * The tail (i.e., last (N % 4) elements) will still be in original order. + * + */ + +void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize) +{ + const q7_t *pIn = pSrc; /* Src pointer */ + uint32_t blkCnt; /* loop counter */ + +#ifndef ARM_MATH_CM0_FAMILY + q31_t in; + q31_t in1, in2; + + /* Run the below code for Cortex-M4 and Cortex-M3 */ + + /*loop Unrolling */ + blkCnt = blockSize >> 2u; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + in = arm_nn_read_q7x4_ia(&pIn); + + /* rotatate in by 8 and extend two q7_t values to q15_t values */ + in1 = __SXTB16(__ROR((uint32_t)in, 8)); + + /* extend remainig two q7_t values to q15_t values */ + in2 = __SXTB16(in); + +#ifndef ARM_MATH_BIG_ENDIAN + *__SIMD32(pDst)++ = in2; + *__SIMD32(pDst)++ = in1; +#else + *__SIMD32(pDst)++ = in1; + *__SIMD32(pDst)++ = in2; +#endif + + /* Decrement the loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4u; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Loop over blockSize number of values */ + blkCnt = blockSize; + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + *pDst++ = (q15_t) * pIn++; + + /* Decrement the loop counter */ + blkCnt--; + } + +} + +/** + * @} end of q7_to_x group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_with_offset.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_with_offset.c new file mode 100644 index 0000000..34e13ca --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_with_offset.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_reordered_with_offset.c + * Description: Converts the elements of the Q7 vector to a reordered Q15 vector with an added offset. The re-ordering + * is a signature of sign extension intrinsic(DSP extension). + * + * $Date: May 29, 2020 + * $Revision: V.2.0.3 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +/** + * @brief Converts the elements of the Q7 vector to a reordered Q15 vector with an added offset. + * + * @note Refer header file for details. + * + */ + +void arm_q7_to_q15_reordered_with_offset(const q7_t *src, q15_t *dst, uint32_t block_size, q15_t offset) +{ + +#if defined(ARM_MATH_DSP) + uint32_t block_cnt; + /* Run the below code for cores that support SIMD instructions */ + q31_t in_q7x4; + q31_t out_q15x2_1; + q31_t out_q15x2_2; + + /*loop unrolling */ + block_cnt = block_size >> 2u; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. */ + const q31_t offset_q15x2 = (q31_t)__PKHBT(offset, offset, 16); + while (block_cnt > 0u) + { + /* convert from q7 to q15 and then store the results in the destination buffer */ + in_q7x4 = arm_nn_read_q7x4_ia(&src); + + /* Extract and sign extend each of the four q7 values to q15 */ + out_q15x2_1 = __SXTAB16(offset_q15x2, __ROR((uint32_t)in_q7x4, 8)); + out_q15x2_2 = __SXTAB16(offset_q15x2, in_q7x4); + + write_q15x2_ia(&dst, out_q15x2_2); + write_q15x2_ia(&dst, out_q15x2_1); + + block_cnt--; + } + /* Handle left over samples */ + block_cnt = block_size % 0x4u; + + while (block_cnt > 0u) + { + *dst++ = (q15_t)*src++ + offset; + + /* Decrement the loop counter */ + block_cnt--; + } +#else + (void)src; + (void)dst; + (void)block_size; + (void)offset; + /* Not available */ +#endif +} + +/** + * @} end of nndata_convert group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_with_offset.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_with_offset.c new file mode 100644 index 0000000..4b69f55 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_with_offset.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in_q7x4 compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in_q7x4 writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_with_offset.c + * Description: Converts the elements of the Q7 vector to Q15 vector with an added offset + * + * $Date: March 3, 2020 + * $Revision: V.2.0.2 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +void arm_q7_to_q15_with_offset(const q7_t *src, + q15_t *dst, + uint32_t block_size, + q15_t offset) +{ + int block_cnt; + +#if defined(ARM_MATH_MVEI) + + int16x8_t source; + const int16x8_t source_offset = vdupq_n_s16(offset); + block_cnt = block_size / 8; + + while (block_cnt > 0) + { + source = vldrbq_s16(src); + source = vaddq_s16(source, source_offset); + vstrhq_s16(dst, source); + dst += 8; + src += 8; + block_cnt--; + } + + block_cnt = block_size & 0x7; + +#elif defined(ARM_MATH_DSP) + /* Run the below code for cores that support SIMD instructions */ + q31_t in_q7x4; + q31_t in_q15x2_1; + q31_t in_q15x2_2; + q31_t out_q15x2_1; + q31_t out_q15x2_2; + + /*loop unrolling */ + block_cnt = block_size >> 2; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. */ + const q31_t offset_q15x2 = __PKHBT(offset, offset, 16); + while (block_cnt > 0) + { + /* convert from q7 to q15 and then store the results in the destination buffer */ + in_q7x4 = arm_nn_read_q7x4_ia(&src); + + /* Extract and sign extend each of the four q7 values to q15 */ + in_q15x2_1 = __SXTAB16(offset_q15x2, __ROR(in_q7x4, 8)); + in_q15x2_2 = __SXTAB16(offset_q15x2, in_q7x4); + + out_q15x2_2 = __PKHTB(in_q15x2_1, in_q15x2_2, 16); + out_q15x2_1 = __PKHBT(in_q15x2_2, in_q15x2_1, 16); + + write_q15x2_ia(&dst, out_q15x2_1); + write_q15x2_ia(&dst, out_q15x2_2); + + block_cnt--; + } + /* Handle left over samples */ + block_cnt = block_size % 0x4; + +#else + /* Run the below code for Cortex-M0 */ + /* Loop over block_size number of values */ + block_cnt = block_size; +#endif + + while (block_cnt > 0) + { + *dst++ = (q15_t)*src++ + offset; + + /* Decrement the loop counter */ + block_cnt--; + } +} + +/** + * @} end of nndata_convert group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s8.c new file mode 100644 index 0000000..fbcfdf6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s8.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_avgpool_s8.c + * Description: Pooling function implementations + * + * $Date: May 29,2020 + * $Revision: V.2.0.1 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + + +#if defined (ARM_MATH_DSP) && !defined (ARM_MATH_MVEI) + +static void buffer_scale_back_q15_to_q7_and_clamp(q15_t *buffer, q7_t *target, uint16_t length, + uint16_t count,const int act_min, const int act_max) +{ + int i; + int sum; + + for (i = 0; i < length; i++) + { + sum = buffer[i] > 0 ? (buffer[i] + count / 2) / count : (buffer[i] - count / 2) / count; + + sum = MAX(sum, act_min); + sum = MIN(sum, act_max); + + target[i] = (q7_t) (sum); + } +} +#endif + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Pooling + * @{ + */ + +/* + * s8 average pooling function + * + * Refer to header file for details. + * + */ + +#if defined(ARM_MATH_MVEI) + +arm_status arm_avgpool_s8(const cmsis_nn_context *ctx, + const cmsis_nn_pool_params *pool_params, + const cmsis_nn_dims *input_dims, + const q7_t *src, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims, + q7_t *dst) +{ + (void)ctx; + const int32_t dim_src_height = input_dims->h; + const int32_t dim_src_width = input_dims->w; + const int32_t dim_dst_height = output_dims->h; + const int32_t dim_dst_width = output_dims->w; + const int32_t stride_height = pool_params->stride.h; + const int32_t stride_width = pool_params->stride.w; + const int32_t dim_kernel_height = filter_dims->h; + const int32_t dim_kernel_width = filter_dims->w; + const int32_t padding_height = pool_params->padding.h; + const int32_t padding_width = pool_params->padding.w; + const int32_t act_min = pool_params->activation.min; + const int32_t act_max = pool_params->activation.max; + const int32_t ch_src = input_dims->c; + + int32_t i_x, i_y; + int32_t k_x, k_y; + + for (i_y = 0; i_y < dim_dst_height; i_y++) + { + for (i_x = 0; i_x < dim_dst_width; i_x++) + { + + int32_t k_y_start,k_y_end; + int32_t k_x_start,k_x_end; + int32_t chCnt; + const int8_t *pTmp, *pTmpInner; + int8_t *pDst; + + k_y_start = MAX(0, i_y * stride_height - padding_height); + k_y_end = MIN(i_y * stride_height - padding_height + dim_kernel_height,dim_src_height); + + k_x_start = MAX(0,i_x * stride_width - padding_width); + k_x_end = MIN(i_x * stride_width - padding_width + dim_kernel_width, dim_src_width); + + + pTmp = src; + pDst = &dst[ch_src * (i_x + i_y * dim_dst_width)]; + + chCnt = ch_src >> 4; + while(chCnt > 0) + { + int32x4_t sumV1,sumV2,sumV3,sumV4; + + int8x16_t tempV; + int16x8_t tempVLO, tempVHI; + int32x4_t tempVLOLO, tempVLOHI, tempVHILO, tempVHIHI; + int32_t count = 0; + + sumV1 = vdupq_n_s32(0); + sumV2 = vdupq_n_s32(0); + sumV3 = vdupq_n_s32(0); + sumV4 = vdupq_n_s32(0); + + for (k_y = k_y_start; k_y < k_y_end; k_y++) + { + for (k_x = k_x_start; k_x < k_x_end; k_x++) + { + pTmpInner = pTmp + (ch_src * (k_x + k_y * dim_src_width)); + tempV = vldrbq_s8 (pTmpInner); + + tempVLO = vmovlbq_s8(tempV); + tempVHI = vmovltq_s8(tempV); + + tempVLOLO = vmovlbq_s16(tempVLO); + tempVLOHI = vmovltq_s16(tempVLO); + + tempVHILO = vmovlbq_s16(tempVHI); + tempVHIHI = vmovltq_s16(tempVHI); + + sumV1 = vaddq_s32(sumV1,tempVLOLO); + sumV2 = vaddq_s32(sumV2,tempVLOHI); + sumV3 = vaddq_s32(sumV3,tempVHILO); + sumV4 = vaddq_s32(sumV4,tempVHIHI); + + count++; + } + } + + + sumV1[0] = sumV1[0] > 0 ? (sumV1[0] + count / 2) / count : (sumV1[0] - count / 2) / count; + sumV1[1] = sumV1[1] > 0 ? (sumV1[1] + count / 2) / count : (sumV1[1] - count / 2) / count; + sumV1[2] = sumV1[2] > 0 ? (sumV1[2] + count / 2) / count : (sumV1[2] - count / 2) / count; + sumV1[3] = sumV1[3] > 0 ? (sumV1[3] + count / 2) / count : (sumV1[3] - count / 2) / count; + + sumV2[0] = sumV2[0] > 0 ? (sumV2[0] + count / 2) / count : (sumV2[0] - count / 2) / count; + sumV2[1] = sumV2[1] > 0 ? (sumV2[1] + count / 2) / count : (sumV2[1] - count / 2) / count; + sumV2[2] = sumV2[2] > 0 ? (sumV2[2] + count / 2) / count : (sumV2[2] - count / 2) / count; + sumV2[3] = sumV2[3] > 0 ? (sumV2[3] + count / 2) / count : (sumV2[3] - count / 2) / count; + + sumV3[0] = sumV3[0] > 0 ? (sumV3[0] + count / 2) / count : (sumV3[0] - count / 2) / count; + sumV3[1] = sumV3[1] > 0 ? (sumV3[1] + count / 2) / count : (sumV3[1] - count / 2) / count; + sumV3[2] = sumV3[2] > 0 ? (sumV3[2] + count / 2) / count : (sumV3[2] - count / 2) / count; + sumV3[3] = sumV3[3] > 0 ? (sumV3[3] + count / 2) / count : (sumV3[3] - count / 2) / count; + + sumV4[0] = sumV4[0] > 0 ? (sumV4[0] + count / 2) / count : (sumV4[0] - count / 2) / count; + sumV4[1] = sumV4[1] > 0 ? (sumV4[1] + count / 2) / count : (sumV4[1] - count / 2) / count; + sumV4[2] = sumV4[2] > 0 ? (sumV4[2] + count / 2) / count : (sumV4[2] - count / 2) / count; + sumV4[3] = sumV4[3] > 0 ? (sumV4[3] + count / 2) / count : (sumV4[3] - count / 2) / count; + + sumV1 = vmaxq_s32(sumV1, vdupq_n_s32(act_min)); + sumV1 = vminq_s32(sumV1, vdupq_n_s32(act_max)); + + sumV2 = vmaxq_s32(sumV2, vdupq_n_s32(act_min)); + sumV2 = vminq_s32(sumV2, vdupq_n_s32(act_max)); + + sumV3 = vmaxq_s32(sumV3, vdupq_n_s32(act_min)); + sumV3 = vminq_s32(sumV3, vdupq_n_s32(act_max)); + + sumV4 = vmaxq_s32(sumV4, vdupq_n_s32(act_min)); + sumV4 = vminq_s32(sumV4, vdupq_n_s32(act_max)); + + tempVLO = vmovnbq_s32(tempVLO,sumV1); + tempVLO = vmovntq_s32(tempVLO,sumV2); + + tempVHI = vmovnbq_s32(tempVHI,sumV3); + tempVHI = vmovntq_s32(tempVHI,sumV4); + + + tempV = vmovnbq_s16(tempV,tempVLO); + tempV = vmovntq_s16(tempV,tempVHI); + + vstrbq_s8(pDst,tempV); + pDst += 16; + + chCnt --; + pTmp += 16; + } + + chCnt = ch_src & 0xF; + while(chCnt > 0) + { + int32_t sum = 0; + int32_t count = 0; + + for (k_y = k_y_start; k_y < k_y_end; k_y++) + { + for (k_x = k_x_start; k_x < k_x_end; k_x++) + { + sum += pTmp[ch_src * (k_x + k_y * dim_src_width)]; + count++; + } + } + sum = sum > 0 ? (sum + count / 2) / count : (sum - count / 2) / count; + sum = MAX(sum, act_min); + sum = MIN(sum, act_max); + + *pDst++ = sum; + + chCnt --; + pTmp++; + } + } + } + return ARM_MATH_SUCCESS; +} + +#else +arm_status arm_avgpool_s8(const cmsis_nn_context *ctx, + const cmsis_nn_pool_params *pool_params, + const cmsis_nn_dims *input_dims, + const q7_t *src, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims, + q7_t *dst) +{ + const int32_t dim_src_height = input_dims->h; + const int32_t dim_src_width = input_dims->w; + const int32_t dim_dst_height = output_dims->h; + const int32_t dim_dst_width = output_dims->w; + const int32_t stride_height = pool_params->stride.h; + const int32_t stride_width = pool_params->stride.w; + const int32_t dim_kernel_height = filter_dims->h; + const int32_t dim_kernel_width = filter_dims->w; + const int32_t padding_height = pool_params->padding.h; + const int32_t padding_width = pool_params->padding.w; + const int32_t act_min = pool_params->activation.min; + const int32_t act_max = pool_params->activation.max; + const int32_t ch_src = input_dims->c; + q15_t *bufferA = (q15_t *)ctx->buf; + +#if defined (ARM_MATH_DSP) + + /* Run the following code for Cortex-M4 and Cortex-M7 + */ + int32_t k_x, k_y, i_x, i_y; + + for (i_y = 0; i_y < dim_dst_height; i_y++) + { + for (i_x = 0; i_x < dim_dst_width; i_x++) + { + /* Condition for kernel start dimension: (base_idx_ + kernel__start) >= 0 */ + const int32_t base_idx_y = (i_y * stride_height) - padding_height; + const int32_t base_idx_x = (i_x * stride_width) - padding_width; + const int32_t kernel_y_start = MAX(0, -base_idx_y); + const int32_t kernel_x_start = MAX(0, -base_idx_x); + + /* Condition for kernel end dimension: (base_idx_ + kernel__end) < dim_src_ */ + const int32_t kernel_y_end = MIN(dim_kernel_height, dim_src_height - base_idx_y); + const int32_t kernel_x_end = MIN(dim_kernel_width, dim_src_width - base_idx_x); + + int count = 0; + + for (k_y = kernel_y_start; k_y < kernel_y_end; k_y++) + { + for (k_x = kernel_x_start; k_x < kernel_x_end; k_x++) + { + const q7_t *start = src + ch_src * (k_x + base_idx_x + (k_y + base_idx_y) * dim_src_width); + + if (count == 0) + { + arm_q7_to_q15_no_shift(start, bufferA, ch_src); + } + else + { + arm_nn_accumulate_q7_to_q15(bufferA, start, ch_src); + } + count++; + } + } + buffer_scale_back_q15_to_q7_and_clamp(bufferA, dst, ch_src, count, act_min, act_max); + dst += ch_src; + } + } +#else + + /* Reference C code adapted from CMSIS-NN arm_avepool_q7_HWC. + */ + (void)bufferA; + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_y = 0; i_y < dim_dst_height; i_y++) + { + for (i_x = 0; i_x < dim_dst_width; i_x++) + { + for (i_ch_in = 0; i_ch_in < ch_src; i_ch_in++) + { + int sum = 0; + int count = 0; + for (k_y = i_y * stride_height - padding_height; k_y < i_y * stride_height - padding_height + dim_kernel_height; k_y++) + { + for (k_x = i_x * stride_width - padding_width; k_x < i_x * stride_width - padding_width + dim_kernel_width; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_src_height && k_x < dim_src_width) + { + sum += src[i_ch_in + ch_src * (k_x + k_y * dim_src_width)]; + count++; + } + } + } + sum = sum > 0 ? (sum + count / 2) / count : (sum - count / 2) / count; + sum = MAX(sum, act_min); + sum = MIN(sum, act_max); + + dst[i_ch_in + ch_src * (i_x + i_y * dim_dst_width)] = sum; + } + } + } + +#endif + return ARM_MATH_SUCCESS; +} + +#endif /* ARM_MATH_MVEI */ + +int32_t arm_avgpool_s8_get_buffer_size(const int dim_dst_width, + const int ch_src) +{ + (void)dim_dst_width; + +#if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI) + return (ch_src * sizeof(int16_t)); +#else + (void)ch_src; + return 0; +#endif +} +/** + * @} end of Pooling group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c new file mode 100644 index 0000000..df87ad9 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_max_pool_s8.c + * Description: Pooling function implementations + * + * $Date: June 11, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +static void compare_and_replace_if_larger_q7(q7_t *base, + const q7_t *target, + int32_t length) +{ +#if defined(ARM_MATH_MVEI) + int32_t loop_count = (length + 15) / 16; + for (int i = 0; i < loop_count; i++) + { + mve_pred16_t p = vctp16q((uint32_t)length); + const int8x16_t op_1 = vldrbq_z_s8(base, p); + const int8x16_t op_2 = vldrbq_z_s8(target, p); + const int8x16_t max = vmaxq_m_s8(vuninitializedq_s8(), op_1, op_2, p); + vstrbq_p_s8(base, max, p); + base += 16; + target += 16; + length -= 16; + } +#else + q7_t *dst = base; + const q7_t *src = target; + union arm_nnword ref_max; + union arm_nnword comp_max; + int32_t cnt = length >> 2; + + while (cnt > 0l) + { + ref_max.word = arm_nn_read_q7x4(dst); + comp_max.word = arm_nn_read_q7x4_ia(&src); + + if (comp_max.bytes[0] > ref_max.bytes[0]) + { + ref_max.bytes[0] = comp_max.bytes[0]; + } + if (comp_max.bytes[1] > ref_max.bytes[1]) + { + ref_max.bytes[1] = comp_max.bytes[1]; + } + if (comp_max.bytes[2] > ref_max.bytes[2]) + { + ref_max.bytes[2] = comp_max.bytes[2]; + } + if (comp_max.bytes[3] > ref_max.bytes[3]) + { + ref_max.bytes[3] = comp_max.bytes[3]; + } + + write_q7x4_ia(&dst, ref_max.word); + + cnt--; + } + + cnt = length & 0x3; + while (cnt > 0l) + { + if (*src > *dst) + { + *dst = *src; + } + dst++; + src++; + cnt--; + } +#endif +} + +static void +clamp_output(q7_t *source, int32_t length, const int32_t act_min, const int32_t act_max) +{ +#if defined(ARM_MATH_MVEI) + int32_t + loop_count = (length + 15) / 16; + for (int i = 0; i < loop_count; i++) + { + mve_pred16_t p = vctp16q((uint32_t)length); + length -= 16; + const int8x16_t src = vldrbq_z_s8(source, p); + const int8x16_t predicated_min = vdupq_m_n_s8(vuninitializedq_s8(), (int8_t)act_min, p); + const int8x16_t predicated_max = vdupq_m_n_s8(vuninitializedq_s8(), (int8_t)act_max, p); + int8x16_t + res = vmaxq_m_s8(vuninitializedq_s8(), src, predicated_min, p); + res = vminq_m_s8(vuninitializedq_s8(), src, predicated_max, p); + vstrbq_p_s8(source, res, p); + source += 16; + } +#else + union arm_nnword in; + int32_t cnt = length >> 2; + + while (cnt > 0l) + { + in.word = arm_nn_read_q7x4(source); + + in.bytes[0] = MAX(in.bytes[0], act_min); + in.bytes[0] = MIN(in.bytes[0], act_max); + in.bytes[1] = MAX(in.bytes[1], act_min); + in.bytes[1] = MIN(in.bytes[1], act_max); + in.bytes[2] = MAX(in.bytes[2], act_min); + in.bytes[2] = MIN(in.bytes[2], act_max); + in.bytes[3] = MAX(in.bytes[3], act_min); + in.bytes[3] = MIN(in.bytes[3], act_max); + + write_q7x4_ia(&source, in.word); + cnt--; + } + + cnt = length & 0x3; + while (cnt > 0l) + { + int32_t comp = *source; + comp = MAX(comp, act_min); + comp = MIN(comp, act_max); + *source++ = (int8_t)comp; + cnt--; + } +#endif +} + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Pooling + * @{ + */ + +/* + * Optimized s8 max pooling function + * + * Refer to header file for details. + * + */ + +arm_status +arm_max_pool_s8(const cmsis_nn_context *ctx, + const cmsis_nn_pool_params *pool_params, + const cmsis_nn_dims *input_dims, + const q7_t *src, + const cmsis_nn_dims *filter_dims, + const cmsis_nn_dims *output_dims, + q7_t *dst) +{ + const int32_t input_y = input_dims->h; + const int32_t input_x = input_dims->w; + const int32_t output_y = output_dims->h; + const int32_t output_x = output_dims->w; + const int32_t stride_y = pool_params->stride.h; + const int32_t stride_x = pool_params->stride.w; + const int32_t kernel_y = filter_dims->h; + const int32_t kernel_x = filter_dims->w; + const int32_t pad_y = pool_params->padding.h; + const int32_t pad_x = pool_params->padding.w; + const int32_t act_min = pool_params->activation.min; + const int32_t act_max = pool_params->activation.max; + const int32_t channel_in = input_dims->c; + (void)ctx; + q7_t *dst_base = dst; + + for (int i_y = 0, base_idx_y = -pad_y; i_y < output_y; base_idx_y += stride_y, i_y++) + { + for (int i_x = 0, base_idx_x = -pad_x; i_x < output_x; base_idx_x += stride_x, i_x++) + { + /* Condition for kernel start dimension: (base_idx_ + kernel__start) >= 0 */ + const int32_t ker_y_start = MAX(0, -base_idx_y); + const int32_t ker_x_start = MAX(0, -base_idx_x); + + /* Condition for kernel end dimension: (base_idx_ + kernel__end) < dim_src_ */ + const int32_t kernel_y_end = MIN(kernel_y, input_y - base_idx_y); + const int32_t kernel_x_end = MIN(kernel_x, input_x - base_idx_x); + + int count = 0; + + for (int k_y = ker_y_start; k_y < kernel_y_end; k_y++) + { + for (int k_x = ker_x_start; k_x < kernel_x_end; k_x++) + { + const q7_t *start = src + channel_in * (k_x + base_idx_x + (k_y + base_idx_y) * input_x); + + if (count == 0) + { + memcpy(dst, start, channel_in); + count++; + } + else + { + compare_and_replace_if_larger_q7(dst, start, channel_in); + } + } + } + /* 'count' is expected to be non-zero here. */ + dst += channel_in; + } + } + + clamp_output(dst_base, output_x * output_y * channel_in, act_min, act_max); + + return ARM_MATH_SUCCESS; +} + +/** + * @} end of Pooling group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c new file mode 100644 index 0000000..4f1e2a5 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c @@ -0,0 +1,454 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_pool_q7_HWC.c + * Description: Pooling function implementations + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +#if defined (ARM_MATH_DSP) + +/** + * @brief A few utility functions used by pooling functions + * + * + */ + +static void buffer_scale_back_q15_to_q7(q15_t * buffer, q7_t * target, uint16_t length, uint16_t scale) +{ + int i; + + for (i = 0; i < length; i++) + { + target[i] = (q7_t) (buffer[i] / scale); + } +} + +static void compare_and_replace_if_larger_q7(q7_t * base, // base data + const q7_t * target, // compare target + const uint16_t length // data length + ) +{ + q7_t *pIn = base; + const q7_t *pCom = target; + union arm_nnword in; + union arm_nnword com; + uint16_t cnt = length >> 2; + + while (cnt > 0u) + { + in.word = arm_nn_read_q7x4((const q7_t*)pIn); + com.word = arm_nn_read_q7x4_ia((const q7_t**)&pCom); + + // if version + if (com.bytes[0] > in.bytes[0]) + in.bytes[0] = com.bytes[0]; + if (com.bytes[1] > in.bytes[1]) + in.bytes[1] = com.bytes[1]; + if (com.bytes[2] > in.bytes[2]) + in.bytes[2] = com.bytes[2]; + if (com.bytes[3] > in.bytes[3]) + in.bytes[3] = com.bytes[3]; + + *__SIMD32(pIn)++ = in.word; + + cnt--; + } + + cnt = length & 0x3; + while (cnt > 0u) + { + if (*pCom > *pIn) + { + *pIn = *pCom; + } + pIn++; + pCom++; + cnt--; + } +} + +static void accumulate_q7_to_q15(q15_t * base, q7_t * target, const uint16_t length) +{ + q15_t *pCnt = base; + q7_t *pV = target; + q31_t v1, v2, vo1, vo2; + uint16_t cnt = length >> 2; + q31_t in; + + while (cnt > 0u) + { + q31_t value = arm_nn_read_q7x4_ia((const q7_t**)&pV); + v1 = __SXTB16(__ROR(value, 8)); + v2 = __SXTB16(value); +#ifndef ARM_MATH_BIG_ENDIAN + + vo2 = __PKHTB(v1, v2, 16); + vo1 = __PKHBT(v2, v1, 16); + +#else + + vo1 = __PKHTB(v1, v2, 16); + vo2 = __PKHBT(v2, v1, 16); + +#endif + + in = arm_nn_read_q15x2(pCnt); + *__SIMD32(pCnt)++ = __QADD16(vo1, in); + + in = arm_nn_read_q15x2(pCnt); + *__SIMD32(pCnt)++ = __QADD16(vo2, in); + + cnt--; + } + cnt = length & 0x3; + while (cnt > 0u) + { + *pCnt++ += *pV++; + cnt--; + } +} + +#endif // ARM_MATH_DSP + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Pooling + * @{ + */ + + /** + * @brief Q7 max pooling function + * @param[in, out] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA Not used + * @param[in,out] Im_out pointer to output tensor + * + * @details + * + * The pooling function is implemented as split x-pooling then + * y-pooling. + * + * This pooling function is input-destructive. Input data is undefined + * after calling this function. + * + */ + +void +arm_maxpool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out) +{ + (void)bufferA; +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_x, i_y; + + /* first does the pooling along x axis */ + for (i_y = 0; i_y < dim_im_in; i_y++) + { + + for (i_x = 0; i_x < dim_im_out; i_x++) + { + /* for each output pixel */ + q7_t *target = Im_in + (i_y * dim_im_in + i_x) * ch_im_in; + q7_t *win_start; + q7_t *win_stop; + if (i_x * stride - padding < 0) + { + win_start = target; + } else + { + win_start = Im_in + (i_y * dim_im_in + i_x * stride - padding) * ch_im_in; + } + + if (i_x * stride - padding + dim_kernel >= dim_im_in) + { + win_stop = Im_in + (i_y * dim_im_in + dim_im_in) * ch_im_in; + } else + { + win_stop = Im_in + (i_y * dim_im_in + i_x * stride - padding + dim_kernel) * ch_im_in; + } + + /* first step is to copy over initial data */ + /* arm_copy_q7(win_start, target, ch_im_in); */ + memmove(target, win_start, ch_im_in); + + /* start the max operation from the second part */ + win_start += ch_im_in; + for (; win_start < win_stop; win_start += ch_im_in) + { + compare_and_replace_if_larger_q7(target, win_start, ch_im_in); + } + } + } + + /* then does the pooling along y axis */ + for (i_y = 0; i_y < dim_im_out; i_y++) + { + + /* for each output row */ + q7_t *target = Im_out + i_y * dim_im_out * ch_im_in; + q7_t *row_start; + q7_t *row_end; + /* setting the starting row */ + if (i_y * stride - padding < 0) + { + row_start = Im_in; + } else + { + row_start = Im_in + (i_y * stride - padding) * dim_im_in * ch_im_in; + } + /* setting the stopping row */ + if (i_y * stride - padding + dim_kernel >= dim_im_in) + { + row_end = Im_in + dim_im_in * dim_im_in * ch_im_in; + } else + { + row_end = Im_in + (i_y * stride - padding + dim_kernel) * dim_im_in * ch_im_in; + } + + /* copy over the first row */ + /* arm_copy_q7(row_start, target, dim_im_out * ch_im_in); */ + memmove(target, row_start, dim_im_out * ch_im_in); + + /* move over to next row */ + row_start += ch_im_in * dim_im_in; + + for (; row_start < row_end; row_start += dim_im_in * ch_im_in) + { + compare_and_replace_if_larger_q7(target, row_start, dim_im_out * ch_im_in); + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int max = -129; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + if (Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)] > max) + { + max = Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + } + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = max; + } + } + } + +#endif /* ARM_MATH_DSP */ + +} + + /** + * @brief Q7 average pooling function + * @param[in,out] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * + * @details + * + * Buffer size: + * + * bufferA size: 2*dim_im_out*ch_im_in + * + * The pooling function is implemented as split x-pooling then + * y-pooling. + * + * This pooling function is input-destructive. Input data is undefined + * after calling this function. + * + */ + +void +arm_avepool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + q15_t *buffer = (q15_t *) bufferA; + int16_t i_x, i_y; + int16_t count = 0; + + /* first does the pooling along x axis */ + for (i_y = 0; i_y < dim_im_in; i_y++) + { + + for (i_x = 0; i_x < dim_im_out; i_x++) + { + /* for each output pixel */ + q7_t *target = Im_in + (i_y * dim_im_in + i_x) * ch_im_in; + q7_t *win_start; + q7_t *win_stop; + if (i_x * stride - padding < 0) + { + win_start = target; + } else + { + win_start = Im_in + (i_y * dim_im_in + i_x * stride - padding) * ch_im_in; + } + + if (i_x * stride - padding + dim_kernel >= dim_im_in) + { + win_stop = Im_in + (i_y * dim_im_in + dim_im_in) * ch_im_in; + } else + { + win_stop = Im_in + (i_y * dim_im_in + i_x * stride - padding + dim_kernel) * ch_im_in; + } + + /* first step is to copy over initial data */ + arm_q7_to_q15_no_shift(win_start, buffer, ch_im_in); + count = 1; + + /* start the max operation from the second part */ + win_start += ch_im_in; + for (; win_start < win_stop; win_start += ch_im_in) + { + accumulate_q7_to_q15(buffer, win_start, ch_im_in); + count++; + } + buffer_scale_back_q15_to_q7(buffer, target, ch_im_in, count); + } + } + + /* then does the pooling along y axis */ + for (i_y = 0; i_y < dim_im_out; i_y++) + { + /* for each output row */ + q7_t *target = Im_out + i_y * dim_im_out * ch_im_in; + q7_t *row_start; + q7_t *row_end; + /* setting the starting row */ + if (i_y * stride - padding < 0) + { + row_start = Im_in; + } else + { + row_start = Im_in + (i_y * stride - padding) * dim_im_in * ch_im_in; + } + /* setting the stopping row */ + if (i_y * stride - padding + dim_kernel >= dim_im_in) + { + row_end = Im_in + dim_im_in * dim_im_in * ch_im_in; + } else + { + row_end = Im_in + (i_y * stride - padding + dim_kernel) * dim_im_in * ch_im_in; + } + + /* copy over the first row */ + arm_q7_to_q15_no_shift(row_start, buffer, dim_im_out * ch_im_in); + count = 1; + + /* move over to next row */ + row_start += ch_im_in * dim_im_in; + + for (; row_start < row_end; row_start += dim_im_in * ch_im_in) + { + accumulate_q7_to_q15(buffer, row_start, dim_im_out * ch_im_in); + count++; + } + buffer_scale_back_q15_to_q7(buffer, target, dim_im_out * ch_im_in, count); + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + (void)bufferA; + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int sum = 0; + int count = 0; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + sum += Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + count++; + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = sum / count; + } + } + } + +#endif /* ARM_MATH_DSP */ + +} + +/** + * @} end of Pooling group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ReshapeFunctions/arm_reshape_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ReshapeFunctions/arm_reshape_s8.c new file mode 100644 index 0000000..f943976 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/ReshapeFunctions/arm_reshape_s8.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_reshape_s8.c + * Description: Reshape a s8 vector + * + * $Date: September 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Reshape + * @{ + */ + +/** + * Basic s8 reshape function. + * + * Refer header file for details. + * + */ + +void arm_reshape_s8(const int8_t *input, + int8_t *output, + const uint32_t total_size) +{ + memcpy(output, input, total_size); +} + +/** + * @} end of Reshape group + */ \ No newline at end of file diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c new file mode 100644 index 0000000..3000043 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_q15.c + * Description: Q15 softmax function + * + * $Date: 20. February 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + + /** + * @brief Q15 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * + * @details + * + * Here, instead of typical e based softmax, we use + * 2-based softmax, i.e.,: + * + * y_i = 2^(x_i) / sum(2^x_j) + * + * The relative output will be different here. + * But mathematically, the gradient will be the same + * with a log(2) scaling factor. + * + */ + +void arm_softmax_q15(const q15_t * vec_in, const uint16_t dim_vec, q15_t * p_out) +{ + q31_t sum; + int16_t i; + uint8_t shift; + q31_t base; + base = -1 * 0x100000; + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + base = vec_in[i]; + } + } + + /* we ignore really small values + * anyway, they will be 0 after shrinking + * to q15_t + */ + base = base - 16; + + sum = 0; + + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + shift = (uint8_t)__USAT(vec_in[i] - base, 5); + sum += 0x1 << shift; + } + } + + /* This is effectively (0x1 << 32) / sum */ + int64_t div_base = 0x100000000LL; + int output_base = (int32_t)(div_base / sum); + + /* Final confidence will be output_base >> ( 17 - (vec_in[i] - base) ) + * so 32768 (0x1<<15) -> 100% confidence when sum = 0x1 << 16, output_base = 0x1 << 16 + * and vec_in[i]-base = 16 + */ + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + /* Here minimum value of 17+base-vec[i] will be 1 */ + shift = (uint8_t)__USAT(17+base-vec_in[i], 5); + p_out[i] = (q15_t) __SSAT((output_base >> shift), 16); + } else + { + p_out[i] = 0; + } + } + +} + +/** + * @} end of Softmax group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c new file mode 100644 index 0000000..c203227 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_q7.c + * Description: Q7 softmax function + * + * $Date: June 8, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + + /** + * @brief Q7 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * + * @details + * + * Here, instead of typical natural logarithm e based softmax, we use + * 2-based softmax here, i.e.,: + * + * y_i = 2^(x_i) / sum(2^x_j) + * + * The relative output will be different here. + * But mathematically, the gradient will be the same + * with a log(2) scaling factor. + * + */ + +void arm_softmax_q7(const q7_t * vec_in, const uint16_t dim_vec, q7_t * p_out ) +{ + q31_t sum; + int16_t i; + uint8_t shift; + q15_t base; + base = -128; + + /* We first search for the maximum */ + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + base = vec_in[i]; + } + } + + /* + * So the base is set to max-8, meaning + * that we ignore really small values. + * anyway, they will be 0 after shrinking to q7_t. + */ + base = base - (1 << 3); + + sum = 0; + + for (i = 0; i < dim_vec; i++) + { + shift = (uint8_t)__USAT(vec_in[i] - base, 3); + sum += 0x1 << shift; + } + + /* This is effectively (0x1 << 20) / sum */ + int output_base = (1 << 20) / sum; + + for (i = 0; i < dim_vec; i++) + { + + /* Here minimum value of 13+base-vec_in[i] will be 5 */ + shift = (uint8_t)__USAT(13 + base - vec_in[i], 5); + p_out[i] = (q7_t)__SSAT((output_base >> shift), 8); + } +} + +/** + * @} end of Softmax group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_s8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_s8.c new file mode 100644 index 0000000..8639f70 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_s8.c @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_s8.c + * Description: S8 softmax function + * + * $Date: April 6, 2020 + * $Revision: V.2.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnsupportfunctions.h" + +#define ACCUM_BITS 12 + +#ifdef ARM_MATH_MVEI +static int32x4_t arm_exp_on_negative_values_mve_32x4(int32x4_t val) +{ +#define SHIFT_START (24) + int32_t shift = SHIFT_START; + int32x4_t mask; + + const int32x4_t val_mod_minus_quarter = vandq_s32(val, vdupq_n_s32((1 << SHIFT_START) - 1)) - vdupq_n_s32(1 << SHIFT_START); + const int32x4_t remainder = vsubq_s32(val_mod_minus_quarter, val); + const int32x4_t x = vaddq_n_s32(val_mod_minus_quarter << 5, 1 << 28); + const int32x4_t x2 = MUL_SAT_MVE(x, x); + const int32x4_t op_1 = DIV_POW2_MVE(MUL_SAT_MVE(x2, x2), 2) + MUL_SAT_MVE(x2, x); + const int32x4_t op_2 = x + DIV_POW2_MVE(MUL_SAT_MVE(op_1, vdupq_n_s32(715827883)) + x2, 1); + int32x4_t result = vdupq_n_s32(1895147668) + MUL_SAT_MVE(vdupq_n_s32(1895147668), op_2); + +#define SELECT_IF_NON_ZERO(x) \ + { \ + mve_pred16_t p = vcmpneq_n_s32(remainder & vdupq_n_s32(1 << shift++), 0); \ + mask = vmvnq_m_s32(vdupq_n_s32(0), vdupq_n_s32(0), p); \ + result = SELECT_USING_MASK(mask, MUL_SAT_MVE(result, vdupq_n_s32(x)), result); \ + } + + SELECT_IF_NON_ZERO(1672461947) + SELECT_IF_NON_ZERO(1302514674) + SELECT_IF_NON_ZERO(790015084) + SELECT_IF_NON_ZERO(290630308) + SELECT_IF_NON_ZERO(39332535) + SELECT_IF_NON_ZERO(720401) + SELECT_IF_NON_ZERO(242) + +#undef SELECT_IF_NON_ZERO + + mve_pred16_t p = vcmpeqq_n_s32(val, 0); + mask = vmvnq_m_s32(vdupq_n_s32(0), vdupq_n_s32(0), p); + + result = SELECT_USING_MASK(mask, vdupq_n_s32(Q31_MAX), result); + return result; +} +#endif + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + +void arm_softmax_s8(const int8_t *input, + const int32_t num_rows, + const int32_t row_size, + const int32_t mult, + const int32_t shift, + const int32_t diff_min, + int8_t *output) +{ +#ifdef ARM_MATH_MVEI + +#define ACT_MIN ((int8_t)Q7_MIN) +#define ACT_MAX ((int8_t)Q7_MAX) + + const int32_t mask = (1 << shift); + + for (int i_num_rows = 0; i_num_rows < num_rows; ++i_num_rows) + { + int8_t max = ACT_MIN; + + int32_t vec_count = (row_size + 15) / 16; + uint32_t r_count = (uint32_t)row_size; + for (int i = 0; i < vec_count; i++) + { + mve_pred16_t p = vctp8q(r_count); + const int8x16_t ip = vldrbq_z_s8(&input[i * 16], p); + max = vmaxvq_p_s8(max, ip, p); + r_count -= 16; + } + + vec_count = row_size / 4; + int32_t idx = 0; + int32_t sum = 0; + + while (vec_count) + { + int32x4_t ip = vldrbq_s32(&input[idx * 4]); + ip = vsubq_n_s32(ip, max); + mve_pred16_t p = vcmpgeq_n_s32(ip, diff_min); + if (p != 0) + { + ip = vmulq_n_s32(ip, mask); + + int32x4_t res = MUL_SAT_MVE(ip, vdupq_n_s32(mult)); + + res = arm_exp_on_negative_values_mve_32x4(res); + res = DIV_POW2_MVE(res, ACCUM_BITS); + res = vpselq_s32(res, vdupq_n_s32(0), p); + sum += vaddvq_s32(res); + } + + vec_count--; + idx++; + } + + const int32_t tail_idx = row_size & ~3; + for (int i = 0; i < (row_size & 3); i++) + { + const int32_t diff = input[tail_idx + i] - max; + if (diff >= diff_min) + { + sum += DIV_POW2(EXP_ON_NEG(MUL_SAT(diff * mask, mult)), ACCUM_BITS); + } + } + + const int32_t headroom = __CLZ((uint32_t)sum); + const int32_t bits_over_unit = ACCUM_BITS - headroom + 23; + const int32_t shifted_scale = ONE_OVER1((sum << headroom) - (1 << 31)); + + vec_count = row_size / 4; + idx = 0; + + while (vec_count) + { + int32x4_t ip = vldrbq_s32(&input[idx]); + ip = vsubq_n_s32(ip, max); + + mve_pred16_t p = vcmpgeq_n_s32(ip, diff_min); + + int32x4_t tmp_res; + + if (p != 0) + { + ip = vmulq_n_s32(ip, mask); + + tmp_res = MUL_SAT_MVE(ip, vdupq_n_s32(mult)); + tmp_res = arm_exp_on_negative_values_mve_32x4(tmp_res); + tmp_res = MUL_SAT_MVE(vdupq_n_s32(shifted_scale), tmp_res); + tmp_res = DIV_POW2_MVE(tmp_res, bits_over_unit); + tmp_res += vdupq_n_s32(ACT_MIN); + + tmp_res = vmaxq_s32(tmp_res, vdupq_n_s32(ACT_MIN)); + tmp_res = vminq_s32(tmp_res, vdupq_n_s32(ACT_MAX)); + tmp_res = vpselq_s32(tmp_res, vdupq_n_s32(ACT_MIN), p); + } + else + { + tmp_res = vdupq_n_s32(ACT_MIN); + } + vstrbq_s32(&output[idx], tmp_res); + vec_count--; + idx += 4; + } + + for (int i = 0; i < (row_size & 3); i++) + { + int32_t diff = input[tail_idx + i] - max; + if (diff >= diff_min) + { + const int32_t res = DIV_POW2(MUL_SAT(shifted_scale, EXP_ON_NEG(MUL_SAT(diff * mask, mult))), bits_over_unit) - 128; + output[tail_idx + i] = (int8_t)CLAMP(res, (int32_t)ACT_MAX, (int32_t)ACT_MIN); + } + else + { + output[tail_idx + i] = ACT_MIN; + } + } + + input += row_size; + output += row_size; + } +#else + const int32_t mask = (1 << shift); + + int32_t col = 0; + int32_t row_idx; + + for (row_idx = 0; row_idx < num_rows; ++row_idx) + { + // Find the maximum value in order to ensure numerical stability + int8_t max = *input; + + for (col = 1; col < row_size; ++col) + { + max = MAX(max, input[col]); + } + + int32_t diff = 0; + int32_t sum = 0; + + for (col = 0; col < row_size; ++col) + { + diff = input[col] - max; + if (diff >= diff_min) + { + sum += DIV_POW2(EXP_ON_NEG(MUL_SAT(diff * mask, mult)), ACCUM_BITS); + } + } + + const int32_t headroom = __CLZ(sum); + const int32_t bits_over_unit = ACCUM_BITS - headroom + 23; + const int32_t shifted_scale = ONE_OVER1((sum << headroom) - (1 << 31)); + + for (col = 0; col < row_size; ++col) + { + diff = input[col] - max; + if (diff >= diff_min) + { + const int32_t res = DIV_POW2(MUL_SAT(shifted_scale, EXP_ON_NEG(MUL_SAT(diff * mask, mult))), bits_over_unit) - 128; + output[col] = (int8_t)CLAMP(res, (int32_t)127, (int32_t)-128); + } + else + { + output[col] = -128; + } + } + input += row_size; + output += row_size; + } + +#endif +} +/** + * @} end of Softmax group + */ diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_u8.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_u8.c new file mode 100644 index 0000000..2820af6 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_u8.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010-2020 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_u8.c + * Description: U8 softmax function + * + * $Date: May 29, 2020 + * $Revision: V.1.0.1 + * + * Target Processor: Cortex-M CPUs + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +#define ACCUM_BITS 12 + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ +void arm_softmax_u8(const uint8_t *input, + const int32_t num_rows, + const int32_t row_size, + const int32_t mult, + const int32_t shift, + const int32_t diff_min, + uint8_t *output) +{ + const int32_t mask = (1 << shift); + + int32_t col = 0; + int32_t row_idx; + + for(row_idx = 0; row_idx < num_rows; ++row_idx) + { + // Find the maximum value in order to ensure numerical stability + uint8_t max = *input; + + for (col = 1; col < row_size; ++col) + { + max = MAX(max, input[col]); + } + + int32_t diff = 0; + int32_t sum = 0; + + for (col = 0; col < row_size; ++col) + { + diff = input[col] - max; + if(diff >= diff_min) + { + sum += DIV_POW2(EXP_ON_NEG(MUL_SAT(diff * mask, mult)), ACCUM_BITS); + } + } + + const int32_t headroom = __CLZ((uint32_t)sum); + const int32_t bits_over_unit = ACCUM_BITS - headroom + 23; + const int32_t shifted_scale = ONE_OVER1((sum << headroom) - (1 << 31)); + + for (col = 0; col < row_size; ++col) + { + diff = input[col] - max; + if (diff >= diff_min) + { + const int32_t res = DIV_POW2(MUL_SAT(shifted_scale, EXP_ON_NEG(MUL_SAT(diff * mask, mult))), bits_over_unit); + output[col] = (uint8_t) CLAMP(res, (int32_t)255, (int32_t)0); + } + else + { + output[col] = 0; + } + } + input += row_size; + output += row_size; + } +} +/** + * @} end of Softmax group + */ \ No newline at end of file diff --git a/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_with_batch_q7.c b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_with_batch_q7.c new file mode 100644 index 0000000..e4a634d --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/micro/tools/cmsis/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_with_batch_q7.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_with_batch_q7.c + * Description: Q7 softmax function + * + * $Date: 05. August 2019 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M and Cortex-A cores + * + * -------------------------------------------------------------------- */ + +#include "cmsis/CMSIS/DSP/Include/arm_math.h" +#include "cmsis/CMSIS/NN/Include/arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + + /** + * @brief Q7 softmax function with batch parameter + * @param[in] vec_in pointer to input vector + * @param[in] nb_batches number of batches + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * + * @details + * + * Here, instead of typical natural logarithm e based softmax, we use + * 2-based softmax here, i.e.,: + * + * y_i = 2^(x_i) / sum(2^x_j) + * + * The relative output will be different here. + * But mathematically, the gradient will be the same + * with a log(2) scaling factor. + * + */ + +void arm_softmax_with_batch_q7(const q7_t * vec_in, const uint16_t nb_batches,const uint16_t dim_vec, q7_t * p_out ) +{ + for(int i=0; i(e); + return EnumNamesTensorType()[index]; +} + +enum QuantizationDetails { + QuantizationDetails_NONE = 0, + QuantizationDetails_CustomQuantization = 1, + QuantizationDetails_MIN = QuantizationDetails_NONE, + QuantizationDetails_MAX = QuantizationDetails_CustomQuantization +}; + +inline const QuantizationDetails (&EnumValuesQuantizationDetails())[2] { + static const QuantizationDetails values[] = { + QuantizationDetails_NONE, + QuantizationDetails_CustomQuantization + }; + return values; +} + +inline const char * const *EnumNamesQuantizationDetails() { + static const char * const names[3] = { + "NONE", + "CustomQuantization", + nullptr + }; + return names; +} + +inline const char *EnumNameQuantizationDetails(QuantizationDetails e) { + if (flatbuffers::IsOutRange(e, QuantizationDetails_NONE, QuantizationDetails_CustomQuantization)) return ""; + const size_t index = static_cast(e); + return EnumNamesQuantizationDetails()[index]; +} + +template struct QuantizationDetailsTraits { + static const QuantizationDetails enum_value = QuantizationDetails_NONE; +}; + +template<> struct QuantizationDetailsTraits { + static const QuantizationDetails enum_value = QuantizationDetails_CustomQuantization; +}; + +struct QuantizationDetailsUnion { + QuantizationDetails type; + void *value; + + QuantizationDetailsUnion() : type(QuantizationDetails_NONE), value(nullptr) {} + QuantizationDetailsUnion(QuantizationDetailsUnion&& u) FLATBUFFERS_NOEXCEPT : + type(QuantizationDetails_NONE), value(nullptr) + { std::swap(type, u.type); std::swap(value, u.value); } + QuantizationDetailsUnion(const QuantizationDetailsUnion &) FLATBUFFERS_NOEXCEPT; + QuantizationDetailsUnion &operator=(const QuantizationDetailsUnion &u) FLATBUFFERS_NOEXCEPT + { QuantizationDetailsUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } + QuantizationDetailsUnion &operator=(QuantizationDetailsUnion &&u) FLATBUFFERS_NOEXCEPT + { std::swap(type, u.type); std::swap(value, u.value); return *this; } + ~QuantizationDetailsUnion() { Reset(); } + + void Reset(); + +#ifndef FLATBUFFERS_CPP98_STL + template + void Set(T&& val) { + using RT = typename std::remove_reference::type; + Reset(); + type = QuantizationDetailsTraits::enum_value; + if (type != QuantizationDetails_NONE) { + value = new RT(std::forward(val)); + } + } +#endif // FLATBUFFERS_CPP98_STL + + static void *UnPack(const void *obj, QuantizationDetails type, const flatbuffers::resolver_function_t *resolver); + flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; + + tflite::CustomQuantizationT *AsCustomQuantization() { + return type == QuantizationDetails_CustomQuantization ? + reinterpret_cast(value) : nullptr; + } + const tflite::CustomQuantizationT *AsCustomQuantization() const { + return type == QuantizationDetails_CustomQuantization ? + reinterpret_cast(value) : nullptr; + } +}; + +bool VerifyQuantizationDetails(flatbuffers::Verifier &verifier, const void *obj, QuantizationDetails type); +bool VerifyQuantizationDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types); + +enum DimensionType { + DimensionType_DENSE = 0, + DimensionType_SPARSE_CSR = 1, + DimensionType_MIN = DimensionType_DENSE, + DimensionType_MAX = DimensionType_SPARSE_CSR +}; + +inline const DimensionType (&EnumValuesDimensionType())[2] { + static const DimensionType values[] = { + DimensionType_DENSE, + DimensionType_SPARSE_CSR + }; + return values; +} + +inline const char * const *EnumNamesDimensionType() { + static const char * const names[3] = { + "DENSE", + "SPARSE_CSR", + nullptr + }; + return names; +} + +inline const char *EnumNameDimensionType(DimensionType e) { + if (flatbuffers::IsOutRange(e, DimensionType_DENSE, DimensionType_SPARSE_CSR)) return ""; + const size_t index = static_cast(e); + return EnumNamesDimensionType()[index]; +} + +enum SparseIndexVector { + SparseIndexVector_NONE = 0, + SparseIndexVector_Int32Vector = 1, + SparseIndexVector_Uint16Vector = 2, + SparseIndexVector_Uint8Vector = 3, + SparseIndexVector_MIN = SparseIndexVector_NONE, + SparseIndexVector_MAX = SparseIndexVector_Uint8Vector +}; + +inline const SparseIndexVector (&EnumValuesSparseIndexVector())[4] { + static const SparseIndexVector values[] = { + SparseIndexVector_NONE, + SparseIndexVector_Int32Vector, + SparseIndexVector_Uint16Vector, + SparseIndexVector_Uint8Vector + }; + return values; +} + +inline const char * const *EnumNamesSparseIndexVector() { + static const char * const names[5] = { + "NONE", + "Int32Vector", + "Uint16Vector", + "Uint8Vector", + nullptr + }; + return names; +} + +inline const char *EnumNameSparseIndexVector(SparseIndexVector e) { + if (flatbuffers::IsOutRange(e, SparseIndexVector_NONE, SparseIndexVector_Uint8Vector)) return ""; + const size_t index = static_cast(e); + return EnumNamesSparseIndexVector()[index]; +} + +template struct SparseIndexVectorTraits { + static const SparseIndexVector enum_value = SparseIndexVector_NONE; +}; + +template<> struct SparseIndexVectorTraits { + static const SparseIndexVector enum_value = SparseIndexVector_Int32Vector; +}; + +template<> struct SparseIndexVectorTraits { + static const SparseIndexVector enum_value = SparseIndexVector_Uint16Vector; +}; + +template<> struct SparseIndexVectorTraits { + static const SparseIndexVector enum_value = SparseIndexVector_Uint8Vector; +}; + +struct SparseIndexVectorUnion { + SparseIndexVector type; + void *value; + + SparseIndexVectorUnion() : type(SparseIndexVector_NONE), value(nullptr) {} + SparseIndexVectorUnion(SparseIndexVectorUnion&& u) FLATBUFFERS_NOEXCEPT : + type(SparseIndexVector_NONE), value(nullptr) + { std::swap(type, u.type); std::swap(value, u.value); } + SparseIndexVectorUnion(const SparseIndexVectorUnion &) FLATBUFFERS_NOEXCEPT; + SparseIndexVectorUnion &operator=(const SparseIndexVectorUnion &u) FLATBUFFERS_NOEXCEPT + { SparseIndexVectorUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } + SparseIndexVectorUnion &operator=(SparseIndexVectorUnion &&u) FLATBUFFERS_NOEXCEPT + { std::swap(type, u.type); std::swap(value, u.value); return *this; } + ~SparseIndexVectorUnion() { Reset(); } + + void Reset(); + +#ifndef FLATBUFFERS_CPP98_STL + template + void Set(T&& val) { + using RT = typename std::remove_reference::type; + Reset(); + type = SparseIndexVectorTraits::enum_value; + if (type != SparseIndexVector_NONE) { + value = new RT(std::forward(val)); + } + } +#endif // FLATBUFFERS_CPP98_STL + + static void *UnPack(const void *obj, SparseIndexVector type, const flatbuffers::resolver_function_t *resolver); + flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; + + tflite::Int32VectorT *AsInt32Vector() { + return type == SparseIndexVector_Int32Vector ? + reinterpret_cast(value) : nullptr; + } + const tflite::Int32VectorT *AsInt32Vector() const { + return type == SparseIndexVector_Int32Vector ? + reinterpret_cast(value) : nullptr; + } + tflite::Uint16VectorT *AsUint16Vector() { + return type == SparseIndexVector_Uint16Vector ? + reinterpret_cast(value) : nullptr; + } + const tflite::Uint16VectorT *AsUint16Vector() const { + return type == SparseIndexVector_Uint16Vector ? + reinterpret_cast(value) : nullptr; + } + tflite::Uint8VectorT *AsUint8Vector() { + return type == SparseIndexVector_Uint8Vector ? + reinterpret_cast(value) : nullptr; + } + const tflite::Uint8VectorT *AsUint8Vector() const { + return type == SparseIndexVector_Uint8Vector ? + reinterpret_cast(value) : nullptr; + } +}; + +bool VerifySparseIndexVector(flatbuffers::Verifier &verifier, const void *obj, SparseIndexVector type); +bool VerifySparseIndexVectorVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types); + +enum BuiltinOperator { + BuiltinOperator_ADD = 0, + BuiltinOperator_AVERAGE_POOL_2D = 1, + BuiltinOperator_CONCATENATION = 2, + BuiltinOperator_CONV_2D = 3, + BuiltinOperator_DEPTHWISE_CONV_2D = 4, + BuiltinOperator_DEPTH_TO_SPACE = 5, + BuiltinOperator_DEQUANTIZE = 6, + BuiltinOperator_EMBEDDING_LOOKUP = 7, + BuiltinOperator_FLOOR = 8, + BuiltinOperator_FULLY_CONNECTED = 9, + BuiltinOperator_HASHTABLE_LOOKUP = 10, + BuiltinOperator_L2_NORMALIZATION = 11, + BuiltinOperator_L2_POOL_2D = 12, + BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION = 13, + BuiltinOperator_LOGISTIC = 14, + BuiltinOperator_LSH_PROJECTION = 15, + BuiltinOperator_LSTM = 16, + BuiltinOperator_MAX_POOL_2D = 17, + BuiltinOperator_MUL = 18, + BuiltinOperator_RELU = 19, + BuiltinOperator_RELU_N1_TO_1 = 20, + BuiltinOperator_RELU6 = 21, + BuiltinOperator_RESHAPE = 22, + BuiltinOperator_RESIZE_BILINEAR = 23, + BuiltinOperator_RNN = 24, + BuiltinOperator_SOFTMAX = 25, + BuiltinOperator_SPACE_TO_DEPTH = 26, + BuiltinOperator_SVDF = 27, + BuiltinOperator_TANH = 28, + BuiltinOperator_CONCAT_EMBEDDINGS = 29, + BuiltinOperator_SKIP_GRAM = 30, + BuiltinOperator_CALL = 31, + BuiltinOperator_CUSTOM = 32, + BuiltinOperator_EMBEDDING_LOOKUP_SPARSE = 33, + BuiltinOperator_PAD = 34, + BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN = 35, + BuiltinOperator_GATHER = 36, + BuiltinOperator_BATCH_TO_SPACE_ND = 37, + BuiltinOperator_SPACE_TO_BATCH_ND = 38, + BuiltinOperator_TRANSPOSE = 39, + BuiltinOperator_MEAN = 40, + BuiltinOperator_SUB = 41, + BuiltinOperator_DIV = 42, + BuiltinOperator_SQUEEZE = 43, + BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM = 44, + BuiltinOperator_STRIDED_SLICE = 45, + BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN = 46, + BuiltinOperator_EXP = 47, + BuiltinOperator_TOPK_V2 = 48, + BuiltinOperator_SPLIT = 49, + BuiltinOperator_LOG_SOFTMAX = 50, + BuiltinOperator_DELEGATE = 51, + BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM = 52, + BuiltinOperator_CAST = 53, + BuiltinOperator_PRELU = 54, + BuiltinOperator_MAXIMUM = 55, + BuiltinOperator_ARG_MAX = 56, + BuiltinOperator_MINIMUM = 57, + BuiltinOperator_LESS = 58, + BuiltinOperator_NEG = 59, + BuiltinOperator_PADV2 = 60, + BuiltinOperator_GREATER = 61, + BuiltinOperator_GREATER_EQUAL = 62, + BuiltinOperator_LESS_EQUAL = 63, + BuiltinOperator_SELECT = 64, + BuiltinOperator_SLICE = 65, + BuiltinOperator_SIN = 66, + BuiltinOperator_TRANSPOSE_CONV = 67, + BuiltinOperator_SPARSE_TO_DENSE = 68, + BuiltinOperator_TILE = 69, + BuiltinOperator_EXPAND_DIMS = 70, + BuiltinOperator_EQUAL = 71, + BuiltinOperator_NOT_EQUAL = 72, + BuiltinOperator_LOG = 73, + BuiltinOperator_SUM = 74, + BuiltinOperator_SQRT = 75, + BuiltinOperator_RSQRT = 76, + BuiltinOperator_SHAPE = 77, + BuiltinOperator_POW = 78, + BuiltinOperator_ARG_MIN = 79, + BuiltinOperator_FAKE_QUANT = 80, + BuiltinOperator_REDUCE_PROD = 81, + BuiltinOperator_REDUCE_MAX = 82, + BuiltinOperator_PACK = 83, + BuiltinOperator_LOGICAL_OR = 84, + BuiltinOperator_ONE_HOT = 85, + BuiltinOperator_LOGICAL_AND = 86, + BuiltinOperator_LOGICAL_NOT = 87, + BuiltinOperator_UNPACK = 88, + BuiltinOperator_REDUCE_MIN = 89, + BuiltinOperator_FLOOR_DIV = 90, + BuiltinOperator_REDUCE_ANY = 91, + BuiltinOperator_SQUARE = 92, + BuiltinOperator_ZEROS_LIKE = 93, + BuiltinOperator_FILL = 94, + BuiltinOperator_FLOOR_MOD = 95, + BuiltinOperator_RANGE = 96, + BuiltinOperator_RESIZE_NEAREST_NEIGHBOR = 97, + BuiltinOperator_LEAKY_RELU = 98, + BuiltinOperator_SQUARED_DIFFERENCE = 99, + BuiltinOperator_MIRROR_PAD = 100, + BuiltinOperator_ABS = 101, + BuiltinOperator_SPLIT_V = 102, + BuiltinOperator_UNIQUE = 103, + BuiltinOperator_CEIL = 104, + BuiltinOperator_REVERSE_V2 = 105, + BuiltinOperator_ADD_N = 106, + BuiltinOperator_GATHER_ND = 107, + BuiltinOperator_COS = 108, + BuiltinOperator_WHERE = 109, + BuiltinOperator_RANK = 110, + BuiltinOperator_ELU = 111, + BuiltinOperator_REVERSE_SEQUENCE = 112, + BuiltinOperator_MATRIX_DIAG = 113, + BuiltinOperator_QUANTIZE = 114, + BuiltinOperator_MATRIX_SET_DIAG = 115, + BuiltinOperator_ROUND = 116, + BuiltinOperator_HARD_SWISH = 117, + BuiltinOperator_IF = 118, + BuiltinOperator_WHILE = 119, + BuiltinOperator_NON_MAX_SUPPRESSION_V4 = 120, + BuiltinOperator_NON_MAX_SUPPRESSION_V5 = 121, + BuiltinOperator_SCATTER_ND = 122, + BuiltinOperator_SELECT_V2 = 123, + BuiltinOperator_DENSIFY = 124, + BuiltinOperator_SEGMENT_SUM = 125, + BuiltinOperator_BATCH_MATMUL = 126, + BuiltinOperator_MIN = BuiltinOperator_ADD, + BuiltinOperator_MAX = BuiltinOperator_BATCH_MATMUL +}; + +inline const BuiltinOperator (&EnumValuesBuiltinOperator())[127] { + static const BuiltinOperator values[] = { + BuiltinOperator_ADD, + BuiltinOperator_AVERAGE_POOL_2D, + BuiltinOperator_CONCATENATION, + BuiltinOperator_CONV_2D, + BuiltinOperator_DEPTHWISE_CONV_2D, + BuiltinOperator_DEPTH_TO_SPACE, + BuiltinOperator_DEQUANTIZE, + BuiltinOperator_EMBEDDING_LOOKUP, + BuiltinOperator_FLOOR, + BuiltinOperator_FULLY_CONNECTED, + BuiltinOperator_HASHTABLE_LOOKUP, + BuiltinOperator_L2_NORMALIZATION, + BuiltinOperator_L2_POOL_2D, + BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION, + BuiltinOperator_LOGISTIC, + BuiltinOperator_LSH_PROJECTION, + BuiltinOperator_LSTM, + BuiltinOperator_MAX_POOL_2D, + BuiltinOperator_MUL, + BuiltinOperator_RELU, + BuiltinOperator_RELU_N1_TO_1, + BuiltinOperator_RELU6, + BuiltinOperator_RESHAPE, + BuiltinOperator_RESIZE_BILINEAR, + BuiltinOperator_RNN, + BuiltinOperator_SOFTMAX, + BuiltinOperator_SPACE_TO_DEPTH, + BuiltinOperator_SVDF, + BuiltinOperator_TANH, + BuiltinOperator_CONCAT_EMBEDDINGS, + BuiltinOperator_SKIP_GRAM, + BuiltinOperator_CALL, + BuiltinOperator_CUSTOM, + BuiltinOperator_EMBEDDING_LOOKUP_SPARSE, + BuiltinOperator_PAD, + BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_RNN, + BuiltinOperator_GATHER, + BuiltinOperator_BATCH_TO_SPACE_ND, + BuiltinOperator_SPACE_TO_BATCH_ND, + BuiltinOperator_TRANSPOSE, + BuiltinOperator_MEAN, + BuiltinOperator_SUB, + BuiltinOperator_DIV, + BuiltinOperator_SQUEEZE, + BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM, + BuiltinOperator_STRIDED_SLICE, + BuiltinOperator_BIDIRECTIONAL_SEQUENCE_RNN, + BuiltinOperator_EXP, + BuiltinOperator_TOPK_V2, + BuiltinOperator_SPLIT, + BuiltinOperator_LOG_SOFTMAX, + BuiltinOperator_DELEGATE, + BuiltinOperator_BIDIRECTIONAL_SEQUENCE_LSTM, + BuiltinOperator_CAST, + BuiltinOperator_PRELU, + BuiltinOperator_MAXIMUM, + BuiltinOperator_ARG_MAX, + BuiltinOperator_MINIMUM, + BuiltinOperator_LESS, + BuiltinOperator_NEG, + BuiltinOperator_PADV2, + BuiltinOperator_GREATER, + BuiltinOperator_GREATER_EQUAL, + BuiltinOperator_LESS_EQUAL, + BuiltinOperator_SELECT, + BuiltinOperator_SLICE, + BuiltinOperator_SIN, + BuiltinOperator_TRANSPOSE_CONV, + BuiltinOperator_SPARSE_TO_DENSE, + BuiltinOperator_TILE, + BuiltinOperator_EXPAND_DIMS, + BuiltinOperator_EQUAL, + BuiltinOperator_NOT_EQUAL, + BuiltinOperator_LOG, + BuiltinOperator_SUM, + BuiltinOperator_SQRT, + BuiltinOperator_RSQRT, + BuiltinOperator_SHAPE, + BuiltinOperator_POW, + BuiltinOperator_ARG_MIN, + BuiltinOperator_FAKE_QUANT, + BuiltinOperator_REDUCE_PROD, + BuiltinOperator_REDUCE_MAX, + BuiltinOperator_PACK, + BuiltinOperator_LOGICAL_OR, + BuiltinOperator_ONE_HOT, + BuiltinOperator_LOGICAL_AND, + BuiltinOperator_LOGICAL_NOT, + BuiltinOperator_UNPACK, + BuiltinOperator_REDUCE_MIN, + BuiltinOperator_FLOOR_DIV, + BuiltinOperator_REDUCE_ANY, + BuiltinOperator_SQUARE, + BuiltinOperator_ZEROS_LIKE, + BuiltinOperator_FILL, + BuiltinOperator_FLOOR_MOD, + BuiltinOperator_RANGE, + BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, + BuiltinOperator_LEAKY_RELU, + BuiltinOperator_SQUARED_DIFFERENCE, + BuiltinOperator_MIRROR_PAD, + BuiltinOperator_ABS, + BuiltinOperator_SPLIT_V, + BuiltinOperator_UNIQUE, + BuiltinOperator_CEIL, + BuiltinOperator_REVERSE_V2, + BuiltinOperator_ADD_N, + BuiltinOperator_GATHER_ND, + BuiltinOperator_COS, + BuiltinOperator_WHERE, + BuiltinOperator_RANK, + BuiltinOperator_ELU, + BuiltinOperator_REVERSE_SEQUENCE, + BuiltinOperator_MATRIX_DIAG, + BuiltinOperator_QUANTIZE, + BuiltinOperator_MATRIX_SET_DIAG, + BuiltinOperator_ROUND, + BuiltinOperator_HARD_SWISH, + BuiltinOperator_IF, + BuiltinOperator_WHILE, + BuiltinOperator_NON_MAX_SUPPRESSION_V4, + BuiltinOperator_NON_MAX_SUPPRESSION_V5, + BuiltinOperator_SCATTER_ND, + BuiltinOperator_SELECT_V2, + BuiltinOperator_DENSIFY, + BuiltinOperator_SEGMENT_SUM, + BuiltinOperator_BATCH_MATMUL + }; + return values; +} + +inline const char * const *EnumNamesBuiltinOperator() { + static const char * const names[128] = { + "ADD", + "AVERAGE_POOL_2D", + "CONCATENATION", + "CONV_2D", + "DEPTHWISE_CONV_2D", + "DEPTH_TO_SPACE", + "DEQUANTIZE", + "EMBEDDING_LOOKUP", + "FLOOR", + "FULLY_CONNECTED", + "HASHTABLE_LOOKUP", + "L2_NORMALIZATION", + "L2_POOL_2D", + "LOCAL_RESPONSE_NORMALIZATION", + "LOGISTIC", + "LSH_PROJECTION", + "LSTM", + "MAX_POOL_2D", + "MUL", + "RELU", + "RELU_N1_TO_1", + "RELU6", + "RESHAPE", + "RESIZE_BILINEAR", + "RNN", + "SOFTMAX", + "SPACE_TO_DEPTH", + "SVDF", + "TANH", + "CONCAT_EMBEDDINGS", + "SKIP_GRAM", + "CALL", + "CUSTOM", + "EMBEDDING_LOOKUP_SPARSE", + "PAD", + "UNIDIRECTIONAL_SEQUENCE_RNN", + "GATHER", + "BATCH_TO_SPACE_ND", + "SPACE_TO_BATCH_ND", + "TRANSPOSE", + "MEAN", + "SUB", + "DIV", + "SQUEEZE", + "UNIDIRECTIONAL_SEQUENCE_LSTM", + "STRIDED_SLICE", + "BIDIRECTIONAL_SEQUENCE_RNN", + "EXP", + "TOPK_V2", + "SPLIT", + "LOG_SOFTMAX", + "DELEGATE", + "BIDIRECTIONAL_SEQUENCE_LSTM", + "CAST", + "PRELU", + "MAXIMUM", + "ARG_MAX", + "MINIMUM", + "LESS", + "NEG", + "PADV2", + "GREATER", + "GREATER_EQUAL", + "LESS_EQUAL", + "SELECT", + "SLICE", + "SIN", + "TRANSPOSE_CONV", + "SPARSE_TO_DENSE", + "TILE", + "EXPAND_DIMS", + "EQUAL", + "NOT_EQUAL", + "LOG", + "SUM", + "SQRT", + "RSQRT", + "SHAPE", + "POW", + "ARG_MIN", + "FAKE_QUANT", + "REDUCE_PROD", + "REDUCE_MAX", + "PACK", + "LOGICAL_OR", + "ONE_HOT", + "LOGICAL_AND", + "LOGICAL_NOT", + "UNPACK", + "REDUCE_MIN", + "FLOOR_DIV", + "REDUCE_ANY", + "SQUARE", + "ZEROS_LIKE", + "FILL", + "FLOOR_MOD", + "RANGE", + "RESIZE_NEAREST_NEIGHBOR", + "LEAKY_RELU", + "SQUARED_DIFFERENCE", + "MIRROR_PAD", + "ABS", + "SPLIT_V", + "UNIQUE", + "CEIL", + "REVERSE_V2", + "ADD_N", + "GATHER_ND", + "COS", + "WHERE", + "RANK", + "ELU", + "REVERSE_SEQUENCE", + "MATRIX_DIAG", + "QUANTIZE", + "MATRIX_SET_DIAG", + "ROUND", + "HARD_SWISH", + "IF", + "WHILE", + "NON_MAX_SUPPRESSION_V4", + "NON_MAX_SUPPRESSION_V5", + "SCATTER_ND", + "SELECT_V2", + "DENSIFY", + "SEGMENT_SUM", + "BATCH_MATMUL", + nullptr + }; + return names; +} + +inline const char *EnumNameBuiltinOperator(BuiltinOperator e) { + if (flatbuffers::IsOutRange(e, BuiltinOperator_ADD, BuiltinOperator_BATCH_MATMUL)) return ""; + const size_t index = static_cast(e); + return EnumNamesBuiltinOperator()[index]; +} + +enum BuiltinOptions { + BuiltinOptions_NONE = 0, + BuiltinOptions_Conv2DOptions = 1, + BuiltinOptions_DepthwiseConv2DOptions = 2, + BuiltinOptions_ConcatEmbeddingsOptions = 3, + BuiltinOptions_LSHProjectionOptions = 4, + BuiltinOptions_Pool2DOptions = 5, + BuiltinOptions_SVDFOptions = 6, + BuiltinOptions_RNNOptions = 7, + BuiltinOptions_FullyConnectedOptions = 8, + BuiltinOptions_SoftmaxOptions = 9, + BuiltinOptions_ConcatenationOptions = 10, + BuiltinOptions_AddOptions = 11, + BuiltinOptions_L2NormOptions = 12, + BuiltinOptions_LocalResponseNormalizationOptions = 13, + BuiltinOptions_LSTMOptions = 14, + BuiltinOptions_ResizeBilinearOptions = 15, + BuiltinOptions_CallOptions = 16, + BuiltinOptions_ReshapeOptions = 17, + BuiltinOptions_SkipGramOptions = 18, + BuiltinOptions_SpaceToDepthOptions = 19, + BuiltinOptions_EmbeddingLookupSparseOptions = 20, + BuiltinOptions_MulOptions = 21, + BuiltinOptions_PadOptions = 22, + BuiltinOptions_GatherOptions = 23, + BuiltinOptions_BatchToSpaceNDOptions = 24, + BuiltinOptions_SpaceToBatchNDOptions = 25, + BuiltinOptions_TransposeOptions = 26, + BuiltinOptions_ReducerOptions = 27, + BuiltinOptions_SubOptions = 28, + BuiltinOptions_DivOptions = 29, + BuiltinOptions_SqueezeOptions = 30, + BuiltinOptions_SequenceRNNOptions = 31, + BuiltinOptions_StridedSliceOptions = 32, + BuiltinOptions_ExpOptions = 33, + BuiltinOptions_TopKV2Options = 34, + BuiltinOptions_SplitOptions = 35, + BuiltinOptions_LogSoftmaxOptions = 36, + BuiltinOptions_CastOptions = 37, + BuiltinOptions_DequantizeOptions = 38, + BuiltinOptions_MaximumMinimumOptions = 39, + BuiltinOptions_ArgMaxOptions = 40, + BuiltinOptions_LessOptions = 41, + BuiltinOptions_NegOptions = 42, + BuiltinOptions_PadV2Options = 43, + BuiltinOptions_GreaterOptions = 44, + BuiltinOptions_GreaterEqualOptions = 45, + BuiltinOptions_LessEqualOptions = 46, + BuiltinOptions_SelectOptions = 47, + BuiltinOptions_SliceOptions = 48, + BuiltinOptions_TransposeConvOptions = 49, + BuiltinOptions_SparseToDenseOptions = 50, + BuiltinOptions_TileOptions = 51, + BuiltinOptions_ExpandDimsOptions = 52, + BuiltinOptions_EqualOptions = 53, + BuiltinOptions_NotEqualOptions = 54, + BuiltinOptions_ShapeOptions = 55, + BuiltinOptions_PowOptions = 56, + BuiltinOptions_ArgMinOptions = 57, + BuiltinOptions_FakeQuantOptions = 58, + BuiltinOptions_PackOptions = 59, + BuiltinOptions_LogicalOrOptions = 60, + BuiltinOptions_OneHotOptions = 61, + BuiltinOptions_LogicalAndOptions = 62, + BuiltinOptions_LogicalNotOptions = 63, + BuiltinOptions_UnpackOptions = 64, + BuiltinOptions_FloorDivOptions = 65, + BuiltinOptions_SquareOptions = 66, + BuiltinOptions_ZerosLikeOptions = 67, + BuiltinOptions_FillOptions = 68, + BuiltinOptions_BidirectionalSequenceLSTMOptions = 69, + BuiltinOptions_BidirectionalSequenceRNNOptions = 70, + BuiltinOptions_UnidirectionalSequenceLSTMOptions = 71, + BuiltinOptions_FloorModOptions = 72, + BuiltinOptions_RangeOptions = 73, + BuiltinOptions_ResizeNearestNeighborOptions = 74, + BuiltinOptions_LeakyReluOptions = 75, + BuiltinOptions_SquaredDifferenceOptions = 76, + BuiltinOptions_MirrorPadOptions = 77, + BuiltinOptions_AbsOptions = 78, + BuiltinOptions_SplitVOptions = 79, + BuiltinOptions_UniqueOptions = 80, + BuiltinOptions_ReverseV2Options = 81, + BuiltinOptions_AddNOptions = 82, + BuiltinOptions_GatherNdOptions = 83, + BuiltinOptions_CosOptions = 84, + BuiltinOptions_WhereOptions = 85, + BuiltinOptions_RankOptions = 86, + BuiltinOptions_ReverseSequenceOptions = 87, + BuiltinOptions_MatrixDiagOptions = 88, + BuiltinOptions_QuantizeOptions = 89, + BuiltinOptions_MatrixSetDiagOptions = 90, + BuiltinOptions_HardSwishOptions = 91, + BuiltinOptions_IfOptions = 92, + BuiltinOptions_WhileOptions = 93, + BuiltinOptions_DepthToSpaceOptions = 94, + BuiltinOptions_NonMaxSuppressionV4Options = 95, + BuiltinOptions_NonMaxSuppressionV5Options = 96, + BuiltinOptions_ScatterNdOptions = 97, + BuiltinOptions_SelectV2Options = 98, + BuiltinOptions_DensifyOptions = 99, + BuiltinOptions_SegmentSumOptions = 100, + BuiltinOptions_BatchMatMulOptions = 101, + BuiltinOptions_MIN = BuiltinOptions_NONE, + BuiltinOptions_MAX = BuiltinOptions_BatchMatMulOptions +}; + +inline const BuiltinOptions (&EnumValuesBuiltinOptions())[102] { + static const BuiltinOptions values[] = { + BuiltinOptions_NONE, + BuiltinOptions_Conv2DOptions, + BuiltinOptions_DepthwiseConv2DOptions, + BuiltinOptions_ConcatEmbeddingsOptions, + BuiltinOptions_LSHProjectionOptions, + BuiltinOptions_Pool2DOptions, + BuiltinOptions_SVDFOptions, + BuiltinOptions_RNNOptions, + BuiltinOptions_FullyConnectedOptions, + BuiltinOptions_SoftmaxOptions, + BuiltinOptions_ConcatenationOptions, + BuiltinOptions_AddOptions, + BuiltinOptions_L2NormOptions, + BuiltinOptions_LocalResponseNormalizationOptions, + BuiltinOptions_LSTMOptions, + BuiltinOptions_ResizeBilinearOptions, + BuiltinOptions_CallOptions, + BuiltinOptions_ReshapeOptions, + BuiltinOptions_SkipGramOptions, + BuiltinOptions_SpaceToDepthOptions, + BuiltinOptions_EmbeddingLookupSparseOptions, + BuiltinOptions_MulOptions, + BuiltinOptions_PadOptions, + BuiltinOptions_GatherOptions, + BuiltinOptions_BatchToSpaceNDOptions, + BuiltinOptions_SpaceToBatchNDOptions, + BuiltinOptions_TransposeOptions, + BuiltinOptions_ReducerOptions, + BuiltinOptions_SubOptions, + BuiltinOptions_DivOptions, + BuiltinOptions_SqueezeOptions, + BuiltinOptions_SequenceRNNOptions, + BuiltinOptions_StridedSliceOptions, + BuiltinOptions_ExpOptions, + BuiltinOptions_TopKV2Options, + BuiltinOptions_SplitOptions, + BuiltinOptions_LogSoftmaxOptions, + BuiltinOptions_CastOptions, + BuiltinOptions_DequantizeOptions, + BuiltinOptions_MaximumMinimumOptions, + BuiltinOptions_ArgMaxOptions, + BuiltinOptions_LessOptions, + BuiltinOptions_NegOptions, + BuiltinOptions_PadV2Options, + BuiltinOptions_GreaterOptions, + BuiltinOptions_GreaterEqualOptions, + BuiltinOptions_LessEqualOptions, + BuiltinOptions_SelectOptions, + BuiltinOptions_SliceOptions, + BuiltinOptions_TransposeConvOptions, + BuiltinOptions_SparseToDenseOptions, + BuiltinOptions_TileOptions, + BuiltinOptions_ExpandDimsOptions, + BuiltinOptions_EqualOptions, + BuiltinOptions_NotEqualOptions, + BuiltinOptions_ShapeOptions, + BuiltinOptions_PowOptions, + BuiltinOptions_ArgMinOptions, + BuiltinOptions_FakeQuantOptions, + BuiltinOptions_PackOptions, + BuiltinOptions_LogicalOrOptions, + BuiltinOptions_OneHotOptions, + BuiltinOptions_LogicalAndOptions, + BuiltinOptions_LogicalNotOptions, + BuiltinOptions_UnpackOptions, + BuiltinOptions_FloorDivOptions, + BuiltinOptions_SquareOptions, + BuiltinOptions_ZerosLikeOptions, + BuiltinOptions_FillOptions, + BuiltinOptions_BidirectionalSequenceLSTMOptions, + BuiltinOptions_BidirectionalSequenceRNNOptions, + BuiltinOptions_UnidirectionalSequenceLSTMOptions, + BuiltinOptions_FloorModOptions, + BuiltinOptions_RangeOptions, + BuiltinOptions_ResizeNearestNeighborOptions, + BuiltinOptions_LeakyReluOptions, + BuiltinOptions_SquaredDifferenceOptions, + BuiltinOptions_MirrorPadOptions, + BuiltinOptions_AbsOptions, + BuiltinOptions_SplitVOptions, + BuiltinOptions_UniqueOptions, + BuiltinOptions_ReverseV2Options, + BuiltinOptions_AddNOptions, + BuiltinOptions_GatherNdOptions, + BuiltinOptions_CosOptions, + BuiltinOptions_WhereOptions, + BuiltinOptions_RankOptions, + BuiltinOptions_ReverseSequenceOptions, + BuiltinOptions_MatrixDiagOptions, + BuiltinOptions_QuantizeOptions, + BuiltinOptions_MatrixSetDiagOptions, + BuiltinOptions_HardSwishOptions, + BuiltinOptions_IfOptions, + BuiltinOptions_WhileOptions, + BuiltinOptions_DepthToSpaceOptions, + BuiltinOptions_NonMaxSuppressionV4Options, + BuiltinOptions_NonMaxSuppressionV5Options, + BuiltinOptions_ScatterNdOptions, + BuiltinOptions_SelectV2Options, + BuiltinOptions_DensifyOptions, + BuiltinOptions_SegmentSumOptions, + BuiltinOptions_BatchMatMulOptions + }; + return values; +} + +inline const char * const *EnumNamesBuiltinOptions() { + static const char * const names[103] = { + "NONE", + "Conv2DOptions", + "DepthwiseConv2DOptions", + "ConcatEmbeddingsOptions", + "LSHProjectionOptions", + "Pool2DOptions", + "SVDFOptions", + "RNNOptions", + "FullyConnectedOptions", + "SoftmaxOptions", + "ConcatenationOptions", + "AddOptions", + "L2NormOptions", + "LocalResponseNormalizationOptions", + "LSTMOptions", + "ResizeBilinearOptions", + "CallOptions", + "ReshapeOptions", + "SkipGramOptions", + "SpaceToDepthOptions", + "EmbeddingLookupSparseOptions", + "MulOptions", + "PadOptions", + "GatherOptions", + "BatchToSpaceNDOptions", + "SpaceToBatchNDOptions", + "TransposeOptions", + "ReducerOptions", + "SubOptions", + "DivOptions", + "SqueezeOptions", + "SequenceRNNOptions", + "StridedSliceOptions", + "ExpOptions", + "TopKV2Options", + "SplitOptions", + "LogSoftmaxOptions", + "CastOptions", + "DequantizeOptions", + "MaximumMinimumOptions", + "ArgMaxOptions", + "LessOptions", + "NegOptions", + "PadV2Options", + "GreaterOptions", + "GreaterEqualOptions", + "LessEqualOptions", + "SelectOptions", + "SliceOptions", + "TransposeConvOptions", + "SparseToDenseOptions", + "TileOptions", + "ExpandDimsOptions", + "EqualOptions", + "NotEqualOptions", + "ShapeOptions", + "PowOptions", + "ArgMinOptions", + "FakeQuantOptions", + "PackOptions", + "LogicalOrOptions", + "OneHotOptions", + "LogicalAndOptions", + "LogicalNotOptions", + "UnpackOptions", + "FloorDivOptions", + "SquareOptions", + "ZerosLikeOptions", + "FillOptions", + "BidirectionalSequenceLSTMOptions", + "BidirectionalSequenceRNNOptions", + "UnidirectionalSequenceLSTMOptions", + "FloorModOptions", + "RangeOptions", + "ResizeNearestNeighborOptions", + "LeakyReluOptions", + "SquaredDifferenceOptions", + "MirrorPadOptions", + "AbsOptions", + "SplitVOptions", + "UniqueOptions", + "ReverseV2Options", + "AddNOptions", + "GatherNdOptions", + "CosOptions", + "WhereOptions", + "RankOptions", + "ReverseSequenceOptions", + "MatrixDiagOptions", + "QuantizeOptions", + "MatrixSetDiagOptions", + "HardSwishOptions", + "IfOptions", + "WhileOptions", + "DepthToSpaceOptions", + "NonMaxSuppressionV4Options", + "NonMaxSuppressionV5Options", + "ScatterNdOptions", + "SelectV2Options", + "DensifyOptions", + "SegmentSumOptions", + "BatchMatMulOptions", + nullptr + }; + return names; +} + +inline const char *EnumNameBuiltinOptions(BuiltinOptions e) { + if (flatbuffers::IsOutRange(e, BuiltinOptions_NONE, BuiltinOptions_BatchMatMulOptions)) return ""; + const size_t index = static_cast(e); + return EnumNamesBuiltinOptions()[index]; +} + +template struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_NONE; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_Conv2DOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_DepthwiseConv2DOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ConcatEmbeddingsOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LSHProjectionOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_Pool2DOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SVDFOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_RNNOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_FullyConnectedOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SoftmaxOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ConcatenationOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_AddOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_L2NormOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LocalResponseNormalizationOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LSTMOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ResizeBilinearOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_CallOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ReshapeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SkipGramOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SpaceToDepthOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_EmbeddingLookupSparseOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_MulOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_PadOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_GatherOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_BatchToSpaceNDOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SpaceToBatchNDOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_TransposeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ReducerOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SubOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_DivOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SqueezeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SequenceRNNOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_StridedSliceOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ExpOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_TopKV2Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SplitOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LogSoftmaxOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_CastOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_DequantizeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_MaximumMinimumOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ArgMaxOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LessOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_NegOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_PadV2Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_GreaterOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_GreaterEqualOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LessEqualOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SelectOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SliceOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_TransposeConvOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SparseToDenseOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_TileOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ExpandDimsOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_EqualOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_NotEqualOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ShapeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_PowOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ArgMinOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_FakeQuantOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_PackOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LogicalOrOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_OneHotOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LogicalAndOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LogicalNotOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_UnpackOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_FloorDivOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SquareOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ZerosLikeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_FillOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_BidirectionalSequenceLSTMOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_BidirectionalSequenceRNNOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_UnidirectionalSequenceLSTMOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_FloorModOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_RangeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ResizeNearestNeighborOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_LeakyReluOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SquaredDifferenceOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_MirrorPadOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_AbsOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SplitVOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_UniqueOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ReverseV2Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_AddNOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_GatherNdOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_CosOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_WhereOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_RankOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ReverseSequenceOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_MatrixDiagOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_QuantizeOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_MatrixSetDiagOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_HardSwishOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_IfOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_WhileOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_DepthToSpaceOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_NonMaxSuppressionV4Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_NonMaxSuppressionV5Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_ScatterNdOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SelectV2Options; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_DensifyOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_SegmentSumOptions; +}; + +template<> struct BuiltinOptionsTraits { + static const BuiltinOptions enum_value = BuiltinOptions_BatchMatMulOptions; +}; + +struct BuiltinOptionsUnion { + BuiltinOptions type; + void *value; + + BuiltinOptionsUnion() : type(BuiltinOptions_NONE), value(nullptr) {} + BuiltinOptionsUnion(BuiltinOptionsUnion&& u) FLATBUFFERS_NOEXCEPT : + type(BuiltinOptions_NONE), value(nullptr) + { std::swap(type, u.type); std::swap(value, u.value); } + BuiltinOptionsUnion(const BuiltinOptionsUnion &) FLATBUFFERS_NOEXCEPT; + BuiltinOptionsUnion &operator=(const BuiltinOptionsUnion &u) FLATBUFFERS_NOEXCEPT + { BuiltinOptionsUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } + BuiltinOptionsUnion &operator=(BuiltinOptionsUnion &&u) FLATBUFFERS_NOEXCEPT + { std::swap(type, u.type); std::swap(value, u.value); return *this; } + ~BuiltinOptionsUnion() { Reset(); } + + void Reset(); + +#ifndef FLATBUFFERS_CPP98_STL + template + void Set(T&& val) { + using RT = typename std::remove_reference::type; + Reset(); + type = BuiltinOptionsTraits::enum_value; + if (type != BuiltinOptions_NONE) { + value = new RT(std::forward(val)); + } + } +#endif // FLATBUFFERS_CPP98_STL + + static void *UnPack(const void *obj, BuiltinOptions type, const flatbuffers::resolver_function_t *resolver); + flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; + + tflite::Conv2DOptionsT *AsConv2DOptions() { + return type == BuiltinOptions_Conv2DOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::Conv2DOptionsT *AsConv2DOptions() const { + return type == BuiltinOptions_Conv2DOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::DepthwiseConv2DOptionsT *AsDepthwiseConv2DOptions() { + return type == BuiltinOptions_DepthwiseConv2DOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::DepthwiseConv2DOptionsT *AsDepthwiseConv2DOptions() const { + return type == BuiltinOptions_DepthwiseConv2DOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ConcatEmbeddingsOptionsT *AsConcatEmbeddingsOptions() { + return type == BuiltinOptions_ConcatEmbeddingsOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ConcatEmbeddingsOptionsT *AsConcatEmbeddingsOptions() const { + return type == BuiltinOptions_ConcatEmbeddingsOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LSHProjectionOptionsT *AsLSHProjectionOptions() { + return type == BuiltinOptions_LSHProjectionOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LSHProjectionOptionsT *AsLSHProjectionOptions() const { + return type == BuiltinOptions_LSHProjectionOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::Pool2DOptionsT *AsPool2DOptions() { + return type == BuiltinOptions_Pool2DOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::Pool2DOptionsT *AsPool2DOptions() const { + return type == BuiltinOptions_Pool2DOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SVDFOptionsT *AsSVDFOptions() { + return type == BuiltinOptions_SVDFOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SVDFOptionsT *AsSVDFOptions() const { + return type == BuiltinOptions_SVDFOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::RNNOptionsT *AsRNNOptions() { + return type == BuiltinOptions_RNNOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::RNNOptionsT *AsRNNOptions() const { + return type == BuiltinOptions_RNNOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::FullyConnectedOptionsT *AsFullyConnectedOptions() { + return type == BuiltinOptions_FullyConnectedOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::FullyConnectedOptionsT *AsFullyConnectedOptions() const { + return type == BuiltinOptions_FullyConnectedOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SoftmaxOptionsT *AsSoftmaxOptions() { + return type == BuiltinOptions_SoftmaxOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SoftmaxOptionsT *AsSoftmaxOptions() const { + return type == BuiltinOptions_SoftmaxOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ConcatenationOptionsT *AsConcatenationOptions() { + return type == BuiltinOptions_ConcatenationOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ConcatenationOptionsT *AsConcatenationOptions() const { + return type == BuiltinOptions_ConcatenationOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::AddOptionsT *AsAddOptions() { + return type == BuiltinOptions_AddOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::AddOptionsT *AsAddOptions() const { + return type == BuiltinOptions_AddOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::L2NormOptionsT *AsL2NormOptions() { + return type == BuiltinOptions_L2NormOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::L2NormOptionsT *AsL2NormOptions() const { + return type == BuiltinOptions_L2NormOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LocalResponseNormalizationOptionsT *AsLocalResponseNormalizationOptions() { + return type == BuiltinOptions_LocalResponseNormalizationOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LocalResponseNormalizationOptionsT *AsLocalResponseNormalizationOptions() const { + return type == BuiltinOptions_LocalResponseNormalizationOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LSTMOptionsT *AsLSTMOptions() { + return type == BuiltinOptions_LSTMOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LSTMOptionsT *AsLSTMOptions() const { + return type == BuiltinOptions_LSTMOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ResizeBilinearOptionsT *AsResizeBilinearOptions() { + return type == BuiltinOptions_ResizeBilinearOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ResizeBilinearOptionsT *AsResizeBilinearOptions() const { + return type == BuiltinOptions_ResizeBilinearOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::CallOptionsT *AsCallOptions() { + return type == BuiltinOptions_CallOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::CallOptionsT *AsCallOptions() const { + return type == BuiltinOptions_CallOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ReshapeOptionsT *AsReshapeOptions() { + return type == BuiltinOptions_ReshapeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ReshapeOptionsT *AsReshapeOptions() const { + return type == BuiltinOptions_ReshapeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SkipGramOptionsT *AsSkipGramOptions() { + return type == BuiltinOptions_SkipGramOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SkipGramOptionsT *AsSkipGramOptions() const { + return type == BuiltinOptions_SkipGramOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SpaceToDepthOptionsT *AsSpaceToDepthOptions() { + return type == BuiltinOptions_SpaceToDepthOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SpaceToDepthOptionsT *AsSpaceToDepthOptions() const { + return type == BuiltinOptions_SpaceToDepthOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::EmbeddingLookupSparseOptionsT *AsEmbeddingLookupSparseOptions() { + return type == BuiltinOptions_EmbeddingLookupSparseOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::EmbeddingLookupSparseOptionsT *AsEmbeddingLookupSparseOptions() const { + return type == BuiltinOptions_EmbeddingLookupSparseOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::MulOptionsT *AsMulOptions() { + return type == BuiltinOptions_MulOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::MulOptionsT *AsMulOptions() const { + return type == BuiltinOptions_MulOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::PadOptionsT *AsPadOptions() { + return type == BuiltinOptions_PadOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::PadOptionsT *AsPadOptions() const { + return type == BuiltinOptions_PadOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::GatherOptionsT *AsGatherOptions() { + return type == BuiltinOptions_GatherOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::GatherOptionsT *AsGatherOptions() const { + return type == BuiltinOptions_GatherOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::BatchToSpaceNDOptionsT *AsBatchToSpaceNDOptions() { + return type == BuiltinOptions_BatchToSpaceNDOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::BatchToSpaceNDOptionsT *AsBatchToSpaceNDOptions() const { + return type == BuiltinOptions_BatchToSpaceNDOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SpaceToBatchNDOptionsT *AsSpaceToBatchNDOptions() { + return type == BuiltinOptions_SpaceToBatchNDOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SpaceToBatchNDOptionsT *AsSpaceToBatchNDOptions() const { + return type == BuiltinOptions_SpaceToBatchNDOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::TransposeOptionsT *AsTransposeOptions() { + return type == BuiltinOptions_TransposeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::TransposeOptionsT *AsTransposeOptions() const { + return type == BuiltinOptions_TransposeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ReducerOptionsT *AsReducerOptions() { + return type == BuiltinOptions_ReducerOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ReducerOptionsT *AsReducerOptions() const { + return type == BuiltinOptions_ReducerOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SubOptionsT *AsSubOptions() { + return type == BuiltinOptions_SubOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SubOptionsT *AsSubOptions() const { + return type == BuiltinOptions_SubOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::DivOptionsT *AsDivOptions() { + return type == BuiltinOptions_DivOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::DivOptionsT *AsDivOptions() const { + return type == BuiltinOptions_DivOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SqueezeOptionsT *AsSqueezeOptions() { + return type == BuiltinOptions_SqueezeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SqueezeOptionsT *AsSqueezeOptions() const { + return type == BuiltinOptions_SqueezeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SequenceRNNOptionsT *AsSequenceRNNOptions() { + return type == BuiltinOptions_SequenceRNNOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SequenceRNNOptionsT *AsSequenceRNNOptions() const { + return type == BuiltinOptions_SequenceRNNOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::StridedSliceOptionsT *AsStridedSliceOptions() { + return type == BuiltinOptions_StridedSliceOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::StridedSliceOptionsT *AsStridedSliceOptions() const { + return type == BuiltinOptions_StridedSliceOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ExpOptionsT *AsExpOptions() { + return type == BuiltinOptions_ExpOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ExpOptionsT *AsExpOptions() const { + return type == BuiltinOptions_ExpOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::TopKV2OptionsT *AsTopKV2Options() { + return type == BuiltinOptions_TopKV2Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::TopKV2OptionsT *AsTopKV2Options() const { + return type == BuiltinOptions_TopKV2Options ? + reinterpret_cast(value) : nullptr; + } + tflite::SplitOptionsT *AsSplitOptions() { + return type == BuiltinOptions_SplitOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SplitOptionsT *AsSplitOptions() const { + return type == BuiltinOptions_SplitOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LogSoftmaxOptionsT *AsLogSoftmaxOptions() { + return type == BuiltinOptions_LogSoftmaxOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LogSoftmaxOptionsT *AsLogSoftmaxOptions() const { + return type == BuiltinOptions_LogSoftmaxOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::CastOptionsT *AsCastOptions() { + return type == BuiltinOptions_CastOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::CastOptionsT *AsCastOptions() const { + return type == BuiltinOptions_CastOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::DequantizeOptionsT *AsDequantizeOptions() { + return type == BuiltinOptions_DequantizeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::DequantizeOptionsT *AsDequantizeOptions() const { + return type == BuiltinOptions_DequantizeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::MaximumMinimumOptionsT *AsMaximumMinimumOptions() { + return type == BuiltinOptions_MaximumMinimumOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::MaximumMinimumOptionsT *AsMaximumMinimumOptions() const { + return type == BuiltinOptions_MaximumMinimumOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ArgMaxOptionsT *AsArgMaxOptions() { + return type == BuiltinOptions_ArgMaxOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ArgMaxOptionsT *AsArgMaxOptions() const { + return type == BuiltinOptions_ArgMaxOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LessOptionsT *AsLessOptions() { + return type == BuiltinOptions_LessOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LessOptionsT *AsLessOptions() const { + return type == BuiltinOptions_LessOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::NegOptionsT *AsNegOptions() { + return type == BuiltinOptions_NegOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::NegOptionsT *AsNegOptions() const { + return type == BuiltinOptions_NegOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::PadV2OptionsT *AsPadV2Options() { + return type == BuiltinOptions_PadV2Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::PadV2OptionsT *AsPadV2Options() const { + return type == BuiltinOptions_PadV2Options ? + reinterpret_cast(value) : nullptr; + } + tflite::GreaterOptionsT *AsGreaterOptions() { + return type == BuiltinOptions_GreaterOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::GreaterOptionsT *AsGreaterOptions() const { + return type == BuiltinOptions_GreaterOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::GreaterEqualOptionsT *AsGreaterEqualOptions() { + return type == BuiltinOptions_GreaterEqualOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::GreaterEqualOptionsT *AsGreaterEqualOptions() const { + return type == BuiltinOptions_GreaterEqualOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LessEqualOptionsT *AsLessEqualOptions() { + return type == BuiltinOptions_LessEqualOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LessEqualOptionsT *AsLessEqualOptions() const { + return type == BuiltinOptions_LessEqualOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SelectOptionsT *AsSelectOptions() { + return type == BuiltinOptions_SelectOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SelectOptionsT *AsSelectOptions() const { + return type == BuiltinOptions_SelectOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SliceOptionsT *AsSliceOptions() { + return type == BuiltinOptions_SliceOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SliceOptionsT *AsSliceOptions() const { + return type == BuiltinOptions_SliceOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::TransposeConvOptionsT *AsTransposeConvOptions() { + return type == BuiltinOptions_TransposeConvOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::TransposeConvOptionsT *AsTransposeConvOptions() const { + return type == BuiltinOptions_TransposeConvOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SparseToDenseOptionsT *AsSparseToDenseOptions() { + return type == BuiltinOptions_SparseToDenseOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SparseToDenseOptionsT *AsSparseToDenseOptions() const { + return type == BuiltinOptions_SparseToDenseOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::TileOptionsT *AsTileOptions() { + return type == BuiltinOptions_TileOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::TileOptionsT *AsTileOptions() const { + return type == BuiltinOptions_TileOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ExpandDimsOptionsT *AsExpandDimsOptions() { + return type == BuiltinOptions_ExpandDimsOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ExpandDimsOptionsT *AsExpandDimsOptions() const { + return type == BuiltinOptions_ExpandDimsOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::EqualOptionsT *AsEqualOptions() { + return type == BuiltinOptions_EqualOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::EqualOptionsT *AsEqualOptions() const { + return type == BuiltinOptions_EqualOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::NotEqualOptionsT *AsNotEqualOptions() { + return type == BuiltinOptions_NotEqualOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::NotEqualOptionsT *AsNotEqualOptions() const { + return type == BuiltinOptions_NotEqualOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ShapeOptionsT *AsShapeOptions() { + return type == BuiltinOptions_ShapeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ShapeOptionsT *AsShapeOptions() const { + return type == BuiltinOptions_ShapeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::PowOptionsT *AsPowOptions() { + return type == BuiltinOptions_PowOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::PowOptionsT *AsPowOptions() const { + return type == BuiltinOptions_PowOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ArgMinOptionsT *AsArgMinOptions() { + return type == BuiltinOptions_ArgMinOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ArgMinOptionsT *AsArgMinOptions() const { + return type == BuiltinOptions_ArgMinOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::FakeQuantOptionsT *AsFakeQuantOptions() { + return type == BuiltinOptions_FakeQuantOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::FakeQuantOptionsT *AsFakeQuantOptions() const { + return type == BuiltinOptions_FakeQuantOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::PackOptionsT *AsPackOptions() { + return type == BuiltinOptions_PackOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::PackOptionsT *AsPackOptions() const { + return type == BuiltinOptions_PackOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LogicalOrOptionsT *AsLogicalOrOptions() { + return type == BuiltinOptions_LogicalOrOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LogicalOrOptionsT *AsLogicalOrOptions() const { + return type == BuiltinOptions_LogicalOrOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::OneHotOptionsT *AsOneHotOptions() { + return type == BuiltinOptions_OneHotOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::OneHotOptionsT *AsOneHotOptions() const { + return type == BuiltinOptions_OneHotOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LogicalAndOptionsT *AsLogicalAndOptions() { + return type == BuiltinOptions_LogicalAndOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LogicalAndOptionsT *AsLogicalAndOptions() const { + return type == BuiltinOptions_LogicalAndOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LogicalNotOptionsT *AsLogicalNotOptions() { + return type == BuiltinOptions_LogicalNotOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LogicalNotOptionsT *AsLogicalNotOptions() const { + return type == BuiltinOptions_LogicalNotOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::UnpackOptionsT *AsUnpackOptions() { + return type == BuiltinOptions_UnpackOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::UnpackOptionsT *AsUnpackOptions() const { + return type == BuiltinOptions_UnpackOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::FloorDivOptionsT *AsFloorDivOptions() { + return type == BuiltinOptions_FloorDivOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::FloorDivOptionsT *AsFloorDivOptions() const { + return type == BuiltinOptions_FloorDivOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SquareOptionsT *AsSquareOptions() { + return type == BuiltinOptions_SquareOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SquareOptionsT *AsSquareOptions() const { + return type == BuiltinOptions_SquareOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ZerosLikeOptionsT *AsZerosLikeOptions() { + return type == BuiltinOptions_ZerosLikeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ZerosLikeOptionsT *AsZerosLikeOptions() const { + return type == BuiltinOptions_ZerosLikeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::FillOptionsT *AsFillOptions() { + return type == BuiltinOptions_FillOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::FillOptionsT *AsFillOptions() const { + return type == BuiltinOptions_FillOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::BidirectionalSequenceLSTMOptionsT *AsBidirectionalSequenceLSTMOptions() { + return type == BuiltinOptions_BidirectionalSequenceLSTMOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::BidirectionalSequenceLSTMOptionsT *AsBidirectionalSequenceLSTMOptions() const { + return type == BuiltinOptions_BidirectionalSequenceLSTMOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::BidirectionalSequenceRNNOptionsT *AsBidirectionalSequenceRNNOptions() { + return type == BuiltinOptions_BidirectionalSequenceRNNOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::BidirectionalSequenceRNNOptionsT *AsBidirectionalSequenceRNNOptions() const { + return type == BuiltinOptions_BidirectionalSequenceRNNOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::UnidirectionalSequenceLSTMOptionsT *AsUnidirectionalSequenceLSTMOptions() { + return type == BuiltinOptions_UnidirectionalSequenceLSTMOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::UnidirectionalSequenceLSTMOptionsT *AsUnidirectionalSequenceLSTMOptions() const { + return type == BuiltinOptions_UnidirectionalSequenceLSTMOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::FloorModOptionsT *AsFloorModOptions() { + return type == BuiltinOptions_FloorModOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::FloorModOptionsT *AsFloorModOptions() const { + return type == BuiltinOptions_FloorModOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::RangeOptionsT *AsRangeOptions() { + return type == BuiltinOptions_RangeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::RangeOptionsT *AsRangeOptions() const { + return type == BuiltinOptions_RangeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ResizeNearestNeighborOptionsT *AsResizeNearestNeighborOptions() { + return type == BuiltinOptions_ResizeNearestNeighborOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ResizeNearestNeighborOptionsT *AsResizeNearestNeighborOptions() const { + return type == BuiltinOptions_ResizeNearestNeighborOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::LeakyReluOptionsT *AsLeakyReluOptions() { + return type == BuiltinOptions_LeakyReluOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::LeakyReluOptionsT *AsLeakyReluOptions() const { + return type == BuiltinOptions_LeakyReluOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SquaredDifferenceOptionsT *AsSquaredDifferenceOptions() { + return type == BuiltinOptions_SquaredDifferenceOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SquaredDifferenceOptionsT *AsSquaredDifferenceOptions() const { + return type == BuiltinOptions_SquaredDifferenceOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::MirrorPadOptionsT *AsMirrorPadOptions() { + return type == BuiltinOptions_MirrorPadOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::MirrorPadOptionsT *AsMirrorPadOptions() const { + return type == BuiltinOptions_MirrorPadOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::AbsOptionsT *AsAbsOptions() { + return type == BuiltinOptions_AbsOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::AbsOptionsT *AsAbsOptions() const { + return type == BuiltinOptions_AbsOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SplitVOptionsT *AsSplitVOptions() { + return type == BuiltinOptions_SplitVOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SplitVOptionsT *AsSplitVOptions() const { + return type == BuiltinOptions_SplitVOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::UniqueOptionsT *AsUniqueOptions() { + return type == BuiltinOptions_UniqueOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::UniqueOptionsT *AsUniqueOptions() const { + return type == BuiltinOptions_UniqueOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ReverseV2OptionsT *AsReverseV2Options() { + return type == BuiltinOptions_ReverseV2Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::ReverseV2OptionsT *AsReverseV2Options() const { + return type == BuiltinOptions_ReverseV2Options ? + reinterpret_cast(value) : nullptr; + } + tflite::AddNOptionsT *AsAddNOptions() { + return type == BuiltinOptions_AddNOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::AddNOptionsT *AsAddNOptions() const { + return type == BuiltinOptions_AddNOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::GatherNdOptionsT *AsGatherNdOptions() { + return type == BuiltinOptions_GatherNdOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::GatherNdOptionsT *AsGatherNdOptions() const { + return type == BuiltinOptions_GatherNdOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::CosOptionsT *AsCosOptions() { + return type == BuiltinOptions_CosOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::CosOptionsT *AsCosOptions() const { + return type == BuiltinOptions_CosOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::WhereOptionsT *AsWhereOptions() { + return type == BuiltinOptions_WhereOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::WhereOptionsT *AsWhereOptions() const { + return type == BuiltinOptions_WhereOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::RankOptionsT *AsRankOptions() { + return type == BuiltinOptions_RankOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::RankOptionsT *AsRankOptions() const { + return type == BuiltinOptions_RankOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::ReverseSequenceOptionsT *AsReverseSequenceOptions() { + return type == BuiltinOptions_ReverseSequenceOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ReverseSequenceOptionsT *AsReverseSequenceOptions() const { + return type == BuiltinOptions_ReverseSequenceOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::MatrixDiagOptionsT *AsMatrixDiagOptions() { + return type == BuiltinOptions_MatrixDiagOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::MatrixDiagOptionsT *AsMatrixDiagOptions() const { + return type == BuiltinOptions_MatrixDiagOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::QuantizeOptionsT *AsQuantizeOptions() { + return type == BuiltinOptions_QuantizeOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::QuantizeOptionsT *AsQuantizeOptions() const { + return type == BuiltinOptions_QuantizeOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::MatrixSetDiagOptionsT *AsMatrixSetDiagOptions() { + return type == BuiltinOptions_MatrixSetDiagOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::MatrixSetDiagOptionsT *AsMatrixSetDiagOptions() const { + return type == BuiltinOptions_MatrixSetDiagOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::HardSwishOptionsT *AsHardSwishOptions() { + return type == BuiltinOptions_HardSwishOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::HardSwishOptionsT *AsHardSwishOptions() const { + return type == BuiltinOptions_HardSwishOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::IfOptionsT *AsIfOptions() { + return type == BuiltinOptions_IfOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::IfOptionsT *AsIfOptions() const { + return type == BuiltinOptions_IfOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::WhileOptionsT *AsWhileOptions() { + return type == BuiltinOptions_WhileOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::WhileOptionsT *AsWhileOptions() const { + return type == BuiltinOptions_WhileOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::DepthToSpaceOptionsT *AsDepthToSpaceOptions() { + return type == BuiltinOptions_DepthToSpaceOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::DepthToSpaceOptionsT *AsDepthToSpaceOptions() const { + return type == BuiltinOptions_DepthToSpaceOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::NonMaxSuppressionV4OptionsT *AsNonMaxSuppressionV4Options() { + return type == BuiltinOptions_NonMaxSuppressionV4Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::NonMaxSuppressionV4OptionsT *AsNonMaxSuppressionV4Options() const { + return type == BuiltinOptions_NonMaxSuppressionV4Options ? + reinterpret_cast(value) : nullptr; + } + tflite::NonMaxSuppressionV5OptionsT *AsNonMaxSuppressionV5Options() { + return type == BuiltinOptions_NonMaxSuppressionV5Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::NonMaxSuppressionV5OptionsT *AsNonMaxSuppressionV5Options() const { + return type == BuiltinOptions_NonMaxSuppressionV5Options ? + reinterpret_cast(value) : nullptr; + } + tflite::ScatterNdOptionsT *AsScatterNdOptions() { + return type == BuiltinOptions_ScatterNdOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::ScatterNdOptionsT *AsScatterNdOptions() const { + return type == BuiltinOptions_ScatterNdOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SelectV2OptionsT *AsSelectV2Options() { + return type == BuiltinOptions_SelectV2Options ? + reinterpret_cast(value) : nullptr; + } + const tflite::SelectV2OptionsT *AsSelectV2Options() const { + return type == BuiltinOptions_SelectV2Options ? + reinterpret_cast(value) : nullptr; + } + tflite::DensifyOptionsT *AsDensifyOptions() { + return type == BuiltinOptions_DensifyOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::DensifyOptionsT *AsDensifyOptions() const { + return type == BuiltinOptions_DensifyOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::SegmentSumOptionsT *AsSegmentSumOptions() { + return type == BuiltinOptions_SegmentSumOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::SegmentSumOptionsT *AsSegmentSumOptions() const { + return type == BuiltinOptions_SegmentSumOptions ? + reinterpret_cast(value) : nullptr; + } + tflite::BatchMatMulOptionsT *AsBatchMatMulOptions() { + return type == BuiltinOptions_BatchMatMulOptions ? + reinterpret_cast(value) : nullptr; + } + const tflite::BatchMatMulOptionsT *AsBatchMatMulOptions() const { + return type == BuiltinOptions_BatchMatMulOptions ? + reinterpret_cast(value) : nullptr; + } +}; + +bool VerifyBuiltinOptions(flatbuffers::Verifier &verifier, const void *obj, BuiltinOptions type); +bool VerifyBuiltinOptionsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types); + +enum Padding { + Padding_SAME = 0, + Padding_VALID = 1, + Padding_MIN = Padding_SAME, + Padding_MAX = Padding_VALID +}; + +inline const Padding (&EnumValuesPadding())[2] { + static const Padding values[] = { + Padding_SAME, + Padding_VALID + }; + return values; +} + +inline const char * const *EnumNamesPadding() { + static const char * const names[3] = { + "SAME", + "VALID", + nullptr + }; + return names; +} + +inline const char *EnumNamePadding(Padding e) { + if (flatbuffers::IsOutRange(e, Padding_SAME, Padding_VALID)) return ""; + const size_t index = static_cast(e); + return EnumNamesPadding()[index]; +} + +enum ActivationFunctionType { + ActivationFunctionType_NONE = 0, + ActivationFunctionType_RELU = 1, + ActivationFunctionType_RELU_N1_TO_1 = 2, + ActivationFunctionType_RELU6 = 3, + ActivationFunctionType_TANH = 4, + ActivationFunctionType_SIGN_BIT = 5, + ActivationFunctionType_MIN = ActivationFunctionType_NONE, + ActivationFunctionType_MAX = ActivationFunctionType_SIGN_BIT +}; + +inline const ActivationFunctionType (&EnumValuesActivationFunctionType())[6] { + static const ActivationFunctionType values[] = { + ActivationFunctionType_NONE, + ActivationFunctionType_RELU, + ActivationFunctionType_RELU_N1_TO_1, + ActivationFunctionType_RELU6, + ActivationFunctionType_TANH, + ActivationFunctionType_SIGN_BIT + }; + return values; +} + +inline const char * const *EnumNamesActivationFunctionType() { + static const char * const names[7] = { + "NONE", + "RELU", + "RELU_N1_TO_1", + "RELU6", + "TANH", + "SIGN_BIT", + nullptr + }; + return names; +} + +inline const char *EnumNameActivationFunctionType(ActivationFunctionType e) { + if (flatbuffers::IsOutRange(e, ActivationFunctionType_NONE, ActivationFunctionType_SIGN_BIT)) return ""; + const size_t index = static_cast(e); + return EnumNamesActivationFunctionType()[index]; +} + +enum LSHProjectionType { + LSHProjectionType_UNKNOWN = 0, + LSHProjectionType_SPARSE = 1, + LSHProjectionType_DENSE = 2, + LSHProjectionType_MIN = LSHProjectionType_UNKNOWN, + LSHProjectionType_MAX = LSHProjectionType_DENSE +}; + +inline const LSHProjectionType (&EnumValuesLSHProjectionType())[3] { + static const LSHProjectionType values[] = { + LSHProjectionType_UNKNOWN, + LSHProjectionType_SPARSE, + LSHProjectionType_DENSE + }; + return values; +} + +inline const char * const *EnumNamesLSHProjectionType() { + static const char * const names[4] = { + "UNKNOWN", + "SPARSE", + "DENSE", + nullptr + }; + return names; +} + +inline const char *EnumNameLSHProjectionType(LSHProjectionType e) { + if (flatbuffers::IsOutRange(e, LSHProjectionType_UNKNOWN, LSHProjectionType_DENSE)) return ""; + const size_t index = static_cast(e); + return EnumNamesLSHProjectionType()[index]; +} + +enum FullyConnectedOptionsWeightsFormat { + FullyConnectedOptionsWeightsFormat_DEFAULT = 0, + FullyConnectedOptionsWeightsFormat_SHUFFLED4x16INT8 = 1, + FullyConnectedOptionsWeightsFormat_MIN = FullyConnectedOptionsWeightsFormat_DEFAULT, + FullyConnectedOptionsWeightsFormat_MAX = FullyConnectedOptionsWeightsFormat_SHUFFLED4x16INT8 +}; + +inline const FullyConnectedOptionsWeightsFormat (&EnumValuesFullyConnectedOptionsWeightsFormat())[2] { + static const FullyConnectedOptionsWeightsFormat values[] = { + FullyConnectedOptionsWeightsFormat_DEFAULT, + FullyConnectedOptionsWeightsFormat_SHUFFLED4x16INT8 + }; + return values; +} + +inline const char * const *EnumNamesFullyConnectedOptionsWeightsFormat() { + static const char * const names[3] = { + "DEFAULT", + "SHUFFLED4x16INT8", + nullptr + }; + return names; +} + +inline const char *EnumNameFullyConnectedOptionsWeightsFormat(FullyConnectedOptionsWeightsFormat e) { + if (flatbuffers::IsOutRange(e, FullyConnectedOptionsWeightsFormat_DEFAULT, FullyConnectedOptionsWeightsFormat_SHUFFLED4x16INT8)) return ""; + const size_t index = static_cast(e); + return EnumNamesFullyConnectedOptionsWeightsFormat()[index]; +} + +enum LSTMKernelType { + LSTMKernelType_FULL = 0, + LSTMKernelType_BASIC = 1, + LSTMKernelType_MIN = LSTMKernelType_FULL, + LSTMKernelType_MAX = LSTMKernelType_BASIC +}; + +inline const LSTMKernelType (&EnumValuesLSTMKernelType())[2] { + static const LSTMKernelType values[] = { + LSTMKernelType_FULL, + LSTMKernelType_BASIC + }; + return values; +} + +inline const char * const *EnumNamesLSTMKernelType() { + static const char * const names[3] = { + "FULL", + "BASIC", + nullptr + }; + return names; +} + +inline const char *EnumNameLSTMKernelType(LSTMKernelType e) { + if (flatbuffers::IsOutRange(e, LSTMKernelType_FULL, LSTMKernelType_BASIC)) return ""; + const size_t index = static_cast(e); + return EnumNamesLSTMKernelType()[index]; +} + +enum CombinerType { + CombinerType_SUM = 0, + CombinerType_MEAN = 1, + CombinerType_SQRTN = 2, + CombinerType_MIN = CombinerType_SUM, + CombinerType_MAX = CombinerType_SQRTN +}; + +inline const CombinerType (&EnumValuesCombinerType())[3] { + static const CombinerType values[] = { + CombinerType_SUM, + CombinerType_MEAN, + CombinerType_SQRTN + }; + return values; +} + +inline const char * const *EnumNamesCombinerType() { + static const char * const names[4] = { + "SUM", + "MEAN", + "SQRTN", + nullptr + }; + return names; +} + +inline const char *EnumNameCombinerType(CombinerType e) { + if (flatbuffers::IsOutRange(e, CombinerType_SUM, CombinerType_SQRTN)) return ""; + const size_t index = static_cast(e); + return EnumNamesCombinerType()[index]; +} + +enum MirrorPadMode { + MirrorPadMode_REFLECT = 0, + MirrorPadMode_SYMMETRIC = 1, + MirrorPadMode_MIN = MirrorPadMode_REFLECT, + MirrorPadMode_MAX = MirrorPadMode_SYMMETRIC +}; + +inline const MirrorPadMode (&EnumValuesMirrorPadMode())[2] { + static const MirrorPadMode values[] = { + MirrorPadMode_REFLECT, + MirrorPadMode_SYMMETRIC + }; + return values; +} + +inline const char * const *EnumNamesMirrorPadMode() { + static const char * const names[3] = { + "REFLECT", + "SYMMETRIC", + nullptr + }; + return names; +} + +inline const char *EnumNameMirrorPadMode(MirrorPadMode e) { + if (flatbuffers::IsOutRange(e, MirrorPadMode_REFLECT, MirrorPadMode_SYMMETRIC)) return ""; + const size_t index = static_cast(e); + return EnumNamesMirrorPadMode()[index]; +} + +enum CustomOptionsFormat { + CustomOptionsFormat_FLEXBUFFERS = 0, + CustomOptionsFormat_MIN = CustomOptionsFormat_FLEXBUFFERS, + CustomOptionsFormat_MAX = CustomOptionsFormat_FLEXBUFFERS +}; + +inline const CustomOptionsFormat (&EnumValuesCustomOptionsFormat())[1] { + static const CustomOptionsFormat values[] = { + CustomOptionsFormat_FLEXBUFFERS + }; + return values; +} + +inline const char * const *EnumNamesCustomOptionsFormat() { + static const char * const names[2] = { + "FLEXBUFFERS", + nullptr + }; + return names; +} + +inline const char *EnumNameCustomOptionsFormat(CustomOptionsFormat e) { + if (flatbuffers::IsOutRange(e, CustomOptionsFormat_FLEXBUFFERS, CustomOptionsFormat_FLEXBUFFERS)) return ""; + const size_t index = static_cast(e); + return EnumNamesCustomOptionsFormat()[index]; +} + +struct CustomQuantizationT : public flatbuffers::NativeTable { + typedef CustomQuantization TableType; + std::vector custom; + CustomQuantizationT() { + } +}; + +struct CustomQuantization FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef CustomQuantizationT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_CUSTOM = 4 + }; + const flatbuffers::Vector *custom() const { + return GetPointer *>(VT_CUSTOM); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_CUSTOM) && + verifier.VerifyVector(custom()) && + verifier.EndTable(); + } + CustomQuantizationT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(CustomQuantizationT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CustomQuantizationT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct CustomQuantizationBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_custom(flatbuffers::Offset> custom) { + fbb_.AddOffset(CustomQuantization::VT_CUSTOM, custom); + } + explicit CustomQuantizationBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + CustomQuantizationBuilder &operator=(const CustomQuantizationBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateCustomQuantization( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> custom = 0) { + CustomQuantizationBuilder builder_(_fbb); + builder_.add_custom(custom); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateCustomQuantizationDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *custom = nullptr) { + if (custom) { _fbb.ForceVectorAlignment(custom->size(), sizeof(uint8_t), 16); } + auto custom__ = custom ? _fbb.CreateVector(*custom) : 0; + return tflite::CreateCustomQuantization( + _fbb, + custom__); +} + +flatbuffers::Offset CreateCustomQuantization(flatbuffers::FlatBufferBuilder &_fbb, const CustomQuantizationT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct QuantizationParametersT : public flatbuffers::NativeTable { + typedef QuantizationParameters TableType; + std::vector min; + std::vector max; + std::vector scale; + std::vector zero_point; + tflite::QuantizationDetailsUnion details; + int32_t quantized_dimension; + QuantizationParametersT() + : quantized_dimension(0) { + } +}; + +struct QuantizationParameters FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef QuantizationParametersT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MIN = 4, + VT_MAX = 6, + VT_SCALE = 8, + VT_ZERO_POINT = 10, + VT_DETAILS_TYPE = 12, + VT_DETAILS = 14, + VT_QUANTIZED_DIMENSION = 16 + }; + const flatbuffers::Vector *min() const { + return GetPointer *>(VT_MIN); + } + const flatbuffers::Vector *max() const { + return GetPointer *>(VT_MAX); + } + const flatbuffers::Vector *scale() const { + return GetPointer *>(VT_SCALE); + } + const flatbuffers::Vector *zero_point() const { + return GetPointer *>(VT_ZERO_POINT); + } + tflite::QuantizationDetails details_type() const { + return static_cast(GetField(VT_DETAILS_TYPE, 0)); + } + const void *details() const { + return GetPointer(VT_DETAILS); + } + template const T *details_as() const; + const tflite::CustomQuantization *details_as_CustomQuantization() const { + return details_type() == tflite::QuantizationDetails_CustomQuantization ? static_cast(details()) : nullptr; + } + int32_t quantized_dimension() const { + return GetField(VT_QUANTIZED_DIMENSION, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_MIN) && + verifier.VerifyVector(min()) && + VerifyOffset(verifier, VT_MAX) && + verifier.VerifyVector(max()) && + VerifyOffset(verifier, VT_SCALE) && + verifier.VerifyVector(scale()) && + VerifyOffset(verifier, VT_ZERO_POINT) && + verifier.VerifyVector(zero_point()) && + VerifyField(verifier, VT_DETAILS_TYPE) && + VerifyOffset(verifier, VT_DETAILS) && + VerifyQuantizationDetails(verifier, details(), details_type()) && + VerifyField(verifier, VT_QUANTIZED_DIMENSION) && + verifier.EndTable(); + } + QuantizationParametersT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(QuantizationParametersT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const QuantizationParametersT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +template<> inline const tflite::CustomQuantization *QuantizationParameters::details_as() const { + return details_as_CustomQuantization(); +} + +struct QuantizationParametersBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_min(flatbuffers::Offset> min) { + fbb_.AddOffset(QuantizationParameters::VT_MIN, min); + } + void add_max(flatbuffers::Offset> max) { + fbb_.AddOffset(QuantizationParameters::VT_MAX, max); + } + void add_scale(flatbuffers::Offset> scale) { + fbb_.AddOffset(QuantizationParameters::VT_SCALE, scale); + } + void add_zero_point(flatbuffers::Offset> zero_point) { + fbb_.AddOffset(QuantizationParameters::VT_ZERO_POINT, zero_point); + } + void add_details_type(tflite::QuantizationDetails details_type) { + fbb_.AddElement(QuantizationParameters::VT_DETAILS_TYPE, static_cast(details_type), 0); + } + void add_details(flatbuffers::Offset details) { + fbb_.AddOffset(QuantizationParameters::VT_DETAILS, details); + } + void add_quantized_dimension(int32_t quantized_dimension) { + fbb_.AddElement(QuantizationParameters::VT_QUANTIZED_DIMENSION, quantized_dimension, 0); + } + explicit QuantizationParametersBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + QuantizationParametersBuilder &operator=(const QuantizationParametersBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateQuantizationParameters( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> min = 0, + flatbuffers::Offset> max = 0, + flatbuffers::Offset> scale = 0, + flatbuffers::Offset> zero_point = 0, + tflite::QuantizationDetails details_type = tflite::QuantizationDetails_NONE, + flatbuffers::Offset details = 0, + int32_t quantized_dimension = 0) { + QuantizationParametersBuilder builder_(_fbb); + builder_.add_quantized_dimension(quantized_dimension); + builder_.add_details(details); + builder_.add_zero_point(zero_point); + builder_.add_scale(scale); + builder_.add_max(max); + builder_.add_min(min); + builder_.add_details_type(details_type); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateQuantizationParametersDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *min = nullptr, + const std::vector *max = nullptr, + const std::vector *scale = nullptr, + const std::vector *zero_point = nullptr, + tflite::QuantizationDetails details_type = tflite::QuantizationDetails_NONE, + flatbuffers::Offset details = 0, + int32_t quantized_dimension = 0) { + auto min__ = min ? _fbb.CreateVector(*min) : 0; + auto max__ = max ? _fbb.CreateVector(*max) : 0; + auto scale__ = scale ? _fbb.CreateVector(*scale) : 0; + auto zero_point__ = zero_point ? _fbb.CreateVector(*zero_point) : 0; + return tflite::CreateQuantizationParameters( + _fbb, + min__, + max__, + scale__, + zero_point__, + details_type, + details, + quantized_dimension); +} + +flatbuffers::Offset CreateQuantizationParameters(flatbuffers::FlatBufferBuilder &_fbb, const QuantizationParametersT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct Int32VectorT : public flatbuffers::NativeTable { + typedef Int32Vector TableType; + std::vector values; + Int32VectorT() { + } +}; + +struct Int32Vector FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef Int32VectorT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VALUES = 4 + }; + const flatbuffers::Vector *values() const { + return GetPointer *>(VT_VALUES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_VALUES) && + verifier.VerifyVector(values()) && + verifier.EndTable(); + } + Int32VectorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(Int32VectorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const Int32VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct Int32VectorBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_values(flatbuffers::Offset> values) { + fbb_.AddOffset(Int32Vector::VT_VALUES, values); + } + explicit Int32VectorBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + Int32VectorBuilder &operator=(const Int32VectorBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateInt32Vector( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> values = 0) { + Int32VectorBuilder builder_(_fbb); + builder_.add_values(values); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateInt32VectorDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *values = nullptr) { + auto values__ = values ? _fbb.CreateVector(*values) : 0; + return tflite::CreateInt32Vector( + _fbb, + values__); +} + +flatbuffers::Offset CreateInt32Vector(flatbuffers::FlatBufferBuilder &_fbb, const Int32VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct Uint16VectorT : public flatbuffers::NativeTable { + typedef Uint16Vector TableType; + std::vector values; + Uint16VectorT() { + } +}; + +struct Uint16Vector FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef Uint16VectorT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VALUES = 4 + }; + const flatbuffers::Vector *values() const { + return GetPointer *>(VT_VALUES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_VALUES) && + verifier.VerifyVector(values()) && + verifier.EndTable(); + } + Uint16VectorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(Uint16VectorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const Uint16VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct Uint16VectorBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_values(flatbuffers::Offset> values) { + fbb_.AddOffset(Uint16Vector::VT_VALUES, values); + } + explicit Uint16VectorBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + Uint16VectorBuilder &operator=(const Uint16VectorBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateUint16Vector( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> values = 0) { + Uint16VectorBuilder builder_(_fbb); + builder_.add_values(values); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateUint16VectorDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *values = nullptr) { + if (values) { _fbb.ForceVectorAlignment(values->size(), sizeof(uint16_t), 4); } + auto values__ = values ? _fbb.CreateVector(*values) : 0; + return tflite::CreateUint16Vector( + _fbb, + values__); +} + +flatbuffers::Offset CreateUint16Vector(flatbuffers::FlatBufferBuilder &_fbb, const Uint16VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct Uint8VectorT : public flatbuffers::NativeTable { + typedef Uint8Vector TableType; + std::vector values; + Uint8VectorT() { + } +}; + +struct Uint8Vector FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef Uint8VectorT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VALUES = 4 + }; + const flatbuffers::Vector *values() const { + return GetPointer *>(VT_VALUES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_VALUES) && + verifier.VerifyVector(values()) && + verifier.EndTable(); + } + Uint8VectorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(Uint8VectorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const Uint8VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct Uint8VectorBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_values(flatbuffers::Offset> values) { + fbb_.AddOffset(Uint8Vector::VT_VALUES, values); + } + explicit Uint8VectorBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + Uint8VectorBuilder &operator=(const Uint8VectorBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateUint8Vector( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> values = 0) { + Uint8VectorBuilder builder_(_fbb); + builder_.add_values(values); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateUint8VectorDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *values = nullptr) { + if (values) { _fbb.ForceVectorAlignment(values->size(), sizeof(uint8_t), 4); } + auto values__ = values ? _fbb.CreateVector(*values) : 0; + return tflite::CreateUint8Vector( + _fbb, + values__); +} + +flatbuffers::Offset CreateUint8Vector(flatbuffers::FlatBufferBuilder &_fbb, const Uint8VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DimensionMetadataT : public flatbuffers::NativeTable { + typedef DimensionMetadata TableType; + tflite::DimensionType format; + int32_t dense_size; + tflite::SparseIndexVectorUnion array_segments; + tflite::SparseIndexVectorUnion array_indices; + DimensionMetadataT() + : format(tflite::DimensionType_DENSE), + dense_size(0) { + } +}; + +struct DimensionMetadata FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DimensionMetadataT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FORMAT = 4, + VT_DENSE_SIZE = 6, + VT_ARRAY_SEGMENTS_TYPE = 8, + VT_ARRAY_SEGMENTS = 10, + VT_ARRAY_INDICES_TYPE = 12, + VT_ARRAY_INDICES = 14 + }; + tflite::DimensionType format() const { + return static_cast(GetField(VT_FORMAT, 0)); + } + int32_t dense_size() const { + return GetField(VT_DENSE_SIZE, 0); + } + tflite::SparseIndexVector array_segments_type() const { + return static_cast(GetField(VT_ARRAY_SEGMENTS_TYPE, 0)); + } + const void *array_segments() const { + return GetPointer(VT_ARRAY_SEGMENTS); + } + template const T *array_segments_as() const; + const tflite::Int32Vector *array_segments_as_Int32Vector() const { + return array_segments_type() == tflite::SparseIndexVector_Int32Vector ? static_cast(array_segments()) : nullptr; + } + const tflite::Uint16Vector *array_segments_as_Uint16Vector() const { + return array_segments_type() == tflite::SparseIndexVector_Uint16Vector ? static_cast(array_segments()) : nullptr; + } + const tflite::Uint8Vector *array_segments_as_Uint8Vector() const { + return array_segments_type() == tflite::SparseIndexVector_Uint8Vector ? static_cast(array_segments()) : nullptr; + } + tflite::SparseIndexVector array_indices_type() const { + return static_cast(GetField(VT_ARRAY_INDICES_TYPE, 0)); + } + const void *array_indices() const { + return GetPointer(VT_ARRAY_INDICES); + } + template const T *array_indices_as() const; + const tflite::Int32Vector *array_indices_as_Int32Vector() const { + return array_indices_type() == tflite::SparseIndexVector_Int32Vector ? static_cast(array_indices()) : nullptr; + } + const tflite::Uint16Vector *array_indices_as_Uint16Vector() const { + return array_indices_type() == tflite::SparseIndexVector_Uint16Vector ? static_cast(array_indices()) : nullptr; + } + const tflite::Uint8Vector *array_indices_as_Uint8Vector() const { + return array_indices_type() == tflite::SparseIndexVector_Uint8Vector ? static_cast(array_indices()) : nullptr; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FORMAT) && + VerifyField(verifier, VT_DENSE_SIZE) && + VerifyField(verifier, VT_ARRAY_SEGMENTS_TYPE) && + VerifyOffset(verifier, VT_ARRAY_SEGMENTS) && + VerifySparseIndexVector(verifier, array_segments(), array_segments_type()) && + VerifyField(verifier, VT_ARRAY_INDICES_TYPE) && + VerifyOffset(verifier, VT_ARRAY_INDICES) && + VerifySparseIndexVector(verifier, array_indices(), array_indices_type()) && + verifier.EndTable(); + } + DimensionMetadataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DimensionMetadataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DimensionMetadataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +template<> inline const tflite::Int32Vector *DimensionMetadata::array_segments_as() const { + return array_segments_as_Int32Vector(); +} + +template<> inline const tflite::Uint16Vector *DimensionMetadata::array_segments_as() const { + return array_segments_as_Uint16Vector(); +} + +template<> inline const tflite::Uint8Vector *DimensionMetadata::array_segments_as() const { + return array_segments_as_Uint8Vector(); +} + +template<> inline const tflite::Int32Vector *DimensionMetadata::array_indices_as() const { + return array_indices_as_Int32Vector(); +} + +template<> inline const tflite::Uint16Vector *DimensionMetadata::array_indices_as() const { + return array_indices_as_Uint16Vector(); +} + +template<> inline const tflite::Uint8Vector *DimensionMetadata::array_indices_as() const { + return array_indices_as_Uint8Vector(); +} + +struct DimensionMetadataBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_format(tflite::DimensionType format) { + fbb_.AddElement(DimensionMetadata::VT_FORMAT, static_cast(format), 0); + } + void add_dense_size(int32_t dense_size) { + fbb_.AddElement(DimensionMetadata::VT_DENSE_SIZE, dense_size, 0); + } + void add_array_segments_type(tflite::SparseIndexVector array_segments_type) { + fbb_.AddElement(DimensionMetadata::VT_ARRAY_SEGMENTS_TYPE, static_cast(array_segments_type), 0); + } + void add_array_segments(flatbuffers::Offset array_segments) { + fbb_.AddOffset(DimensionMetadata::VT_ARRAY_SEGMENTS, array_segments); + } + void add_array_indices_type(tflite::SparseIndexVector array_indices_type) { + fbb_.AddElement(DimensionMetadata::VT_ARRAY_INDICES_TYPE, static_cast(array_indices_type), 0); + } + void add_array_indices(flatbuffers::Offset array_indices) { + fbb_.AddOffset(DimensionMetadata::VT_ARRAY_INDICES, array_indices); + } + explicit DimensionMetadataBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DimensionMetadataBuilder &operator=(const DimensionMetadataBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDimensionMetadata( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::DimensionType format = tflite::DimensionType_DENSE, + int32_t dense_size = 0, + tflite::SparseIndexVector array_segments_type = tflite::SparseIndexVector_NONE, + flatbuffers::Offset array_segments = 0, + tflite::SparseIndexVector array_indices_type = tflite::SparseIndexVector_NONE, + flatbuffers::Offset array_indices = 0) { + DimensionMetadataBuilder builder_(_fbb); + builder_.add_array_indices(array_indices); + builder_.add_array_segments(array_segments); + builder_.add_dense_size(dense_size); + builder_.add_array_indices_type(array_indices_type); + builder_.add_array_segments_type(array_segments_type); + builder_.add_format(format); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDimensionMetadata(flatbuffers::FlatBufferBuilder &_fbb, const DimensionMetadataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SparsityParametersT : public flatbuffers::NativeTable { + typedef SparsityParameters TableType; + std::vector traversal_order; + std::vector block_map; + std::vector> dim_metadata; + SparsityParametersT() { + } +}; + +struct SparsityParameters FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SparsityParametersT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TRAVERSAL_ORDER = 4, + VT_BLOCK_MAP = 6, + VT_DIM_METADATA = 8 + }; + const flatbuffers::Vector *traversal_order() const { + return GetPointer *>(VT_TRAVERSAL_ORDER); + } + const flatbuffers::Vector *block_map() const { + return GetPointer *>(VT_BLOCK_MAP); + } + const flatbuffers::Vector> *dim_metadata() const { + return GetPointer> *>(VT_DIM_METADATA); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_TRAVERSAL_ORDER) && + verifier.VerifyVector(traversal_order()) && + VerifyOffset(verifier, VT_BLOCK_MAP) && + verifier.VerifyVector(block_map()) && + VerifyOffset(verifier, VT_DIM_METADATA) && + verifier.VerifyVector(dim_metadata()) && + verifier.VerifyVectorOfTables(dim_metadata()) && + verifier.EndTable(); + } + SparsityParametersT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SparsityParametersT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SparsityParametersT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SparsityParametersBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_traversal_order(flatbuffers::Offset> traversal_order) { + fbb_.AddOffset(SparsityParameters::VT_TRAVERSAL_ORDER, traversal_order); + } + void add_block_map(flatbuffers::Offset> block_map) { + fbb_.AddOffset(SparsityParameters::VT_BLOCK_MAP, block_map); + } + void add_dim_metadata(flatbuffers::Offset>> dim_metadata) { + fbb_.AddOffset(SparsityParameters::VT_DIM_METADATA, dim_metadata); + } + explicit SparsityParametersBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SparsityParametersBuilder &operator=(const SparsityParametersBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSparsityParameters( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> traversal_order = 0, + flatbuffers::Offset> block_map = 0, + flatbuffers::Offset>> dim_metadata = 0) { + SparsityParametersBuilder builder_(_fbb); + builder_.add_dim_metadata(dim_metadata); + builder_.add_block_map(block_map); + builder_.add_traversal_order(traversal_order); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateSparsityParametersDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *traversal_order = nullptr, + const std::vector *block_map = nullptr, + const std::vector> *dim_metadata = nullptr) { + auto traversal_order__ = traversal_order ? _fbb.CreateVector(*traversal_order) : 0; + auto block_map__ = block_map ? _fbb.CreateVector(*block_map) : 0; + auto dim_metadata__ = dim_metadata ? _fbb.CreateVector>(*dim_metadata) : 0; + return tflite::CreateSparsityParameters( + _fbb, + traversal_order__, + block_map__, + dim_metadata__); +} + +flatbuffers::Offset CreateSparsityParameters(flatbuffers::FlatBufferBuilder &_fbb, const SparsityParametersT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct TensorT : public flatbuffers::NativeTable { + typedef Tensor TableType; + std::vector shape; + tflite::TensorType type; + uint32_t buffer; + std::string name; + std::unique_ptr quantization; + bool is_variable; + std::unique_ptr sparsity; + std::vector shape_signature; + TensorT() + : type(tflite::TensorType_FLOAT32), + buffer(0), + is_variable(false) { + } +}; + +struct Tensor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TensorT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SHAPE = 4, + VT_TYPE = 6, + VT_BUFFER = 8, + VT_NAME = 10, + VT_QUANTIZATION = 12, + VT_IS_VARIABLE = 14, + VT_SPARSITY = 16, + VT_SHAPE_SIGNATURE = 18 + }; + const flatbuffers::Vector *shape() const { + return GetPointer *>(VT_SHAPE); + } + tflite::TensorType type() const { + return static_cast(GetField(VT_TYPE, 0)); + } + uint32_t buffer() const { + return GetField(VT_BUFFER, 0); + } + const flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const tflite::QuantizationParameters *quantization() const { + return GetPointer(VT_QUANTIZATION); + } + bool is_variable() const { + return GetField(VT_IS_VARIABLE, 0) != 0; + } + const tflite::SparsityParameters *sparsity() const { + return GetPointer(VT_SPARSITY); + } + const flatbuffers::Vector *shape_signature() const { + return GetPointer *>(VT_SHAPE_SIGNATURE); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_SHAPE) && + verifier.VerifyVector(shape()) && + VerifyField(verifier, VT_TYPE) && + VerifyField(verifier, VT_BUFFER) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_QUANTIZATION) && + verifier.VerifyTable(quantization()) && + VerifyField(verifier, VT_IS_VARIABLE) && + VerifyOffset(verifier, VT_SPARSITY) && + verifier.VerifyTable(sparsity()) && + VerifyOffset(verifier, VT_SHAPE_SIGNATURE) && + verifier.VerifyVector(shape_signature()) && + verifier.EndTable(); + } + TensorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(TensorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const TensorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct TensorBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_shape(flatbuffers::Offset> shape) { + fbb_.AddOffset(Tensor::VT_SHAPE, shape); + } + void add_type(tflite::TensorType type) { + fbb_.AddElement(Tensor::VT_TYPE, static_cast(type), 0); + } + void add_buffer(uint32_t buffer) { + fbb_.AddElement(Tensor::VT_BUFFER, buffer, 0); + } + void add_name(flatbuffers::Offset name) { + fbb_.AddOffset(Tensor::VT_NAME, name); + } + void add_quantization(flatbuffers::Offset quantization) { + fbb_.AddOffset(Tensor::VT_QUANTIZATION, quantization); + } + void add_is_variable(bool is_variable) { + fbb_.AddElement(Tensor::VT_IS_VARIABLE, static_cast(is_variable), 0); + } + void add_sparsity(flatbuffers::Offset sparsity) { + fbb_.AddOffset(Tensor::VT_SPARSITY, sparsity); + } + void add_shape_signature(flatbuffers::Offset> shape_signature) { + fbb_.AddOffset(Tensor::VT_SHAPE_SIGNATURE, shape_signature); + } + explicit TensorBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + TensorBuilder &operator=(const TensorBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateTensor( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> shape = 0, + tflite::TensorType type = tflite::TensorType_FLOAT32, + uint32_t buffer = 0, + flatbuffers::Offset name = 0, + flatbuffers::Offset quantization = 0, + bool is_variable = false, + flatbuffers::Offset sparsity = 0, + flatbuffers::Offset> shape_signature = 0) { + TensorBuilder builder_(_fbb); + builder_.add_shape_signature(shape_signature); + builder_.add_sparsity(sparsity); + builder_.add_quantization(quantization); + builder_.add_name(name); + builder_.add_buffer(buffer); + builder_.add_shape(shape); + builder_.add_is_variable(is_variable); + builder_.add_type(type); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateTensorDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *shape = nullptr, + tflite::TensorType type = tflite::TensorType_FLOAT32, + uint32_t buffer = 0, + const char *name = nullptr, + flatbuffers::Offset quantization = 0, + bool is_variable = false, + flatbuffers::Offset sparsity = 0, + const std::vector *shape_signature = nullptr) { + auto shape__ = shape ? _fbb.CreateVector(*shape) : 0; + auto name__ = name ? _fbb.CreateString(name) : 0; + auto shape_signature__ = shape_signature ? _fbb.CreateVector(*shape_signature) : 0; + return tflite::CreateTensor( + _fbb, + shape__, + type, + buffer, + name__, + quantization, + is_variable, + sparsity, + shape_signature__); +} + +flatbuffers::Offset CreateTensor(flatbuffers::FlatBufferBuilder &_fbb, const TensorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct Conv2DOptionsT : public flatbuffers::NativeTable { + typedef Conv2DOptions TableType; + tflite::Padding padding; + int32_t stride_w; + int32_t stride_h; + tflite::ActivationFunctionType fused_activation_function; + int32_t dilation_w_factor; + int32_t dilation_h_factor; + Conv2DOptionsT() + : padding(tflite::Padding_SAME), + stride_w(0), + stride_h(0), + fused_activation_function(tflite::ActivationFunctionType_NONE), + dilation_w_factor(1), + dilation_h_factor(1) { + } +}; + +struct Conv2DOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef Conv2DOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PADDING = 4, + VT_STRIDE_W = 6, + VT_STRIDE_H = 8, + VT_FUSED_ACTIVATION_FUNCTION = 10, + VT_DILATION_W_FACTOR = 12, + VT_DILATION_H_FACTOR = 14 + }; + tflite::Padding padding() const { + return static_cast(GetField(VT_PADDING, 0)); + } + int32_t stride_w() const { + return GetField(VT_STRIDE_W, 0); + } + int32_t stride_h() const { + return GetField(VT_STRIDE_H, 0); + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + int32_t dilation_w_factor() const { + return GetField(VT_DILATION_W_FACTOR, 1); + } + int32_t dilation_h_factor() const { + return GetField(VT_DILATION_H_FACTOR, 1); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PADDING) && + VerifyField(verifier, VT_STRIDE_W) && + VerifyField(verifier, VT_STRIDE_H) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_DILATION_W_FACTOR) && + VerifyField(verifier, VT_DILATION_H_FACTOR) && + verifier.EndTable(); + } + Conv2DOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(Conv2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const Conv2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct Conv2DOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_padding(tflite::Padding padding) { + fbb_.AddElement(Conv2DOptions::VT_PADDING, static_cast(padding), 0); + } + void add_stride_w(int32_t stride_w) { + fbb_.AddElement(Conv2DOptions::VT_STRIDE_W, stride_w, 0); + } + void add_stride_h(int32_t stride_h) { + fbb_.AddElement(Conv2DOptions::VT_STRIDE_H, stride_h, 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(Conv2DOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_dilation_w_factor(int32_t dilation_w_factor) { + fbb_.AddElement(Conv2DOptions::VT_DILATION_W_FACTOR, dilation_w_factor, 1); + } + void add_dilation_h_factor(int32_t dilation_h_factor) { + fbb_.AddElement(Conv2DOptions::VT_DILATION_H_FACTOR, dilation_h_factor, 1); + } + explicit Conv2DOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + Conv2DOptionsBuilder &operator=(const Conv2DOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateConv2DOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::Padding padding = tflite::Padding_SAME, + int32_t stride_w = 0, + int32_t stride_h = 0, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + int32_t dilation_w_factor = 1, + int32_t dilation_h_factor = 1) { + Conv2DOptionsBuilder builder_(_fbb); + builder_.add_dilation_h_factor(dilation_h_factor); + builder_.add_dilation_w_factor(dilation_w_factor); + builder_.add_stride_h(stride_h); + builder_.add_stride_w(stride_w); + builder_.add_fused_activation_function(fused_activation_function); + builder_.add_padding(padding); + return builder_.Finish(); +} + +flatbuffers::Offset CreateConv2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const Conv2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct Pool2DOptionsT : public flatbuffers::NativeTable { + typedef Pool2DOptions TableType; + tflite::Padding padding; + int32_t stride_w; + int32_t stride_h; + int32_t filter_width; + int32_t filter_height; + tflite::ActivationFunctionType fused_activation_function; + Pool2DOptionsT() + : padding(tflite::Padding_SAME), + stride_w(0), + stride_h(0), + filter_width(0), + filter_height(0), + fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct Pool2DOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef Pool2DOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PADDING = 4, + VT_STRIDE_W = 6, + VT_STRIDE_H = 8, + VT_FILTER_WIDTH = 10, + VT_FILTER_HEIGHT = 12, + VT_FUSED_ACTIVATION_FUNCTION = 14 + }; + tflite::Padding padding() const { + return static_cast(GetField(VT_PADDING, 0)); + } + int32_t stride_w() const { + return GetField(VT_STRIDE_W, 0); + } + int32_t stride_h() const { + return GetField(VT_STRIDE_H, 0); + } + int32_t filter_width() const { + return GetField(VT_FILTER_WIDTH, 0); + } + int32_t filter_height() const { + return GetField(VT_FILTER_HEIGHT, 0); + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PADDING) && + VerifyField(verifier, VT_STRIDE_W) && + VerifyField(verifier, VT_STRIDE_H) && + VerifyField(verifier, VT_FILTER_WIDTH) && + VerifyField(verifier, VT_FILTER_HEIGHT) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + Pool2DOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(Pool2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const Pool2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct Pool2DOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_padding(tflite::Padding padding) { + fbb_.AddElement(Pool2DOptions::VT_PADDING, static_cast(padding), 0); + } + void add_stride_w(int32_t stride_w) { + fbb_.AddElement(Pool2DOptions::VT_STRIDE_W, stride_w, 0); + } + void add_stride_h(int32_t stride_h) { + fbb_.AddElement(Pool2DOptions::VT_STRIDE_H, stride_h, 0); + } + void add_filter_width(int32_t filter_width) { + fbb_.AddElement(Pool2DOptions::VT_FILTER_WIDTH, filter_width, 0); + } + void add_filter_height(int32_t filter_height) { + fbb_.AddElement(Pool2DOptions::VT_FILTER_HEIGHT, filter_height, 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(Pool2DOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit Pool2DOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + Pool2DOptionsBuilder &operator=(const Pool2DOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreatePool2DOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::Padding padding = tflite::Padding_SAME, + int32_t stride_w = 0, + int32_t stride_h = 0, + int32_t filter_width = 0, + int32_t filter_height = 0, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + Pool2DOptionsBuilder builder_(_fbb); + builder_.add_filter_height(filter_height); + builder_.add_filter_width(filter_width); + builder_.add_stride_h(stride_h); + builder_.add_stride_w(stride_w); + builder_.add_fused_activation_function(fused_activation_function); + builder_.add_padding(padding); + return builder_.Finish(); +} + +flatbuffers::Offset CreatePool2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const Pool2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DepthwiseConv2DOptionsT : public flatbuffers::NativeTable { + typedef DepthwiseConv2DOptions TableType; + tflite::Padding padding; + int32_t stride_w; + int32_t stride_h; + int32_t depth_multiplier; + tflite::ActivationFunctionType fused_activation_function; + int32_t dilation_w_factor; + int32_t dilation_h_factor; + DepthwiseConv2DOptionsT() + : padding(tflite::Padding_SAME), + stride_w(0), + stride_h(0), + depth_multiplier(0), + fused_activation_function(tflite::ActivationFunctionType_NONE), + dilation_w_factor(1), + dilation_h_factor(1) { + } +}; + +struct DepthwiseConv2DOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DepthwiseConv2DOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PADDING = 4, + VT_STRIDE_W = 6, + VT_STRIDE_H = 8, + VT_DEPTH_MULTIPLIER = 10, + VT_FUSED_ACTIVATION_FUNCTION = 12, + VT_DILATION_W_FACTOR = 14, + VT_DILATION_H_FACTOR = 16 + }; + tflite::Padding padding() const { + return static_cast(GetField(VT_PADDING, 0)); + } + int32_t stride_w() const { + return GetField(VT_STRIDE_W, 0); + } + int32_t stride_h() const { + return GetField(VT_STRIDE_H, 0); + } + int32_t depth_multiplier() const { + return GetField(VT_DEPTH_MULTIPLIER, 0); + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + int32_t dilation_w_factor() const { + return GetField(VT_DILATION_W_FACTOR, 1); + } + int32_t dilation_h_factor() const { + return GetField(VT_DILATION_H_FACTOR, 1); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PADDING) && + VerifyField(verifier, VT_STRIDE_W) && + VerifyField(verifier, VT_STRIDE_H) && + VerifyField(verifier, VT_DEPTH_MULTIPLIER) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_DILATION_W_FACTOR) && + VerifyField(verifier, VT_DILATION_H_FACTOR) && + verifier.EndTable(); + } + DepthwiseConv2DOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DepthwiseConv2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DepthwiseConv2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct DepthwiseConv2DOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_padding(tflite::Padding padding) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_PADDING, static_cast(padding), 0); + } + void add_stride_w(int32_t stride_w) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_STRIDE_W, stride_w, 0); + } + void add_stride_h(int32_t stride_h) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_STRIDE_H, stride_h, 0); + } + void add_depth_multiplier(int32_t depth_multiplier) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_DEPTH_MULTIPLIER, depth_multiplier, 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_dilation_w_factor(int32_t dilation_w_factor) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_DILATION_W_FACTOR, dilation_w_factor, 1); + } + void add_dilation_h_factor(int32_t dilation_h_factor) { + fbb_.AddElement(DepthwiseConv2DOptions::VT_DILATION_H_FACTOR, dilation_h_factor, 1); + } + explicit DepthwiseConv2DOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DepthwiseConv2DOptionsBuilder &operator=(const DepthwiseConv2DOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDepthwiseConv2DOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::Padding padding = tflite::Padding_SAME, + int32_t stride_w = 0, + int32_t stride_h = 0, + int32_t depth_multiplier = 0, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + int32_t dilation_w_factor = 1, + int32_t dilation_h_factor = 1) { + DepthwiseConv2DOptionsBuilder builder_(_fbb); + builder_.add_dilation_h_factor(dilation_h_factor); + builder_.add_dilation_w_factor(dilation_w_factor); + builder_.add_depth_multiplier(depth_multiplier); + builder_.add_stride_h(stride_h); + builder_.add_stride_w(stride_w); + builder_.add_fused_activation_function(fused_activation_function); + builder_.add_padding(padding); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDepthwiseConv2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const DepthwiseConv2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ConcatEmbeddingsOptionsT : public flatbuffers::NativeTable { + typedef ConcatEmbeddingsOptions TableType; + int32_t num_channels; + std::vector num_columns_per_channel; + std::vector embedding_dim_per_channel; + ConcatEmbeddingsOptionsT() + : num_channels(0) { + } +}; + +struct ConcatEmbeddingsOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ConcatEmbeddingsOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUM_CHANNELS = 4, + VT_NUM_COLUMNS_PER_CHANNEL = 6, + VT_EMBEDDING_DIM_PER_CHANNEL = 8 + }; + int32_t num_channels() const { + return GetField(VT_NUM_CHANNELS, 0); + } + const flatbuffers::Vector *num_columns_per_channel() const { + return GetPointer *>(VT_NUM_COLUMNS_PER_CHANNEL); + } + const flatbuffers::Vector *embedding_dim_per_channel() const { + return GetPointer *>(VT_EMBEDDING_DIM_PER_CHANNEL); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUM_CHANNELS) && + VerifyOffset(verifier, VT_NUM_COLUMNS_PER_CHANNEL) && + verifier.VerifyVector(num_columns_per_channel()) && + VerifyOffset(verifier, VT_EMBEDDING_DIM_PER_CHANNEL) && + verifier.VerifyVector(embedding_dim_per_channel()) && + verifier.EndTable(); + } + ConcatEmbeddingsOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ConcatEmbeddingsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ConcatEmbeddingsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ConcatEmbeddingsOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_num_channels(int32_t num_channels) { + fbb_.AddElement(ConcatEmbeddingsOptions::VT_NUM_CHANNELS, num_channels, 0); + } + void add_num_columns_per_channel(flatbuffers::Offset> num_columns_per_channel) { + fbb_.AddOffset(ConcatEmbeddingsOptions::VT_NUM_COLUMNS_PER_CHANNEL, num_columns_per_channel); + } + void add_embedding_dim_per_channel(flatbuffers::Offset> embedding_dim_per_channel) { + fbb_.AddOffset(ConcatEmbeddingsOptions::VT_EMBEDDING_DIM_PER_CHANNEL, embedding_dim_per_channel); + } + explicit ConcatEmbeddingsOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ConcatEmbeddingsOptionsBuilder &operator=(const ConcatEmbeddingsOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateConcatEmbeddingsOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t num_channels = 0, + flatbuffers::Offset> num_columns_per_channel = 0, + flatbuffers::Offset> embedding_dim_per_channel = 0) { + ConcatEmbeddingsOptionsBuilder builder_(_fbb); + builder_.add_embedding_dim_per_channel(embedding_dim_per_channel); + builder_.add_num_columns_per_channel(num_columns_per_channel); + builder_.add_num_channels(num_channels); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateConcatEmbeddingsOptionsDirect( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t num_channels = 0, + const std::vector *num_columns_per_channel = nullptr, + const std::vector *embedding_dim_per_channel = nullptr) { + auto num_columns_per_channel__ = num_columns_per_channel ? _fbb.CreateVector(*num_columns_per_channel) : 0; + auto embedding_dim_per_channel__ = embedding_dim_per_channel ? _fbb.CreateVector(*embedding_dim_per_channel) : 0; + return tflite::CreateConcatEmbeddingsOptions( + _fbb, + num_channels, + num_columns_per_channel__, + embedding_dim_per_channel__); +} + +flatbuffers::Offset CreateConcatEmbeddingsOptions(flatbuffers::FlatBufferBuilder &_fbb, const ConcatEmbeddingsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LSHProjectionOptionsT : public flatbuffers::NativeTable { + typedef LSHProjectionOptions TableType; + tflite::LSHProjectionType type; + LSHProjectionOptionsT() + : type(tflite::LSHProjectionType_UNKNOWN) { + } +}; + +struct LSHProjectionOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LSHProjectionOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TYPE = 4 + }; + tflite::LSHProjectionType type() const { + return static_cast(GetField(VT_TYPE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_TYPE) && + verifier.EndTable(); + } + LSHProjectionOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LSHProjectionOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LSHProjectionOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LSHProjectionOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_type(tflite::LSHProjectionType type) { + fbb_.AddElement(LSHProjectionOptions::VT_TYPE, static_cast(type), 0); + } + explicit LSHProjectionOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LSHProjectionOptionsBuilder &operator=(const LSHProjectionOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLSHProjectionOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::LSHProjectionType type = tflite::LSHProjectionType_UNKNOWN) { + LSHProjectionOptionsBuilder builder_(_fbb); + builder_.add_type(type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLSHProjectionOptions(flatbuffers::FlatBufferBuilder &_fbb, const LSHProjectionOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SVDFOptionsT : public flatbuffers::NativeTable { + typedef SVDFOptions TableType; + int32_t rank; + tflite::ActivationFunctionType fused_activation_function; + bool asymmetric_quantize_inputs; + SVDFOptionsT() + : rank(0), + fused_activation_function(tflite::ActivationFunctionType_NONE), + asymmetric_quantize_inputs(false) { + } +}; + +struct SVDFOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SVDFOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_RANK = 4, + VT_FUSED_ACTIVATION_FUNCTION = 6, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 8 + }; + int32_t rank() const { + return GetField(VT_RANK, 0); + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_RANK) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + SVDFOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SVDFOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SVDFOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SVDFOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_rank(int32_t rank) { + fbb_.AddElement(SVDFOptions::VT_RANK, rank, 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(SVDFOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(SVDFOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit SVDFOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SVDFOptionsBuilder &operator=(const SVDFOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSVDFOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t rank = 0, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + bool asymmetric_quantize_inputs = false) { + SVDFOptionsBuilder builder_(_fbb); + builder_.add_rank(rank); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSVDFOptions(flatbuffers::FlatBufferBuilder &_fbb, const SVDFOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct RNNOptionsT : public flatbuffers::NativeTable { + typedef RNNOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + bool asymmetric_quantize_inputs; + RNNOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE), + asymmetric_quantize_inputs(false) { + } +}; + +struct RNNOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RNNOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 6 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + RNNOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(RNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const RNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct RNNOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(RNNOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(RNNOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit RNNOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RNNOptionsBuilder &operator=(const RNNOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateRNNOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + bool asymmetric_quantize_inputs = false) { + RNNOptionsBuilder builder_(_fbb); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const RNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SequenceRNNOptionsT : public flatbuffers::NativeTable { + typedef SequenceRNNOptions TableType; + bool time_major; + tflite::ActivationFunctionType fused_activation_function; + bool asymmetric_quantize_inputs; + SequenceRNNOptionsT() + : time_major(false), + fused_activation_function(tflite::ActivationFunctionType_NONE), + asymmetric_quantize_inputs(false) { + } +}; + +struct SequenceRNNOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SequenceRNNOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TIME_MAJOR = 4, + VT_FUSED_ACTIVATION_FUNCTION = 6, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 8 + }; + bool time_major() const { + return GetField(VT_TIME_MAJOR, 0) != 0; + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_TIME_MAJOR) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + SequenceRNNOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SequenceRNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SequenceRNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SequenceRNNOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_time_major(bool time_major) { + fbb_.AddElement(SequenceRNNOptions::VT_TIME_MAJOR, static_cast(time_major), 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(SequenceRNNOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(SequenceRNNOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit SequenceRNNOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SequenceRNNOptionsBuilder &operator=(const SequenceRNNOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSequenceRNNOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool time_major = false, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + bool asymmetric_quantize_inputs = false) { + SequenceRNNOptionsBuilder builder_(_fbb); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_fused_activation_function(fused_activation_function); + builder_.add_time_major(time_major); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSequenceRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const SequenceRNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BidirectionalSequenceRNNOptionsT : public flatbuffers::NativeTable { + typedef BidirectionalSequenceRNNOptions TableType; + bool time_major; + tflite::ActivationFunctionType fused_activation_function; + bool merge_outputs; + bool asymmetric_quantize_inputs; + BidirectionalSequenceRNNOptionsT() + : time_major(false), + fused_activation_function(tflite::ActivationFunctionType_NONE), + merge_outputs(false), + asymmetric_quantize_inputs(false) { + } +}; + +struct BidirectionalSequenceRNNOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BidirectionalSequenceRNNOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TIME_MAJOR = 4, + VT_FUSED_ACTIVATION_FUNCTION = 6, + VT_MERGE_OUTPUTS = 8, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 10 + }; + bool time_major() const { + return GetField(VT_TIME_MAJOR, 0) != 0; + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool merge_outputs() const { + return GetField(VT_MERGE_OUTPUTS, 0) != 0; + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_TIME_MAJOR) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_MERGE_OUTPUTS) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + BidirectionalSequenceRNNOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BidirectionalSequenceRNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceRNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BidirectionalSequenceRNNOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_time_major(bool time_major) { + fbb_.AddElement(BidirectionalSequenceRNNOptions::VT_TIME_MAJOR, static_cast(time_major), 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(BidirectionalSequenceRNNOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_merge_outputs(bool merge_outputs) { + fbb_.AddElement(BidirectionalSequenceRNNOptions::VT_MERGE_OUTPUTS, static_cast(merge_outputs), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(BidirectionalSequenceRNNOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit BidirectionalSequenceRNNOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BidirectionalSequenceRNNOptionsBuilder &operator=(const BidirectionalSequenceRNNOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateBidirectionalSequenceRNNOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool time_major = false, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + bool merge_outputs = false, + bool asymmetric_quantize_inputs = false) { + BidirectionalSequenceRNNOptionsBuilder builder_(_fbb); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_merge_outputs(merge_outputs); + builder_.add_fused_activation_function(fused_activation_function); + builder_.add_time_major(time_major); + return builder_.Finish(); +} + +flatbuffers::Offset CreateBidirectionalSequenceRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceRNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct FullyConnectedOptionsT : public flatbuffers::NativeTable { + typedef FullyConnectedOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + tflite::FullyConnectedOptionsWeightsFormat weights_format; + bool keep_num_dims; + bool asymmetric_quantize_inputs; + FullyConnectedOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE), + weights_format(tflite::FullyConnectedOptionsWeightsFormat_DEFAULT), + keep_num_dims(false), + asymmetric_quantize_inputs(false) { + } +}; + +struct FullyConnectedOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FullyConnectedOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_WEIGHTS_FORMAT = 6, + VT_KEEP_NUM_DIMS = 8, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 10 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + tflite::FullyConnectedOptionsWeightsFormat weights_format() const { + return static_cast(GetField(VT_WEIGHTS_FORMAT, 0)); + } + bool keep_num_dims() const { + return GetField(VT_KEEP_NUM_DIMS, 0) != 0; + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_WEIGHTS_FORMAT) && + VerifyField(verifier, VT_KEEP_NUM_DIMS) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + FullyConnectedOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FullyConnectedOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FullyConnectedOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FullyConnectedOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(FullyConnectedOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_weights_format(tflite::FullyConnectedOptionsWeightsFormat weights_format) { + fbb_.AddElement(FullyConnectedOptions::VT_WEIGHTS_FORMAT, static_cast(weights_format), 0); + } + void add_keep_num_dims(bool keep_num_dims) { + fbb_.AddElement(FullyConnectedOptions::VT_KEEP_NUM_DIMS, static_cast(keep_num_dims), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(FullyConnectedOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit FullyConnectedOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + FullyConnectedOptionsBuilder &operator=(const FullyConnectedOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFullyConnectedOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + tflite::FullyConnectedOptionsWeightsFormat weights_format = tflite::FullyConnectedOptionsWeightsFormat_DEFAULT, + bool keep_num_dims = false, + bool asymmetric_quantize_inputs = false) { + FullyConnectedOptionsBuilder builder_(_fbb); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_keep_num_dims(keep_num_dims); + builder_.add_weights_format(weights_format); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateFullyConnectedOptions(flatbuffers::FlatBufferBuilder &_fbb, const FullyConnectedOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SoftmaxOptionsT : public flatbuffers::NativeTable { + typedef SoftmaxOptions TableType; + float beta; + SoftmaxOptionsT() + : beta(0.0f) { + } +}; + +struct SoftmaxOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SoftmaxOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BETA = 4 + }; + float beta() const { + return GetField(VT_BETA, 0.0f); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_BETA) && + verifier.EndTable(); + } + SoftmaxOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SoftmaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SoftmaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SoftmaxOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_beta(float beta) { + fbb_.AddElement(SoftmaxOptions::VT_BETA, beta, 0.0f); + } + explicit SoftmaxOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SoftmaxOptionsBuilder &operator=(const SoftmaxOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSoftmaxOptions( + flatbuffers::FlatBufferBuilder &_fbb, + float beta = 0.0f) { + SoftmaxOptionsBuilder builder_(_fbb); + builder_.add_beta(beta); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSoftmaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const SoftmaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ConcatenationOptionsT : public flatbuffers::NativeTable { + typedef ConcatenationOptions TableType; + int32_t axis; + tflite::ActivationFunctionType fused_activation_function; + ConcatenationOptionsT() + : axis(0), + fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct ConcatenationOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ConcatenationOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_AXIS = 4, + VT_FUSED_ACTIVATION_FUNCTION = 6 + }; + int32_t axis() const { + return GetField(VT_AXIS, 0); + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_AXIS) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + ConcatenationOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ConcatenationOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ConcatenationOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ConcatenationOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_axis(int32_t axis) { + fbb_.AddElement(ConcatenationOptions::VT_AXIS, axis, 0); + } + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(ConcatenationOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit ConcatenationOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ConcatenationOptionsBuilder &operator=(const ConcatenationOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateConcatenationOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t axis = 0, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + ConcatenationOptionsBuilder builder_(_fbb); + builder_.add_axis(axis); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateConcatenationOptions(flatbuffers::FlatBufferBuilder &_fbb, const ConcatenationOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct AddOptionsT : public flatbuffers::NativeTable { + typedef AddOptions TableType; + bool pot_scale_int16; + tflite::ActivationFunctionType fused_activation_function; + AddOptionsT() + : pot_scale_int16(true), + fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct AddOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef AddOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_POT_SCALE_INT16 = 6 + }; + bool pot_scale_int16() const { + return GetField(VT_POT_SCALE_INT16, 0) != 0; + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_POT_SCALE_INT16) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + AddOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(AddOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const AddOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct AddOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(AddOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit AddOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + AddOptionsBuilder &operator=(const AddOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateAddOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + AddOptionsBuilder builder_(_fbb); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateAddOptions(flatbuffers::FlatBufferBuilder &_fbb, const AddOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MulOptionsT : public flatbuffers::NativeTable { + typedef MulOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + MulOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct MulOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MulOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + MulOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MulOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MulOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MulOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(MulOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit MulOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MulOptionsBuilder &operator=(const MulOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMulOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + MulOptionsBuilder builder_(_fbb); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateMulOptions(flatbuffers::FlatBufferBuilder &_fbb, const MulOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct L2NormOptionsT : public flatbuffers::NativeTable { + typedef L2NormOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + L2NormOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct L2NormOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef L2NormOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + L2NormOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(L2NormOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const L2NormOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct L2NormOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(L2NormOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit L2NormOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + L2NormOptionsBuilder &operator=(const L2NormOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateL2NormOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + L2NormOptionsBuilder builder_(_fbb); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateL2NormOptions(flatbuffers::FlatBufferBuilder &_fbb, const L2NormOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LocalResponseNormalizationOptionsT : public flatbuffers::NativeTable { + typedef LocalResponseNormalizationOptions TableType; + int32_t radius; + float bias; + float alpha; + float beta; + LocalResponseNormalizationOptionsT() + : radius(0), + bias(0.0f), + alpha(0.0f), + beta(0.0f) { + } +}; + +struct LocalResponseNormalizationOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LocalResponseNormalizationOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_RADIUS = 4, + VT_BIAS = 6, + VT_ALPHA = 8, + VT_BETA = 10 + }; + int32_t radius() const { + return GetField(VT_RADIUS, 0); + } + float bias() const { + return GetField(VT_BIAS, 0.0f); + } + float alpha() const { + return GetField(VT_ALPHA, 0.0f); + } + float beta() const { + return GetField(VT_BETA, 0.0f); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_RADIUS) && + VerifyField(verifier, VT_BIAS) && + VerifyField(verifier, VT_ALPHA) && + VerifyField(verifier, VT_BETA) && + verifier.EndTable(); + } + LocalResponseNormalizationOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LocalResponseNormalizationOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LocalResponseNormalizationOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LocalResponseNormalizationOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_radius(int32_t radius) { + fbb_.AddElement(LocalResponseNormalizationOptions::VT_RADIUS, radius, 0); + } + void add_bias(float bias) { + fbb_.AddElement(LocalResponseNormalizationOptions::VT_BIAS, bias, 0.0f); + } + void add_alpha(float alpha) { + fbb_.AddElement(LocalResponseNormalizationOptions::VT_ALPHA, alpha, 0.0f); + } + void add_beta(float beta) { + fbb_.AddElement(LocalResponseNormalizationOptions::VT_BETA, beta, 0.0f); + } + explicit LocalResponseNormalizationOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LocalResponseNormalizationOptionsBuilder &operator=(const LocalResponseNormalizationOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLocalResponseNormalizationOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t radius = 0, + float bias = 0.0f, + float alpha = 0.0f, + float beta = 0.0f) { + LocalResponseNormalizationOptionsBuilder builder_(_fbb); + builder_.add_beta(beta); + builder_.add_alpha(alpha); + builder_.add_bias(bias); + builder_.add_radius(radius); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLocalResponseNormalizationOptions(flatbuffers::FlatBufferBuilder &_fbb, const LocalResponseNormalizationOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LSTMOptionsT : public flatbuffers::NativeTable { + typedef LSTMOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + float cell_clip; + float proj_clip; + tflite::LSTMKernelType kernel_type; + bool asymmetric_quantize_inputs; + LSTMOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE), + cell_clip(0.0f), + proj_clip(0.0f), + kernel_type(tflite::LSTMKernelType_FULL), + asymmetric_quantize_inputs(false) { + } +}; + +struct LSTMOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LSTMOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_CELL_CLIP = 6, + VT_PROJ_CLIP = 8, + VT_KERNEL_TYPE = 10, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 12 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + float cell_clip() const { + return GetField(VT_CELL_CLIP, 0.0f); + } + float proj_clip() const { + return GetField(VT_PROJ_CLIP, 0.0f); + } + tflite::LSTMKernelType kernel_type() const { + return static_cast(GetField(VT_KERNEL_TYPE, 0)); + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_CELL_CLIP) && + VerifyField(verifier, VT_PROJ_CLIP) && + VerifyField(verifier, VT_KERNEL_TYPE) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + LSTMOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LSTMOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(LSTMOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_cell_clip(float cell_clip) { + fbb_.AddElement(LSTMOptions::VT_CELL_CLIP, cell_clip, 0.0f); + } + void add_proj_clip(float proj_clip) { + fbb_.AddElement(LSTMOptions::VT_PROJ_CLIP, proj_clip, 0.0f); + } + void add_kernel_type(tflite::LSTMKernelType kernel_type) { + fbb_.AddElement(LSTMOptions::VT_KERNEL_TYPE, static_cast(kernel_type), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(LSTMOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit LSTMOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LSTMOptionsBuilder &operator=(const LSTMOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLSTMOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + float cell_clip = 0.0f, + float proj_clip = 0.0f, + tflite::LSTMKernelType kernel_type = tflite::LSTMKernelType_FULL, + bool asymmetric_quantize_inputs = false) { + LSTMOptionsBuilder builder_(_fbb); + builder_.add_proj_clip(proj_clip); + builder_.add_cell_clip(cell_clip); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_kernel_type(kernel_type); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const LSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct UnidirectionalSequenceLSTMOptionsT : public flatbuffers::NativeTable { + typedef UnidirectionalSequenceLSTMOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + float cell_clip; + float proj_clip; + bool time_major; + bool asymmetric_quantize_inputs; + UnidirectionalSequenceLSTMOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE), + cell_clip(0.0f), + proj_clip(0.0f), + time_major(false), + asymmetric_quantize_inputs(false) { + } +}; + +struct UnidirectionalSequenceLSTMOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnidirectionalSequenceLSTMOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_CELL_CLIP = 6, + VT_PROJ_CLIP = 8, + VT_TIME_MAJOR = 10, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 12 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + float cell_clip() const { + return GetField(VT_CELL_CLIP, 0.0f); + } + float proj_clip() const { + return GetField(VT_PROJ_CLIP, 0.0f); + } + bool time_major() const { + return GetField(VT_TIME_MAJOR, 0) != 0; + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_CELL_CLIP) && + VerifyField(verifier, VT_PROJ_CLIP) && + VerifyField(verifier, VT_TIME_MAJOR) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + UnidirectionalSequenceLSTMOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(UnidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnidirectionalSequenceLSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct UnidirectionalSequenceLSTMOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(UnidirectionalSequenceLSTMOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_cell_clip(float cell_clip) { + fbb_.AddElement(UnidirectionalSequenceLSTMOptions::VT_CELL_CLIP, cell_clip, 0.0f); + } + void add_proj_clip(float proj_clip) { + fbb_.AddElement(UnidirectionalSequenceLSTMOptions::VT_PROJ_CLIP, proj_clip, 0.0f); + } + void add_time_major(bool time_major) { + fbb_.AddElement(UnidirectionalSequenceLSTMOptions::VT_TIME_MAJOR, static_cast(time_major), 0); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(UnidirectionalSequenceLSTMOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit UnidirectionalSequenceLSTMOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnidirectionalSequenceLSTMOptionsBuilder &operator=(const UnidirectionalSequenceLSTMOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateUnidirectionalSequenceLSTMOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + float cell_clip = 0.0f, + float proj_clip = 0.0f, + bool time_major = false, + bool asymmetric_quantize_inputs = false) { + UnidirectionalSequenceLSTMOptionsBuilder builder_(_fbb); + builder_.add_proj_clip(proj_clip); + builder_.add_cell_clip(cell_clip); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_time_major(time_major); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateUnidirectionalSequenceLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const UnidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BidirectionalSequenceLSTMOptionsT : public flatbuffers::NativeTable { + typedef BidirectionalSequenceLSTMOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + float cell_clip; + float proj_clip; + bool merge_outputs; + bool time_major; + bool asymmetric_quantize_inputs; + BidirectionalSequenceLSTMOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE), + cell_clip(0.0f), + proj_clip(0.0f), + merge_outputs(false), + time_major(true), + asymmetric_quantize_inputs(false) { + } +}; + +struct BidirectionalSequenceLSTMOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BidirectionalSequenceLSTMOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_CELL_CLIP = 6, + VT_PROJ_CLIP = 8, + VT_MERGE_OUTPUTS = 10, + VT_TIME_MAJOR = 12, + VT_ASYMMETRIC_QUANTIZE_INPUTS = 14 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + float cell_clip() const { + return GetField(VT_CELL_CLIP, 0.0f); + } + float proj_clip() const { + return GetField(VT_PROJ_CLIP, 0.0f); + } + bool merge_outputs() const { + return GetField(VT_MERGE_OUTPUTS, 0) != 0; + } + bool time_major() const { + return GetField(VT_TIME_MAJOR, 1) != 0; + } + bool asymmetric_quantize_inputs() const { + return GetField(VT_ASYMMETRIC_QUANTIZE_INPUTS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + VerifyField(verifier, VT_CELL_CLIP) && + VerifyField(verifier, VT_PROJ_CLIP) && + VerifyField(verifier, VT_MERGE_OUTPUTS) && + VerifyField(verifier, VT_TIME_MAJOR) && + VerifyField(verifier, VT_ASYMMETRIC_QUANTIZE_INPUTS) && + verifier.EndTable(); + } + BidirectionalSequenceLSTMOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceLSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BidirectionalSequenceLSTMOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + void add_cell_clip(float cell_clip) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_CELL_CLIP, cell_clip, 0.0f); + } + void add_proj_clip(float proj_clip) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_PROJ_CLIP, proj_clip, 0.0f); + } + void add_merge_outputs(bool merge_outputs) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_MERGE_OUTPUTS, static_cast(merge_outputs), 0); + } + void add_time_major(bool time_major) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_TIME_MAJOR, static_cast(time_major), 1); + } + void add_asymmetric_quantize_inputs(bool asymmetric_quantize_inputs) { + fbb_.AddElement(BidirectionalSequenceLSTMOptions::VT_ASYMMETRIC_QUANTIZE_INPUTS, static_cast(asymmetric_quantize_inputs), 0); + } + explicit BidirectionalSequenceLSTMOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BidirectionalSequenceLSTMOptionsBuilder &operator=(const BidirectionalSequenceLSTMOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateBidirectionalSequenceLSTMOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE, + float cell_clip = 0.0f, + float proj_clip = 0.0f, + bool merge_outputs = false, + bool time_major = true, + bool asymmetric_quantize_inputs = false) { + BidirectionalSequenceLSTMOptionsBuilder builder_(_fbb); + builder_.add_proj_clip(proj_clip); + builder_.add_cell_clip(cell_clip); + builder_.add_asymmetric_quantize_inputs(asymmetric_quantize_inputs); + builder_.add_time_major(time_major); + builder_.add_merge_outputs(merge_outputs); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateBidirectionalSequenceLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ResizeBilinearOptionsT : public flatbuffers::NativeTable { + typedef ResizeBilinearOptions TableType; + bool align_corners; + bool half_pixel_centers; + ResizeBilinearOptionsT() + : align_corners(false), + half_pixel_centers(false) { + } +}; + +struct ResizeBilinearOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ResizeBilinearOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ALIGN_CORNERS = 8, + VT_HALF_PIXEL_CENTERS = 10 + }; + bool align_corners() const { + return GetField(VT_ALIGN_CORNERS, 0) != 0; + } + bool half_pixel_centers() const { + return GetField(VT_HALF_PIXEL_CENTERS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ALIGN_CORNERS) && + VerifyField(verifier, VT_HALF_PIXEL_CENTERS) && + verifier.EndTable(); + } + ResizeBilinearOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ResizeBilinearOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ResizeBilinearOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ResizeBilinearOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_align_corners(bool align_corners) { + fbb_.AddElement(ResizeBilinearOptions::VT_ALIGN_CORNERS, static_cast(align_corners), 0); + } + void add_half_pixel_centers(bool half_pixel_centers) { + fbb_.AddElement(ResizeBilinearOptions::VT_HALF_PIXEL_CENTERS, static_cast(half_pixel_centers), 0); + } + explicit ResizeBilinearOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ResizeBilinearOptionsBuilder &operator=(const ResizeBilinearOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateResizeBilinearOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool align_corners = false, + bool half_pixel_centers = false) { + ResizeBilinearOptionsBuilder builder_(_fbb); + builder_.add_half_pixel_centers(half_pixel_centers); + builder_.add_align_corners(align_corners); + return builder_.Finish(); +} + +flatbuffers::Offset CreateResizeBilinearOptions(flatbuffers::FlatBufferBuilder &_fbb, const ResizeBilinearOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ResizeNearestNeighborOptionsT : public flatbuffers::NativeTable { + typedef ResizeNearestNeighborOptions TableType; + bool align_corners; + bool half_pixel_centers; + ResizeNearestNeighborOptionsT() + : align_corners(false), + half_pixel_centers(false) { + } +}; + +struct ResizeNearestNeighborOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ResizeNearestNeighborOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ALIGN_CORNERS = 4, + VT_HALF_PIXEL_CENTERS = 6 + }; + bool align_corners() const { + return GetField(VT_ALIGN_CORNERS, 0) != 0; + } + bool half_pixel_centers() const { + return GetField(VT_HALF_PIXEL_CENTERS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ALIGN_CORNERS) && + VerifyField(verifier, VT_HALF_PIXEL_CENTERS) && + verifier.EndTable(); + } + ResizeNearestNeighborOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ResizeNearestNeighborOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ResizeNearestNeighborOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ResizeNearestNeighborOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_align_corners(bool align_corners) { + fbb_.AddElement(ResizeNearestNeighborOptions::VT_ALIGN_CORNERS, static_cast(align_corners), 0); + } + void add_half_pixel_centers(bool half_pixel_centers) { + fbb_.AddElement(ResizeNearestNeighborOptions::VT_HALF_PIXEL_CENTERS, static_cast(half_pixel_centers), 0); + } + explicit ResizeNearestNeighborOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ResizeNearestNeighborOptionsBuilder &operator=(const ResizeNearestNeighborOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateResizeNearestNeighborOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool align_corners = false, + bool half_pixel_centers = false) { + ResizeNearestNeighborOptionsBuilder builder_(_fbb); + builder_.add_half_pixel_centers(half_pixel_centers); + builder_.add_align_corners(align_corners); + return builder_.Finish(); +} + +flatbuffers::Offset CreateResizeNearestNeighborOptions(flatbuffers::FlatBufferBuilder &_fbb, const ResizeNearestNeighborOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct CallOptionsT : public flatbuffers::NativeTable { + typedef CallOptions TableType; + uint32_t subgraph; + CallOptionsT() + : subgraph(0) { + } +}; + +struct CallOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef CallOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SUBGRAPH = 4 + }; + uint32_t subgraph() const { + return GetField(VT_SUBGRAPH, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SUBGRAPH) && + verifier.EndTable(); + } + CallOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(CallOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CallOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct CallOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_subgraph(uint32_t subgraph) { + fbb_.AddElement(CallOptions::VT_SUBGRAPH, subgraph, 0); + } + explicit CallOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + CallOptionsBuilder &operator=(const CallOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateCallOptions( + flatbuffers::FlatBufferBuilder &_fbb, + uint32_t subgraph = 0) { + CallOptionsBuilder builder_(_fbb); + builder_.add_subgraph(subgraph); + return builder_.Finish(); +} + +flatbuffers::Offset CreateCallOptions(flatbuffers::FlatBufferBuilder &_fbb, const CallOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct PadOptionsT : public flatbuffers::NativeTable { + typedef PadOptions TableType; + PadOptionsT() { + } +}; + +struct PadOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PadOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + PadOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(PadOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PadOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct PadOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit PadOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + PadOptionsBuilder &operator=(const PadOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreatePadOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + PadOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreatePadOptions(flatbuffers::FlatBufferBuilder &_fbb, const PadOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct PadV2OptionsT : public flatbuffers::NativeTable { + typedef PadV2Options TableType; + PadV2OptionsT() { + } +}; + +struct PadV2Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PadV2OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + PadV2OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(PadV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PadV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct PadV2OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit PadV2OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + PadV2OptionsBuilder &operator=(const PadV2OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreatePadV2Options( + flatbuffers::FlatBufferBuilder &_fbb) { + PadV2OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreatePadV2Options(flatbuffers::FlatBufferBuilder &_fbb, const PadV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ReshapeOptionsT : public flatbuffers::NativeTable { + typedef ReshapeOptions TableType; + std::vector new_shape; + ReshapeOptionsT() { + } +}; + +struct ReshapeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ReshapeOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NEW_SHAPE = 4 + }; + const flatbuffers::Vector *new_shape() const { + return GetPointer *>(VT_NEW_SHAPE); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NEW_SHAPE) && + verifier.VerifyVector(new_shape()) && + verifier.EndTable(); + } + ReshapeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ReshapeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReshapeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ReshapeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_new_shape(flatbuffers::Offset> new_shape) { + fbb_.AddOffset(ReshapeOptions::VT_NEW_SHAPE, new_shape); + } + explicit ReshapeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ReshapeOptionsBuilder &operator=(const ReshapeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateReshapeOptions( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> new_shape = 0) { + ReshapeOptionsBuilder builder_(_fbb); + builder_.add_new_shape(new_shape); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateReshapeOptionsDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *new_shape = nullptr) { + auto new_shape__ = new_shape ? _fbb.CreateVector(*new_shape) : 0; + return tflite::CreateReshapeOptions( + _fbb, + new_shape__); +} + +flatbuffers::Offset CreateReshapeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReshapeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SpaceToBatchNDOptionsT : public flatbuffers::NativeTable { + typedef SpaceToBatchNDOptions TableType; + SpaceToBatchNDOptionsT() { + } +}; + +struct SpaceToBatchNDOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SpaceToBatchNDOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SpaceToBatchNDOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SpaceToBatchNDOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToBatchNDOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SpaceToBatchNDOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SpaceToBatchNDOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SpaceToBatchNDOptionsBuilder &operator=(const SpaceToBatchNDOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSpaceToBatchNDOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SpaceToBatchNDOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSpaceToBatchNDOptions(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToBatchNDOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BatchToSpaceNDOptionsT : public flatbuffers::NativeTable { + typedef BatchToSpaceNDOptions TableType; + BatchToSpaceNDOptionsT() { + } +}; + +struct BatchToSpaceNDOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BatchToSpaceNDOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + BatchToSpaceNDOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BatchToSpaceNDOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const BatchToSpaceNDOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BatchToSpaceNDOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit BatchToSpaceNDOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BatchToSpaceNDOptionsBuilder &operator=(const BatchToSpaceNDOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateBatchToSpaceNDOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + BatchToSpaceNDOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateBatchToSpaceNDOptions(flatbuffers::FlatBufferBuilder &_fbb, const BatchToSpaceNDOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SkipGramOptionsT : public flatbuffers::NativeTable { + typedef SkipGramOptions TableType; + int32_t ngram_size; + int32_t max_skip_size; + bool include_all_ngrams; + SkipGramOptionsT() + : ngram_size(0), + max_skip_size(0), + include_all_ngrams(false) { + } +}; + +struct SkipGramOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SkipGramOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NGRAM_SIZE = 4, + VT_MAX_SKIP_SIZE = 6, + VT_INCLUDE_ALL_NGRAMS = 8 + }; + int32_t ngram_size() const { + return GetField(VT_NGRAM_SIZE, 0); + } + int32_t max_skip_size() const { + return GetField(VT_MAX_SKIP_SIZE, 0); + } + bool include_all_ngrams() const { + return GetField(VT_INCLUDE_ALL_NGRAMS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NGRAM_SIZE) && + VerifyField(verifier, VT_MAX_SKIP_SIZE) && + VerifyField(verifier, VT_INCLUDE_ALL_NGRAMS) && + verifier.EndTable(); + } + SkipGramOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SkipGramOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SkipGramOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SkipGramOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_ngram_size(int32_t ngram_size) { + fbb_.AddElement(SkipGramOptions::VT_NGRAM_SIZE, ngram_size, 0); + } + void add_max_skip_size(int32_t max_skip_size) { + fbb_.AddElement(SkipGramOptions::VT_MAX_SKIP_SIZE, max_skip_size, 0); + } + void add_include_all_ngrams(bool include_all_ngrams) { + fbb_.AddElement(SkipGramOptions::VT_INCLUDE_ALL_NGRAMS, static_cast(include_all_ngrams), 0); + } + explicit SkipGramOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SkipGramOptionsBuilder &operator=(const SkipGramOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSkipGramOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t ngram_size = 0, + int32_t max_skip_size = 0, + bool include_all_ngrams = false) { + SkipGramOptionsBuilder builder_(_fbb); + builder_.add_max_skip_size(max_skip_size); + builder_.add_ngram_size(ngram_size); + builder_.add_include_all_ngrams(include_all_ngrams); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSkipGramOptions(flatbuffers::FlatBufferBuilder &_fbb, const SkipGramOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SpaceToDepthOptionsT : public flatbuffers::NativeTable { + typedef SpaceToDepthOptions TableType; + int32_t block_size; + SpaceToDepthOptionsT() + : block_size(0) { + } +}; + +struct SpaceToDepthOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SpaceToDepthOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BLOCK_SIZE = 4 + }; + int32_t block_size() const { + return GetField(VT_BLOCK_SIZE, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_BLOCK_SIZE) && + verifier.EndTable(); + } + SpaceToDepthOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SpaceToDepthOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToDepthOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SpaceToDepthOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_block_size(int32_t block_size) { + fbb_.AddElement(SpaceToDepthOptions::VT_BLOCK_SIZE, block_size, 0); + } + explicit SpaceToDepthOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SpaceToDepthOptionsBuilder &operator=(const SpaceToDepthOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSpaceToDepthOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t block_size = 0) { + SpaceToDepthOptionsBuilder builder_(_fbb); + builder_.add_block_size(block_size); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSpaceToDepthOptions(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToDepthOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DepthToSpaceOptionsT : public flatbuffers::NativeTable { + typedef DepthToSpaceOptions TableType; + int32_t block_size; + DepthToSpaceOptionsT() + : block_size(0) { + } +}; + +struct DepthToSpaceOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DepthToSpaceOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BLOCK_SIZE = 4 + }; + int32_t block_size() const { + return GetField(VT_BLOCK_SIZE, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_BLOCK_SIZE) && + verifier.EndTable(); + } + DepthToSpaceOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DepthToSpaceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DepthToSpaceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct DepthToSpaceOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_block_size(int32_t block_size) { + fbb_.AddElement(DepthToSpaceOptions::VT_BLOCK_SIZE, block_size, 0); + } + explicit DepthToSpaceOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DepthToSpaceOptionsBuilder &operator=(const DepthToSpaceOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDepthToSpaceOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t block_size = 0) { + DepthToSpaceOptionsBuilder builder_(_fbb); + builder_.add_block_size(block_size); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDepthToSpaceOptions(flatbuffers::FlatBufferBuilder &_fbb, const DepthToSpaceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SubOptionsT : public flatbuffers::NativeTable { + typedef SubOptions TableType; + bool pot_scale_int16; + tflite::ActivationFunctionType fused_activation_function; + SubOptionsT() + : pot_scale_int16(true), + fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct SubOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SubOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4, + VT_POT_SCALE_INT16 = 6 + }; + bool pot_scale_int16() const { + return GetField(VT_POT_SCALE_INT16, 0) != 0; + } + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_POT_SCALE_INT16) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + SubOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SubOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SubOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SubOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(SubOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit SubOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SubOptionsBuilder &operator=(const SubOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSubOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + SubOptionsBuilder builder_(_fbb); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSubOptions(flatbuffers::FlatBufferBuilder &_fbb, const SubOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DivOptionsT : public flatbuffers::NativeTable { + typedef DivOptions TableType; + tflite::ActivationFunctionType fused_activation_function; + DivOptionsT() + : fused_activation_function(tflite::ActivationFunctionType_NONE) { + } +}; + +struct DivOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DivOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FUSED_ACTIVATION_FUNCTION = 4 + }; + tflite::ActivationFunctionType fused_activation_function() const { + return static_cast(GetField(VT_FUSED_ACTIVATION_FUNCTION, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_FUSED_ACTIVATION_FUNCTION) && + verifier.EndTable(); + } + DivOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DivOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DivOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct DivOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_fused_activation_function(tflite::ActivationFunctionType fused_activation_function) { + fbb_.AddElement(DivOptions::VT_FUSED_ACTIVATION_FUNCTION, static_cast(fused_activation_function), 0); + } + explicit DivOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DivOptionsBuilder &operator=(const DivOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDivOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::ActivationFunctionType fused_activation_function = tflite::ActivationFunctionType_NONE) { + DivOptionsBuilder builder_(_fbb); + builder_.add_fused_activation_function(fused_activation_function); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDivOptions(flatbuffers::FlatBufferBuilder &_fbb, const DivOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct TopKV2OptionsT : public flatbuffers::NativeTable { + typedef TopKV2Options TableType; + TopKV2OptionsT() { + } +}; + +struct TopKV2Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TopKV2OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + TopKV2OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(TopKV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const TopKV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct TopKV2OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit TopKV2OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + TopKV2OptionsBuilder &operator=(const TopKV2OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateTopKV2Options( + flatbuffers::FlatBufferBuilder &_fbb) { + TopKV2OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateTopKV2Options(flatbuffers::FlatBufferBuilder &_fbb, const TopKV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EmbeddingLookupSparseOptionsT : public flatbuffers::NativeTable { + typedef EmbeddingLookupSparseOptions TableType; + tflite::CombinerType combiner; + EmbeddingLookupSparseOptionsT() + : combiner(tflite::CombinerType_SUM) { + } +}; + +struct EmbeddingLookupSparseOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EmbeddingLookupSparseOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_COMBINER = 4 + }; + tflite::CombinerType combiner() const { + return static_cast(GetField(VT_COMBINER, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_COMBINER) && + verifier.EndTable(); + } + EmbeddingLookupSparseOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EmbeddingLookupSparseOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const EmbeddingLookupSparseOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EmbeddingLookupSparseOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_combiner(tflite::CombinerType combiner) { + fbb_.AddElement(EmbeddingLookupSparseOptions::VT_COMBINER, static_cast(combiner), 0); + } + explicit EmbeddingLookupSparseOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EmbeddingLookupSparseOptionsBuilder &operator=(const EmbeddingLookupSparseOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateEmbeddingLookupSparseOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::CombinerType combiner = tflite::CombinerType_SUM) { + EmbeddingLookupSparseOptionsBuilder builder_(_fbb); + builder_.add_combiner(combiner); + return builder_.Finish(); +} + +flatbuffers::Offset CreateEmbeddingLookupSparseOptions(flatbuffers::FlatBufferBuilder &_fbb, const EmbeddingLookupSparseOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GatherOptionsT : public flatbuffers::NativeTable { + typedef GatherOptions TableType; + int32_t axis; + GatherOptionsT() + : axis(0) { + } +}; + +struct GatherOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GatherOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_AXIS = 4 + }; + int32_t axis() const { + return GetField(VT_AXIS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_AXIS) && + verifier.EndTable(); + } + GatherOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GatherOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GatherOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GatherOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_axis(int32_t axis) { + fbb_.AddElement(GatherOptions::VT_AXIS, axis, 0); + } + explicit GatherOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GatherOptionsBuilder &operator=(const GatherOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGatherOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t axis = 0) { + GatherOptionsBuilder builder_(_fbb); + builder_.add_axis(axis); + return builder_.Finish(); +} + +flatbuffers::Offset CreateGatherOptions(flatbuffers::FlatBufferBuilder &_fbb, const GatherOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct TransposeOptionsT : public flatbuffers::NativeTable { + typedef TransposeOptions TableType; + TransposeOptionsT() { + } +}; + +struct TransposeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TransposeOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + TransposeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(TransposeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const TransposeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct TransposeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit TransposeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + TransposeOptionsBuilder &operator=(const TransposeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateTransposeOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + TransposeOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateTransposeOptions(flatbuffers::FlatBufferBuilder &_fbb, const TransposeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ExpOptionsT : public flatbuffers::NativeTable { + typedef ExpOptions TableType; + ExpOptionsT() { + } +}; + +struct ExpOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ExpOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + ExpOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ExpOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ExpOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ExpOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit ExpOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ExpOptionsBuilder &operator=(const ExpOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateExpOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + ExpOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateExpOptions(flatbuffers::FlatBufferBuilder &_fbb, const ExpOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct CosOptionsT : public flatbuffers::NativeTable { + typedef CosOptions TableType; + CosOptionsT() { + } +}; + +struct CosOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef CosOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + CosOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(CosOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CosOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct CosOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit CosOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + CosOptionsBuilder &operator=(const CosOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateCosOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + CosOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateCosOptions(flatbuffers::FlatBufferBuilder &_fbb, const CosOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ReducerOptionsT : public flatbuffers::NativeTable { + typedef ReducerOptions TableType; + bool keep_dims; + ReducerOptionsT() + : keep_dims(false) { + } +}; + +struct ReducerOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ReducerOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_KEEP_DIMS = 4 + }; + bool keep_dims() const { + return GetField(VT_KEEP_DIMS, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_KEEP_DIMS) && + verifier.EndTable(); + } + ReducerOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ReducerOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReducerOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ReducerOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_keep_dims(bool keep_dims) { + fbb_.AddElement(ReducerOptions::VT_KEEP_DIMS, static_cast(keep_dims), 0); + } + explicit ReducerOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ReducerOptionsBuilder &operator=(const ReducerOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateReducerOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool keep_dims = false) { + ReducerOptionsBuilder builder_(_fbb); + builder_.add_keep_dims(keep_dims); + return builder_.Finish(); +} + +flatbuffers::Offset CreateReducerOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReducerOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SqueezeOptionsT : public flatbuffers::NativeTable { + typedef SqueezeOptions TableType; + std::vector squeeze_dims; + SqueezeOptionsT() { + } +}; + +struct SqueezeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SqueezeOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SQUEEZE_DIMS = 4 + }; + const flatbuffers::Vector *squeeze_dims() const { + return GetPointer *>(VT_SQUEEZE_DIMS); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_SQUEEZE_DIMS) && + verifier.VerifyVector(squeeze_dims()) && + verifier.EndTable(); + } + SqueezeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SqueezeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SqueezeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SqueezeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_squeeze_dims(flatbuffers::Offset> squeeze_dims) { + fbb_.AddOffset(SqueezeOptions::VT_SQUEEZE_DIMS, squeeze_dims); + } + explicit SqueezeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SqueezeOptionsBuilder &operator=(const SqueezeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSqueezeOptions( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> squeeze_dims = 0) { + SqueezeOptionsBuilder builder_(_fbb); + builder_.add_squeeze_dims(squeeze_dims); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateSqueezeOptionsDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *squeeze_dims = nullptr) { + auto squeeze_dims__ = squeeze_dims ? _fbb.CreateVector(*squeeze_dims) : 0; + return tflite::CreateSqueezeOptions( + _fbb, + squeeze_dims__); +} + +flatbuffers::Offset CreateSqueezeOptions(flatbuffers::FlatBufferBuilder &_fbb, const SqueezeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SplitOptionsT : public flatbuffers::NativeTable { + typedef SplitOptions TableType; + int32_t num_splits; + SplitOptionsT() + : num_splits(0) { + } +}; + +struct SplitOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SplitOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUM_SPLITS = 4 + }; + int32_t num_splits() const { + return GetField(VT_NUM_SPLITS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUM_SPLITS) && + verifier.EndTable(); + } + SplitOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SplitOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SplitOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SplitOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_num_splits(int32_t num_splits) { + fbb_.AddElement(SplitOptions::VT_NUM_SPLITS, num_splits, 0); + } + explicit SplitOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SplitOptionsBuilder &operator=(const SplitOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSplitOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t num_splits = 0) { + SplitOptionsBuilder builder_(_fbb); + builder_.add_num_splits(num_splits); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSplitOptions(flatbuffers::FlatBufferBuilder &_fbb, const SplitOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SplitVOptionsT : public flatbuffers::NativeTable { + typedef SplitVOptions TableType; + int32_t num_splits; + SplitVOptionsT() + : num_splits(0) { + } +}; + +struct SplitVOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SplitVOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUM_SPLITS = 4 + }; + int32_t num_splits() const { + return GetField(VT_NUM_SPLITS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUM_SPLITS) && + verifier.EndTable(); + } + SplitVOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SplitVOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SplitVOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SplitVOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_num_splits(int32_t num_splits) { + fbb_.AddElement(SplitVOptions::VT_NUM_SPLITS, num_splits, 0); + } + explicit SplitVOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SplitVOptionsBuilder &operator=(const SplitVOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSplitVOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t num_splits = 0) { + SplitVOptionsBuilder builder_(_fbb); + builder_.add_num_splits(num_splits); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSplitVOptions(flatbuffers::FlatBufferBuilder &_fbb, const SplitVOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct StridedSliceOptionsT : public flatbuffers::NativeTable { + typedef StridedSliceOptions TableType; + int32_t begin_mask; + int32_t end_mask; + int32_t ellipsis_mask; + int32_t new_axis_mask; + int32_t shrink_axis_mask; + StridedSliceOptionsT() + : begin_mask(0), + end_mask(0), + ellipsis_mask(0), + new_axis_mask(0), + shrink_axis_mask(0) { + } +}; + +struct StridedSliceOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef StridedSliceOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BEGIN_MASK = 4, + VT_END_MASK = 6, + VT_ELLIPSIS_MASK = 8, + VT_NEW_AXIS_MASK = 10, + VT_SHRINK_AXIS_MASK = 12 + }; + int32_t begin_mask() const { + return GetField(VT_BEGIN_MASK, 0); + } + int32_t end_mask() const { + return GetField(VT_END_MASK, 0); + } + int32_t ellipsis_mask() const { + return GetField(VT_ELLIPSIS_MASK, 0); + } + int32_t new_axis_mask() const { + return GetField(VT_NEW_AXIS_MASK, 0); + } + int32_t shrink_axis_mask() const { + return GetField(VT_SHRINK_AXIS_MASK, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_BEGIN_MASK) && + VerifyField(verifier, VT_END_MASK) && + VerifyField(verifier, VT_ELLIPSIS_MASK) && + VerifyField(verifier, VT_NEW_AXIS_MASK) && + VerifyField(verifier, VT_SHRINK_AXIS_MASK) && + verifier.EndTable(); + } + StridedSliceOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(StridedSliceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const StridedSliceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct StridedSliceOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_begin_mask(int32_t begin_mask) { + fbb_.AddElement(StridedSliceOptions::VT_BEGIN_MASK, begin_mask, 0); + } + void add_end_mask(int32_t end_mask) { + fbb_.AddElement(StridedSliceOptions::VT_END_MASK, end_mask, 0); + } + void add_ellipsis_mask(int32_t ellipsis_mask) { + fbb_.AddElement(StridedSliceOptions::VT_ELLIPSIS_MASK, ellipsis_mask, 0); + } + void add_new_axis_mask(int32_t new_axis_mask) { + fbb_.AddElement(StridedSliceOptions::VT_NEW_AXIS_MASK, new_axis_mask, 0); + } + void add_shrink_axis_mask(int32_t shrink_axis_mask) { + fbb_.AddElement(StridedSliceOptions::VT_SHRINK_AXIS_MASK, shrink_axis_mask, 0); + } + explicit StridedSliceOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + StridedSliceOptionsBuilder &operator=(const StridedSliceOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateStridedSliceOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t begin_mask = 0, + int32_t end_mask = 0, + int32_t ellipsis_mask = 0, + int32_t new_axis_mask = 0, + int32_t shrink_axis_mask = 0) { + StridedSliceOptionsBuilder builder_(_fbb); + builder_.add_shrink_axis_mask(shrink_axis_mask); + builder_.add_new_axis_mask(new_axis_mask); + builder_.add_ellipsis_mask(ellipsis_mask); + builder_.add_end_mask(end_mask); + builder_.add_begin_mask(begin_mask); + return builder_.Finish(); +} + +flatbuffers::Offset CreateStridedSliceOptions(flatbuffers::FlatBufferBuilder &_fbb, const StridedSliceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LogSoftmaxOptionsT : public flatbuffers::NativeTable { + typedef LogSoftmaxOptions TableType; + LogSoftmaxOptionsT() { + } +}; + +struct LogSoftmaxOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LogSoftmaxOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LogSoftmaxOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LogSoftmaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogSoftmaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LogSoftmaxOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LogSoftmaxOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LogSoftmaxOptionsBuilder &operator=(const LogSoftmaxOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLogSoftmaxOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LogSoftmaxOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLogSoftmaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogSoftmaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct CastOptionsT : public flatbuffers::NativeTable { + typedef CastOptions TableType; + tflite::TensorType in_data_type; + tflite::TensorType out_data_type; + CastOptionsT() + : in_data_type(tflite::TensorType_FLOAT32), + out_data_type(tflite::TensorType_FLOAT32) { + } +}; + +struct CastOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef CastOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_IN_DATA_TYPE = 4, + VT_OUT_DATA_TYPE = 6 + }; + tflite::TensorType in_data_type() const { + return static_cast(GetField(VT_IN_DATA_TYPE, 0)); + } + tflite::TensorType out_data_type() const { + return static_cast(GetField(VT_OUT_DATA_TYPE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_IN_DATA_TYPE) && + VerifyField(verifier, VT_OUT_DATA_TYPE) && + verifier.EndTable(); + } + CastOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(CastOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CastOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct CastOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_in_data_type(tflite::TensorType in_data_type) { + fbb_.AddElement(CastOptions::VT_IN_DATA_TYPE, static_cast(in_data_type), 0); + } + void add_out_data_type(tflite::TensorType out_data_type) { + fbb_.AddElement(CastOptions::VT_OUT_DATA_TYPE, static_cast(out_data_type), 0); + } + explicit CastOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + CastOptionsBuilder &operator=(const CastOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateCastOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::TensorType in_data_type = tflite::TensorType_FLOAT32, + tflite::TensorType out_data_type = tflite::TensorType_FLOAT32) { + CastOptionsBuilder builder_(_fbb); + builder_.add_out_data_type(out_data_type); + builder_.add_in_data_type(in_data_type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateCastOptions(flatbuffers::FlatBufferBuilder &_fbb, const CastOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DequantizeOptionsT : public flatbuffers::NativeTable { + typedef DequantizeOptions TableType; + DequantizeOptionsT() { + } +}; + +struct DequantizeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DequantizeOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + DequantizeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DequantizeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DequantizeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct DequantizeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit DequantizeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DequantizeOptionsBuilder &operator=(const DequantizeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDequantizeOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + DequantizeOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDequantizeOptions(flatbuffers::FlatBufferBuilder &_fbb, const DequantizeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MaximumMinimumOptionsT : public flatbuffers::NativeTable { + typedef MaximumMinimumOptions TableType; + MaximumMinimumOptionsT() { + } +}; + +struct MaximumMinimumOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MaximumMinimumOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + MaximumMinimumOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MaximumMinimumOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MaximumMinimumOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MaximumMinimumOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit MaximumMinimumOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MaximumMinimumOptionsBuilder &operator=(const MaximumMinimumOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMaximumMinimumOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + MaximumMinimumOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateMaximumMinimumOptions(flatbuffers::FlatBufferBuilder &_fbb, const MaximumMinimumOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct TileOptionsT : public flatbuffers::NativeTable { + typedef TileOptions TableType; + TileOptionsT() { + } +}; + +struct TileOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TileOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + TileOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(TileOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const TileOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct TileOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit TileOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + TileOptionsBuilder &operator=(const TileOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateTileOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + TileOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateTileOptions(flatbuffers::FlatBufferBuilder &_fbb, const TileOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ArgMaxOptionsT : public flatbuffers::NativeTable { + typedef ArgMaxOptions TableType; + tflite::TensorType output_type; + ArgMaxOptionsT() + : output_type(tflite::TensorType_FLOAT32) { + } +}; + +struct ArgMaxOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ArgMaxOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_OUTPUT_TYPE = 4 + }; + tflite::TensorType output_type() const { + return static_cast(GetField(VT_OUTPUT_TYPE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_OUTPUT_TYPE) && + verifier.EndTable(); + } + ArgMaxOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ArgMaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArgMaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ArgMaxOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_output_type(tflite::TensorType output_type) { + fbb_.AddElement(ArgMaxOptions::VT_OUTPUT_TYPE, static_cast(output_type), 0); + } + explicit ArgMaxOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ArgMaxOptionsBuilder &operator=(const ArgMaxOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateArgMaxOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::TensorType output_type = tflite::TensorType_FLOAT32) { + ArgMaxOptionsBuilder builder_(_fbb); + builder_.add_output_type(output_type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateArgMaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const ArgMaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ArgMinOptionsT : public flatbuffers::NativeTable { + typedef ArgMinOptions TableType; + tflite::TensorType output_type; + ArgMinOptionsT() + : output_type(tflite::TensorType_FLOAT32) { + } +}; + +struct ArgMinOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ArgMinOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_OUTPUT_TYPE = 4 + }; + tflite::TensorType output_type() const { + return static_cast(GetField(VT_OUTPUT_TYPE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_OUTPUT_TYPE) && + verifier.EndTable(); + } + ArgMinOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ArgMinOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArgMinOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ArgMinOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_output_type(tflite::TensorType output_type) { + fbb_.AddElement(ArgMinOptions::VT_OUTPUT_TYPE, static_cast(output_type), 0); + } + explicit ArgMinOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ArgMinOptionsBuilder &operator=(const ArgMinOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateArgMinOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::TensorType output_type = tflite::TensorType_FLOAT32) { + ArgMinOptionsBuilder builder_(_fbb); + builder_.add_output_type(output_type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateArgMinOptions(flatbuffers::FlatBufferBuilder &_fbb, const ArgMinOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GreaterOptionsT : public flatbuffers::NativeTable { + typedef GreaterOptions TableType; + GreaterOptionsT() { + } +}; + +struct GreaterOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GreaterOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + GreaterOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GreaterOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GreaterOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GreaterOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit GreaterOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GreaterOptionsBuilder &operator=(const GreaterOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGreaterOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + GreaterOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateGreaterOptions(flatbuffers::FlatBufferBuilder &_fbb, const GreaterOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GreaterEqualOptionsT : public flatbuffers::NativeTable { + typedef GreaterEqualOptions TableType; + GreaterEqualOptionsT() { + } +}; + +struct GreaterEqualOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GreaterEqualOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + GreaterEqualOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GreaterEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GreaterEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GreaterEqualOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit GreaterEqualOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GreaterEqualOptionsBuilder &operator=(const GreaterEqualOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGreaterEqualOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + GreaterEqualOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateGreaterEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const GreaterEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LessOptionsT : public flatbuffers::NativeTable { + typedef LessOptions TableType; + LessOptionsT() { + } +}; + +struct LessOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LessOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LessOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LessOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LessOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LessOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LessOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LessOptionsBuilder &operator=(const LessOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLessOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LessOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLessOptions(flatbuffers::FlatBufferBuilder &_fbb, const LessOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LessEqualOptionsT : public flatbuffers::NativeTable { + typedef LessEqualOptions TableType; + LessEqualOptionsT() { + } +}; + +struct LessEqualOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LessEqualOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LessEqualOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LessEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LessEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LessEqualOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LessEqualOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LessEqualOptionsBuilder &operator=(const LessEqualOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLessEqualOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LessEqualOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLessEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const LessEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct NegOptionsT : public flatbuffers::NativeTable { + typedef NegOptions TableType; + NegOptionsT() { + } +}; + +struct NegOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef NegOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + NegOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(NegOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const NegOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct NegOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit NegOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + NegOptionsBuilder &operator=(const NegOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateNegOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + NegOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateNegOptions(flatbuffers::FlatBufferBuilder &_fbb, const NegOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SelectOptionsT : public flatbuffers::NativeTable { + typedef SelectOptions TableType; + SelectOptionsT() { + } +}; + +struct SelectOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SelectOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SelectOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SelectOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SelectOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SelectOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SelectOptionsBuilder &operator=(const SelectOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSelectOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SelectOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSelectOptions(flatbuffers::FlatBufferBuilder &_fbb, const SelectOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SliceOptionsT : public flatbuffers::NativeTable { + typedef SliceOptions TableType; + SliceOptionsT() { + } +}; + +struct SliceOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SliceOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SliceOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SliceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SliceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SliceOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SliceOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SliceOptionsBuilder &operator=(const SliceOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSliceOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SliceOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSliceOptions(flatbuffers::FlatBufferBuilder &_fbb, const SliceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct TransposeConvOptionsT : public flatbuffers::NativeTable { + typedef TransposeConvOptions TableType; + tflite::Padding padding; + int32_t stride_w; + int32_t stride_h; + TransposeConvOptionsT() + : padding(tflite::Padding_SAME), + stride_w(0), + stride_h(0) { + } +}; + +struct TransposeConvOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef TransposeConvOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PADDING = 4, + VT_STRIDE_W = 6, + VT_STRIDE_H = 8 + }; + tflite::Padding padding() const { + return static_cast(GetField(VT_PADDING, 0)); + } + int32_t stride_w() const { + return GetField(VT_STRIDE_W, 0); + } + int32_t stride_h() const { + return GetField(VT_STRIDE_H, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PADDING) && + VerifyField(verifier, VT_STRIDE_W) && + VerifyField(verifier, VT_STRIDE_H) && + verifier.EndTable(); + } + TransposeConvOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(TransposeConvOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const TransposeConvOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct TransposeConvOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_padding(tflite::Padding padding) { + fbb_.AddElement(TransposeConvOptions::VT_PADDING, static_cast(padding), 0); + } + void add_stride_w(int32_t stride_w) { + fbb_.AddElement(TransposeConvOptions::VT_STRIDE_W, stride_w, 0); + } + void add_stride_h(int32_t stride_h) { + fbb_.AddElement(TransposeConvOptions::VT_STRIDE_H, stride_h, 0); + } + explicit TransposeConvOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + TransposeConvOptionsBuilder &operator=(const TransposeConvOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateTransposeConvOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::Padding padding = tflite::Padding_SAME, + int32_t stride_w = 0, + int32_t stride_h = 0) { + TransposeConvOptionsBuilder builder_(_fbb); + builder_.add_stride_h(stride_h); + builder_.add_stride_w(stride_w); + builder_.add_padding(padding); + return builder_.Finish(); +} + +flatbuffers::Offset CreateTransposeConvOptions(flatbuffers::FlatBufferBuilder &_fbb, const TransposeConvOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ExpandDimsOptionsT : public flatbuffers::NativeTable { + typedef ExpandDimsOptions TableType; + ExpandDimsOptionsT() { + } +}; + +struct ExpandDimsOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ExpandDimsOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + ExpandDimsOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ExpandDimsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ExpandDimsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ExpandDimsOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit ExpandDimsOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ExpandDimsOptionsBuilder &operator=(const ExpandDimsOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateExpandDimsOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + ExpandDimsOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateExpandDimsOptions(flatbuffers::FlatBufferBuilder &_fbb, const ExpandDimsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SparseToDenseOptionsT : public flatbuffers::NativeTable { + typedef SparseToDenseOptions TableType; + bool validate_indices; + SparseToDenseOptionsT() + : validate_indices(false) { + } +}; + +struct SparseToDenseOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SparseToDenseOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VALIDATE_INDICES = 4 + }; + bool validate_indices() const { + return GetField(VT_VALIDATE_INDICES, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_VALIDATE_INDICES) && + verifier.EndTable(); + } + SparseToDenseOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SparseToDenseOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SparseToDenseOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SparseToDenseOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_validate_indices(bool validate_indices) { + fbb_.AddElement(SparseToDenseOptions::VT_VALIDATE_INDICES, static_cast(validate_indices), 0); + } + explicit SparseToDenseOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SparseToDenseOptionsBuilder &operator=(const SparseToDenseOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSparseToDenseOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool validate_indices = false) { + SparseToDenseOptionsBuilder builder_(_fbb); + builder_.add_validate_indices(validate_indices); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSparseToDenseOptions(flatbuffers::FlatBufferBuilder &_fbb, const SparseToDenseOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct EqualOptionsT : public flatbuffers::NativeTable { + typedef EqualOptions TableType; + EqualOptionsT() { + } +}; + +struct EqualOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef EqualOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + EqualOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(EqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const EqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct EqualOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit EqualOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + EqualOptionsBuilder &operator=(const EqualOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateEqualOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + EqualOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const EqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct NotEqualOptionsT : public flatbuffers::NativeTable { + typedef NotEqualOptions TableType; + NotEqualOptionsT() { + } +}; + +struct NotEqualOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef NotEqualOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + NotEqualOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(NotEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const NotEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct NotEqualOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit NotEqualOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + NotEqualOptionsBuilder &operator=(const NotEqualOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateNotEqualOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + NotEqualOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateNotEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const NotEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ShapeOptionsT : public flatbuffers::NativeTable { + typedef ShapeOptions TableType; + tflite::TensorType out_type; + ShapeOptionsT() + : out_type(tflite::TensorType_FLOAT32) { + } +}; + +struct ShapeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ShapeOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_OUT_TYPE = 4 + }; + tflite::TensorType out_type() const { + return static_cast(GetField(VT_OUT_TYPE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_OUT_TYPE) && + verifier.EndTable(); + } + ShapeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ShapeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ShapeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ShapeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_out_type(tflite::TensorType out_type) { + fbb_.AddElement(ShapeOptions::VT_OUT_TYPE, static_cast(out_type), 0); + } + explicit ShapeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ShapeOptionsBuilder &operator=(const ShapeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateShapeOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::TensorType out_type = tflite::TensorType_FLOAT32) { + ShapeOptionsBuilder builder_(_fbb); + builder_.add_out_type(out_type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateShapeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ShapeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct RankOptionsT : public flatbuffers::NativeTable { + typedef RankOptions TableType; + RankOptionsT() { + } +}; + +struct RankOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RankOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + RankOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(RankOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const RankOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct RankOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit RankOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RankOptionsBuilder &operator=(const RankOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateRankOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + RankOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateRankOptions(flatbuffers::FlatBufferBuilder &_fbb, const RankOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct PowOptionsT : public flatbuffers::NativeTable { + typedef PowOptions TableType; + PowOptionsT() { + } +}; + +struct PowOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PowOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + PowOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(PowOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PowOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct PowOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit PowOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + PowOptionsBuilder &operator=(const PowOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreatePowOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + PowOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreatePowOptions(flatbuffers::FlatBufferBuilder &_fbb, const PowOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct FakeQuantOptionsT : public flatbuffers::NativeTable { + typedef FakeQuantOptions TableType; + float min; + float max; + int32_t num_bits; + bool narrow_range; + FakeQuantOptionsT() + : min(0.0f), + max(0.0f), + num_bits(0), + narrow_range(false) { + } +}; + +struct FakeQuantOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FakeQuantOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MIN = 4, + VT_MAX = 6, + VT_NUM_BITS = 8, + VT_NARROW_RANGE = 10 + }; + float min() const { + return GetField(VT_MIN, 0.0f); + } + float max() const { + return GetField(VT_MAX, 0.0f); + } + int32_t num_bits() const { + return GetField(VT_NUM_BITS, 0); + } + bool narrow_range() const { + return GetField(VT_NARROW_RANGE, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_MIN) && + VerifyField(verifier, VT_MAX) && + VerifyField(verifier, VT_NUM_BITS) && + VerifyField(verifier, VT_NARROW_RANGE) && + verifier.EndTable(); + } + FakeQuantOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FakeQuantOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FakeQuantOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FakeQuantOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_min(float min) { + fbb_.AddElement(FakeQuantOptions::VT_MIN, min, 0.0f); + } + void add_max(float max) { + fbb_.AddElement(FakeQuantOptions::VT_MAX, max, 0.0f); + } + void add_num_bits(int32_t num_bits) { + fbb_.AddElement(FakeQuantOptions::VT_NUM_BITS, num_bits, 0); + } + void add_narrow_range(bool narrow_range) { + fbb_.AddElement(FakeQuantOptions::VT_NARROW_RANGE, static_cast(narrow_range), 0); + } + explicit FakeQuantOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + FakeQuantOptionsBuilder &operator=(const FakeQuantOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFakeQuantOptions( + flatbuffers::FlatBufferBuilder &_fbb, + float min = 0.0f, + float max = 0.0f, + int32_t num_bits = 0, + bool narrow_range = false) { + FakeQuantOptionsBuilder builder_(_fbb); + builder_.add_num_bits(num_bits); + builder_.add_max(max); + builder_.add_min(min); + builder_.add_narrow_range(narrow_range); + return builder_.Finish(); +} + +flatbuffers::Offset CreateFakeQuantOptions(flatbuffers::FlatBufferBuilder &_fbb, const FakeQuantOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct PackOptionsT : public flatbuffers::NativeTable { + typedef PackOptions TableType; + int32_t values_count; + int32_t axis; + PackOptionsT() + : values_count(0), + axis(0) { + } +}; + +struct PackOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PackOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VALUES_COUNT = 4, + VT_AXIS = 6 + }; + int32_t values_count() const { + return GetField(VT_VALUES_COUNT, 0); + } + int32_t axis() const { + return GetField(VT_AXIS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_VALUES_COUNT) && + VerifyField(verifier, VT_AXIS) && + verifier.EndTable(); + } + PackOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(PackOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PackOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct PackOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_values_count(int32_t values_count) { + fbb_.AddElement(PackOptions::VT_VALUES_COUNT, values_count, 0); + } + void add_axis(int32_t axis) { + fbb_.AddElement(PackOptions::VT_AXIS, axis, 0); + } + explicit PackOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + PackOptionsBuilder &operator=(const PackOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreatePackOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t values_count = 0, + int32_t axis = 0) { + PackOptionsBuilder builder_(_fbb); + builder_.add_axis(axis); + builder_.add_values_count(values_count); + return builder_.Finish(); +} + +flatbuffers::Offset CreatePackOptions(flatbuffers::FlatBufferBuilder &_fbb, const PackOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LogicalOrOptionsT : public flatbuffers::NativeTable { + typedef LogicalOrOptions TableType; + LogicalOrOptionsT() { + } +}; + +struct LogicalOrOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LogicalOrOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LogicalOrOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LogicalOrOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalOrOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LogicalOrOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LogicalOrOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LogicalOrOptionsBuilder &operator=(const LogicalOrOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLogicalOrOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LogicalOrOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLogicalOrOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalOrOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct OneHotOptionsT : public flatbuffers::NativeTable { + typedef OneHotOptions TableType; + int32_t axis; + OneHotOptionsT() + : axis(0) { + } +}; + +struct OneHotOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OneHotOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_AXIS = 4 + }; + int32_t axis() const { + return GetField(VT_AXIS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_AXIS) && + verifier.EndTable(); + } + OneHotOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(OneHotOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const OneHotOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct OneHotOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_axis(int32_t axis) { + fbb_.AddElement(OneHotOptions::VT_AXIS, axis, 0); + } + explicit OneHotOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + OneHotOptionsBuilder &operator=(const OneHotOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateOneHotOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t axis = 0) { + OneHotOptionsBuilder builder_(_fbb); + builder_.add_axis(axis); + return builder_.Finish(); +} + +flatbuffers::Offset CreateOneHotOptions(flatbuffers::FlatBufferBuilder &_fbb, const OneHotOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct AbsOptionsT : public flatbuffers::NativeTable { + typedef AbsOptions TableType; + AbsOptionsT() { + } +}; + +struct AbsOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef AbsOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + AbsOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(AbsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const AbsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct AbsOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit AbsOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + AbsOptionsBuilder &operator=(const AbsOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateAbsOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + AbsOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateAbsOptions(flatbuffers::FlatBufferBuilder &_fbb, const AbsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct HardSwishOptionsT : public flatbuffers::NativeTable { + typedef HardSwishOptions TableType; + HardSwishOptionsT() { + } +}; + +struct HardSwishOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef HardSwishOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + HardSwishOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(HardSwishOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const HardSwishOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct HardSwishOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit HardSwishOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + HardSwishOptionsBuilder &operator=(const HardSwishOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateHardSwishOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + HardSwishOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateHardSwishOptions(flatbuffers::FlatBufferBuilder &_fbb, const HardSwishOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LogicalAndOptionsT : public flatbuffers::NativeTable { + typedef LogicalAndOptions TableType; + LogicalAndOptionsT() { + } +}; + +struct LogicalAndOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LogicalAndOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LogicalAndOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LogicalAndOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalAndOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LogicalAndOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LogicalAndOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LogicalAndOptionsBuilder &operator=(const LogicalAndOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLogicalAndOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LogicalAndOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLogicalAndOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalAndOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LogicalNotOptionsT : public flatbuffers::NativeTable { + typedef LogicalNotOptions TableType; + LogicalNotOptionsT() { + } +}; + +struct LogicalNotOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LogicalNotOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + LogicalNotOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LogicalNotOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalNotOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LogicalNotOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit LogicalNotOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LogicalNotOptionsBuilder &operator=(const LogicalNotOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLogicalNotOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + LogicalNotOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLogicalNotOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalNotOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct UnpackOptionsT : public flatbuffers::NativeTable { + typedef UnpackOptions TableType; + int32_t num; + int32_t axis; + UnpackOptionsT() + : num(0), + axis(0) { + } +}; + +struct UnpackOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UnpackOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUM = 4, + VT_AXIS = 6 + }; + int32_t num() const { + return GetField(VT_NUM, 0); + } + int32_t axis() const { + return GetField(VT_AXIS, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUM) && + VerifyField(verifier, VT_AXIS) && + verifier.EndTable(); + } + UnpackOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(UnpackOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnpackOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct UnpackOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_num(int32_t num) { + fbb_.AddElement(UnpackOptions::VT_NUM, num, 0); + } + void add_axis(int32_t axis) { + fbb_.AddElement(UnpackOptions::VT_AXIS, axis, 0); + } + explicit UnpackOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UnpackOptionsBuilder &operator=(const UnpackOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateUnpackOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t num = 0, + int32_t axis = 0) { + UnpackOptionsBuilder builder_(_fbb); + builder_.add_axis(axis); + builder_.add_num(num); + return builder_.Finish(); +} + +flatbuffers::Offset CreateUnpackOptions(flatbuffers::FlatBufferBuilder &_fbb, const UnpackOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct FloorDivOptionsT : public flatbuffers::NativeTable { + typedef FloorDivOptions TableType; + FloorDivOptionsT() { + } +}; + +struct FloorDivOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FloorDivOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + FloorDivOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FloorDivOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FloorDivOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FloorDivOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit FloorDivOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + FloorDivOptionsBuilder &operator=(const FloorDivOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFloorDivOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + FloorDivOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateFloorDivOptions(flatbuffers::FlatBufferBuilder &_fbb, const FloorDivOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SquareOptionsT : public flatbuffers::NativeTable { + typedef SquareOptions TableType; + SquareOptionsT() { + } +}; + +struct SquareOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SquareOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SquareOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SquareOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SquareOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SquareOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SquareOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SquareOptionsBuilder &operator=(const SquareOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSquareOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SquareOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSquareOptions(flatbuffers::FlatBufferBuilder &_fbb, const SquareOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ZerosLikeOptionsT : public flatbuffers::NativeTable { + typedef ZerosLikeOptions TableType; + ZerosLikeOptionsT() { + } +}; + +struct ZerosLikeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ZerosLikeOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + ZerosLikeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ZerosLikeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ZerosLikeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ZerosLikeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit ZerosLikeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ZerosLikeOptionsBuilder &operator=(const ZerosLikeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateZerosLikeOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + ZerosLikeOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateZerosLikeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ZerosLikeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct FillOptionsT : public flatbuffers::NativeTable { + typedef FillOptions TableType; + FillOptionsT() { + } +}; + +struct FillOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FillOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + FillOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FillOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FillOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FillOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit FillOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + FillOptionsBuilder &operator=(const FillOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFillOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + FillOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateFillOptions(flatbuffers::FlatBufferBuilder &_fbb, const FillOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct FloorModOptionsT : public flatbuffers::NativeTable { + typedef FloorModOptions TableType; + FloorModOptionsT() { + } +}; + +struct FloorModOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FloorModOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + FloorModOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FloorModOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FloorModOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FloorModOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit FloorModOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + FloorModOptionsBuilder &operator=(const FloorModOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFloorModOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + FloorModOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateFloorModOptions(flatbuffers::FlatBufferBuilder &_fbb, const FloorModOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct RangeOptionsT : public flatbuffers::NativeTable { + typedef RangeOptions TableType; + RangeOptionsT() { + } +}; + +struct RangeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef RangeOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + RangeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(RangeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const RangeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct RangeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit RangeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + RangeOptionsBuilder &operator=(const RangeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateRangeOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + RangeOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateRangeOptions(flatbuffers::FlatBufferBuilder &_fbb, const RangeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LeakyReluOptionsT : public flatbuffers::NativeTable { + typedef LeakyReluOptions TableType; + float alpha; + LeakyReluOptionsT() + : alpha(0.0f) { + } +}; + +struct LeakyReluOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LeakyReluOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ALPHA = 4 + }; + float alpha() const { + return GetField(VT_ALPHA, 0.0f); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ALPHA) && + verifier.EndTable(); + } + LeakyReluOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(LeakyReluOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const LeakyReluOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct LeakyReluOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_alpha(float alpha) { + fbb_.AddElement(LeakyReluOptions::VT_ALPHA, alpha, 0.0f); + } + explicit LeakyReluOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + LeakyReluOptionsBuilder &operator=(const LeakyReluOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateLeakyReluOptions( + flatbuffers::FlatBufferBuilder &_fbb, + float alpha = 0.0f) { + LeakyReluOptionsBuilder builder_(_fbb); + builder_.add_alpha(alpha); + return builder_.Finish(); +} + +flatbuffers::Offset CreateLeakyReluOptions(flatbuffers::FlatBufferBuilder &_fbb, const LeakyReluOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SquaredDifferenceOptionsT : public flatbuffers::NativeTable { + typedef SquaredDifferenceOptions TableType; + SquaredDifferenceOptionsT() { + } +}; + +struct SquaredDifferenceOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SquaredDifferenceOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SquaredDifferenceOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SquaredDifferenceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SquaredDifferenceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SquaredDifferenceOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SquaredDifferenceOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SquaredDifferenceOptionsBuilder &operator=(const SquaredDifferenceOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSquaredDifferenceOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SquaredDifferenceOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSquaredDifferenceOptions(flatbuffers::FlatBufferBuilder &_fbb, const SquaredDifferenceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MirrorPadOptionsT : public flatbuffers::NativeTable { + typedef MirrorPadOptions TableType; + tflite::MirrorPadMode mode; + MirrorPadOptionsT() + : mode(tflite::MirrorPadMode_REFLECT) { + } +}; + +struct MirrorPadOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MirrorPadOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MODE = 4 + }; + tflite::MirrorPadMode mode() const { + return static_cast(GetField(VT_MODE, 0)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_MODE) && + verifier.EndTable(); + } + MirrorPadOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MirrorPadOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MirrorPadOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MirrorPadOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_mode(tflite::MirrorPadMode mode) { + fbb_.AddElement(MirrorPadOptions::VT_MODE, static_cast(mode), 0); + } + explicit MirrorPadOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MirrorPadOptionsBuilder &operator=(const MirrorPadOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMirrorPadOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::MirrorPadMode mode = tflite::MirrorPadMode_REFLECT) { + MirrorPadOptionsBuilder builder_(_fbb); + builder_.add_mode(mode); + return builder_.Finish(); +} + +flatbuffers::Offset CreateMirrorPadOptions(flatbuffers::FlatBufferBuilder &_fbb, const MirrorPadOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct UniqueOptionsT : public flatbuffers::NativeTable { + typedef UniqueOptions TableType; + tflite::TensorType idx_out_type; + UniqueOptionsT() + : idx_out_type(tflite::TensorType_INT32) { + } +}; + +struct UniqueOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef UniqueOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_IDX_OUT_TYPE = 4 + }; + tflite::TensorType idx_out_type() const { + return static_cast(GetField(VT_IDX_OUT_TYPE, 2)); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_IDX_OUT_TYPE) && + verifier.EndTable(); + } + UniqueOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(UniqueOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const UniqueOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct UniqueOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_idx_out_type(tflite::TensorType idx_out_type) { + fbb_.AddElement(UniqueOptions::VT_IDX_OUT_TYPE, static_cast(idx_out_type), 2); + } + explicit UniqueOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + UniqueOptionsBuilder &operator=(const UniqueOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateUniqueOptions( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::TensorType idx_out_type = tflite::TensorType_INT32) { + UniqueOptionsBuilder builder_(_fbb); + builder_.add_idx_out_type(idx_out_type); + return builder_.Finish(); +} + +flatbuffers::Offset CreateUniqueOptions(flatbuffers::FlatBufferBuilder &_fbb, const UniqueOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ReverseV2OptionsT : public flatbuffers::NativeTable { + typedef ReverseV2Options TableType; + ReverseV2OptionsT() { + } +}; + +struct ReverseV2Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ReverseV2OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + ReverseV2OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ReverseV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReverseV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ReverseV2OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit ReverseV2OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ReverseV2OptionsBuilder &operator=(const ReverseV2OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateReverseV2Options( + flatbuffers::FlatBufferBuilder &_fbb) { + ReverseV2OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateReverseV2Options(flatbuffers::FlatBufferBuilder &_fbb, const ReverseV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct AddNOptionsT : public flatbuffers::NativeTable { + typedef AddNOptions TableType; + AddNOptionsT() { + } +}; + +struct AddNOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef AddNOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + AddNOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(AddNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const AddNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct AddNOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit AddNOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + AddNOptionsBuilder &operator=(const AddNOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateAddNOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + AddNOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateAddNOptions(flatbuffers::FlatBufferBuilder &_fbb, const AddNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct GatherNdOptionsT : public flatbuffers::NativeTable { + typedef GatherNdOptions TableType; + GatherNdOptionsT() { + } +}; + +struct GatherNdOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GatherNdOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + GatherNdOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GatherNdOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GatherNdOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct GatherNdOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit GatherNdOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + GatherNdOptionsBuilder &operator=(const GatherNdOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateGatherNdOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + GatherNdOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateGatherNdOptions(flatbuffers::FlatBufferBuilder &_fbb, const GatherNdOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct WhereOptionsT : public flatbuffers::NativeTable { + typedef WhereOptions TableType; + WhereOptionsT() { + } +}; + +struct WhereOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef WhereOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + WhereOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(WhereOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const WhereOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct WhereOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit WhereOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + WhereOptionsBuilder &operator=(const WhereOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateWhereOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + WhereOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateWhereOptions(flatbuffers::FlatBufferBuilder &_fbb, const WhereOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ReverseSequenceOptionsT : public flatbuffers::NativeTable { + typedef ReverseSequenceOptions TableType; + int32_t seq_dim; + int32_t batch_dim; + ReverseSequenceOptionsT() + : seq_dim(0), + batch_dim(0) { + } +}; + +struct ReverseSequenceOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ReverseSequenceOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SEQ_DIM = 4, + VT_BATCH_DIM = 6 + }; + int32_t seq_dim() const { + return GetField(VT_SEQ_DIM, 0); + } + int32_t batch_dim() const { + return GetField(VT_BATCH_DIM, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SEQ_DIM) && + VerifyField(verifier, VT_BATCH_DIM) && + verifier.EndTable(); + } + ReverseSequenceOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ReverseSequenceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReverseSequenceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ReverseSequenceOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_seq_dim(int32_t seq_dim) { + fbb_.AddElement(ReverseSequenceOptions::VT_SEQ_DIM, seq_dim, 0); + } + void add_batch_dim(int32_t batch_dim) { + fbb_.AddElement(ReverseSequenceOptions::VT_BATCH_DIM, batch_dim, 0); + } + explicit ReverseSequenceOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ReverseSequenceOptionsBuilder &operator=(const ReverseSequenceOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateReverseSequenceOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t seq_dim = 0, + int32_t batch_dim = 0) { + ReverseSequenceOptionsBuilder builder_(_fbb); + builder_.add_batch_dim(batch_dim); + builder_.add_seq_dim(seq_dim); + return builder_.Finish(); +} + +flatbuffers::Offset CreateReverseSequenceOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReverseSequenceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MatrixDiagOptionsT : public flatbuffers::NativeTable { + typedef MatrixDiagOptions TableType; + MatrixDiagOptionsT() { + } +}; + +struct MatrixDiagOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MatrixDiagOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + MatrixDiagOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MatrixDiagOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MatrixDiagOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MatrixDiagOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit MatrixDiagOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MatrixDiagOptionsBuilder &operator=(const MatrixDiagOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMatrixDiagOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + MatrixDiagOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateMatrixDiagOptions(flatbuffers::FlatBufferBuilder &_fbb, const MatrixDiagOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct QuantizeOptionsT : public flatbuffers::NativeTable { + typedef QuantizeOptions TableType; + QuantizeOptionsT() { + } +}; + +struct QuantizeOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef QuantizeOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + QuantizeOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(QuantizeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const QuantizeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct QuantizeOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit QuantizeOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + QuantizeOptionsBuilder &operator=(const QuantizeOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateQuantizeOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + QuantizeOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateQuantizeOptions(flatbuffers::FlatBufferBuilder &_fbb, const QuantizeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MatrixSetDiagOptionsT : public flatbuffers::NativeTable { + typedef MatrixSetDiagOptions TableType; + MatrixSetDiagOptionsT() { + } +}; + +struct MatrixSetDiagOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MatrixSetDiagOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + MatrixSetDiagOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MatrixSetDiagOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MatrixSetDiagOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MatrixSetDiagOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit MatrixSetDiagOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MatrixSetDiagOptionsBuilder &operator=(const MatrixSetDiagOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMatrixSetDiagOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + MatrixSetDiagOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateMatrixSetDiagOptions(flatbuffers::FlatBufferBuilder &_fbb, const MatrixSetDiagOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct IfOptionsT : public flatbuffers::NativeTable { + typedef IfOptions TableType; + int32_t then_subgraph_index; + int32_t else_subgraph_index; + IfOptionsT() + : then_subgraph_index(0), + else_subgraph_index(0) { + } +}; + +struct IfOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef IfOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_THEN_SUBGRAPH_INDEX = 4, + VT_ELSE_SUBGRAPH_INDEX = 6 + }; + int32_t then_subgraph_index() const { + return GetField(VT_THEN_SUBGRAPH_INDEX, 0); + } + int32_t else_subgraph_index() const { + return GetField(VT_ELSE_SUBGRAPH_INDEX, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_THEN_SUBGRAPH_INDEX) && + VerifyField(verifier, VT_ELSE_SUBGRAPH_INDEX) && + verifier.EndTable(); + } + IfOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(IfOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const IfOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct IfOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_then_subgraph_index(int32_t then_subgraph_index) { + fbb_.AddElement(IfOptions::VT_THEN_SUBGRAPH_INDEX, then_subgraph_index, 0); + } + void add_else_subgraph_index(int32_t else_subgraph_index) { + fbb_.AddElement(IfOptions::VT_ELSE_SUBGRAPH_INDEX, else_subgraph_index, 0); + } + explicit IfOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + IfOptionsBuilder &operator=(const IfOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateIfOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t then_subgraph_index = 0, + int32_t else_subgraph_index = 0) { + IfOptionsBuilder builder_(_fbb); + builder_.add_else_subgraph_index(else_subgraph_index); + builder_.add_then_subgraph_index(then_subgraph_index); + return builder_.Finish(); +} + +flatbuffers::Offset CreateIfOptions(flatbuffers::FlatBufferBuilder &_fbb, const IfOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct WhileOptionsT : public flatbuffers::NativeTable { + typedef WhileOptions TableType; + int32_t cond_subgraph_index; + int32_t body_subgraph_index; + WhileOptionsT() + : cond_subgraph_index(0), + body_subgraph_index(0) { + } +}; + +struct WhileOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef WhileOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_COND_SUBGRAPH_INDEX = 4, + VT_BODY_SUBGRAPH_INDEX = 6 + }; + int32_t cond_subgraph_index() const { + return GetField(VT_COND_SUBGRAPH_INDEX, 0); + } + int32_t body_subgraph_index() const { + return GetField(VT_BODY_SUBGRAPH_INDEX, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_COND_SUBGRAPH_INDEX) && + VerifyField(verifier, VT_BODY_SUBGRAPH_INDEX) && + verifier.EndTable(); + } + WhileOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(WhileOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const WhileOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct WhileOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_cond_subgraph_index(int32_t cond_subgraph_index) { + fbb_.AddElement(WhileOptions::VT_COND_SUBGRAPH_INDEX, cond_subgraph_index, 0); + } + void add_body_subgraph_index(int32_t body_subgraph_index) { + fbb_.AddElement(WhileOptions::VT_BODY_SUBGRAPH_INDEX, body_subgraph_index, 0); + } + explicit WhileOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + WhileOptionsBuilder &operator=(const WhileOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateWhileOptions( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t cond_subgraph_index = 0, + int32_t body_subgraph_index = 0) { + WhileOptionsBuilder builder_(_fbb); + builder_.add_body_subgraph_index(body_subgraph_index); + builder_.add_cond_subgraph_index(cond_subgraph_index); + return builder_.Finish(); +} + +flatbuffers::Offset CreateWhileOptions(flatbuffers::FlatBufferBuilder &_fbb, const WhileOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct NonMaxSuppressionV4OptionsT : public flatbuffers::NativeTable { + typedef NonMaxSuppressionV4Options TableType; + NonMaxSuppressionV4OptionsT() { + } +}; + +struct NonMaxSuppressionV4Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef NonMaxSuppressionV4OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + NonMaxSuppressionV4OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(NonMaxSuppressionV4OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV4OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct NonMaxSuppressionV4OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit NonMaxSuppressionV4OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + NonMaxSuppressionV4OptionsBuilder &operator=(const NonMaxSuppressionV4OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateNonMaxSuppressionV4Options( + flatbuffers::FlatBufferBuilder &_fbb) { + NonMaxSuppressionV4OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateNonMaxSuppressionV4Options(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV4OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct NonMaxSuppressionV5OptionsT : public flatbuffers::NativeTable { + typedef NonMaxSuppressionV5Options TableType; + NonMaxSuppressionV5OptionsT() { + } +}; + +struct NonMaxSuppressionV5Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef NonMaxSuppressionV5OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + NonMaxSuppressionV5OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(NonMaxSuppressionV5OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV5OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct NonMaxSuppressionV5OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit NonMaxSuppressionV5OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + NonMaxSuppressionV5OptionsBuilder &operator=(const NonMaxSuppressionV5OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateNonMaxSuppressionV5Options( + flatbuffers::FlatBufferBuilder &_fbb) { + NonMaxSuppressionV5OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateNonMaxSuppressionV5Options(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV5OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ScatterNdOptionsT : public flatbuffers::NativeTable { + typedef ScatterNdOptions TableType; + ScatterNdOptionsT() { + } +}; + +struct ScatterNdOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ScatterNdOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + ScatterNdOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ScatterNdOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScatterNdOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ScatterNdOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit ScatterNdOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ScatterNdOptionsBuilder &operator=(const ScatterNdOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateScatterNdOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + ScatterNdOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateScatterNdOptions(flatbuffers::FlatBufferBuilder &_fbb, const ScatterNdOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SelectV2OptionsT : public flatbuffers::NativeTable { + typedef SelectV2Options TableType; + SelectV2OptionsT() { + } +}; + +struct SelectV2Options FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SelectV2OptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SelectV2OptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SelectV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SelectV2OptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SelectV2OptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SelectV2OptionsBuilder &operator=(const SelectV2OptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSelectV2Options( + flatbuffers::FlatBufferBuilder &_fbb) { + SelectV2OptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSelectV2Options(flatbuffers::FlatBufferBuilder &_fbb, const SelectV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct DensifyOptionsT : public flatbuffers::NativeTable { + typedef DensifyOptions TableType; + DensifyOptionsT() { + } +}; + +struct DensifyOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef DensifyOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + DensifyOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(DensifyOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DensifyOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct DensifyOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit DensifyOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + DensifyOptionsBuilder &operator=(const DensifyOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateDensifyOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + DensifyOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateDensifyOptions(flatbuffers::FlatBufferBuilder &_fbb, const DensifyOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SegmentSumOptionsT : public flatbuffers::NativeTable { + typedef SegmentSumOptions TableType; + SegmentSumOptionsT() { + } +}; + +struct SegmentSumOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SegmentSumOptionsT NativeTableType; + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + verifier.EndTable(); + } + SegmentSumOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SegmentSumOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SegmentSumOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SegmentSumOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + explicit SegmentSumOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SegmentSumOptionsBuilder &operator=(const SegmentSumOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSegmentSumOptions( + flatbuffers::FlatBufferBuilder &_fbb) { + SegmentSumOptionsBuilder builder_(_fbb); + return builder_.Finish(); +} + +flatbuffers::Offset CreateSegmentSumOptions(flatbuffers::FlatBufferBuilder &_fbb, const SegmentSumOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BatchMatMulOptionsT : public flatbuffers::NativeTable { + typedef BatchMatMulOptions TableType; + bool adj_x; + bool adj_y; + BatchMatMulOptionsT() + : adj_x(false), + adj_y(false) { + } +}; + +struct BatchMatMulOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BatchMatMulOptionsT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_ADJ_X = 4, + VT_ADJ_Y = 6 + }; + bool adj_x() const { + return GetField(VT_ADJ_X, 0) != 0; + } + bool adj_y() const { + return GetField(VT_ADJ_Y, 0) != 0; + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_ADJ_X) && + VerifyField(verifier, VT_ADJ_Y) && + verifier.EndTable(); + } + BatchMatMulOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BatchMatMulOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const BatchMatMulOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BatchMatMulOptionsBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_adj_x(bool adj_x) { + fbb_.AddElement(BatchMatMulOptions::VT_ADJ_X, static_cast(adj_x), 0); + } + void add_adj_y(bool adj_y) { + fbb_.AddElement(BatchMatMulOptions::VT_ADJ_Y, static_cast(adj_y), 0); + } + explicit BatchMatMulOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BatchMatMulOptionsBuilder &operator=(const BatchMatMulOptionsBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateBatchMatMulOptions( + flatbuffers::FlatBufferBuilder &_fbb, + bool adj_x = false, + bool adj_y = false) { + BatchMatMulOptionsBuilder builder_(_fbb); + builder_.add_adj_y(adj_y); + builder_.add_adj_x(adj_x); + return builder_.Finish(); +} + +flatbuffers::Offset CreateBatchMatMulOptions(flatbuffers::FlatBufferBuilder &_fbb, const BatchMatMulOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct OperatorCodeT : public flatbuffers::NativeTable { + typedef OperatorCode TableType; + tflite::BuiltinOperator builtin_code; + std::string custom_code; + int32_t version; + OperatorCodeT() + : builtin_code(tflite::BuiltinOperator_ADD), + version(1) { + } +}; + +struct OperatorCode FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OperatorCodeT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BUILTIN_CODE = 4, + VT_CUSTOM_CODE = 6, + VT_VERSION = 8 + }; + tflite::BuiltinOperator builtin_code() const { + return static_cast(GetField(VT_BUILTIN_CODE, 0)); + } + const flatbuffers::String *custom_code() const { + return GetPointer(VT_CUSTOM_CODE); + } + int32_t version() const { + return GetField(VT_VERSION, 1); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_BUILTIN_CODE) && + VerifyOffset(verifier, VT_CUSTOM_CODE) && + verifier.VerifyString(custom_code()) && + VerifyField(verifier, VT_VERSION) && + verifier.EndTable(); + } + OperatorCodeT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(OperatorCodeT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const OperatorCodeT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct OperatorCodeBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_builtin_code(tflite::BuiltinOperator builtin_code) { + fbb_.AddElement(OperatorCode::VT_BUILTIN_CODE, static_cast(builtin_code), 0); + } + void add_custom_code(flatbuffers::Offset custom_code) { + fbb_.AddOffset(OperatorCode::VT_CUSTOM_CODE, custom_code); + } + void add_version(int32_t version) { + fbb_.AddElement(OperatorCode::VT_VERSION, version, 1); + } + explicit OperatorCodeBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + OperatorCodeBuilder &operator=(const OperatorCodeBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateOperatorCode( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::BuiltinOperator builtin_code = tflite::BuiltinOperator_ADD, + flatbuffers::Offset custom_code = 0, + int32_t version = 1) { + OperatorCodeBuilder builder_(_fbb); + builder_.add_version(version); + builder_.add_custom_code(custom_code); + builder_.add_builtin_code(builtin_code); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateOperatorCodeDirect( + flatbuffers::FlatBufferBuilder &_fbb, + tflite::BuiltinOperator builtin_code = tflite::BuiltinOperator_ADD, + const char *custom_code = nullptr, + int32_t version = 1) { + auto custom_code__ = custom_code ? _fbb.CreateString(custom_code) : 0; + return tflite::CreateOperatorCode( + _fbb, + builtin_code, + custom_code__, + version); +} + +flatbuffers::Offset CreateOperatorCode(flatbuffers::FlatBufferBuilder &_fbb, const OperatorCodeT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct OperatorT : public flatbuffers::NativeTable { + typedef Operator TableType; + uint32_t opcode_index; + std::vector inputs; + std::vector outputs; + tflite::BuiltinOptionsUnion builtin_options; + std::vector custom_options; + tflite::CustomOptionsFormat custom_options_format; + std::vector mutating_variable_inputs; + std::vector intermediates; + OperatorT() + : opcode_index(0), + custom_options_format(tflite::CustomOptionsFormat_FLEXBUFFERS) { + } +}; + +struct Operator FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef OperatorT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_OPCODE_INDEX = 4, + VT_INPUTS = 6, + VT_OUTPUTS = 8, + VT_BUILTIN_OPTIONS_TYPE = 10, + VT_BUILTIN_OPTIONS = 12, + VT_CUSTOM_OPTIONS = 14, + VT_CUSTOM_OPTIONS_FORMAT = 16, + VT_MUTATING_VARIABLE_INPUTS = 18, + VT_INTERMEDIATES = 20 + }; + uint32_t opcode_index() const { + return GetField(VT_OPCODE_INDEX, 0); + } + const flatbuffers::Vector *inputs() const { + return GetPointer *>(VT_INPUTS); + } + const flatbuffers::Vector *outputs() const { + return GetPointer *>(VT_OUTPUTS); + } + tflite::BuiltinOptions builtin_options_type() const { + return static_cast(GetField(VT_BUILTIN_OPTIONS_TYPE, 0)); + } + const void *builtin_options() const { + return GetPointer(VT_BUILTIN_OPTIONS); + } + template const T *builtin_options_as() const; + const tflite::Conv2DOptions *builtin_options_as_Conv2DOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_Conv2DOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::DepthwiseConv2DOptions *builtin_options_as_DepthwiseConv2DOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_DepthwiseConv2DOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ConcatEmbeddingsOptions *builtin_options_as_ConcatEmbeddingsOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ConcatEmbeddingsOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LSHProjectionOptions *builtin_options_as_LSHProjectionOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LSHProjectionOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::Pool2DOptions *builtin_options_as_Pool2DOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_Pool2DOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SVDFOptions *builtin_options_as_SVDFOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SVDFOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::RNNOptions *builtin_options_as_RNNOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_RNNOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::FullyConnectedOptions *builtin_options_as_FullyConnectedOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_FullyConnectedOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SoftmaxOptions *builtin_options_as_SoftmaxOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SoftmaxOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ConcatenationOptions *builtin_options_as_ConcatenationOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ConcatenationOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::AddOptions *builtin_options_as_AddOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_AddOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::L2NormOptions *builtin_options_as_L2NormOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_L2NormOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LocalResponseNormalizationOptions *builtin_options_as_LocalResponseNormalizationOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LocalResponseNormalizationOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LSTMOptions *builtin_options_as_LSTMOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LSTMOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ResizeBilinearOptions *builtin_options_as_ResizeBilinearOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ResizeBilinearOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::CallOptions *builtin_options_as_CallOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_CallOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ReshapeOptions *builtin_options_as_ReshapeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ReshapeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SkipGramOptions *builtin_options_as_SkipGramOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SkipGramOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SpaceToDepthOptions *builtin_options_as_SpaceToDepthOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SpaceToDepthOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::EmbeddingLookupSparseOptions *builtin_options_as_EmbeddingLookupSparseOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_EmbeddingLookupSparseOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::MulOptions *builtin_options_as_MulOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_MulOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::PadOptions *builtin_options_as_PadOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_PadOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::GatherOptions *builtin_options_as_GatherOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_GatherOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::BatchToSpaceNDOptions *builtin_options_as_BatchToSpaceNDOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_BatchToSpaceNDOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SpaceToBatchNDOptions *builtin_options_as_SpaceToBatchNDOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SpaceToBatchNDOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::TransposeOptions *builtin_options_as_TransposeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_TransposeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ReducerOptions *builtin_options_as_ReducerOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ReducerOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SubOptions *builtin_options_as_SubOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SubOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::DivOptions *builtin_options_as_DivOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_DivOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SqueezeOptions *builtin_options_as_SqueezeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SqueezeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SequenceRNNOptions *builtin_options_as_SequenceRNNOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SequenceRNNOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::StridedSliceOptions *builtin_options_as_StridedSliceOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_StridedSliceOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ExpOptions *builtin_options_as_ExpOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ExpOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::TopKV2Options *builtin_options_as_TopKV2Options() const { + return builtin_options_type() == tflite::BuiltinOptions_TopKV2Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::SplitOptions *builtin_options_as_SplitOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SplitOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LogSoftmaxOptions *builtin_options_as_LogSoftmaxOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LogSoftmaxOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::CastOptions *builtin_options_as_CastOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_CastOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::DequantizeOptions *builtin_options_as_DequantizeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_DequantizeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::MaximumMinimumOptions *builtin_options_as_MaximumMinimumOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_MaximumMinimumOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ArgMaxOptions *builtin_options_as_ArgMaxOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ArgMaxOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LessOptions *builtin_options_as_LessOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LessOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::NegOptions *builtin_options_as_NegOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_NegOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::PadV2Options *builtin_options_as_PadV2Options() const { + return builtin_options_type() == tflite::BuiltinOptions_PadV2Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::GreaterOptions *builtin_options_as_GreaterOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_GreaterOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::GreaterEqualOptions *builtin_options_as_GreaterEqualOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_GreaterEqualOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LessEqualOptions *builtin_options_as_LessEqualOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LessEqualOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SelectOptions *builtin_options_as_SelectOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SelectOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SliceOptions *builtin_options_as_SliceOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SliceOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::TransposeConvOptions *builtin_options_as_TransposeConvOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_TransposeConvOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SparseToDenseOptions *builtin_options_as_SparseToDenseOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SparseToDenseOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::TileOptions *builtin_options_as_TileOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_TileOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ExpandDimsOptions *builtin_options_as_ExpandDimsOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ExpandDimsOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::EqualOptions *builtin_options_as_EqualOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_EqualOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::NotEqualOptions *builtin_options_as_NotEqualOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_NotEqualOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ShapeOptions *builtin_options_as_ShapeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ShapeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::PowOptions *builtin_options_as_PowOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_PowOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ArgMinOptions *builtin_options_as_ArgMinOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ArgMinOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::FakeQuantOptions *builtin_options_as_FakeQuantOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_FakeQuantOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::PackOptions *builtin_options_as_PackOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_PackOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LogicalOrOptions *builtin_options_as_LogicalOrOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LogicalOrOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::OneHotOptions *builtin_options_as_OneHotOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_OneHotOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LogicalAndOptions *builtin_options_as_LogicalAndOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LogicalAndOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LogicalNotOptions *builtin_options_as_LogicalNotOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LogicalNotOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::UnpackOptions *builtin_options_as_UnpackOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_UnpackOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::FloorDivOptions *builtin_options_as_FloorDivOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_FloorDivOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SquareOptions *builtin_options_as_SquareOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SquareOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ZerosLikeOptions *builtin_options_as_ZerosLikeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ZerosLikeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::FillOptions *builtin_options_as_FillOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_FillOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::BidirectionalSequenceLSTMOptions *builtin_options_as_BidirectionalSequenceLSTMOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_BidirectionalSequenceLSTMOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::BidirectionalSequenceRNNOptions *builtin_options_as_BidirectionalSequenceRNNOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_BidirectionalSequenceRNNOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::UnidirectionalSequenceLSTMOptions *builtin_options_as_UnidirectionalSequenceLSTMOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_UnidirectionalSequenceLSTMOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::FloorModOptions *builtin_options_as_FloorModOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_FloorModOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::RangeOptions *builtin_options_as_RangeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_RangeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ResizeNearestNeighborOptions *builtin_options_as_ResizeNearestNeighborOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ResizeNearestNeighborOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::LeakyReluOptions *builtin_options_as_LeakyReluOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_LeakyReluOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SquaredDifferenceOptions *builtin_options_as_SquaredDifferenceOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SquaredDifferenceOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::MirrorPadOptions *builtin_options_as_MirrorPadOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_MirrorPadOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::AbsOptions *builtin_options_as_AbsOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_AbsOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SplitVOptions *builtin_options_as_SplitVOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SplitVOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::UniqueOptions *builtin_options_as_UniqueOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_UniqueOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ReverseV2Options *builtin_options_as_ReverseV2Options() const { + return builtin_options_type() == tflite::BuiltinOptions_ReverseV2Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::AddNOptions *builtin_options_as_AddNOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_AddNOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::GatherNdOptions *builtin_options_as_GatherNdOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_GatherNdOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::CosOptions *builtin_options_as_CosOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_CosOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::WhereOptions *builtin_options_as_WhereOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_WhereOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::RankOptions *builtin_options_as_RankOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_RankOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::ReverseSequenceOptions *builtin_options_as_ReverseSequenceOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ReverseSequenceOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::MatrixDiagOptions *builtin_options_as_MatrixDiagOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_MatrixDiagOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::QuantizeOptions *builtin_options_as_QuantizeOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_QuantizeOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::MatrixSetDiagOptions *builtin_options_as_MatrixSetDiagOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_MatrixSetDiagOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::HardSwishOptions *builtin_options_as_HardSwishOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_HardSwishOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::IfOptions *builtin_options_as_IfOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_IfOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::WhileOptions *builtin_options_as_WhileOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_WhileOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::DepthToSpaceOptions *builtin_options_as_DepthToSpaceOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_DepthToSpaceOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::NonMaxSuppressionV4Options *builtin_options_as_NonMaxSuppressionV4Options() const { + return builtin_options_type() == tflite::BuiltinOptions_NonMaxSuppressionV4Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::NonMaxSuppressionV5Options *builtin_options_as_NonMaxSuppressionV5Options() const { + return builtin_options_type() == tflite::BuiltinOptions_NonMaxSuppressionV5Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::ScatterNdOptions *builtin_options_as_ScatterNdOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_ScatterNdOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SelectV2Options *builtin_options_as_SelectV2Options() const { + return builtin_options_type() == tflite::BuiltinOptions_SelectV2Options ? static_cast(builtin_options()) : nullptr; + } + const tflite::DensifyOptions *builtin_options_as_DensifyOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_DensifyOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::SegmentSumOptions *builtin_options_as_SegmentSumOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_SegmentSumOptions ? static_cast(builtin_options()) : nullptr; + } + const tflite::BatchMatMulOptions *builtin_options_as_BatchMatMulOptions() const { + return builtin_options_type() == tflite::BuiltinOptions_BatchMatMulOptions ? static_cast(builtin_options()) : nullptr; + } + const flatbuffers::Vector *custom_options() const { + return GetPointer *>(VT_CUSTOM_OPTIONS); + } + tflite::CustomOptionsFormat custom_options_format() const { + return static_cast(GetField(VT_CUSTOM_OPTIONS_FORMAT, 0)); + } + const flatbuffers::Vector *mutating_variable_inputs() const { + return GetPointer *>(VT_MUTATING_VARIABLE_INPUTS); + } + const flatbuffers::Vector *intermediates() const { + return GetPointer *>(VT_INTERMEDIATES); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_OPCODE_INDEX) && + VerifyOffset(verifier, VT_INPUTS) && + verifier.VerifyVector(inputs()) && + VerifyOffset(verifier, VT_OUTPUTS) && + verifier.VerifyVector(outputs()) && + VerifyField(verifier, VT_BUILTIN_OPTIONS_TYPE) && + VerifyOffset(verifier, VT_BUILTIN_OPTIONS) && + VerifyBuiltinOptions(verifier, builtin_options(), builtin_options_type()) && + VerifyOffset(verifier, VT_CUSTOM_OPTIONS) && + verifier.VerifyVector(custom_options()) && + VerifyField(verifier, VT_CUSTOM_OPTIONS_FORMAT) && + VerifyOffset(verifier, VT_MUTATING_VARIABLE_INPUTS) && + verifier.VerifyVector(mutating_variable_inputs()) && + VerifyOffset(verifier, VT_INTERMEDIATES) && + verifier.VerifyVector(intermediates()) && + verifier.EndTable(); + } + OperatorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(OperatorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const OperatorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +template<> inline const tflite::Conv2DOptions *Operator::builtin_options_as() const { + return builtin_options_as_Conv2DOptions(); +} + +template<> inline const tflite::DepthwiseConv2DOptions *Operator::builtin_options_as() const { + return builtin_options_as_DepthwiseConv2DOptions(); +} + +template<> inline const tflite::ConcatEmbeddingsOptions *Operator::builtin_options_as() const { + return builtin_options_as_ConcatEmbeddingsOptions(); +} + +template<> inline const tflite::LSHProjectionOptions *Operator::builtin_options_as() const { + return builtin_options_as_LSHProjectionOptions(); +} + +template<> inline const tflite::Pool2DOptions *Operator::builtin_options_as() const { + return builtin_options_as_Pool2DOptions(); +} + +template<> inline const tflite::SVDFOptions *Operator::builtin_options_as() const { + return builtin_options_as_SVDFOptions(); +} + +template<> inline const tflite::RNNOptions *Operator::builtin_options_as() const { + return builtin_options_as_RNNOptions(); +} + +template<> inline const tflite::FullyConnectedOptions *Operator::builtin_options_as() const { + return builtin_options_as_FullyConnectedOptions(); +} + +template<> inline const tflite::SoftmaxOptions *Operator::builtin_options_as() const { + return builtin_options_as_SoftmaxOptions(); +} + +template<> inline const tflite::ConcatenationOptions *Operator::builtin_options_as() const { + return builtin_options_as_ConcatenationOptions(); +} + +template<> inline const tflite::AddOptions *Operator::builtin_options_as() const { + return builtin_options_as_AddOptions(); +} + +template<> inline const tflite::L2NormOptions *Operator::builtin_options_as() const { + return builtin_options_as_L2NormOptions(); +} + +template<> inline const tflite::LocalResponseNormalizationOptions *Operator::builtin_options_as() const { + return builtin_options_as_LocalResponseNormalizationOptions(); +} + +template<> inline const tflite::LSTMOptions *Operator::builtin_options_as() const { + return builtin_options_as_LSTMOptions(); +} + +template<> inline const tflite::ResizeBilinearOptions *Operator::builtin_options_as() const { + return builtin_options_as_ResizeBilinearOptions(); +} + +template<> inline const tflite::CallOptions *Operator::builtin_options_as() const { + return builtin_options_as_CallOptions(); +} + +template<> inline const tflite::ReshapeOptions *Operator::builtin_options_as() const { + return builtin_options_as_ReshapeOptions(); +} + +template<> inline const tflite::SkipGramOptions *Operator::builtin_options_as() const { + return builtin_options_as_SkipGramOptions(); +} + +template<> inline const tflite::SpaceToDepthOptions *Operator::builtin_options_as() const { + return builtin_options_as_SpaceToDepthOptions(); +} + +template<> inline const tflite::EmbeddingLookupSparseOptions *Operator::builtin_options_as() const { + return builtin_options_as_EmbeddingLookupSparseOptions(); +} + +template<> inline const tflite::MulOptions *Operator::builtin_options_as() const { + return builtin_options_as_MulOptions(); +} + +template<> inline const tflite::PadOptions *Operator::builtin_options_as() const { + return builtin_options_as_PadOptions(); +} + +template<> inline const tflite::GatherOptions *Operator::builtin_options_as() const { + return builtin_options_as_GatherOptions(); +} + +template<> inline const tflite::BatchToSpaceNDOptions *Operator::builtin_options_as() const { + return builtin_options_as_BatchToSpaceNDOptions(); +} + +template<> inline const tflite::SpaceToBatchNDOptions *Operator::builtin_options_as() const { + return builtin_options_as_SpaceToBatchNDOptions(); +} + +template<> inline const tflite::TransposeOptions *Operator::builtin_options_as() const { + return builtin_options_as_TransposeOptions(); +} + +template<> inline const tflite::ReducerOptions *Operator::builtin_options_as() const { + return builtin_options_as_ReducerOptions(); +} + +template<> inline const tflite::SubOptions *Operator::builtin_options_as() const { + return builtin_options_as_SubOptions(); +} + +template<> inline const tflite::DivOptions *Operator::builtin_options_as() const { + return builtin_options_as_DivOptions(); +} + +template<> inline const tflite::SqueezeOptions *Operator::builtin_options_as() const { + return builtin_options_as_SqueezeOptions(); +} + +template<> inline const tflite::SequenceRNNOptions *Operator::builtin_options_as() const { + return builtin_options_as_SequenceRNNOptions(); +} + +template<> inline const tflite::StridedSliceOptions *Operator::builtin_options_as() const { + return builtin_options_as_StridedSliceOptions(); +} + +template<> inline const tflite::ExpOptions *Operator::builtin_options_as() const { + return builtin_options_as_ExpOptions(); +} + +template<> inline const tflite::TopKV2Options *Operator::builtin_options_as() const { + return builtin_options_as_TopKV2Options(); +} + +template<> inline const tflite::SplitOptions *Operator::builtin_options_as() const { + return builtin_options_as_SplitOptions(); +} + +template<> inline const tflite::LogSoftmaxOptions *Operator::builtin_options_as() const { + return builtin_options_as_LogSoftmaxOptions(); +} + +template<> inline const tflite::CastOptions *Operator::builtin_options_as() const { + return builtin_options_as_CastOptions(); +} + +template<> inline const tflite::DequantizeOptions *Operator::builtin_options_as() const { + return builtin_options_as_DequantizeOptions(); +} + +template<> inline const tflite::MaximumMinimumOptions *Operator::builtin_options_as() const { + return builtin_options_as_MaximumMinimumOptions(); +} + +template<> inline const tflite::ArgMaxOptions *Operator::builtin_options_as() const { + return builtin_options_as_ArgMaxOptions(); +} + +template<> inline const tflite::LessOptions *Operator::builtin_options_as() const { + return builtin_options_as_LessOptions(); +} + +template<> inline const tflite::NegOptions *Operator::builtin_options_as() const { + return builtin_options_as_NegOptions(); +} + +template<> inline const tflite::PadV2Options *Operator::builtin_options_as() const { + return builtin_options_as_PadV2Options(); +} + +template<> inline const tflite::GreaterOptions *Operator::builtin_options_as() const { + return builtin_options_as_GreaterOptions(); +} + +template<> inline const tflite::GreaterEqualOptions *Operator::builtin_options_as() const { + return builtin_options_as_GreaterEqualOptions(); +} + +template<> inline const tflite::LessEqualOptions *Operator::builtin_options_as() const { + return builtin_options_as_LessEqualOptions(); +} + +template<> inline const tflite::SelectOptions *Operator::builtin_options_as() const { + return builtin_options_as_SelectOptions(); +} + +template<> inline const tflite::SliceOptions *Operator::builtin_options_as() const { + return builtin_options_as_SliceOptions(); +} + +template<> inline const tflite::TransposeConvOptions *Operator::builtin_options_as() const { + return builtin_options_as_TransposeConvOptions(); +} + +template<> inline const tflite::SparseToDenseOptions *Operator::builtin_options_as() const { + return builtin_options_as_SparseToDenseOptions(); +} + +template<> inline const tflite::TileOptions *Operator::builtin_options_as() const { + return builtin_options_as_TileOptions(); +} + +template<> inline const tflite::ExpandDimsOptions *Operator::builtin_options_as() const { + return builtin_options_as_ExpandDimsOptions(); +} + +template<> inline const tflite::EqualOptions *Operator::builtin_options_as() const { + return builtin_options_as_EqualOptions(); +} + +template<> inline const tflite::NotEqualOptions *Operator::builtin_options_as() const { + return builtin_options_as_NotEqualOptions(); +} + +template<> inline const tflite::ShapeOptions *Operator::builtin_options_as() const { + return builtin_options_as_ShapeOptions(); +} + +template<> inline const tflite::PowOptions *Operator::builtin_options_as() const { + return builtin_options_as_PowOptions(); +} + +template<> inline const tflite::ArgMinOptions *Operator::builtin_options_as() const { + return builtin_options_as_ArgMinOptions(); +} + +template<> inline const tflite::FakeQuantOptions *Operator::builtin_options_as() const { + return builtin_options_as_FakeQuantOptions(); +} + +template<> inline const tflite::PackOptions *Operator::builtin_options_as() const { + return builtin_options_as_PackOptions(); +} + +template<> inline const tflite::LogicalOrOptions *Operator::builtin_options_as() const { + return builtin_options_as_LogicalOrOptions(); +} + +template<> inline const tflite::OneHotOptions *Operator::builtin_options_as() const { + return builtin_options_as_OneHotOptions(); +} + +template<> inline const tflite::LogicalAndOptions *Operator::builtin_options_as() const { + return builtin_options_as_LogicalAndOptions(); +} + +template<> inline const tflite::LogicalNotOptions *Operator::builtin_options_as() const { + return builtin_options_as_LogicalNotOptions(); +} + +template<> inline const tflite::UnpackOptions *Operator::builtin_options_as() const { + return builtin_options_as_UnpackOptions(); +} + +template<> inline const tflite::FloorDivOptions *Operator::builtin_options_as() const { + return builtin_options_as_FloorDivOptions(); +} + +template<> inline const tflite::SquareOptions *Operator::builtin_options_as() const { + return builtin_options_as_SquareOptions(); +} + +template<> inline const tflite::ZerosLikeOptions *Operator::builtin_options_as() const { + return builtin_options_as_ZerosLikeOptions(); +} + +template<> inline const tflite::FillOptions *Operator::builtin_options_as() const { + return builtin_options_as_FillOptions(); +} + +template<> inline const tflite::BidirectionalSequenceLSTMOptions *Operator::builtin_options_as() const { + return builtin_options_as_BidirectionalSequenceLSTMOptions(); +} + +template<> inline const tflite::BidirectionalSequenceRNNOptions *Operator::builtin_options_as() const { + return builtin_options_as_BidirectionalSequenceRNNOptions(); +} + +template<> inline const tflite::UnidirectionalSequenceLSTMOptions *Operator::builtin_options_as() const { + return builtin_options_as_UnidirectionalSequenceLSTMOptions(); +} + +template<> inline const tflite::FloorModOptions *Operator::builtin_options_as() const { + return builtin_options_as_FloorModOptions(); +} + +template<> inline const tflite::RangeOptions *Operator::builtin_options_as() const { + return builtin_options_as_RangeOptions(); +} + +template<> inline const tflite::ResizeNearestNeighborOptions *Operator::builtin_options_as() const { + return builtin_options_as_ResizeNearestNeighborOptions(); +} + +template<> inline const tflite::LeakyReluOptions *Operator::builtin_options_as() const { + return builtin_options_as_LeakyReluOptions(); +} + +template<> inline const tflite::SquaredDifferenceOptions *Operator::builtin_options_as() const { + return builtin_options_as_SquaredDifferenceOptions(); +} + +template<> inline const tflite::MirrorPadOptions *Operator::builtin_options_as() const { + return builtin_options_as_MirrorPadOptions(); +} + +template<> inline const tflite::AbsOptions *Operator::builtin_options_as() const { + return builtin_options_as_AbsOptions(); +} + +template<> inline const tflite::SplitVOptions *Operator::builtin_options_as() const { + return builtin_options_as_SplitVOptions(); +} + +template<> inline const tflite::UniqueOptions *Operator::builtin_options_as() const { + return builtin_options_as_UniqueOptions(); +} + +template<> inline const tflite::ReverseV2Options *Operator::builtin_options_as() const { + return builtin_options_as_ReverseV2Options(); +} + +template<> inline const tflite::AddNOptions *Operator::builtin_options_as() const { + return builtin_options_as_AddNOptions(); +} + +template<> inline const tflite::GatherNdOptions *Operator::builtin_options_as() const { + return builtin_options_as_GatherNdOptions(); +} + +template<> inline const tflite::CosOptions *Operator::builtin_options_as() const { + return builtin_options_as_CosOptions(); +} + +template<> inline const tflite::WhereOptions *Operator::builtin_options_as() const { + return builtin_options_as_WhereOptions(); +} + +template<> inline const tflite::RankOptions *Operator::builtin_options_as() const { + return builtin_options_as_RankOptions(); +} + +template<> inline const tflite::ReverseSequenceOptions *Operator::builtin_options_as() const { + return builtin_options_as_ReverseSequenceOptions(); +} + +template<> inline const tflite::MatrixDiagOptions *Operator::builtin_options_as() const { + return builtin_options_as_MatrixDiagOptions(); +} + +template<> inline const tflite::QuantizeOptions *Operator::builtin_options_as() const { + return builtin_options_as_QuantizeOptions(); +} + +template<> inline const tflite::MatrixSetDiagOptions *Operator::builtin_options_as() const { + return builtin_options_as_MatrixSetDiagOptions(); +} + +template<> inline const tflite::HardSwishOptions *Operator::builtin_options_as() const { + return builtin_options_as_HardSwishOptions(); +} + +template<> inline const tflite::IfOptions *Operator::builtin_options_as() const { + return builtin_options_as_IfOptions(); +} + +template<> inline const tflite::WhileOptions *Operator::builtin_options_as() const { + return builtin_options_as_WhileOptions(); +} + +template<> inline const tflite::DepthToSpaceOptions *Operator::builtin_options_as() const { + return builtin_options_as_DepthToSpaceOptions(); +} + +template<> inline const tflite::NonMaxSuppressionV4Options *Operator::builtin_options_as() const { + return builtin_options_as_NonMaxSuppressionV4Options(); +} + +template<> inline const tflite::NonMaxSuppressionV5Options *Operator::builtin_options_as() const { + return builtin_options_as_NonMaxSuppressionV5Options(); +} + +template<> inline const tflite::ScatterNdOptions *Operator::builtin_options_as() const { + return builtin_options_as_ScatterNdOptions(); +} + +template<> inline const tflite::SelectV2Options *Operator::builtin_options_as() const { + return builtin_options_as_SelectV2Options(); +} + +template<> inline const tflite::DensifyOptions *Operator::builtin_options_as() const { + return builtin_options_as_DensifyOptions(); +} + +template<> inline const tflite::SegmentSumOptions *Operator::builtin_options_as() const { + return builtin_options_as_SegmentSumOptions(); +} + +template<> inline const tflite::BatchMatMulOptions *Operator::builtin_options_as() const { + return builtin_options_as_BatchMatMulOptions(); +} + +struct OperatorBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_opcode_index(uint32_t opcode_index) { + fbb_.AddElement(Operator::VT_OPCODE_INDEX, opcode_index, 0); + } + void add_inputs(flatbuffers::Offset> inputs) { + fbb_.AddOffset(Operator::VT_INPUTS, inputs); + } + void add_outputs(flatbuffers::Offset> outputs) { + fbb_.AddOffset(Operator::VT_OUTPUTS, outputs); + } + void add_builtin_options_type(tflite::BuiltinOptions builtin_options_type) { + fbb_.AddElement(Operator::VT_BUILTIN_OPTIONS_TYPE, static_cast(builtin_options_type), 0); + } + void add_builtin_options(flatbuffers::Offset builtin_options) { + fbb_.AddOffset(Operator::VT_BUILTIN_OPTIONS, builtin_options); + } + void add_custom_options(flatbuffers::Offset> custom_options) { + fbb_.AddOffset(Operator::VT_CUSTOM_OPTIONS, custom_options); + } + void add_custom_options_format(tflite::CustomOptionsFormat custom_options_format) { + fbb_.AddElement(Operator::VT_CUSTOM_OPTIONS_FORMAT, static_cast(custom_options_format), 0); + } + void add_mutating_variable_inputs(flatbuffers::Offset> mutating_variable_inputs) { + fbb_.AddOffset(Operator::VT_MUTATING_VARIABLE_INPUTS, mutating_variable_inputs); + } + void add_intermediates(flatbuffers::Offset> intermediates) { + fbb_.AddOffset(Operator::VT_INTERMEDIATES, intermediates); + } + explicit OperatorBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + OperatorBuilder &operator=(const OperatorBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateOperator( + flatbuffers::FlatBufferBuilder &_fbb, + uint32_t opcode_index = 0, + flatbuffers::Offset> inputs = 0, + flatbuffers::Offset> outputs = 0, + tflite::BuiltinOptions builtin_options_type = tflite::BuiltinOptions_NONE, + flatbuffers::Offset builtin_options = 0, + flatbuffers::Offset> custom_options = 0, + tflite::CustomOptionsFormat custom_options_format = tflite::CustomOptionsFormat_FLEXBUFFERS, + flatbuffers::Offset> mutating_variable_inputs = 0, + flatbuffers::Offset> intermediates = 0) { + OperatorBuilder builder_(_fbb); + builder_.add_intermediates(intermediates); + builder_.add_mutating_variable_inputs(mutating_variable_inputs); + builder_.add_custom_options(custom_options); + builder_.add_builtin_options(builtin_options); + builder_.add_outputs(outputs); + builder_.add_inputs(inputs); + builder_.add_opcode_index(opcode_index); + builder_.add_custom_options_format(custom_options_format); + builder_.add_builtin_options_type(builtin_options_type); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateOperatorDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint32_t opcode_index = 0, + const std::vector *inputs = nullptr, + const std::vector *outputs = nullptr, + tflite::BuiltinOptions builtin_options_type = tflite::BuiltinOptions_NONE, + flatbuffers::Offset builtin_options = 0, + const std::vector *custom_options = nullptr, + tflite::CustomOptionsFormat custom_options_format = tflite::CustomOptionsFormat_FLEXBUFFERS, + const std::vector *mutating_variable_inputs = nullptr, + const std::vector *intermediates = nullptr) { + auto inputs__ = inputs ? _fbb.CreateVector(*inputs) : 0; + auto outputs__ = outputs ? _fbb.CreateVector(*outputs) : 0; + auto custom_options__ = custom_options ? _fbb.CreateVector(*custom_options) : 0; + auto mutating_variable_inputs__ = mutating_variable_inputs ? _fbb.CreateVector(*mutating_variable_inputs) : 0; + auto intermediates__ = intermediates ? _fbb.CreateVector(*intermediates) : 0; + return tflite::CreateOperator( + _fbb, + opcode_index, + inputs__, + outputs__, + builtin_options_type, + builtin_options, + custom_options__, + custom_options_format, + mutating_variable_inputs__, + intermediates__); +} + +flatbuffers::Offset CreateOperator(flatbuffers::FlatBufferBuilder &_fbb, const OperatorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct SubGraphT : public flatbuffers::NativeTable { + typedef SubGraph TableType; + std::vector> tensors; + std::vector inputs; + std::vector outputs; + std::vector> operators; + std::string name; + SubGraphT() { + } +}; + +struct SubGraph FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SubGraphT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TENSORS = 4, + VT_INPUTS = 6, + VT_OUTPUTS = 8, + VT_OPERATORS = 10, + VT_NAME = 12 + }; + const flatbuffers::Vector> *tensors() const { + return GetPointer> *>(VT_TENSORS); + } + const flatbuffers::Vector *inputs() const { + return GetPointer *>(VT_INPUTS); + } + const flatbuffers::Vector *outputs() const { + return GetPointer *>(VT_OUTPUTS); + } + const flatbuffers::Vector> *operators() const { + return GetPointer> *>(VT_OPERATORS); + } + const flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_TENSORS) && + verifier.VerifyVector(tensors()) && + verifier.VerifyVectorOfTables(tensors()) && + VerifyOffset(verifier, VT_INPUTS) && + verifier.VerifyVector(inputs()) && + VerifyOffset(verifier, VT_OUTPUTS) && + verifier.VerifyVector(outputs()) && + VerifyOffset(verifier, VT_OPERATORS) && + verifier.VerifyVector(operators()) && + verifier.VerifyVectorOfTables(operators()) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + verifier.EndTable(); + } + SubGraphT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SubGraphT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SubGraphT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SubGraphBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_tensors(flatbuffers::Offset>> tensors) { + fbb_.AddOffset(SubGraph::VT_TENSORS, tensors); + } + void add_inputs(flatbuffers::Offset> inputs) { + fbb_.AddOffset(SubGraph::VT_INPUTS, inputs); + } + void add_outputs(flatbuffers::Offset> outputs) { + fbb_.AddOffset(SubGraph::VT_OUTPUTS, outputs); + } + void add_operators(flatbuffers::Offset>> operators) { + fbb_.AddOffset(SubGraph::VT_OPERATORS, operators); + } + void add_name(flatbuffers::Offset name) { + fbb_.AddOffset(SubGraph::VT_NAME, name); + } + explicit SubGraphBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + SubGraphBuilder &operator=(const SubGraphBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateSubGraph( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset>> tensors = 0, + flatbuffers::Offset> inputs = 0, + flatbuffers::Offset> outputs = 0, + flatbuffers::Offset>> operators = 0, + flatbuffers::Offset name = 0) { + SubGraphBuilder builder_(_fbb); + builder_.add_name(name); + builder_.add_operators(operators); + builder_.add_outputs(outputs); + builder_.add_inputs(inputs); + builder_.add_tensors(tensors); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateSubGraphDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector> *tensors = nullptr, + const std::vector *inputs = nullptr, + const std::vector *outputs = nullptr, + const std::vector> *operators = nullptr, + const char *name = nullptr) { + auto tensors__ = tensors ? _fbb.CreateVector>(*tensors) : 0; + auto inputs__ = inputs ? _fbb.CreateVector(*inputs) : 0; + auto outputs__ = outputs ? _fbb.CreateVector(*outputs) : 0; + auto operators__ = operators ? _fbb.CreateVector>(*operators) : 0; + auto name__ = name ? _fbb.CreateString(name) : 0; + return tflite::CreateSubGraph( + _fbb, + tensors__, + inputs__, + outputs__, + operators__, + name__); +} + +flatbuffers::Offset CreateSubGraph(flatbuffers::FlatBufferBuilder &_fbb, const SubGraphT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct BufferT : public flatbuffers::NativeTable { + typedef Buffer TableType; + std::vector data; + BufferT() { + } +}; + +struct Buffer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef BufferT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DATA = 4 + }; + const flatbuffers::Vector *data() const { + return GetPointer *>(VT_DATA); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DATA) && + verifier.VerifyVector(data()) && + verifier.EndTable(); + } + BufferT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(BufferT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const BufferT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct BufferBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_data(flatbuffers::Offset> data) { + fbb_.AddOffset(Buffer::VT_DATA, data); + } + explicit BufferBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + BufferBuilder &operator=(const BufferBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateBuffer( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset> data = 0) { + BufferBuilder builder_(_fbb); + builder_.add_data(data); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateBufferDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *data = nullptr) { + if (data) { _fbb.ForceVectorAlignment(data->size(), sizeof(uint8_t), 16); } + auto data__ = data ? _fbb.CreateVector(*data) : 0; + return tflite::CreateBuffer( + _fbb, + data__); +} + +flatbuffers::Offset CreateBuffer(flatbuffers::FlatBufferBuilder &_fbb, const BufferT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct MetadataT : public flatbuffers::NativeTable { + typedef Metadata TableType; + std::string name; + uint32_t buffer; + MetadataT() + : buffer(0) { + } +}; + +struct Metadata FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef MetadataT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_BUFFER = 6 + }; + const flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + uint32_t buffer() const { + return GetField(VT_BUFFER, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyField(verifier, VT_BUFFER) && + verifier.EndTable(); + } + MetadataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(MetadataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const MetadataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct MetadataBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset name) { + fbb_.AddOffset(Metadata::VT_NAME, name); + } + void add_buffer(uint32_t buffer) { + fbb_.AddElement(Metadata::VT_BUFFER, buffer, 0); + } + explicit MetadataBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + MetadataBuilder &operator=(const MetadataBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateMetadata( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset name = 0, + uint32_t buffer = 0) { + MetadataBuilder builder_(_fbb); + builder_.add_buffer(buffer); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateMetadataDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + uint32_t buffer = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + return tflite::CreateMetadata( + _fbb, + name__, + buffer); +} + +flatbuffers::Offset CreateMetadata(flatbuffers::FlatBufferBuilder &_fbb, const MetadataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct ModelT : public flatbuffers::NativeTable { + typedef Model TableType; + uint32_t version; + std::vector> operator_codes; + std::vector> subgraphs; + std::string description; + std::vector> buffers; + std::vector metadata_buffer; + std::vector> metadata; + ModelT() + : version(0) { + } +}; + +struct Model FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef ModelT NativeTableType; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VERSION = 4, + VT_OPERATOR_CODES = 6, + VT_SUBGRAPHS = 8, + VT_DESCRIPTION = 10, + VT_BUFFERS = 12, + VT_METADATA_BUFFER = 14, + VT_METADATA = 16 + }; + uint32_t version() const { + return GetField(VT_VERSION, 0); + } + const flatbuffers::Vector> *operator_codes() const { + return GetPointer> *>(VT_OPERATOR_CODES); + } + const flatbuffers::Vector> *subgraphs() const { + return GetPointer> *>(VT_SUBGRAPHS); + } + const flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const flatbuffers::Vector> *buffers() const { + return GetPointer> *>(VT_BUFFERS); + } + const flatbuffers::Vector *metadata_buffer() const { + return GetPointer *>(VT_METADATA_BUFFER); + } + const flatbuffers::Vector> *metadata() const { + return GetPointer> *>(VT_METADATA); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_VERSION) && + VerifyOffset(verifier, VT_OPERATOR_CODES) && + verifier.VerifyVector(operator_codes()) && + verifier.VerifyVectorOfTables(operator_codes()) && + VerifyOffset(verifier, VT_SUBGRAPHS) && + verifier.VerifyVector(subgraphs()) && + verifier.VerifyVectorOfTables(subgraphs()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_BUFFERS) && + verifier.VerifyVector(buffers()) && + verifier.VerifyVectorOfTables(buffers()) && + VerifyOffset(verifier, VT_METADATA_BUFFER) && + verifier.VerifyVector(metadata_buffer()) && + VerifyOffset(verifier, VT_METADATA) && + verifier.VerifyVector(metadata()) && + verifier.VerifyVectorOfTables(metadata()) && + verifier.EndTable(); + } + ModelT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(ModelT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct ModelBuilder { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_version(uint32_t version) { + fbb_.AddElement(Model::VT_VERSION, version, 0); + } + void add_operator_codes(flatbuffers::Offset>> operator_codes) { + fbb_.AddOffset(Model::VT_OPERATOR_CODES, operator_codes); + } + void add_subgraphs(flatbuffers::Offset>> subgraphs) { + fbb_.AddOffset(Model::VT_SUBGRAPHS, subgraphs); + } + void add_description(flatbuffers::Offset description) { + fbb_.AddOffset(Model::VT_DESCRIPTION, description); + } + void add_buffers(flatbuffers::Offset>> buffers) { + fbb_.AddOffset(Model::VT_BUFFERS, buffers); + } + void add_metadata_buffer(flatbuffers::Offset> metadata_buffer) { + fbb_.AddOffset(Model::VT_METADATA_BUFFER, metadata_buffer); + } + void add_metadata(flatbuffers::Offset>> metadata) { + fbb_.AddOffset(Model::VT_METADATA, metadata); + } + explicit ModelBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ModelBuilder &operator=(const ModelBuilder &); + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateModel( + flatbuffers::FlatBufferBuilder &_fbb, + uint32_t version = 0, + flatbuffers::Offset>> operator_codes = 0, + flatbuffers::Offset>> subgraphs = 0, + flatbuffers::Offset description = 0, + flatbuffers::Offset>> buffers = 0, + flatbuffers::Offset> metadata_buffer = 0, + flatbuffers::Offset>> metadata = 0) { + ModelBuilder builder_(_fbb); + builder_.add_metadata(metadata); + builder_.add_metadata_buffer(metadata_buffer); + builder_.add_buffers(buffers); + builder_.add_description(description); + builder_.add_subgraphs(subgraphs); + builder_.add_operator_codes(operator_codes); + builder_.add_version(version); + return builder_.Finish(); +} + +inline flatbuffers::Offset CreateModelDirect( + flatbuffers::FlatBufferBuilder &_fbb, + uint32_t version = 0, + const std::vector> *operator_codes = nullptr, + const std::vector> *subgraphs = nullptr, + const char *description = nullptr, + const std::vector> *buffers = nullptr, + const std::vector *metadata_buffer = nullptr, + const std::vector> *metadata = nullptr) { + auto operator_codes__ = operator_codes ? _fbb.CreateVector>(*operator_codes) : 0; + auto subgraphs__ = subgraphs ? _fbb.CreateVector>(*subgraphs) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + auto buffers__ = buffers ? _fbb.CreateVector>(*buffers) : 0; + auto metadata_buffer__ = metadata_buffer ? _fbb.CreateVector(*metadata_buffer) : 0; + auto metadata__ = metadata ? _fbb.CreateVector>(*metadata) : 0; + return tflite::CreateModel( + _fbb, + version, + operator_codes__, + subgraphs__, + description__, + buffers__, + metadata_buffer__, + metadata__); +} + +flatbuffers::Offset CreateModel(flatbuffers::FlatBufferBuilder &_fbb, const ModelT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +inline CustomQuantizationT *CustomQuantization::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new CustomQuantizationT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void CustomQuantization::UnPackTo(CustomQuantizationT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = custom(); if (_e) { _o->custom.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->custom[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset CustomQuantization::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CustomQuantizationT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateCustomQuantization(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateCustomQuantization(flatbuffers::FlatBufferBuilder &_fbb, const CustomQuantizationT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CustomQuantizationT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + _fbb.ForceVectorAlignment(_o->custom.size(), sizeof(uint8_t), 16); + auto _custom = _o->custom.size() ? _fbb.CreateVector(_o->custom) : 0; + return tflite::CreateCustomQuantization( + _fbb, + _custom); +} + +inline QuantizationParametersT *QuantizationParameters::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new QuantizationParametersT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void QuantizationParameters::UnPackTo(QuantizationParametersT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = min(); if (_e) { _o->min.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->min[_i] = _e->Get(_i); } } } + { auto _e = max(); if (_e) { _o->max.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->max[_i] = _e->Get(_i); } } } + { auto _e = scale(); if (_e) { _o->scale.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->scale[_i] = _e->Get(_i); } } } + { auto _e = zero_point(); if (_e) { _o->zero_point.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->zero_point[_i] = _e->Get(_i); } } } + { auto _e = details_type(); _o->details.type = _e; } + { auto _e = details(); if (_e) _o->details.value = tflite::QuantizationDetailsUnion::UnPack(_e, details_type(), _resolver); } + { auto _e = quantized_dimension(); _o->quantized_dimension = _e; } +} + +inline flatbuffers::Offset QuantizationParameters::Pack(flatbuffers::FlatBufferBuilder &_fbb, const QuantizationParametersT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateQuantizationParameters(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateQuantizationParameters(flatbuffers::FlatBufferBuilder &_fbb, const QuantizationParametersT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const QuantizationParametersT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _min = _o->min.size() ? _fbb.CreateVector(_o->min) : 0; + auto _max = _o->max.size() ? _fbb.CreateVector(_o->max) : 0; + auto _scale = _o->scale.size() ? _fbb.CreateVector(_o->scale) : 0; + auto _zero_point = _o->zero_point.size() ? _fbb.CreateVector(_o->zero_point) : 0; + auto _details_type = _o->details.type; + auto _details = _o->details.Pack(_fbb); + auto _quantized_dimension = _o->quantized_dimension; + return tflite::CreateQuantizationParameters( + _fbb, + _min, + _max, + _scale, + _zero_point, + _details_type, + _details, + _quantized_dimension); +} + +inline Int32VectorT *Int32Vector::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new Int32VectorT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Int32Vector::UnPackTo(Int32VectorT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = values(); if (_e) { _o->values.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->values[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Int32Vector::Pack(flatbuffers::FlatBufferBuilder &_fbb, const Int32VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateInt32Vector(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateInt32Vector(flatbuffers::FlatBufferBuilder &_fbb, const Int32VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const Int32VectorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _values = _o->values.size() ? _fbb.CreateVector(_o->values) : 0; + return tflite::CreateInt32Vector( + _fbb, + _values); +} + +inline Uint16VectorT *Uint16Vector::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new Uint16VectorT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Uint16Vector::UnPackTo(Uint16VectorT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = values(); if (_e) { _o->values.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->values[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Uint16Vector::Pack(flatbuffers::FlatBufferBuilder &_fbb, const Uint16VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUint16Vector(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateUint16Vector(flatbuffers::FlatBufferBuilder &_fbb, const Uint16VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const Uint16VectorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + _fbb.ForceVectorAlignment(_o->values.size(), sizeof(uint16_t), 4); + auto _values = _o->values.size() ? _fbb.CreateVector(_o->values) : 0; + return tflite::CreateUint16Vector( + _fbb, + _values); +} + +inline Uint8VectorT *Uint8Vector::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new Uint8VectorT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Uint8Vector::UnPackTo(Uint8VectorT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = values(); if (_e) { _o->values.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->values[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Uint8Vector::Pack(flatbuffers::FlatBufferBuilder &_fbb, const Uint8VectorT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUint8Vector(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateUint8Vector(flatbuffers::FlatBufferBuilder &_fbb, const Uint8VectorT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const Uint8VectorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + _fbb.ForceVectorAlignment(_o->values.size(), sizeof(uint8_t), 4); + auto _values = _o->values.size() ? _fbb.CreateVector(_o->values) : 0; + return tflite::CreateUint8Vector( + _fbb, + _values); +} + +inline DimensionMetadataT *DimensionMetadata::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DimensionMetadataT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DimensionMetadata::UnPackTo(DimensionMetadataT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = format(); _o->format = _e; } + { auto _e = dense_size(); _o->dense_size = _e; } + { auto _e = array_segments_type(); _o->array_segments.type = _e; } + { auto _e = array_segments(); if (_e) _o->array_segments.value = tflite::SparseIndexVectorUnion::UnPack(_e, array_segments_type(), _resolver); } + { auto _e = array_indices_type(); _o->array_indices.type = _e; } + { auto _e = array_indices(); if (_e) _o->array_indices.value = tflite::SparseIndexVectorUnion::UnPack(_e, array_indices_type(), _resolver); } +} + +inline flatbuffers::Offset DimensionMetadata::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DimensionMetadataT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDimensionMetadata(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDimensionMetadata(flatbuffers::FlatBufferBuilder &_fbb, const DimensionMetadataT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DimensionMetadataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _format = _o->format; + auto _dense_size = _o->dense_size; + auto _array_segments_type = _o->array_segments.type; + auto _array_segments = _o->array_segments.Pack(_fbb); + auto _array_indices_type = _o->array_indices.type; + auto _array_indices = _o->array_indices.Pack(_fbb); + return tflite::CreateDimensionMetadata( + _fbb, + _format, + _dense_size, + _array_segments_type, + _array_segments, + _array_indices_type, + _array_indices); +} + +inline SparsityParametersT *SparsityParameters::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SparsityParametersT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SparsityParameters::UnPackTo(SparsityParametersT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = traversal_order(); if (_e) { _o->traversal_order.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->traversal_order[_i] = _e->Get(_i); } } } + { auto _e = block_map(); if (_e) { _o->block_map.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->block_map[_i] = _e->Get(_i); } } } + { auto _e = dim_metadata(); if (_e) { _o->dim_metadata.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->dim_metadata[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } +} + +inline flatbuffers::Offset SparsityParameters::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SparsityParametersT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSparsityParameters(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSparsityParameters(flatbuffers::FlatBufferBuilder &_fbb, const SparsityParametersT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SparsityParametersT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _traversal_order = _o->traversal_order.size() ? _fbb.CreateVector(_o->traversal_order) : 0; + auto _block_map = _o->block_map.size() ? _fbb.CreateVector(_o->block_map) : 0; + auto _dim_metadata = _o->dim_metadata.size() ? _fbb.CreateVector> (_o->dim_metadata.size(), [](size_t i, _VectorArgs *__va) { return CreateDimensionMetadata(*__va->__fbb, __va->__o->dim_metadata[i].get(), __va->__rehasher); }, &_va ) : 0; + return tflite::CreateSparsityParameters( + _fbb, + _traversal_order, + _block_map, + _dim_metadata); +} + +inline TensorT *Tensor::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new TensorT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Tensor::UnPackTo(TensorT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = shape(); if (_e) { _o->shape.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->shape[_i] = _e->Get(_i); } } } + { auto _e = type(); _o->type = _e; } + { auto _e = buffer(); _o->buffer = _e; } + { auto _e = name(); if (_e) _o->name = _e->str(); } + { auto _e = quantization(); if (_e) _o->quantization = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = is_variable(); _o->is_variable = _e; } + { auto _e = sparsity(); if (_e) _o->sparsity = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = shape_signature(); if (_e) { _o->shape_signature.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->shape_signature[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Tensor::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TensorT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateTensor(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateTensor(flatbuffers::FlatBufferBuilder &_fbb, const TensorT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TensorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _shape = _o->shape.size() ? _fbb.CreateVector(_o->shape) : 0; + auto _type = _o->type; + auto _buffer = _o->buffer; + auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name); + auto _quantization = _o->quantization ? CreateQuantizationParameters(_fbb, _o->quantization.get(), _rehasher) : 0; + auto _is_variable = _o->is_variable; + auto _sparsity = _o->sparsity ? CreateSparsityParameters(_fbb, _o->sparsity.get(), _rehasher) : 0; + auto _shape_signature = _o->shape_signature.size() ? _fbb.CreateVector(_o->shape_signature) : 0; + return tflite::CreateTensor( + _fbb, + _shape, + _type, + _buffer, + _name, + _quantization, + _is_variable, + _sparsity, + _shape_signature); +} + +inline Conv2DOptionsT *Conv2DOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new Conv2DOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Conv2DOptions::UnPackTo(Conv2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = padding(); _o->padding = _e; } + { auto _e = stride_w(); _o->stride_w = _e; } + { auto _e = stride_h(); _o->stride_h = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = dilation_w_factor(); _o->dilation_w_factor = _e; } + { auto _e = dilation_h_factor(); _o->dilation_h_factor = _e; } +} + +inline flatbuffers::Offset Conv2DOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const Conv2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateConv2DOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateConv2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const Conv2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const Conv2DOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _padding = _o->padding; + auto _stride_w = _o->stride_w; + auto _stride_h = _o->stride_h; + auto _fused_activation_function = _o->fused_activation_function; + auto _dilation_w_factor = _o->dilation_w_factor; + auto _dilation_h_factor = _o->dilation_h_factor; + return tflite::CreateConv2DOptions( + _fbb, + _padding, + _stride_w, + _stride_h, + _fused_activation_function, + _dilation_w_factor, + _dilation_h_factor); +} + +inline Pool2DOptionsT *Pool2DOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new Pool2DOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Pool2DOptions::UnPackTo(Pool2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = padding(); _o->padding = _e; } + { auto _e = stride_w(); _o->stride_w = _e; } + { auto _e = stride_h(); _o->stride_h = _e; } + { auto _e = filter_width(); _o->filter_width = _e; } + { auto _e = filter_height(); _o->filter_height = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset Pool2DOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const Pool2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePool2DOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePool2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const Pool2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const Pool2DOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _padding = _o->padding; + auto _stride_w = _o->stride_w; + auto _stride_h = _o->stride_h; + auto _filter_width = _o->filter_width; + auto _filter_height = _o->filter_height; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreatePool2DOptions( + _fbb, + _padding, + _stride_w, + _stride_h, + _filter_width, + _filter_height, + _fused_activation_function); +} + +inline DepthwiseConv2DOptionsT *DepthwiseConv2DOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DepthwiseConv2DOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DepthwiseConv2DOptions::UnPackTo(DepthwiseConv2DOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = padding(); _o->padding = _e; } + { auto _e = stride_w(); _o->stride_w = _e; } + { auto _e = stride_h(); _o->stride_h = _e; } + { auto _e = depth_multiplier(); _o->depth_multiplier = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = dilation_w_factor(); _o->dilation_w_factor = _e; } + { auto _e = dilation_h_factor(); _o->dilation_h_factor = _e; } +} + +inline flatbuffers::Offset DepthwiseConv2DOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DepthwiseConv2DOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDepthwiseConv2DOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDepthwiseConv2DOptions(flatbuffers::FlatBufferBuilder &_fbb, const DepthwiseConv2DOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DepthwiseConv2DOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _padding = _o->padding; + auto _stride_w = _o->stride_w; + auto _stride_h = _o->stride_h; + auto _depth_multiplier = _o->depth_multiplier; + auto _fused_activation_function = _o->fused_activation_function; + auto _dilation_w_factor = _o->dilation_w_factor; + auto _dilation_h_factor = _o->dilation_h_factor; + return tflite::CreateDepthwiseConv2DOptions( + _fbb, + _padding, + _stride_w, + _stride_h, + _depth_multiplier, + _fused_activation_function, + _dilation_w_factor, + _dilation_h_factor); +} + +inline ConcatEmbeddingsOptionsT *ConcatEmbeddingsOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ConcatEmbeddingsOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ConcatEmbeddingsOptions::UnPackTo(ConcatEmbeddingsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = num_channels(); _o->num_channels = _e; } + { auto _e = num_columns_per_channel(); if (_e) { _o->num_columns_per_channel.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->num_columns_per_channel[_i] = _e->Get(_i); } } } + { auto _e = embedding_dim_per_channel(); if (_e) { _o->embedding_dim_per_channel.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->embedding_dim_per_channel[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset ConcatEmbeddingsOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ConcatEmbeddingsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateConcatEmbeddingsOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateConcatEmbeddingsOptions(flatbuffers::FlatBufferBuilder &_fbb, const ConcatEmbeddingsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ConcatEmbeddingsOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _num_channels = _o->num_channels; + auto _num_columns_per_channel = _o->num_columns_per_channel.size() ? _fbb.CreateVector(_o->num_columns_per_channel) : 0; + auto _embedding_dim_per_channel = _o->embedding_dim_per_channel.size() ? _fbb.CreateVector(_o->embedding_dim_per_channel) : 0; + return tflite::CreateConcatEmbeddingsOptions( + _fbb, + _num_channels, + _num_columns_per_channel, + _embedding_dim_per_channel); +} + +inline LSHProjectionOptionsT *LSHProjectionOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LSHProjectionOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LSHProjectionOptions::UnPackTo(LSHProjectionOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = type(); _o->type = _e; } +} + +inline flatbuffers::Offset LSHProjectionOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LSHProjectionOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLSHProjectionOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLSHProjectionOptions(flatbuffers::FlatBufferBuilder &_fbb, const LSHProjectionOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LSHProjectionOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _type = _o->type; + return tflite::CreateLSHProjectionOptions( + _fbb, + _type); +} + +inline SVDFOptionsT *SVDFOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SVDFOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SVDFOptions::UnPackTo(SVDFOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = rank(); _o->rank = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset SVDFOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SVDFOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSVDFOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSVDFOptions(flatbuffers::FlatBufferBuilder &_fbb, const SVDFOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SVDFOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _rank = _o->rank; + auto _fused_activation_function = _o->fused_activation_function; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateSVDFOptions( + _fbb, + _rank, + _fused_activation_function, + _asymmetric_quantize_inputs); +} + +inline RNNOptionsT *RNNOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new RNNOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void RNNOptions::UnPackTo(RNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset RNNOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateRNNOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const RNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RNNOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateRNNOptions( + _fbb, + _fused_activation_function, + _asymmetric_quantize_inputs); +} + +inline SequenceRNNOptionsT *SequenceRNNOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SequenceRNNOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SequenceRNNOptions::UnPackTo(SequenceRNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = time_major(); _o->time_major = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset SequenceRNNOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SequenceRNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSequenceRNNOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSequenceRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const SequenceRNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SequenceRNNOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _time_major = _o->time_major; + auto _fused_activation_function = _o->fused_activation_function; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateSequenceRNNOptions( + _fbb, + _time_major, + _fused_activation_function, + _asymmetric_quantize_inputs); +} + +inline BidirectionalSequenceRNNOptionsT *BidirectionalSequenceRNNOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new BidirectionalSequenceRNNOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void BidirectionalSequenceRNNOptions::UnPackTo(BidirectionalSequenceRNNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = time_major(); _o->time_major = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = merge_outputs(); _o->merge_outputs = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset BidirectionalSequenceRNNOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceRNNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBidirectionalSequenceRNNOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateBidirectionalSequenceRNNOptions(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceRNNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BidirectionalSequenceRNNOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _time_major = _o->time_major; + auto _fused_activation_function = _o->fused_activation_function; + auto _merge_outputs = _o->merge_outputs; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateBidirectionalSequenceRNNOptions( + _fbb, + _time_major, + _fused_activation_function, + _merge_outputs, + _asymmetric_quantize_inputs); +} + +inline FullyConnectedOptionsT *FullyConnectedOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new FullyConnectedOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void FullyConnectedOptions::UnPackTo(FullyConnectedOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = weights_format(); _o->weights_format = _e; } + { auto _e = keep_num_dims(); _o->keep_num_dims = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset FullyConnectedOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FullyConnectedOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFullyConnectedOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFullyConnectedOptions(flatbuffers::FlatBufferBuilder &_fbb, const FullyConnectedOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FullyConnectedOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + auto _weights_format = _o->weights_format; + auto _keep_num_dims = _o->keep_num_dims; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateFullyConnectedOptions( + _fbb, + _fused_activation_function, + _weights_format, + _keep_num_dims, + _asymmetric_quantize_inputs); +} + +inline SoftmaxOptionsT *SoftmaxOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SoftmaxOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SoftmaxOptions::UnPackTo(SoftmaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = beta(); _o->beta = _e; } +} + +inline flatbuffers::Offset SoftmaxOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SoftmaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSoftmaxOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSoftmaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const SoftmaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SoftmaxOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _beta = _o->beta; + return tflite::CreateSoftmaxOptions( + _fbb, + _beta); +} + +inline ConcatenationOptionsT *ConcatenationOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ConcatenationOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ConcatenationOptions::UnPackTo(ConcatenationOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = axis(); _o->axis = _e; } + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset ConcatenationOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ConcatenationOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateConcatenationOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateConcatenationOptions(flatbuffers::FlatBufferBuilder &_fbb, const ConcatenationOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ConcatenationOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _axis = _o->axis; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateConcatenationOptions( + _fbb, + _axis, + _fused_activation_function); +} + +inline AddOptionsT *AddOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new AddOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void AddOptions::UnPackTo(AddOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset AddOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AddOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateAddOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateAddOptions(flatbuffers::FlatBufferBuilder &_fbb, const AddOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AddOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateAddOptions( + _fbb, + _fused_activation_function); +} + +inline MulOptionsT *MulOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MulOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void MulOptions::UnPackTo(MulOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset MulOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MulOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMulOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMulOptions(flatbuffers::FlatBufferBuilder &_fbb, const MulOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MulOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateMulOptions( + _fbb, + _fused_activation_function); +} + +inline L2NormOptionsT *L2NormOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new L2NormOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void L2NormOptions::UnPackTo(L2NormOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset L2NormOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const L2NormOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateL2NormOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateL2NormOptions(flatbuffers::FlatBufferBuilder &_fbb, const L2NormOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const L2NormOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateL2NormOptions( + _fbb, + _fused_activation_function); +} + +inline LocalResponseNormalizationOptionsT *LocalResponseNormalizationOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LocalResponseNormalizationOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LocalResponseNormalizationOptions::UnPackTo(LocalResponseNormalizationOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = radius(); _o->radius = _e; } + { auto _e = bias(); _o->bias = _e; } + { auto _e = alpha(); _o->alpha = _e; } + { auto _e = beta(); _o->beta = _e; } +} + +inline flatbuffers::Offset LocalResponseNormalizationOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LocalResponseNormalizationOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLocalResponseNormalizationOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLocalResponseNormalizationOptions(flatbuffers::FlatBufferBuilder &_fbb, const LocalResponseNormalizationOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LocalResponseNormalizationOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _radius = _o->radius; + auto _bias = _o->bias; + auto _alpha = _o->alpha; + auto _beta = _o->beta; + return tflite::CreateLocalResponseNormalizationOptions( + _fbb, + _radius, + _bias, + _alpha, + _beta); +} + +inline LSTMOptionsT *LSTMOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LSTMOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LSTMOptions::UnPackTo(LSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = cell_clip(); _o->cell_clip = _e; } + { auto _e = proj_clip(); _o->proj_clip = _e; } + { auto _e = kernel_type(); _o->kernel_type = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset LSTMOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLSTMOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const LSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LSTMOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + auto _cell_clip = _o->cell_clip; + auto _proj_clip = _o->proj_clip; + auto _kernel_type = _o->kernel_type; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateLSTMOptions( + _fbb, + _fused_activation_function, + _cell_clip, + _proj_clip, + _kernel_type, + _asymmetric_quantize_inputs); +} + +inline UnidirectionalSequenceLSTMOptionsT *UnidirectionalSequenceLSTMOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new UnidirectionalSequenceLSTMOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void UnidirectionalSequenceLSTMOptions::UnPackTo(UnidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = cell_clip(); _o->cell_clip = _e; } + { auto _e = proj_clip(); _o->proj_clip = _e; } + { auto _e = time_major(); _o->time_major = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset UnidirectionalSequenceLSTMOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnidirectionalSequenceLSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUnidirectionalSequenceLSTMOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateUnidirectionalSequenceLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const UnidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const UnidirectionalSequenceLSTMOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + auto _cell_clip = _o->cell_clip; + auto _proj_clip = _o->proj_clip; + auto _time_major = _o->time_major; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateUnidirectionalSequenceLSTMOptions( + _fbb, + _fused_activation_function, + _cell_clip, + _proj_clip, + _time_major, + _asymmetric_quantize_inputs); +} + +inline BidirectionalSequenceLSTMOptionsT *BidirectionalSequenceLSTMOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new BidirectionalSequenceLSTMOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void BidirectionalSequenceLSTMOptions::UnPackTo(BidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } + { auto _e = cell_clip(); _o->cell_clip = _e; } + { auto _e = proj_clip(); _o->proj_clip = _e; } + { auto _e = merge_outputs(); _o->merge_outputs = _e; } + { auto _e = time_major(); _o->time_major = _e; } + { auto _e = asymmetric_quantize_inputs(); _o->asymmetric_quantize_inputs = _e; } +} + +inline flatbuffers::Offset BidirectionalSequenceLSTMOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceLSTMOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBidirectionalSequenceLSTMOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateBidirectionalSequenceLSTMOptions(flatbuffers::FlatBufferBuilder &_fbb, const BidirectionalSequenceLSTMOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BidirectionalSequenceLSTMOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + auto _cell_clip = _o->cell_clip; + auto _proj_clip = _o->proj_clip; + auto _merge_outputs = _o->merge_outputs; + auto _time_major = _o->time_major; + auto _asymmetric_quantize_inputs = _o->asymmetric_quantize_inputs; + return tflite::CreateBidirectionalSequenceLSTMOptions( + _fbb, + _fused_activation_function, + _cell_clip, + _proj_clip, + _merge_outputs, + _time_major, + _asymmetric_quantize_inputs); +} + +inline ResizeBilinearOptionsT *ResizeBilinearOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ResizeBilinearOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ResizeBilinearOptions::UnPackTo(ResizeBilinearOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = align_corners(); _o->align_corners = _e; } + { auto _e = half_pixel_centers(); _o->half_pixel_centers = _e; } +} + +inline flatbuffers::Offset ResizeBilinearOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ResizeBilinearOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateResizeBilinearOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateResizeBilinearOptions(flatbuffers::FlatBufferBuilder &_fbb, const ResizeBilinearOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ResizeBilinearOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _align_corners = _o->align_corners; + auto _half_pixel_centers = _o->half_pixel_centers; + return tflite::CreateResizeBilinearOptions( + _fbb, + _align_corners, + _half_pixel_centers); +} + +inline ResizeNearestNeighborOptionsT *ResizeNearestNeighborOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ResizeNearestNeighborOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ResizeNearestNeighborOptions::UnPackTo(ResizeNearestNeighborOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = align_corners(); _o->align_corners = _e; } + { auto _e = half_pixel_centers(); _o->half_pixel_centers = _e; } +} + +inline flatbuffers::Offset ResizeNearestNeighborOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ResizeNearestNeighborOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateResizeNearestNeighborOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateResizeNearestNeighborOptions(flatbuffers::FlatBufferBuilder &_fbb, const ResizeNearestNeighborOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ResizeNearestNeighborOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _align_corners = _o->align_corners; + auto _half_pixel_centers = _o->half_pixel_centers; + return tflite::CreateResizeNearestNeighborOptions( + _fbb, + _align_corners, + _half_pixel_centers); +} + +inline CallOptionsT *CallOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new CallOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void CallOptions::UnPackTo(CallOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = subgraph(); _o->subgraph = _e; } +} + +inline flatbuffers::Offset CallOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CallOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateCallOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateCallOptions(flatbuffers::FlatBufferBuilder &_fbb, const CallOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CallOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _subgraph = _o->subgraph; + return tflite::CreateCallOptions( + _fbb, + _subgraph); +} + +inline PadOptionsT *PadOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new PadOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void PadOptions::UnPackTo(PadOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset PadOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PadOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePadOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePadOptions(flatbuffers::FlatBufferBuilder &_fbb, const PadOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PadOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreatePadOptions( + _fbb); +} + +inline PadV2OptionsT *PadV2Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new PadV2OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void PadV2Options::UnPackTo(PadV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset PadV2Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PadV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePadV2Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePadV2Options(flatbuffers::FlatBufferBuilder &_fbb, const PadV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PadV2OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreatePadV2Options( + _fbb); +} + +inline ReshapeOptionsT *ReshapeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ReshapeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ReshapeOptions::UnPackTo(ReshapeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = new_shape(); if (_e) { _o->new_shape.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->new_shape[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset ReshapeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReshapeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateReshapeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateReshapeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReshapeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReshapeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _new_shape = _o->new_shape.size() ? _fbb.CreateVector(_o->new_shape) : 0; + return tflite::CreateReshapeOptions( + _fbb, + _new_shape); +} + +inline SpaceToBatchNDOptionsT *SpaceToBatchNDOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SpaceToBatchNDOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SpaceToBatchNDOptions::UnPackTo(SpaceToBatchNDOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SpaceToBatchNDOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToBatchNDOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSpaceToBatchNDOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSpaceToBatchNDOptions(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToBatchNDOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SpaceToBatchNDOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSpaceToBatchNDOptions( + _fbb); +} + +inline BatchToSpaceNDOptionsT *BatchToSpaceNDOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new BatchToSpaceNDOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void BatchToSpaceNDOptions::UnPackTo(BatchToSpaceNDOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset BatchToSpaceNDOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BatchToSpaceNDOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBatchToSpaceNDOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateBatchToSpaceNDOptions(flatbuffers::FlatBufferBuilder &_fbb, const BatchToSpaceNDOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BatchToSpaceNDOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateBatchToSpaceNDOptions( + _fbb); +} + +inline SkipGramOptionsT *SkipGramOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SkipGramOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SkipGramOptions::UnPackTo(SkipGramOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = ngram_size(); _o->ngram_size = _e; } + { auto _e = max_skip_size(); _o->max_skip_size = _e; } + { auto _e = include_all_ngrams(); _o->include_all_ngrams = _e; } +} + +inline flatbuffers::Offset SkipGramOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SkipGramOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSkipGramOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSkipGramOptions(flatbuffers::FlatBufferBuilder &_fbb, const SkipGramOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SkipGramOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _ngram_size = _o->ngram_size; + auto _max_skip_size = _o->max_skip_size; + auto _include_all_ngrams = _o->include_all_ngrams; + return tflite::CreateSkipGramOptions( + _fbb, + _ngram_size, + _max_skip_size, + _include_all_ngrams); +} + +inline SpaceToDepthOptionsT *SpaceToDepthOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SpaceToDepthOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SpaceToDepthOptions::UnPackTo(SpaceToDepthOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = block_size(); _o->block_size = _e; } +} + +inline flatbuffers::Offset SpaceToDepthOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToDepthOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSpaceToDepthOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSpaceToDepthOptions(flatbuffers::FlatBufferBuilder &_fbb, const SpaceToDepthOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SpaceToDepthOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _block_size = _o->block_size; + return tflite::CreateSpaceToDepthOptions( + _fbb, + _block_size); +} + +inline DepthToSpaceOptionsT *DepthToSpaceOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DepthToSpaceOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DepthToSpaceOptions::UnPackTo(DepthToSpaceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = block_size(); _o->block_size = _e; } +} + +inline flatbuffers::Offset DepthToSpaceOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DepthToSpaceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDepthToSpaceOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDepthToSpaceOptions(flatbuffers::FlatBufferBuilder &_fbb, const DepthToSpaceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DepthToSpaceOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _block_size = _o->block_size; + return tflite::CreateDepthToSpaceOptions( + _fbb, + _block_size); +} + +inline SubOptionsT *SubOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SubOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SubOptions::UnPackTo(SubOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset SubOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SubOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSubOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSubOptions(flatbuffers::FlatBufferBuilder &_fbb, const SubOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SubOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateSubOptions( + _fbb, + _fused_activation_function); +} + +inline DivOptionsT *DivOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DivOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DivOptions::UnPackTo(DivOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = fused_activation_function(); _o->fused_activation_function = _e; } +} + +inline flatbuffers::Offset DivOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DivOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDivOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDivOptions(flatbuffers::FlatBufferBuilder &_fbb, const DivOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DivOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _fused_activation_function = _o->fused_activation_function; + return tflite::CreateDivOptions( + _fbb, + _fused_activation_function); +} + +inline TopKV2OptionsT *TopKV2Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new TopKV2OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void TopKV2Options::UnPackTo(TopKV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset TopKV2Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TopKV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateTopKV2Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateTopKV2Options(flatbuffers::FlatBufferBuilder &_fbb, const TopKV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TopKV2OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateTopKV2Options( + _fbb); +} + +inline EmbeddingLookupSparseOptionsT *EmbeddingLookupSparseOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new EmbeddingLookupSparseOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void EmbeddingLookupSparseOptions::UnPackTo(EmbeddingLookupSparseOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = combiner(); _o->combiner = _e; } +} + +inline flatbuffers::Offset EmbeddingLookupSparseOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EmbeddingLookupSparseOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEmbeddingLookupSparseOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateEmbeddingLookupSparseOptions(flatbuffers::FlatBufferBuilder &_fbb, const EmbeddingLookupSparseOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EmbeddingLookupSparseOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _combiner = _o->combiner; + return tflite::CreateEmbeddingLookupSparseOptions( + _fbb, + _combiner); +} + +inline GatherOptionsT *GatherOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GatherOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void GatherOptions::UnPackTo(GatherOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = axis(); _o->axis = _e; } +} + +inline flatbuffers::Offset GatherOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GatherOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGatherOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateGatherOptions(flatbuffers::FlatBufferBuilder &_fbb, const GatherOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GatherOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _axis = _o->axis; + return tflite::CreateGatherOptions( + _fbb, + _axis); +} + +inline TransposeOptionsT *TransposeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new TransposeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void TransposeOptions::UnPackTo(TransposeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset TransposeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TransposeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateTransposeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateTransposeOptions(flatbuffers::FlatBufferBuilder &_fbb, const TransposeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TransposeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateTransposeOptions( + _fbb); +} + +inline ExpOptionsT *ExpOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ExpOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ExpOptions::UnPackTo(ExpOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset ExpOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ExpOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateExpOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateExpOptions(flatbuffers::FlatBufferBuilder &_fbb, const ExpOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ExpOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateExpOptions( + _fbb); +} + +inline CosOptionsT *CosOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new CosOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void CosOptions::UnPackTo(CosOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset CosOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CosOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateCosOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateCosOptions(flatbuffers::FlatBufferBuilder &_fbb, const CosOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CosOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateCosOptions( + _fbb); +} + +inline ReducerOptionsT *ReducerOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ReducerOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ReducerOptions::UnPackTo(ReducerOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = keep_dims(); _o->keep_dims = _e; } +} + +inline flatbuffers::Offset ReducerOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReducerOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateReducerOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateReducerOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReducerOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReducerOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _keep_dims = _o->keep_dims; + return tflite::CreateReducerOptions( + _fbb, + _keep_dims); +} + +inline SqueezeOptionsT *SqueezeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SqueezeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SqueezeOptions::UnPackTo(SqueezeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = squeeze_dims(); if (_e) { _o->squeeze_dims.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->squeeze_dims[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset SqueezeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SqueezeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSqueezeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSqueezeOptions(flatbuffers::FlatBufferBuilder &_fbb, const SqueezeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SqueezeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _squeeze_dims = _o->squeeze_dims.size() ? _fbb.CreateVector(_o->squeeze_dims) : 0; + return tflite::CreateSqueezeOptions( + _fbb, + _squeeze_dims); +} + +inline SplitOptionsT *SplitOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SplitOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SplitOptions::UnPackTo(SplitOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = num_splits(); _o->num_splits = _e; } +} + +inline flatbuffers::Offset SplitOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SplitOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSplitOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSplitOptions(flatbuffers::FlatBufferBuilder &_fbb, const SplitOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SplitOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _num_splits = _o->num_splits; + return tflite::CreateSplitOptions( + _fbb, + _num_splits); +} + +inline SplitVOptionsT *SplitVOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SplitVOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SplitVOptions::UnPackTo(SplitVOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = num_splits(); _o->num_splits = _e; } +} + +inline flatbuffers::Offset SplitVOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SplitVOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSplitVOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSplitVOptions(flatbuffers::FlatBufferBuilder &_fbb, const SplitVOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SplitVOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _num_splits = _o->num_splits; + return tflite::CreateSplitVOptions( + _fbb, + _num_splits); +} + +inline StridedSliceOptionsT *StridedSliceOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new StridedSliceOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void StridedSliceOptions::UnPackTo(StridedSliceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = begin_mask(); _o->begin_mask = _e; } + { auto _e = end_mask(); _o->end_mask = _e; } + { auto _e = ellipsis_mask(); _o->ellipsis_mask = _e; } + { auto _e = new_axis_mask(); _o->new_axis_mask = _e; } + { auto _e = shrink_axis_mask(); _o->shrink_axis_mask = _e; } +} + +inline flatbuffers::Offset StridedSliceOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StridedSliceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateStridedSliceOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateStridedSliceOptions(flatbuffers::FlatBufferBuilder &_fbb, const StridedSliceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StridedSliceOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _begin_mask = _o->begin_mask; + auto _end_mask = _o->end_mask; + auto _ellipsis_mask = _o->ellipsis_mask; + auto _new_axis_mask = _o->new_axis_mask; + auto _shrink_axis_mask = _o->shrink_axis_mask; + return tflite::CreateStridedSliceOptions( + _fbb, + _begin_mask, + _end_mask, + _ellipsis_mask, + _new_axis_mask, + _shrink_axis_mask); +} + +inline LogSoftmaxOptionsT *LogSoftmaxOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LogSoftmaxOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LogSoftmaxOptions::UnPackTo(LogSoftmaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LogSoftmaxOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogSoftmaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLogSoftmaxOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLogSoftmaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogSoftmaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LogSoftmaxOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLogSoftmaxOptions( + _fbb); +} + +inline CastOptionsT *CastOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new CastOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void CastOptions::UnPackTo(CastOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = in_data_type(); _o->in_data_type = _e; } + { auto _e = out_data_type(); _o->out_data_type = _e; } +} + +inline flatbuffers::Offset CastOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CastOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateCastOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateCastOptions(flatbuffers::FlatBufferBuilder &_fbb, const CastOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CastOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _in_data_type = _o->in_data_type; + auto _out_data_type = _o->out_data_type; + return tflite::CreateCastOptions( + _fbb, + _in_data_type, + _out_data_type); +} + +inline DequantizeOptionsT *DequantizeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DequantizeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DequantizeOptions::UnPackTo(DequantizeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset DequantizeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DequantizeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDequantizeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDequantizeOptions(flatbuffers::FlatBufferBuilder &_fbb, const DequantizeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DequantizeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateDequantizeOptions( + _fbb); +} + +inline MaximumMinimumOptionsT *MaximumMinimumOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MaximumMinimumOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void MaximumMinimumOptions::UnPackTo(MaximumMinimumOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset MaximumMinimumOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MaximumMinimumOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMaximumMinimumOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMaximumMinimumOptions(flatbuffers::FlatBufferBuilder &_fbb, const MaximumMinimumOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MaximumMinimumOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateMaximumMinimumOptions( + _fbb); +} + +inline TileOptionsT *TileOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new TileOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void TileOptions::UnPackTo(TileOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset TileOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TileOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateTileOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateTileOptions(flatbuffers::FlatBufferBuilder &_fbb, const TileOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TileOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateTileOptions( + _fbb); +} + +inline ArgMaxOptionsT *ArgMaxOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ArgMaxOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ArgMaxOptions::UnPackTo(ArgMaxOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = output_type(); _o->output_type = _e; } +} + +inline flatbuffers::Offset ArgMaxOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArgMaxOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateArgMaxOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateArgMaxOptions(flatbuffers::FlatBufferBuilder &_fbb, const ArgMaxOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ArgMaxOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _output_type = _o->output_type; + return tflite::CreateArgMaxOptions( + _fbb, + _output_type); +} + +inline ArgMinOptionsT *ArgMinOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ArgMinOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ArgMinOptions::UnPackTo(ArgMinOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = output_type(); _o->output_type = _e; } +} + +inline flatbuffers::Offset ArgMinOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArgMinOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateArgMinOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateArgMinOptions(flatbuffers::FlatBufferBuilder &_fbb, const ArgMinOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ArgMinOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _output_type = _o->output_type; + return tflite::CreateArgMinOptions( + _fbb, + _output_type); +} + +inline GreaterOptionsT *GreaterOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GreaterOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void GreaterOptions::UnPackTo(GreaterOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset GreaterOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GreaterOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGreaterOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateGreaterOptions(flatbuffers::FlatBufferBuilder &_fbb, const GreaterOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GreaterOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateGreaterOptions( + _fbb); +} + +inline GreaterEqualOptionsT *GreaterEqualOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GreaterEqualOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void GreaterEqualOptions::UnPackTo(GreaterEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset GreaterEqualOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GreaterEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGreaterEqualOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateGreaterEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const GreaterEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GreaterEqualOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateGreaterEqualOptions( + _fbb); +} + +inline LessOptionsT *LessOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LessOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LessOptions::UnPackTo(LessOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LessOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LessOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLessOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLessOptions(flatbuffers::FlatBufferBuilder &_fbb, const LessOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LessOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLessOptions( + _fbb); +} + +inline LessEqualOptionsT *LessEqualOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LessEqualOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LessEqualOptions::UnPackTo(LessEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LessEqualOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LessEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLessEqualOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLessEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const LessEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LessEqualOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLessEqualOptions( + _fbb); +} + +inline NegOptionsT *NegOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new NegOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void NegOptions::UnPackTo(NegOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset NegOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const NegOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateNegOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateNegOptions(flatbuffers::FlatBufferBuilder &_fbb, const NegOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const NegOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateNegOptions( + _fbb); +} + +inline SelectOptionsT *SelectOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SelectOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SelectOptions::UnPackTo(SelectOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SelectOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSelectOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSelectOptions(flatbuffers::FlatBufferBuilder &_fbb, const SelectOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SelectOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSelectOptions( + _fbb); +} + +inline SliceOptionsT *SliceOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SliceOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SliceOptions::UnPackTo(SliceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SliceOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SliceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSliceOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSliceOptions(flatbuffers::FlatBufferBuilder &_fbb, const SliceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SliceOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSliceOptions( + _fbb); +} + +inline TransposeConvOptionsT *TransposeConvOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new TransposeConvOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void TransposeConvOptions::UnPackTo(TransposeConvOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = padding(); _o->padding = _e; } + { auto _e = stride_w(); _o->stride_w = _e; } + { auto _e = stride_h(); _o->stride_h = _e; } +} + +inline flatbuffers::Offset TransposeConvOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TransposeConvOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateTransposeConvOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateTransposeConvOptions(flatbuffers::FlatBufferBuilder &_fbb, const TransposeConvOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TransposeConvOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _padding = _o->padding; + auto _stride_w = _o->stride_w; + auto _stride_h = _o->stride_h; + return tflite::CreateTransposeConvOptions( + _fbb, + _padding, + _stride_w, + _stride_h); +} + +inline ExpandDimsOptionsT *ExpandDimsOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ExpandDimsOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ExpandDimsOptions::UnPackTo(ExpandDimsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset ExpandDimsOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ExpandDimsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateExpandDimsOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateExpandDimsOptions(flatbuffers::FlatBufferBuilder &_fbb, const ExpandDimsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ExpandDimsOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateExpandDimsOptions( + _fbb); +} + +inline SparseToDenseOptionsT *SparseToDenseOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SparseToDenseOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SparseToDenseOptions::UnPackTo(SparseToDenseOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = validate_indices(); _o->validate_indices = _e; } +} + +inline flatbuffers::Offset SparseToDenseOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SparseToDenseOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSparseToDenseOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSparseToDenseOptions(flatbuffers::FlatBufferBuilder &_fbb, const SparseToDenseOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SparseToDenseOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _validate_indices = _o->validate_indices; + return tflite::CreateSparseToDenseOptions( + _fbb, + _validate_indices); +} + +inline EqualOptionsT *EqualOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new EqualOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void EqualOptions::UnPackTo(EqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset EqualOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateEqualOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const EqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EqualOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateEqualOptions( + _fbb); +} + +inline NotEqualOptionsT *NotEqualOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new NotEqualOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void NotEqualOptions::UnPackTo(NotEqualOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset NotEqualOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const NotEqualOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateNotEqualOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateNotEqualOptions(flatbuffers::FlatBufferBuilder &_fbb, const NotEqualOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const NotEqualOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateNotEqualOptions( + _fbb); +} + +inline ShapeOptionsT *ShapeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ShapeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ShapeOptions::UnPackTo(ShapeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = out_type(); _o->out_type = _e; } +} + +inline flatbuffers::Offset ShapeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ShapeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateShapeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateShapeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ShapeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ShapeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _out_type = _o->out_type; + return tflite::CreateShapeOptions( + _fbb, + _out_type); +} + +inline RankOptionsT *RankOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new RankOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void RankOptions::UnPackTo(RankOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset RankOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RankOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateRankOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateRankOptions(flatbuffers::FlatBufferBuilder &_fbb, const RankOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RankOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateRankOptions( + _fbb); +} + +inline PowOptionsT *PowOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new PowOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void PowOptions::UnPackTo(PowOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset PowOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PowOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePowOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePowOptions(flatbuffers::FlatBufferBuilder &_fbb, const PowOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PowOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreatePowOptions( + _fbb); +} + +inline FakeQuantOptionsT *FakeQuantOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new FakeQuantOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void FakeQuantOptions::UnPackTo(FakeQuantOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = min(); _o->min = _e; } + { auto _e = max(); _o->max = _e; } + { auto _e = num_bits(); _o->num_bits = _e; } + { auto _e = narrow_range(); _o->narrow_range = _e; } +} + +inline flatbuffers::Offset FakeQuantOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FakeQuantOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFakeQuantOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFakeQuantOptions(flatbuffers::FlatBufferBuilder &_fbb, const FakeQuantOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FakeQuantOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _min = _o->min; + auto _max = _o->max; + auto _num_bits = _o->num_bits; + auto _narrow_range = _o->narrow_range; + return tflite::CreateFakeQuantOptions( + _fbb, + _min, + _max, + _num_bits, + _narrow_range); +} + +inline PackOptionsT *PackOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new PackOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void PackOptions::UnPackTo(PackOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = values_count(); _o->values_count = _e; } + { auto _e = axis(); _o->axis = _e; } +} + +inline flatbuffers::Offset PackOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PackOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePackOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePackOptions(flatbuffers::FlatBufferBuilder &_fbb, const PackOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PackOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _values_count = _o->values_count; + auto _axis = _o->axis; + return tflite::CreatePackOptions( + _fbb, + _values_count, + _axis); +} + +inline LogicalOrOptionsT *LogicalOrOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LogicalOrOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LogicalOrOptions::UnPackTo(LogicalOrOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LogicalOrOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalOrOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLogicalOrOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLogicalOrOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalOrOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LogicalOrOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLogicalOrOptions( + _fbb); +} + +inline OneHotOptionsT *OneHotOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new OneHotOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void OneHotOptions::UnPackTo(OneHotOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = axis(); _o->axis = _e; } +} + +inline flatbuffers::Offset OneHotOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const OneHotOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateOneHotOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateOneHotOptions(flatbuffers::FlatBufferBuilder &_fbb, const OneHotOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const OneHotOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _axis = _o->axis; + return tflite::CreateOneHotOptions( + _fbb, + _axis); +} + +inline AbsOptionsT *AbsOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new AbsOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void AbsOptions::UnPackTo(AbsOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset AbsOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AbsOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateAbsOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateAbsOptions(flatbuffers::FlatBufferBuilder &_fbb, const AbsOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AbsOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateAbsOptions( + _fbb); +} + +inline HardSwishOptionsT *HardSwishOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new HardSwishOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void HardSwishOptions::UnPackTo(HardSwishOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset HardSwishOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const HardSwishOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateHardSwishOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateHardSwishOptions(flatbuffers::FlatBufferBuilder &_fbb, const HardSwishOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const HardSwishOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateHardSwishOptions( + _fbb); +} + +inline LogicalAndOptionsT *LogicalAndOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LogicalAndOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LogicalAndOptions::UnPackTo(LogicalAndOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LogicalAndOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalAndOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLogicalAndOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLogicalAndOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalAndOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LogicalAndOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLogicalAndOptions( + _fbb); +} + +inline LogicalNotOptionsT *LogicalNotOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LogicalNotOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LogicalNotOptions::UnPackTo(LogicalNotOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset LogicalNotOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LogicalNotOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLogicalNotOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLogicalNotOptions(flatbuffers::FlatBufferBuilder &_fbb, const LogicalNotOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LogicalNotOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateLogicalNotOptions( + _fbb); +} + +inline UnpackOptionsT *UnpackOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new UnpackOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void UnpackOptions::UnPackTo(UnpackOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = num(); _o->num = _e; } + { auto _e = axis(); _o->axis = _e; } +} + +inline flatbuffers::Offset UnpackOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const UnpackOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUnpackOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateUnpackOptions(flatbuffers::FlatBufferBuilder &_fbb, const UnpackOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const UnpackOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _num = _o->num; + auto _axis = _o->axis; + return tflite::CreateUnpackOptions( + _fbb, + _num, + _axis); +} + +inline FloorDivOptionsT *FloorDivOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new FloorDivOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void FloorDivOptions::UnPackTo(FloorDivOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset FloorDivOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FloorDivOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFloorDivOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFloorDivOptions(flatbuffers::FlatBufferBuilder &_fbb, const FloorDivOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FloorDivOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateFloorDivOptions( + _fbb); +} + +inline SquareOptionsT *SquareOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SquareOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SquareOptions::UnPackTo(SquareOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SquareOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SquareOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSquareOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSquareOptions(flatbuffers::FlatBufferBuilder &_fbb, const SquareOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SquareOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSquareOptions( + _fbb); +} + +inline ZerosLikeOptionsT *ZerosLikeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ZerosLikeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ZerosLikeOptions::UnPackTo(ZerosLikeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset ZerosLikeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ZerosLikeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateZerosLikeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateZerosLikeOptions(flatbuffers::FlatBufferBuilder &_fbb, const ZerosLikeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ZerosLikeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateZerosLikeOptions( + _fbb); +} + +inline FillOptionsT *FillOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new FillOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void FillOptions::UnPackTo(FillOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset FillOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FillOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFillOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFillOptions(flatbuffers::FlatBufferBuilder &_fbb, const FillOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FillOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateFillOptions( + _fbb); +} + +inline FloorModOptionsT *FloorModOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new FloorModOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void FloorModOptions::UnPackTo(FloorModOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset FloorModOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FloorModOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFloorModOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFloorModOptions(flatbuffers::FlatBufferBuilder &_fbb, const FloorModOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FloorModOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateFloorModOptions( + _fbb); +} + +inline RangeOptionsT *RangeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new RangeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void RangeOptions::UnPackTo(RangeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset RangeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RangeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateRangeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateRangeOptions(flatbuffers::FlatBufferBuilder &_fbb, const RangeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RangeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateRangeOptions( + _fbb); +} + +inline LeakyReluOptionsT *LeakyReluOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new LeakyReluOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void LeakyReluOptions::UnPackTo(LeakyReluOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = alpha(); _o->alpha = _e; } +} + +inline flatbuffers::Offset LeakyReluOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LeakyReluOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateLeakyReluOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateLeakyReluOptions(flatbuffers::FlatBufferBuilder &_fbb, const LeakyReluOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LeakyReluOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _alpha = _o->alpha; + return tflite::CreateLeakyReluOptions( + _fbb, + _alpha); +} + +inline SquaredDifferenceOptionsT *SquaredDifferenceOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SquaredDifferenceOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SquaredDifferenceOptions::UnPackTo(SquaredDifferenceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SquaredDifferenceOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SquaredDifferenceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSquaredDifferenceOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSquaredDifferenceOptions(flatbuffers::FlatBufferBuilder &_fbb, const SquaredDifferenceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SquaredDifferenceOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSquaredDifferenceOptions( + _fbb); +} + +inline MirrorPadOptionsT *MirrorPadOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MirrorPadOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void MirrorPadOptions::UnPackTo(MirrorPadOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = mode(); _o->mode = _e; } +} + +inline flatbuffers::Offset MirrorPadOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MirrorPadOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMirrorPadOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMirrorPadOptions(flatbuffers::FlatBufferBuilder &_fbb, const MirrorPadOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MirrorPadOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _mode = _o->mode; + return tflite::CreateMirrorPadOptions( + _fbb, + _mode); +} + +inline UniqueOptionsT *UniqueOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new UniqueOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void UniqueOptions::UnPackTo(UniqueOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = idx_out_type(); _o->idx_out_type = _e; } +} + +inline flatbuffers::Offset UniqueOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const UniqueOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateUniqueOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateUniqueOptions(flatbuffers::FlatBufferBuilder &_fbb, const UniqueOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const UniqueOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _idx_out_type = _o->idx_out_type; + return tflite::CreateUniqueOptions( + _fbb, + _idx_out_type); +} + +inline ReverseV2OptionsT *ReverseV2Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ReverseV2OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ReverseV2Options::UnPackTo(ReverseV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset ReverseV2Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReverseV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateReverseV2Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateReverseV2Options(flatbuffers::FlatBufferBuilder &_fbb, const ReverseV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReverseV2OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateReverseV2Options( + _fbb); +} + +inline AddNOptionsT *AddNOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new AddNOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void AddNOptions::UnPackTo(AddNOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset AddNOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AddNOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateAddNOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateAddNOptions(flatbuffers::FlatBufferBuilder &_fbb, const AddNOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AddNOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateAddNOptions( + _fbb); +} + +inline GatherNdOptionsT *GatherNdOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GatherNdOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void GatherNdOptions::UnPackTo(GatherNdOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset GatherNdOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GatherNdOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGatherNdOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateGatherNdOptions(flatbuffers::FlatBufferBuilder &_fbb, const GatherNdOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GatherNdOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateGatherNdOptions( + _fbb); +} + +inline WhereOptionsT *WhereOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new WhereOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void WhereOptions::UnPackTo(WhereOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset WhereOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WhereOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateWhereOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateWhereOptions(flatbuffers::FlatBufferBuilder &_fbb, const WhereOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const WhereOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateWhereOptions( + _fbb); +} + +inline ReverseSequenceOptionsT *ReverseSequenceOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ReverseSequenceOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ReverseSequenceOptions::UnPackTo(ReverseSequenceOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = seq_dim(); _o->seq_dim = _e; } + { auto _e = batch_dim(); _o->batch_dim = _e; } +} + +inline flatbuffers::Offset ReverseSequenceOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReverseSequenceOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateReverseSequenceOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateReverseSequenceOptions(flatbuffers::FlatBufferBuilder &_fbb, const ReverseSequenceOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReverseSequenceOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _seq_dim = _o->seq_dim; + auto _batch_dim = _o->batch_dim; + return tflite::CreateReverseSequenceOptions( + _fbb, + _seq_dim, + _batch_dim); +} + +inline MatrixDiagOptionsT *MatrixDiagOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MatrixDiagOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void MatrixDiagOptions::UnPackTo(MatrixDiagOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset MatrixDiagOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MatrixDiagOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMatrixDiagOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMatrixDiagOptions(flatbuffers::FlatBufferBuilder &_fbb, const MatrixDiagOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MatrixDiagOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateMatrixDiagOptions( + _fbb); +} + +inline QuantizeOptionsT *QuantizeOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new QuantizeOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void QuantizeOptions::UnPackTo(QuantizeOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset QuantizeOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const QuantizeOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateQuantizeOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateQuantizeOptions(flatbuffers::FlatBufferBuilder &_fbb, const QuantizeOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const QuantizeOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateQuantizeOptions( + _fbb); +} + +inline MatrixSetDiagOptionsT *MatrixSetDiagOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MatrixSetDiagOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void MatrixSetDiagOptions::UnPackTo(MatrixSetDiagOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset MatrixSetDiagOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MatrixSetDiagOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMatrixSetDiagOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMatrixSetDiagOptions(flatbuffers::FlatBufferBuilder &_fbb, const MatrixSetDiagOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MatrixSetDiagOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateMatrixSetDiagOptions( + _fbb); +} + +inline IfOptionsT *IfOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new IfOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void IfOptions::UnPackTo(IfOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = then_subgraph_index(); _o->then_subgraph_index = _e; } + { auto _e = else_subgraph_index(); _o->else_subgraph_index = _e; } +} + +inline flatbuffers::Offset IfOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const IfOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateIfOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateIfOptions(flatbuffers::FlatBufferBuilder &_fbb, const IfOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const IfOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _then_subgraph_index = _o->then_subgraph_index; + auto _else_subgraph_index = _o->else_subgraph_index; + return tflite::CreateIfOptions( + _fbb, + _then_subgraph_index, + _else_subgraph_index); +} + +inline WhileOptionsT *WhileOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new WhileOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void WhileOptions::UnPackTo(WhileOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = cond_subgraph_index(); _o->cond_subgraph_index = _e; } + { auto _e = body_subgraph_index(); _o->body_subgraph_index = _e; } +} + +inline flatbuffers::Offset WhileOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WhileOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateWhileOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateWhileOptions(flatbuffers::FlatBufferBuilder &_fbb, const WhileOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const WhileOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _cond_subgraph_index = _o->cond_subgraph_index; + auto _body_subgraph_index = _o->body_subgraph_index; + return tflite::CreateWhileOptions( + _fbb, + _cond_subgraph_index, + _body_subgraph_index); +} + +inline NonMaxSuppressionV4OptionsT *NonMaxSuppressionV4Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new NonMaxSuppressionV4OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void NonMaxSuppressionV4Options::UnPackTo(NonMaxSuppressionV4OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset NonMaxSuppressionV4Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV4OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateNonMaxSuppressionV4Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateNonMaxSuppressionV4Options(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV4OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const NonMaxSuppressionV4OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateNonMaxSuppressionV4Options( + _fbb); +} + +inline NonMaxSuppressionV5OptionsT *NonMaxSuppressionV5Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new NonMaxSuppressionV5OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void NonMaxSuppressionV5Options::UnPackTo(NonMaxSuppressionV5OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset NonMaxSuppressionV5Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV5OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateNonMaxSuppressionV5Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateNonMaxSuppressionV5Options(flatbuffers::FlatBufferBuilder &_fbb, const NonMaxSuppressionV5OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const NonMaxSuppressionV5OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateNonMaxSuppressionV5Options( + _fbb); +} + +inline ScatterNdOptionsT *ScatterNdOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ScatterNdOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void ScatterNdOptions::UnPackTo(ScatterNdOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset ScatterNdOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ScatterNdOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateScatterNdOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateScatterNdOptions(flatbuffers::FlatBufferBuilder &_fbb, const ScatterNdOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ScatterNdOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateScatterNdOptions( + _fbb); +} + +inline SelectV2OptionsT *SelectV2Options::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SelectV2OptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SelectV2Options::UnPackTo(SelectV2OptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SelectV2Options::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectV2OptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSelectV2Options(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSelectV2Options(flatbuffers::FlatBufferBuilder &_fbb, const SelectV2OptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SelectV2OptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSelectV2Options( + _fbb); +} + +inline DensifyOptionsT *DensifyOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new DensifyOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void DensifyOptions::UnPackTo(DensifyOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset DensifyOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DensifyOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateDensifyOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateDensifyOptions(flatbuffers::FlatBufferBuilder &_fbb, const DensifyOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DensifyOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateDensifyOptions( + _fbb); +} + +inline SegmentSumOptionsT *SegmentSumOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SegmentSumOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SegmentSumOptions::UnPackTo(SegmentSumOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; +} + +inline flatbuffers::Offset SegmentSumOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SegmentSumOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSegmentSumOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSegmentSumOptions(flatbuffers::FlatBufferBuilder &_fbb, const SegmentSumOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SegmentSumOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + return tflite::CreateSegmentSumOptions( + _fbb); +} + +inline BatchMatMulOptionsT *BatchMatMulOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new BatchMatMulOptionsT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void BatchMatMulOptions::UnPackTo(BatchMatMulOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = adj_x(); _o->adj_x = _e; } + { auto _e = adj_y(); _o->adj_y = _e; } +} + +inline flatbuffers::Offset BatchMatMulOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BatchMatMulOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBatchMatMulOptions(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateBatchMatMulOptions(flatbuffers::FlatBufferBuilder &_fbb, const BatchMatMulOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BatchMatMulOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _adj_x = _o->adj_x; + auto _adj_y = _o->adj_y; + return tflite::CreateBatchMatMulOptions( + _fbb, + _adj_x, + _adj_y); +} + +inline OperatorCodeT *OperatorCode::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new OperatorCodeT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void OperatorCode::UnPackTo(OperatorCodeT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = builtin_code(); _o->builtin_code = _e; } + { auto _e = custom_code(); if (_e) _o->custom_code = _e->str(); } + { auto _e = version(); _o->version = _e; } +} + +inline flatbuffers::Offset OperatorCode::Pack(flatbuffers::FlatBufferBuilder &_fbb, const OperatorCodeT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateOperatorCode(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateOperatorCode(flatbuffers::FlatBufferBuilder &_fbb, const OperatorCodeT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const OperatorCodeT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _builtin_code = _o->builtin_code; + auto _custom_code = _o->custom_code.empty() ? 0 : _fbb.CreateString(_o->custom_code); + auto _version = _o->version; + return tflite::CreateOperatorCode( + _fbb, + _builtin_code, + _custom_code, + _version); +} + +inline OperatorT *Operator::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new OperatorT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Operator::UnPackTo(OperatorT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = opcode_index(); _o->opcode_index = _e; } + { auto _e = inputs(); if (_e) { _o->inputs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inputs[_i] = _e->Get(_i); } } } + { auto _e = outputs(); if (_e) { _o->outputs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->outputs[_i] = _e->Get(_i); } } } + { auto _e = builtin_options_type(); _o->builtin_options.type = _e; } + { auto _e = builtin_options(); if (_e) _o->builtin_options.value = tflite::BuiltinOptionsUnion::UnPack(_e, builtin_options_type(), _resolver); } + { auto _e = custom_options(); if (_e) { _o->custom_options.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->custom_options[_i] = _e->Get(_i); } } } + { auto _e = custom_options_format(); _o->custom_options_format = _e; } + { auto _e = mutating_variable_inputs(); if (_e) { _o->mutating_variable_inputs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->mutating_variable_inputs[_i] = _e->Get(_i) != 0; } } } + { auto _e = intermediates(); if (_e) { _o->intermediates.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->intermediates[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Operator::Pack(flatbuffers::FlatBufferBuilder &_fbb, const OperatorT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateOperator(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateOperator(flatbuffers::FlatBufferBuilder &_fbb, const OperatorT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const OperatorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _opcode_index = _o->opcode_index; + auto _inputs = _o->inputs.size() ? _fbb.CreateVector(_o->inputs) : 0; + auto _outputs = _o->outputs.size() ? _fbb.CreateVector(_o->outputs) : 0; + auto _builtin_options_type = _o->builtin_options.type; + auto _builtin_options = _o->builtin_options.Pack(_fbb); + auto _custom_options = _o->custom_options.size() ? _fbb.CreateVector(_o->custom_options) : 0; + auto _custom_options_format = _o->custom_options_format; + auto _mutating_variable_inputs = _o->mutating_variable_inputs.size() ? _fbb.CreateVector(_o->mutating_variable_inputs) : 0; + auto _intermediates = _o->intermediates.size() ? _fbb.CreateVector(_o->intermediates) : 0; + return tflite::CreateOperator( + _fbb, + _opcode_index, + _inputs, + _outputs, + _builtin_options_type, + _builtin_options, + _custom_options, + _custom_options_format, + _mutating_variable_inputs, + _intermediates); +} + +inline SubGraphT *SubGraph::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new SubGraphT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void SubGraph::UnPackTo(SubGraphT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = tensors(); if (_e) { _o->tensors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->tensors[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = inputs(); if (_e) { _o->inputs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inputs[_i] = _e->Get(_i); } } } + { auto _e = outputs(); if (_e) { _o->outputs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->outputs[_i] = _e->Get(_i); } } } + { auto _e = operators(); if (_e) { _o->operators.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->operators[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = name(); if (_e) _o->name = _e->str(); } +} + +inline flatbuffers::Offset SubGraph::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SubGraphT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSubGraph(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSubGraph(flatbuffers::FlatBufferBuilder &_fbb, const SubGraphT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SubGraphT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _tensors = _o->tensors.size() ? _fbb.CreateVector> (_o->tensors.size(), [](size_t i, _VectorArgs *__va) { return CreateTensor(*__va->__fbb, __va->__o->tensors[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _inputs = _o->inputs.size() ? _fbb.CreateVector(_o->inputs) : 0; + auto _outputs = _o->outputs.size() ? _fbb.CreateVector(_o->outputs) : 0; + auto _operators = _o->operators.size() ? _fbb.CreateVector> (_o->operators.size(), [](size_t i, _VectorArgs *__va) { return CreateOperator(*__va->__fbb, __va->__o->operators[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name); + return tflite::CreateSubGraph( + _fbb, + _tensors, + _inputs, + _outputs, + _operators, + _name); +} + +inline BufferT *Buffer::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new BufferT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Buffer::UnPackTo(BufferT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = data(); if (_e) { _o->data.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->data[_i] = _e->Get(_i); } } } +} + +inline flatbuffers::Offset Buffer::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BufferT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateBuffer(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateBuffer(flatbuffers::FlatBufferBuilder &_fbb, const BufferT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BufferT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + _fbb.ForceVectorAlignment(_o->data.size(), sizeof(uint8_t), 16); + auto _data = _o->data.size() ? _fbb.CreateVector(_o->data) : 0; + return tflite::CreateBuffer( + _fbb, + _data); +} + +inline MetadataT *Metadata::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new MetadataT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Metadata::UnPackTo(MetadataT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = name(); if (_e) _o->name = _e->str(); } + { auto _e = buffer(); _o->buffer = _e; } +} + +inline flatbuffers::Offset Metadata::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MetadataT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateMetadata(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateMetadata(flatbuffers::FlatBufferBuilder &_fbb, const MetadataT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MetadataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name); + auto _buffer = _o->buffer; + return tflite::CreateMetadata( + _fbb, + _name, + _buffer); +} + +inline ModelT *Model::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new ModelT(); + UnPackTo(_o, _resolver); + return _o; +} + +inline void Model::UnPackTo(ModelT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = version(); _o->version = _e; } + { auto _e = operator_codes(); if (_e) { _o->operator_codes.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->operator_codes[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = subgraphs(); if (_e) { _o->subgraphs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->subgraphs[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = description(); if (_e) _o->description = _e->str(); } + { auto _e = buffers(); if (_e) { _o->buffers.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->buffers[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = metadata_buffer(); if (_e) { _o->metadata_buffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->metadata_buffer[_i] = _e->Get(_i); } } } + { auto _e = metadata(); if (_e) { _o->metadata.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->metadata[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } +} + +inline flatbuffers::Offset Model::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateModel(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateModel(flatbuffers::FlatBufferBuilder &_fbb, const ModelT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ModelT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _version = _o->version; + auto _operator_codes = _o->operator_codes.size() ? _fbb.CreateVector> (_o->operator_codes.size(), [](size_t i, _VectorArgs *__va) { return CreateOperatorCode(*__va->__fbb, __va->__o->operator_codes[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _subgraphs = _o->subgraphs.size() ? _fbb.CreateVector> (_o->subgraphs.size(), [](size_t i, _VectorArgs *__va) { return CreateSubGraph(*__va->__fbb, __va->__o->subgraphs[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _description = _o->description.empty() ? 0 : _fbb.CreateString(_o->description); + auto _buffers = _o->buffers.size() ? _fbb.CreateVector> (_o->buffers.size(), [](size_t i, _VectorArgs *__va) { return CreateBuffer(*__va->__fbb, __va->__o->buffers[i].get(), __va->__rehasher); }, &_va ) : 0; + auto _metadata_buffer = _o->metadata_buffer.size() ? _fbb.CreateVector(_o->metadata_buffer) : 0; + auto _metadata = _o->metadata.size() ? _fbb.CreateVector> (_o->metadata.size(), [](size_t i, _VectorArgs *__va) { return CreateMetadata(*__va->__fbb, __va->__o->metadata[i].get(), __va->__rehasher); }, &_va ) : 0; + return tflite::CreateModel( + _fbb, + _version, + _operator_codes, + _subgraphs, + _description, + _buffers, + _metadata_buffer, + _metadata); +} + +inline bool VerifyQuantizationDetails(flatbuffers::Verifier &verifier, const void *obj, QuantizationDetails type) { + switch (type) { + case QuantizationDetails_NONE: { + return true; + } + case QuantizationDetails_CustomQuantization: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyQuantizationDetailsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyQuantizationDetails( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline void *QuantizationDetailsUnion::UnPack(const void *obj, QuantizationDetails type, const flatbuffers::resolver_function_t *resolver) { + switch (type) { + case QuantizationDetails_CustomQuantization: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + default: return nullptr; + } +} + +inline flatbuffers::Offset QuantizationDetailsUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { + switch (type) { + case QuantizationDetails_CustomQuantization: { + auto ptr = reinterpret_cast(value); + return CreateCustomQuantization(_fbb, ptr, _rehasher).Union(); + } + default: return 0; + } +} + +inline QuantizationDetailsUnion::QuantizationDetailsUnion(const QuantizationDetailsUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) { + switch (type) { + case QuantizationDetails_CustomQuantization: { + value = new tflite::CustomQuantizationT(*reinterpret_cast(u.value)); + break; + } + default: + break; + } +} + +inline void QuantizationDetailsUnion::Reset() { + switch (type) { + case QuantizationDetails_CustomQuantization: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + default: break; + } + value = nullptr; + type = QuantizationDetails_NONE; +} + +inline bool VerifySparseIndexVector(flatbuffers::Verifier &verifier, const void *obj, SparseIndexVector type) { + switch (type) { + case SparseIndexVector_NONE: { + return true; + } + case SparseIndexVector_Int32Vector: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case SparseIndexVector_Uint16Vector: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case SparseIndexVector_Uint8Vector: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifySparseIndexVectorVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifySparseIndexVector( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline void *SparseIndexVectorUnion::UnPack(const void *obj, SparseIndexVector type, const flatbuffers::resolver_function_t *resolver) { + switch (type) { + case SparseIndexVector_Int32Vector: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case SparseIndexVector_Uint16Vector: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case SparseIndexVector_Uint8Vector: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + default: return nullptr; + } +} + +inline flatbuffers::Offset SparseIndexVectorUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { + switch (type) { + case SparseIndexVector_Int32Vector: { + auto ptr = reinterpret_cast(value); + return CreateInt32Vector(_fbb, ptr, _rehasher).Union(); + } + case SparseIndexVector_Uint16Vector: { + auto ptr = reinterpret_cast(value); + return CreateUint16Vector(_fbb, ptr, _rehasher).Union(); + } + case SparseIndexVector_Uint8Vector: { + auto ptr = reinterpret_cast(value); + return CreateUint8Vector(_fbb, ptr, _rehasher).Union(); + } + default: return 0; + } +} + +inline SparseIndexVectorUnion::SparseIndexVectorUnion(const SparseIndexVectorUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) { + switch (type) { + case SparseIndexVector_Int32Vector: { + value = new tflite::Int32VectorT(*reinterpret_cast(u.value)); + break; + } + case SparseIndexVector_Uint16Vector: { + value = new tflite::Uint16VectorT(*reinterpret_cast(u.value)); + break; + } + case SparseIndexVector_Uint8Vector: { + value = new tflite::Uint8VectorT(*reinterpret_cast(u.value)); + break; + } + default: + break; + } +} + +inline void SparseIndexVectorUnion::Reset() { + switch (type) { + case SparseIndexVector_Int32Vector: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case SparseIndexVector_Uint16Vector: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case SparseIndexVector_Uint8Vector: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + default: break; + } + value = nullptr; + type = SparseIndexVector_NONE; +} + +inline bool VerifyBuiltinOptions(flatbuffers::Verifier &verifier, const void *obj, BuiltinOptions type) { + switch (type) { + case BuiltinOptions_NONE: { + return true; + } + case BuiltinOptions_Conv2DOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_DepthwiseConv2DOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ConcatEmbeddingsOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LSHProjectionOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_Pool2DOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SVDFOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_RNNOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_FullyConnectedOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SoftmaxOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ConcatenationOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_AddOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_L2NormOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LocalResponseNormalizationOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LSTMOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ResizeBilinearOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_CallOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ReshapeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SkipGramOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SpaceToDepthOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_EmbeddingLookupSparseOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_MulOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_PadOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_GatherOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_BatchToSpaceNDOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SpaceToBatchNDOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_TransposeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ReducerOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SubOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_DivOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SqueezeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SequenceRNNOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_StridedSliceOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ExpOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_TopKV2Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SplitOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LogSoftmaxOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_CastOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_DequantizeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_MaximumMinimumOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ArgMaxOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LessOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_NegOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_PadV2Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_GreaterOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_GreaterEqualOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LessEqualOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SelectOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SliceOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_TransposeConvOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SparseToDenseOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_TileOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ExpandDimsOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_EqualOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_NotEqualOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ShapeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_PowOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ArgMinOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_FakeQuantOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_PackOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LogicalOrOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_OneHotOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LogicalAndOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LogicalNotOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_UnpackOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_FloorDivOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SquareOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ZerosLikeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_FillOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_BidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_BidirectionalSequenceRNNOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_UnidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_FloorModOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_RangeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ResizeNearestNeighborOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_LeakyReluOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SquaredDifferenceOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_MirrorPadOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_AbsOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SplitVOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_UniqueOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ReverseV2Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_AddNOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_GatherNdOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_CosOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_WhereOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_RankOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ReverseSequenceOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_MatrixDiagOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_QuantizeOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_MatrixSetDiagOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_HardSwishOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_IfOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_WhileOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_DepthToSpaceOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_NonMaxSuppressionV4Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_NonMaxSuppressionV5Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_ScatterNdOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SelectV2Options: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_DensifyOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_SegmentSumOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case BuiltinOptions_BatchMatMulOptions: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyBuiltinOptionsVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyBuiltinOptions( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline void *BuiltinOptionsUnion::UnPack(const void *obj, BuiltinOptions type, const flatbuffers::resolver_function_t *resolver) { + switch (type) { + case BuiltinOptions_Conv2DOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_DepthwiseConv2DOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ConcatEmbeddingsOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LSHProjectionOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_Pool2DOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SVDFOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_RNNOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_FullyConnectedOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SoftmaxOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ConcatenationOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_AddOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_L2NormOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LocalResponseNormalizationOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LSTMOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ResizeBilinearOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_CallOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ReshapeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SkipGramOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SpaceToDepthOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_EmbeddingLookupSparseOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_MulOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_PadOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_GatherOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_BatchToSpaceNDOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SpaceToBatchNDOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_TransposeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ReducerOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SubOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_DivOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SqueezeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SequenceRNNOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_StridedSliceOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ExpOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_TopKV2Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SplitOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LogSoftmaxOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_CastOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_DequantizeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_MaximumMinimumOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ArgMaxOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LessOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_NegOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_PadV2Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_GreaterOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_GreaterEqualOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LessEqualOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SelectOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SliceOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_TransposeConvOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SparseToDenseOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_TileOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ExpandDimsOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_EqualOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_NotEqualOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ShapeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_PowOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ArgMinOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_FakeQuantOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_PackOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LogicalOrOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_OneHotOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LogicalAndOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LogicalNotOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_UnpackOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_FloorDivOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SquareOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ZerosLikeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_FillOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_BidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_BidirectionalSequenceRNNOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_UnidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_FloorModOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_RangeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ResizeNearestNeighborOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_LeakyReluOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SquaredDifferenceOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_MirrorPadOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_AbsOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SplitVOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_UniqueOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ReverseV2Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_AddNOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_GatherNdOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_CosOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_WhereOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_RankOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ReverseSequenceOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_MatrixDiagOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_QuantizeOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_MatrixSetDiagOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_HardSwishOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_IfOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_WhileOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_DepthToSpaceOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_NonMaxSuppressionV4Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_NonMaxSuppressionV5Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_ScatterNdOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SelectV2Options: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_DensifyOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_SegmentSumOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + case BuiltinOptions_BatchMatMulOptions: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } + default: return nullptr; + } +} + +inline flatbuffers::Offset BuiltinOptionsUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { + switch (type) { + case BuiltinOptions_Conv2DOptions: { + auto ptr = reinterpret_cast(value); + return CreateConv2DOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_DepthwiseConv2DOptions: { + auto ptr = reinterpret_cast(value); + return CreateDepthwiseConv2DOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ConcatEmbeddingsOptions: { + auto ptr = reinterpret_cast(value); + return CreateConcatEmbeddingsOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LSHProjectionOptions: { + auto ptr = reinterpret_cast(value); + return CreateLSHProjectionOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_Pool2DOptions: { + auto ptr = reinterpret_cast(value); + return CreatePool2DOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SVDFOptions: { + auto ptr = reinterpret_cast(value); + return CreateSVDFOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_RNNOptions: { + auto ptr = reinterpret_cast(value); + return CreateRNNOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_FullyConnectedOptions: { + auto ptr = reinterpret_cast(value); + return CreateFullyConnectedOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SoftmaxOptions: { + auto ptr = reinterpret_cast(value); + return CreateSoftmaxOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ConcatenationOptions: { + auto ptr = reinterpret_cast(value); + return CreateConcatenationOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_AddOptions: { + auto ptr = reinterpret_cast(value); + return CreateAddOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_L2NormOptions: { + auto ptr = reinterpret_cast(value); + return CreateL2NormOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LocalResponseNormalizationOptions: { + auto ptr = reinterpret_cast(value); + return CreateLocalResponseNormalizationOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LSTMOptions: { + auto ptr = reinterpret_cast(value); + return CreateLSTMOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ResizeBilinearOptions: { + auto ptr = reinterpret_cast(value); + return CreateResizeBilinearOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_CallOptions: { + auto ptr = reinterpret_cast(value); + return CreateCallOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ReshapeOptions: { + auto ptr = reinterpret_cast(value); + return CreateReshapeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SkipGramOptions: { + auto ptr = reinterpret_cast(value); + return CreateSkipGramOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SpaceToDepthOptions: { + auto ptr = reinterpret_cast(value); + return CreateSpaceToDepthOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_EmbeddingLookupSparseOptions: { + auto ptr = reinterpret_cast(value); + return CreateEmbeddingLookupSparseOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_MulOptions: { + auto ptr = reinterpret_cast(value); + return CreateMulOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_PadOptions: { + auto ptr = reinterpret_cast(value); + return CreatePadOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_GatherOptions: { + auto ptr = reinterpret_cast(value); + return CreateGatherOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_BatchToSpaceNDOptions: { + auto ptr = reinterpret_cast(value); + return CreateBatchToSpaceNDOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SpaceToBatchNDOptions: { + auto ptr = reinterpret_cast(value); + return CreateSpaceToBatchNDOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_TransposeOptions: { + auto ptr = reinterpret_cast(value); + return CreateTransposeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ReducerOptions: { + auto ptr = reinterpret_cast(value); + return CreateReducerOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SubOptions: { + auto ptr = reinterpret_cast(value); + return CreateSubOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_DivOptions: { + auto ptr = reinterpret_cast(value); + return CreateDivOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SqueezeOptions: { + auto ptr = reinterpret_cast(value); + return CreateSqueezeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SequenceRNNOptions: { + auto ptr = reinterpret_cast(value); + return CreateSequenceRNNOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_StridedSliceOptions: { + auto ptr = reinterpret_cast(value); + return CreateStridedSliceOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ExpOptions: { + auto ptr = reinterpret_cast(value); + return CreateExpOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_TopKV2Options: { + auto ptr = reinterpret_cast(value); + return CreateTopKV2Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SplitOptions: { + auto ptr = reinterpret_cast(value); + return CreateSplitOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LogSoftmaxOptions: { + auto ptr = reinterpret_cast(value); + return CreateLogSoftmaxOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_CastOptions: { + auto ptr = reinterpret_cast(value); + return CreateCastOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_DequantizeOptions: { + auto ptr = reinterpret_cast(value); + return CreateDequantizeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_MaximumMinimumOptions: { + auto ptr = reinterpret_cast(value); + return CreateMaximumMinimumOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ArgMaxOptions: { + auto ptr = reinterpret_cast(value); + return CreateArgMaxOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LessOptions: { + auto ptr = reinterpret_cast(value); + return CreateLessOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_NegOptions: { + auto ptr = reinterpret_cast(value); + return CreateNegOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_PadV2Options: { + auto ptr = reinterpret_cast(value); + return CreatePadV2Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_GreaterOptions: { + auto ptr = reinterpret_cast(value); + return CreateGreaterOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_GreaterEqualOptions: { + auto ptr = reinterpret_cast(value); + return CreateGreaterEqualOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LessEqualOptions: { + auto ptr = reinterpret_cast(value); + return CreateLessEqualOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SelectOptions: { + auto ptr = reinterpret_cast(value); + return CreateSelectOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SliceOptions: { + auto ptr = reinterpret_cast(value); + return CreateSliceOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_TransposeConvOptions: { + auto ptr = reinterpret_cast(value); + return CreateTransposeConvOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SparseToDenseOptions: { + auto ptr = reinterpret_cast(value); + return CreateSparseToDenseOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_TileOptions: { + auto ptr = reinterpret_cast(value); + return CreateTileOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ExpandDimsOptions: { + auto ptr = reinterpret_cast(value); + return CreateExpandDimsOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_EqualOptions: { + auto ptr = reinterpret_cast(value); + return CreateEqualOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_NotEqualOptions: { + auto ptr = reinterpret_cast(value); + return CreateNotEqualOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ShapeOptions: { + auto ptr = reinterpret_cast(value); + return CreateShapeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_PowOptions: { + auto ptr = reinterpret_cast(value); + return CreatePowOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ArgMinOptions: { + auto ptr = reinterpret_cast(value); + return CreateArgMinOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_FakeQuantOptions: { + auto ptr = reinterpret_cast(value); + return CreateFakeQuantOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_PackOptions: { + auto ptr = reinterpret_cast(value); + return CreatePackOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LogicalOrOptions: { + auto ptr = reinterpret_cast(value); + return CreateLogicalOrOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_OneHotOptions: { + auto ptr = reinterpret_cast(value); + return CreateOneHotOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LogicalAndOptions: { + auto ptr = reinterpret_cast(value); + return CreateLogicalAndOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LogicalNotOptions: { + auto ptr = reinterpret_cast(value); + return CreateLogicalNotOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_UnpackOptions: { + auto ptr = reinterpret_cast(value); + return CreateUnpackOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_FloorDivOptions: { + auto ptr = reinterpret_cast(value); + return CreateFloorDivOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SquareOptions: { + auto ptr = reinterpret_cast(value); + return CreateSquareOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ZerosLikeOptions: { + auto ptr = reinterpret_cast(value); + return CreateZerosLikeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_FillOptions: { + auto ptr = reinterpret_cast(value); + return CreateFillOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_BidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(value); + return CreateBidirectionalSequenceLSTMOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_BidirectionalSequenceRNNOptions: { + auto ptr = reinterpret_cast(value); + return CreateBidirectionalSequenceRNNOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_UnidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(value); + return CreateUnidirectionalSequenceLSTMOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_FloorModOptions: { + auto ptr = reinterpret_cast(value); + return CreateFloorModOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_RangeOptions: { + auto ptr = reinterpret_cast(value); + return CreateRangeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ResizeNearestNeighborOptions: { + auto ptr = reinterpret_cast(value); + return CreateResizeNearestNeighborOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_LeakyReluOptions: { + auto ptr = reinterpret_cast(value); + return CreateLeakyReluOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SquaredDifferenceOptions: { + auto ptr = reinterpret_cast(value); + return CreateSquaredDifferenceOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_MirrorPadOptions: { + auto ptr = reinterpret_cast(value); + return CreateMirrorPadOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_AbsOptions: { + auto ptr = reinterpret_cast(value); + return CreateAbsOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SplitVOptions: { + auto ptr = reinterpret_cast(value); + return CreateSplitVOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_UniqueOptions: { + auto ptr = reinterpret_cast(value); + return CreateUniqueOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ReverseV2Options: { + auto ptr = reinterpret_cast(value); + return CreateReverseV2Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_AddNOptions: { + auto ptr = reinterpret_cast(value); + return CreateAddNOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_GatherNdOptions: { + auto ptr = reinterpret_cast(value); + return CreateGatherNdOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_CosOptions: { + auto ptr = reinterpret_cast(value); + return CreateCosOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_WhereOptions: { + auto ptr = reinterpret_cast(value); + return CreateWhereOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_RankOptions: { + auto ptr = reinterpret_cast(value); + return CreateRankOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ReverseSequenceOptions: { + auto ptr = reinterpret_cast(value); + return CreateReverseSequenceOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_MatrixDiagOptions: { + auto ptr = reinterpret_cast(value); + return CreateMatrixDiagOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_QuantizeOptions: { + auto ptr = reinterpret_cast(value); + return CreateQuantizeOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_MatrixSetDiagOptions: { + auto ptr = reinterpret_cast(value); + return CreateMatrixSetDiagOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_HardSwishOptions: { + auto ptr = reinterpret_cast(value); + return CreateHardSwishOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_IfOptions: { + auto ptr = reinterpret_cast(value); + return CreateIfOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_WhileOptions: { + auto ptr = reinterpret_cast(value); + return CreateWhileOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_DepthToSpaceOptions: { + auto ptr = reinterpret_cast(value); + return CreateDepthToSpaceOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_NonMaxSuppressionV4Options: { + auto ptr = reinterpret_cast(value); + return CreateNonMaxSuppressionV4Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_NonMaxSuppressionV5Options: { + auto ptr = reinterpret_cast(value); + return CreateNonMaxSuppressionV5Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_ScatterNdOptions: { + auto ptr = reinterpret_cast(value); + return CreateScatterNdOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SelectV2Options: { + auto ptr = reinterpret_cast(value); + return CreateSelectV2Options(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_DensifyOptions: { + auto ptr = reinterpret_cast(value); + return CreateDensifyOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_SegmentSumOptions: { + auto ptr = reinterpret_cast(value); + return CreateSegmentSumOptions(_fbb, ptr, _rehasher).Union(); + } + case BuiltinOptions_BatchMatMulOptions: { + auto ptr = reinterpret_cast(value); + return CreateBatchMatMulOptions(_fbb, ptr, _rehasher).Union(); + } + default: return 0; + } +} + +inline BuiltinOptionsUnion::BuiltinOptionsUnion(const BuiltinOptionsUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) { + switch (type) { + case BuiltinOptions_Conv2DOptions: { + value = new tflite::Conv2DOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_DepthwiseConv2DOptions: { + value = new tflite::DepthwiseConv2DOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ConcatEmbeddingsOptions: { + value = new tflite::ConcatEmbeddingsOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LSHProjectionOptions: { + value = new tflite::LSHProjectionOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_Pool2DOptions: { + value = new tflite::Pool2DOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SVDFOptions: { + value = new tflite::SVDFOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_RNNOptions: { + value = new tflite::RNNOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_FullyConnectedOptions: { + value = new tflite::FullyConnectedOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SoftmaxOptions: { + value = new tflite::SoftmaxOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ConcatenationOptions: { + value = new tflite::ConcatenationOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_AddOptions: { + value = new tflite::AddOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_L2NormOptions: { + value = new tflite::L2NormOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LocalResponseNormalizationOptions: { + value = new tflite::LocalResponseNormalizationOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LSTMOptions: { + value = new tflite::LSTMOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ResizeBilinearOptions: { + value = new tflite::ResizeBilinearOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_CallOptions: { + value = new tflite::CallOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ReshapeOptions: { + value = new tflite::ReshapeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SkipGramOptions: { + value = new tflite::SkipGramOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SpaceToDepthOptions: { + value = new tflite::SpaceToDepthOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_EmbeddingLookupSparseOptions: { + value = new tflite::EmbeddingLookupSparseOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_MulOptions: { + value = new tflite::MulOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_PadOptions: { + value = new tflite::PadOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_GatherOptions: { + value = new tflite::GatherOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_BatchToSpaceNDOptions: { + value = new tflite::BatchToSpaceNDOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SpaceToBatchNDOptions: { + value = new tflite::SpaceToBatchNDOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_TransposeOptions: { + value = new tflite::TransposeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ReducerOptions: { + value = new tflite::ReducerOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SubOptions: { + value = new tflite::SubOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_DivOptions: { + value = new tflite::DivOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SqueezeOptions: { + value = new tflite::SqueezeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SequenceRNNOptions: { + value = new tflite::SequenceRNNOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_StridedSliceOptions: { + value = new tflite::StridedSliceOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ExpOptions: { + value = new tflite::ExpOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_TopKV2Options: { + value = new tflite::TopKV2OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SplitOptions: { + value = new tflite::SplitOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LogSoftmaxOptions: { + value = new tflite::LogSoftmaxOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_CastOptions: { + value = new tflite::CastOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_DequantizeOptions: { + value = new tflite::DequantizeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_MaximumMinimumOptions: { + value = new tflite::MaximumMinimumOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ArgMaxOptions: { + value = new tflite::ArgMaxOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LessOptions: { + value = new tflite::LessOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_NegOptions: { + value = new tflite::NegOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_PadV2Options: { + value = new tflite::PadV2OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_GreaterOptions: { + value = new tflite::GreaterOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_GreaterEqualOptions: { + value = new tflite::GreaterEqualOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LessEqualOptions: { + value = new tflite::LessEqualOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SelectOptions: { + value = new tflite::SelectOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SliceOptions: { + value = new tflite::SliceOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_TransposeConvOptions: { + value = new tflite::TransposeConvOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SparseToDenseOptions: { + value = new tflite::SparseToDenseOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_TileOptions: { + value = new tflite::TileOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ExpandDimsOptions: { + value = new tflite::ExpandDimsOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_EqualOptions: { + value = new tflite::EqualOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_NotEqualOptions: { + value = new tflite::NotEqualOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ShapeOptions: { + value = new tflite::ShapeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_PowOptions: { + value = new tflite::PowOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ArgMinOptions: { + value = new tflite::ArgMinOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_FakeQuantOptions: { + value = new tflite::FakeQuantOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_PackOptions: { + value = new tflite::PackOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LogicalOrOptions: { + value = new tflite::LogicalOrOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_OneHotOptions: { + value = new tflite::OneHotOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LogicalAndOptions: { + value = new tflite::LogicalAndOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LogicalNotOptions: { + value = new tflite::LogicalNotOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_UnpackOptions: { + value = new tflite::UnpackOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_FloorDivOptions: { + value = new tflite::FloorDivOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SquareOptions: { + value = new tflite::SquareOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ZerosLikeOptions: { + value = new tflite::ZerosLikeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_FillOptions: { + value = new tflite::FillOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_BidirectionalSequenceLSTMOptions: { + value = new tflite::BidirectionalSequenceLSTMOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_BidirectionalSequenceRNNOptions: { + value = new tflite::BidirectionalSequenceRNNOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_UnidirectionalSequenceLSTMOptions: { + value = new tflite::UnidirectionalSequenceLSTMOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_FloorModOptions: { + value = new tflite::FloorModOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_RangeOptions: { + value = new tflite::RangeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ResizeNearestNeighborOptions: { + value = new tflite::ResizeNearestNeighborOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_LeakyReluOptions: { + value = new tflite::LeakyReluOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SquaredDifferenceOptions: { + value = new tflite::SquaredDifferenceOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_MirrorPadOptions: { + value = new tflite::MirrorPadOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_AbsOptions: { + value = new tflite::AbsOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SplitVOptions: { + value = new tflite::SplitVOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_UniqueOptions: { + value = new tflite::UniqueOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ReverseV2Options: { + value = new tflite::ReverseV2OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_AddNOptions: { + value = new tflite::AddNOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_GatherNdOptions: { + value = new tflite::GatherNdOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_CosOptions: { + value = new tflite::CosOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_WhereOptions: { + value = new tflite::WhereOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_RankOptions: { + value = new tflite::RankOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ReverseSequenceOptions: { + value = new tflite::ReverseSequenceOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_MatrixDiagOptions: { + value = new tflite::MatrixDiagOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_QuantizeOptions: { + value = new tflite::QuantizeOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_MatrixSetDiagOptions: { + value = new tflite::MatrixSetDiagOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_HardSwishOptions: { + value = new tflite::HardSwishOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_IfOptions: { + value = new tflite::IfOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_WhileOptions: { + value = new tflite::WhileOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_DepthToSpaceOptions: { + value = new tflite::DepthToSpaceOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_NonMaxSuppressionV4Options: { + value = new tflite::NonMaxSuppressionV4OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_NonMaxSuppressionV5Options: { + value = new tflite::NonMaxSuppressionV5OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_ScatterNdOptions: { + value = new tflite::ScatterNdOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SelectV2Options: { + value = new tflite::SelectV2OptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_DensifyOptions: { + value = new tflite::DensifyOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_SegmentSumOptions: { + value = new tflite::SegmentSumOptionsT(*reinterpret_cast(u.value)); + break; + } + case BuiltinOptions_BatchMatMulOptions: { + value = new tflite::BatchMatMulOptionsT(*reinterpret_cast(u.value)); + break; + } + default: + break; + } +} + +inline void BuiltinOptionsUnion::Reset() { + switch (type) { + case BuiltinOptions_Conv2DOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_DepthwiseConv2DOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ConcatEmbeddingsOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LSHProjectionOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_Pool2DOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SVDFOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_RNNOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_FullyConnectedOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SoftmaxOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ConcatenationOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_AddOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_L2NormOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LocalResponseNormalizationOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LSTMOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ResizeBilinearOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_CallOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ReshapeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SkipGramOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SpaceToDepthOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_EmbeddingLookupSparseOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_MulOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_PadOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_GatherOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_BatchToSpaceNDOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SpaceToBatchNDOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_TransposeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ReducerOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SubOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_DivOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SqueezeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SequenceRNNOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_StridedSliceOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ExpOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_TopKV2Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SplitOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LogSoftmaxOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_CastOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_DequantizeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_MaximumMinimumOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ArgMaxOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LessOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_NegOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_PadV2Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_GreaterOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_GreaterEqualOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LessEqualOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SelectOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SliceOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_TransposeConvOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SparseToDenseOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_TileOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ExpandDimsOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_EqualOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_NotEqualOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ShapeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_PowOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ArgMinOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_FakeQuantOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_PackOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LogicalOrOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_OneHotOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LogicalAndOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LogicalNotOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_UnpackOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_FloorDivOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SquareOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ZerosLikeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_FillOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_BidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_BidirectionalSequenceRNNOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_UnidirectionalSequenceLSTMOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_FloorModOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_RangeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ResizeNearestNeighborOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_LeakyReluOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SquaredDifferenceOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_MirrorPadOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_AbsOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SplitVOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_UniqueOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ReverseV2Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_AddNOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_GatherNdOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_CosOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_WhereOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_RankOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ReverseSequenceOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_MatrixDiagOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_QuantizeOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_MatrixSetDiagOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_HardSwishOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_IfOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_WhileOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_DepthToSpaceOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_NonMaxSuppressionV4Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_NonMaxSuppressionV5Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_ScatterNdOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SelectV2Options: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_DensifyOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_SegmentSumOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + case BuiltinOptions_BatchMatMulOptions: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } + default: break; + } + value = nullptr; + type = BuiltinOptions_NONE; +} + +inline const tflite::Model *GetModel(const void *buf) { + return flatbuffers::GetRoot(buf); +} + +inline const tflite::Model *GetSizePrefixedModel(const void *buf) { + return flatbuffers::GetSizePrefixedRoot(buf); +} + +inline const char *ModelIdentifier() { + return "TFL3"; +} + +inline bool ModelBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier( + buf, ModelIdentifier()); +} + +inline bool VerifyModelBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(ModelIdentifier()); +} + +inline bool VerifySizePrefixedModelBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(ModelIdentifier()); +} + +inline const char *ModelExtension() { + return "tflite"; +} + +inline void FinishModelBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset root) { + fbb.Finish(root, ModelIdentifier()); +} + +inline void FinishSizePrefixedModelBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root, ModelIdentifier()); +} + +inline std::unique_ptr UnPackModel( + const void *buf, + const flatbuffers::resolver_function_t *res = nullptr) { + return std::unique_ptr(GetModel(buf)->UnPack(res)); +} + +inline std::unique_ptr UnPackSizePrefixedModel( + const void *buf, + const flatbuffers::resolver_function_t *res = nullptr) { + return std::unique_ptr(GetSizePrefixedModel(buf)->UnPack(res)); +} + +} // namespace tflite + +#endif // FLATBUFFERS_GENERATED_SCHEMA_TFLITE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/string_type.h b/TensorflowLiteMicro/tensorflow/lite/string_type.h new file mode 100644 index 0000000..f5a7f83 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/string_type.h @@ -0,0 +1,27 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +// Abstract string. We don't want even absl at this level. +#ifndef TENSORFLOW_LITE_STRING_TYPE_H_ +#define TENSORFLOW_LITE_STRING_TYPE_H_ + +#include + +namespace tflite { + +using std::string; + +} // namespace tflite + +#endif // TENSORFLOW_LITE_STRING_TYPE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/string_util.h b/TensorflowLiteMicro/tensorflow/lite/string_util.h new file mode 100644 index 0000000..2086f9b --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/string_util.h @@ -0,0 +1,109 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +// Util methods to read and write String tensors. +// String tensors are considered to be char tensor with protocol. +// [0, 3] 4 bytes: N, num of strings in the tensor in little endian. +// [(i+1)*4, (i+1)*4+3] 4 bytes: offset of i-th string in little endian. +// [(N+2)*4, (N+2)*4+3] 4 bytes: length of the whole char buffer. +// [offset(i), offset(i+1) - 1] : content of i-th string. +// Example of a string tensor: +// [ +// 2, 0, 0, 0, # 2 strings. +// 16, 0, 0, 0, # 0-th string starts from index 16. +// 18, 0, 0, 0, # 1-st string starts from index 18. +// 18, 0, 0, 0, # total length of array. +// 'A', 'B', # 0-th string [16..17]: "AB" +// ] # 1-th string, empty +// +// A typical usage: +// In op.Eval(context, node): +// DynamicBuffer buf; +// # Add string "AB" to tensor, string is stored in dynamic buffer. +// buf.AddString("AB", 2); +// # Write content of DynamicBuffer to tensor in format of string tensor +// # described above. +// buf.WriteToTensor(tensor, nullptr) + +#ifndef TENSORFLOW_LITE_STRING_UTIL_H_ +#define TENSORFLOW_LITE_STRING_UTIL_H_ + +#include + +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/string_type.h" + +namespace tflite { + +// Convenient structure to store string pointer and length. +typedef struct { + const char* str; + int len; +} StringRef; + +// DynamicBuffer holds temporary buffer that will be used to create a dynamic +// tensor. A typical usage is to initialize a DynamicBuffer object, fill in +// content and call CreateStringTensor in op.Eval(). +class DynamicBuffer { + public: + DynamicBuffer() : offset_({0}) {} + + // Add string to dynamic buffer by resizing the buffer and copying the data. + void AddString(const StringRef& string); + + // Add string to dynamic buffer by resizing the buffer and copying the data. + void AddString(const char* str, size_t len); + + // Join a list of string with separator, and add as a single string to the + // buffer. + void AddJoinedString(const std::vector& strings, char separator); + void AddJoinedString(const std::vector& strings, + StringRef separator); + + // Fill content into a buffer and returns the number of bytes stored. + // The function allocates space for the buffer but does NOT take ownership. + int WriteToBuffer(char** buffer); + + // String tensors are not generally supported on platforms w/ static memory. + // TODO(b/156130024): Remove this guard after removing header from TFLM deps. +#ifndef TF_LITE_STATIC_MEMORY + // Fill content into a string tensor, with the given new_shape. The new shape + // must match the number of strings in this object. Caller relinquishes + // ownership of new_shape. If 'new_shape' is nullptr, keep the tensor's + // existing shape. + void WriteToTensor(TfLiteTensor* tensor, TfLiteIntArray* new_shape); + + // Fill content into a string tensor. Set shape to {num_strings}. + void WriteToTensorAsVector(TfLiteTensor* tensor); +#endif // TF_LITE_STATIC_MEMORY + + private: + // Data buffer to store contents of strings, not including headers. + std::vector data_; + // Offset of the starting index of each string in data buffer. + std::vector offset_; +}; + +// Return num of strings in a String tensor. +int GetStringCount(const void* raw_buffer); +int GetStringCount(const TfLiteTensor* tensor); + +// Get String pointer and length of index-th string in tensor. +// NOTE: This will not create a copy of string data. +StringRef GetString(const void* raw_buffer, int string_index); +StringRef GetString(const TfLiteTensor* tensor, int string_index); +} // namespace tflite + +#endif // TENSORFLOW_LITE_STRING_UTIL_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/type_to_tflitetype.h b/TensorflowLiteMicro/tensorflow/lite/type_to_tflitetype.h new file mode 100644 index 0000000..a95b233 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/type_to_tflitetype.h @@ -0,0 +1,70 @@ +/* Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_TYPE_TO_TFLITETYPE_H_ +#define TENSORFLOW_LITE_TYPE_TO_TFLITETYPE_H_ + +// Arduino build defines abs as a macro here. That is invalid C++, and breaks +// libc++'s header, undefine it. +#ifdef abs +#undef abs +#endif + +#include +#include + +#include "tensorflow/lite/c/common.h" + +namespace tflite { + +// Map statically from a C++ type to a TfLiteType. Used in interpreter for +// safe casts. +// Example: +// typeToTfLiteType() -> kTfLiteBool +template +constexpr TfLiteType typeToTfLiteType() { + return kTfLiteNoType; +} +// Map from TfLiteType to the corresponding C++ type. +// Example: +// TfLiteTypeToType::Type -> bool +template +struct TfLiteTypeToType {}; // Specializations below + +// Template specialization for both typeToTfLiteType and TfLiteTypeToType. +#define MATCH_TYPE_AND_TFLITE_TYPE(CPP_TYPE, TFLITE_TYPE_ENUM) \ + template <> \ + constexpr TfLiteType typeToTfLiteType() { \ + return TFLITE_TYPE_ENUM; \ + } \ + template <> \ + struct TfLiteTypeToType { \ + using Type = CPP_TYPE; \ + } + +MATCH_TYPE_AND_TFLITE_TYPE(int, kTfLiteInt32); +MATCH_TYPE_AND_TFLITE_TYPE(int16_t, kTfLiteInt16); +MATCH_TYPE_AND_TFLITE_TYPE(int64_t, kTfLiteInt64); +MATCH_TYPE_AND_TFLITE_TYPE(float, kTfLiteFloat32); +MATCH_TYPE_AND_TFLITE_TYPE(unsigned char, kTfLiteUInt8); +MATCH_TYPE_AND_TFLITE_TYPE(int8_t, kTfLiteInt8); +MATCH_TYPE_AND_TFLITE_TYPE(bool, kTfLiteBool); +MATCH_TYPE_AND_TFLITE_TYPE(std::complex, kTfLiteComplex64); +MATCH_TYPE_AND_TFLITE_TYPE(std::complex, kTfLiteComplex128); +MATCH_TYPE_AND_TFLITE_TYPE(std::string, kTfLiteString); +MATCH_TYPE_AND_TFLITE_TYPE(TfLiteFloat16, kTfLiteFloat16); +MATCH_TYPE_AND_TFLITE_TYPE(double, kTfLiteFloat64); + +} // namespace tflite +#endif // TENSORFLOW_LITE_TYPE_TO_TFLITETYPE_H_ diff --git a/TensorflowLiteMicro/tensorflow/lite/version.h b/TensorflowLiteMicro/tensorflow/lite/version.h new file mode 100644 index 0000000..f667447 --- /dev/null +++ b/TensorflowLiteMicro/tensorflow/lite/version.h @@ -0,0 +1,29 @@ +/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_VERSION_H_ +#define TENSORFLOW_LITE_VERSION_H_ + +#include "tensorflow/core/public/version.h" + +// The version number of the Schema. Ideally all changes will be backward +// compatible. If that ever changes, we must ensure that version is the first +// entry in the new tflite root so that we can see that version is not 1. +#define TFLITE_SCHEMA_VERSION (3) + +// TensorFlow Lite Runtime version. +// This value is currently shared with that of TensorFlow. +#define TFLITE_VERSION_STRING TF_VERSION_STRING + +#endif // TENSORFLOW_LITE_VERSION_H_ diff --git a/TensorflowLiteMicro/third_party/SConscript b/TensorflowLiteMicro/third_party/SConscript new file mode 100644 index 0000000..4c815c4 --- /dev/null +++ b/TensorflowLiteMicro/third_party/SConscript @@ -0,0 +1,15 @@ +# RT-Thread building script for bridge + +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/base.h b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/base.h new file mode 100644 index 0000000..9557380 --- /dev/null +++ b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/base.h @@ -0,0 +1,398 @@ +#ifndef FLATBUFFERS_BASE_H_ +#define FLATBUFFERS_BASE_H_ + +// clang-format off + +// If activate should be declared and included first. +#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ + defined(_MSC_VER) && defined(_DEBUG) + // The _CRTDBG_MAP_ALLOC inside will replace + // calloc/free (etc) to its debug version using #define directives. + #define _CRTDBG_MAP_ALLOC + #include + #include + // Replace operator new by trace-enabled version. + #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) + #define new DEBUG_NEW +#endif + +#if !defined(FLATBUFFERS_ASSERT) +#include +#define FLATBUFFERS_ASSERT assert +#elif defined(FLATBUFFERS_ASSERT_INCLUDE) +// Include file with forward declaration +#include FLATBUFFERS_ASSERT_INCLUDE +#endif + +#ifndef ARDUINO +#include +#endif + +#include +#include +#include + +#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) + #include +#else + #include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _STLPORT_VERSION + #define FLATBUFFERS_CPP98_STL +#endif +#ifndef FLATBUFFERS_CPP98_STL + #include +#endif + +#include "flatbuffers/stl_emulation.h" + +#if defined(__ICCARM__) +#include +#endif + +// Note the __clang__ check is needed, because clang presents itself +// as an older GNUC compiler (4.2). +// Clang 3.3 and later implement all of the ISO C++ 2011 standard. +// Clang 3.4 and later implement all of the ISO C++ 2014 standard. +// http://clang.llvm.org/cxx_status.html + +// Note the MSVC value '__cplusplus' may be incorrect: +// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, +// indicating (erroneously!) that the compiler conformed to the C++98 Standard. +// This value should be correct starting from MSVC2017-15.7-Preview-3. +// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set. +// Workaround (for details see MSDN): +// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility. +// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch. + +#if defined(__GNUC__) && !defined(__clang__) + #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else + #define FLATBUFFERS_GCC 0 +#endif + +#if defined(__clang__) + #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#else + #define FLATBUFFERS_CLANG 0 +#endif + +/// @cond FLATBUFFERS_INTERNAL +#if __cplusplus <= 199711L && \ + (!defined(_MSC_VER) || _MSC_VER < 1600) && \ + (!defined(__GNUC__) || \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) + #error A C++11 compatible compiler with support for the auto typing is \ + required for FlatBuffers. + #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ +#endif + +#if !defined(__clang__) && \ + defined(__GNUC__) && \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) + // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr + // and constexpr keywords. Note the __clang__ check is needed, because clang + // presents itself as an older GNUC compiler. + #ifndef nullptr_t + const class nullptr_t { + public: + template inline operator T*() const { return 0; } + private: + void operator&() const; + } nullptr = {}; + #endif + #ifndef constexpr + #define constexpr const + #endif +#endif + +// The wire format uses a little endian encoding (since that's efficient for +// the common platforms). +#if defined(__s390x__) + #define FLATBUFFERS_LITTLEENDIAN 0 +#endif // __s390x__ +#if !defined(FLATBUFFERS_LITTLEENDIAN) + #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) + #if (defined(__BIG_ENDIAN__) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + #define FLATBUFFERS_LITTLEENDIAN 0 + #else + #define FLATBUFFERS_LITTLEENDIAN 1 + #endif // __BIG_ENDIAN__ + #elif defined(_MSC_VER) + #if defined(_M_PPC) + #define FLATBUFFERS_LITTLEENDIAN 0 + #else + #define FLATBUFFERS_LITTLEENDIAN 1 + #endif + #else + #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. + #endif +#endif // !defined(FLATBUFFERS_LITTLEENDIAN) + +#define FLATBUFFERS_VERSION_MAJOR 1 +#define FLATBUFFERS_VERSION_MINOR 12 +#define FLATBUFFERS_VERSION_REVISION 0 +#define FLATBUFFERS_STRING_EXPAND(X) #X +#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) +namespace flatbuffers { + // Returns version as string "MAJOR.MINOR.REVISION". + const char* FLATBUFFERS_VERSION(); +} + +#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ + defined(__clang__) + #define FLATBUFFERS_FINAL_CLASS final + #define FLATBUFFERS_OVERRIDE override + #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t +#else + #define FLATBUFFERS_FINAL_CLASS + #define FLATBUFFERS_OVERRIDE + #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE +#endif + +#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ + (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) + #define FLATBUFFERS_CONSTEXPR constexpr +#else + #define FLATBUFFERS_CONSTEXPR const +#endif + +#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ + (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) + #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR +#else + #define FLATBUFFERS_CONSTEXPR_CPP14 +#endif + +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ + (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ + defined(__clang__) + #define FLATBUFFERS_NOEXCEPT noexcept +#else + #define FLATBUFFERS_NOEXCEPT +#endif + +// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to +// private, so be sure to put it at the end or reset access mode explicitly. +#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ + defined(__clang__) + #define FLATBUFFERS_DELETE_FUNC(func) func = delete; +#else + #define FLATBUFFERS_DELETE_FUNC(func) private: func; +#endif + +#ifndef FLATBUFFERS_HAS_STRING_VIEW + // Only provide flatbuffers::string_view if __has_include can be used + // to detect a header that provides an implementation + #if defined(__has_include) + // Check for std::string_view (in c++17) + #if __has_include() && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) + #include + namespace flatbuffers { + typedef std::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + // Check for std::experimental::string_view (in c++14, compiler-dependent) + #elif __has_include() && (__cplusplus >= 201411) + #include + namespace flatbuffers { + typedef std::experimental::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + // Check for absl::string_view + #elif __has_include("absl/strings/string_view.h") + #include "absl/strings/string_view.h" + namespace flatbuffers { + typedef absl::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + #endif + #endif // __has_include +#endif // !FLATBUFFERS_HAS_STRING_VIEW + +#ifndef FLATBUFFERS_HAS_NEW_STRTOD + // Modern (C++11) strtod and strtof functions are available for use. + // 1) nan/inf strings as argument of strtod; + // 2) hex-float as argument of strtod/strtof. + #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ + (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ + (defined(__clang__)) + #define FLATBUFFERS_HAS_NEW_STRTOD 1 + #endif +#endif // !FLATBUFFERS_HAS_NEW_STRTOD + +#ifndef FLATBUFFERS_LOCALE_INDEPENDENT + // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}. + // They are part of the POSIX-2008 but not part of the C/C++ standard. + // GCC/Clang have definition (_XOPEN_SOURCE>=700) if POSIX-2008. + #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \ + (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE>=700))) + #define FLATBUFFERS_LOCALE_INDEPENDENT 1 + #else + #define FLATBUFFERS_LOCALE_INDEPENDENT 0 + #endif +#endif // !FLATBUFFERS_LOCALE_INDEPENDENT + +// Suppress Undefined Behavior Sanitizer (recoverable only). Usage: +// - __supress_ubsan__("undefined") +// - __supress_ubsan__("signed-integer-overflow") +#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) + #define __supress_ubsan__(type) __attribute__((no_sanitize(type))) +#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) + #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) +#else + #define __supress_ubsan__(type) +#endif + +// This is constexpr function used for checking compile-time constants. +// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. +template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { + return !!t; +} + +// Enable C++ attribute [[]] if std:c++17 or higher. +#if ((__cplusplus >= 201703L) \ + || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) + // All attributes unknown to an implementation are ignored without causing an error. + #define FLATBUFFERS_ATTRIBUTE(attr) [[attr]] + + #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] +#else + #define FLATBUFFERS_ATTRIBUTE(attr) + + #if FLATBUFFERS_CLANG >= 30800 + #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]] + #elif FLATBUFFERS_GCC >= 70300 + #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]] + #else + #define FLATBUFFERS_FALLTHROUGH() + #endif +#endif + +/// @endcond + +/// @file +namespace flatbuffers { + +/// @cond FLATBUFFERS_INTERNAL +// Our default offset / size type, 32bit on purpose on 64bit systems. +// Also, using a consistent offset type maintains compatibility of serialized +// offset values between 32bit and 64bit systems. +typedef uint32_t uoffset_t; + +// Signed offsets for references that can go in both directions. +typedef int32_t soffset_t; + +// Offset/index used in v-tables, can be changed to uint8_t in +// format forks to save a bit of space if desired. +typedef uint16_t voffset_t; + +typedef uintmax_t largest_scalar_t; + +// In 32bits, this evaluates to 2GB - 1 +#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) + +// We support aligning the contents of buffers up to this size. +#define FLATBUFFERS_MAX_ALIGNMENT 16 + +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4127) // C4127: conditional expression is constant +#endif + +template T EndianSwap(T t) { + #if defined(_MSC_VER) + #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort + #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong + #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 + #elif defined(__ICCARM__) + #define FLATBUFFERS_BYTESWAP16 __REV16 + #define FLATBUFFERS_BYTESWAP32 __REV + #define FLATBUFFERS_BYTESWAP64(x) \ + ((__REV(static_cast(x >> 32U))) | (static_cast(__REV(static_cast(x)))) << 32U) + #else + #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) + // __builtin_bswap16 was missing prior to GCC 4.8. + #define FLATBUFFERS_BYTESWAP16(x) \ + static_cast(__builtin_bswap32(static_cast(x) << 16)) + #else + #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 + #endif + #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 + #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 + #endif + if (sizeof(T) == 1) { // Compile-time if-then's. + return t; + } else if (sizeof(T) == 2) { + union { T t; uint16_t i; } u = { t }; + u.i = FLATBUFFERS_BYTESWAP16(u.i); + return u.t; + } else if (sizeof(T) == 4) { + union { T t; uint32_t i; } u = { t }; + u.i = FLATBUFFERS_BYTESWAP32(u.i); + return u.t; + } else if (sizeof(T) == 8) { + union { T t; uint64_t i; } u = { t }; + u.i = FLATBUFFERS_BYTESWAP64(u.i); + return u.t; + } else { + FLATBUFFERS_ASSERT(0); + return t; + } +} + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + +template T EndianScalar(T t) { + #if FLATBUFFERS_LITTLEENDIAN + return t; + #else + return EndianSwap(t); + #endif +} + +template +// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. +__supress_ubsan__("alignment") +T ReadScalar(const void *p) { + return EndianScalar(*reinterpret_cast(p)); +} + +template +// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. +__supress_ubsan__("alignment") +void WriteScalar(void *p, T t) { + *reinterpret_cast(p) = EndianScalar(t); +} + +template struct Offset; +template __supress_ubsan__("alignment") void WriteScalar(void *p, Offset t) { + *reinterpret_cast(p) = EndianScalar(t.o); +} + +// Computes how many bytes you'd have to pad to be able to write an +// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in +// memory). +__supress_ubsan__("unsigned-integer-overflow") +inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { + return ((~buf_size) + 1) & (scalar_size - 1); +} + +} // namespace flatbuffers +#endif // FLATBUFFERS_BASE_H_ diff --git a/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/flatbuffers.h b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/flatbuffers.h new file mode 100644 index 0000000..c4dc5bc --- /dev/null +++ b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/flatbuffers.h @@ -0,0 +1,2783 @@ +/* + * Copyright 2014 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLATBUFFERS_H_ +#define FLATBUFFERS_H_ + +#include "flatbuffers/base.h" + +#if defined(FLATBUFFERS_NAN_DEFAULTS) +# include +#endif + +namespace flatbuffers { +// Generic 'operator==' with conditional specialisations. +// T e - new value of a scalar field. +// T def - default of scalar (is known at compile-time). +template inline bool IsTheSameAs(T e, T def) { return e == def; } + +#if defined(FLATBUFFERS_NAN_DEFAULTS) && \ + defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) +// Like `operator==(e, def)` with weak NaN if T=(float|double). +template inline bool IsFloatTheSameAs(T e, T def) { + return (e == def) || ((def != def) && (e != e)); +} +template<> inline bool IsTheSameAs(float e, float def) { + return IsFloatTheSameAs(e, def); +} +template<> inline bool IsTheSameAs(double e, double def) { + return IsFloatTheSameAs(e, def); +} +#endif + +// Check 'v' is out of closed range [low; high]. +// Workaround for GCC warning [-Werror=type-limits]: +// comparison is always true due to limited range of data type. +template +inline bool IsOutRange(const T &v, const T &low, const T &high) { + return (v < low) || (high < v); +} + +// Check 'v' is in closed range [low; high]. +template +inline bool IsInRange(const T &v, const T &low, const T &high) { + return !IsOutRange(v, low, high); +} + +// Wrapper for uoffset_t to allow safe template specialization. +// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). +template struct Offset { + uoffset_t o; + Offset() : o(0) {} + Offset(uoffset_t _o) : o(_o) {} + Offset Union() const { return Offset(o); } + bool IsNull() const { return !o; } +}; + +inline void EndianCheck() { + int endiantest = 1; + // If this fails, see FLATBUFFERS_LITTLEENDIAN above. + FLATBUFFERS_ASSERT(*reinterpret_cast(&endiantest) == + FLATBUFFERS_LITTLEENDIAN); + (void)endiantest; +} + +template FLATBUFFERS_CONSTEXPR size_t AlignOf() { + // clang-format off + #ifdef _MSC_VER + return __alignof(T); + #else + #ifndef alignof + return __alignof__(T); + #else + return alignof(T); + #endif + #endif + // clang-format on +} + +// When we read serialized data from memory, in the case of most scalars, +// we want to just read T, but in the case of Offset, we want to actually +// perform the indirection and return a pointer. +// The template specialization below does just that. +// It is wrapped in a struct since function templates can't overload on the +// return type like this. +// The typedef is for the convenience of callers of this function +// (avoiding the need for a trailing return decltype) +template struct IndirectHelper { + typedef T return_type; + typedef T mutable_return_type; + static const size_t element_stride = sizeof(T); + static return_type Read(const uint8_t *p, uoffset_t i) { + return EndianScalar((reinterpret_cast(p))[i]); + } +}; +template struct IndirectHelper> { + typedef const T *return_type; + typedef T *mutable_return_type; + static const size_t element_stride = sizeof(uoffset_t); + static return_type Read(const uint8_t *p, uoffset_t i) { + p += i * sizeof(uoffset_t); + return reinterpret_cast(p + ReadScalar(p)); + } +}; +template struct IndirectHelper { + typedef const T *return_type; + typedef T *mutable_return_type; + static const size_t element_stride = sizeof(T); + static return_type Read(const uint8_t *p, uoffset_t i) { + return reinterpret_cast(p + i * sizeof(T)); + } +}; + +// An STL compatible iterator implementation for Vector below, effectively +// calling Get() for every element. +template struct VectorIterator { + typedef std::random_access_iterator_tag iterator_category; + typedef IT value_type; + typedef ptrdiff_t difference_type; + typedef IT *pointer; + typedef IT &reference; + + VectorIterator(const uint8_t *data, uoffset_t i) + : data_(data + IndirectHelper::element_stride * i) {} + VectorIterator(const VectorIterator &other) : data_(other.data_) {} + VectorIterator() : data_(nullptr) {} + + VectorIterator &operator=(const VectorIterator &other) { + data_ = other.data_; + return *this; + } + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + VectorIterator &operator=(VectorIterator &&other) { + data_ = other.data_; + return *this; + } + #endif // !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + bool operator==(const VectorIterator &other) const { + return data_ == other.data_; + } + + bool operator<(const VectorIterator &other) const { + return data_ < other.data_; + } + + bool operator!=(const VectorIterator &other) const { + return data_ != other.data_; + } + + difference_type operator-(const VectorIterator &other) const { + return (data_ - other.data_) / IndirectHelper::element_stride; + } + + IT operator*() const { return IndirectHelper::Read(data_, 0); } + + IT operator->() const { return IndirectHelper::Read(data_, 0); } + + VectorIterator &operator++() { + data_ += IndirectHelper::element_stride; + return *this; + } + + VectorIterator operator++(int) { + VectorIterator temp(data_, 0); + data_ += IndirectHelper::element_stride; + return temp; + } + + VectorIterator operator+(const uoffset_t &offset) const { + return VectorIterator(data_ + offset * IndirectHelper::element_stride, + 0); + } + + VectorIterator &operator+=(const uoffset_t &offset) { + data_ += offset * IndirectHelper::element_stride; + return *this; + } + + VectorIterator &operator--() { + data_ -= IndirectHelper::element_stride; + return *this; + } + + VectorIterator operator--(int) { + VectorIterator temp(data_, 0); + data_ -= IndirectHelper::element_stride; + return temp; + } + + VectorIterator operator-(const uoffset_t &offset) const { + return VectorIterator(data_ - offset * IndirectHelper::element_stride, + 0); + } + + VectorIterator &operator-=(const uoffset_t &offset) { + data_ -= offset * IndirectHelper::element_stride; + return *this; + } + + private: + const uint8_t *data_; +}; + +template +struct VectorReverseIterator : public std::reverse_iterator { + explicit VectorReverseIterator(Iterator iter) + : std::reverse_iterator(iter) {} + + typename Iterator::value_type operator*() const { + return *(std::reverse_iterator::current); + } + + typename Iterator::value_type operator->() const { + return *(std::reverse_iterator::current); + } +}; + +struct String; + +// This is used as a helper type for accessing vectors. +// Vector::data() assumes the vector elements start after the length field. +template class Vector { + public: + typedef VectorIterator::mutable_return_type> + iterator; + typedef VectorIterator::return_type> + const_iterator; + typedef VectorReverseIterator reverse_iterator; + typedef VectorReverseIterator const_reverse_iterator; + + uoffset_t size() const { return EndianScalar(length_); } + + // Deprecated: use size(). Here for backwards compatibility. + FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead")) + uoffset_t Length() const { return size(); } + + typedef typename IndirectHelper::return_type return_type; + typedef typename IndirectHelper::mutable_return_type mutable_return_type; + + return_type Get(uoffset_t i) const { + FLATBUFFERS_ASSERT(i < size()); + return IndirectHelper::Read(Data(), i); + } + + return_type operator[](uoffset_t i) const { return Get(i); } + + // If this is a Vector of enums, T will be its storage type, not the enum + // type. This function makes it convenient to retrieve value with enum + // type E. + template E GetEnum(uoffset_t i) const { + return static_cast(Get(i)); + } + + // If this a vector of unions, this does the cast for you. There's no check + // to make sure this is the right type! + template const U *GetAs(uoffset_t i) const { + return reinterpret_cast(Get(i)); + } + + // If this a vector of unions, this does the cast for you. There's no check + // to make sure this is actually a string! + const String *GetAsString(uoffset_t i) const { + return reinterpret_cast(Get(i)); + } + + const void *GetStructFromOffset(size_t o) const { + return reinterpret_cast(Data() + o); + } + + iterator begin() { return iterator(Data(), 0); } + const_iterator begin() const { return const_iterator(Data(), 0); } + + iterator end() { return iterator(Data(), size()); } + const_iterator end() const { return const_iterator(Data(), size()); } + + reverse_iterator rbegin() { return reverse_iterator(end() - 1); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end() - 1); + } + + reverse_iterator rend() { return reverse_iterator(begin() - 1); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin() - 1); + } + + const_iterator cbegin() const { return begin(); } + + const_iterator cend() const { return end(); } + + const_reverse_iterator crbegin() const { return rbegin(); } + + const_reverse_iterator crend() const { return rend(); } + + // Change elements if you have a non-const pointer to this object. + // Scalars only. See reflection.h, and the documentation. + void Mutate(uoffset_t i, const T &val) { + FLATBUFFERS_ASSERT(i < size()); + WriteScalar(data() + i, val); + } + + // Change an element of a vector of tables (or strings). + // "val" points to the new table/string, as you can obtain from + // e.g. reflection::AddFlatBuffer(). + void MutateOffset(uoffset_t i, const uint8_t *val) { + FLATBUFFERS_ASSERT(i < size()); + static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types"); + WriteScalar(data() + i, + static_cast(val - (Data() + i * sizeof(uoffset_t)))); + } + + // Get a mutable pointer to tables/strings inside this vector. + mutable_return_type GetMutableObject(uoffset_t i) const { + FLATBUFFERS_ASSERT(i < size()); + return const_cast(IndirectHelper::Read(Data(), i)); + } + + // The raw data in little endian format. Use with care. + const uint8_t *Data() const { + return reinterpret_cast(&length_ + 1); + } + + uint8_t *Data() { return reinterpret_cast(&length_ + 1); } + + // Similarly, but typed, much like std::vector::data + const T *data() const { return reinterpret_cast(Data()); } + T *data() { return reinterpret_cast(Data()); } + + template return_type LookupByKey(K key) const { + void *search_result = std::bsearch( + &key, Data(), size(), IndirectHelper::element_stride, KeyCompare); + + if (!search_result) { + return nullptr; // Key not found. + } + + const uint8_t *element = reinterpret_cast(search_result); + + return IndirectHelper::Read(element, 0); + } + + protected: + // This class is only used to access pre-existing data. Don't ever + // try to construct these manually. + Vector(); + + uoffset_t length_; + + private: + // This class is a pointer. Copying will therefore create an invalid object. + // Private and unimplemented copy constructor. + Vector(const Vector &); + Vector &operator=(const Vector &); + + template static int KeyCompare(const void *ap, const void *bp) { + const K *key = reinterpret_cast(ap); + const uint8_t *data = reinterpret_cast(bp); + auto table = IndirectHelper::Read(data, 0); + + // std::bsearch compares with the operands transposed, so we negate the + // result here. + return -table->KeyCompareWithValue(*key); + } +}; + +// Represent a vector much like the template above, but in this case we +// don't know what the element types are (used with reflection.h). +class VectorOfAny { + public: + uoffset_t size() const { return EndianScalar(length_); } + + const uint8_t *Data() const { + return reinterpret_cast(&length_ + 1); + } + uint8_t *Data() { return reinterpret_cast(&length_ + 1); } + + protected: + VectorOfAny(); + + uoffset_t length_; + + private: + VectorOfAny(const VectorOfAny &); + VectorOfAny &operator=(const VectorOfAny &); +}; + +#ifndef FLATBUFFERS_CPP98_STL +template +Vector> *VectorCast(Vector> *ptr) { + static_assert(std::is_base_of::value, "Unrelated types"); + return reinterpret_cast> *>(ptr); +} + +template +const Vector> *VectorCast(const Vector> *ptr) { + static_assert(std::is_base_of::value, "Unrelated types"); + return reinterpret_cast> *>(ptr); +} +#endif + +// Convenient helper function to get the length of any vector, regardless +// of whether it is null or not (the field is not set). +template static inline size_t VectorLength(const Vector *v) { + return v ? v->size() : 0; +} + +// This is used as a helper type for accessing arrays. +template class Array { + typedef + typename flatbuffers::integral_constant::value> + scalar_tag; + typedef + typename flatbuffers::conditional::type + IndirectHelperType; + + public: + typedef typename IndirectHelper::return_type return_type; + typedef VectorIterator const_iterator; + typedef VectorReverseIterator const_reverse_iterator; + + FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; } + + return_type Get(uoffset_t i) const { + FLATBUFFERS_ASSERT(i < size()); + return IndirectHelper::Read(Data(), i); + } + + return_type operator[](uoffset_t i) const { return Get(i); } + + // If this is a Vector of enums, T will be its storage type, not the enum + // type. This function makes it convenient to retrieve value with enum + // type E. + template E GetEnum(uoffset_t i) const { + return static_cast(Get(i)); + } + + const_iterator begin() const { return const_iterator(Data(), 0); } + const_iterator end() const { return const_iterator(Data(), size()); } + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator rend() const { return const_reverse_iterator(end()); } + + const_iterator cbegin() const { return begin(); } + const_iterator cend() const { return end(); } + + const_reverse_iterator crbegin() const { return rbegin(); } + const_reverse_iterator crend() const { return rend(); } + + // Get a mutable pointer to elements inside this array. + // This method used to mutate arrays of structs followed by a @p Mutate + // operation. For primitive types use @p Mutate directly. + // @warning Assignments and reads to/from the dereferenced pointer are not + // automatically converted to the correct endianness. + typename flatbuffers::conditional::type + GetMutablePointer(uoffset_t i) const { + FLATBUFFERS_ASSERT(i < size()); + return const_cast(&data()[i]); + } + + // Change elements if you have a non-const pointer to this object. + void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); } + + // The raw data in little endian format. Use with care. + const uint8_t *Data() const { return data_; } + + uint8_t *Data() { return data_; } + + // Similarly, but typed, much like std::vector::data + const T *data() const { return reinterpret_cast(Data()); } + T *data() { return reinterpret_cast(Data()); } + + protected: + void MutateImpl(flatbuffers::integral_constant, uoffset_t i, + const T &val) { + FLATBUFFERS_ASSERT(i < size()); + WriteScalar(data() + i, val); + } + + void MutateImpl(flatbuffers::integral_constant, uoffset_t i, + const T &val) { + *(GetMutablePointer(i)) = val; + } + + // This class is only used to access pre-existing data. Don't ever + // try to construct these manually. + // 'constexpr' allows us to use 'size()' at compile time. + // @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on + // a constructor. +#if defined(__cpp_constexpr) + constexpr Array(); +#else + Array(); +#endif + + uint8_t data_[length * sizeof(T)]; + + private: + // This class is a pointer. Copying will therefore create an invalid object. + // Private and unimplemented copy constructor. + Array(const Array &); + Array &operator=(const Array &); +}; + +// Specialization for Array[struct] with access using Offset pointer. +// This specialization used by idl_gen_text.cpp. +template class Array, length> { + static_assert(flatbuffers::is_same::value, "unexpected type T"); + + public: + typedef const void *return_type; + + const uint8_t *Data() const { return data_; } + + // Make idl_gen_text.cpp::PrintContainer happy. + return_type operator[](uoffset_t) const { + FLATBUFFERS_ASSERT(false); + return nullptr; + } + + private: + // This class is only used to access pre-existing data. + Array(); + Array(const Array &); + Array &operator=(const Array &); + + uint8_t data_[1]; +}; + +// Lexicographically compare two strings (possibly containing nulls), and +// return true if the first is less than the second. +static inline bool StringLessThan(const char *a_data, uoffset_t a_size, + const char *b_data, uoffset_t b_size) { + const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size)); + return cmp == 0 ? a_size < b_size : cmp < 0; +} + +struct String : public Vector { + const char *c_str() const { return reinterpret_cast(Data()); } + std::string str() const { return std::string(c_str(), size()); } + + // clang-format off + #ifdef FLATBUFFERS_HAS_STRING_VIEW + flatbuffers::string_view string_view() const { + return flatbuffers::string_view(c_str(), size()); + } + #endif // FLATBUFFERS_HAS_STRING_VIEW + // clang-format on + + bool operator<(const String &o) const { + return StringLessThan(this->data(), this->size(), o.data(), o.size()); + } +}; + +// Convenience function to get std::string from a String returning an empty +// string on null pointer. +static inline std::string GetString(const String *str) { + return str ? str->str() : ""; +} + +// Convenience function to get char* from a String returning an empty string on +// null pointer. +static inline const char *GetCstring(const String *str) { + return str ? str->c_str() : ""; +} + +// Allocator interface. This is flatbuffers-specific and meant only for +// `vector_downward` usage. +class Allocator { + public: + virtual ~Allocator() {} + + // Allocate `size` bytes of memory. + virtual uint8_t *allocate(size_t size) = 0; + + // Deallocate `size` bytes of memory at `p` allocated by this allocator. + virtual void deallocate(uint8_t *p, size_t size) = 0; + + // Reallocate `new_size` bytes of memory, replacing the old region of size + // `old_size` at `p`. In contrast to a normal realloc, this grows downwards, + // and is intended specifcally for `vector_downward` use. + // `in_use_back` and `in_use_front` indicate how much of `old_size` is + // actually in use at each end, and needs to be copied. + virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size, + size_t new_size, size_t in_use_back, + size_t in_use_front) { + FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows + uint8_t *new_p = allocate(new_size); + memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, + in_use_front); + deallocate(old_p, old_size); + return new_p; + } + + protected: + // Called by `reallocate_downward` to copy memory from `old_p` of `old_size` + // to `new_p` of `new_size`. Only memory of size `in_use_front` and + // `in_use_back` will be copied from the front and back of the old memory + // allocation. + void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p, + size_t new_size, size_t in_use_back, + size_t in_use_front) { + memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, + in_use_back); + memcpy(new_p, old_p, in_use_front); + } +}; + +// DefaultAllocator uses new/delete to allocate memory regions +class DefaultAllocator : public Allocator { + public: + uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE { + return new uint8_t[size]; + } + + void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; } + + static void dealloc(void *p, size_t) { delete[] static_cast(p); } +}; + +// These functions allow for a null allocator to mean use the default allocator, +// as used by DetachedBuffer and vector_downward below. +// This is to avoid having a statically or dynamically allocated default +// allocator, or having to move it between the classes that may own it. +inline uint8_t *Allocate(Allocator *allocator, size_t size) { + return allocator ? allocator->allocate(size) + : DefaultAllocator().allocate(size); +} + +inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) { + if (allocator) + allocator->deallocate(p, size); + else + DefaultAllocator().deallocate(p, size); +} + +inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p, + size_t old_size, size_t new_size, + size_t in_use_back, size_t in_use_front) { + return allocator ? allocator->reallocate_downward(old_p, old_size, new_size, + in_use_back, in_use_front) + : DefaultAllocator().reallocate_downward( + old_p, old_size, new_size, in_use_back, in_use_front); +} + +// DetachedBuffer is a finished flatbuffer memory region, detached from its +// builder. The original memory region and allocator are also stored so that +// the DetachedBuffer can manage the memory lifetime. +class DetachedBuffer { + public: + DetachedBuffer() + : allocator_(nullptr), + own_allocator_(false), + buf_(nullptr), + reserved_(0), + cur_(nullptr), + size_(0) {} + + DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf, + size_t reserved, uint8_t *cur, size_t sz) + : allocator_(allocator), + own_allocator_(own_allocator), + buf_(buf), + reserved_(reserved), + cur_(cur), + size_(sz) {} + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + DetachedBuffer(DetachedBuffer &&other) + : allocator_(other.allocator_), + own_allocator_(other.own_allocator_), + buf_(other.buf_), + reserved_(other.reserved_), + cur_(other.cur_), + size_(other.size_) { + other.reset(); + } + // clang-format off + #endif // !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + DetachedBuffer &operator=(DetachedBuffer &&other) { + if (this == &other) return *this; + + destroy(); + + allocator_ = other.allocator_; + own_allocator_ = other.own_allocator_; + buf_ = other.buf_; + reserved_ = other.reserved_; + cur_ = other.cur_; + size_ = other.size_; + + other.reset(); + + return *this; + } + // clang-format off + #endif // !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + ~DetachedBuffer() { destroy(); } + + const uint8_t *data() const { return cur_; } + + uint8_t *data() { return cur_; } + + size_t size() const { return size_; } + + // clang-format off + #if 0 // disabled for now due to the ordering of classes in this header + template + bool Verify() const { + Verifier verifier(data(), size()); + return verifier.Verify(nullptr); + } + + template + const T* GetRoot() const { + return flatbuffers::GetRoot(data()); + } + + template + T* GetRoot() { + return flatbuffers::GetRoot(data()); + } + #endif + // clang-format on + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + // These may change access mode, leave these at end of public section + FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other)) + FLATBUFFERS_DELETE_FUNC( + DetachedBuffer &operator=(const DetachedBuffer &other)) + // clang-format off + #endif // !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + protected: + Allocator *allocator_; + bool own_allocator_; + uint8_t *buf_; + size_t reserved_; + uint8_t *cur_; + size_t size_; + + inline void destroy() { + if (buf_) Deallocate(allocator_, buf_, reserved_); + if (own_allocator_ && allocator_) { delete allocator_; } + reset(); + } + + inline void reset() { + allocator_ = nullptr; + own_allocator_ = false; + buf_ = nullptr; + reserved_ = 0; + cur_ = nullptr; + size_ = 0; + } +}; + +// This is a minimal replication of std::vector functionality, +// except growing from higher to lower addresses. i.e push_back() inserts data +// in the lowest address in the vector. +// Since this vector leaves the lower part unused, we support a "scratch-pad" +// that can be stored there for temporary data, to share the allocated space. +// Essentially, this supports 2 std::vectors in a single buffer. +class vector_downward { + public: + explicit vector_downward(size_t initial_size, Allocator *allocator, + bool own_allocator, size_t buffer_minalign) + : allocator_(allocator), + own_allocator_(own_allocator), + initial_size_(initial_size), + buffer_minalign_(buffer_minalign), + reserved_(0), + buf_(nullptr), + cur_(nullptr), + scratch_(nullptr) {} + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + vector_downward(vector_downward &&other) + #else + vector_downward(vector_downward &other) + #endif // defined(FLATBUFFERS_CPP98_STL) + // clang-format on + : allocator_(other.allocator_), + own_allocator_(other.own_allocator_), + initial_size_(other.initial_size_), + buffer_minalign_(other.buffer_minalign_), + reserved_(other.reserved_), + buf_(other.buf_), + cur_(other.cur_), + scratch_(other.scratch_) { + // No change in other.allocator_ + // No change in other.initial_size_ + // No change in other.buffer_minalign_ + other.own_allocator_ = false; + other.reserved_ = 0; + other.buf_ = nullptr; + other.cur_ = nullptr; + other.scratch_ = nullptr; + } + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + vector_downward &operator=(vector_downward &&other) { + // Move construct a temporary and swap idiom + vector_downward temp(std::move(other)); + swap(temp); + return *this; + } + // clang-format off + #endif // defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + ~vector_downward() { + clear_buffer(); + clear_allocator(); + } + + void reset() { + clear_buffer(); + clear(); + } + + void clear() { + if (buf_) { + cur_ = buf_ + reserved_; + } else { + reserved_ = 0; + cur_ = nullptr; + } + clear_scratch(); + } + + void clear_scratch() { scratch_ = buf_; } + + void clear_allocator() { + if (own_allocator_ && allocator_) { delete allocator_; } + allocator_ = nullptr; + own_allocator_ = false; + } + + void clear_buffer() { + if (buf_) Deallocate(allocator_, buf_, reserved_); + buf_ = nullptr; + } + + // Relinquish the pointer to the caller. + uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) { + auto *buf = buf_; + allocated_bytes = reserved_; + offset = static_cast(cur_ - buf_); + + // release_raw only relinquishes the buffer ownership. + // Does not deallocate or reset the allocator. Destructor will do that. + buf_ = nullptr; + clear(); + return buf; + } + + // Relinquish the pointer to the caller. + DetachedBuffer release() { + // allocator ownership (if any) is transferred to DetachedBuffer. + DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_, + size()); + if (own_allocator_) { + allocator_ = nullptr; + own_allocator_ = false; + } + buf_ = nullptr; + clear(); + return fb; + } + + size_t ensure_space(size_t len) { + FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); + if (len > static_cast(cur_ - scratch_)) { reallocate(len); } + // Beyond this, signed offsets may not have enough range: + // (FlatBuffers > 2GB not supported). + FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE); + return len; + } + + inline uint8_t *make_space(size_t len) { + size_t space = ensure_space(len); + cur_ -= space; + return cur_; + } + + // Returns nullptr if using the DefaultAllocator. + Allocator *get_custom_allocator() { return allocator_; } + + uoffset_t size() const { + return static_cast(reserved_ - (cur_ - buf_)); + } + + uoffset_t scratch_size() const { + return static_cast(scratch_ - buf_); + } + + size_t capacity() const { return reserved_; } + + uint8_t *data() const { + FLATBUFFERS_ASSERT(cur_); + return cur_; + } + + uint8_t *scratch_data() const { + FLATBUFFERS_ASSERT(buf_); + return buf_; + } + + uint8_t *scratch_end() const { + FLATBUFFERS_ASSERT(scratch_); + return scratch_; + } + + uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; } + + void push(const uint8_t *bytes, size_t num) { + if (num > 0) { memcpy(make_space(num), bytes, num); } + } + + // Specialized version of push() that avoids memcpy call for small data. + template void push_small(const T &little_endian_t) { + make_space(sizeof(T)); + *reinterpret_cast(cur_) = little_endian_t; + } + + template void scratch_push_small(const T &t) { + ensure_space(sizeof(T)); + *reinterpret_cast(scratch_) = t; + scratch_ += sizeof(T); + } + + // fill() is most frequently called with small byte counts (<= 4), + // which is why we're using loops rather than calling memset. + void fill(size_t zero_pad_bytes) { + make_space(zero_pad_bytes); + for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0; + } + + // Version for when we know the size is larger. + // Precondition: zero_pad_bytes > 0 + void fill_big(size_t zero_pad_bytes) { + memset(make_space(zero_pad_bytes), 0, zero_pad_bytes); + } + + void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; } + void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; } + + void swap(vector_downward &other) { + using std::swap; + swap(allocator_, other.allocator_); + swap(own_allocator_, other.own_allocator_); + swap(initial_size_, other.initial_size_); + swap(buffer_minalign_, other.buffer_minalign_); + swap(reserved_, other.reserved_); + swap(buf_, other.buf_); + swap(cur_, other.cur_); + swap(scratch_, other.scratch_); + } + + void swap_allocator(vector_downward &other) { + using std::swap; + swap(allocator_, other.allocator_); + swap(own_allocator_, other.own_allocator_); + } + + private: + // You shouldn't really be copying instances of this class. + FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &)) + FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &)) + + Allocator *allocator_; + bool own_allocator_; + size_t initial_size_; + size_t buffer_minalign_; + size_t reserved_; + uint8_t *buf_; + uint8_t *cur_; // Points at location between empty (below) and used (above). + uint8_t *scratch_; // Points to the end of the scratchpad in use. + + void reallocate(size_t len) { + auto old_reserved = reserved_; + auto old_size = size(); + auto old_scratch_size = scratch_size(); + reserved_ += + (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_); + reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); + if (buf_) { + buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, + old_size, old_scratch_size); + } else { + buf_ = Allocate(allocator_, reserved_); + } + cur_ = buf_ + reserved_ - old_size; + scratch_ = buf_ + old_scratch_size; + } +}; + +// Converts a Field ID to a virtual table offset. +inline voffset_t FieldIndexToOffset(voffset_t field_id) { + // Should correspond to what EndTable() below builds up. + const int fixed_fields = 2; // Vtable size and Object Size. + return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); +} + +template +const T *data(const std::vector &v) { + // Eventually the returned pointer gets passed down to memcpy, so + // we need it to be non-null to avoid undefined behavior. + static uint8_t t; + return v.empty() ? reinterpret_cast(&t) : &v.front(); +} +template T *data(std::vector &v) { + // Eventually the returned pointer gets passed down to memcpy, so + // we need it to be non-null to avoid undefined behavior. + static uint8_t t; + return v.empty() ? reinterpret_cast(&t) : &v.front(); +} + +/// @endcond + +/// @addtogroup flatbuffers_cpp_api +/// @{ +/// @class FlatBufferBuilder +/// @brief Helper class to hold data needed in creation of a FlatBuffer. +/// To serialize data, you typically call one of the `Create*()` functions in +/// the generated code, which in turn call a sequence of `StartTable`/ +/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ +/// `CreateVector` functions. Do this is depth-first order to build up a tree to +/// the root. `Finish()` wraps up the buffer ready for transport. +class FlatBufferBuilder { + public: + /// @brief Default constructor for FlatBufferBuilder. + /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults + /// to `1024`. + /// @param[in] allocator An `Allocator` to use. If null will use + /// `DefaultAllocator`. + /// @param[in] own_allocator Whether the builder/vector should own the + /// allocator. Defaults to / `false`. + /// @param[in] buffer_minalign Force the buffer to be aligned to the given + /// minimum alignment upon reallocation. Only needed if you intend to store + /// types with custom alignment AND you wish to read the buffer in-place + /// directly after creation. + explicit FlatBufferBuilder( + size_t initial_size = 1024, Allocator *allocator = nullptr, + bool own_allocator = false, + size_t buffer_minalign = AlignOf()) + : buf_(initial_size, allocator, own_allocator, buffer_minalign), + num_field_loc(0), + max_voffset_(0), + nested(false), + finished(false), + minalign_(1), + force_defaults_(false), + dedup_vtables_(true), + string_pool(nullptr) { + EndianCheck(); + } + + // clang-format off + /// @brief Move constructor for FlatBufferBuilder. + #if !defined(FLATBUFFERS_CPP98_STL) + FlatBufferBuilder(FlatBufferBuilder &&other) + #else + FlatBufferBuilder(FlatBufferBuilder &other) + #endif // #if !defined(FLATBUFFERS_CPP98_STL) + : buf_(1024, nullptr, false, AlignOf()), + num_field_loc(0), + max_voffset_(0), + nested(false), + finished(false), + minalign_(1), + force_defaults_(false), + dedup_vtables_(true), + string_pool(nullptr) { + EndianCheck(); + // Default construct and swap idiom. + // Lack of delegating constructors in vs2010 makes it more verbose than needed. + Swap(other); + } + // clang-format on + + // clang-format off + #if !defined(FLATBUFFERS_CPP98_STL) + // clang-format on + /// @brief Move assignment operator for FlatBufferBuilder. + FlatBufferBuilder &operator=(FlatBufferBuilder &&other) { + // Move construct a temporary and swap idiom + FlatBufferBuilder temp(std::move(other)); + Swap(temp); + return *this; + } + // clang-format off + #endif // defined(FLATBUFFERS_CPP98_STL) + // clang-format on + + void Swap(FlatBufferBuilder &other) { + using std::swap; + buf_.swap(other.buf_); + swap(num_field_loc, other.num_field_loc); + swap(max_voffset_, other.max_voffset_); + swap(nested, other.nested); + swap(finished, other.finished); + swap(minalign_, other.minalign_); + swap(force_defaults_, other.force_defaults_); + swap(dedup_vtables_, other.dedup_vtables_); + swap(string_pool, other.string_pool); + } + + ~FlatBufferBuilder() { + if (string_pool) delete string_pool; + } + + void Reset() { + Clear(); // clear builder state + buf_.reset(); // deallocate buffer + } + + /// @brief Reset all the state in this FlatBufferBuilder so it can be reused + /// to construct another buffer. + void Clear() { + ClearOffsets(); + buf_.clear(); + nested = false; + finished = false; + minalign_ = 1; + if (string_pool) string_pool->clear(); + } + + /// @brief The current size of the serialized buffer, counting from the end. + /// @return Returns an `uoffset_t` with the current size of the buffer. + uoffset_t GetSize() const { return buf_.size(); } + + /// @brief Get the serialized buffer (after you call `Finish()`). + /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the + /// buffer. + uint8_t *GetBufferPointer() const { + Finished(); + return buf_.data(); + } + + /// @brief Get a pointer to an unfinished buffer. + /// @return Returns a `uint8_t` pointer to the unfinished buffer. + uint8_t *GetCurrentBufferPointer() const { return buf_.data(); } + + /// @brief Get the released pointer to the serialized buffer. + /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! + /// @return A `FlatBuffer` that owns the buffer and its allocator and + /// behaves similar to a `unique_ptr` with a deleter. + FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) + DetachedBuffer ReleaseBufferPointer() { + Finished(); + return buf_.release(); + } + + /// @brief Get the released DetachedBuffer. + /// @return A `DetachedBuffer` that owns the buffer and its allocator. + DetachedBuffer Release() { + Finished(); + return buf_.release(); + } + + /// @brief Get the released pointer to the serialized buffer. + /// @param size The size of the memory block containing + /// the serialized `FlatBuffer`. + /// @param offset The offset from the released pointer where the finished + /// `FlatBuffer` starts. + /// @return A raw pointer to the start of the memory block containing + /// the serialized `FlatBuffer`. + /// @remark If the allocator is owned, it gets deleted when the destructor is + /// called.. + uint8_t *ReleaseRaw(size_t &size, size_t &offset) { + Finished(); + return buf_.release_raw(size, offset); + } + + /// @brief get the minimum alignment this buffer needs to be accessed + /// properly. This is only known once all elements have been written (after + /// you call Finish()). You can use this information if you need to embed + /// a FlatBuffer in some other buffer, such that you can later read it + /// without first having to copy it into its own buffer. + size_t GetBufferMinAlignment() { + Finished(); + return minalign_; + } + + /// @cond FLATBUFFERS_INTERNAL + void Finished() const { + // If you get this assert, you're attempting to get access a buffer + // which hasn't been finished yet. Be sure to call + // FlatBufferBuilder::Finish with your root table. + // If you really need to access an unfinished buffer, call + // GetCurrentBufferPointer instead. + FLATBUFFERS_ASSERT(finished); + } + /// @endcond + + /// @brief In order to save space, fields that are set to their default value + /// don't get serialized into the buffer. + /// @param[in] fd When set to `true`, always serializes default values that + /// are set. Optional fields which are not set explicitly, will still not be + /// serialized. + void ForceDefaults(bool fd) { force_defaults_ = fd; } + + /// @brief By default vtables are deduped in order to save space. + /// @param[in] dedup When set to `true`, dedup vtables. + void DedupVtables(bool dedup) { dedup_vtables_ = dedup; } + + /// @cond FLATBUFFERS_INTERNAL + void Pad(size_t num_bytes) { buf_.fill(num_bytes); } + + void TrackMinAlign(size_t elem_size) { + if (elem_size > minalign_) minalign_ = elem_size; + } + + void Align(size_t elem_size) { + TrackMinAlign(elem_size); + buf_.fill(PaddingBytes(buf_.size(), elem_size)); + } + + void PushFlatBuffer(const uint8_t *bytes, size_t size) { + PushBytes(bytes, size); + finished = true; + } + + void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); } + + void PopBytes(size_t amount) { buf_.pop(amount); } + + template void AssertScalarT() { + // The code assumes power of 2 sizes and endian-swap-ability. + static_assert(flatbuffers::is_scalar::value, "T must be a scalar type"); + } + + // Write a single aligned scalar to the buffer + template uoffset_t PushElement(T element) { + AssertScalarT(); + T litle_endian_element = EndianScalar(element); + Align(sizeof(T)); + buf_.push_small(litle_endian_element); + return GetSize(); + } + + template uoffset_t PushElement(Offset off) { + // Special case for offsets: see ReferTo below. + return PushElement(ReferTo(off.o)); + } + + // When writing fields, we track where they are, so we can create correct + // vtables later. + void TrackField(voffset_t field, uoffset_t off) { + FieldLoc fl = { off, field }; + buf_.scratch_push_small(fl); + num_field_loc++; + max_voffset_ = (std::max)(max_voffset_, field); + } + + // Like PushElement, but additionally tracks the field this represents. + template void AddElement(voffset_t field, T e, T def) { + // We don't serialize values equal to the default. + if (IsTheSameAs(e, def) && !force_defaults_) return; + auto off = PushElement(e); + TrackField(field, off); + } + + template void AddOffset(voffset_t field, Offset off) { + if (off.IsNull()) return; // Don't store. + AddElement(field, ReferTo(off.o), static_cast(0)); + } + + template void AddStruct(voffset_t field, const T *structptr) { + if (!structptr) return; // Default, don't store. + Align(AlignOf()); + buf_.push_small(*structptr); + TrackField(field, GetSize()); + } + + void AddStructOffset(voffset_t field, uoffset_t off) { + TrackField(field, off); + } + + // Offsets initially are relative to the end of the buffer (downwards). + // This function converts them to be relative to the current location + // in the buffer (when stored here), pointing upwards. + uoffset_t ReferTo(uoffset_t off) { + // Align to ensure GetSize() below is correct. + Align(sizeof(uoffset_t)); + // Offset must refer to something already in buffer. + FLATBUFFERS_ASSERT(off && off <= GetSize()); + return GetSize() - off + static_cast(sizeof(uoffset_t)); + } + + void NotNested() { + // If you hit this, you're trying to construct a Table/Vector/String + // during the construction of its parent table (between the MyTableBuilder + // and table.Finish(). + // Move the creation of these sub-objects to above the MyTableBuilder to + // not get this assert. + // Ignoring this assert may appear to work in simple cases, but the reason + // it is here is that storing objects in-line may cause vtable offsets + // to not fit anymore. It also leads to vtable duplication. + FLATBUFFERS_ASSERT(!nested); + // If you hit this, fields were added outside the scope of a table. + FLATBUFFERS_ASSERT(!num_field_loc); + } + + // From generated code (or from the parser), we call StartTable/EndTable + // with a sequence of AddElement calls in between. + uoffset_t StartTable() { + NotNested(); + nested = true; + return GetSize(); + } + + // This finishes one serialized object by generating the vtable if it's a + // table, comparing it against existing vtables, and writing the + // resulting vtable offset. + uoffset_t EndTable(uoffset_t start) { + // If you get this assert, a corresponding StartTable wasn't called. + FLATBUFFERS_ASSERT(nested); + // Write the vtable offset, which is the start of any Table. + // We fill it's value later. + auto vtableoffsetloc = PushElement(0); + // Write a vtable, which consists entirely of voffset_t elements. + // It starts with the number of offsets, followed by a type id, followed + // by the offsets themselves. In reverse: + // Include space for the last offset and ensure empty tables have a + // minimum size. + max_voffset_ = + (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), + FieldIndexToOffset(0)); + buf_.fill_big(max_voffset_); + auto table_object_size = vtableoffsetloc - start; + // Vtable use 16bit offsets. + FLATBUFFERS_ASSERT(table_object_size < 0x10000); + WriteScalar(buf_.data() + sizeof(voffset_t), + static_cast(table_object_size)); + WriteScalar(buf_.data(), max_voffset_); + // Write the offsets into the table + for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); + it < buf_.scratch_end(); it += sizeof(FieldLoc)) { + auto field_location = reinterpret_cast(it); + auto pos = static_cast(vtableoffsetloc - field_location->off); + // If this asserts, it means you've set a field twice. + FLATBUFFERS_ASSERT( + !ReadScalar(buf_.data() + field_location->id)); + WriteScalar(buf_.data() + field_location->id, pos); + } + ClearOffsets(); + auto vt1 = reinterpret_cast(buf_.data()); + auto vt1_size = ReadScalar(vt1); + auto vt_use = GetSize(); + // See if we already have generated a vtable with this exact same + // layout before. If so, make it point to the old one, remove this one. + if (dedup_vtables_) { + for (auto it = buf_.scratch_data(); it < buf_.scratch_end(); + it += sizeof(uoffset_t)) { + auto vt_offset_ptr = reinterpret_cast(it); + auto vt2 = reinterpret_cast(buf_.data_at(*vt_offset_ptr)); + auto vt2_size = ReadScalar(vt2); + if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; + vt_use = *vt_offset_ptr; + buf_.pop(GetSize() - vtableoffsetloc); + break; + } + } + // If this is a new vtable, remember it. + if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); } + // Fill the vtable offset we created above. + // The offset points from the beginning of the object to where the + // vtable is stored. + // Offsets default direction is downward in memory for future format + // flexibility (storing all vtables at the start of the file). + WriteScalar(buf_.data_at(vtableoffsetloc), + static_cast(vt_use) - + static_cast(vtableoffsetloc)); + + nested = false; + return vtableoffsetloc; + } + + FLATBUFFERS_ATTRIBUTE(deprecated("call the version above instead")) + uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) { + return EndTable(start); + } + + // This checks a required field has been set in a given table that has + // just been constructed. + template void Required(Offset table, voffset_t field); + + uoffset_t StartStruct(size_t alignment) { + Align(alignment); + return GetSize(); + } + + uoffset_t EndStruct() { return GetSize(); } + + void ClearOffsets() { + buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); + num_field_loc = 0; + max_voffset_ = 0; + } + + // Aligns such that when "len" bytes are written, an object can be written + // after it with "alignment" without padding. + void PreAlign(size_t len, size_t alignment) { + TrackMinAlign(alignment); + buf_.fill(PaddingBytes(GetSize() + len, alignment)); + } + template void PreAlign(size_t len) { + AssertScalarT(); + PreAlign(len, sizeof(T)); + } + /// @endcond + + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const char pointer to the data to be stored as a string. + /// @param[in] len The number of bytes that should be stored from `str`. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(const char *str, size_t len) { + NotNested(); + PreAlign(len + 1); // Always 0-terminated. + buf_.fill(1); + PushBytes(reinterpret_cast(str), len); + PushElement(static_cast(len)); + return Offset(GetSize()); + } + + /// @brief Store a string in the buffer, which is null-terminated. + /// @param[in] str A const char pointer to a C-string to add to the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(const char *str) { + return CreateString(str, strlen(str)); + } + + /// @brief Store a string in the buffer, which is null-terminated. + /// @param[in] str A char pointer to a C-string to add to the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(char *str) { + return CreateString(str, strlen(str)); + } + + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const reference to a std::string to store in the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(const std::string &str) { + return CreateString(str.c_str(), str.length()); + } + + // clang-format off + #ifdef FLATBUFFERS_HAS_STRING_VIEW + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const string_view to copy in to the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(flatbuffers::string_view str) { + return CreateString(str.data(), str.size()); + } + #endif // FLATBUFFERS_HAS_STRING_VIEW + // clang-format on + + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const pointer to a `String` struct to add to the buffer. + /// @return Returns the offset in the buffer where the string starts + Offset CreateString(const String *str) { + return str ? CreateString(str->c_str(), str->size()) : 0; + } + + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const reference to a std::string like type with support + /// of T::c_str() and T::length() to store in the buffer. + /// @return Returns the offset in the buffer where the string starts. + template Offset CreateString(const T &str) { + return CreateString(str.c_str(), str.length()); + } + + /// @brief Store a string in the buffer, which can contain any binary data. + /// If a string with this exact contents has already been serialized before, + /// instead simply returns the offset of the existing string. + /// @param[in] str A const char pointer to the data to be stored as a string. + /// @param[in] len The number of bytes that should be stored from `str`. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateSharedString(const char *str, size_t len) { + if (!string_pool) + string_pool = new StringOffsetMap(StringOffsetCompare(buf_)); + auto size_before_string = buf_.size(); + // Must first serialize the string, since the set is all offsets into + // buffer. + auto off = CreateString(str, len); + auto it = string_pool->find(off); + // If it exists we reuse existing serialized data! + if (it != string_pool->end()) { + // We can remove the string we serialized. + buf_.pop(buf_.size() - size_before_string); + return *it; + } + // Record this string for future use. + string_pool->insert(off); + return off; + } + + /// @brief Store a string in the buffer, which null-terminated. + /// If a string with this exact contents has already been serialized before, + /// instead simply returns the offset of the existing string. + /// @param[in] str A const char pointer to a C-string to add to the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateSharedString(const char *str) { + return CreateSharedString(str, strlen(str)); + } + + /// @brief Store a string in the buffer, which can contain any binary data. + /// If a string with this exact contents has already been serialized before, + /// instead simply returns the offset of the existing string. + /// @param[in] str A const reference to a std::string to store in the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateSharedString(const std::string &str) { + return CreateSharedString(str.c_str(), str.length()); + } + + /// @brief Store a string in the buffer, which can contain any binary data. + /// If a string with this exact contents has already been serialized before, + /// instead simply returns the offset of the existing string. + /// @param[in] str A const pointer to a `String` struct to add to the buffer. + /// @return Returns the offset in the buffer where the string starts + Offset CreateSharedString(const String *str) { + return CreateSharedString(str->c_str(), str->size()); + } + + /// @cond FLATBUFFERS_INTERNAL + uoffset_t EndVector(size_t len) { + FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector. + nested = false; + return PushElement(static_cast(len)); + } + + void StartVector(size_t len, size_t elemsize) { + NotNested(); + nested = true; + PreAlign(len * elemsize); + PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t. + } + + // Call this right before StartVector/CreateVector if you want to force the + // alignment to be something different than what the element size would + // normally dictate. + // This is useful when storing a nested_flatbuffer in a vector of bytes, + // or when storing SIMD floats, etc. + void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) { + PreAlign(len * elemsize, alignment); + } + + // Similar to ForceVectorAlignment but for String fields. + void ForceStringAlignment(size_t len, size_t alignment) { + PreAlign((len + 1) * sizeof(char), alignment); + } + + /// @endcond + + /// @brief Serialize an array into a FlatBuffer `vector`. + /// @tparam T The data type of the array elements. + /// @param[in] v A pointer to the array of type `T` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template Offset> CreateVector(const T *v, size_t len) { + // If this assert hits, you're specifying a template argument that is + // causing the wrong overload to be selected, remove it. + AssertScalarT(); + StartVector(len, sizeof(T)); + // clang-format off + #if FLATBUFFERS_LITTLEENDIAN + PushBytes(reinterpret_cast(v), len * sizeof(T)); + #else + if (sizeof(T) == 1) { + PushBytes(reinterpret_cast(v), len); + } else { + for (auto i = len; i > 0; ) { + PushElement(v[--i]); + } + } + #endif + // clang-format on + return Offset>(EndVector(len)); + } + + template + Offset>> CreateVector(const Offset *v, size_t len) { + StartVector(len, sizeof(Offset)); + for (auto i = len; i > 0;) { PushElement(v[--i]); } + return Offset>>(EndVector(len)); + } + + /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. + /// @tparam T The data type of the `std::vector` elements. + /// @param v A const reference to the `std::vector` to serialize into the + /// buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template Offset> CreateVector(const std::vector &v) { + return CreateVector(data(v), v.size()); + } + + // vector may be implemented using a bit-set, so we can't access it as + // an array. Instead, read elements manually. + // Background: https://isocpp.org/blog/2012/11/on-vectorbool + Offset> CreateVector(const std::vector &v) { + StartVector(v.size(), sizeof(uint8_t)); + for (auto i = v.size(); i > 0;) { + PushElement(static_cast(v[--i])); + } + return Offset>(EndVector(v.size())); + } + + // clang-format off + #ifndef FLATBUFFERS_CPP98_STL + /// @brief Serialize values returned by a function into a FlatBuffer `vector`. + /// This is a convenience function that takes care of iteration for you. + /// @tparam T The data type of the `std::vector` elements. + /// @param f A function that takes the current iteration 0..vector_size-1 and + /// returns any type that you can construct a FlatBuffers vector out of. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template Offset> CreateVector(size_t vector_size, + const std::function &f) { + std::vector elems(vector_size); + for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); + return CreateVector(elems); + } + #endif + // clang-format on + + /// @brief Serialize values returned by a function into a FlatBuffer `vector`. + /// This is a convenience function that takes care of iteration for you. + /// @tparam T The data type of the `std::vector` elements. + /// @param f A function that takes the current iteration 0..vector_size-1, + /// and the state parameter returning any type that you can construct a + /// FlatBuffers vector out of. + /// @param state State passed to f. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVector(size_t vector_size, F f, S *state) { + std::vector elems(vector_size); + for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state); + return CreateVector(elems); + } + + /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. + /// This is a convenience function for a common case. + /// @param v A const reference to the `std::vector` to serialize into the + /// buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + Offset>> CreateVectorOfStrings( + const std::vector &v) { + std::vector> offsets(v.size()); + for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); + return CreateVector(offsets); + } + + /// @brief Serialize an array of structs into a FlatBuffer `vector`. + /// @tparam T The data type of the struct array elements. + /// @param[in] v A pointer to the array of type `T` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfStructs(const T *v, size_t len) { + StartVector(len * sizeof(T) / AlignOf(), AlignOf()); + PushBytes(reinterpret_cast(v), sizeof(T) * len); + return Offset>(EndVector(len)); + } + + /// @brief Serialize an array of native structs into a FlatBuffer `vector`. + /// @tparam T The data type of the struct array elements. + /// @tparam S The data type of the native struct array elements. + /// @param[in] v A pointer to the array of type `S` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfNativeStructs(const S *v, + size_t len) { + extern T Pack(const S &); + std::vector vv(len); + std::transform(v, v + len, vv.begin(), Pack); + return CreateVectorOfStructs(data(vv), vv.size()); + } + + // clang-format off + #ifndef FLATBUFFERS_CPP98_STL + /// @brief Serialize an array of structs into a FlatBuffer `vector`. + /// @tparam T The data type of the struct array elements. + /// @param[in] filler A function that takes the current iteration 0..vector_size-1 + /// and a pointer to the struct that must be filled. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + /// This is mostly useful when flatbuffers are generated with mutation + /// accessors. + template Offset> CreateVectorOfStructs( + size_t vector_size, const std::function &filler) { + T* structs = StartVectorOfStructs(vector_size); + for (size_t i = 0; i < vector_size; i++) { + filler(i, structs); + structs++; + } + return EndVectorOfStructs(vector_size); + } + #endif + // clang-format on + + /// @brief Serialize an array of structs into a FlatBuffer `vector`. + /// @tparam T The data type of the struct array elements. + /// @param[in] f A function that takes the current iteration 0..vector_size-1, + /// a pointer to the struct that must be filled and the state argument. + /// @param[in] state Arbitrary state to pass to f. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + /// This is mostly useful when flatbuffers are generated with mutation + /// accessors. + template + Offset> CreateVectorOfStructs(size_t vector_size, F f, + S *state) { + T *structs = StartVectorOfStructs(vector_size); + for (size_t i = 0; i < vector_size; i++) { + f(i, structs, state); + structs++; + } + return EndVectorOfStructs(vector_size); + } + + /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`. + /// @tparam T The data type of the `std::vector` struct elements. + /// @param[in] v A const reference to the `std::vector` of structs to + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfStructs( + const std::vector &v) { + return CreateVectorOfStructs(data(v), v.size()); + } + + /// @brief Serialize a `std::vector` of native structs into a FlatBuffer + /// `vector`. + /// @tparam T The data type of the `std::vector` struct elements. + /// @tparam S The data type of the `std::vector` native struct elements. + /// @param[in] v A const reference to the `std::vector` of structs to + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfNativeStructs( + const std::vector &v) { + return CreateVectorOfNativeStructs(data(v), v.size()); + } + + /// @cond FLATBUFFERS_INTERNAL + template struct StructKeyComparator { + bool operator()(const T &a, const T &b) const { + return a.KeyCompareLessThan(&b); + } + + private: + StructKeyComparator &operator=(const StructKeyComparator &); + }; + /// @endcond + + /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector` + /// in sorted order. + /// @tparam T The data type of the `std::vector` struct elements. + /// @param[in] v A const reference to the `std::vector` of structs to + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfSortedStructs(std::vector *v) { + return CreateVectorOfSortedStructs(data(*v), v->size()); + } + + /// @brief Serialize a `std::vector` of native structs into a FlatBuffer + /// `vector` in sorted order. + /// @tparam T The data type of the `std::vector` struct elements. + /// @tparam S The data type of the `std::vector` native struct elements. + /// @param[in] v A const reference to the `std::vector` of structs to + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfSortedNativeStructs( + std::vector *v) { + return CreateVectorOfSortedNativeStructs(data(*v), v->size()); + } + + /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted + /// order. + /// @tparam T The data type of the struct array elements. + /// @param[in] v A pointer to the array of type `T` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfSortedStructs(T *v, size_t len) { + std::sort(v, v + len, StructKeyComparator()); + return CreateVectorOfStructs(v, len); + } + + /// @brief Serialize an array of native structs into a FlatBuffer `vector` in + /// sorted order. + /// @tparam T The data type of the struct array elements. + /// @tparam S The data type of the native struct array elements. + /// @param[in] v A pointer to the array of type `S` to serialize into the + /// buffer as a `vector`. + /// @param[in] len The number of elements to serialize. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset> CreateVectorOfSortedNativeStructs(S *v, + size_t len) { + extern T Pack(const S &); + typedef T (*Pack_t)(const S &); + std::vector vv(len); + std::transform(v, v + len, vv.begin(), static_cast(Pack)); + return CreateVectorOfSortedStructs(vv, len); + } + + /// @cond FLATBUFFERS_INTERNAL + template struct TableKeyComparator { + TableKeyComparator(vector_downward &buf) : buf_(buf) {} + TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {} + bool operator()(const Offset &a, const Offset &b) const { + auto table_a = reinterpret_cast(buf_.data_at(a.o)); + auto table_b = reinterpret_cast(buf_.data_at(b.o)); + return table_a->KeyCompareLessThan(table_b); + } + vector_downward &buf_; + + private: + TableKeyComparator &operator=(const TableKeyComparator &other) { + buf_ = other.buf_; + return *this; + } + }; + /// @endcond + + /// @brief Serialize an array of `table` offsets as a `vector` in the buffer + /// in sorted order. + /// @tparam T The data type that the offset refers to. + /// @param[in] v An array of type `Offset` that contains the `table` + /// offsets to store in the buffer in sorted order. + /// @param[in] len The number of elements to store in the `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset>> CreateVectorOfSortedTables(Offset *v, + size_t len) { + std::sort(v, v + len, TableKeyComparator(buf_)); + return CreateVector(v, len); + } + + /// @brief Serialize an array of `table` offsets as a `vector` in the buffer + /// in sorted order. + /// @tparam T The data type that the offset refers to. + /// @param[in] v An array of type `Offset` that contains the `table` + /// offsets to store in the buffer in sorted order. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template + Offset>> CreateVectorOfSortedTables( + std::vector> *v) { + return CreateVectorOfSortedTables(data(*v), v->size()); + } + + /// @brief Specialized version of `CreateVector` for non-copying use cases. + /// Write the data any time later to the returned buffer pointer `buf`. + /// @param[in] len The number of elements to store in the `vector`. + /// @param[in] elemsize The size of each element in the `vector`. + /// @param[out] buf A pointer to a `uint8_t` pointer that can be + /// written to at a later time to serialize the data into a `vector` + /// in the buffer. + uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, + uint8_t **buf) { + NotNested(); + StartVector(len, elemsize); + buf_.make_space(len * elemsize); + auto vec_start = GetSize(); + auto vec_end = EndVector(len); + *buf = buf_.data_at(vec_start); + return vec_end; + } + + /// @brief Specialized version of `CreateVector` for non-copying use cases. + /// Write the data any time later to the returned buffer pointer `buf`. + /// @tparam T The data type of the data that will be stored in the buffer + /// as a `vector`. + /// @param[in] len The number of elements to store in the `vector`. + /// @param[out] buf A pointer to a pointer of type `T` that can be + /// written to at a later time to serialize the data into a `vector` + /// in the buffer. + template + Offset> CreateUninitializedVector(size_t len, T **buf) { + AssertScalarT(); + return CreateUninitializedVector(len, sizeof(T), + reinterpret_cast(buf)); + } + + template + Offset> CreateUninitializedVectorOfStructs(size_t len, + T **buf) { + return CreateUninitializedVector(len, sizeof(T), + reinterpret_cast(buf)); + } + + // @brief Create a vector of scalar type T given as input a vector of scalar + // type U, useful with e.g. pre "enum class" enums, or any existing scalar + // data of the wrong type. + template + Offset> CreateVectorScalarCast(const U *v, size_t len) { + AssertScalarT(); + AssertScalarT(); + StartVector(len, sizeof(T)); + for (auto i = len; i > 0;) { PushElement(static_cast(v[--i])); } + return Offset>(EndVector(len)); + } + + /// @brief Write a struct by itself, typically to be part of a union. + template Offset CreateStruct(const T &structobj) { + NotNested(); + Align(AlignOf()); + buf_.push_small(structobj); + return Offset(GetSize()); + } + + /// @brief The length of a FlatBuffer file header. + static const size_t kFileIdentifierLength = 4; + + /// @brief Finish serializing a buffer by writing the root offset. + /// @param[in] file_identifier If a `file_identifier` is given, the buffer + /// will be prefixed with a standard FlatBuffers file header. + template + void Finish(Offset root, const char *file_identifier = nullptr) { + Finish(root.o, file_identifier, false); + } + + /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the + /// buffer following the size field). These buffers are NOT compatible + /// with standard buffers created by Finish, i.e. you can't call GetRoot + /// on them, you have to use GetSizePrefixedRoot instead. + /// All >32 bit quantities in this buffer will be aligned when the whole + /// size pre-fixed buffer is aligned. + /// These kinds of buffers are useful for creating a stream of FlatBuffers. + template + void FinishSizePrefixed(Offset root, + const char *file_identifier = nullptr) { + Finish(root.o, file_identifier, true); + } + + void SwapBufAllocator(FlatBufferBuilder &other) { + buf_.swap_allocator(other.buf_); + } + + protected: + // You shouldn't really be copying instances of this class. + FlatBufferBuilder(const FlatBufferBuilder &); + FlatBufferBuilder &operator=(const FlatBufferBuilder &); + + void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) { + NotNested(); + buf_.clear_scratch(); + // This will cause the whole buffer to be aligned. + PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) + + (file_identifier ? kFileIdentifierLength : 0), + minalign_); + if (file_identifier) { + FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength); + PushBytes(reinterpret_cast(file_identifier), + kFileIdentifierLength); + } + PushElement(ReferTo(root)); // Location of root. + if (size_prefix) { PushElement(GetSize()); } + finished = true; + } + + struct FieldLoc { + uoffset_t off; + voffset_t id; + }; + + vector_downward buf_; + + // Accumulating offsets of table members while it is being built. + // We store these in the scratch pad of buf_, after the vtable offsets. + uoffset_t num_field_loc; + // Track how much of the vtable is in use, so we can output the most compact + // possible vtable. + voffset_t max_voffset_; + + // Ensure objects are not nested. + bool nested; + + // Ensure the buffer is finished before it is being accessed. + bool finished; + + size_t minalign_; + + bool force_defaults_; // Serialize values equal to their defaults anyway. + + bool dedup_vtables_; + + struct StringOffsetCompare { + StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {} + bool operator()(const Offset &a, const Offset &b) const { + auto stra = reinterpret_cast(buf_->data_at(a.o)); + auto strb = reinterpret_cast(buf_->data_at(b.o)); + return StringLessThan(stra->data(), stra->size(), strb->data(), + strb->size()); + } + const vector_downward *buf_; + }; + + // For use with CreateSharedString. Instantiated on first use only. + typedef std::set, StringOffsetCompare> StringOffsetMap; + StringOffsetMap *string_pool; + + private: + // Allocates space for a vector of structures. + // Must be completed with EndVectorOfStructs(). + template T *StartVectorOfStructs(size_t vector_size) { + StartVector(vector_size * sizeof(T) / AlignOf(), AlignOf()); + return reinterpret_cast(buf_.make_space(vector_size * sizeof(T))); + } + + // End the vector of structues in the flatbuffers. + // Vector should have previously be started with StartVectorOfStructs(). + template + Offset> EndVectorOfStructs(size_t vector_size) { + return Offset>(EndVector(vector_size)); + } +}; +/// @} + +/// @cond FLATBUFFERS_INTERNAL +// Helpers to get a typed pointer to the root object contained in the buffer. +template T *GetMutableRoot(void *buf) { + EndianCheck(); + return reinterpret_cast( + reinterpret_cast(buf) + + EndianScalar(*reinterpret_cast(buf))); +} + +template const T *GetRoot(const void *buf) { + return GetMutableRoot(const_cast(buf)); +} + +template const T *GetSizePrefixedRoot(const void *buf) { + return GetRoot(reinterpret_cast(buf) + sizeof(uoffset_t)); +} + +/// Helpers to get a typed pointer to objects that are currently being built. +/// @warning Creating new objects will lead to reallocations and invalidates +/// the pointer! +template +T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { + return reinterpret_cast(fbb.GetCurrentBufferPointer() + fbb.GetSize() - + offset.o); +} + +template +const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { + return GetMutableTemporaryPointer(fbb, offset); +} + +/// @brief Get a pointer to the the file_identifier section of the buffer. +/// @return Returns a const char pointer to the start of the file_identifier +/// characters in the buffer. The returned char * has length +/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'. +/// This function is UNDEFINED for FlatBuffers whose schema does not include +/// a file_identifier (likely points at padding or the start of a the root +/// vtable). +inline const char *GetBufferIdentifier(const void *buf, + bool size_prefixed = false) { + return reinterpret_cast(buf) + + ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); +} + +// Helper to see if the identifier in a buffer has the expected value. +inline bool BufferHasIdentifier(const void *buf, const char *identifier, + bool size_prefixed = false) { + return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, + FlatBufferBuilder::kFileIdentifierLength) == 0; +} + +// Helper class to verify the integrity of a FlatBuffer +class Verifier FLATBUFFERS_FINAL_CLASS { + public: + Verifier(const uint8_t *buf, size_t buf_len, uoffset_t _max_depth = 64, + uoffset_t _max_tables = 1000000, bool _check_alignment = true) + : buf_(buf), + size_(buf_len), + depth_(0), + max_depth_(_max_depth), + num_tables_(0), + max_tables_(_max_tables), + upper_bound_(0), + check_alignment_(_check_alignment) { + FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); + } + + // Central location where any verification failures register. + bool Check(bool ok) const { + // clang-format off + #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE + FLATBUFFERS_ASSERT(ok); + #endif + #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE + if (!ok) + upper_bound_ = 0; + #endif + // clang-format on + return ok; + } + + // Verify any range within the buffer. + bool Verify(size_t elem, size_t elem_len) const { + // clang-format off + #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE + auto upper_bound = elem + elem_len; + if (upper_bound_ < upper_bound) + upper_bound_ = upper_bound; + #endif + // clang-format on + return Check(elem_len < size_ && elem <= size_ - elem_len); + } + + template bool VerifyAlignment(size_t elem) const { + return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); + } + + // Verify a range indicated by sizeof(T). + template bool Verify(size_t elem) const { + return VerifyAlignment(elem) && Verify(elem, sizeof(T)); + } + + bool VerifyFromPointer(const uint8_t *p, size_t len) { + auto o = static_cast(p - buf_); + return Verify(o, len); + } + + // Verify relative to a known-good base pointer. + bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const { + return Verify(static_cast(base - buf_) + elem_off, elem_len); + } + + template + bool Verify(const uint8_t *base, voffset_t elem_off) const { + return Verify(static_cast(base - buf_) + elem_off, sizeof(T)); + } + + // Verify a pointer (may be NULL) of a table type. + template bool VerifyTable(const T *table) { + return !table || table->Verify(*this); + } + + // Verify a pointer (may be NULL) of any vector type. + template bool VerifyVector(const Vector *vec) const { + return !vec || VerifyVectorOrString(reinterpret_cast(vec), + sizeof(T)); + } + + // Verify a pointer (may be NULL) of a vector to struct. + template bool VerifyVector(const Vector *vec) const { + return VerifyVector(reinterpret_cast *>(vec)); + } + + // Verify a pointer (may be NULL) to string. + bool VerifyString(const String *str) const { + size_t end; + return !str || (VerifyVectorOrString(reinterpret_cast(str), + 1, &end) && + Verify(end, 1) && // Must have terminator + Check(buf_[end] == '\0')); // Terminating byte must be 0. + } + + // Common code between vectors and strings. + bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, + size_t *end = nullptr) const { + auto veco = static_cast(vec - buf_); + // Check we can read the size field. + if (!Verify(veco)) return false; + // Check the whole array. If this is a string, the byte past the array + // must be 0. + auto size = ReadScalar(vec); + auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; + if (!Check(size < max_elems)) + return false; // Protect against byte_size overflowing. + auto byte_size = sizeof(size) + elem_size * size; + if (end) *end = veco + byte_size; + return Verify(veco, byte_size); + } + + // Special case for string contents, after the above has been called. + bool VerifyVectorOfStrings(const Vector> *vec) const { + if (vec) { + for (uoffset_t i = 0; i < vec->size(); i++) { + if (!VerifyString(vec->Get(i))) return false; + } + } + return true; + } + + // Special case for table contents, after the above has been called. + template bool VerifyVectorOfTables(const Vector> *vec) { + if (vec) { + for (uoffset_t i = 0; i < vec->size(); i++) { + if (!vec->Get(i)->Verify(*this)) return false; + } + } + return true; + } + + __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( + const uint8_t *table) { + // Check the vtable offset. + auto tableo = static_cast(table - buf_); + if (!Verify(tableo)) return false; + // This offset may be signed, but doing the subtraction unsigned always + // gives the result we want. + auto vtableo = tableo - static_cast(ReadScalar(table)); + // Check the vtable size field, then check vtable fits in its entirety. + return VerifyComplexity() && Verify(vtableo) && + VerifyAlignment(ReadScalar(buf_ + vtableo)) && + Verify(vtableo, ReadScalar(buf_ + vtableo)); + } + + template + bool VerifyBufferFromStart(const char *identifier, size_t start) { + if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) || + !BufferHasIdentifier(buf_ + start, identifier))) { + return false; + } + + // Call T::Verify, which must be in the generated code for this type. + auto o = VerifyOffset(start); + return o && reinterpret_cast(buf_ + start + o)->Verify(*this) + // clang-format off + #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE + && GetComputedSize() + #endif + ; + // clang-format on + } + + // Verify this whole buffer, starting with root type T. + template bool VerifyBuffer() { return VerifyBuffer(nullptr); } + + template bool VerifyBuffer(const char *identifier) { + return VerifyBufferFromStart(identifier, 0); + } + + template bool VerifySizePrefixedBuffer(const char *identifier) { + return Verify(0U) && + ReadScalar(buf_) == size_ - sizeof(uoffset_t) && + VerifyBufferFromStart(identifier, sizeof(uoffset_t)); + } + + uoffset_t VerifyOffset(size_t start) const { + if (!Verify(start)) return 0; + auto o = ReadScalar(buf_ + start); + // May not point to itself. + if (!Check(o != 0)) return 0; + // Can't wrap around / buffers are max 2GB. + if (!Check(static_cast(o) >= 0)) return 0; + // Must be inside the buffer to create a pointer from it (pointer outside + // buffer is UB). + if (!Verify(start + o, 1)) return 0; + return o; + } + + uoffset_t VerifyOffset(const uint8_t *base, voffset_t start) const { + return VerifyOffset(static_cast(base - buf_) + start); + } + + // Called at the start of a table to increase counters measuring data + // structure depth and amount, and possibly bails out with false if + // limits set by the constructor have been hit. Needs to be balanced + // with EndTable(). + bool VerifyComplexity() { + depth_++; + num_tables_++; + return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); + } + + // Called at the end of a table to pop the depth count. + bool EndTable() { + depth_--; + return true; + } + + // Returns the message size in bytes + size_t GetComputedSize() const { + // clang-format off + #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE + uintptr_t size = upper_bound_; + // Align the size to uoffset_t + size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); + return (size > size_) ? 0 : size; + #else + // Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work. + (void)upper_bound_; + FLATBUFFERS_ASSERT(false); + return 0; + #endif + // clang-format on + } + + private: + const uint8_t *buf_; + size_t size_; + uoffset_t depth_; + uoffset_t max_depth_; + uoffset_t num_tables_; + uoffset_t max_tables_; + mutable size_t upper_bound_; + bool check_alignment_; +}; + +// Convenient way to bundle a buffer and its length, to pass it around +// typed by its root. +// A BufferRef does not own its buffer. +struct BufferRefBase {}; // for std::is_base_of +template struct BufferRef : BufferRefBase { + BufferRef() : buf(nullptr), len(0), must_free(false) {} + BufferRef(uint8_t *_buf, uoffset_t _len) + : buf(_buf), len(_len), must_free(false) {} + + ~BufferRef() { + if (must_free) free(buf); + } + + const T *GetRoot() const { return flatbuffers::GetRoot(buf); } + + bool Verify() { + Verifier verifier(buf, len); + return verifier.VerifyBuffer(nullptr); + } + + uint8_t *buf; + uoffset_t len; + bool must_free; +}; + +// "structs" are flat structures that do not have an offset table, thus +// always have all members present and do not support forwards/backwards +// compatible extensions. + +class Struct FLATBUFFERS_FINAL_CLASS { + public: + template T GetField(uoffset_t o) const { + return ReadScalar(&data_[o]); + } + + template T GetStruct(uoffset_t o) const { + return reinterpret_cast(&data_[o]); + } + + const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; } + uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; } + + private: + // private constructor & copy constructor: you obtain instances of this + // class by pointing to existing data only + Struct(); + Struct(const Struct &); + Struct &operator=(const Struct &); + + uint8_t data_[1]; +}; + +// "tables" use an offset table (possibly shared) that allows fields to be +// omitted and added at will, but uses an extra indirection to read. +class Table { + public: + const uint8_t *GetVTable() const { + return data_ - ReadScalar(data_); + } + + // This gets the field offset for any of the functions below it, or 0 + // if the field was not present. + voffset_t GetOptionalFieldOffset(voffset_t field) const { + // The vtable offset is always at the start. + auto vtable = GetVTable(); + // The first element is the size of the vtable (fields + type id + itself). + auto vtsize = ReadScalar(vtable); + // If the field we're accessing is outside the vtable, we're reading older + // data, so it's the same as if the offset was 0 (not present). + return field < vtsize ? ReadScalar(vtable + field) : 0; + } + + template T GetField(voffset_t field, T defaultval) const { + auto field_offset = GetOptionalFieldOffset(field); + return field_offset ? ReadScalar(data_ + field_offset) : defaultval; + } + + template P GetPointer(voffset_t field) { + auto field_offset = GetOptionalFieldOffset(field); + auto p = data_ + field_offset; + return field_offset ? reinterpret_cast

(p + ReadScalar(p)) + : nullptr; + } + template P GetPointer(voffset_t field) const { + return const_cast(this)->GetPointer

(field); + } + + template P GetStruct(voffset_t field) const { + auto field_offset = GetOptionalFieldOffset(field); + auto p = const_cast(data_ + field_offset); + return field_offset ? reinterpret_cast

(p) : nullptr; + } + + template bool SetField(voffset_t field, T val, T def) { + auto field_offset = GetOptionalFieldOffset(field); + if (!field_offset) return IsTheSameAs(val, def); + WriteScalar(data_ + field_offset, val); + return true; + } + + bool SetPointer(voffset_t field, const uint8_t *val) { + auto field_offset = GetOptionalFieldOffset(field); + if (!field_offset) return false; + WriteScalar(data_ + field_offset, + static_cast(val - (data_ + field_offset))); + return true; + } + + uint8_t *GetAddressOf(voffset_t field) { + auto field_offset = GetOptionalFieldOffset(field); + return field_offset ? data_ + field_offset : nullptr; + } + const uint8_t *GetAddressOf(voffset_t field) const { + return const_cast

(this)->GetAddressOf(field); + } + + bool CheckField(voffset_t field) const { + return GetOptionalFieldOffset(field) != 0; + } + + // Verify the vtable of this table. + // Call this once per table, followed by VerifyField once per field. + bool VerifyTableStart(Verifier &verifier) const { + return verifier.VerifyTableStart(data_); + } + + // Verify a particular field. + template + bool VerifyField(const Verifier &verifier, voffset_t field) const { + // Calling GetOptionalFieldOffset should be safe now thanks to + // VerifyTable(). + auto field_offset = GetOptionalFieldOffset(field); + // Check the actual field. + return !field_offset || verifier.Verify(data_, field_offset); + } + + // VerifyField for required fields. + template + bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { + auto field_offset = GetOptionalFieldOffset(field); + return verifier.Check(field_offset != 0) && + verifier.Verify(data_, field_offset); + } + + // Versions for offsets. + bool VerifyOffset(const Verifier &verifier, voffset_t field) const { + auto field_offset = GetOptionalFieldOffset(field); + return !field_offset || verifier.VerifyOffset(data_, field_offset); + } + + bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const { + auto field_offset = GetOptionalFieldOffset(field); + return verifier.Check(field_offset != 0) && + verifier.VerifyOffset(data_, field_offset); + } + + private: + // private constructor & copy constructor: you obtain instances of this + // class by pointing to existing data only + Table(); + Table(const Table &other); + Table &operator=(const Table &); + + uint8_t data_[1]; +}; + +template +void FlatBufferBuilder::Required(Offset table, voffset_t field) { + auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); + bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; + // If this fails, the caller will show what field needs to be set. + FLATBUFFERS_ASSERT(ok); + (void)ok; +} + +/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e. +/// it is the opposite transformation of GetRoot(). +/// This may be useful if you want to pass on a root and have the recipient +/// delete the buffer afterwards. +inline const uint8_t *GetBufferStartFromRootPointer(const void *root) { + auto table = reinterpret_cast(root); + auto vtable = table->GetVTable(); + // Either the vtable is before the root or after the root. + auto start = (std::min)(vtable, reinterpret_cast(root)); + // Align to at least sizeof(uoffset_t). + start = reinterpret_cast(reinterpret_cast(start) & + ~(sizeof(uoffset_t) - 1)); + // Additionally, there may be a file_identifier in the buffer, and the root + // offset. The buffer may have been aligned to any size between + // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align"). + // Sadly, the exact alignment is only known when constructing the buffer, + // since it depends on the presence of values with said alignment properties. + // So instead, we simply look at the next uoffset_t values (root, + // file_identifier, and alignment padding) to see which points to the root. + // None of the other values can "impersonate" the root since they will either + // be 0 or four ASCII characters. + static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t), + "file_identifier is assumed to be the same size as uoffset_t"); + for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1; + possible_roots; possible_roots--) { + start -= sizeof(uoffset_t); + if (ReadScalar(start) + start == + reinterpret_cast(root)) + return start; + } + // We didn't find the root, either the "root" passed isn't really a root, + // or the buffer is corrupt. + // Assert, because calling this function with bad data may cause reads + // outside of buffer boundaries. + FLATBUFFERS_ASSERT(false); + return nullptr; +} + +/// @brief This return the prefixed size of a FlatBuffer. +inline uoffset_t GetPrefixedSize(const uint8_t *buf) { + return ReadScalar(buf); +} + +// Base class for native objects (FlatBuffer data de-serialized into native +// C++ data structures). +// Contains no functionality, purely documentative. +struct NativeTable {}; + +/// @brief Function types to be used with resolving hashes into objects and +/// back again. The resolver gets a pointer to a field inside an object API +/// object that is of the type specified in the schema using the attribute +/// `cpp_type` (it is thus important whatever you write to this address +/// matches that type). The value of this field is initially null, so you +/// may choose to implement a delayed binding lookup using this function +/// if you wish. The resolver does the opposite lookup, for when the object +/// is being serialized again. +typedef uint64_t hash_value_t; +// clang-format off +#ifdef FLATBUFFERS_CPP98_STL + typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash); + typedef hash_value_t (*rehasher_function_t)(void *pointer); +#else + typedef std::function + resolver_function_t; + typedef std::function rehasher_function_t; +#endif +// clang-format on + +// Helper function to test if a field is present, using any of the field +// enums in the generated code. +// `table` must be a generated table type. Since this is a template parameter, +// this is not typechecked to be a subclass of Table, so beware! +// Note: this function will return false for fields equal to the default +// value, since they're not stored in the buffer (unless force_defaults was +// used). +template +bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) { + // Cast, since Table is a private baseclass of any table types. + return reinterpret_cast(table)->CheckField( + static_cast(field)); +} + +// Utility function for reverse lookups on the EnumNames*() functions +// (in the generated C++ code) +// names must be NULL terminated. +inline int LookupEnum(const char **names, const char *name) { + for (const char **p = names; *p; p++) + if (!strcmp(*p, name)) return static_cast(p - names); + return -1; +} + +// These macros allow us to layout a struct with a guarantee that they'll end +// up looking the same on different compilers and platforms. +// It does this by disallowing the compiler to do any padding, and then +// does padding itself by inserting extra padding fields that make every +// element aligned to its own size. +// Additionally, it manually sets the alignment of the struct as a whole, +// which is typically its largest element, or a custom size set in the schema +// by the force_align attribute. +// These are used in the generated code only. + +// clang-format off +#if defined(_MSC_VER) + #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ + __pragma(pack(1)) \ + struct __declspec(align(alignment)) + #define FLATBUFFERS_STRUCT_END(name, size) \ + __pragma(pack()) \ + static_assert(sizeof(name) == size, "compiler breaks packing rules") +#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) + #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ + _Pragma("pack(1)") \ + struct __attribute__((aligned(alignment))) + #define FLATBUFFERS_STRUCT_END(name, size) \ + _Pragma("pack()") \ + static_assert(sizeof(name) == size, "compiler breaks packing rules") +#else + #error Unknown compiler, please define structure alignment macros +#endif +// clang-format on + +// Minimal reflection via code generation. +// Besides full-fat reflection (see reflection.h) and parsing/printing by +// loading schemas (see idl.h), we can also have code generation for mimimal +// reflection data which allows pretty-printing and other uses without needing +// a schema or a parser. +// Generate code with --reflect-types (types only) or --reflect-names (names +// also) to enable. +// See minireflect.h for utilities using this functionality. + +// These types are organized slightly differently as the ones in idl.h. +enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM }; + +// Scalars have the same order as in idl.h +// clang-format off +#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \ + ET(ET_UTYPE) \ + ET(ET_BOOL) \ + ET(ET_CHAR) \ + ET(ET_UCHAR) \ + ET(ET_SHORT) \ + ET(ET_USHORT) \ + ET(ET_INT) \ + ET(ET_UINT) \ + ET(ET_LONG) \ + ET(ET_ULONG) \ + ET(ET_FLOAT) \ + ET(ET_DOUBLE) \ + ET(ET_STRING) \ + ET(ET_SEQUENCE) // See SequenceType. + +enum ElementaryType { + #define FLATBUFFERS_ET(E) E, + FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) + #undef FLATBUFFERS_ET +}; + +inline const char * const *ElementaryTypeNames() { + static const char * const names[] = { + #define FLATBUFFERS_ET(E) #E, + FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) + #undef FLATBUFFERS_ET + }; + return names; +} +// clang-format on + +// Basic type info cost just 16bits per field! +struct TypeCode { + uint16_t base_type : 4; // ElementaryType + uint16_t is_vector : 1; + int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none. +}; + +static_assert(sizeof(TypeCode) == 2, "TypeCode"); + +struct TypeTable; + +// Signature of the static method present in each type. +typedef const TypeTable *(*TypeFunction)(); + +struct TypeTable { + SequenceType st; + size_t num_elems; // of type_codes, values, names (but not type_refs). + const TypeCode *type_codes; // num_elems count + const TypeFunction *type_refs; // less than num_elems entries (see TypeCode). + const int64_t *values; // Only set for non-consecutive enum/union or structs. + const char *const *names; // Only set if compiled with --reflect-names. +}; + +// String which identifies the current version of FlatBuffers. +// flatbuffer_version_string is used by Google developers to identify which +// applications uploaded to Google Play are using this library. This allows +// the development team at Google to determine the popularity of the library. +// How it works: Applications that are uploaded to the Google Play Store are +// scanned for this version string. We track which applications are using it +// to measure popularity. You are free to remove it (of course) but we would +// appreciate if you left it in. + +// Weak linkage is culled by VS & doesn't work on cygwin. +// clang-format off +#if !defined(_WIN32) && !defined(__CYGWIN__) + +extern volatile __attribute__((weak)) const char *flatbuffer_version_string; +volatile __attribute__((weak)) const char *flatbuffer_version_string = + "FlatBuffers " + FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." + FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." + FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); + +#endif // !defined(_WIN32) && !defined(__CYGWIN__) + +#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\ + inline E operator | (E lhs, E rhs){\ + return E(T(lhs) | T(rhs));\ + }\ + inline E operator & (E lhs, E rhs){\ + return E(T(lhs) & T(rhs));\ + }\ + inline E operator ^ (E lhs, E rhs){\ + return E(T(lhs) ^ T(rhs));\ + }\ + inline E operator ~ (E lhs){\ + return E(~T(lhs));\ + }\ + inline E operator |= (E &lhs, E rhs){\ + lhs = lhs | rhs;\ + return lhs;\ + }\ + inline E operator &= (E &lhs, E rhs){\ + lhs = lhs & rhs;\ + return lhs;\ + }\ + inline E operator ^= (E &lhs, E rhs){\ + lhs = lhs ^ rhs;\ + return lhs;\ + }\ + inline bool operator !(E rhs) \ + {\ + return !bool(T(rhs)); \ + } +/// @endcond +} // namespace flatbuffers + +// clang-format on + +#endif // FLATBUFFERS_H_ diff --git a/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/stl_emulation.h b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/stl_emulation.h new file mode 100644 index 0000000..8bae61b --- /dev/null +++ b/TensorflowLiteMicro/third_party/flatbuffers/include/flatbuffers/stl_emulation.h @@ -0,0 +1,307 @@ +/* + * Copyright 2017 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLATBUFFERS_STL_EMULATION_H_ +#define FLATBUFFERS_STL_EMULATION_H_ + +// clang-format off + +#include +#include +#include +#include +#include + +#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) + #define FLATBUFFERS_CPP98_STL +#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) + +#if defined(FLATBUFFERS_CPP98_STL) + #include +#endif // defined(FLATBUFFERS_CPP98_STL) + +// Check if we can use template aliases +// Not possible if Microsoft Compiler before 2012 +// Possible is the language feature __cpp_alias_templates is defined well +// Or possible if the C++ std is C+11 or newer +#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \ + || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \ + || (defined(__cplusplus) && __cplusplus >= 201103L) + #define FLATBUFFERS_TEMPLATES_ALIASES +#endif + +// This header provides backwards compatibility for C++98 STLs like stlport. +namespace flatbuffers { + +// Retrieve ::back() from a string in a way that is compatible with pre C++11 +// STLs (e.g stlport). +inline char& string_back(std::string &value) { + return value[value.length() - 1]; +} + +inline char string_back(const std::string &value) { + return value[value.length() - 1]; +} + +// Helper method that retrieves ::data() from a vector in a way that is +// compatible with pre C++11 STLs (e.g stlport). +template inline T *vector_data(std::vector &vector) { + // In some debug environments, operator[] does bounds checking, so &vector[0] + // can't be used. + return vector.empty() ? nullptr : &vector[0]; +} + +template inline const T *vector_data( + const std::vector &vector) { + return vector.empty() ? nullptr : &vector[0]; +} + +template +inline void vector_emplace_back(std::vector *vector, V &&data) { + #if defined(FLATBUFFERS_CPP98_STL) + vector->push_back(data); + #else + vector->emplace_back(std::forward(data)); + #endif // defined(FLATBUFFERS_CPP98_STL) +} + +#ifndef FLATBUFFERS_CPP98_STL + #if defined(FLATBUFFERS_TEMPLATES_ALIASES) + template + using numeric_limits = std::numeric_limits; + #else + template class numeric_limits : + public std::numeric_limits {}; + #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) +#else + template class numeric_limits : + public std::numeric_limits { + public: + // Android NDK fix. + static T lowest() { + return std::numeric_limits::min(); + } + }; + + template <> class numeric_limits : + public std::numeric_limits { + public: + static float lowest() { return -FLT_MAX; } + }; + + template <> class numeric_limits : + public std::numeric_limits { + public: + static double lowest() { return -DBL_MAX; } + }; + + template <> class numeric_limits { + public: + static unsigned long long min() { return 0ULL; } + static unsigned long long max() { return ~0ULL; } + static unsigned long long lowest() { + return numeric_limits::min(); + } + }; + + template <> class numeric_limits { + public: + static long long min() { + return static_cast(1ULL << ((sizeof(long long) << 3) - 1)); + } + static long long max() { + return static_cast( + (1ULL << ((sizeof(long long) << 3) - 1)) - 1); + } + static long long lowest() { + return numeric_limits::min(); + } + }; +#endif // FLATBUFFERS_CPP98_STL + +#if defined(FLATBUFFERS_TEMPLATES_ALIASES) + #ifndef FLATBUFFERS_CPP98_STL + template using is_scalar = std::is_scalar; + template using is_same = std::is_same; + template using is_floating_point = std::is_floating_point; + template using is_unsigned = std::is_unsigned; + template using is_enum = std::is_enum; + template using make_unsigned = std::make_unsigned; + template + using conditional = std::conditional; + template + using integral_constant = std::integral_constant; + #else + // Map C++ TR1 templates defined by stlport. + template using is_scalar = std::tr1::is_scalar; + template using is_same = std::tr1::is_same; + template using is_floating_point = + std::tr1::is_floating_point; + template using is_unsigned = std::tr1::is_unsigned; + template using is_enum = std::tr1::is_enum; + // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned. + template struct make_unsigned { + static_assert(is_unsigned::value, "Specialization not implemented!"); + using type = T; + }; + template<> struct make_unsigned { using type = unsigned char; }; + template<> struct make_unsigned { using type = unsigned short; }; + template<> struct make_unsigned { using type = unsigned int; }; + template<> struct make_unsigned { using type = unsigned long; }; + template<> + struct make_unsigned { using type = unsigned long long; }; + template + using conditional = std::tr1::conditional; + template + using integral_constant = std::tr1::integral_constant; + #endif // !FLATBUFFERS_CPP98_STL +#else + // MSVC 2010 doesn't support C++11 aliases. + template struct is_scalar : public std::is_scalar {}; + template struct is_same : public std::is_same {}; + template struct is_floating_point : + public std::is_floating_point {}; + template struct is_unsigned : public std::is_unsigned {}; + template struct is_enum : public std::is_enum {}; + template struct make_unsigned : public std::make_unsigned {}; + template + struct conditional : public std::conditional {}; + template + struct integral_constant : public std::integral_constant {}; +#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) + +#ifndef FLATBUFFERS_CPP98_STL + #if defined(FLATBUFFERS_TEMPLATES_ALIASES) + template using unique_ptr = std::unique_ptr; + #else + // MSVC 2010 doesn't support C++11 aliases. + // We're manually "aliasing" the class here as we want to bring unique_ptr + // into the flatbuffers namespace. We have unique_ptr in the flatbuffers + // namespace we have a completely independent implemenation (see below) + // for C++98 STL implementations. + template class unique_ptr : public std::unique_ptr { + public: + unique_ptr() {} + explicit unique_ptr(T* p) : std::unique_ptr(p) {} + unique_ptr(std::unique_ptr&& u) { *this = std::move(u); } + unique_ptr(unique_ptr&& u) { *this = std::move(u); } + unique_ptr& operator=(std::unique_ptr&& u) { + std::unique_ptr::reset(u.release()); + return *this; + } + unique_ptr& operator=(unique_ptr&& u) { + std::unique_ptr::reset(u.release()); + return *this; + } + unique_ptr& operator=(T* p) { + return std::unique_ptr::operator=(p); + } + }; + #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) +#else + // Very limited implementation of unique_ptr. + // This is provided simply to allow the C++ code generated from the default + // settings to function in C++98 environments with no modifications. + template class unique_ptr { + public: + typedef T element_type; + + unique_ptr() : ptr_(nullptr) {} + explicit unique_ptr(T* p) : ptr_(p) {} + unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); } + unique_ptr(const unique_ptr& u) : ptr_(nullptr) { + reset(const_cast(&u)->release()); + } + ~unique_ptr() { reset(); } + + unique_ptr& operator=(const unique_ptr& u) { + reset(const_cast(&u)->release()); + return *this; + } + + unique_ptr& operator=(unique_ptr&& u) { + reset(u.release()); + return *this; + } + + unique_ptr& operator=(T* p) { + reset(p); + return *this; + } + + const T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const noexcept { return ptr_; } + explicit operator bool() const { return ptr_ != nullptr; } + + // modifiers + T* release() { + T* value = ptr_; + ptr_ = nullptr; + return value; + } + + void reset(T* p = nullptr) { + T* value = ptr_; + ptr_ = p; + if (value) delete value; + } + + void swap(unique_ptr& u) { + T* temp_ptr = ptr_; + ptr_ = u.ptr_; + u.ptr_ = temp_ptr; + } + + private: + T* ptr_; + }; + + template bool operator==(const unique_ptr& x, + const unique_ptr& y) { + return x.get() == y.get(); + } + + template bool operator==(const unique_ptr& x, + const D* y) { + return static_cast(x.get()) == y; + } + + template bool operator==(const unique_ptr& x, intptr_t y) { + return reinterpret_cast(x.get()) == y; + } + + template bool operator!=(const unique_ptr& x, decltype(nullptr)) { + return !!x; + } + + template bool operator!=(decltype(nullptr), const unique_ptr& x) { + return !!x; + } + + template bool operator==(const unique_ptr& x, decltype(nullptr)) { + return !x; + } + + template bool operator==(decltype(nullptr), const unique_ptr& x) { + return !x; + } + +#endif // !FLATBUFFERS_CPP98_STL + +} // namespace flatbuffers + +#endif // FLATBUFFERS_STL_EMULATION_H_ diff --git a/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint.h b/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint.h new file mode 100644 index 0000000..51b5aff --- /dev/null +++ b/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint.h @@ -0,0 +1,900 @@ +// Copyright 2015 The Gemmlowp Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// fixedpoint.h: fixed-point arithmetic, with basic operations and +// a few math functions such as tanh. + +#ifndef GEMMLOWP_INTERNAL_FIXEDPOINT_H_ +#define GEMMLOWP_INTERNAL_FIXEDPOINT_H_ + +#include +#include +#include +#include +#include + +#include "../internal/detect_platform.h" + +namespace gemmlowp { + +// Part 1: Low-level integer-arithmetic primitives. +// The implementations here are generic implementations valid for +// scalar types (e.g. std::int32_t). Architecture-specific SIMD types +// (e.g. NEON int32x4_t) may be supported by providing +// specializations for them in separate files. +// +// The purpose of these primitives is two-fold: +// - They will be used to implement higher-level fixed-point +// abstractions, namely the FixedPoint class and its arithmetic +// operators. +// - They will be directly used to implement some more involved +// fixed-point computations, e.g. the fixed-point implementation +// of math functions such as tanh. + +// Some compile-time traits around raw types to handle SIMD aspects: +// number of lanes, underlying scalar type. +template +struct FixedPointRawTypeTraits {}; + +template <> +struct FixedPointRawTypeTraits { + typedef std::int32_t ScalarRawType; + static constexpr int kLanes = 1; +}; + +template <> +struct FixedPointRawTypeTraits { + typedef std::int16_t ScalarRawType; + static constexpr int kLanes = 1; +}; + +// Returns a SIMD value duplicating a scalar value across all lanes. +template +tRawType Dup(typename FixedPointRawTypeTraits::ScalarRawType x) { + return x; +} + +// Plain bit-wise AND +template +tIntegerType BitAnd(tIntegerType a, tIntegerType b) { + return a & b; +} + +// Plain bit-wise OR +template +tIntegerType BitOr(tIntegerType a, tIntegerType b) { + return a | b; +} + +// Plain bit-wise XOR +template +tIntegerType BitXor(tIntegerType a, tIntegerType b) { + return a ^ b; +} + +// Plain bit-wise NOT +template +tIntegerType BitNot(tIntegerType a) { + return ~a; +} + +// Integer addition. Not saturating. Overflow is undefined behavior. +template +tIntegerType Add(tIntegerType a, tIntegerType b) { + return a + b; +} + +// Integer subtraction. Not saturating. Overflow is undefined behavior. +template +tIntegerType Mul(tIntegerType a, tIntegerType b) { + return a * b; +} + +template +tIntegerType Sub(tIntegerType a, tIntegerType b) { + return a - b; +} + +// Integer unary negative. Not saturating. Overflow is undefined behavior. +template +tIntegerType Neg(tIntegerType a) { + return -a; +} + +// Integer arithmetic left-shift, equivalent to multiplying with a power of two. +// Negative values are OK. In case of overflow, no Undefined +// Behavior, but the results are implementation-defined (in practice, +// they currently are saturated, but we make no commitment to that). The idea +// is that the caller will want to implement the overflowing cases with +// saturation with compare-and-mask, so we don't care about the results +// in the overflow case, we just want to avoid undefined behavior. +// +// tIntegerType may be int32 or any narrower signed type. +template +tIntegerType ShiftLeft(tIntegerType a, int offset) { + const std::int64_t wide_a = static_cast(a); + const std::int64_t wide_shifted = wide_a * (1 << offset); + const auto min = std::numeric_limits::min(); + const auto max = std::numeric_limits::max(); + return wide_shifted < min + ? min + : wide_shifted > max ? max + : static_cast(wide_shifted); +} + +// Integer arithmetic right-shift. Not rounding. +// Relying on implementation-defined, but in-practice-consistent, +// C++ compiler behavior. +template +tIntegerType ShiftRight(tIntegerType a, int offset) { + return a >> offset; +} + +// Each bit of the result is set to the corresponding bit of either then_val or +// else_val depending on whether the corresponding bit of if_mask is set. +// Equivalent to the VBSL instruction in ARM NEON. +template +tIntegerType SelectUsingMask(tIntegerType if_mask, tIntegerType then_val, + tIntegerType else_val) { + return BitXor(BitAnd(if_mask, then_val), BitAnd(BitNot(if_mask), else_val)); +} + +// For each input scalar, the corresponding bits of the result are set if the +// input scalar is non-zero. +template +tIntegerType MaskIfNonZero(tIntegerType a) { + static constexpr tIntegerType zero = 0; + return a ? BitNot(zero) : zero; +} + +// For each input scalar, the corresponding bits of the result are set if the +// input scalar is zero. +template +tIntegerType MaskIfZero(tIntegerType a) { + return MaskIfNonZero(!a); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars are equal. +template +tIntegerType MaskIfEqual(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a == b); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars are not equal. +template +tIntegerType MaskIfNotEqual(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a != b); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars a, b satisfy a > b. +template +tIntegerType MaskIfGreaterThan(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a > b); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars a, b satisfy a >= b. +template +tIntegerType MaskIfGreaterThanOrEqual(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a >= b); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars a, b satisfy a < b. +template +tIntegerType MaskIfLessThan(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a < b); +} + +// For each pair of input scalars, the corresponding bits of the result are +// set if the input scalars a, b satisfy a <= b. +template +tIntegerType MaskIfLessThanOrEqual(tIntegerType a, tIntegerType b) { + return MaskIfNonZero(a <= b); +} + +// Returns true if all of the input scalars are nonzero. +// This function may currently assume that each of the input scalars has either +// all or none of its bits set. Otherwise, its behavior is currently undefined. +template +bool All(tIntegerType a) { + return a; +} + +// Returns true if any of the input scalars are nonzero. +// This function may currently assume that each of the input scalars has either +// all or none of its bits set. Otherwise, its behavior is currently undefined. +template +bool Any(tIntegerType a) { + return a; +} + +// Returns (a+b)/2, rounded to the nearest integer. +// Equivalent to VRHADD in the ARM NEON instruction set. +template +IntegerType RoundingHalfSum(IntegerType a, IntegerType b) { + static_assert(std::is_same::value, "unimplemented"); + (void)b; + return a; +} + +template <> +inline std::int32_t RoundingHalfSum(std::int32_t a, std::int32_t b) { + std::int64_t a64 = a; + std::int64_t b64 = b; + std::int64_t sum = a64 + b64; + std::int64_t sign = sum >= 0 ? 1 : -1; + return static_cast((sum + sign) / 2); +} + +template <> +inline std::int16_t RoundingHalfSum(std::int16_t a, std::int16_t b) { + std::int32_t a32 = a; + std::int32_t b32 = b; + std::int32_t sum = a32 + b32; + std::int32_t sign = sum >= 0 ? 1 : -1; + return static_cast((sum + sign) / 2); +} + +template +IntegerType SaturatingAdd(IntegerType a, IntegerType b) { + static_assert(std::is_same::value, "unimplemented"); + (void)b; + return a; +} + +// So far this is only needed for int16. +template <> +inline std::int16_t SaturatingAdd(std::int16_t a, std::int16_t b) { + std::int32_t a32 = a; + std::int32_t b32 = b; + std::int32_t sum = a32 + b32; + return static_cast( + std::min(static_cast(32767), + std::max(static_cast(-32768), sum))); +} + +// Returns a+b, saturating if the integers are 16bit or narrower, +// otherwise just a plain addition. +template +struct AddSaturatingIf16BitImpl { + static IntegerType Run(IntegerType a, IntegerType b) { return Add(a, b); } +}; +template +struct AddSaturatingIf16BitImpl { + static IntegerType Run(IntegerType a, IntegerType b) { + return SaturatingAdd(a, b); + } +}; +template +IntegerType AddSaturatingIf16Bit(IntegerType a, IntegerType b) { + using ScalarType = + typename FixedPointRawTypeTraits::ScalarRawType; + return AddSaturatingIf16BitImpl::Run(a, + b); +} + +// Returns the integer that represents the product of two fixed-point +// numbers, interpreting all integers as fixed-point values in the +// interval [-1, 1), rounding to the nearest value, and saturating +// -1 * -1 to the maximum value (since 1 is not in the half-open +// interval [-1, 1)). +// +// [The explanation below specializes to std::int32_t for example purpose.] +// +// The mapping between IntegerType and the interval [-1, 1) is unique and +// implied by IntegerType, which is assumed to be signed. For example, +// for IntegerType==std::int32_t, the mapping is +// real_value = integer_value / 2^31. +// So in this case, and leaving aside rounding and saturating, this +// function computes ((a / 2^31) * (b / 2^31)) * 2^31, which simplifies to +// (a * b) / 2^31. +// +// The 'doubling' part in the name of this function comes from the fact that +// this operation is very close to a "multiply-high" operation, keeping only +// the top half bits, except that that would be effectively computing +// (a * b) / 2^32, +// so here we are computing 2x that, since +// 1/2^31 = 2 * 1/2^32. +// The idea is to use all of the available 32 bits in the destination int32 +// value. +// +// [End of the explanation specializing to int32.] +// +// This is equivalent to the VQRDMULH instruction in ARM NEON. +template +IntegerType SaturatingRoundingDoublingHighMul(IntegerType a, IntegerType b) { + static_assert(std::is_same::value, "unimplemented"); + (void)b; + return a; +} + +// This function implements the same computation as the ARMv7 NEON VQRDMULH +// instruction. +template <> +inline std::int32_t SaturatingRoundingDoublingHighMul(std::int32_t a, + std::int32_t b) { + bool overflow = a == b && a == std::numeric_limits::min(); + std::int64_t a_64(a); + std::int64_t b_64(b); + std::int64_t ab_64 = a_64 * b_64; + std::int32_t nudge = ab_64 >= 0 ? (1 << 30) : (1 - (1 << 30)); + std::int32_t ab_x2_high32 = + static_cast((ab_64 + nudge) / (1ll << 31)); + return overflow ? std::numeric_limits::max() : ab_x2_high32; +} + +template <> +inline std::int16_t SaturatingRoundingDoublingHighMul(std::int16_t a, + std::int16_t b) { + bool overflow = a == b && a == std::numeric_limits::min(); + std::int32_t a_32(a); + std::int32_t b_32(b); + std::int32_t ab_32 = a_32 * b_32; + std::int16_t nudge = ab_32 >= 0 ? (1 << 14) : (1 - (1 << 14)); + std::int16_t ab_x2_high16 = + static_cast((ab_32 + nudge) / (1 << 15)); + return overflow ? std::numeric_limits::max() : ab_x2_high16; +} + +// Correctly-rounded-to-nearest division by a power-of-two. +// Also known as a rounding arithmetic right shift. +template +inline IntegerType RoundingDivideByPOT(IntegerType x, int exponent) { + assert(exponent >= 0); + assert(exponent <= 31); + const IntegerType mask = Dup((1ll << exponent) - 1); + const IntegerType zero = Dup(0); + const IntegerType one = Dup(1); + const IntegerType remainder = BitAnd(x, mask); + const IntegerType threshold = + Add(ShiftRight(mask, 1), BitAnd(MaskIfLessThan(x, zero), one)); + return Add(ShiftRight(x, exponent), + BitAnd(MaskIfGreaterThan(remainder, threshold), one)); +} + +// Returns the product of a run-time integer value by a compile-time power +// of two, with either a positive exponent (equivalent to an arithmetic +// left shift, saturating) or a negative exponent (equivalent to an arithmetic +// right shift, rounding to nearest). +template 0 ? 1 : Exponent < 0 ? -1 : 0)> +struct ImplSaturatingRoundingMultiplyByPOT {}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static IntegerType eval(IntegerType x) { return x; } +}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static IntegerType eval(IntegerType x) { + using ScalarIntegerType = + typename FixedPointRawTypeTraits::ScalarRawType; + const IntegerType min = + Dup(std::numeric_limits::min()); + const IntegerType max = + Dup(std::numeric_limits::max()); + const int ScalarIntegerTypeBits = 8 * sizeof(ScalarIntegerType); + + const std::int32_t threshold = + ((1 << (ScalarIntegerTypeBits - 1 - Exponent)) - 1); + const IntegerType positive_mask = + MaskIfGreaterThan(x, Dup(threshold)); + const IntegerType negative_mask = + MaskIfLessThan(x, Dup(-threshold)); + + IntegerType result = ShiftLeft(x, Exponent); + result = SelectUsingMask(positive_mask, max, result); + result = SelectUsingMask(negative_mask, min, result); + return result; + } +}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static IntegerType eval(IntegerType x) { + return RoundingDivideByPOT(x, -Exponent); + } +}; + +template +IntegerType SaturatingRoundingMultiplyByPOT(IntegerType x) { + return ImplSaturatingRoundingMultiplyByPOT::eval(x); +} + +// Part 2: the FixedPoint class. + +// A FixedPoint object represents a fixed-point value stored in the underlying +// integer type tRawType, if tRawType is a plain scalar integer type. +// Alternatively, tRawType may be a SIMD type (e.g. NEON int32x4_t) in which +// case a FixedPoint object represents a corresponding SIMD vector of fixed +// point values. +// +// tIntegerBits describes the range of the fixed-point format: if +// tIntegerBits == m then the range of representable values is the half-open +// interval [-2^m; 2^m) where the open boundary on the right side means that +// 2^m is not representable (how close the maximum representable value is to +// it, depends on bit-depth of tRawType). +// +// In "Q format notation", +// https://en.wikipedia.org/wiki/Q_(number_format) +// we are describing the format +// Qm.n +// where +// m = tIntegerBits +// and +// n = NumberOfBits(tRawType) - (m + 1) +// Note that the (m + 1) in the above line is because we adopt the convention +// that we count the integer bits exclusively of the sign bit; so (m + 1) is +// the total number of integer bits inclusive of the sign bit. +// +// Accordingly, the number of integral representable values in our range +// [-2^m ; 2^m) +// is equal to 2^(m+1). +template +class FixedPoint { + public: + typedef tRawType RawType; + + typedef FixedPointRawTypeTraits RawTypeTraits; + typedef typename RawTypeTraits::ScalarRawType ScalarRawType; + + static constexpr int kTotalBits = 8 * sizeof(ScalarRawType); + static constexpr int kIntegerBits = tIntegerBits; + static constexpr int kFractionalBits = kTotalBits - 1 - kIntegerBits; + static_assert(kIntegerBits >= 0 && kIntegerBits < kTotalBits, + "bad IntegerBits"); + + typedef FixedPoint ScalarFixedPointType; + + static const ScalarRawType ScalarRawMin() { + return std::numeric_limits::min(); + } + + static const ScalarRawType ScalarRawMax() { + return std::numeric_limits::max(); + } + + static const ScalarRawType RawMin() { + return VectorFromScalar(ScalarRawMin()); + } + + static const ScalarRawType RawMax() { + return VectorFromScalar(ScalarRawMax()); + } + + static FixedPoint FromRaw(RawType x) { + FixedPoint retval; + retval.raw() = x; + return retval; + } + + static FixedPoint FromScalarRaw(ScalarRawType x) { + FixedPoint retval; + retval.raw() = Dup(x); + return retval; + } + + static FixedPoint FromScalarFixedPoint(ScalarFixedPointType x) { + return FromScalarRaw(x.raw()); + } + + template + static FixedPoint ConstantPOT() { + static constexpr int kOffset = kFractionalBits + Exponent; + static_assert( + kOffset < 31, + "Constant not exactly representable in this fixed-point format"); + return FromScalarRaw(ScalarRawType(1) << kOffset); + } + + static FixedPoint Zero() { return FromScalarRaw(0); } + + static FixedPoint One() { + return FromScalarRaw( + kIntegerBits == 0 + ? ScalarRawMax() + : (ScalarRawType(1) << (kIntegerBits == 0 ? 0 : kFractionalBits))); + } + + static FixedPoint FromDouble(double x) { + const double min_bound = static_cast(ScalarRawMin()); + const double max_bound = static_cast(ScalarRawMax()); + return FromScalarRaw(static_cast(std::min( + std::max(round(x * static_cast(1ll << kFractionalBits)), + min_bound), + max_bound))); + } + + RawType raw() const { return i_; } + RawType& raw() { return i_; } + + private: + RawType i_; +}; + +// Part 3: implementation of arithmetic operators for the +// FixedPoint class, and a few related functions. + +// A FixedPoint multiplication is just a +// SaturatingRoundingDoublingHighMul operation on the underlying +// raw integer values. The IntegerBits simply add up, as is obvious +// from the fact that the range is [-2^IntegerBits, 2^IntegerBits). +template +FixedPoint operator*( + FixedPoint a, + FixedPoint b) { + FixedPoint c; + c.raw() = SaturatingRoundingDoublingHighMul(a.raw(), b.raw()); + return c; +} + +// Tweaking IntegerBits gives exact multiplication by a power of two. +template +FixedPoint ExactMulByPot( + FixedPoint a) { + FixedPoint c; + c.raw() = a.raw(); + return c; +} + +// If we want to leave IntegerBits fixed, then multiplication +// by a power of two has to be saturating/rounding, not exact anymore. +template +FixedPoint SaturatingRoundingMultiplyByPOT( + FixedPoint a) { + return FixedPoint::FromRaw( + SaturatingRoundingMultiplyByPOT(a.raw())); +} + +// Generic arithmetic operators. + +#define MAKE_FIXEDPOINT_UNARY_FUNC(FuncName, ImplFuncName) \ + template \ + FixedPoint FuncName( \ + FixedPoint a) { \ + return FixedPoint::FromRaw(ImplFuncName(a.raw())); \ + } + +#define MAKE_FIXEDPOINT_BINARY_FUNC(FuncName, ImplFuncName) \ + template \ + FixedPoint FuncName( \ + FixedPoint a, \ + FixedPoint b) { \ + return FixedPoint::FromRaw( \ + ImplFuncName(a.raw(), b.raw())); \ + } + +MAKE_FIXEDPOINT_UNARY_FUNC(operator-, Neg) +MAKE_FIXEDPOINT_UNARY_FUNC(operator~, BitNot) +MAKE_FIXEDPOINT_BINARY_FUNC(operator+, Add) +MAKE_FIXEDPOINT_BINARY_FUNC(operator-, Sub) +MAKE_FIXEDPOINT_BINARY_FUNC(operator&, BitAnd) +MAKE_FIXEDPOINT_BINARY_FUNC(operator^, BitXor) +MAKE_FIXEDPOINT_BINARY_FUNC(operator|, BitOr) +MAKE_FIXEDPOINT_BINARY_FUNC(RoundingHalfSum, RoundingHalfSum) + +#undef MAKE_FIXEDPOINT_UNARY_FUNC +#undef MAKE_FIXEDPOINT_BINARY_FUNC + +#define MAKE_FIXEDPOINT_UNARY_FUNC_RETURNING_RAW(FuncName) \ + template \ + tRawType FuncName(FixedPoint a) { \ + return FuncName(a.raw()); \ + } + +#define MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(FuncName) \ + template \ + tRawType FuncName(FixedPoint a, \ + FixedPoint b) { \ + return FuncName(a.raw(), b.raw()); \ + } + +MAKE_FIXEDPOINT_UNARY_FUNC_RETURNING_RAW(MaskIfZero) +MAKE_FIXEDPOINT_UNARY_FUNC_RETURNING_RAW(MaskIfNonZero) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfEqual) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfNotEqual) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfGreaterThan) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfGreaterThanOrEqual) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfLessThan) +MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW(MaskIfLessThanOrEqual) + +#undef MAKE_FIXEDPOINT_UNARY_FUNC_RETURNING_RAW +#undef MAKE_FIXEDPOINT_BINARY_FUNC_RETURNING_RAW + +template +FixedPoint SelectUsingMask( + tRawType if_mask, FixedPoint then_val, + FixedPoint else_val) { + return FixedPoint::FromRaw( + SelectUsingMask(if_mask, then_val.raw(), else_val.raw())); +} + +template +bool operator==(FixedPoint a, + FixedPoint b) { + return All(MaskIfEqual(a.raw(), b.raw())); +} + +template +bool operator!=(FixedPoint a, + FixedPoint b) { + return !(a == b); +} + +template +FixedPoint SaturatingAdd( + FixedPoint a, + FixedPoint b) { + return FixedPoint::FromRaw( + SaturatingAdd(a.raw(), b.raw())); +} + +template +FixedPoint AddSaturatingIf16Bit( + FixedPoint a, + FixedPoint b) { + return FixedPoint::FromRaw( + AddSaturatingIf16Bit(a.raw(), b.raw())); +} + +// Conversion to floating-point. +template +double ToDouble(FixedPoint x) { + static_assert(FixedPointRawTypeTraits::kLanes == 1, + "not applicable to SIMD types"); + typedef FixedPoint F; + return x.raw() / static_cast(1ll << F::kFractionalBits); +} + +// Rescale changes the number of IntegerBits and updates the underlying +// raw integer value accordingly. +template +FixedPoint Rescale( + FixedPoint x) { + static constexpr int kExponent = tIntegerBitsSrc - tIntegerBitsDst; + FixedPoint result; + result.raw() = SaturatingRoundingMultiplyByPOT(x.raw()); + return result; +} + +// CheckedFixedPointConstant allows to specify fixed-point constants +// initialized as real numbers, in a way that does not compile floating-point +// arithmetic in production code, yet still checks agreement with the +// floating-point expressions when asserts are enabled. +// +// The raw integer value provided is always a int32, encoding a 32-bit +// fixed-point value, regardless of the actual Scalar type. This allows +// writing generic code that applies just as well to the 32-bit and 16-bit +// cases. In the 16-bit case, the raw integer value is internally +// rounding-shifted by 16 bits to the right. +template +inline typename FixedPointType::ScalarRawType RescaleConstantInitializer( + std::int32_t int32_value) { + typedef typename FixedPointType::ScalarRawType ScalarRawType; + static constexpr int ScalarTypeBits = 8 * sizeof(ScalarRawType); + return static_cast( + RoundingDivideByPOT(int32_value, 32 - ScalarTypeBits)); +} +#ifdef GEMMLOWP_ENABLE_FIXEDPOINT_CONSTANTS_CHECKS +template +FixedPointType CheckedFixedPointConstant(std::int32_t raw_value, + double double_value) { + const FixedPointType result = FixedPointType::FromScalarRaw(raw_value); + assert(result == FixedPointType::FromDouble(double_value)); + return result; +} +#define GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(FixedPointType, \ + ScalarRawInt32Value, DoubleValue) \ + (gemmlowp::CheckedFixedPointConstant( \ + gemmlowp::RescaleConstantInitializer( \ + ScalarRawInt32Value), \ + DoubleValue)) + +#else +#define GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(FixedPointType, \ + ScalarRawInt32Value, DoubleValue) \ + (FixedPointType::FromScalarRaw( \ + gemmlowp::RescaleConstantInitializer( \ + ScalarRawInt32Value))) +#endif + +// Implementation of exponential function. + +// Returns exp(x) for x in [-1/4, 0). +template +FixedPoint exp_on_interval_between_negative_one_quarter_and_0_excl( + FixedPoint a) { + typedef FixedPoint F; + const F constant_term = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F, 1895147668, std::exp(-1.0 / 8.0)); + const F constant_1_over_3 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F, 715827883, 1.0 / 3.0); + // We're evaluating a Taylor expansion around -1/8, so we do the change of + // variable: x = a + 1/8. + // In fixed-point with 0 integer bits, 1/8 is represented by 1 << 28. + F x = a + F::template ConstantPOT<-3>(); + F x2 = x * x; + F x3 = x2 * x; + F x4 = x2 * x2; + F x4_over_4 = SaturatingRoundingMultiplyByPOT<-2>(x4); + F x4_over_24_plus_x3_over_6_plus_x2_over_2 = + SaturatingRoundingMultiplyByPOT<-1>( + ((x4_over_4 + x3) * constant_1_over_3) + x2); + return AddSaturatingIf16Bit( + constant_term, + constant_term * (x + x4_over_24_plus_x3_over_6_plus_x2_over_2)); +} + +// Returns exp(x) for x < 0. +template +FixedPoint exp_on_negative_values( + FixedPoint a) { + typedef FixedPoint InputF; + typedef FixedPoint ResultF; + static constexpr int kFractionalBits = InputF::kFractionalBits; + static constexpr int kIntegerBits = InputF::kIntegerBits; + const InputF kOneQuarter = InputF::template ConstantPOT<-2>(); + InputF mask = kOneQuarter - InputF::FromScalarRaw(1); + InputF a_mod_quarter_minus_one_quarter = (a & mask) - kOneQuarter; + ResultF result = exp_on_interval_between_negative_one_quarter_and_0_excl( + Rescale<0>(a_mod_quarter_minus_one_quarter)); + tRawType remainder = (a_mod_quarter_minus_one_quarter - a).raw(); + +#define GEMMLOWP_EXP_BARREL_SHIFTER(Exponent, FixedPointMultiplier) \ + if (kIntegerBits > Exponent) { \ + const ResultF kMultiplier = GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT( \ + ResultF, FixedPointMultiplier, std::exp(-std::pow(2.0, Exponent))); \ + static constexpr int kShiftAmount = \ + kIntegerBits > Exponent ? kFractionalBits + Exponent : 0; \ + result = SelectUsingMask( \ + MaskIfNonZero(BitAnd(remainder, Dup(1 << kShiftAmount))), \ + result * kMultiplier, result); \ + } + + GEMMLOWP_EXP_BARREL_SHIFTER(-2, 1672461947); + GEMMLOWP_EXP_BARREL_SHIFTER(-1, 1302514674); + GEMMLOWP_EXP_BARREL_SHIFTER(+0, 790015084); + GEMMLOWP_EXP_BARREL_SHIFTER(+1, 290630308); + GEMMLOWP_EXP_BARREL_SHIFTER(+2, 39332535); + GEMMLOWP_EXP_BARREL_SHIFTER(+3, 720401); + GEMMLOWP_EXP_BARREL_SHIFTER(+4, 242); + +#undef GEMMLOWP_EXP_BARREL_SHIFTER + + static constexpr int clampB = kIntegerBits > 5 ? 36 - kIntegerBits : 0; + if (kIntegerBits > 5) { + const InputF clamp = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(InputF, -(1 << clampB), -32.0); + result = SelectUsingMask(MaskIfLessThan(a, clamp), ResultF::Zero(), result); + } + + result = SelectUsingMask(MaskIfZero(a), ResultF::One(), result); + return result; +} + +// Implementation of tanh: (1 - exp(-2x)) / (1 + exp(-2x)). + +// Returns (1 - x) / (1 + x) for x in (0, 1). +template +FixedPoint one_minus_x_over_one_plus_x_for_x_in_0_1( + FixedPoint a) { + typedef FixedPoint F0; + typedef FixedPoint F2; + F0 half_denominator = RoundingHalfSum(a, F0::One()); + // Newton-Raphson division + // https://en.wikipedia.org/wiki/Division_algorithm#Newton.E2.80.93Raphson_division + // Refer to that page for the logic behind the 48/17 and 32/17 constants. + const F2 constant_48_over_17 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F2, 1515870810, 48.0 / 17.0); + const F2 constant_neg_32_over_17 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F2, -1010580540, -32.0 / 17.0); + F2 x = constant_48_over_17 + half_denominator * constant_neg_32_over_17; + for (int i = 0; i < 3; i++) { + F2 half_denominator_times_x = half_denominator * x; + F2 one_minus_half_denominator_times_x = + F2::One() - half_denominator_times_x; + x = x + Rescale<2>(x * one_minus_half_denominator_times_x); + } + return Rescale<0>(x - F2::One()); +} + +// Returns -tanh(x) for x < 0. +template +FixedPoint neg_tanh_on_negative_values( + FixedPoint a) { + return one_minus_x_over_one_plus_x_for_x_in_0_1( + exp_on_negative_values(ExactMulByPot<1>(a))); +} + +// Returns tanh(x) for any x. +template +FixedPoint tanh(FixedPoint a) { + typedef FixedPoint InputF; + typedef FixedPoint ResultF; + tRawType mask_if_negative = MaskIfLessThan(a, InputF::Zero()); + tRawType mask_if_zero = MaskIfZero(a); + InputF n = SelectUsingMask(mask_if_negative, a, -a); + ResultF t = neg_tanh_on_negative_values(n); + return SelectUsingMask(mask_if_zero, ResultF::Zero(), + SelectUsingMask(mask_if_negative, -t, t)); +} + +// Implementation of logistic function. + +// Returns 1 / (1 + x) for x in (0, 1). +template +FixedPoint one_over_one_plus_x_for_x_in_0_1( + FixedPoint a) { + typedef FixedPoint F0; + typedef FixedPoint F2; + F0 half_denominator = RoundingHalfSum(a, F0::One()); + // Newton-Raphson division + // https://en.wikipedia.org/wiki/Division_algorithm#Newton.E2.80.93Raphson_division + // Refer to that page for the logic behind the 48/17 and 32/17 constants. + const F2 constant_48_over_17 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F2, 1515870810, 48.0 / 17.0); + const F2 constant_neg_32_over_17 = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(F2, -1010580540, -32.0 / 17.0); + F2 x = constant_48_over_17 + half_denominator * constant_neg_32_over_17; + for (int i = 0; i < 3; i++) { + F2 half_denominator_times_x = half_denominator * x; + F2 one_minus_half_denominator_times_x = + F2::One() - half_denominator_times_x; + x = x + Rescale<2>(x * one_minus_half_denominator_times_x); + } + return Rescale<0>(ExactMulByPot<-1>(x)); +} + +// Returns logistic(x) = 1 / (1 + exp(-x)) for x > 0. +template +FixedPoint logistic_on_positive_values( + FixedPoint a) { + return one_over_one_plus_x_for_x_in_0_1(exp_on_negative_values(-a)); +} + +// Returns logistic(x) = 1 / (1 + exp(-x)) for any x. +template +FixedPoint logistic(FixedPoint a) { + typedef FixedPoint InputF; + typedef FixedPoint ResultF; + tRawType mask_if_positive = MaskIfGreaterThan(a, InputF::Zero()); + tRawType mask_if_zero = MaskIfZero(a); + InputF abs_input = SelectUsingMask(mask_if_positive, a, -a); + ResultF result_if_positive = logistic_on_positive_values(abs_input); + ResultF result_if_negative = ResultF::One() - result_if_positive; + const ResultF one_half = + GEMMLOWP_CHECKED_FIXEDPOINT_CONSTANT(ResultF, 1 << 30, 0.5); + return SelectUsingMask(mask_if_zero, one_half, + SelectUsingMask(mask_if_positive, result_if_positive, + result_if_negative)); +} + +} // end namespace gemmlowp + +#ifdef GEMMLOWP_NEON +#include "./fixedpoint_neon.h" +#elif defined(GEMMLOWP_AVX2) +#include "./fixedpoint_avx.h" +#elif defined(GEMMLOWP_SSE4) +#include "./fixedpoint_sse.h" +#elif defined(GEMMLOWP_MSA) +#include "./fixedpoint_msa.h" +#endif + +#endif // GEMMLOWP_INTERNAL_FIXEDPOINT_H_ diff --git a/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint_neon.h b/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint_neon.h new file mode 100644 index 0000000..646c590 --- /dev/null +++ b/TensorflowLiteMicro/third_party/gemmlowp/fixedpoint/fixedpoint_neon.h @@ -0,0 +1,331 @@ +// Copyright 2015 The Gemmlowp Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// fixedpoint_neon.h: optimized NEON specializations of the templates +// in fixedpoint.h. + +#ifndef GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ +#define GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ + +#include + +namespace gemmlowp { + +template <> +struct FixedPointRawTypeTraits { + typedef std::int32_t ScalarRawType; + static constexpr int kLanes = 4; +}; + +template <> +struct FixedPointRawTypeTraits { + typedef std::int16_t ScalarRawType; + static constexpr int kLanes = 8; +}; + +template <> +inline int32x4_t BitAnd(int32x4_t a, int32x4_t b) { + return vandq_s32(a, b); +} + +template <> +inline int16x8_t BitAnd(int16x8_t a, int16x8_t b) { + return vandq_s16(a, b); +} + +template <> +inline int32x4_t BitOr(int32x4_t a, int32x4_t b) { + return vorrq_s32(a, b); +} + +template <> +inline int16x8_t BitOr(int16x8_t a, int16x8_t b) { + return vorrq_s16(a, b); +} + +template <> +inline int32x4_t BitXor(int32x4_t a, int32x4_t b) { + return veorq_s32(a, b); +} + +template <> +inline int16x8_t BitXor(int16x8_t a, int16x8_t b) { + return veorq_s16(a, b); +} + +template <> +inline int32x4_t BitNot(int32x4_t a) { + return veorq_s32(a, vdupq_n_s32(-1)); +} + +template <> +inline int16x8_t BitNot(int16x8_t a) { + return veorq_s16(a, vdupq_n_s16(-1)); +} + +template <> +inline int32x4_t Add(int32x4_t a, int32x4_t b) { + return vaddq_s32(a, b); +} + +template <> +inline int16x8_t Add(int16x8_t a, int16x8_t b) { + return vaddq_s16(a, b); +} + +template <> +inline int32x4_t Sub(int32x4_t a, int32x4_t b) { + return vsubq_s32(a, b); +} + +template <> +inline int16x8_t Sub(int16x8_t a, int16x8_t b) { + return vsubq_s16(a, b); +} + +template <> +inline int32x4_t Neg(int32x4_t a) { + return vnegq_s32(a); +} + +template <> +inline int16x8_t Neg(int16x8_t a) { + return vnegq_s16(a); +} + +template <> +inline int32x4_t ShiftLeft(int32x4_t a, int offset) { + return vshlq_s32(a, vdupq_n_s32(offset)); +} + +template <> +inline int16x8_t ShiftLeft(int16x8_t a, int offset) { + return vshlq_s16(a, vdupq_n_s16(offset)); +} + +template <> +inline int32x4_t ShiftRight(int32x4_t a, int offset) { + return vshlq_s32(a, vdupq_n_s32(-offset)); +} + +template <> +inline int16x8_t ShiftRight(int16x8_t a, int offset) { + return vshlq_s16(a, vdupq_n_s16(-offset)); +} + +template <> +inline int32x4_t SelectUsingMask(int32x4_t if_mask, int32x4_t then_val, + int32x4_t else_val) { + return vbslq_s32(vreinterpretq_u32_s32(if_mask), then_val, else_val); +} + +template <> +inline int16x8_t SelectUsingMask(int16x8_t if_mask, int16x8_t then_val, + int16x8_t else_val) { + return vbslq_s16(vreinterpretq_u16_s16(if_mask), then_val, else_val); +} + +template <> +inline int32x4_t MaskIfEqual(int32x4_t a, int32x4_t b) { + return vreinterpretq_s32_u32(vceqq_s32(a, b)); +} + +template <> +inline int16x8_t MaskIfEqual(int16x8_t a, int16x8_t b) { + return vreinterpretq_s16_u16(vceqq_s16(a, b)); +} + +template <> +inline int32x4_t MaskIfNotEqual(int32x4_t a, int32x4_t b) { + return BitNot(MaskIfEqual(a, b)); +} + +template <> +inline int16x8_t MaskIfNotEqual(int16x8_t a, int16x8_t b) { + return BitNot(MaskIfEqual(a, b)); +} + +template <> +inline int32x4_t MaskIfZero(int32x4_t a) { + return MaskIfEqual(a, vdupq_n_s32(0)); +} + +template <> +inline int16x8_t MaskIfZero(int16x8_t a) { + return MaskIfEqual(a, vdupq_n_s16(0)); +} + +template <> +inline int32x4_t MaskIfNonZero(int32x4_t a) { + return vreinterpretq_s32_u32(vtstq_s32(a, a)); +} + +template <> +inline int16x8_t MaskIfNonZero(int16x8_t a) { + return vreinterpretq_s16_u16(vtstq_s16(a, a)); +} + +template <> +inline int32x4_t MaskIfGreaterThan(int32x4_t a, int32x4_t b) { + return vreinterpretq_s32_u32(vcgtq_s32(a, b)); +} + +template <> +inline int16x8_t MaskIfGreaterThan(int16x8_t a, int16x8_t b) { + return vreinterpretq_s16_u16(vcgtq_s16(a, b)); +} + +template <> +inline int32x4_t MaskIfGreaterThanOrEqual(int32x4_t a, int32x4_t b) { + return vreinterpretq_s32_u32(vcgeq_s32(a, b)); +} + +template <> +inline int16x8_t MaskIfGreaterThanOrEqual(int16x8_t a, int16x8_t b) { + return vreinterpretq_s16_u16(vcgeq_s16(a, b)); +} + +template <> +inline int32x4_t MaskIfLessThan(int32x4_t a, int32x4_t b) { + return vreinterpretq_s32_u32(vcltq_s32(a, b)); +} + +template <> +inline int16x8_t MaskIfLessThan(int16x8_t a, int16x8_t b) { + return vreinterpretq_s16_u16(vcltq_s16(a, b)); +} + +template <> +inline int32x4_t MaskIfLessThanOrEqual(int32x4_t a, int32x4_t b) { + return vreinterpretq_s32_u32(vcleq_s32(a, b)); +} + +template <> +inline int16x8_t MaskIfLessThanOrEqual(int16x8_t a, int16x8_t b) { + return vreinterpretq_s16_u16(vcleq_s16(a, b)); +} + +template <> +inline bool All(int32x4_t a) { + a = vandq_s32(a, vextq_s32(a, a, 1)); + a = vandq_s32(a, vextq_s32(a, a, 2)); + return vgetq_lane_s32(a, 0); +} + +template <> +inline bool All(int16x8_t a) { + a = vandq_s16(a, vextq_s16(a, a, 1)); + a = vandq_s16(a, vextq_s16(a, a, 2)); + a = vandq_s16(a, vextq_s16(a, a, 4)); + return vgetq_lane_s16(a, 0); +} + +template <> +inline bool Any(int32x4_t a) { + a = vorrq_s32(a, vextq_s32(a, a, 1)); + a = vorrq_s32(a, vextq_s32(a, a, 2)); + return vgetq_lane_s32(a, 0); +} + +template <> +inline bool Any(int16x8_t a) { + a = vorrq_s16(a, vextq_s16(a, a, 1)); + a = vorrq_s16(a, vextq_s16(a, a, 2)); + a = vorrq_s16(a, vextq_s16(a, a, 4)); + return vgetq_lane_s16(a, 0); +} + +template <> +inline int32x4_t RoundingHalfSum(int32x4_t a, int32x4_t b) { + return vrhaddq_s32(a, b); +} + +template <> +inline int16x8_t RoundingHalfSum(int16x8_t a, int16x8_t b) { + return vrhaddq_s16(a, b); +} + +template <> +inline int32x4_t SaturatingRoundingDoublingHighMul(int32x4_t a, int32x4_t b) { + return vqrdmulhq_s32(a, b); +} + +template <> +inline int16x8_t SaturatingRoundingDoublingHighMul(int16x8_t a, int16x8_t b) { + return vqrdmulhq_s16(a, b); +} + +template <> +inline int32x4_t RoundingDivideByPOT(int32x4_t x, int exponent) { + const int32x4_t shift_vec = vdupq_n_s32(-exponent); + const int32x4_t fixup = vshrq_n_s32(vandq_s32(x, shift_vec), 31); + const int32x4_t fixed_up_x = vqaddq_s32(x, fixup); + return vrshlq_s32(fixed_up_x, shift_vec); +} + +template <> +inline int16x8_t RoundingDivideByPOT(int16x8_t x, int exponent) { + const int16x8_t shift_vec = vdupq_n_s16(-exponent); + const int16x8_t fixup = vshrq_n_s16(vandq_s16(x, shift_vec), 15); + const int16x8_t fixed_up_x = vqaddq_s16(x, fixup); + return vrshlq_s16(fixed_up_x, shift_vec); +} + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static int32x4_t eval(int32x4_t x) { return vqshlq_n_s32(x, Exponent); } +}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static int32x4_t eval(int32x4_t x) { + const int32x4_t fixup = vshrq_n_s32(x, 31); + const int32x4_t fixed_up_x = vqaddq_s32(x, fixup); + return vrshrq_n_s32(fixed_up_x, -Exponent); + } +}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static int16x8_t eval(int16x8_t x) { return vqshlq_n_s16(x, Exponent); } +}; + +template +struct ImplSaturatingRoundingMultiplyByPOT { + static int16x8_t eval(int16x8_t x) { + const int16x8_t fixup = vshrq_n_s16(x, 15); + const int16x8_t fixed_up_x = vqaddq_s16(x, fixup); + return vrshrq_n_s16(fixed_up_x, -Exponent); + } +}; + +template <> +inline int32x4_t Dup(std::int32_t x) { + return vdupq_n_s32(x); +} + +template <> +inline int16x8_t Dup(std::int16_t x) { + return vdupq_n_s16(x); +} + +// So far this is only needed for int16. +template <> +inline int16x8_t SaturatingAdd(int16x8_t a, int16x8_t b) { + return vqaddq_s16(a, b); +} + +} // end namespace gemmlowp + +#endif // GEMMLOWP_INTERNAL_FIXEDPOINT_NEON_H_ diff --git a/TensorflowLiteMicro/third_party/gemmlowp/internal/detect_platform.h b/TensorflowLiteMicro/third_party/gemmlowp/internal/detect_platform.h new file mode 100644 index 0000000..6f06d19 --- /dev/null +++ b/TensorflowLiteMicro/third_party/gemmlowp/internal/detect_platform.h @@ -0,0 +1,166 @@ +// Copyright 2018 The Gemmlowp Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// detect_platform.h: Sets up macros that control architecture-specific +// features of gemmlowp's implementation. + +#ifndef GEMMLOWP_INTERNAL_DETECT_PLATFORM_H_ +#define GEMMLOWP_INTERNAL_DETECT_PLATFORM_H_ + +// Our inline assembly path assume GCC/Clang syntax. +// Native Client doesn't seem to support inline assembly(?). +#if defined(__GNUC__) && !defined(__native_client__) +#define GEMMLOWP_ALLOW_INLINE_ASM +#endif + +// Define macro statement that avoids inlining for GCC. +// For non-GCC, define as empty macro. +#if defined(__GNUC__) +#define GEMMLOWP_NOINLINE __attribute__((noinline)) +#else +#define GEMMLOWP_NOINLINE +#endif + +// Detect ARM, 32-bit or 64-bit +#ifdef __arm__ +#define GEMMLOWP_ARM_32 +#endif + +#ifdef __aarch64__ +#define GEMMLOWP_ARM_64 +#endif + +#if defined(GEMMLOWP_ARM_32) || defined(GEMMLOWP_ARM_64) +#define GEMMLOWP_ARM +#endif + +// Detect MIPS, 32-bit or 64-bit +#if defined(__mips) && !defined(__LP64__) +#define GEMMLOWP_MIPS_32 +#endif + +#if defined(__mips) && defined(__LP64__) +#define GEMMLOWP_MIPS_64 +#endif + +#if defined(GEMMLOWP_MIPS_32) || defined(GEMMLOWP_MIPS_64) +#define GEMMLOWP_MIPS +#endif + +// Detect x86, 32-bit or 64-bit +#if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__i386) +#define GEMMLOWP_X86_32 +#endif + +#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64) +#define GEMMLOWP_X86_64 +#endif + +#if defined(GEMMLOWP_X86_32) || defined(GEMMLOWP_X86_64) +#define GEMMLOWP_X86 +#endif + +// Some of our optimized paths use inline assembly and for +// now we don't bother enabling some other optimized paths using intrinddics +// where we can't use inline assembly paths. +#ifdef GEMMLOWP_ALLOW_INLINE_ASM + +// Detect NEON. It's important to check for both tokens. +#if (defined __ARM_NEON) || (defined __ARM_NEON__) +#define GEMMLOWP_NEON +#endif + +// Convenience NEON tokens for 32-bit or 64-bit +#if defined(GEMMLOWP_NEON) && defined(GEMMLOWP_ARM_32) +#define GEMMLOWP_NEON_32 +#endif + +#if defined(GEMMLOWP_NEON) && defined(GEMMLOWP_ARM_64) +#define GEMMLOWP_NEON_64 +#endif + +// Detect MIPS MSA. +// Limit MSA optimizations to little-endian CPUs for now. +// TODO: Perhaps, eventually support MSA optimizations on big-endian CPUs? +#if defined(GEMMLOWP_MIPS) && (__mips_isa_rev >= 5) && defined(__mips_msa) && \ + defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define GEMMLOWP_MSA +#endif + +// Convenience MIPS MSA tokens for 32-bit or 64-bit. +#if defined(GEMMLOWP_MSA) && defined(GEMMLOWP_MIPS_32) +#define GEMMLOWP_MSA_32 +#endif + +#if defined(GEMMLOWP_MSA) && defined(GEMMLOWP_MIPS_64) +#define GEMMLOWP_MSA_64 +#endif + +// compiler define for AVX2 -D GEMMLOWP_ENABLE_AVX2 +// Detect AVX2 +#if defined(__AVX2__) && defined(GEMMLOWP_ENABLE_AVX2) +#define GEMMLOWP_AVX2 +// Detect SSE4. +// MSVC does not have __SSE4_1__ macro, but will enable SSE4 +// when AVX is turned on. +#elif defined(__SSE4_1__) || (defined(_MSC_VER) && defined(__AVX__)) +#define GEMMLOWP_SSE4 +// Detect SSE3. +#elif defined(__SSE3__) +#define GEMMLOWP_SSE3 +#endif + +// Convenience SSE4 tokens for 32-bit or 64-bit +#if defined(GEMMLOWP_SSE4) && defined(GEMMLOWP_X86_32) && \ + !defined(GEMMLOWP_DISABLE_SSE4) +#define GEMMLOWP_SSE4_32 +#endif + +#if defined(GEMMLOWP_SSE3) && defined(GEMMLOWP_X86_32) +#define GEMMLOWP_SSE3_32 +#endif + +#if defined(GEMMLOWP_SSE4) && defined(GEMMLOWP_X86_64) && \ + !defined(GEMMLOWP_DISABLE_SSE4) +#define GEMMLOWP_SSE4_64 +#endif + +#if defined(GEMMLOWP_SSE3) && defined(GEMMLOWP_X86_64) +#define GEMMLOWP_SSE3_64 +#endif + +#if defined(GEMMLOWP_AVX2) && defined(GEMMLOWP_X86_64) +#define GEMMLOWP_AVX2_64 +#endif + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#define GEMMLOWP_MARK_MEMORY_AS_INITIALIZED __msan_unpoison +#elif __has_feature(address_sanitizer) +#include +#define GEMMLOWP_MARK_MEMORY_AS_INITIALIZED __asan_unpoison_memory_region +#endif +#endif + +#endif // GEMMLOWP_ALLOW_INLINE_ASM + +// Detect Android. Don't conflate with ARM - we care about tuning +// for non-ARM Android devices too. This can be used in conjunction +// with x86 to tune differently for mobile x86 CPUs (Atom) vs. desktop x86 CPUs. +#if defined(__ANDROID__) || defined(ANDROID) +#define GEMMLOWP_ANDROID +#endif + +#endif // GEMMLOWP_INTERNAL_DETECT_PLATFORM_H_ diff --git a/TensorflowLiteMicro/third_party/kissfft/COPYING b/TensorflowLiteMicro/third_party/kissfft/COPYING new file mode 100644 index 0000000..2fc6685 --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/COPYING @@ -0,0 +1,11 @@ +Copyright (c) 2003-2010 Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/TensorflowLiteMicro/third_party/kissfft/SConscript b/TensorflowLiteMicro/third_party/kissfft/SConscript new file mode 100644 index 0000000..1e85b0d --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/SConscript @@ -0,0 +1,29 @@ +from building import * +import os + +cwd = GetCurrentDir() +src = Glob('tools/*.c') + Glob('*.c') + +#. +root = str(Dir('#')) +packages = os.path.join(root, 'Middlewares') +file_list = os.listdir(packages) +for f in file_list: + if(f.split('-')[0] == 'TF'): + tflm_pkg = os.path.join(packages, f) + break +#./third_party/flatbuffer/include +flatbuffer = os.path.join(tflm_pkg, "third_party/flatbuffers/include") +#./third_party/gemmlowp +gemmlowp = os.path.join(tflm_pkg, "third_party/gemmlowp") +#./third_party/kissfft +kissfft = os.path.join(tflm_pkg, "third_party/kissfft") +#./third_party/ruy +ruy = os.path.join(tflm_pkg, "third_party/ruy") + + +CPPPATH = [tflm_pkg, flatbuffer, gemmlowp, kissfft, ruy] + +group = DefineGroup('third_party', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/TensorflowLiteMicro/third_party/kissfft/_kiss_fft_guts.h b/TensorflowLiteMicro/third_party/kissfft/_kiss_fft_guts.h new file mode 100644 index 0000000..ba66144 --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/_kiss_fft_guts.h @@ -0,0 +1,164 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" +#include + +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +struct kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + kiss_fft_cpx twiddles[1]; +}; + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#if (FIXED_POINT==32) +# define FRACBITS 31 +# define SAMPPROD int64_t +#define SAMP_MAX 2147483647 +#else +# define FRACBITS 15 +# define SAMPPROD int32_t +#define SAMP_MAX 32767 +#endif + +#define SAMP_MIN -SAMP_MAX + +#if defined(CHECK_OVERFLOW) +# define CHECK_OVERFLOW_OP(a,op,b) \ + if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ + fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } +#endif + + +# define smul(a,b) ( (SAMPPROD)(a)*(b) ) +# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) + +# define S_MUL(a,b) sround( smul(a,b) ) + +# define C_MUL(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) + +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, SAMP_MAX/k ) ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) +# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) + + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) + + +#ifdef KISS_FFT_USE_ALLOCA +// define this to allow use of alloca instead of malloc for temporary buffers +// Temporary buffers are used in two case: +// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 +// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. +#include +#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) +#define KISS_FFT_TMP_FREE(ptr) +#else +#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) +#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) +#endif diff --git a/TensorflowLiteMicro/third_party/kissfft/kiss_fft.c b/TensorflowLiteMicro/third_party/kissfft/kiss_fft.c new file mode 100644 index 0000000..465d6c9 --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/kiss_fft.c @@ -0,0 +1,408 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "_kiss_fft_guts.h" +/* The guts header contains all the multiplication and addition macros that are defined for + fixed or floating point complex numbers. It also delares the kf_ internal functions. + */ + +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx * Fout2; + kiss_fft_cpx * tw1 = st->twiddles; + kiss_fft_cpx t; + Fout2 = Fout + m; + do{ + C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); + + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + }while (--m); +} + +static void kf_bfly4( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + const size_t m + ) +{ + kiss_fft_cpx *tw1,*tw2,*tw3; + kiss_fft_cpx scratch[6]; + size_t k=m; + const size_t m2=2*m; + const size_t m3=3*m; + + + tw3 = tw2 = tw1 = st->twiddles; + + do { + C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); + + C_MUL(scratch[0],Fout[m] , *tw1 ); + C_MUL(scratch[1],Fout[m2] , *tw2 ); + C_MUL(scratch[2],Fout[m3] , *tw3 ); + + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + if(st->inverse) { + Fout[m].r = scratch[5].r - scratch[4].i; + Fout[m].i = scratch[5].i + scratch[4].r; + Fout[m3].r = scratch[5].r + scratch[4].i; + Fout[m3].i = scratch[5].i - scratch[4].r; + }else{ + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + } + ++Fout; + }while(--k); +} + +static void kf_bfly3( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + size_t m + ) +{ + size_t k=m; + const size_t m2 = 2*m; + kiss_fft_cpx *tw1,*tw2; + kiss_fft_cpx scratch[5]; + kiss_fft_cpx epi3; + epi3 = st->twiddles[fstride*m]; + + tw1=tw2=st->twiddles; + + do{ + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); +} + +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int u; + kiss_fft_cpx scratch[13]; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx *tw; + kiss_fft_cpx ya,yb; + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + Fout3=Fout0+3*m; + Fout4=Fout0+4*m; + + tw=st->twiddles; + for ( u=0; ur += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } +} + +/* perform the butterfly for one stage of a mixed radix FFT */ +static void kf_bfly_generic( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int p + ) +{ + int u,k,q1,q; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx t; + int Norig = st->nfft; + + kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); + + for ( u=0; u=Norig) twidx-=Norig; + C_MUL(t,scratch[q] , twiddles[twidx] ); + C_ADDTO( Fout[ k ] ,t); + } + k += m; + } + } + KISS_FFT_TMP_FREE(scratch); +} + +static +void kf_work( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st + ) +{ + kiss_fft_cpx * Fout_beg=Fout; + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + const kiss_fft_cpx * Fout_end = Fout + p*m; + +#ifdef _OPENMP + // use openmp extensions at the + // top-level (not recursive) + if (fstride==1 && p<=5) + { + int k; + + // execute the p different work units in different threads +# pragma omp parallel for + for (k=0;k floor_sqrt) + p = n; /* no more factors, skip to end */ + } + n /= p; + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); +} + +/* + * + * User-callable function to allocate all necessary storage space for the fft. + * + * The return value is a contiguous block of memory, allocated with malloc. As such, + * It can be freed with free(), rather than a kiss_fft-specific function. + * */ +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) +{ + kiss_fft_cfg st=NULL; + size_t memneeded = sizeof(struct kiss_fft_state) + + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ + + if ( lenmem==NULL ) { + st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); + }else{ + if (mem != NULL && *lenmem >= memneeded) + st = (kiss_fft_cfg)mem; + *lenmem = memneeded; + } + if (st) { + int i; + st->nfft=nfft; + st->inverse = inverse_fft; + + for (i=0;iinverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } + + kf_factor(nfft,st->factors); + } + return st; +} + + +void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) +{ + if (fin == fout) { + //NOTE: this is not really an in-place FFT algorithm. + //It just performs an out-of-place FFT into a temp buffer + kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); + KISS_FFT_TMP_FREE(tmpbuf); + }else{ + kf_work( fout, fin, 1,in_stride, st->factors,st ); + } +} + +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) +{ + kiss_fft_stride(cfg,fin,fout,1); +} + + +void kiss_fft_cleanup(void) +{ + // nothing needed any more +} + +int kiss_fft_next_fast_size(int n) +{ + while(1) { + int m=n; + while ( (m%2) == 0 ) m/=2; + while ( (m%3) == 0 ) m/=3; + while ( (m%5) == 0 ) m/=5; + if (m<=1) + break; /* n is completely factorable by twos, threes, and fives */ + n++; + } + return n; +} diff --git a/TensorflowLiteMicro/third_party/kissfft/kiss_fft.h b/TensorflowLiteMicro/third_party/kissfft/kiss_fft.h new file mode 100644 index 0000000..c34ea5e --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/kiss_fft.h @@ -0,0 +1,131 @@ +#ifndef KISS_FFT_H +#define KISS_FFT_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ATTENTION! + If you would like a : + -- a utility that will handle the caching of fft objects + -- real-only (no imaginary time component ) FFT + -- a multi-dimensional FFT + -- a command-line utility to perform ffts + -- a command-line utility to perform fast-convolution filtering + + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c + in the tools/ directory. +*/ + +#ifdef USE_SIMD +# include +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) +#define KISS_FFT_FREE _mm_free +#else +#define KISS_FFT_MALLOC(X) (void*)(0) /* Patched. */ +#define KISS_FFT_FREE(X) /* Patched. */ +#endif + + +// Patched automatically by download_dependencies.sh so default is 16 bit. +#ifndef FIXED_POINT +#define FIXED_POINT (16) +#endif +// End patch. + +#ifdef FIXED_POINT +#include /* Patched. */ +#include +# if (FIXED_POINT == 32) +# define kiss_fft_scalar int32_t +# else +# define kiss_fft_scalar int16_t +# endif +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# endif +#endif + +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct kiss_fft_state* kiss_fft_cfg; + +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +#define kiss_fft_free free + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void kiss_fft_cleanup(void); + + +/* + * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) + */ +int kiss_fft_next_fast_size(int n); + +/* for real ffts, we need an even size */ +#define kiss_fftr_next_fast_size_real(n) \ + (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.c b/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.c new file mode 100644 index 0000000..0d22a04 --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.c @@ -0,0 +1,159 @@ +/* +Copyright (c) 2003-2004, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "kiss_fftr.h" +#include "_kiss_fft_guts.h" + +struct kiss_fftr_state{ + kiss_fft_cfg substate; + kiss_fft_cpx * tmpbuf; + kiss_fft_cpx * super_twiddles; +#ifdef USE_SIMD + void * pad; +#endif +}; + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) +{ + int i; + kiss_fftr_cfg st = NULL; + size_t subsize, memneeded; + + if (nfft & 1) { + /* fprintf(stderr,"Real FFT optimization must be even.\n"); */ + return NULL; + } + nfft >>= 1; + + kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); + memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); + + if (lenmem == NULL) { + st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); + } else { + if (*lenmem >= memneeded) + st = (kiss_fftr_cfg) mem; + *lenmem = memneeded; + } + if (!st) + return NULL; + + st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ + st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); + st->super_twiddles = st->tmpbuf + nfft; + kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); + + for (i = 0; i < nfft/2; ++i) { + double phase = + -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); + if (inverse_fft) + phase *= -1; + kf_cexp (st->super_twiddles+i,phase); + } + return st; +} + +void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) +{ + /* input buffer timedata is stored row-wise */ + int k,ncfft; + kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; + + if ( st->substate->inverse) { + /* fprintf(stderr,"kiss fft usage error: improper alloc\n"); */ + return; /* exit(1); */ + } + + ncfft = st->substate->nfft; + + /*perform the parallel fft of two real signals packed in real,imag*/ + kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); + /* The real part of the DC element of the frequency spectrum in st->tmpbuf + * contains the sum of the even-numbered elements of the input time sequence + * The imag part is the sum of the odd-numbered elements + * + * The sum of tdc.r and tdc.i is the sum of the input time sequence. + * yielding DC of input time sequence + * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... + * yielding Nyquist bin of input time sequence + */ + + tdc.r = st->tmpbuf[0].r; + tdc.i = st->tmpbuf[0].i; + C_FIXDIV(tdc,2); + CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); + CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); + freqdata[0].r = tdc.r + tdc.i; + freqdata[ncfft].r = tdc.r - tdc.i; +#ifdef USE_SIMD + freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); +#else + freqdata[ncfft].i = freqdata[0].i = 0; +#endif + + for ( k=1;k <= ncfft/2 ; ++k ) { + fpk = st->tmpbuf[k]; + fpnk.r = st->tmpbuf[ncfft-k].r; + fpnk.i = - st->tmpbuf[ncfft-k].i; + C_FIXDIV(fpk,2); + C_FIXDIV(fpnk,2); + + C_ADD( f1k, fpk , fpnk ); + C_SUB( f2k, fpk , fpnk ); + C_MUL( tw , f2k , st->super_twiddles[k-1]); + + freqdata[k].r = HALF_OF(f1k.r + tw.r); + freqdata[k].i = HALF_OF(f1k.i + tw.i); + freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); + freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); + } +} + +void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) +{ + /* input buffer timedata is stored row-wise */ + int k, ncfft; + + if (st->substate->inverse == 0) { + /* fprintf (stderr, "kiss fft usage error: improper alloc\n"); */ + return; /* exit (1); */ + } + + ncfft = st->substate->nfft; + + st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; + st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; + C_FIXDIV(st->tmpbuf[0],2); + + for (k = 1; k <= ncfft / 2; ++k) { + kiss_fft_cpx fk, fnkc, fek, fok, tmp; + fk = freqdata[k]; + fnkc.r = freqdata[ncfft - k].r; + fnkc.i = -freqdata[ncfft - k].i; + C_FIXDIV( fk , 2 ); + C_FIXDIV( fnkc , 2 ); + + C_ADD (fek, fk, fnkc); + C_SUB (tmp, fk, fnkc); + C_MUL (fok, tmp, st->super_twiddles[k-1]); + C_ADD (st->tmpbuf[k], fek, fok); + C_SUB (st->tmpbuf[ncfft - k], fek, fok); +#ifdef USE_SIMD + st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); +#else + st->tmpbuf[ncfft - k].i *= -1; +#endif + } + kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); +} diff --git a/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.h b/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.h new file mode 100644 index 0000000..72e5a57 --- /dev/null +++ b/TensorflowLiteMicro/third_party/kissfft/tools/kiss_fftr.h @@ -0,0 +1,46 @@ +#ifndef KISS_FTR_H +#define KISS_FTR_H + +#include "kiss_fft.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/* + + Real optimized version can save about 45% cpu time vs. complex fft of a real seq. + + + + */ + +typedef struct kiss_fftr_state *kiss_fftr_cfg; + + +kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); +/* + nfft must be even + + If you don't care to allocate space, use mem = lenmem = NULL +*/ + + +void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); +/* + input timedata has nfft scalar points + output freqdata has nfft/2+1 complex points +*/ + +void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); +/* + input freqdata has nfft/2+1 complex points + output timedata has nfft scalar points +*/ + +#define kiss_fftr_free free + +#ifdef __cplusplus +} +#endif +#endif diff --git a/TensorflowLiteMicro/third_party/ruy/ruy/profiler/instrumentation.h b/TensorflowLiteMicro/third_party/ruy/ruy/profiler/instrumentation.h new file mode 100644 index 0000000..c4df1e6 --- /dev/null +++ b/TensorflowLiteMicro/third_party/ruy/ruy/profiler/instrumentation.h @@ -0,0 +1,203 @@ +/* Copyright 2020 Google LLC. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef RUY_RUY_PROFILER_INSTRUMENTATION_H_ +#define RUY_RUY_PROFILER_INSTRUMENTATION_H_ + +#ifdef RUY_PROFILER +#include +#include +#include +#endif + +namespace ruy { +namespace profiler { + +#ifdef RUY_PROFILER + +// A label is how a code scope is annotated to appear in profiles. +// The stacks that are sampled by the profiler are stacks of such labels. +// A label consists of a literal string, plus optional integer arguments. +class Label { + public: + Label() {} + template + explicit Label(Args... args) { + Set(args...); + } + void Set(const char* format) { + format_ = format; + args_count_ = 0; + } + template + void Set(const char* format, Args... args) { + format_ = format; + args_count_ = sizeof...(args); + SetArgs(0, args...); + } + + void operator=(const Label& other); + + bool operator==(const Label& other) const; + + std::string Formatted() const; + const char* format() const { return format_; } + + private: + void SetArgs(int position, int arg0) { args_[position] = arg0; } + + template + void SetArgs(int position, int arg0, Args... args) { + SetArgs(position, arg0); + SetArgs(position + 1, args...); + } + + static constexpr int kMaxArgs = 4; + const char* format_ = nullptr; + int args_count_ = 0; + int args_[kMaxArgs]; +}; + +namespace detail { + +// Forward-declaration, see class ThreadStack below. +class ThreadStack; + +bool& GlobalIsProfilerRunning(); + +// Returns the global vector of pointers to all stacks, there being one stack +// per thread executing instrumented code. +std::vector* GlobalAllThreadStacks(); + +// Returns the mutex to be locked around any access to GlobalAllThreadStacks(). +std::mutex* GlobalsMutex(); + +// Returns the thread-local stack, specific to the current thread. +ThreadStack* ThreadLocalThreadStack(); + +// This 'stack' is what may be more appropriately called a 'pseudostack': +// It contains Label entries that are 'manually' entered by instrumentation +// code. It's unrelated to real call stacks. +struct Stack { + std::uint32_t id = 0; + static constexpr int kMaxSize = 64; + int size = 0; + Label labels[kMaxSize]; +}; + +// Returns the buffer byte size required by CopyToSample. +int GetBufferSize(const Stack& stack); + +// Copies this Stack into a byte buffer, called a 'sample'. +void CopyToBuffer(const Stack& stack, char* dst); + +// Populates this Stack from an existing sample buffer, typically +// produced by CopyToSample. +void ReadFromBuffer(const char* src, Stack* stack); + +// ThreadStack is meant to be used as a thread-local singleton, assigning to +// each thread a Stack object holding its pseudo-stack of profile labels, +// plus a mutex allowing to synchronize accesses to this pseudo-stack between +// this thread and a possible profiler thread sampling it. +class ThreadStack { + public: + ThreadStack(); + ~ThreadStack(); + + const Stack& stack() const { return stack_; } + + // Returns the mutex to lock around any access to this stack. Each stack is + // accessed by potentially two threads: the thread that it belongs to + // (which calls Push and Pop) and the profiler thread during profiling + // (which calls CopyToSample). + std::mutex& Mutex() const { return mutex_; } + + // Pushes a new label on the top of this Stack. + template + void Push(Args... args) { + // This mutex locking is needed to guard against race conditions as both + // the current thread and the profiler thread may be concurrently accessing + // this stack. In addition to that, this mutex locking also serves the other + // purpose of acting as a barrier (of compiler code reordering, of runtime + // CPU instruction reordering, and of memory access reordering), which + // gives a measure of correctness to this profiler. The downside is some + // latency. As this lock will be uncontended most of the times, the cost + // should be roughly that of an sequentially-consistent atomic access, + // comparable to an access to the level of CPU data cache that is shared + // among all cores, typically 60 cycles on current ARM CPUs, plus side + // effects from barrier instructions. + std::lock_guard lock(mutex_); + // Avoid overrunning the stack, even in 'release' builds. This profiling + // instrumentation code should not ship in release builds anyway, the + // overhead of this check is negligible, and overrunning a stack array would + // be bad. + if (stack_.size >= Stack::kMaxSize) { + abort(); + } + stack_.labels[stack_.size++].Set(args...); + } + + // Pops the top-most label from this Stack. + void Pop() { + // See the comment in Push about this lock. While it would be tempting to + // try to remove this lock and just atomically decrement size_ with a + // store-release, that would not necessarily be a substitute for all of the + // purposes that this lock serves, or if it was done carefully to serve all + // of the same purposes, then that wouldn't be faster than this (mostly + // uncontended) lock. + std::lock_guard lock(mutex_); + stack_.size--; + } + + private: + mutable std::mutex mutex_; + Stack stack_; +}; + +} // namespace detail + +// RAII user-facing way to construct Labels associated with their life scope +// and get them pushed to / popped from the current thread stack. +class ScopeLabel { + public: + template + ScopeLabel(Args... args) : thread_stack_(detail::ThreadLocalThreadStack()) { + thread_stack_->Push(args...); + } + + ~ScopeLabel() { thread_stack_->Pop(); } + + private: + detail::ThreadStack* thread_stack_; +}; + +#else // no RUY_PROFILER + +class ScopeLabel { + public: + template + explicit ScopeLabel(Args...) {} + + // This destructor is needed to consistently silence clang's -Wunused-variable + // which seems to trigger semi-randomly. + ~ScopeLabel() {} +}; + +#endif + +} // namespace profiler +} // namespace ruy + +#endif // RUY_RUY_PROFILER_INSTRUMENTATION_H_ diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..a9a9740 --- /dev/null +++ b/__init__.py @@ -0,0 +1,11 @@ +# coding=utf-8 +''' +@ Summary: +@ Update: + +@ file: __init__.py.py +@ version: 1.0.0 + +@ Author: Lebhoryi@gmail.com +@ Date: 2020/12/23 16:08 +''' diff --git a/backend_plugin_tflm/backend_tflm.c b/backend_plugin_tflm/backend_tflm.c new file mode 100644 index 0000000..d708ba0 --- /dev/null +++ b/backend_plugin_tflm/backend_tflm.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09-29 derekduke the first version + */ + +#include +#include +#ifdef RT_AI_USE_TFLM + +#define tflm_load_model person_detect_init +#define tflm_run_model person_detect +#define tflm_get_model + +extern uint32_t g_ai_done_flag; +static void kpu_done_callback(void *data) +{ + g_ai_done_flag = 1; +} + +static int _tflm_init(rt_ai_t ai, rt_ai_buffer_t *buf) +{ + tflm_load_model(TFLITE(ai)->model); + return 0; +} + +static int _tflm_run(rt_ai_t ai, void (*callback)(void *arg), void *arg) +{ + tflm_run_model(); + return 0; +} + +static int _tflm_get_ouput(rt_ai_t ai, rt_ai_uint32_t index) +{ + return 0; +} + +static int _tflm_get_info(rt_ai_t ai, rt_ai_buffer_t *buf) +{ + return 0; +} + +static int _tflm_config(rt_ai_t ai, int cmd, rt_ai_buffer_t *args) +{ + return 0; +} + +int backend_tflm(void *tflm_s) +{ + RT_AI_T(tflm_s)->init = _tflm_init; + RT_AI_T(tflm_s)->run = _tflm_run; + RT_AI_T(tflm_s)->get_output = _tflm_get_ouput; + RT_AI_T(tflm_s)->get_info = _tflm_get_info; + RT_AI_T(tflm_s)->config = _tflm_config; + RT_AI_T(tflm_s)->mem_flag = ALLOC_INPUT_BUFFER_FLAG; + + return 0; +} + +#endif //RT_AI_USE_TFLM diff --git a/backend_plugin_tflm/backend_tflm.h b/backend_plugin_tflm/backend_tflm.h new file mode 100644 index 0000000..6169956 --- /dev/null +++ b/backend_plugin_tflm/backend_tflm.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09-29 derekduke the first version + */ + +#ifndef __BACKEND_tflm_H__ +#define __BACKEND_tflm_H__ +#include +#include "rt_ai.h" +#ifdef RT_AI_USE_TFLM + +struct tflm +{ + struct rt_ai parent; + uint8_t *model; +}; +typedef struct tflm *tflm_t; +#define TFLM(h) ((tflm_t)(h)) + +int backend_tflm(void *tflm_s); +#endif //RT_AI_USE_TFLM +#endif + diff --git a/backend_plugin_tflm/readme.md b/backend_plugin_tflm/readme.md new file mode 100644 index 0000000..5394d6b --- /dev/null +++ b/backend_plugin_tflm/readme.md @@ -0,0 +1,3 @@ +# RTAK-backend_imx6ull_tflite + +RTAK imx6ull-tflite后端适配层 \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..779b568 --- /dev/null +++ b/config.py @@ -0,0 +1,35 @@ +# coding=utf-8 +''' +@ Summary: +@ Update: + +@ file: config.py.py +@ version: 1.0.0 + +@ Author: Lebhoryi@gmail.com +@ Date: 2021/2/25 11:08 +''' + + +# support models +sup_models = { + "keras": [".h5", ".hdf5", ".json", ".yml", ".yaml"], + "tflite": [".tflite"], + "lasagne": [".npz", ".npz"], + "caffe": [".prototxt", ".caffemodel"], + "convnetjs": [".json"], + "onnx": [".onnx"], +} + +# support cpus +sup_cpus = ["H7", "MP1", "WL", "M4", "M7", "M33" , "tflm"] + +# x-cube-ai libraries and c-model dir +tflm_dirs = ["Middlewares", "TFLite"] + +# sconscripts path +sconscript_path = "platforms/plugin_tflm/Sconscripts" + +# support modes:{analyze, validate, generate} +sup_modes = {"001", "011", "101", "111"} + diff --git "a/docs/RT-AK\344\271\213tflm\345\277\253\351\200\237\344\270\212\346\211\213.md" "b/docs/RT-AK\344\271\213tflm\345\277\253\351\200\237\344\270\212\346\211\213.md" new file mode 100644 index 0000000..643128b --- /dev/null +++ "b/docs/RT-AK\344\271\213tflm\345\277\253\351\200\237\344\270\212\346\211\213.md" @@ -0,0 +1,124 @@ +

RT-AK imx6ull 快速上手

+ +[TOC] + +*本项目为 `RT-AK` 的一个实战 `DEMO`。* + +*本教程 RT-AK 搭配平台插件:imx6ull* + +- Windows 10 +- Python >= 3.7 + +# 1. 准备工作 + +准备以下三份材料: + +| Index | Prepare | Example | +| :---: | :-------------: | ------------------------------------------------------------ | +| 1 | 硬件以及 `BSP` | `imx6ull(正点阿尔法) BSP` | +| 2 | 神经网络模型 | `./rt_ai_tools/Model/facelandmark.tflite` | | +| 3 | `RT-AK` | [RT-AK](https://github.com/RT-Thread/RT-AK.git) 代码克隆到本地 | + +- 下载 `imx6ull BSP` 地址: [imx6ull](https://github.com/Derekduke/imx6ull.git) + +# 2. 执行步骤 + +> 代码将会自动使用 `tensorflow lite micro` 推理后端,获得一个集成了 AI 的 BSP +> +> 对,就是这么硬核,一步肝到位! + +内部的流程请看源码或者 `plugin_tflm` 仓库下的 `readme` 文档 + +# 3. 运行命令 + +请在 `edge-ai/RTAK/tools` 路径下运行该程序。 + + +```shell +# 基础运行命令 +python aitools.py --project --model_name --platform tflm + +# 示例 +python aitools.py --project="D:\Code\Project\imx6ullrtak\imx6ull" --model="./Models/facelandmark.tflite" --platform=tflm --clear +``` + +![](./pic/run_example.png) + +# 4.编译 + +支持的编译器 + +- `Env Scons` + +- [Env 工具](https://www.rt-thread.org/document/site/#) + +进入到 `BSP` 项目工程路径,右键打开 Env + +执行: + +```shell +# 这是个好习惯 +$ scons -c +$ scons -j 6 +``` + +![](./pic/env_scons.png) + + +# 5. 下载 + +根据前面的步骤,已经成功获得了一个集成了 `AI` 和 `RT-Thread` 的新的 `ART-Pi BSP`, + +就可以`RT-Thread` 系统上做应用开发: + +```c +#include +#include +#include + +int ai_app(void) +{ + rt_err_t result = RT_EOK; + model = rt_ai_find(RT_AI_NETWORK_MODEL_NAME); + if(model == RT_AI_NULL){ + return -1; + } + rt_kprintf("find ai model success\n"); + //初始化模型 + result = rt_ai_init(model , NULL); + if(result != 0){ + return -1; + } + rt_kprintf("init ai model success\n"); + result = rt_ai_run(model , NULL, NULL); + if (result != 0) { + rt_kprintf("ai model run err\r\n"); + return -1; + } + rt_kprintf("run ai model success\n"); +} +MSH_CMD_EXPORT(ai_app , "test ai function"); +``` + +应用开发 `API` 见 [rt_ai_lib/readme](../rt_ai_lib) + +完整的示例工程:https://github.com/EdgeAIWithRTT/Project3-Mnist_Cube_RTT/tree/master/Mnist_RTT + + +1. 打开Tftpd64软件设置tftp烧录路径 + +![tftpd64](./pic/tftpd64.png) + +2. 在uboot中设置tftp烧录 + +```c +setenv bootcmd "dhcp 0x87800000 192.168.1.101:rtthread.bin;dcache flush;go 0x87800000" +``` + +3. 重启开发板 + +![ai_app](./pic/ai_app.png) + + + + diff --git a/docs/pic/ai_app.png b/docs/pic/ai_app.png new file mode 100644 index 0000000..595ac0d Binary files /dev/null and b/docs/pic/ai_app.png differ diff --git a/docs/pic/env_scons.png b/docs/pic/env_scons.png new file mode 100644 index 0000000..d141b08 Binary files /dev/null and b/docs/pic/env_scons.png differ diff --git a/docs/pic/run_example.png b/docs/pic/run_example.png new file mode 100644 index 0000000..0d7b1dc Binary files /dev/null and b/docs/pic/run_example.png differ diff --git a/docs/pic/tftpd64.png b/docs/pic/tftpd64.png new file mode 100644 index 0000000..4769a34 Binary files /dev/null and b/docs/pic/tftpd64.png differ diff --git a/docs/version.md b/docs/version.md new file mode 100644 index 0000000..5490332 --- /dev/null +++ b/docs/version.md @@ -0,0 +1,15 @@ + + +| Date | Description | +| ---------- | ------------------------ | +| 2021/09/29 | 第一个版本 | + + + +| Version | Date | Description | +| ------- | ---------- | -------------------------------------- | +| V0.0.1 | 2021/09/29 | 第一个版本,不支持模型解析 +| | | | \ No newline at end of file diff --git a/gen_rt_ai_model_c.py b/gen_rt_ai_model_c.py new file mode 100644 index 0000000..e0bddd2 --- /dev/null +++ b/gen_rt_ai_model_c.py @@ -0,0 +1,67 @@ +# coding=utf-8 +''' +@ Summary: generate rt_ai__model.c + rt_ai_template.c/h +@ Update: 将会在稳定版本被移除,需要后续做修改 + +@ file: gen_rt_ai_model_c.py +@ version: 1.0.0 + +@ Author: Lebhoryi@gmail.com +@ Date: 2021/2/26 11:13 +''' +import re +import logging +from pathlib import Path + + +def update_network_name(info_file, new_example_file, default_name, model_name): + """ replace old_name by new_name """ + # load file + with info_file.open() as fr: + lines = fr.read() + + if default_name != model_name: + old_name_list = [default_name, default_name.upper()] + new_name_list = [model_name, model_name.upper()] + + # replace file + for i in range(len(old_name_list)): + lines = re.sub(old_name_list[i], new_name_list[i], lines) + + # save new example file + with new_example_file.open("w") as fw: + fw.write(lines) + + return new_example_file + + +def load_rt_ai_example(project, rt_ai_example, platform, old_name, new_name): + """ replace old_name by new_name; RTAK inference example and rt_ai_model file""" + rt_ai_example = Path(rt_ai_example) + + # model.c + file = rt_ai_example / "rt_ai_template_model.c" + new_file_name = f"rt_ai_network_model.c" + example_file = Path(project) / "applications" / new_file_name + if example_file.exists(): example_file.unlink() + + update_network_name(file, example_file, old_name, new_name) + + logging.info("Load rt_ai examples successfully...") + return True + + +if __name__ == "__main__": + logging.getLogger().setLevel(logging.INFO) + + project = "tmp_cwd" + tmp_project = Path("tmp_cwd") / "applications" + if not tmp_project.exists(): + tmp_project.mkdir() + + rt_ai_example = "../../Documents" + platform = "tflm" + old_name = "mnist" + new_name = "network" + load_rt_ai_example(project, rt_ai_example, platform, old_name, new_name) + print("u a right...") \ No newline at end of file diff --git a/generate_rt_ai_model_h.py b/generate_rt_ai_model_h.py new file mode 100644 index 0000000..68ed8e7 --- /dev/null +++ b/generate_rt_ai_model_h.py @@ -0,0 +1,62 @@ +# coding=utf-8 +''' +@ Summary: +@ Update: + +@ file: generate_rt_ai_model_h.py +@ version: 1.0.0 + +@ Author: Lebhoryi@gmail.com +@ Date: 2021/2/4 16:32 +''' +import os +import sys +import logging +from pathlib import Path + +path = os.path.dirname(__file__) +sys.path.append(os.path.join(path, '../../')) + +from platforms.plugin_tflm import plugin_tflm_parser + +def check_file(file): + assert Path(file).exists(), logging.error(f"No such file {file} exists!") + +def read_file(file): + check_file(file) + with open(file, "r") as f: + lines = f.readlines() + return lines + +def get_model_info(template, model_name, default_name="network"): + template_lines = read_file(template) + return template_lines + +def rt_ai_model_gen(stm_out, project, model_name, rt_ai_example): + # modol informations + + template_file = Path(rt_ai_example)/"rt_ai_template_model.h" + model_info = get_model_info(template_file, model_name) + + # project/applications/.h + pro_app_model_h = Path(project) / "applications" / f"rt_ai_{model_name}_model.h" + #pro_app_model_h = Path(project) / "applications" / f"rt_ai_network_model.h" + if pro_app_model_h.exists(): pro_app_model_h.unlink() + + with pro_app_model_h.open("w+") as fw: + fw.write("".join(model_info)) + + logging.info(f"Generate rt_ai_{model_name}_model.h successfully...") + + +if __name__ == "__main__": + logging.getLogger().setLevel(logging.INFO) + convert_info = "" + tmp_project = Path("tmp_cwd") + app_path = tmp_project / "applications" + + if not app_path.exists(): + app_path.mkdir(parents=True) + + report = "./convert_report.txt" + _ = rt_ai_model_gen(report, tmp_project, "facelandmark") \ No newline at end of file diff --git a/plugin_tflm.py b/plugin_tflm.py new file mode 100644 index 0000000..89e1405 --- /dev/null +++ b/plugin_tflm.py @@ -0,0 +1,251 @@ +# coding=utf-8 +''' +@ Summary: Platform: imx6ull + 1. check part + 2. prepare part + 3. convert model + 4. load lib + 5. load to project +@ Update: + +@ file: plugin_imx6ull.py +@ version: 1.0.0 + +@ Author: dkeji627@gmail.com +@ Date: 2021/09/29 20:55 + +@ Update: +@ Date: + +''' +import os +import sys +import re +import logging +import datetime +import shutil +from pathlib import Path + + +path = os.path.dirname(__file__) +sys.path.append(os.path.join(path, '../../')) + +from platforms.plugin_tflm.config import * +from platforms.plugin_tflm import prepare_work +from platforms.plugin_tflm import generate_rt_ai_model_h +from platforms.plugin_tflm import gen_rt_ai_model_c + + +def readonly_handler(func, path): + # Change the mode of file, to make it could be used of shutil.rmtree + os.chmod(path, 128) + func(path) + + +class Plugin(object): + def __init__(self, opt): + self.project = opt.project # project path + # self.model_path = os.path.abspath(opt.model) # model path + self.model_path = opt.model + self.rt_ai_example = opt.rt_ai_example # Documents + self.platform = opt.platform + self.c_model_name = opt.model_name.lower() # c model name + + # config.py + self.sup_models = sup_models + self.sup_cpus = sup_cpus + self.tflm_dirs = tflm_dirs # tflite libraries + self.sconscript_path = sconscript_path + self.sup_modes = sup_modes # support modes:{analyze, validate, generate} + + # imx6ull + self.ext_tools = opt.ext_tools + self.tflite = opt.tflite # tflite micro libraries + self.network = opt.network # default network name in sample files + self.enable_rt_lib = opt.enable_rt_lib # enable imx6ull in /rtconfig.h + self.clear = opt.clear + + # setting aitools: tflm output path + self.tflm_out = opt.tflm_out if opt.tflm_out else \ + datetime.date.today().strftime("%Y%m%d") + + # check the model + self.is_valid_model(self.model_path, self.sup_models) + + # check the cpu + self.cpu = self.is_valid_cpu(self.project, self.sup_cpus) + + + def is_valid_model(self, model, sup_models): + """ Determine whether the model supports""" + # model suffix: ".h5" + m_suf = Path(model).suffix + + # all supportted models suffix + m_suf_lists = list() + for value in sup_models.values(): + m_suf_lists += value + + logging.info("The model is '{}'".format(Path(model).name)) + if m_suf not in m_suf_lists: + raise IOError("The '{}' is not surpported now...".format(model)) + + + def is_valid_cpu(self, project, sup_cpus, cpu=""): + """ Determine whether the cpu supports""" + project = Path(project) + assert project.exists(), IOError("{} does not exist".format(project)) + + # get cpu information + sys.path.append(str(project)) # add rt_config.py path + import rtconfig + # CPU = 'imx6ull' + real_cpu = rtconfig.CPU[7:].upper() # M4 M7 M33 + real_cpu = "tflm" #手动强行赋值,暂时无平台差异 + print("real_cpu : " , real_cpu) + # get chip information + rt_config_path = project / "rtconfig.h" + with open(rt_config_path, "r") as f: + rt_config_text = f.read() + #chip = re.findall(r"SOC_SERIES_STM32\w\d", rt_config_text)[0] + #platform = chip[16:] # H7 MP1 WL + + if real_cpu in sup_cpus: + cpu = real_cpu + #elif platform in sup_cpus: + # cpu = platform + else: + raise Exception("The cpu is not in supported now...") + + logging.info("The cpu is '{}'".format(cpu)) + return cpu + + + def get_lib_path(self, stm_lib, cpu): + """ load lib path """ + # select M7 folders + for dir in os.listdir(stm_lib): + if cpu in dir: + lib_path = stm_lib / dir + lib_path = list(filter(lambda path: "PIC" not in path.name, lib_path.iterdir()))[0] + filename = "lib" + lib_path.name if stm_lib.name[:3] == "GCC" \ + else lib_path.name + return lib_path, filename + + + def load_lib(self, tflm_out, tflite_path, cpu, middle=r"Middlewares/TF"): + """ Loading tflite libs to from tflmai package + + Args: + imx6ull_out: tflite output path, str + tflite_path: tflite libraries + path, str + cpu: the project's cpu, str + middle: r"Middlewares/TF/", str + + Returns: + result: AI Lib files would be copied. list + + Raise: + Failed copy Inc/Lib dir from to + """ + # list of aitools_out files + result = list() + target, source = Path(tflm_out), Path(tflite_path) + # load tflite package path + source_list = [source] + target_list = [target / middle] + + # load Inc + if target_list[0].exists(): # if the file have existed, delete it first. + shutil.rmtree(target_list[0], onerror=readonly_handler) + try: + shutil.copytree(source_list[0], target_list[0]) + except Exception: + raise Exception("Failed to load Inc???") + + logging.info("Loading tflm libs successfully...") + + + def load_to_project(self, tflm_out, project, tflm_dirs): + """ load TFLite / Middleware dir to project """ + # load TFLite & Middleware + for path in tflm_dirs: + source, target = Path(tflm_out) / path, Path(project) / path + if target.exists(): + shutil.rmtree(target, onerror=readonly_handler) + try: + shutil.copytree(source, target) + except Exception: + raise Exception("Failed to load {}???".format(path)) + logging.info("{} loading to project successfully...".format(source.name)) + + def c_model_convert(self, tflm_out , model_path): + c_model_name = model_path[9:-7] + tflite_model = Path(tflm_out) / "TFLite/App" + assert tflite_model.exists(), "No TFLite/App exists, pls check the path!!!" + + # convert model to c_model + model_data_c_path = str(tflite_model)+"/"+c_model_name+"_data.c" + model_data_h_path = str(tflite_model)+"/"+c_model_name+"_data.h" + + print("c_model_name: " + c_model_name) + #if model_data_c.exists(): model_data_c.unlink() + print("model_data_c path:" , model_data_c_path) + + os.system("xxd -i "+ "./Models/"+c_model_name +".tflite"+" > " +model_data_c_path) + print("xxd convert over") + with open(model_data_c_path , 'r+') as f: + content = f.read() + f.seek(0,0) + include_path = "#include \n\n" + f.write(include_path+'const '+content) + + with open(model_data_h_path , 'w+') as f: + content = f.read() + f.seek(0,0) + c_model_data_define = "extern const unsigned char" + " __Models_"+c_model_name+"_tflite[];\n" + f.write(c_model_data_define) + + def run_plugin(self,): + """start tflite micro: running """ + logging.info("start to run_plugin...") + # 1. prepare part + # 1.1 imx6ull ext_tools env settings + + # 1.2 create two dirs and SConscripts + prepare_work.pre_sconscript(self.tflm_out, self.sconscript_path, self.tflm_dirs) + + # 2. convert model + _ = self.c_model_convert(self.tflm_out, self.model_path) + + # 3.1 generate rt_ai__model.h + _ = generate_rt_ai_model_h.rt_ai_model_gen(self.tflm_out, self.project, + self.c_model_name, self.rt_ai_example) + + # 3.2 load rt_ai__model.c + _ = gen_rt_ai_model_c.load_rt_ai_example(self.project, self.rt_ai_example, self.platform, + self.network, self.c_model_name) + + # 4. load lib from to + # copy lib files from tflm to current dir + self.load_lib(self.tflm_out, self.tflite, self.cpu) + + # 5. load to project + self.load_to_project(self.tflm_out, self.project, self.tflm_dirs) + + # 6. remove imx6ull output dirs or not + if os.path.exists(self.tflm_out) and self.clear: + shutil.rmtree(self.tflm_out, onerror=readonly_handler) + +if __name__ == "__main__": + os.chdir("../..") + logging.getLogger().setLevel(logging.INFO) + + class Opt(): + def __init__(self): + self.tflite = "./platforms/tflm/TensorflowLiteMicro" + + opt = Opt() + tflm = Plugin(opt) + tflm.run_plugin() diff --git a/plugin_tflm_parser.py b/plugin_tflm_parser.py new file mode 100644 index 0000000..4704b64 --- /dev/null +++ b/plugin_tflm_parser.py @@ -0,0 +1,38 @@ +# coding=utf-8 +''' +@ Summary: +@ Update: + +@ file: plugin_tflm_parser.py +@ version: 1.0.0 + +@ Author: dkeji627@gmail.com +@ Date: 2021/9/29 21:50 +''' +def platform_parameters(parser): + """ imx6ull platform parameters """ + parser.add_argument("--ext_tools", type=str, default="", help="") + parser.add_argument("--tflite", type=str, default="./platforms/plugin_tflm/TensorflowLiteMicro", + help="tensorflow lite micro dir") + parser.add_argument("--rt_ai_example", type=str, default="./platforms/plugin_tflm/templates", + help="Model & platform informations registered to RT-AK Lib, eg:imx6ull, stm32, k210.") + parser.add_argument("--tflm_out", type=str, default="", + help="TFLite output dir") + parser.add_argument("--workspace", type=str, default="tflmai_ws", + help="indicates a working/temporary directory for the intermediate/temporary files") + parser.add_argument("--val_data", type=str, default="", + help="indicates the custom test data set which must be used," + "now is not supported") + parser.add_argument("--compress", type=int, default=1, + help="indicates the expected global factor of compression which will be applied." + "1|4|8") + parser.add_argument("--batches", type=int, default=10, + help="indicates how many random data sample is generated (default: 10)") + parser.add_argument("--mode", type=str, default="001", + help="Describe analyze|validate|generate, 0 is False") + parser.add_argument("--network", type=str, default="network", + help="The model name in '/Documents/ files'") + parser.add_argument("--enable_rt_lib", type=str, default="RT_AI_USE_TFLM", + help="Enabel RT-AK Lib using tflite") + parser.add_argument("--clear", action="store_true", help="remove tflm middleware") + return parser diff --git a/prepare_work.py b/prepare_work.py new file mode 100644 index 0000000..1a70c2d --- /dev/null +++ b/prepare_work.py @@ -0,0 +1,53 @@ +# coding=utf-8 +''' +@ Summary: prepare + 1. create two dirs: + /Middlewares + /TFLite + 2. load 'SConscript' files +@ Update: + +@ file: prepare_work.py +@ version: 1.0.0 + +@ Author: dkeji627@gmail.com +@ Date: 2021/09/29 21:50 + +''' +import shutil +import logging +from pathlib import Path + + +def pre_sconscript(stm_out, sconscripts, tflm_dirs): + stm_out, sconscripts = Path(stm_out), Path(sconscripts) + + # delete the dir first + if stm_out.exists(): shutil.rmtree(stm_out) + + for i, dir in enumerate(tflm_dirs): + # step 1: create two dirs ("Middlewares", "TFLite") + new_dir = stm_out / dir / ("TF" if i == 0 else "App") + print(new_dir) + new_dir.mkdir(parents=True, exist_ok=True) + + # step 2: load sconscript file to + source_scons = sconscripts / dir + target_scons = stm_out / dir / "SConscript" + if not source_scons.exists(): + raise FileNotFoundError(f"Not {source_scons} file found!!!") + shutil.copy(source_scons, target_scons) + + logging.info(f"Create two dirs: {' '.join(tflm_dirs)} successfully...") + + +if __name__ == "__main__": + logging.getLogger().setLevel(logging.INFO) + + stm_out = 'tmp_cwd' + scons_path = "./Sconscripts" + tflm_dirs = ["Middlewares", "TFLite"] + + # 2. prepare tmp output + _ = pre_sconscript(stm_out, scons_path, tflm_dirs) + print("u a right...") diff --git a/templates/rt_ai_template_model.c b/templates/rt_ai_template_model.c new file mode 100644 index 0000000..89bca69 --- /dev/null +++ b/templates/rt_ai_template_model.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +extern unsigned char __Models_person_detect_tflite[]; + +#define RT_IMX6ULL_AI_NETWORK { \ + .model = __Models_person_detect_tflite, \ +} + +static struct imx6ull_tflite rt_imx6ull_tflite_network_model = RT_IMX6ULL_AI_NETWORK; + +static int rt_ai_network_model_init(){ + rt_ai_register(RT_AI_T(&rt_imx6ull_tflite_network_model),RT_AI_NETWORK_MODEL_NAME,0,backend_imx6ull_tflite,&rt_imx6ull_tflite_network_model); + rt_kprintf("ai register success\n"); + return 0; +} +INIT_APP_EXPORT(rt_ai_network_model_init); \ No newline at end of file diff --git a/templates/rt_ai_template_model.h b/templates/rt_ai_template_model.h new file mode 100644 index 0000000..8c66cbf --- /dev/null +++ b/templates/rt_ai_template_model.h @@ -0,0 +1 @@ +#define RT_AI_NETWORK_MODEL_NAME "network" \ No newline at end of file