4.3:AT 开源接口
- PWLINK2(含Lite)、PW400 不支持当前页面所描述的功能,请留意。
1.1 概览
AT命令端口,支持从PowerWriter 两端控制输入和输出,即 USB端口和扩展通用RX/TX 口输入和输入命令:
PWX1 不支持UART端口AT。
- USB-CDC :用户可以通过USB-CDC 下发数据到PowerWriter ,也可以通过PowerWriter 支持的AT 命令控制PowerWriter 的行为,读取状态或者数据,这种模式适合用户二次开发桌面软件来集成PowerWriter 来控制生产流程。
- 硬件端UART(输出串口):用户除了使用USB -CDC 来控制PowerWriter 的行为之外,也可以将PowerWriter 集成到硬件控制系统中来来控制PowerWriter 的行为,数据上传和下载,这种模式适合脱离桌面系统的开发模式。
仓库地址:
#github(推介下载上面的压缩包)
git clone https://github.com/openpowerwriter/PowerWriter_AT_Command.git
#gitee 码云(推介下载上面的压缩包)
git clone https://gitee.com/openpowerwriter/PowerWriter_AT_Command.git
1.2 AT 命令使能
使用AT 功能需要先对设备开启AT 模式,参考: 设备首选项..
1.3 AT 命令结构
标准的AT 命令 以 "AT" 开头,以回车CR(LF) 作为结尾,返回的响应样式是<回车><换行><响应内容><回车><换行>, 为纯字符串终端响应模式,在PowerWriter 上,由于部分接口需要发送大数据,以及数据加密需求,以及更好的实时性,降低通信带宽占用,综合权衡,PowerWriter 开放AT接口采用统一的二进制格式,以便提供更好的性能,指令结构如下所示:
frame header | length | data | crc32 |
---|---|---|---|
"PWAT" | uint32_t | object | crc32 |
frame header : 同步头信号,用于PowerWriter 从流中获取 AT 命令,四字节,无 ‘\0’ 结尾。
length: 命令帧长度,含:Frameheader、length、data、crc32。
data: object 类型,为命令实体数据,与对应的命令有关,具体请参考AT命令详情以及代码。
data 的格式定义如下
typedef struct S_ATCmdObject{
E_ATcmdType m_cmdType; //Type
uint32_t m_cmdSize; //Size
U_ATCmdProprety * m_cmdPropretyp; //Payload
}S_ATCmdObject;m_cmdType: 表示命令类型,具体请参考E_ATcmdType的定义
m_cmdSize:表示当前命令的有效数据长度(预留)
U_ATCmdProprety *:表示当前命令的属性节点,每一个命令都有各自的属性节点,具体请参考 U_ATCmdProprety 的定义。
crc32:命令帧的整帧校验值(frameheader、length、data),参数配置:
Polynomial : 0x04C11DB7
Initial/Final remainder : 0xffffffff
Input/Output reverse : yes
- 接口数据可选AES128CBC 加密,通讯密码需在PowerWriter 端手动设置。
- 纯命令行式 的AT 接口,请提交反馈。
- data 节点在定义时,默认强制以字节对齐,这么做的目的是去除不同平台的编译器特性差异 (结构体填充),会有一定的性能损失,为了弥补可能存在的性能损失(内存拷贝),所以在定义时尝试将属性节点默认对齐到 4字节(32位平台),实际上没有区别,但不能依赖编译器的默认特性。
- data 节点由于长度不统一,所以如果开启加密,将会检查 object 的总大小是否对齐到16 字节,如果没对齐,则会在尾部执行 Zero padding(某些开源的AES128CBC library 内部带了其他方式,如PKCS15,不依赖差异化特性是一个好的选择),故 m_cmdSize 实际可能小于 data 节点的长度,最多15个字节。
1.4 AT 命令分类
当前PowerWriter AT 接口提供的操作接口如下:
// PowerWriter AT command type
typedef enum E_ATcmdType
{
// Null command for reserved
ATCmdNull = 0,
// Query and configuration
ATCmdGetWriterInfo = 1, // Get writer information
ATCmdRspWriterInfo, // Respone writer information
ATCmdGetWriterCfg, // Get writer configuration
ATCmdRspWriterCfg, // Respone writer configuration
ATCmdSetWriterCfg, // Update writer confuguration
ATCmdSetBaudrate, // Set AT hardware commander baudrate
// Online mode target chip operation
ATCmdConnectTarget = 100, // Connnect target chip (manual operation)
ATCmdGetTargetStatus, // Get target chip status
ATCmdGetTargetChipID, // Get target chip id
ATCmdRspTargetChipID, // Respone target chip id
ATCmdReadTargetMemory, // Read target memory
ATCmdRspTargetMemory, // Respone target memory content
ATCmdEraseTarget, // Erase target chip (full)
ATCmdEraseTargetSectors, // Erase target sectors
ATCmdWriteTargetMemory, // Write target memory
ATCmdReadTargetOptionByte, // Read target option byte
ATCmdRspTargetOptionByte, // Respone target option byte
ATCmdWriteTargetVendorOptionByte, // Write vendor's default option byte to target
ATCmdWriteTargetUserOptionByte, // Write user's option byte to target
// Offline mode target chip operation
ATCmdGetProjectInfo = 200, // Get project info from PowerWriter
ATCmdRspProjectInfo,
ATCmdLoadProject, // Load project to PowerWriter
ATCmdLoadProjectSend, //Load project to PowerWriter send package
ATCmdDisableProject, // Delete project from PowerWriter (Mark as invalid)
ATCmdStartOffline, // Start offline programming
ATCmdGetOfflineStatus, // Get offline programming status
// Benchmark instruction
ATCmdFactoryRunSRAMFW = 300, // Load & run factory SRAM firmware
ATCmdFactoryRunFlashFW, // Load & run factory Flash firmware
// Other command fields
ATCmdBroadcast = 400, // Broadcast data
//...
// State instruction
ATCmdStatusOK = (UINT32_MAX - 100), // Status Ok
ATCmdStatusError, // Status error with error code
ATCmdStatusProgress, // Status busy (progress)
// Align to 4 bytes, compiler independent
_ATCmdTypeMax = UINT32_MAX
} E_ATcmdType;
PowerWriter 将对开发的指令进行更新和维护,具体请查阅仓库源码。
1.4.1 系统功能查询与配置
1.4.1.1 查询PowerWriter信息
ATCmdGetWriterInfo:
调用参数:无需参数,但有占位符(空结构体导致某些编译器警告)
typedef struct S_ATCmdObject{
union powerwriter_at_type{
uint32_t m_placeholder; // An placeholder for empty structure
}property;
}S_ATCmdGetWriterInfo;
m_placeholder:占位符
一部分命令只有命令类型,无参数,均以 S_ATCmdObject 表示,不再重复描述。
命令返回:ATCmdRspWriterInfo
1.4.1.2 返回PowerWriter信息
ATCmdRspWriterInfo:
调用参数:ATCmdGetWriterInfo
返回值:
typedef struct S_ATCmdRspWriterInfo
{
uint8_t m_oem[PW_OEM_LENGTH]; // PowerWriter oem, such as PW200,PW300,PWLINK etc...
uint8_t m_sn[PW_SN_LENGTH]; // PowerWriter sn, formated as "xxxxxxxxxxxx..."
uint8_t m_hardwareVersion[PW_VERSION_LENGTH]; // PowerWriter hardware version, formated as "x.xx.xx"
uint8_t m_bootloaderVersion[PW_VERSION_LENGTH]; // PowerWriter bootloader version, formated as "x.xx.xx"
uint8_t m_interfaceVersion[PW_VERSION_LENGTH]; // PowerWriter interface version, formated as "x.xx.xx"
} S_ATCmdRspWriterInfo;
m_oem:PowerWriter OEM 型号。
m_sn:PowerWriter 序列号。
m_hardwareVersion: PowerWriter 硬件版本。
m_bootloaderVersion: PowerWriter bootloader 版本。
m_interfaceVersion: PowerWriter 接口固件版本。
1.4.1.3 查询PowerWriter配置
ATCmdGetWriterCfg:
调用参数:S_ATCmdObject。
命令返回:ATCmdRspWriterCfg
1.4.1.4 返回PowerWriter配置
ATCmdRspWriterCfg:
调用参数:ATCmdGetWriterCfg
返回值:
// Target names
typedef struct S_TargetName
{
uint8_t m_targetVendor[PW_TARGET_NAME_MAX]; // target chip vendor,such as 'nations' (注: 只能看,不能改)
uint8_t m_targetSeries[PW_TARGET_NAME_MAX]; // target chip series,such as 'N32G020' (注: 只能看,不能改)
uint8_t m_targetModel[PW_TARGET_NAME_MAX]; // target chip model,such as 'N32G020G5' (注: 只能看,不能改)
} S_TargetName;
// Base setting
typedef struct S_BaseWriterCfg
{
uint8_t m_eraseType; // Erase type: 0(no erase),1(chip erase),2(sector erase)
uint8_t m_outputVextType; // Output VEXT: 0(1.8V),1(3.3V),2(5.0V),3(refer to external power supply)
uint8_t m_clockType; // Colok: 0(20Mhz fast mode),1(10Mhz default),2(5Mhz),3(2Mhz),4(1Mhz), etc ...
uint8_t m_buzzerEnable; // 0: disable 1: enable
uint8_t m_obUpdateType; // 0: No operation before programming, no operation after programming
// 1: No operation is performed before programming, and user - defined OptionByte is written after flash programming
// 2: Restore default values is performed before programming, no operation after programming.
// 3: Restore default values is performed before programming, and user - defined OptionByte is written after flash programming
} S_BaseWriterCfg;
// Offline configure
typedef struct S_OfflineWriterCfg
{
uint8_t m_limitOfNumberEnable; // 0 : disable 1: enable (注: 只能看,不能改)
uint32_t m_limitOfNumber; // Current remaining quantity (注: 只能看,不能改)
uint8_t m_targetAutoEnable; // 0: disable 1:enable
uint16_t m_targetAutoInDebonce; // Target connected debonce time
uint16_t m_chipAutoChkOut; // Target disconnected debonce time
} S_OfflineWriterCfg;
// Output Ctrl configure
typedef struct S_OutputCtrlWriterCfg
{
uint8_t m_disablePowerAP; // 0 : disable 1:enable (Power off when programming is complete)
uint8_t m_runAP; // 0 : disbale 1:enable (Run when programming is complete)
uint16_t m_poweronDebonce; // Debonce the output power supply (ms)
uint16_t m_powerdownDebonce; // Debonce the output power off (ms)
uint8_t m_resetType; // 0 : Keep low
// 1 : Off, high resistance
// 2 : Reset output then to off
} S_OutputCtrlWriterCfg;
// Writer configure for currrent project
typedef struct S_ATCmdWriterCfg
{
S_TargetName m_targetName; // Target names
S_BaseWriterCfg m_baseCfg; // Base config
S_OfflineWriterCfg m_offlineCfg; // Offline configure
S_OutputCtrlWriterCfg m_outputCtrlCfg; // Output control configure
} S_ATCmdRspWriterCfg, S_ATCmdSetWriterCfg;
1.4.1.4 更新PowerWriter配置
ATCmdSetWriterCfg
调用参数:S_ATCmdSetWriterCfg,同 ATCmdRspWriterCfg 的返回值
返回值:
ATCmdStatusOK、ATCmdStatusError。
- 处于安全考虑,部分PowerWriter 配置不允许更改(修改无效),如:m_targetName、m_limitOfNumberEnable、m_limitOfNumber
- 烧录器配置信息,默认PowerWrietr 启动时加载离线项目的信息,如果没有预载离线项目, 则返回的是默认值。
1.4.1.4 设置AT 接口波特率
ATCmdSetBaudrate
调用参数:S_ATCmdSetBaudrate
typedef struct S_ATCmdObject
{
union powerwriter_at_type
{
uint32_t m_baudrate; // Set UART AT new baudrate;
}property;
}S_ATCmdSetBaudrate;
m_baudrate: 设置新的波特率
返回值:
ATCmdStatusOK、ATCmdStatusError。
- USB 端口无需更改波特率,为CDC 接口,支持所有的波特率,自动设置,UART 端口AT 为硬件UART 端口,默认波特率为 9600。
- PowerWriter 在接收到指令之后,按照设置以前的波特率返回响应,如果设置成功,PowerWriter 将自动进入新的波特率通信,如果失败,仍保持旧波特率设置。
1.4.2 在线操作指令{#OnlineAPI}:
在线操作指令,需要先加载离线项目,进行数据预设才支持。
1.4.2.1 连接目标芯片
ATCmdConnectTarget
调用参数:S_ATCmdObject
返回值:
ATCmdStatusOK、ATCmdStatusError。
1.4.2.2 获取目标芯片连接状态
ATCmdGetTargetStatus
调用参数:S_ATCmdObject
返回值:
ATCmdStatusOK、ATCmdStatusError。
1.4.2.3 获取目标芯片ID
ATCmdGetTargetChipID
调用参数:S_ATCmdObject
返回值:
ATCmdRspTargetChipID、ATCmdStatusError。
1.4.2.4 返回目标芯片ID
ATCmdRspTargetChipID
调用参数:ATCmdGetTargetChipID
返回值:
typedef struct S_ATCmdRspTargetChipID
{
uint8_t m_CIDSize; // Target chip ID size
uint8_t m_CIDData[PW_TARGET_ID_MAX]; // Target chip ID data
} S_ATCmdRspTargetChipID;
m_CIDSize:当前芯片的ID 长度
m_CIDData:当前芯片的ID Data Buffer ,预留缓冲区长度为 PW_TARGET_ID_MAX(16)
部分芯片的ID是非连续存储的, PowerWriter 会将非连续存储的芯片已连续存储的模式给出,去除冗余信息
1.4.2.5 读取目标芯片数据
ATCmdReadTargetMemory
调用参数:S_ATCmdReadTargetMemory
typedef struct S_ATCmdReadTargetMemory{
uint32_t m_address; //Target chip address, support such as SRAM、Flash、EEPROM、OTP etc...
uint32_t m_size; //Data size of a single read (Must be less than 256)
}S_ATCmdReadTargetMemory;
m_address:读取数据的地址,支持SRAM,外设寄存器值(部分模块可能需要特殊权限,请跟我们反馈),Flash,EEPROM,OTP等。
m_size:读取数据的大小。
单次读取的大小不要超过PW_BUFFER_MAX(256), 否则PowerWriter 只返回 PW_BUFFER_MAX的长度。PowerWriter 暂没提供连续读取的指令,连续虽然可以提高读写效率,但是需要比较大的存储空间来接收数据,这对UART 端的AT 接口并不友好,后续如有特殊需求,请反馈我们,此外也没有提供 mem8、mem16、mem32 的接口。
返回值:参见ATCmdRspTargetMemory、ATCmdStatusError。
1.4.2.6 返回目标芯片数据
ATCmdRspTargetMemory
返回值:S_ATCmdReadTargetMemory
// Respone target chip memory
typedef struct S_ATCmdRspTargetMemory{
uint32_t m_address; //Current data address
uint32_t m_size; //Current data size
uint8_t m_buffer[PW_BUFFER_MAX]; //Current data buffer (fixed length)
}S_ATCmdRspTargetMemory;
m_address: 实际返回的数据的起始地址
m_size:实际成功读取到的数据长度
m_buffer:数据缓冲区 (注:缓冲区为固定长度)
1.4.2.7 擦除目标芯片
ATCmdEraseTarget
调用参数:S_ATCmdObject
返回值:ATCmdStatusOK、ATCmdStatusError。
擦除目标芯片的时间不确定,在执行此命令时,需要预留足够的等待时间。
1.4.2.8 擦除目标芯片扇区
ATCmdEraseTargetSectors
调用参数:ATCmdEraseTargetSectors
// Erase target chip
typedef struct S_ATCmdReadTargetMemory{
uint32_t m_address; //Target chip address, support such as SRAM、Flash、EEPROM、OTP etc...
uint32_t m_size; //Data size of a single read (Must be less than 256)
}S_ATCmdReadTargetMemory,
S_ATCmdEraseTargetSectors;
m_address: 擦除目标芯片的地址(可以擦除Flash,EEPROM等带扇区表的存储空间)
m_size:擦除长度
返回值:ATCmdStatusOK、ATCmdStatusError。
擦除的地址对齐到扇区起始地址,擦除整数个扇区是最优解,如果起始地址或者结束地址不对齐,将会多擦除起始地址扇区(向下取整),以及多擦除尾部一个扇区(向上取整)。
擦除目标芯片的时间不确定,在执行此命令时,需要预留足够的等待时间。
1.4.2.9 写入目标芯片数据
ATCmdWriteTargetMemory
调用参数:S_ATCmdWriteTargetMemory
// Respone target chip memory
// Write target chip memory
typedef struct S_ATCmdTargetMemory{
uint32_t m_address; //Current data address
uint32_t m_size; //Current data size
uint8_t m_buffer[PW_BUFFER_MAX]; //Current data buffer (fixed length)
}S_ATCmdRspTargetMemory,
S_ATCmdWriteTargetMemory;
m_address: 实际写入的数据的起始地址
m_size:实际写入读取的数据长度
m_buffer:数据缓冲区 (注:缓冲区为固定长度)
返回值:ATCmdStatusOK、ATCmdStatusError。
写入数据支持写入SRAM,写入Flash、EEPROM、OTP等,其他区域写入未经充分测试。
1.4.2.10 读取目标芯片选项字
ATCmdReadTargetOptionByte
调用参数:S_ATCmdReadTargetOptionByte
返回值:ATCmdRspTargetOptionByte、ATCmdStatusError。
1.4.2.11 返回目标芯片选项字
ATCmdRspTargetOptionByte
调用参数:ATCmdReadTargetOptionByte
返回值:
// Respone target chip option byte
typedef struct S_ATCmdRspTargetOptionByte{
uint32_t m_OBsize; //Option byte size
uint8_t m_OBData[PW_OB_MAX]; //Option byte data buffer
}S_ATCmdRspTargetOptionByte;
m_OBsize:选项字节的长度
m_OBData:选项字节缓冲区 (目前是固定长度,后续会优化)
1.4.2.12 写入目标芯片默认选项字
ATCmdWriteTargetVendorOptionByte
调用参数:S_ATCmdWriteTargetVendorOptionByte
返回值:ATCmdStatusOK、ATCmdStatusError。
写入选项字,数据来源于离线项目 (pkg)中数据,必须确保先预载
1.4.2.13 写入目标芯片用户选项字
ATCmdWriteTargetUserOptionByte
调用参数:S_ATCmdWriteTargetUserOptionByte
返回值:ATCmdStatusOK、ATCmdStatusError。
写入选项字,数据来源于离线项目(pkg)中数据,必须确保先预载
1.4.3 离线操作指令{#Offline}:
1.4.3.1 查询离线项目信息
ATCmdGetProjectInfo
调用参数:S_ATCmdGetProjectInfo
返回值:ATCmdRspProjectInfo、ATCmdStatusError。
1.4.3.2 返回离线项目信息
ATCmdRspProjectInfo
调用参数:ATCmdGetProjectInfo
返回值:S_ATCmdRspProjectInfo。
// Respone offline project infomation
typedef struct S_ATCmdRspProjectInfo{
uint8_t m_activate; // 0 : Inactivate 1: Activate
uint32_t m_projectSize; // Offline project size
uint32_t m_projectcrc32; // Offline project crc32
}S_ATCmdRspProjectInfo;
m_activate: 0 表示无效,1 表示有效
m_projectSize : 离线项目的大小
m_projectcrc32 : 离线项目的CRC32 校验值
1.4.3.3 加载离线项目
ATCmdLoadProject
调用参数:S_ATCmdLoadProject
//Load offline project to PowerWriter
typedef struct S_ATCmdLoadProject
{
uint8_t m_password[PW_PROJECT_PWD_SIZE] //Project password
uint32_t m_projectSize; //Project Size
uint32_t m_projectCRC32; //Project crc32
}S_ATCmdLoadProject;
m_password: 项目文件密码
m_projectSize:项目文件大小
m_projectCRC32:项目文件的CRC32 校验值
返回值:ATCmdStatusOK、ATCmdStatusError。
- 项目文件密码最长为16个字符,如果密码短于16 字节,剩余的部分请用 0x00 填充。
- 项目文件密码传输是敏感数据,对安全有需求的用户,请开启 AT 通讯加密功能(加密算法为 AES128 CBC)。
1.4.3.4 加载离线项目发送
ATCmdLoadProjectSend
调用参数:S_ATCmdLoadProjectSend
//Load offline project to PowerWriter send
typedef struct S_ATCmdLoadProjectSend
{
uint32_t m_offset; //offset of project
uint32_t m_Size; //currrent acitvate
uint8_t m_data[PW_PACKAGE_SIZE]; //data buffer
}S_ATCmdLoadProjectSend;
m_offset:当前发送数据的偏移地址。
m_Size:当前发送的长度。
m_data:当前数据缓冲区。
返回值:ATCmdStatusOK、ATCmdStatusError。
1.4.3.5 禁用离线项目
ATCmdDisableProject:
调用参数:S_ATCmdDisableProject
返回值:ATCmdStatusOK、ATCmdStatusError。
1.4.3.6 启动离线烧录
ATCmdStartOffline:
调用参数:S_ATCmdStartOffline
返回值:ATCmdStatusOK、ATCmdStatusError。
1.4.3.7 查询离线状态
ATCmdGetOfflineStatus
调用参数:S_ATCmdGetOfflineStatus
返回值:ATCmdStatusOK、ATCmdStatusError、ATCmdStatusProgress。
1.4.4 测试与生产
1.4.4.1:运行测试SRAM 固件
ATCmdFactoryRunSRAMFW
调用参数:S_ATCmdFactoryRunSRAMFW
返回值:ATCmdStatusOK、ATCmdStatusError。
1.4.4.2:运行测试Flash 固件
ATCmdFactoryRunFlashFW
调用参数:S_ATCmdFactoryRunFlashFW
返回值:ATCmdStatusOK、ATCmdStatusError。
1.4.5 扩展指令
1.4.5.1 广播
ATCmdBroadcast
调用参数:S_ATCmdBroadcast
typedef enum S_ATCmdBroadcastDirection{
DIR_CDC2UART, //Forwarding from USB to UART
DIR_UART2CDC, //Forwarding from UART to USB
_DIR_MAX_ = UINT32_MAX
}S_ATCmdBroadcastDirection;
typedef struct S_ATCmdBroadcast
{
uint8_t m_keepATFrame; //0 : Forwarding valid data, 1: forwarding Full AT frame data
S_ATCmdBroadcastDirection m_dirType; //Direction
uint32_t m_size; //Activate size
uint8_t m_data[PW_PACKAGE_SIZE] //data
}S_ATCmdBroadcast;
m_keepATFrame:0表示只转发有效数据,1 表示转发完整的AT 帧结构(在其他系统上也需要解析AT 指令)
m_dirType:广播的方向。
m_size:当前发送数据的长度
m_data:数据缓冲区
返回值:ATCmdStatusOK、ATCmdStatusError。
- 为何要指定传输路径:部分产品上只有USB 和 UART 两个端口,但是其他产品上可能有多个转发端口,这是为了兼容考虑。
1.4.6 调试指令
暂不提供(如有需要,请反馈给我们)...
1.4.7 IO控制指令
暂不提供(如有需要,请反馈给我们)...
1.4.8 状态
1.4.8.1 返回Status Ok
调用参数:主流无数据返回的命令,都返回Ok 响应。
返回:S_ATCmdObject
1.4.8.2 返回Status Error
调用参数:所有命令都有可能返回 ATCmdStatusError,不再详细描述。
返回:
typedef struct S_ATCmdObject
{
union powerwriter_at_type
{
uint32_t m_errorcode; // Status error code
}property;
} S_ATCmdStatusError;
m_errorcode: 返回的错误码,具体请查看 powerwriter_at_error.h 中的定义
1.4.8.3 返回Status Progress
调用参数:ATCmdGetOfflineStatus。
返回:
//ATCmdStatusProgress
typedef struct S_ATCmdStatusProgress{
uint32_t m_total; //Total size
uint32_t m_processed; //Processed size
}S_ATCmdStatusProgress;
m_total:处理总长度
m_processed:已处理的长度
2.0:API
前面章节介绍了命令分类,以及对应的输入输出参数类型,本节,介绍当前提供的接口API,见 powerwriter_at_api.h。
/**
* @file powerwriter_at_api.h
* @brief PowerWriter open communication interface
*
* PowerWriter AT
* Copyright (c) 2009-2021, ICWorkshop Limited, All Rights Reserved
* SPDX-License-Identifier: MIT
*
* Licensed under the Apache License, Version 2.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 __powerwriter_at_api_h
#define __powerwriter_at_api_h
#include "powerwriter_at_type.h"
#include "powerwriter_at_utils.h"
#include "powerwriter_at_cert.h"
#include "powerwriter_at_porting.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include "powerwriter_at_log.h"
/* 打印基本信息 */
extern void powerwriter_at_introduction(void);
// 运行基准测试
extern bool powerwriter_at_benchmark(S_ATChannel *, bool, ATCmdStreamOut, ATCmdEventOut);
// 初始化
extern bool powerwriter_at_init(S_ATChannel *, bool, ATCmdStreamOut, ATCmdEventOut);
// 填充接收数据到AT
extern bool powerwriter_at_datain(S_ATChannel *ch, void *data, size_t size);
// 获取当前的帧信息
extern const S_ATCmdFrame *powerwriter_at_received_frame(S_ATChannel *ch);
// 获取最后一次错误码
extern E_ATCmdError powerwriter_at_last_error(S_ATChannel *ch);
// 获取PowerWriter 信息
extern bool powerwriter_at_get_writerinfo(S_ATChannel *ch, S_ATCmdRspWriterInfo *info);
// 获取PowerWriter 配置
extern bool powerwriter_at_get_writerconfig(S_ATChannel *ch, S_ATCmdRspWriterCfg *cfg);
// 更新PowerWriter 配置
extern bool powerwriter_at_set_writerconfig(S_ATChannel *ch, const S_ATCmdRspWriterCfg *cfg);
// 更新 AT 的波特率
extern bool powerwriter_at_set_baudrate(S_ATChannel *ch, int baudrate);
// 初始化目标芯片连接
extern bool powerwriter_at_target_connect(S_ATChannel *ch);
// 获取连接状态
extern bool powerwriter_at_target_status(S_ATChannel *ch);
// 读取目标芯片ID
extern bool powerwriter_at_target_id(S_ATChannel *ch, S_ATCmdRspTargetChipID *rsp);
// 读取目标芯片内存
extern bool powerwriter_at_target_read(S_ATChannel *ch, uint32_t addr, uint32_t size, S_ATCmdRspTargetMemory **memory);
// 擦除目标芯片
extern bool powerwriter_at_target_erase(S_ATChannel *ch, int timout_ms);
// 擦除目标芯片flash内存
extern bool powerwriter_at_target_erase_sector(S_ATChannel *ch, uint32_t addr, uint32_t size, int timout_ms);
// 编程目标芯片flash数据
extern bool powerwriter_at_target_write_prepare(S_ATChannel *ch, uint32_t total);
extern bool powerwriter_at_target_write(S_ATChannel *ch, uint32_t addr, void *buffer, size_t buffersize);
// 读取目标芯片选项字节
extern bool powerwriter_at_target_read_ob(S_ATChannel *ch, S_ATCmdRspTargetOptionByte **ppob);
// 写入默认的出厂默认选项字到目标芯片
extern bool powerwriter_at_target_write_vendor_ob(S_ATChannel *ch, int timout_ms);
// 写入当前用户自定义的选项字
extern bool powerwriter_at_target_write_user_ob(S_ATChannel *ch, int timout_ms);
// 获取离线项目信息
extern bool powerwriter_at_project_info(S_ATChannel *ch, S_ATCmdRspProjectInfo **ppproject);
// 禁用离线项目
extern bool powerwriter_at_project_disable(S_ATChannel *ch);
// 加载离线项目
extern bool powerwriter_at_project_load(S_ATChannel *ch, const char *password, const void *prj_data, size_t prj_size, ATProgress p_cb);
// 启动离线编程
extern bool powerwriter_at_offline_start(S_ATChannel *ch);
// 查询离线编程撞他
extern bool powerwriter_at_offline_status(S_ATChannel *ch, S_ATCmdStatus *ps);
// 简易广播无应答
extern bool powerwriter_at_easy_broadcast_no_rsp(S_ATChannel *ch, const void *bcdata, size_t bcsize, S_ATCmdBroadcastDir bcdir);
// 标准广播
extern bool powerwriter_at_broadcast(S_ATChannel *ch, const void *bcdata, size_t bcsize, S_ATCmdBroadcastDir bcdir, bool keepframe,
bool waitrsp, S_ATCmdBroadcast *prsp, int waitrsptimeout);
/* 工厂测试 */
// 运行SRAM 测试固件
bool powerwriter_at_run_factory_sram_fw(S_ATChannel *ch, int timeout);
// 运行Flash 测试固件
bool powerwriter_at_run_factory_flash_fw(S_ATChannel *ch, int timeout);
#ifdef __cplusplus
}
#endif
#endif
3.0:配置与移植
本节内容为移植源码和配置接口提供指导。
3.0.1:配置
/**
* @file powerwriter_at_config.h
* @brief PowerWriter open communication interface
*
* PowerWriter AT
* Copyright (c) 2009-2021, ICWorkshop Limited, All Rights Reserved
* SPDX-License-Identifier: MIT
*
* Licensed under the Apache License, Version 2.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 __powerwriter_at_CONFIG_h
#define __powerwriter_at_CONFIG_h
#include <stdint.h>
#include <string.h>
// The global control
#define POWERWRITER_AT_LOGGER_ENABLE /* 是否开启日志打印,默认为 printf */
//#define POWERWRITER_AT_HWCRC_ENABLE /* 是否使用硬件CRC32 以便提升性能 */
//#define POWERWRITER_AT_ENCRYPT_ENABLE /* 是否开启数据加密 */
#define POWERWRITER_AT_ASSERT_ENABLE /* 是否开启断言 */
// 如开启加密,则自行配置加密密码信息
#if defined(POWERWRITER_AT_ENCRYPT_ENABLE)
//#define POWERWRITER_AT_ENCRYPT_HW_AES /* Use hardware AES */
// AES128Bit-CBC Encrypt Key & IV For PowerWriter AT Command
//AES128Bit-CBC Encrypt Key & IV For PowerWriter AT Command
//72C634F2CF2EF3D5F740DA5CEEBE4018
static uint8_t m_at_encrypt_key[] = { 0x72,0xc6,0x34,0xf2,0xcf,0x2e,0xf3,0xd5,0xf7,0x40,0xda,0x5c,0xee,0xbe,0x40,0x18 };
//4BFEB618B2F1F1C92C7E4C376DF0B28A
static uint8_t m_at_encrypt_iv_[] = { 0x4b,0xfe,0xb6,0x18,0xb2,0xf1,0xf1,0xc9,0x2c,0x7e,0x4c,0x37,0x6d,0xf0,0xb2,0x8a };
#endif
/* 多线程锁,默认为空,可根据当前平台自行移植 */
#ifndef __arm__
//#include <thread>
//#include <mutex>
#define MACRO_THREAD_TYPE // std::mutex m_thread_lock;
#define MACRO_THREAD_LOCK(ch) // std::lock_guard<std::mutex> m_thread_mutex(ch->m_ATConfig.m_thread_lock);
#define MACRO_THREAD_EXIT
#else
#define MACRO_THREAD_TYPE /* Threads locked to your operating system! */
#define MACRO_THREAD_LOCK(ch) /* Threads locked to your operating system! */
#define MACRO_THREAD_EXIT /* Threads locked to your operating system! */
#endif // ! __arm__
#endif
3.0.2:移植
/**
* @file powerwriter_porting.c
* @brief ICWorkShop Safety License Shield Api Functions
*
* Safety License Shield
* Copyright (c) 2009-2021, ICWorkshop 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
*
* 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 "powerwriter_at_porting.h"
#include "3rd/crc/crc.h"
#ifdef __arm__
#include <stdio.h>
#include "stm32f1xx_hal.h"
#else
#include <time.h>
#endif
// Sleep
#ifdef WIN32
#include <windows.h>
#elif defined(__GNUC__)
#include <unistd.h>
#endif
/*
获取时间戳接口
*/
uint32_t GetSystemTick()
{
#ifdef __arm__ /* arm complier */
return HAL_GetTick();
#else /* other complier in client */
return (int)clock();
#endif
}
/*
线程delay 接口
*/
void ATSleep(uint32_t ms)
{
#ifdef WIN32
Sleep(ms);
#elif defined(__GNUC__)
usleep(ms);
#else
uint32_t ts = GetSystemTick();
while (GetSystemTick() - ts < ms)
;
#endif
// add a sleep interface to your platform or operating system ...
//...
}
/* log 打印 printf 代理 ?*/
#ifdef POWERWRITER_AT_LOGGER_ENABLE
#ifdef __arm__
extern UART_HandleTypeDef huart1;
extern "C"
{
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);
return (ch);
}
}
#endif
#endif
/* crc32 API 实现 */
uint32_t GetCrc32(const void *data, size_t size)
{
#ifdef POWERWRITER_AT_HWCRC_ENABLE
/*
CRC Setting Reference
Polynomial : 0x04C11DB7
Initial/Final remainder : 0xffffffff
Input/Output reverse : yes
*/
#error "You must implement the hardware AES128-CBC on the current platform"
#else
return crc32(data, (int)size);
#endif
}
4.0:例程
仓库中提供了Windows 下的Demo 工程,基于Demo 工程参考示例源码,见如下,编写AT 应用需要实现的部分包含:
- 设备端口管理(设备扫描,连接,断开等)
- 数据收发(设备数据收发接口)
- 应用流程
#include "SerialPortApp.h"
SerialPortApp m_App;
/* 发送命令帧 */
bool powerwriter_data_out(S_ATCmdFrame * pf, int timeout)
{
return m_App.OnSend(pf, pf->m_frameLength);
}
/* AT 事件接口,命令事件,或错误事件*/
void powerwriter_event_out(void * obj, S_ATCmdEvent event)
{
S_ATChannel * ch = (S_ATChannel *)obj;
switch (event)
{
/* received package */
case ATEventCmd:
{
const S_ATCmdFrame * frame;
if (frame = powerwriter_at_received_frame(ch)) {
powerwriter_at_log(LOGD, "AT received cmd: [%04X]\r\n", frame->m_payload.m_cmdType);
}
}
break;
case ATEventError:
{
powerwriter_at_log(LOGE, "AT received error: [%04X]\r\n", powerwriter_at_last_error(ch));
break;
}
default:
break;
}
}
int main() {
/* 打印信息 */
powerwriter_at_introduction();
return m_App.RunATBenchmark(false, powerwriter_data_out, NULL);
}
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <iostream>
/* PowerWriter AT Commander */
#include "./../../powerwriter_at_core/powerwriter_at_api.h"
/* A serial port */
#include "./CSerialPort/SerialPort.h"
#include "./CSerialPort/SerialPortInfo.h"
#include "NLock.h"
using namespace itas109;
class SerialPortApp : public has_slots<>
{
public:
SerialPortApp() {
m_SerialPort.OnReadReadyCallBack.connect(this, &SerialPortApp::OnReceve);
m_SerialPort.OnDisconnectCallBack.connect(this, &SerialPortApp::DisconnectSerialPort);
}
~SerialPortApp() {
this->DisconnectSerialPort();
}
/* Run AT benchmark */
E_ATCmdError RunATBenchmark(
bool encrypt,
ATCmdStreamOut pfDataOut,
ATCmdEventOut pfEvent)
{
vector<SerialPortInfo> m_SerialPortInfo = CSerialPortInfo::availablePortInfos();
powerwriter_at_log(LOGI, "The serial port is as follows:\r\n");
for (auto s : m_SerialPortInfo) {
powerwriter_at_log(LOGI, "[Port:%s]:%s\r\n", s.portName.c_str(), s.description.c_str());
if (!ConnectSerialPort(s.portName)) {
powerwriter_at_log(LOGE, "Unable to connect to port:%s\r\n", s.portName.c_str());
continue;
}
powerwriter_at_log(LOGI, ">>>benchmark...\r\n");
if (!powerwriter_at_benchmark(&this->m_ATCmdApp, encrypt, pfDataOut, pfEvent)) {
powerwriter_at_log(LOGE, "%s benchmark failed...\r\n", s.portName.c_str());
continue;
}
powerwriter_at_log(LOGD, ">>>All passed...\r\n");
}
return ATErrorNone;
}
/* AT send data */
bool OnSend(void * data, size_t size) {
//object_print(data, size, "Send command");
if (m_SerialPort.isOpened()) {
return m_SerialPort.writeData((char *)data, size) == size;
}
return false;
}
/* Connect Device */
bool ConnectSerialPort(
std::string Device,
int BaudRate = PW_AT_DEFAULT_BAUDRATE,
itas109::Parity Parity = itas109::Parity::ParityNone,
itas109::DataBits DataBits = itas109::DataBits::DataBits8,
itas109::StopBits StopBits = itas109::StopBits::StopOne
){
try
{
DisconnectSerialPort();
m_SerialPort.init(Device.c_str(), BaudRate, Parity, DataBits, StopBits);
m_SerialPort.open();
if (m_SerialPort.isOpened()){
return true;
}
}
catch (const std::exception& e)
{
std::cout << e.what() << endl;
}
return false;
}
/* Close serial port */
void DisconnectSerialPort()
{
try
{
if (m_SerialPort.isOpened())
{
m_SerialPort.close();
}
}
catch (const std::exception& e){
std::cout << e.what() << endl;
}
}
/* public command */
public:
/* private inner */
private:
//recv data
void OnReceve()
{
try
{
vector<char> m_curRead;
int iRet = m_SerialPort.readAllData(m_curRead);
if (iRet > 0) {
//object_print(m_curRead.data(), iRet, "Recived data");
powerwriter_at_datain(&this->m_ATCmdApp, m_curRead.data(), iRet);
}
}
catch (const std::exception & ex)
{
std::cout << std::string("AT commander port exception: ") + ex.what();
}
}
private:
S_ATChannel m_ATCmdApp;
CSerialPort m_SerialPort;
};
AT 所有API 演示案例见如下所示:
/**
* @file powerwriter_at_samples.c
* @brief PowerWriter open communication interface
*
* PowerWriter AT
* Copyright (c) 2009-2021, ICWorkshop Limited, All Rights Reserved
* SPDX-License-Identifier: MIT
*
* Licensed under the Apache License, Version 2.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.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "powerwriter_at_api.h"
// PowerWriter AT test project
unsigned char AT_Project[16516] = { 0x02, 0x2C, 0x85, 0x83, 0x62, 0xBF, 0x30, 0x2C, 0x08, 0xA1, 0x1A, 0x5B,
0xFE, 0x67, 0xDA, 0x80, 0x7B, 0x80, 0x31, 0x4A, 0x1C, 0xC0, 0xA4, 0xE2,
0x46, 0x2D, 0x5C, 0x7D, 0xF0, 0x70, 0x53, 0xB0, 0x1A, 0x34, 0xC1, 0xB2,
0x0B, 0x88, 0xB6, 0x11, 0x57, 0x41, 0x38, 0xAA, 0x3D, 0xE8, 0xAF, 0xF2,
0x66, 0xC0, 0x98, 0x0A, 0x16, 0x10, 0x74, 0xE1, 0xB2, 0x70, 0x74, 0xAE,
0xF7, 0xDC, 0x0D, 0x4C, 0xEF, 0x80, 0xA3, 0xCE, 0xB0, 0x48, 0x68, 0xA2,
0x4E, 0x00, 0xE5, 0x5A, 0xA8, 0xAC, 0x9B, 0x00, 0xA2, 0x80, 0xC3, 0x52,
0x34, 0x74, 0x8F, 0x2D, 0x0A, 0x70, 0x06, 0x54, 0x91, 0xD4, 0x2C, 0x35,
0x2C, 0x03, 0x70, 0xEA, 0xE6, 0xBC, 0x58, 0xCC, 0x16, 0xAE, 0x1C, 0x93,
0x2A, 0x49, 0x80, 0xFF, 0x1A, 0xEA, 0x8C, 0x77, 0xB2, 0x15, 0x00, 0x2A,
0x46, 0xD0, 0x40, 0x22, 0x76, 0xE9, 0x00, 0x87, 0x80, 0xDA, 0x88, 0x66,
0xBA, 0xFF, 0x10, 0x38, 0xAA, 0x3D, 0xE8, 0xAE, 0xF2, 0x66, 0xC0, 0x3A,
0x0A, 0x16, 0x10, 0x09, 0xE0, 0xB2, 0x70, 0x0F, 0xAC, 0xF7, 0xDC, 0x9B,
0x46, 0xEF, 0x80, 0x24, 0xC4, 0xB0, 0x48, 0xE4, 0x98, 0x4E, 0x00, 0x50,
0x50, 0xA8, 0xAC, 0x9D, 0xDC, 0xA2, 0x80, 0x5C, 0x28, 0x34, 0x74, 0x4D,
0xEE, 0x0A, 0x70, 0x99, 0x14, 0x91, 0xD4, 0x35, 0xCE, 0x50, 0x80, 0x84,
0x4E, 0x04, 0xE0, 0x88, 0x9A, 0xBA, 0x38, 0x90, 0xA8, 0x7B, 0x30, 0xF3,
0x8E, 0xAE, 0x40, 0xD8, 0xF4, 0x01, 0x78, 0xE7, 0x32, 0x62, 0x18, 0x83,
0x0A, 0x95, 0xCC, 0xC3, 0x94, 0x82, 0x80, 0x96, 0x82, 0x14, 0x88, 0x95,
0x58, 0xED, 0x60, 0xC7, 0xE4, 0xEF, 0xF4, 0xA7, 0xA2, 0xD8, 0x70, 0x35,
0x3C, 0x45, 0x9C, 0x07, 0xE2, 0xA0, 0x70, 0x57, 0x60, 0x50, 0x18, 0xE1,
0x72, 0x80, 0x60, 0xC0, 0x7C, 0xB6, 0x78, 0xEB, 0x16, 0xF6, 0xC0, 0x69,
0x86, 0x7A, 0x88, 0x83, 0xEC, 0x8C, 0xE0, 0xBD, 0x84, 0xBC, 0x84, 0x90,
0xD4, 0xCE, 0x08, 0xDE, 0x02, 0xC3, 0x64, 0xC9, 0x1E, 0xE2, 0x00, 0xA2,
0x20, 0x96, 0x50, 0xD4, 0x0C, 0x00, 0x80, 0xC8, 0xB0, 0xA3, 0x8C, 0xFA,
0xE4, 0xE8, 0xC0, 0xB4, 0xB8, 0xCB, 0xB4, 0x89, 0x04, 0xE6, 0xD8, 0xA2,
0x8E, 0x81, 0xFC, 0x85, 0xA0, 0xC4, 0x80, 0xF7, 0xD8, 0x28, 0xA0, 0x1B,
0x84, 0x95, 0x80, 0x24, 0xCA, 0x4C, 0x94, 0x9D, 0x7C, 0x44, 0x80, 0xAA,
0xC6, 0x82, 0xFC, 0x77, 0x34, 0xAB, 0x28, 0xA1, 0xE6, 0x1F, 0x04, 0xDE,
0x04, 0xCB, 0x00, 0x01, 0xB8, 0x26, 0x44, 0xF4, 0x82, 0xF4, 0x78, 0x1A,
0xC2, 0x55, 0x24, 0x2C, 0x85, 0x83, 0x5B, 0xA1, 0xEA, 0xE6, 0xBC, 0x58,
0x7B, 0xB3, 0x5A, 0xD0, 0x94, 0x7D, 0x9D, 0xCD, 0x32, 0x4C, 0xEA, 0x8C,
0x77, 0xB2, 0x15, 0x00, 0x2A, 0x46, 0xD0, 0x40, 0x22, 0xC9, 0x3D, 0x4D,
0xBA, 0xB2, 0x21, 0xB8, 0x86, 0x0D, 0x64, 0x82, 0xA1, 0x0F, 0xB0, 0xE8,
0xAE, 0x45, 0xBA, 0x0D, 0x6D, 0x3C, 0x5D, 0x40, 0x40, 0x10, 0x2A, 0xB2,
0x0F, 0xAC, 0xF7, 0xDC, 0x9B, 0x47, 0xF0, 0x83, 0x25, 0xC4, 0xB0, 0x48,
0xE4, 0x98, 0x4E, 0x01, 0x50, 0x50, 0xA8, 0xA8, 0x9C, 0xDD, 0xAA, 0x80,
0x5D, 0x10, 0x37, 0x74, 0x4D, 0xEE, 0x04, 0x70, 0x93, 0x14, 0x91, 0xD4,
0x99, 0xCE, 0xB4, 0x80, 0x87, 0xDE, 0x79, 0xDF, 0xA7, 0xA6, 0xBA, 0x38,
0x90, 0xA8, 0x7B, 0x3C, 0xF3, 0x8E, 0xAE, 0x40, 0xD8, 0xF4, 0x01, 0x78,
0xE7, 0x32, 0x62, 0x18, 0x83, 0x0A, 0x95, 0xCC, 0xC3, 0x94, 0x82, 0x80,
0x96, 0x82, 0x14, 0x88, 0x95, 0x58, 0xED, 0x60, 0xC7, 0xE4, 0xEF, 0xF4,
0xA7, 0xA2, 0xD8, 0x70, 0x35, 0x3C, 0x45, 0x9C, 0x07, 0xE2, 0xA0, 0x70,
0x57, 0x60, 0x50, 0x18, 0xE1, 0x72, 0x80, 0x60, 0xC0, 0x7C, 0xB6, 0x78,
0xEB, 0x16, 0xF6, 0xC0, 0x69, 0x86, 0x7A, 0x88, 0x83, 0xEC, 0x8C, 0xE0,
0xBD, 0x84, 0xBC, 0x84, 0x90, 0xD4, 0xCE, 0x08, 0xDE, 0x02, 0xC3, 0x64,
0xC9, 0x1E, 0xE2, 0x00, 0xA2, 0x20, 0x96, 0x50, 0xD4, 0x0C, 0x00, 0x80,
0xC8, 0xB0, 0xA3, 0x8C, 0xFA, 0xE4, 0xE8, 0xC0, 0xB4, 0xB8, 0xCB, 0xB4,
0x89, 0x04, 0xE6, 0xD8, 0xA2, 0x8E, 0x81, 0xFC, 0x85, 0xA0, 0xC4, 0x80,
0xF7, 0xD8, 0x28, 0xA0, 0x1B, 0x84, 0x95, 0x80, 0x24, 0xCA, 0x4C, 0x94,
0x9D, 0x7C, 0x44, 0x80, 0xAA, 0xC6, 0x82, 0xFC, 0x77, 0x34, 0xAB, 0x28,
0xA1, 0x2C, 0x35, 0x2C, 0x03, 0x70, 0xEA, 0xE6, 0xBC, 0x58, 0xCC, 0x16,
0xAE, 0x1C, 0x3D, 0x0B, 0x48, 0x5F, 0x3E, 0x1A, 0xEA, 0x8C, 0xB6, 0xB2,
0x15, 0x00, 0x2A, 0x46, 0xD0, 0x40, 0x22, 0x76, 0xE9, 0x00, 0x87, 0x80,
0xDA, 0x88, 0x66, 0xBA, 0xFF, 0x10, 0x38, 0xAA, 0x3D, 0xE8, 0xAE, 0xF2,
0x66, 0xC0, 0x3A, 0x0A, 0x16, 0x10, 0x09, 0xE0, 0xB2, 0x70, 0x0F, 0xAC,
0xF7, 0xDC, 0x9B, 0x46, 0xEF, 0x80, 0x24, 0xC4, 0xB0, 0x48, 0xE4, 0x98,
0x4E, 0x00, 0x50, 0x50, 0xA8, 0xAC, 0x9D, 0xDC, 0xA2, 0x80, 0x5C, 0x28,
0x34, 0x74, 0x4D, 0xEE, 0x0A, 0x70, 0x99, 0x14, 0x91, 0xD4, 0x35, 0xCE,
0x50, 0x80, 0x84, 0x4E, 0x04, 0xE0, 0x88, 0x9A, 0xBA, 0x38, 0x90, 0xA8,
0x7B, 0x30, 0xF3, 0x8E, 0xAE, 0x40, 0xD8, 0xF4, 0x01, 0x78, 0xE7, 0x32,
0x62, 0x18, 0x83, 0x0A, 0x95, 0xCC, 0xC3, 0x94, 0x82, 0x80, 0x96, 0x82,
0x14, 0x88, 0x95, 0x58, 0xED, 0x60, 0xC7, 0xE4, 0xEF, 0xF4, 0xA7, 0xA2,
0xD8, 0x70, 0x35, 0x3C, 0x45, 0x9C, 0x07, 0xE2, 0xA0, 0x70, 0x57, 0x60,
0x50, 0x18, 0xE1, 0x72, 0x80, 0x60, 0xC0, 0x7C, 0xB6, 0x78, 0xEB, 0x16,
0xF6, 0xC0, 0x69, 0x86, 0x7A, 0x88, 0x83, 0xEC, 0x8C, 0xE0, 0xBD, 0x84,
0xBC, 0x84, 0x90, 0xD4, 0xCE, 0x08, 0xDE, 0x02, 0xC3, 0x64, 0xC9, 0x1E,
0xE2, 0x00, 0xA2, 0x20, 0x96, 0x50, 0xD4, 0x0C, 0x00, 0x80, 0xC8, 0xB0,
0xA3, 0x8C, 0xFA, 0xE4, 0xE8, 0xC0, 0xB4, 0xB8, 0xCB, 0xB4, 0x89, 0x04,
0xE6, 0xD8, 0xA2, 0x8E, 0x81, 0xFC, 0x85, 0xA0, 0xC4, 0x80, 0xF7, 0xD8,
0x28, 0xA0, 0x1B, 0x84, 0x95, 0x80, 0x24, 0xCA, 0x4C, 0x94, 0x9D, 0x7C,
0x44, 0x80, 0xAA, 0xC6, 0x82, 0xFC, 0x77, 0x34, 0xAB, 0x28, 0xA1, 0xE6,
0x1F, 0x04, 0xDE, 0x04, 0xCB, 0x00, 0x01, 0xB8, 0x26, 0x44, 0xF4, 0x82,
0xF4, 0x78, 0x1A, 0xC2, 0x55, 0x24, 0xFB, 0x30, 0xE1, 0x50, 0x8E, 0xFE,
0xC1, 0x5C, 0xAF, 0x40, 0xB6, 0x68, 0xF0, 0x60, 0x0E, 0x4C, 0xFB, 0x00,
0x39, 0x00, 0x1E, 0xE4, 0x8A, 0x1C, 0x2D, 0xDC, 0x48, 0x28, 0xCF, 0x0C,
0x62, 0x14, 0x72, 0x58, 0x86, 0x70, 0xF2, 0x68, 0xFF, 0x40, 0xF6, 0x2C,
0x01, 0x10, 0x0D, 0xAA, 0x2D, 0x4C, 0x4D, 0x44, 0xDC, 0x80, 0x90, 0xE4,
0xBC, 0x10, 0xCA, 0x00, 0xB0, 0x40, 0xB8, 0x9A, 0x7B, 0x18, 0x26, 0x50,
0x24, 0x40, 0x3C, 0x22, 0x1B, 0x24, 0xFE, 0x5C, 0x17, 0x30, 0x8B, 0x2E,
0xC3, 0x3C, 0xF0, 0x08, 0x7C, 0xA0, 0xAC, 0x70, 0xB8, 0x9C, 0x4E, 0xF2,
0x70, 0xA0, 0x19, 0x68, 0x35, 0xAC, 0x4A, 0x48, 0x28, 0x60, 0x8B, 0x8C,
0x11, 0xBC, 0x06, 0x3E, 0xCD, 0x38, 0x37, 0x72, 0x45, 0x28, 0x86, 0x16,
0x6A, 0x80, 0x5C, 0xC4, 0xF3, 0x90, 0x17, 0x88, 0x29, 0x50, 0x95, 0xB6,
0xA1, 0x54, 0x88, 0x52, 0x6B, 0xE0, 0xB7, 0xE6, 0xB1, 0x7C, 0xE0, 0xFC,
0x79, 0x80, 0x70, 0x04, 0xB7, 0x84, 0x80, 0x12, 0x40, 0xC0, 0x12, 0x9C,
0x4D, 0x44, 0xC2, 0xD0, 0xE7, 0x18, 0x9E, 0x3C, 0xA5, 0xF8, 0x24, 0x2C,
0x23, 0x60, 0x14, 0x7A, 0xF0, 0x18, 0x8A, 0xFA, 0x42, 0x18, 0x91, 0xF6,
0xCF, 0x7C, 0xA6, 0xB8, 0x5E, 0x00, 0x32, 0x28, 0x4C, 0x88, 0x00, 0xE0,
0xB8, 0xC0, 0x91, 0x6A, 0x36, 0x68, 0xB8, 0x88, 0xCC, 0xC0, 0x79, 0x82,
0xBF, 0xF8, 0xD2, 0x56, 0xBE, 0x88, 0xDB, 0x8A, 0xF3, 0x40, 0x4C, 0x78,
0x49, 0x80, 0xB8, 0xD0, 0x1D, 0x18, 0x4F, 0x60, 0x1C, 0x68, 0x84, 0xD6,
0xBB, 0x18, 0x4C, 0xD0, 0x16, 0x50, 0x96, 0x26, 0x01, 0xD8, 0xD1, 0x72,
0xCF, 0x88, 0xC5, 0x86, 0x72, 0x08, 0x61, 0xD4, 0xFF, 0x00, 0x62, 0xA2,
0x2C, 0xAC, 0x1C, 0xDA, 0x86, 0x68, 0x17, 0x1E, 0xAD, 0xE0, 0xC3, 0x86,
0x32, 0x70, 0x0B, 0x06, 0x49, 0x80, 0x42, 0x8A, 0x10, 0x80, 0xFA, 0x22,
0x0D, 0x00, 0xEB, 0x80, 0x62, 0x40, 0xAE, 0x7E, 0x5B, 0xA8, 0x58, 0xA6,
0x61, 0x30, 0x16, 0x36, 0x7E, 0xF0, 0xD2, 0xD6, 0xCE, 0xC0, 0xF5, 0xA0,
0x3A, 0xE8, 0xF3, 0x74, 0x23, 0x78, 0xBF, 0x52, 0xAB, 0x08, 0x94, 0x3C,
0x70, 0x80, 0x94, 0x88, 0x46, 0x00, 0x10, 0x30, 0xC8, 0x88, 0x59, 0x54,
0xAA, 0x20, 0xEC, 0x58, 0x44, 0xD0, 0xE9, 0x5A, 0xF2, 0x48, 0x95, 0x4C,
0x85, 0x88, 0x51, 0xAA, 0x90, 0x90, 0x74, 0xF2, 0x54, 0x00, 0xE8, 0x9E,
0xE2, 0xAC, 0x50, 0x98, 0xB7, 0xA0, 0x77, 0xCA, 0xE6, 0x50, 0x78, 0xCC,
0x15, 0xA0, 0x3B, 0x46, 0xAA, 0x64, 0x17, 0x66, 0xD9, 0x18, 0xC7, 0xBC,
0x8A, 0xAC, 0x3E, 0x7E, 0xA4, 0x00, 0x51, 0xC8, 0x41, 0xB0, 0x8B, 0xBC,
0x3B, 0x78, 0x9B, 0x06, 0x38, 0x34, 0xA1, 0x84, 0x29, 0x30, 0x5B, 0x16,
0x20, 0x88, 0x9B, 0xA0, 0x90, 0xF0, 0x8D, 0x96, 0x80, 0xC4, 0xC0, 0x04,
0x6E, 0xC0, 0xAF, 0x72, 0x8E, 0xE0, 0x65, 0xAA, 0xC2, 0xF0, 0xC7, 0x04,
0xBC, 0x78, 0x89, 0x3C, 0x6C, 0x70, 0x50, 0x5C, 0x46, 0xEC, 0xA6, 0x2E,
0x5F, 0x88, 0xD5, 0xDA, 0x6A, 0x70, 0x1A, 0xE0, 0xCE, 0x00, 0xC4, 0x04,
0x00, 0x40, 0xA8, 0xD0, 0x7F, 0x48, 0x72, 0xEC, 0x88, 0x50, 0xE4, 0xC8,
0x27, 0x50, 0xF5, 0xEC, 0xBE, 0xD4, 0xDA, 0x82, 0x35, 0x18, 0x61, 0xE0,
0xD4, 0x70, 0x9B, 0x28, 0x48, 0x00, 0x1F, 0xAC, 0x09, 0x40, 0x14, 0x06,
0xBC, 0x18, 0xD9, 0xB4, 0x54, 0x20, 0x82, 0xDA, 0xAA, 0x50, 0x8B, 0x7C,
0xF7, 0xBC, 0xFD, 0x2A, 0x6B, 0x08, 0x06, 0x0C, 0xF7, 0xA8, 0xFD, 0x48,
0x9E, 0x00, 0x64, 0xD6, 0x44, 0x3C, 0xF2, 0x0E, 0xD9, 0x18, 0x5F, 0x90,
0xA5, 0xBC, 0xD6, 0xE2, 0x55, 0xB0, 0xE3, 0xC0, 0xCE, 0xAC, 0x30, 0xA0,
0xE6, 0xF8, 0x1F, 0x00, 0x9D, 0x00, 0xA6, 0x9C, 0xD2, 0xE0, 0x89, 0x74,
0x68, 0x24, 0xF3, 0x54, 0xCA, 0x58, 0x8A, 0x88, 0x1E, 0x3C, 0xAA, 0x18,
0xEB, 0x00, 0x7E, 0xA4, 0xE5, 0xD8, 0x39, 0x46, 0x51, 0x58, 0x09, 0xCC,
0x4C, 0xF8, 0x50, 0x1C, 0x6C, 0x00, 0xC2, 0x00, 0x70, 0x20, 0xD8, 0x76,
0x37, 0x90, 0x2E, 0xF0, 0xB4, 0x70, 0x4C, 0x7E, 0xB7, 0x90, 0xE6, 0x34,
0x13, 0x68, 0x7F, 0xE2, 0xDF, 0x18, 0x30, 0x18, 0x6C, 0x44, 0xFC, 0x90,
0x18, 0xA0, 0x76, 0x66, 0x30, 0x90, 0x55, 0xD8, 0xB9, 0xE8, 0x82, 0x58,
0xC8, 0x38, 0x9F, 0xB4, 0x65, 0xD0, 0x4E, 0x8A, 0x61, 0x94, 0x7B, 0xBE,
0x49, 0x50, 0x8E, 0x42, 0x12, 0x7C, 0xEC, 0x3C, 0xAF, 0x00, 0x6B, 0xD8,
0xED, 0x28, 0xE1, 0x3A, 0x95, 0xB8, 0xE8, 0x16, 0xD7, 0x28, 0x9B, 0x7A,
0x05, 0xB0, 0x60, 0x14, 0xBD, 0xC0, 0xB0, 0xDC, 0x63, 0xA8, 0x80, 0x76,
0x40, 0x48, 0xCA, 0xE4, 0x11, 0xA0, 0x5A, 0xF0, 0xE3, 0x3C, 0xE6, 0xA4,
0xE9, 0x10, 0x54, 0xC4, 0xEF, 0x18, 0xC4, 0x66, 0xB0, 0xA0, 0x02, 0xDE,
0x0A, 0x44, 0x2D, 0x1A, 0xDB, 0x38, 0x2E, 0x28, 0xD6, 0xC0, 0x6A, 0xD8,
0x3C, 0x80, 0x00, 0xA0, 0x98, 0xE0, 0x6D, 0x26, 0xAE, 0x70, 0x58, 0x18,
0xFC, 0xD0, 0xD5, 0x1E, 0x2B, 0xE0, 0xAA, 0x52, 0xF6, 0x7C, 0x8F, 0xA6,
0xCF, 0x80, 0x5C, 0x68, 0xED, 0xD0, 0xD8, 0x30, 0x21, 0x40, 0xC3, 0x20,
0x0C, 0xA4, 0xF4, 0x5A, 0xF7, 0x50, 0x5C, 0x70, 0xEE, 0x64, 0xBE, 0x7A,
0x15, 0x20, 0x1D, 0x06, 0x2B, 0xCC, 0x11, 0x8A, 0x9A, 0x10, 0x8D, 0x7C,
0xFB, 0x90, 0xDA, 0x5E, 0x9C, 0x00, 0x6C, 0x9E, 0x5E, 0xB4, 0x9B, 0x12,
0x11, 0x40, 0x87, 0xF2, 0x7A, 0x54, 0x2C, 0x35, 0x2C, 0x03, 0x70, 0xEA,
0xE6, 0xBC, 0x58, 0xCC, 0x16, 0xAE, 0x1C, 0x3D, 0x0B, 0x48, 0x5F, 0x3E,
0x1A, 0xEA, 0x8C, 0xB6, 0xB2, 0x15, 0x00, 0x2A, 0x46, 0xD0, 0x40, 0x22,
0x76, 0xE9, 0x00, 0x87, 0x80, 0xDA, 0x88, 0x66, 0xBA, 0xFF, 0x10, 0x38,
0xAA, 0x3D, 0xE8, 0xAE, 0xF2, 0x66, 0xC0, 0x3A, 0x0A, 0x16, 0x10, 0x09,
0xE0, 0xB2, 0x70, 0x0F, 0xAC, 0xF7, 0xDC, 0x9B, 0x46, 0xEF, 0x80, 0x24,
0xC4, 0xB0, 0x48, 0xE4, 0x98, 0x4E, 0x00, 0x50, 0x50, 0xA8, 0xAC, 0x9D,
0xDC, 0xA2, 0x80, 0x5C, 0x28, 0x34, 0x74, 0x4D, 0xEE, 0x0A, 0x70, 0x99,
0x14, 0x91, 0xD4, 0x35, 0xCE, 0x50, 0x80, 0x84, 0x4E, 0x04, 0xE0, 0x88,
0x9A, 0xBA, 0x38, 0x90, 0xA8, 0x7B, 0x30, 0xF3, 0x8E, 0xAE, 0x40, 0xD8,
0xF4, 0x01, 0x78, 0xE7, 0x32, 0x62, 0x18, 0x83, 0x0A, 0x95, 0xCC, 0xC3,
0x94, 0x82, 0x80, 0x96, 0x82, 0x14, 0x88, 0x95, 0x58, 0xED, 0x60, 0xC7,
0xE4, 0xEF, 0xF4, 0xA7, 0xA2, 0xD8, 0x70, 0x35, 0x3C, 0x45, 0x9C, 0x07,
0xE2, 0xA0, 0x70, 0x57, 0x60, 0x50, 0x18, 0xE1, 0x72, 0x80, 0x60, 0xC0,
0x7C, 0xB6, 0x78, 0xEB, 0x16, 0xF6, 0xC0, 0x69, 0x86, 0x7A, 0x88, 0x83,
0xEC, 0x8C, 0xE0, 0xBD, 0x84, 0xBC, 0x84, 0x90, 0xD4, 0xCE, 0x08, 0xDE,
0x02, 0xC3, 0x64, 0xC9, 0x1E, 0xE2, 0x00, 0xA2, 0x20, 0x96, 0x50, 0xD4,
0x0C, 0x00, 0x80, 0xC8, 0xB0, 0xA3, 0x8C, 0xFA, 0xE4, 0xE8, 0xC0, 0xB4,
0xB8, 0xCB, 0xB4, 0x89, 0x04, 0xE6, 0xD8, 0xA2, 0x8E, 0x81, 0xFC, 0x85,
0xA0, 0xC4, 0x80, 0xF7, 0xD8, 0x28, 0xA0, 0x1B, 0x84, 0x95, 0x80, 0x24,
0xCA, 0x4C, 0x94, 0x9D, 0x7C, 0x44, 0x80, 0xAA, 0xC6, 0x82, 0xFC, 0x77,
0x34, 0xAB, 0x28, 0xA1, 0xE6, 0x1F, 0x04, 0xDE, 0x04, 0xCB, 0x00, 0x01,
0xB8, 0x26, 0x44, 0xF4, 0x82, 0xF4, 0x78, 0x1A, 0xC2, 0x55, 0x24, 0xFB,
0x30, 0xE1, 0x50, 0x8E, 0xFE, 0xC1, 0x5C, 0xAF, 0x40, 0xB6, 0x68, 0xF0,
0x60, 0x0E, 0x4C, 0xFB, 0x00, 0x39, 0x00, 0x1E, 0xE4, 0x8A, 0x1C, 0x2D,
0xDC, 0x48, 0x28, 0xCF, 0x0C, 0x62, 0x14, 0x72, 0x58, 0x86, 0x70, 0xF2,
0x68, 0xFF, 0x40, 0xF6, 0x2C, 0x01, 0x10, 0x0D, 0xAA, 0x2D, 0x4C, 0x4D,
0x44, 0xDC, 0x80, 0x90, 0xE4, 0xBC, 0x10, 0xCA, 0x00, 0xB0, 0x40, 0xB8,
0x9A, 0x7B, 0x18, 0x26, 0x50, 0x24, 0x40, 0x3C, 0x22, 0x1B, 0x24, 0xFE,
0x5C, 0x17, 0x30, 0x8B, 0x2E, 0xC3, 0x3C, 0xF0, 0x08, 0x7C, 0xA0, 0xAC,
0x70, 0xB8, 0x9C, 0x4E, 0xF2, 0x70, 0xA0, 0x19, 0x68, 0x35, 0xAC, 0x4A,
0x48, 0x28, 0x60, 0x8B, 0x8C, 0x11, 0xBC, 0x06, 0x3E, 0xCD, 0x38, 0x37,
0x72, 0x45, 0x28, 0x86, 0x16, 0x6A, 0x80, 0x5C, 0xC4, 0xF3, 0x90, 0x17,
0x88, 0x29, 0x50, 0x95, 0xB6, 0xA1, 0x54, 0x88, 0x52, 0x6B, 0xE0, 0xB7,
0xE6, 0xB1, 0x7C, 0xE0, 0xFC, 0x79, 0x80, 0x70, 0x04, 0xB7, 0x84, 0x80,
0x12, 0x40, 0xC0, 0x12, 0x9C, 0x4D, 0x44, 0xC2, 0xD0, 0xE7, 0x18, 0x9E,
0x3C, 0xA5, 0xF8, 0x24, 0x2C, 0x23, 0x60, 0x14, 0x7A, 0xF0, 0x18, 0x8A,
0xFA, 0x42, 0x18, 0x91, 0xF6, 0xCF, 0x7C, 0xA6, 0xB8, 0x5E, 0x00, 0x32,
0x28, 0x4C, 0x88, 0x00, 0xE0, 0xB8, 0xC0, 0x91, 0x6A, 0x36, 0x68, 0xB8,
0x88, 0xCC, 0xC0, 0x79, 0x82, 0xBF, 0xF8, 0xD2, 0x56, 0xBE, 0x88, 0xDB,
0x8A, 0xF3, 0x40, 0x4C, 0x78, 0x49, 0x80, 0xB8, 0xD0, 0x1D, 0x18, 0x4F,
0x60, 0x1C, 0x68, 0x84, 0xD6, 0xBB, 0x18, 0x4C, 0xD0, 0x16, 0x50, 0x96,
0x26, 0x01, 0xD8, 0xD1, 0x72, 0xCF, 0x88, 0xC5, 0x86, 0x72, 0x08, 0x61,
0xD4, 0xFF, 0x00, 0x62, 0xA2, 0x2C, 0xAC, 0x1C, 0xDA, 0x86, 0x68, 0x17,
0x1E, 0xAD, 0xE0, 0xC3, 0x86, 0x32, 0x70, 0x0B, 0x06, 0x49, 0x80, 0x42,
0x8A, 0x10, 0x80, 0xFA, 0x22, 0x0D, 0x00, 0xEB, 0x80, 0x62, 0x40, 0xAE,
0x7E, 0x5B, 0xA8, 0x58, 0xA6, 0x61, 0x30, 0x16, 0x36, 0x7E, 0xF0, 0xD2,
0xD6, 0xCE, 0xC0, 0xF5, 0xA0, 0x3A, 0xE8, 0xF3, 0x74, 0x23, 0x78, 0xBF,
0x52, 0xAB, 0x08, 0x94, 0x3C, 0x70, 0x80, 0x94, 0x88, 0x46, 0x00, 0x10,
0x30, 0xC8, 0x88, 0x59, 0x54, 0xAA, 0x20, 0xEC, 0x58, 0x44, 0xD0, 0xE9,
0x5A, 0xF2, 0x48, 0x95, 0x4C, 0x85, 0x88, 0x51, 0xAA, 0x90, 0x90, 0x74,
0xF2, 0x54, 0x00, 0xE8, 0x9E, 0xE2, 0xAC, 0x50, 0x98, 0xB7, 0xA0, 0x77,
0xCA, 0xE6, 0x50, 0x78, 0xCC, 0x15, 0xA0, 0x3B, 0x46, 0xAA, 0x64, 0x17,
0x66, 0xD9, 0x18, 0xC7, 0xBC, 0x8A, 0xAC, 0x3E, 0x7E, 0xA4, 0x00, 0x51,
0xC8, 0x41, 0xB0, 0x8B, 0xBC, 0x3B, 0x78, 0x9B, 0x06, 0x38, 0x34, 0xA1,
0x84, 0x29, 0x30, 0x5B, 0x16, 0x20, 0x88, 0x9B, 0xA0, 0x90, 0xF0, 0x8D,
0x96, 0x80, 0xC4, 0xC0, 0x04, 0x6E, 0xC0, 0xAF, 0x72, 0x8E, 0xE0, 0x65,
0xAA, 0xC2, 0xF0, 0xC7, 0x04, 0xBC, 0x78, 0x89, 0x3C, 0x6C, 0x70, 0x50,
0x5C, 0x46, 0xEC, 0xA6, 0x2E, 0x5F, 0x88, 0xD5, 0xDA, 0x6A, 0x70, 0x1A,
0xE0, 0xCE, 0x00, 0xC4, 0x04, 0x00, 0x40, 0xA8, 0xD0, 0x7F, 0x48, 0x72,
0xEC, 0x88, 0x50, 0xE4, 0xC8, 0x27, 0x50, 0xF5, 0xEC, 0xBE, 0xD4, 0xDA,
0x82, 0x35, 0x18, 0x61, 0xE0, 0xD4, 0x70, 0x9B, 0x28, 0x48, 0x00, 0x1F,
0xAC, 0x09, 0x40, 0x14, 0x06, 0xBC, 0x18, 0xD9, 0xB4, 0x54, 0x20, 0x82,
0xDA, 0xAA, 0x50, 0x8B, 0x7C, 0xF7, 0xBC, 0xFD, 0x2A, 0x6B, 0x08, 0x06,
0x0C, 0xF7, 0xA8, 0xFD, 0x48, 0x9E, 0x00, 0x64, 0xD6, 0x44, 0x3C, 0xF2,
0x0E, 0xD9, 0x18, 0x5F, 0x90, 0xA5, 0xBC, 0xD6, 0xE2, 0x55, 0xB0, 0xE3,
0xC0, 0xCE, 0xAC, 0x30, 0xA0, 0xE6, 0xF8, 0x1F, 0x00, 0x9D, 0x00, 0xA6,
0x9C, 0xD2, 0xE0, 0x89, 0x74, 0x68, 0x24, 0xF3, 0x54, 0xCA, 0x58, 0x8A,
0x88, 0x1E, 0x3C, 0xAA, 0x18, 0xEB, 0x00, 0x7E, 0xA4, 0xE5, 0xD8, 0x39,
0x46, 0x51, 0x58, 0x09, 0xCC, 0x4C, 0xF8, 0x50, 0x1C, 0x6C, 0x00, 0xC2,
0x00, 0x70, 0x20, 0xD8, 0x76, 0x37, 0x90, 0x2E, 0xF0, 0xB4, 0x70, 0x4C,
0x7E, 0xB7, 0x90, 0xE6, 0x34, 0x13, 0x68, 0x7F, 0xE2, 0xDF, 0x18, 0x30,
0x18, 0x6C, 0x44, 0xFC, 0x90, 0x18, 0xA0, 0x76, 0x66, 0x30, 0x90, 0x55,
0xD8, 0xB9, 0xE8, 0x82, 0x58, 0xC8, 0x38, 0x9F, 0xB4, 0x65, 0xD0, 0x4E,
0x8A, 0x61, 0x94, 0x7B, 0xBE, 0x49, 0x50, 0x8E, 0x42, 0x12, 0x7C, 0xEC,
0x3C, 0xAF, 0x00, 0x6B, 0xD8, 0xED, 0x28, 0xE1, 0x3A, 0x95, 0xB8, 0xE8,
0x16, 0xD7, 0x28, 0x9B, 0x7A, 0x05, 0xB0, 0x60, 0x14, 0xBD, 0xC0, 0xB0,
0xDC, 0x63, 0xA8, 0x80, 0x76, 0x40, 0x48, 0xCA, 0xE4, 0x11, 0xA0, 0x5A,
0xF0, 0xE3, 0x3C, 0xE6, 0xA4, 0xE9, 0x10, 0x54, 0xC4, 0xEF, 0x18, 0xC4,
0x66, 0xB0, 0xA0, 0x02, 0xDE, 0x0A, 0x44, 0x2D, 0x1A, 0xDB, 0x38, 0x2E,
0x28, 0xD6, 0xC0, 0x6A, 0xD8, 0x3C, 0x80, 0x00, 0xA0, 0x98, 0xE0, 0x6D,
0x26, 0xAE, 0x70, 0x58, 0x18, 0xFC, 0xD0, 0xD5, 0x1E, 0x2B, 0xE0, 0xAA,
0x52, 0xF6, 0x7C, 0x8F, 0xA6, 0xCF, 0x80, 0x5C, 0x68, 0xED, 0xD0, 0xD8,
0x30, 0x21, 0x40, 0xC3, 0x20, 0x0C, 0xA4, 0xF4, 0x5A, 0xF7, 0x50, 0x5C,
0x70, 0xEE, 0x64, 0xBE, 0x7A, 0x15, 0x20, 0x1D, 0x06, 0x2B, 0xCC, 0x11,
0x8A, 0x9A, 0x10, 0x8D, 0x7C, 0xFB, 0x90, 0xDA, 0x5E, 0x9C, 0x00, 0x6C,
0x9E, 0x5E, 0xB4, 0x9B, 0x12, 0x11, 0x40, 0x87, 0xF2, 0x7A, 0x54, 0x2C,
0x36, 0x2C, 0x03, 0x70, 0x2C, 0xCA, 0x36, 0x03, 0x70, 0x53, 0x00, 0xBC,
0x58, 0xCC, 0x16, 0xAE, 0x24, 0xFB, 0x44, 0x49, 0x80, 0x2C, 0xDD, 0x30,
0x03, 0x90, 0xBB, 0xE6, 0xBC, 0x60, 0xCB, 0x19, 0xAE, 0x24, 0x90, 0x2D,
0x49, 0x88, 0xFF, 0x1A, 0xEA, 0x8C, 0x77, 0xB2, 0x15, 0x00, 0x2A, 0x46,
0xD0, 0x40, 0x22, 0x76, 0xE9, 0x00, 0x87, 0x80, 0xDA, 0x88, 0x66, 0xBA,
0xFF, 0x10, 0x38, 0xAA, 0x3D, 0xE8, 0x71, 0x01, 0x66, 0xC8, 0x3A, 0x0A,
0x16, 0x10, 0x09, 0xE0, 0xB2, 0x70, 0xD0, 0xBB, 0xF7, 0xE4, 0x60, 0x55,
0xEF, 0x88, 0x07, 0xC4, 0xB0, 0x50, 0xE4, 0x98, 0x4E, 0x00, 0x33, 0x50,
0xA8, 0xB4, 0x80, 0xDC, 0xA2, 0x88, 0x3F, 0x28, 0x34, 0x7C, 0x30, 0xEE,
0x0A, 0x78, 0x7C, 0x14, 0x91, 0xDC, 0x18, 0xCE, 0x50, 0x88, 0x84, 0x4E,
0x04, 0xE0, 0x6B, 0x9A, 0xBA, 0x40, 0x73, 0xA8, 0x7B, 0x38, 0xD6, 0x8E,
0xAE, 0x48, 0xBB, 0xF4, 0x01, 0x80, 0xCA, 0x32, 0x62, 0x20, 0x66, 0x0A,
0x95, 0xD4, 0xC3, 0x94, 0x82, 0x80, 0x79, 0x82, 0x14, 0x90, 0x78, 0x58,
0xED, 0x68, 0xAA, 0xE4, 0xEF, 0xFC, 0x8A, 0xA2, 0xD8, 0x78, 0x18, 0x3C,
0x45, 0xA4, 0xEA, 0xE2, 0xA0, 0x78, 0x3A, 0x60, 0x50, 0x20, 0xC4, 0x72,
0x80, 0x68, 0xA3, 0x7C, 0xB6, 0x80, 0xCE, 0x16, 0xF6, 0xC8, 0x4C, 0x86,
0x7A, 0x90, 0x66, 0xEC, 0x8C, 0xE8, 0xA0, 0x84, 0xBC, 0x8C, 0x73, 0xD4,
0xCE, 0x10, 0xE2, 0x4A, 0x48, 0xAA, 0xC9, 0x0E, 0x50, 0xF8, 0xA2, 0x68,
0x96, 0x97, 0xE9, 0x25, 0x00, 0x88, 0x88, 0xF6, 0x63, 0xD2, 0xA2, 0xE8,
0xE8, 0xE0, 0xB8, 0x00, 0x4B, 0xFB, 0x8D, 0x4C, 0xE6, 0x1F, 0xA0, 0x75,
0x7F, 0xE3, 0x83, 0x87, 0xC2, 0x67, 0xF5, 0xBF, 0x26, 0x87, 0x42, 0x94,
0x95, 0x88, 0xDD, 0xCA, 0x4C, 0x9C, 0xCD, 0x31, 0x4F, 0xC6, 0xAB, 0x0C,
0x82, 0x1C, 0x97, 0x56, 0xAC, 0x4C, 0xAA, 0xC6, 0x2C, 0x4A, 0xB3, 0x44,
0x68, 0x42, 0x06, 0x8B, 0x43, 0x8A, 0x89, 0xC2, 0x3D, 0x93, 0x3F, 0x08,
0xEA, 0x64, 0x3B, 0x49, 0xF6, 0x96, 0xE0, 0x1C, 0xC1, 0x89, 0xA0, 0x1C,
0xE6, 0x25, 0xC2, 0x12, 0x0F, 0x2C, 0xFD, 0x70, 0x79, 0x1C, 0x67, 0x02,
0x85, 0xEE, 0x9D, 0x23, 0x48, 0x4A, 0xC5, 0xF3, 0x72, 0xC9, 0x85, 0x9E,
0x90, 0xB6, 0xF6, 0xAE, 0x18, 0x86, 0xF5, 0x23, 0xF1, 0x0F, 0x2D, 0xF0,
0x3D, 0x09, 0x3D, 0xF9, 0xFB, 0x34, 0x96, 0x2A, 0xBC, 0x30, 0x4C, 0xB0,
0xB5, 0x86, 0xF8, 0xBE, 0x7C, 0xA9, 0x26, 0xE0, 0x3F, 0x20, 0x3D, 0xBB,
0x3D, 0x6A, 0x0D, 0xA2, 0x47, 0x76, 0x8B, 0x1E, 0x05, 0x34, 0xF4, 0xA2,
0x81, 0x3B, 0x2C, 0x8A, 0x51, 0xDD, 0x5E, 0xC5, 0x80, 0xE6, 0x32, 0xAE,
0x57, 0xF2, 0x4A, 0x38, 0x50, 0x58, 0xC1, 0xA6, 0xA0, 0xFD, 0x07, 0xD5,
0xEF, 0x7E, 0x38, 0x92, 0x45, 0x49, 0x86, 0xB5, 0x6A, 0x70, 0x7B, 0xBC,
0x2B, 0xA8, 0x64, 0xC9, 0x29, 0xE0, 0xB5, 0xFC, 0x05, 0x72, 0x88, 0x7A,
0x4A, 0xBC, 0xB8, 0x81, 0xB1, 0x14, 0x09, 0x42, 0xAB, 0xC6, 0x77, 0xB4,
0xA7, 0x41, 0x86, 0x5E, 0x41, 0xE5, 0x18, 0xEA, 0x52, 0x24, 0xA5, 0x38,
0xEE, 0xE4, 0xC9, 0x7F, 0xB1, 0x34, 0xBC, 0x73, 0x33, 0x94, 0xC8, 0xBC,
0xE7, 0xEB, 0x89, 0xF1, 0xC6, 0x17, 0xC5, 0x10, 0xCF, 0x84, 0xFA, 0xD2,
0x5E, 0x08, 0x42, 0xDD, 0x6C, 0xB2, 0x04, 0xBB, 0xB9, 0x06, 0xB1, 0xA4,
0xC7, 0xA8, 0xB8, 0xA8, 0xDC, 0x7D, 0x0A, 0xC2, 0xDF, 0x1B, 0x6E, 0x70,
0xC1, 0xCE, 0xBE, 0xCA, 0x0C, 0x83, 0xDC, 0xB8, 0x59, 0x3D, 0xC8, 0x85,
0x3D, 0x42, 0x53, 0x3B, 0x24, 0xAE, 0xA4, 0x10, 0x8B, 0x58, 0x4C, 0xF1,
0x26, 0x0D, 0xA1, 0x6C, 0xD4, 0x18, 0xA1, 0xB2, 0xEF, 0xAC, 0x67, 0xA0,
0x03, 0x48, 0x69, 0x17, 0x18, 0x46, 0x72, 0x5F, 0x9E, 0x62, 0x1A, 0xC1,
0x86, 0x68, 0x07, 0xD3, 0xAD, 0x03, 0xC6, 0xAA, 0xCC, 0x50, 0x35, 0x4C,
0x4A, 0xA5, 0xDF, 0xCA, 0x3A, 0xC0, 0x78, 0xF2, 0x1B, 0x79, 0xA1, 0x87,
0x18, 0x4F, 0xAF, 0xAC, 0x5C, 0x78, 0x5A, 0xD4, 0x77, 0x01, 0x9C, 0x9E,
0xA5, 0x36, 0x86, 0x1C, 0x2C, 0xC0, 0xAB, 0xE6, 0xF1, 0x28, 0x59, 0xBA,
0xE1, 0xBB, 0x73, 0x98, 0x7A, 0x70, 0x0A, 0x82, 0x27, 0xC0, 0xFA, 0xCE,
0x7D, 0x43, 0x97, 0x90, 0x0E, 0xF0, 0x07, 0x97, 0xB7, 0x99, 0xD9, 0x5E,
0x31, 0xDF, 0x86, 0x9A, 0x27, 0x8B, 0xDA, 0xAC, 0x92, 0x01, 0x3E, 0xED,
0x3D, 0x97, 0x7C, 0xC2, 0x19, 0x68, 0x47, 0x9E, 0x08, 0xF2, 0x0E, 0xD8,
0x6C, 0xE3, 0x05, 0x32, 0xA4, 0x90, 0xA6, 0x0F, 0xDB, 0x00, 0x48, 0xBF,
0x57, 0x6B, 0xC4, 0x75, 0xDB, 0x45, 0xD5, 0x8D, 0x67, 0xB4, 0xEB, 0x7E,
0xD1, 0x18, 0xFD, 0x0E, 0x6E, 0x1A, 0xE9, 0xC3, 0x31, 0x86, 0xAA, 0x2D,
0xEF, 0x74, 0x5E, 0xC7, 0x38, 0x99, 0x12, 0x56, 0x4F, 0xCB, 0x00, 0xE6,
0xBF, 0x52, 0x92, 0xFE, 0xDF, 0xC4, 0xE6, 0x4A, 0x2C, 0x00, 0x64, 0xB5,
0x9C, 0x59, 0x1B, 0xB1, 0x78, 0xFF, 0x85, 0x44, 0xEA, 0xBB, 0x8F, 0x9C,
0xB9, 0xD8, 0xFD, 0x5F, 0xF3, 0xFB, 0xEC, 0xFE, 0xFD, 0x90, 0xFB, 0x27,
0x20, 0x70, 0x8F, 0xF9, 0x7A, 0x46, 0xF1, 0x72, 0x9E, 0x47, 0x9E, 0xDE,
0x8E, 0x6F, 0x29, 0x2C, 0x45, 0x93, 0xE9, 0xEF, 0x66, 0x57, 0xAD, 0x2E,
0xBF, 0xA5, 0xDA, 0xA9, 0x44, 0xF8, 0x80, 0x2F, 0x8C, 0xB2, 0x9C, 0xF9,
0x49, 0x27, 0x29, 0x8C, 0x27, 0x8F, 0xCC, 0x48, 0xBD, 0xE9, 0xDB, 0xDB,
0x59, 0x00, 0x9E, 0x29, 0x62, 0x92, 0x8C, 0x4D, 0xFA, 0xE3, 0xFD, 0x0A,
0x70, 0x2F, 0xBD, 0x4C, 0x26, 0xEB, 0x12, 0x95, 0x04, 0x46, 0x9B, 0x3C,
0x71, 0xA4, 0x40, 0x76, 0x6E, 0x5B, 0x55, 0x92, 0xA5, 0x91, 0xEB, 0x25,
0x66, 0xFF, 0x20, 0x20, 0x4B, 0x14, 0xC5, 0xE3, 0xE6, 0xD8, 0x33, 0xE0,
0xEB, 0x68, 0x5C, 0x9E, 0xD2, 0xB5, 0x9E, 0xB7, 0xE5, 0x84, 0xFE, 0xA1,
0x4A, 0x8D, 0xF8, 0xF0, 0x6D, 0xA4, 0x40, 0x5B, 0xAA, 0x03, 0x7E, 0x79,
0xFB, 0x1B, 0xA7, 0xA6, 0x7F, 0xC0, 0x58, 0x34, 0xE2, 0x3B, 0x4F, 0x1F,
0x6C, 0xD5, 0xD8, 0x43, 0x9E, 0x80, 0x33, 0x92, 0x41, 0xF8, 0x43, 0x36,
0x8E, 0xB0, 0x4C, 0x4E, 0x16, 0x77, 0xD6, 0xF1, 0x13, 0x68, 0x7F, 0xFA,
0xE1, 0x58, 0x30, 0x1C, 0x6C, 0x94, 0xFC, 0x98, 0x18, 0xF0, 0x76, 0x72,
0x30, 0xE0, 0x55, 0x02, 0xBA, 0xB8, 0x03, 0xB9, 0x38, 0x7F, 0x20, 0x16,
0xD5, 0x17, 0x4F, 0xD2, 0xE1, 0xFC, 0xEB, 0x05, 0x49, 0x50, 0x8E, 0x42,
0x12, 0x9C, 0xEE, 0x84, 0x30, 0x68, 0x6D, 0x50, 0x76, 0x40, 0x62, 0x9A,
0x05, 0xFF, 0xE8, 0x16, 0xD7, 0x48, 0xAB, 0x2F, 0x0D, 0xF8, 0x60, 0x38,
0xBE, 0x28, 0x32, 0xF1, 0x74, 0xEB, 0x81, 0xD6, 0x43, 0x68, 0xCA, 0xD4,
0x1B, 0x98, 0x5A, 0x18, 0xE4, 0x0C, 0xE7, 0xC8, 0xEA, 0xF0, 0x54, 0xB4,
0x53, 0x10, 0xE4, 0xAC, 0xC0, 0x5D, 0x02, 0xFE, 0x0C, 0x84, 0x9D, 0xCF,
0xEA, 0x86, 0x2E, 0x4C, 0x07, 0x38, 0x6F, 0x1E, 0x3C, 0xA9, 0x15, 0x70,
0x15, 0x00, 0x2D, 0x26, 0xAD, 0x67, 0xE9, 0x16, 0xFD, 0x16, 0xDF, 0x66,
0x2B, 0x48, 0xA9, 0x49, 0x82, 0x7A, 0x8F, 0x96, 0x0D, 0x7C, 0x5C, 0x90,
0xF5, 0xA1, 0xDC, 0x5D, 0x27, 0x12, 0xC3, 0x42, 0x35, 0xEA, 0x34, 0x78,
0xF7, 0x40, 0xBB, 0x68, 0x63, 0xC4, 0xBE, 0x5A, 0x16, 0x44, 0x3D, 0x4C,
0x9B, 0x89, 0x11, 0x8A, 0x9A, 0x30, 0x99, 0x7C, 0xFB, 0xB0, 0xD8, 0x45,
0x9A, 0xE7, 0x6C, 0x9E, 0x5E, 0xB4, 0x9B, 0x12, 0x11, 0x40, 0x87, 0xF2,
0x7A, 0x54, 0x9F, 0x5A, 0x7D, 0x00, 0x5A, 0xCE, 0x50, 0xC0, 0xD2, 0xCE,
0x31, 0x00, 0x4F, 0x80, 0xEA, 0xF8, 0xF6, 0x42, 0xB7, 0x40, 0x78, 0xA2,
0x85, 0x78, 0x7E, 0x7A, 0x96, 0x20, 0x6A, 0xA2, 0x86, 0x70, 0xE1, 0x60,
0xC2, 0x60, 0xD7, 0x3C, 0x4F, 0x14, 0xE3, 0x5E, 0x67, 0x90, 0x04, 0xB4,
0x30, 0xB8, 0x44, 0x78, 0x3E, 0x00, 0xD0, 0x10, 0xE8, 0x64, 0x15, 0xCC,
0xB2, 0xC0, 0x7C, 0x88, 0x54, 0x2C, 0x85, 0xC6, 0xDA, 0x20, 0x91, 0x84,
0x79, 0x3C, 0x6D, 0x86, 0xD0, 0xA0, 0x64, 0x96, 0xA4, 0x20, 0x48, 0xA2,
0x0A, 0x20, 0x10, 0x88, 0xF3, 0x10, 0xFB, 0x06, 0x1E, 0x60, 0x18, 0xA4,
0x29, 0xC8, 0x8F, 0x5A, 0xF2, 0xB0, 0xAB, 0xC2, 0x1D, 0x64, 0xD3, 0x99,
0x9D, 0x20, 0xE7, 0xE2, 0x35, 0x9A, 0x1E, 0x7B, 0x96, 0x60, 0x4F, 0xFC,
0x97, 0x3C, 0x8F, 0xFA, 0x9F, 0x40, 0x4D, 0x04, 0xCF, 0x2F, 0xB0, 0x4E,
0xAA, 0xE3, 0xA1, 0x43, 0x90, 0x33, 0x41, 0xFA, 0x80, 0xB8, 0xC3, 0xAC,
0x66, 0x0A, 0x73, 0xBE, 0xF6, 0xFB, 0x69, 0x8B, 0x0A, 0x58, 0x4B, 0x2C,
0xEE, 0x50, 0x65, 0xA9, 0x1C, 0x4C, 0xC9, 0xE3, 0xCE, 0x8D, 0x7E, 0x0F,
0x0A, 0xF8, 0x02, 0xFE, 0xF5, 0x02, 0xE4, 0xA2, 0x97, 0xF3, 0xB5, 0x3F,
0x21, 0x60, 0x49, 0x0F, 0x5A, 0x3D, 0xE4, 0x2D, 0x36, 0xB1, 0x1E, 0x20,
0x89, 0x0D, 0x61, 0x3C, 0xDE, 0x13, 0x1B, 0xBF, 0xE8, 0x2B, 0x48, 0x1E,
0x24, 0x7C, 0x41, 0x58, 0x68, 0x88, 0x28, 0xA4, 0xBD, 0x1E, 0x65, 0xAB,
0x75, 0xA1, 0x0E, 0xC0, 0x64, 0xE0, 0x6A, 0xAB, 0xD5, 0xC4, 0xAF, 0x81,
0x43, 0x50, 0x59, 0xDE, 0xB7, 0x4C, 0x3A, 0x14, 0x23, 0x70, 0x39, 0x1A,
0x25, 0xBC, 0xCC, 0xDF, 0x98, 0x46, 0xCA, 0xC2, 0x5D, 0x32, 0x15, 0x3D,
0xE9, 0x2B, 0x76, 0x9B, 0x3A, 0x4C, 0x17, 0x67, 0x26, 0x28, 0x30, 0x4B,
0x7E, 0xA4, 0x4C, 0xD4, 0x4F, 0x48, 0x6E, 0x8C, 0xDC, 0x0F, 0xE6, 0x10,
0x92, 0x63, 0xD9, 0xFF, 0xF2, 0x07, 0xAA, 0xF8, 0xB7, 0x2F, 0x62, 0x58,
0x21, 0x08, 0x07, 0x84, 0x4B, 0xB5, 0x76, 0x25, 0x76, 0xC4, 0xC4, 0x4B,
0xD8, 0x6F, 0x10, 0xE4, 0x21, 0xD0, 0xB9, 0xF7, 0x48, 0xFF, 0xF8, 0xEB,
0x33, 0x22, 0x38, 0xB8, 0x69, 0x78, 0x9E, 0x22, 0x53, 0x64, 0x8E, 0x11,
0x04, 0x75, 0x5B, 0xFF, 0xFE, 0x15, 0x79, 0x2A, 0x64, 0x28, 0x5B, 0x80,
0x19, 0x0D, 0x1F, 0x1C, 0xFC, 0x50, 0x79, 0xB1, 0x40, 0x45, 0xC3, 0x6A,
0x52, 0x79, 0x3B, 0x1F, 0xBA, 0x05, 0x9F, 0xDA, 0xFF, 0x33, 0xA9, 0x6B,
0x37, 0xE1, 0x20, 0xB1, 0xA4, 0xD9, 0x64, 0x15, 0x2B, 0x77, 0xCE, 0xF8,
0xB0, 0xF7, 0x24, 0xBC, 0x89, 0xAC, 0x50, 0xBA, 0x42, 0x67, 0x72, 0x0C,
0x59, 0x7D, 0x21, 0x46, 0x33, 0x48, 0x71, 0xF6, 0x10, 0xA5, 0x83, 0x00,
0x49, 0xB0, 0x6A, 0x95, 0x55, 0x03, 0xE5, 0xE5, 0xC7, 0xC9, 0x31, 0x2D,
0x36, 0x2A, 0x0C, 0x9F, 0x5C, 0x39, 0x7C, 0x95, 0x58, 0x89, 0x7A, 0xF1,
0xD7, 0x40, 0xF0, 0x86, 0x27, 0x2C, 0x77, 0x03, 0x50, 0x84, 0x33, 0xCB,
0xED, 0xDB, 0x20, 0xD8, 0x38, 0x07, 0x4E, 0xB2, 0x8E, 0xE1, 0x59, 0x10,
0xAC, 0xE8, 0xB1, 0xBA, 0x9F, 0x0B, 0xEA, 0xAF, 0x4E, 0xE8, 0xC3, 0xC9,
0xB0, 0x95, 0xD4, 0xC1, 0x9D, 0x41, 0x80, 0xD3, 0xC6, 0xD0, 0x3F, 0x23,
0x64, 0x41, 0x84, 0x56, 0xB3, 0x8E, 0x72, 0xE5, 0x2E, 0xE1, 0xE9, 0xEF,
0x32, 0x6B, 0xF1, 0xDD, 0x68, 0x78, 0x65, 0xD1, 0x2A, 0x79, 0xD9, 0xAC,
0x37, 0x24, 0x63, 0xEF, 0x74, 0xBD, 0x1D, 0xCB, 0xB6, 0x00, 0x9F, 0x0E,
0x7D, 0xE3, 0xB3, 0xBF, 0xC3, 0x59, 0x93, 0x17, 0x3A, 0x87, 0xFA, 0x54,
0x96, 0xD1, 0xB9, 0xC2, 0x95, 0x38, 0x74, 0xE8, 0x73, 0xD2, 0x50, 0x0A,
0x24, 0x1B, 0x59, 0xFE, 0xC9, 0x48, 0xE6, 0xC3, 0xC0, 0x25, 0x6A, 0xD7,
0x41, 0x41, 0x56, 0x23, 0xD2, 0x1B, 0xDC, 0x6D, 0x83, 0xF3, 0x6F, 0xCB,
0x24, 0x39, 0x94, 0x95, 0x79, 0xF3, 0x7C, 0xAA, 0x3C, 0xD1, 0x94, 0x38,
0x48, 0x78, 0x92, 0xAC, 0xBB, 0x82, 0x1E, 0xBC, 0x75, 0xCB, 0xE2, 0x92,
0xF2, 0x3E, 0x85, 0x79, 0x6D, 0xF0, 0xC9, 0x72, 0x12, 0xF0, 0x54, 0xAA,
0xF4, 0x80, 0x30, 0xB9, 0x32, 0x94, 0xC8, 0x2D, 0x3E, 0xC6, 0x85, 0x42,
0x99, 0x40, 0x05, 0xC9, 0x65, 0x58, 0x23, 0x75, 0x7A, 0x0B, 0xF7, 0x60,
0x74, 0x82, 0xF7, 0x74, 0x5A, 0x0C, 0x4E, 0x76, 0xFC, 0x33, 0xF1, 0x08,
0xE8, 0x47, 0x8C, 0x6A, 0xD7, 0xC6, 0x88, 0xAE, 0xF7, 0xB3, 0xEE, 0x12,
0xF2, 0x73, 0x48, 0xC6, 0xA1, 0xFA, 0x84, 0xF8, 0x38, 0x08, 0x25, 0xE5,
0xC0, 0x9B, 0x78, 0x56, 0xD2, 0x21, 0x67, 0x92, 0x00, 0x6C, 0xDE, 0xF9,
0x5F, 0x95, 0x8F, 0x3B, 0x20, 0x7D, 0xC1, 0x14, 0xD3, 0x69, 0xD9, 0x6F,
0x3E, 0xF7, 0xD6, 0xE6, 0x37, 0x38, 0xFC, 0x73, 0x83, 0x52, 0x92, 0xA3,
0xEF, 0xC8, 0xAC, 0x37, 0xA0, 0x20, 0x98, 0x88, 0xF7, 0xC7, 0x94, 0xCC,