diff --git a/.gitignore b/.gitignore index 2024720..f31bdd6 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,25 @@ *.out *.app +#Emacs +\#*# + +#pio +/.pio/ + +# Doxygen +/doc/html # resources -ponko_face.cpp -ponko_mouth_*.cpp -logo.cpp +/src/res/* +!/src/res/resource.h +!/src/res/u8g2_font_profont22_tr.* +!/src/res/wifi.cpp +!/src/res/bt.cpp +!/src/res/jpmap.cpp +!/src/res/dummy_face.cpp +!/src/res/dummy_mo.cpp +!/src/res/dummy_mc.cpp +!/src/res/dummy_logo.cpp +!/src/res/w???.cpp diff --git a/README.md b/README.md index 2b72b8e..b070edf 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,83 @@ # M5S_WxBeacon2 - https://user-images.githubusercontent.com/26270227/186464005-bfc6b1c4-3f5c-4e7f-b2bc-fb4b9d4b0df4.mp4 -定期的に WxBeacon2 から情報を取得し、ティッカーに表示、ポン子ちゃんアバターが喋ります。 +|天気予報|気象衛星ひまわり画像| +|---|---| +|forecast| himawari| + +* WxBeacon2 から情報を取得し、ティッカーに表示、ポン子ちゃんアバターがアナウンスします。 +* 気象庁の天気予報 JSON データを取得し、全国の天気を表示、ポン子ちゃんアバターがアナウンスします。 +* **(Core2 のみ)** 気象衛星ひまわりの画像を取得し表示します。 ## 概要 [株式会社ウェザーニューズ](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%82%B6%E3%83%BC%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%BA)(以下 WNI )による 24 時間お天気番組[ウェザーニュースLiVE](https://weathernews.jp/web910/) とリンクしたアプリケーション [ウェザーニュース](https://weathernews.jp/app/) では サンクスポイント 2000 pt以上取得すると[ウェザービーコン2](https://weathernews.jp/smart/wxbeacon2/)(以下 WxBeacon2 ) をゲットできます。(別途[有償購入](https://weathernews.jp/sorashop/)も可能) -WxBeacon2 +|WxBeacon2|WEATHEROID TypeA Airi ちゃん| +|---|---| +|WxBeacon2| ponko| -M5Stack Basic / Gray / Core2 を使って WxBeacon2 から情報を取得し、 [AquesTalk ESP32](https://www.a-quest.com/products/aquestalk_esp32.html) にて喋らせるアプリケーションです。
-どうせならウェザーニュースLiVE のマスコット、ポン子こと [WEATHEROID TypeA Airi](https://twitter.com/typea_airi) ちゃんに喋らせようという事で、アバターはポン子ちゃんとなっております。 -ponko +M5Stack Basic, Gray, Core2 にて WxBeacon2 や気象庁からデータを取得し、 +[AquesTalk ESP32](https://www.a-quest.com/products/aquestalk_esp32.html) で喋らせるアプリケーションです。 +どうせならウェザーニュースLiVE のマスコット、ポン子こと [WEATHEROID TypeA Airi](https://twitter.com/typea_airi) ちゃんに喋らせようという事で、アバターポン子ちゃんを作りました。 + ## 必要なもの -### M5Stack -M5Stack Basic,Gray,Core2 のいずれか。 +* M5Stack +M5Stack Basic, Gray, Core2 のいずれか。 + +* Wi-Fi接続可能な機器 +ルータやモバイル Wi-Fi 等。 -### WxBeacon2 -実体は [OMRON 2JCIE-BL01](https://components.omron.com/jp-ja/products/sensors/2JCIE-BL) です。ですので、WxBeacon2 でなく当該製品でも動作すると思われます(手元に無いので未確認)。 +* (持っていれば) WxBeacon2 +実体は [OMRON 2JCIE-BL01](https://components.omron.com/jp-ja/products/sensors/2JCIE-BL) です。 +WxBeacon2 でなく当該製品でも動作すると思われます(手元に無いので未確認)。 ## コンパイル ### 依存ライブラリ -* [M5Unified](https://github.com/m5stack/M5Unified) 0.0.7 or later -* [M5GFX](https://github.com/m5stack/M5GFX) 0.0.20 or later +* [M5Unified](https://github.com/m5stack/M5Unified) 0.1.3 or later (depends on [M5GFX](https://github.com/m5stack/M5GFX) 0.1.3 or later) * [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) 1.4.0 or later -* [AquesTalk ESP32](https://www.a-quest.com/products/aquestalk_esp32.html) 2.21 or later +* [gob_json](https://github.com/GOB52/gob_json.git) 0.0.3 or later +* [gob_datetime](https://github.com/GOB52/gob_datetime.git) 0.1.1 or later +* [AquesTalk ESP32](https://www.a-quest.com/products/aquestalk_esp32.html) 2.21 or later +AquesTalk ESP32 は [こちら](https://www.a-quest.com/download.html) よりダウンロード後、プロジェクトの lib フォルダ(無ければ作成)に展開してください。 + +### 画像リソース +初期状態ではダミーとして私が作った顔とロゴが使用されます。 +dummy -### 画像ソース -**権利上の問題でポン子ちゃんの画像などは当リポジトリには含まれません。**
-自分で以下の条件を満たす画像をソースファイルとして共にコンパイルする必要があります。 +**権利上の問題でポン子ちゃんの画像などは当リポジトリには含まれません。** +ポン子ちゃんや他の画像を使いたい場合、自分で以下の条件を満たす画像を作成し、ソースファイルとして共にコンパイルする必要があります。 +ダミーリソースは全て weak symbol として定義されているので、ダミーリソースのソースファイルは削除する必要はありません。 +自作した同名シンボルが存在すればそちらが使用されます。 -#### フォーマット +#### 画像フォーマット Basic,Gray での動作の都合上、メモリ使用料削減の為に 4bpp,1bpp を扱います。 -[Windows Bitmap](https://ja.wikipedia.org/wiki/Windows_bitmap) Version 3 (BITMAPINFOHEADER.biSize == 40) format であること。 +[Windows Bitmap](https://ja.wikipedia.org/wiki/Windows_bitmap) の場合は Version 3 (BITMAPINFOHEADER.biSize == 40) format である必要があります。 + +**顔、閉じた口、開いた口は同じパレット配列でなければなりません。** +16色 Bitmap のパレットの並び替えは、拙作 [reorder_palette.py](https://github.com/GOB52/bitmap_tools/blob/master/reorder_palette.py) が使用できます。 + 画像は作成の際の位置イメージです。 -* 顔
+* 顔 Windows bitmap 320 px x 240 px 4 bpp (16色) パレット 0 番は透過色。口とパレット構成を合わせる為、顔にも透過色が必要。 ![face](./doc/ponko_face.png) -* 閉じた口
+* 閉じた口 Windows bitmap 48 px x 32 px 4 bpp (16色) パレット 0 番は透過色。顔に透過色を用いて上書きされる。 ![close](./doc/ponko_mouth_close.png) -* 開いた口
+* 開いた口 Windows bitmap 48 px x 32 px 4 bpp (16色) パレット 0 番は透過色。顔に透過色を用いて上書きされる。 ![open](./doc/ponko_mouth_open.png) -* WNI ロゴ
+ +* WNI ロゴ Windows bitmap 32 px x 32 px 1 bpp (2色) パレット 0 番は透過色。ティッカーに透過色を用いて上書きされる。 ![logo](./doc/logo.png) -**顔、閉じた口、開いた口は同じパレット配列でなければなりません。**
-16色 Bitmap のパレットの並び替えは、拙作 [reorder_palette.py](https://github.com/GOB52/bitmap_tools/blob/master/reorder_palette.py) が使用できます。 - - #### ソースファイル化 全てのリソースについて行ってください。 ponko_face.bmp における例を示します。 @@ -66,14 +86,16 @@ xxd -i ponko_face.bmp ./src/res/ponko_face.cpp ``` xxd で C形式に変換します。出力場所は ./src/res が良いでしょう。 -出力したソースを修正します。 +出力したソースを修正します。 +ヒープを空ける為、画像リソースは **PROGMEM として Flash の領域におきます**。 ```cpp +#include // PROGMEM を使う為 #include "resource.h" // 宣言 //unsigned char ponko_face_bmp[] = { -const uint8_t ponko_face_bmp[] = { +PROGMEM const uint8_t ponko_face_bmp[] = { 0x42, 0x4d, 0x76, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, . @@ -85,67 +107,110 @@ const size_t ponko_face_bmp_len = 38518; ``` -#### 参考 : 各リソースの長さ(フォーマット他条件が一致していれば違っても良い) +詳しくは [各リソースの定義](src/res/resource.h) を参照してください。 -|xxd -i source| \_bmp\_len| -|---|---| -|ponk\_face.cpp| 38518 | -|ponko\_mouth\_close.cpp| 886 | -|ponko\_mouth\_open.cpp| 886 | -|logo.cpp| 190 | +### 動作設定 -### 動作制御 -./src/main.cpp の上部にいくつかの設定項目があります。 +* タイムゾーン設定 +コンパイル時のオプション **M5S_WXBEACON2_TIMEZONE_LOCATION** (文字列) で指定します。 +デフォルトは **"Asia/Tokyo"** です。(M5Stack 内部では POSIX 表記を用いて設定されます) -```cpp +* データ自動取得間隔の設定 +コンパイル時のオプション **M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC** (数値)で指定します。 +デフォルトは 300 (5分間隔) です。 +(Core2 ではひまわりの画像取得のインターバルとなります) -// Settings -namespace -{ -// Auto talking interval time (Unit:second) [自動で WxBeacon2 からデータを取得して喋る頻度] -constexpr uint16_t TALKING_INTERVAL_SEC = 60 * 3; -// Measurement interval time (Unit:second) for broadcast mode [WxBeacon2 のデータ更新頻度] -constexpr uint16_t MEASUREMENT_INTERVAL_BROADCAST_SEC = 60 * 3; -// turnon LED when got advertise data. [WxBeacon2 のデータを取得できたら LED を光らせるか?] -constexpr bool TURNON_LED = false; -} +* ランダムお喋り間隔の設定 +コンパイル時のオプション **M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC** (数値)で指定します。 +デフォルトは 60 (1分間隔) です。 -``` -### WiFi SSID password +### Wi-Fi SSID password -時刻取得の為、起動時に WiFi 接続で NTP サーバーへの接続を行います。
-時刻の表示並びに、 WxBeacon2 のモードを出荷時に戻す際に、蓄積データの基準時刻を書き込む必要がある為です。
-前もって接続する WiFi の SSID とパスワードをハードに書き込む必要があります。(Wifi.begin() を引数なしで呼ぶと保存されている情報を元に接続します)
-SmartConfig 等を利用して SSID とパスワード書き込むか、 WiFi.begin(ssid, password); として一旦接続させるかして、ハードに情報を保存してください。
+指定したタイムゾーンでの時刻取得の為、起動時に Wi-Fi 接続で NTP サーバーへの接続を行います。 +(時刻の表示並びに、 WxBeacon2 のモードを出荷時に戻す際に、蓄積データの基準時刻を書き込む必要がある為) +前もって接続する Wi-Fi の SSID とパスワードをハードに書き込む必要があります。(WiFi.begin() を引数なしで呼ぶと保存されている情報を元に接続します) +SmartConfig 等を利用して SSID とパスワード書き込むか、 WiFi.begin(ssid, password); として一旦接続させるかして、ハードに情報を保存してください。 @tnkmasayuki さんによる記事 [Lang-ship](https://lang-ship.com/blog/work/esp32-wi-fi-setting/) が参考になるでしょう。 +### AquesTalk ESP32 ライセンス +評価版では諸々の制限があります。ライセンスを取得した場合は、 src/aq_talk.cpp のライセンス部分を書き換えてください。 + +```cpp +bool initialize(const UBaseType_t priority, const BaseType_t core, aq_talk_callback f) +{ + if(!task_handle) + { + xTaskCreateUniversal(talk_task, "aq_talk_task", 4 * 1024, nullptr, priority, &task_handle, core); + callbackOnEnd = f; + return task_handle + && CAqTkPicoF_Init(workbuf, LEN_FRAME, "XXX-XXX-XXX") == 0; // ここにライセンスコード + } + return true; +} +``` ## 動作 -WxBeacon2 は通常(出荷時状態)、計測データを内部に蓄積しますが、このアプリケーションでは蓄積モードではなく、ブロードキャストモードを利用します。後述の操作方法(\*1)より、ブロードキャストモードに変更する必要があります。
-**なおモードを変更した場合、蓄積したデータは全て失われる点、ウェザーニュースアプリとの連携ができなくなる点には注意です。**
+WxBeacon2 は通常(出荷時状態)、計測データを内部に蓄積しますが、このアプリケーションでは蓄積モードではなく、ブロードキャストモードを利用します。後述の操作方法(\*1)より、ブロードキャストモードに変更する必要があります。 +**なおモードを変更した場合、蓄積したデータは全て失われる点、ウェザーニュースアプリとの連携ができなくなる点には注意です。** **後述の操作方法(\*2)によって出荷時に状態を戻し、再びウェザーニュースアプリとの連携を取ることができるようになります。** -モードがブロードキャストモードではない場合は、ティッカーが紫色となり、ティッカーにその旨表示されます。。
-ブロードキャストモードであれば、起動時にデータを取得、ティッカーに表示してポン子ちゃんが喋ります。その際のティッカーの色は WBGT (熱中症危険度) のレベルに応じて青、黄、赤のいずれかの色となります。以降は定期的にデータを取得して表示と喋りを行います。 +モードがブロードキャストモードではない場合は、ティッカーが紫色となり、ティッカーにその旨表示されます。。 +ブロードキャストモードであれば、起動時にデータを取得、ティッカーに表示してポン子ちゃんが喋ります。その際のティッカーの色は WBGT (熱中症危険度) のレベルに応じて青、黄、赤のいずれかの色となります。 ## 操作方法 -|ボタン| 長押し | 短押し | +|ボタン| 長押し(1.5秒以上) | クリック | |---|---|---| -|A | | 強制的にWxBeacon2のデータを取得して喋る| -|B | (\*2)WxBeacon2 を出荷時の状態へ戻す | | -|C | (\*1)WxBeacon2 をブロードキャストモードに変更する | ティッカー表示の ON/OFF | +|A | 全国の天気を取得して喋る [Wi-Fi 通信] | WxBeacon2のデータを取得して喋る[BLE 通信]| +|B | (\*2)WxBeacon2 を出荷時の状態へ戻す [BLE 通信] | | +|C | (\*1)WxBeacon2 をブロードキャストモードに変更する [BLE 通信] | ティッカー表示の ON/OFF | + +各通信は排他的に動作するので、通信動作させるボタンは通信中は動作しません。 +通信中は画面左下に Wi-Fi か BT マークが点滅表示されています。 +progress C 長押しでブロードキャストモードに上手くならなかった場合は、 B 長押しで出荷時に戻して再度試してください。 -## WxBeacon2 と M5Stack との NumBLE によるやり取り +## Zenn の記事 +- WxBeacon2 と M5Stack との NumBLE によるやり取り こちらで[記事](https://zenn.dev/gob/articles/wxbeacon2_000_bbc2e4106f701c)にしました。 +- 気象庁天気予報 JSON と ひまわり画像に関して +こちらで[記事](https://zenn.dev/gob/articles/wxbeacon2_001_961ea4d226fc24)にしました。 + ## 謝辞 +* 各ライブラリの作成者関係者の方々、助言や示唆を頂いた方々には毎度大変お世話になっております。 +* 気象庁 JSON 、気象衛星ひまわり画像取得に関しての先人の皆様方の情報を参考にしました。 +* 毎日楽しい番組を送ってくださる WNI のスタッフ、[気象予報士、キャスター](https://weathernews.jp/wnl/caster/index.html)他の皆様、作業中ラジオ的に楽しんでおります。 +* 元祖 Vtuber ポン子ちゃんを生み出した皆様、マネージャーの[山岸キャスター](https://twitter.com/airin0609)、木曜日の深夜がいつも楽しみです。 + + +## 権利、規約等 + +### 気象庁 トゥルーカラー再現画像の利用規約に基づく表記 + +#### 日本語 +>(1) トゥルーカラー再現画像の説明 +>トゥルーカラー再現画像は、ひまわり8号・9号の可視3バンド(バンド1、2、3)、近赤外1バンド(バンド4)及び赤外1バンド(バンド13)を利用し、人間の目で見たような色を再現した衛星画像です。本画像は、衛星によって観測された画像を人間の目で見たように再現する手法(参考文献[1])によって作成されています。この色の再現過程において緑色を調節するために、Millerらによる手法(参考文献[2])の応用として、バンド2、3、4が使用されています。また、画像をより鮮明にするために、大気分子により太陽光が散乱される影響を除去するための手法(レイリー散乱補正)(参考文献[2])が利用されています。 +> +>(2) 謝辞 +>トゥルーカラー再現画像は、気象庁気象衛星センターと米国海洋大気庁衛星部門GOES-Rアルゴリズムワーキンググループ画像チーム(NOAA/NESDIS/STAR GOES-R Algorithm Working Group imagery team)との協力により開発されました。また、レイリー散乱補正のためのソフトウェアは、NOAA/NESDISとコロラド州立大学との共同研究施設(Cooperative Institute for Research in the Atmosphere: CIRA)から気象庁気象衛星センターに提供されました。関係機関に感謝いたします。 +> +>(3) 参考文献 +>[1] Murata, H., K. Saitoh, Y. Sumida, 2018: True color imagery rendering for Himawari-8 with a color reproduction approach based on the CIE XYZ color system. J. Meteor. Soc. Japan., doi: 10.2151/jmsj.2018-049. +>[2] Miller, S., T. Schmit, C. Seaman, D. Lindsey, M. Gunshor, R. Kohrs, Y. Sumida, and D. Hillger, 2016: A Sight for Sore Eyes - The Return of True Color to Geostationary Satellites. Bull. Amer. Meteor. Soc. doi: 10.1175/BAMS-D-15-00154.1 + +#### English +>1) True Color Reproduction imagery +>True Color Reproduction (TCR) technology enables the display of earth images taken from space in a way that is familiar to the human eye. The imagery consists of data from three visible bands (Band 1, 2 and 3), one near-infrared band (Band 4) and one infrared band (Band 13). To reproduce colors as seen by the human eye, RGB signals observed by AHI are converted into CIE XYZ values and reconverted into RGB signals for output devices compliant with sRGB (an international standard for RGB color space) (Murata et al., 2018). In this process, as an alternative to the bi-spectral hybrid green method outlined by Miller et al. (2016), the green band is optimally adjusted using Band 2, 3 and 4. To make the imagery more vivid, atmospheric correction (Rayleigh correction, Miller et al., 2016) is also applied to AHI Bands 1-4. Software for this purpose was provided by the Cooperative Institute for Research in the Atmosphere (CIRA) established by NOAA/NESDIS and Colorado State University in United States of America. +> +>2) Acknowledgement +>The imagery was developed on the basis of collaboration between the JMA Meteorological Satellite Center and the NOAA/NESDIS/STAR GOES-R Algorithm Working Group imagery team. We would like to acknowledge them for the collaboration and their permission to use the software. +> +>3) Reference +>Murata, H., K. Saitoh, Y. Sumida, 2018: True color imagery rendering for Himawari-8 with a color reproduction approach based on the CIE XYZ color system. J. Meteor. Soc. Japan. doi: 10.2151/jmsj. 2018-049 +>Miller, S., T. Schmit, C. Seaman, D. Lindsey, M. Gunshor, R. Kohrs, Y. Sumida, and D. Hillger, 2016: A Sight for Sore Eyes - The Return of True Color to Geostationary Satellites. Bull. Amer. Meteor. Soc. doi: 10.1175/BAMS-D-15-00154.1 -* 各ライブラリの作成者関係者の方々、助言や示唆を頂いた方々には毎度大変お世話になっております。
-* 毎日楽しい番組を送ってくださる WNI のスタッフ、[気象予報士、キャスター](https://weathernews.jp/wnl/caster/index.html)他の皆様、作業中ラジオ的に楽しんでおります。
-* 元祖 Vtuber ポン子ちゃんを生み出した皆様、マネージャーの[山岸キャスター](https://twitter.com/airin0609)、木曜日の深夜がいつも楽しみです。
diff --git a/doc/Doxyfile b/doc/Doxyfile index 5e5fa88..58e68e5 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -900,8 +900,8 @@ INPUT_ENCODING = UTF-8 # comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, # *.vhdl, *.ucf, *.qsf and *.ice. -FILE_PATTERNS = wxbeacon2*.cpp \ - wxbeacon2*.hpp +FILE_PATTERNS = wxbeacon2.* \ + wxbeacon2_ble.* # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. diff --git a/doc/dummy.jpg b/doc/dummy.jpg new file mode 100644 index 0000000..632e91f Binary files /dev/null and b/doc/dummy.jpg differ diff --git a/doc/forecast.jpg b/doc/forecast.jpg new file mode 100644 index 0000000..fac98b8 Binary files /dev/null and b/doc/forecast.jpg differ diff --git a/doc/himawari.jpg b/doc/himawari.jpg new file mode 100644 index 0000000..d2d4429 Binary files /dev/null and b/doc/himawari.jpg differ diff --git a/doc/progress.jpg b/doc/progress.jpg new file mode 100644 index 0000000..43c1780 Binary files /dev/null and b/doc/progress.jpg differ diff --git a/doc/w406.png b/doc/w406.png new file mode 100644 index 0000000..24a64ff Binary files /dev/null and b/doc/w406.png differ diff --git a/platformio.ini b/platformio.ini index 6b660a7..ece1700 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,87 +1,115 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - - ;----------------------------------------------------------------------- ; M5S_WxBeacon2 ; NOTE : Please save ssid/pass credential to your M5Stack before invoke this program. ; WiFi.begin() use it. ;----------------------------------------------------------------------- [env] -platform = espressif32@3.4.0 -;platform = espressif32@4.4.0 +platform = espressif32@4.4.0 +;platform = espressif32 +framework = arduino board_build.flash_mode = qio board_build.f_flash = 80000000L board_build.f_cpu = 240000000L -framework = arduino -;The libraries are shared between ArduinoIDE and PlatformIO. -;lib_extra_dirs is the ArduinoIDE library directory. -lib_extra_dirs = ~/projects/M5Stack/libraries/ +; https://www.a-quest.com/download.html Download AquesTalk ESP32 and extract ./lib folder. lib_ldf_mode = deep -;lib_deps=m5stack/M5Unified - -monitor_port = /dev/cu.SLAB_USBtoUART +lib_deps = https://github.com/M5Stack/M5Unified.git @ ^0.1.3 + h2zero/NimBLE-Arduino @ ^1.4.0 + https://github.com/GOB52/gob_json.git @ ^0.0.3 + https://github.com/GOB52/gob_datetime.git @ ^0.1.1 + monitor_speed = 115200 -;monitor_filters = time, esp32_exception_decoder monitor_filters = esp32_exception_decoder, time - upload_speed = 921600 -upload_port = /dev/cu.SLAB_USBtoUART - -; Definition if you want. -; M5S_WXBEACON2_GMT_OFFSET_HOUR : Your time zone(Unit: 1 hour). e.g. +9 (JST) -; M5S_WXBEACON2_DAYLIGHT_OFFSET_SEC : Your daylight time (Unit : 1 second). -; M5S_WXBEACON2_WIFI_HOST_NAME : Your host name for WiFi connection. ("arduino-esp32" as default) -; -build_flags = -Wall -Wextra -Wreturn-local-addr - -D M5S_WXBEACON2_GMT_OFFSET_HOUR=+9 - -D M5S_WXBEACON2_WIFI_HOST_NAME="gob-m5sg" - -;----------------------------------------------------------------------- -[env:release_core2] -board = m5stack-core2 -build_type = release -build_flags = ${env.build_flags} - -DCORE_DEBUG_LEVEL=1 - -DLOG_LOCAL_LEVEL=4 - -DWB2_LOG_LEVEL=5 - -DMYNEWT_VAL_BLE_HS_LOG_LVL=5 -[env:release_core] -board = m5stack-core-esp32 -build_type = release -build_flags = ${env.build_flags} - -DCORE_DEBUG_LEVEL=1 + +; Definition +; M5S_WXBEACON2_TIMEZONE_LOCATION : Your time-zone location string. default as "Asia/Tokyo" (e.g. "Asia/Tokyo" "America/Los_Angeles" "Australia/Lord_Howe") +; M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC : Auto request interval (Unit: second) +; M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC : Auto talk interval (Unit; second) +build_flags = -Wall -Wextra -Wreturn-local-addr -Werror=format -Werror=return-local-addr + -D M5S_WXBEACON2_TIMEZONE_LOCATION=\"Asia/Tokyo\" + -D M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC=300 + -D M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC=60 + -D M5S_WXBEACON2_DEBUG_INFO + -D GOB_JSON_LOG_LEVEL=5 +;300,60 + +; -------------------------------- +;Choose build options +[option_release] +build_flags = -DCORE_DEBUG_LEVEL=1 -DLOG_LOCAL_LEVEL=4 -DWB2_LOG_LEVEL=5 -DMYNEWT_VAL_BLE_HS_LOG_LVL=5 - -[env:release_log] -board = m5stack-core-esp32 -build_type = release -build_flags = ${env.build_flags} - -DCORE_DEBUG_LEVEL=5 + +[option_log] +build_flags = -DCORE_DEBUG_LEVEL=5 -DLOG_LOCAL_LEVEL=5 -DWB2_LOG_LEVEL=5 -DMYNEWT_VAL_BLE_HS_LOG_LVL=0 - -[env:debug] -board = m5stack-core-esp32 -build_type = debug -build_flags = ${env.build_flags} - -DCORE_DEBUG_LEVEL=5 +[option_debug] +build_flags = -DCORE_DEBUG_LEVEL=5 -DLOG_LOCAL_LEVEL=5 -DWB2_LOG_LEVEL=5 -DMYNEWT_VAL_BLE_HS_LOG_LVL=0 +; Choose board +[core2_env] +board = m5stack-core2 + +[m5s_env] +board = m5stack-core-esp32 +board_build.partitions = min_spiffs.csv + +;----------------------------------------------------------------------- +; M5Stack Core2 +[env:core2_master] +extends = core2_env +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -D NDEBUG + +[env:core2_release] +extends = core2_env +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue + +[env:core2_log] +extends = core2_env +build_type=release +build_flags=${env.build_flags} ${option_log.build_flags} -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue + +[env:core2_debug] +extends = core2_env +build_type=debug +build_flags=${env.build_flags} ${option_debug.build_flags} -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue + +; M5Stack BASIC +[env:basic_master] +extends = m5s_env +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} -D NDEBUG + +[env:basic_release] +extends = m5s_env +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} + +[env:basic_map] +extends = m5s_env +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} -Wl,-Map,output.map + +[env:basic_log] +extends = m5s_env +build_type=release +build_flags=${env.build_flags} ${option_log.build_flags} + +[env:basic_debug] +extends = m5s_env +build_type=debug +build_flags=${env.build_flags} ${option_debug.build_flags} + diff --git a/src/aq_talk.cpp b/src/aq_talk.cpp index 76b8bb7..6abe9c8 100644 --- a/src/aq_talk.cpp +++ b/src/aq_talk.cpp @@ -8,17 +8,298 @@ #include #include #include +#include +#include +#include "utility.hpp" +#include "wb2/wxbeacon2_log.hpp" namespace { +// weatcher codeto aqtalk +PROGMEM const char wc_100[] = "hare"; +PROGMEM const char wc_101[] = "hare,tokidoki'kumori"; +PROGMEM const char wc_102[] = "hare,ichiji'ame"; +PROGMEM const char wc_103[] = "hare,tokidoki'ame"; +PROGMEM const char wc_104[] = "hare,ichiji'yuki"; +PROGMEM const char wc_105[] = "hare'tokidoki'yuki"; +PROGMEM const char wc_106[] = "hare,ichiji'ame'kayuki"; +PROGMEM const char wc_107[] = "hare,tokidoki'ame'kayuki"; +PROGMEM const char wc_108[] = "hare,ichiji'ame'karai'u"; +PROGMEM const char wc_110[] = "hare,nochitokidoki'kumori"; +PROGMEM const char wc_111[] = "hare,nochi'kumori"; +PROGMEM const char wc_112[] = "hare,nochiichiji'ame"; +PROGMEM const char wc_113[] = "hare,nochitokidoki'ame"; +PROGMEM const char wc_114[] = "hare,nochi'ame"; +PROGMEM const char wc_115[] = "hare,nochiichiji'yuki"; +PROGMEM const char wc_116[] = "hare,nochitokidoki'yuki"; +PROGMEM const char wc_117[] = "hare,nochi'yuki"; +PROGMEM const char wc_118[] = "hare,nochi/ame'kayuki"; +PROGMEM const char wc_119[] = "hare,nochi/ame'karai'u"; +PROGMEM const char wc_120[] = "hare,asayuuichiji'ame"; +PROGMEM const char wc_121[] = "hare,asanouchiichiji'ame"; +PROGMEM const char wc_122[] = "hare,yuugataichiji'ame"; +PROGMEM const char wc_123[] = "hare,yamazoi'rai'u"; +PROGMEM const char wc_124[] = "hare,yamazoi'yuki"; +PROGMEM const char wc_125[] = "hare,gogowa'rai'u"; +PROGMEM const char wc_126[] = "hare,hirugorokara'ame"; +PROGMEM const char wc_127[] = "hare,yuugatakara'ame"; +PROGMEM const char wc_128[] = "hare,yoruwa'ame"; +PROGMEM const char wc_130[] = "asanouchikiri,nochi'hare"; +PROGMEM const char wc_131[] = "hare,akegata'kiri"; +PROGMEM const char wc_132[] = "hare,asayuu'kumori"; +PROGMEM const char wc_140[] = "hare,tokidoki'amede/kaminario'tomonau"; +PROGMEM const char wc_160[] = "hare,ichiji'yuki'kaame"; +PROGMEM const char wc_170[] = "hare,tokidoki'yuki'kaame"; +PROGMEM const char wc_181[] = "hare,nochi'yuki'kaame"; + +PROGMEM const char wc_200[] = "kumori"; +PROGMEM const char wc_201[] = "kumori,tokidoki'hare"; +PROGMEM const char wc_202[] = "kumori,ichiji'ame"; +PROGMEM const char wc_203[] = "kumori,tokidoki'ame"; +PROGMEM const char wc_204[] = "kumori,ichiji'yuki"; +PROGMEM const char wc_205[] = "kumori,tokidoki'yuki"; +PROGMEM const char wc_206[] = "kumori,ichiji'ame'kayuki"; +PROGMEM const char wc_207[] = "kumori,tokidoki'ame'kayuki"; +PROGMEM const char wc_208[] = "kumori,ichiji'ame'karai'u"; +PROGMEM const char wc_209[] = "kiri"; +PROGMEM const char wc_210[] = "kumori,nochitokidoki'hare"; +PROGMEM const char wc_211[] = "kumori,nochi'hare"; +PROGMEM const char wc_212[] = "kumori,nochiichiji'ame"; +PROGMEM const char wc_213[] = "kumori,nochitokidoki'ame"; +PROGMEM const char wc_214[] = "kumori,nochi'ame"; +PROGMEM const char wc_215[] = "kumori,nochiichiji'yuki"; +PROGMEM const char wc_216[] = "kumori,nochitokidoki'yuki"; +PROGMEM const char wc_217[] = "kumori,nochi'yuki"; +PROGMEM const char wc_218[] = "kumori,nochi/ame'kayuki"; +PROGMEM const char wc_219[] = "kumori,nochi/ame'karai'u"; +PROGMEM const char wc_220[] = "kumori,asayuuichiji'ame"; +PROGMEM const char wc_221[] = "kumori,asanouchiichiji'ame"; +PROGMEM const char wc_222[] = "kumori,yuugataichiji'ame"; +PROGMEM const char wc_223[] = "kumori,niccyu-tokidoki'hare"; +PROGMEM const char wc_224[] = "kumori,hirugorokara'ame"; +PROGMEM const char wc_225[] = "kumori,yuugatakara'ame"; +PROGMEM const char wc_226[] = "kumori,yoruwa'ame"; +PROGMEM const char wc_228[] = "kumori,hirugorokara'yuki"; +PROGMEM const char wc_229[] = "kumori,yuugatakara'yuki"; +PROGMEM const char wc_230[] = "kumori,yoruwa'yuki"; +PROGMEM const char wc_231[] = "kumori,kaijyo-kaiganwa'kiri'ka'kirisame"; +PROGMEM const char wc_240[] = "kumori,tokidoki'amede/kaminariotomonau"; +PROGMEM const char wc_250[] = "kumori,tokidoki'yukide/kaminariotomonau"; +PROGMEM const char wc_260[] = "kumori,ichiji'yuki'kaame"; +PROGMEM const char wc_270[] = "kumori,tokidoki'yuki'kaame"; +PROGMEM const char wc_281[] = "kumori,nochi'yuki'kaame"; + +PROGMEM const char wc_300[] = "a'me"; +PROGMEM const char wc_301[] = "a'me,tokidoki'hare"; +PROGMEM const char wc_302[] = "a'me,tokidoki'yamu"; +PROGMEM const char wc_303[] = "a'me,tokidoki'yuki"; +PROGMEM const char wc_304[] = "a'me'kayuki"; +PROGMEM const char wc_306[] = "ooa'me"; +PROGMEM const char wc_308[] = "a'mede,bo-fu-uo'tomonau"; +PROGMEM const char wc_309[] = "a'me,ichiji'yuki"; +PROGMEM const char wc_311[] = "a'me,nochi'hare"; +PROGMEM const char wc_313[] = "a'me,nochi'kumori"; +PROGMEM const char wc_314[] = "a'me,nochitokidoki'yuki"; +PROGMEM const char wc_315[] = "a'me,nochi'yuki"; +PROGMEM const char wc_316[] = "ame/ka'yuki,nochi'hare"; +PROGMEM const char wc_317[] = "ame/ka'yuki,nochi'kumori"; +PROGMEM const char wc_320[] = "asanouchi,a'me,nochi'hare"; +PROGMEM const char wc_321[] = "asanouchi,a'me,nochi'kumori"; +PROGMEM const char wc_322[] = "a'me,asabann/ichiji'yuki"; +PROGMEM const char wc_323[] = "a'me,hirugorokara'hare"; +PROGMEM const char wc_324[] = "a'me,yuugatajarawa'hare"; +PROGMEM const char wc_325[] = "a'me,yoruwa'hare"; +PROGMEM const char wc_326[] = "a'me,yuugatakara'yuki"; +PROGMEM const char wc_327[] = "a'me,yoruwa'yuki"; +PROGMEM const char wc_328[] = "a'me,ichiji'tuyoku'furu"; +PROGMEM const char wc_329[] = "a'me,ichiji'mizore"; +PROGMEM const char wc_340[] = "yuki/ka'ame"; +PROGMEM const char wc_350[] = "a'mede,kaminario'tomonau"; +PROGMEM const char wc_361[] = "yuki/ka'ame,nochi'hare"; +PROGMEM const char wc_371[] = "yuki/ka'ame,nochi'kumori"; + +PROGMEM const char wc_400[] = "yuki"; +PROGMEM const char wc_401[] = "yuki,tokidoki'hare"; +PROGMEM const char wc_402[] = "yuki,tokidokiyamu"; +PROGMEM const char wc_403[] = "yuki,tokidoki'ame"; +PROGMEM const char wc_405[] = "ooyuki"; +PROGMEM const char wc_406[] = "fu-setsu,tsuyoi"; +PROGMEM const char wc_407[] = "bo-'fu-setsu"; +PROGMEM const char wc_409[] = "yuki,ichji'ame"; +PROGMEM const char wc_411[] = "yuki,nochi'hare"; +PROGMEM const char wc_413[] = "yuki,nochi'kumori"; +PROGMEM const char wc_414[] = "yuki,onchi'ame"; +PROGMEM const char wc_420[] = "asanouchi,yuki,nochi'hare"; +PROGMEM const char wc_421[] = "asanouchi,yuki,nochi'kumori"; +PROGMEM const char wc_422[] = "yuki,hirugorokara'ame"; +PROGMEM const char wc_423[] = "yuki,yuugatakara'ame"; +PROGMEM const char wc_425[] = "yuki,ichiji'tsuyoku'furu"; +PROGMEM const char wc_426[] = "yuki,nochi'mizore"; +PROGMEM const char wc_427[] = "yuki,ichiji'mizore"; +PROGMEM const char wc_450[] = "yukide,kaminario'tomonau"; + +const std::map weatherCodeTable = +{ + { 100, wc_100 }, + { 101, wc_101 }, + { 102, wc_102 }, + { 103, wc_103 }, + { 104, wc_104 }, + { 105, wc_105 }, + { 106, wc_106 }, + { 107, wc_107 }, + { 108, wc_108 }, + { 110, wc_110 }, + { 111, wc_111 }, + { 112, wc_112 }, + { 113, wc_113 }, + { 114, wc_114 }, + { 115, wc_115 }, + { 116, wc_116 }, + { 117, wc_117 }, + { 118, wc_118 }, + { 119, wc_119 }, + { 120, wc_120 }, + { 121, wc_121 }, + { 122, wc_122 }, + { 123, wc_123 }, + { 124, wc_124 }, + { 125, wc_125 }, + { 126, wc_126 }, + { 127, wc_127 }, + { 128, wc_128 }, + { 130, wc_130 }, + { 131, wc_131 }, + { 132, wc_132 }, + { 140, wc_140 }, + { 160, wc_160 }, + { 170, wc_170 }, + { 181, wc_181 }, + { 200, wc_200 }, + { 201, wc_201 }, + { 202, wc_202 }, + { 203, wc_203 }, + { 204, wc_204 }, + { 205, wc_205 }, + { 206, wc_206 }, + { 207, wc_207 }, + { 208, wc_208 }, + { 209, wc_209 }, + { 210, wc_210 }, + { 211, wc_211 }, + { 212, wc_212 }, + { 213, wc_213 }, + { 214, wc_214 }, + { 215, wc_215 }, + { 216, wc_216 }, + { 217, wc_217 }, + { 218, wc_218 }, + { 219, wc_219 }, + { 220, wc_220 }, + { 221, wc_221 }, + { 222, wc_222 }, + { 223, wc_223 }, + { 224, wc_224 }, + { 225, wc_225 }, + { 226, wc_226 }, + { 228, wc_228 }, + { 229, wc_229 }, + { 230, wc_230 }, + { 231, wc_231 }, + { 240, wc_240 }, + { 250, wc_250 }, + { 260, wc_260 }, + { 270, wc_270 }, + { 281, wc_281 }, + { 300, wc_300 }, + { 301, wc_301 }, + { 302, wc_302 }, + { 303, wc_303 }, + { 304, wc_304 }, + { 306, wc_306 }, + { 308, wc_308 }, + { 309, wc_309 }, + { 311, wc_311 }, + { 313, wc_313 }, + { 314, wc_314 }, + { 315, wc_315 }, + { 316, wc_316 }, + { 317, wc_317 }, + { 320, wc_320 }, + { 321, wc_321 }, + { 322, wc_322 }, + { 323, wc_323 }, + { 324, wc_324 }, + { 325, wc_325 }, + { 326, wc_326 }, + { 327, wc_327 }, + { 328, wc_328 }, + { 329, wc_329 }, + { 340, wc_340 }, + { 350, wc_350 }, + { 361, wc_361 }, + { 371, wc_371 }, + { 400, wc_400 }, + { 401, wc_401 }, + { 402, wc_402 }, + { 403, wc_403 }, + { 405, wc_405 }, + { 406, wc_406 }, + { 407, wc_407 }, + { 409, wc_409 }, + { 411, wc_411 }, + { 413, wc_413 }, + { 414, wc_414 }, + { 420, wc_420 }, + { 421, wc_421 }, + { 422, wc_422 }, + { 423, wc_423 }, + { 425, wc_425 }, + { 426, wc_426 }, + { 427, wc_427 }, + { 450, wc_450 }, +}; + +PROGMEM const char oc_16000[] = "sapporo"; +PROGMEM const char oc_40000[] = "sendai"; +PROGMEM const char oc_130000[] = "to-kyo-"; +PROGMEM const char oc_150000[] = "niigata"; +PROGMEM const char oc_170000[] = "kanazawa"; +PROGMEM const char oc_230000[] = "nagoya"; +PROGMEM const char oc_270000[] = "o-saka"; +PROGMEM const char oc_340000[] = "hirosima"; +PROGMEM const char oc_390000[] = "ko-chi"; +PROGMEM const char oc_400000[] = "fukuoka"; +PROGMEM const char oc_471000[] = "naha"; + +const std::map officeCodeTable = +{ + { 16000, oc_16000 }, + { 40000, oc_40000 }, + { 130000, oc_130000 }, + { 150000, oc_150000 }, + { 170000, oc_170000 }, + { 230000, oc_230000 }, + { 270000, oc_270000 }, + { 340000, oc_340000 }, + { 390000, oc_390000 }, + { 400000, oc_400000 }, + { 471000, oc_471000 }, +}; + constexpr uint8_t m5spk_virtual_channel = 0; constexpr std::size_t LEN_FRAME = 32; +aq_talk::aq_talk_callback callbackOnEnd; uint32_t workbuf[AQ_SIZE_WORKBUF]; TaskHandle_t task_handle = nullptr; volatile bool is_talking = false; volatile uint32_t level = 0; +std::vector koeQueue; +uint16_t koeSpeed = 100; +uint16_t koeLenPause = 256U; + void calcGainAverage(const int16_t* wav, const size_t len) { uint32_t acc = 0; @@ -36,17 +317,32 @@ void talk_task(void*) for (;;) { ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); // wait notify + while (is_talking) { uint16_t len = 0; - if (CAqTkPicoF_SyntheFrame(wav[tri_index], &len)) { is_talking = false; break; } + if (CAqTkPicoF_SyntheFrame(wav[tri_index], &len)) + { + if(koeQueue.empty()) + { + is_talking = false; + break; + } + // Connect + auto ret = CAqTkPicoF_SetKoe(reinterpret_cast(koeQueue.front().c_str()), koeSpeed, koeLenPause); + WB2_LOGD("Connect Koe %d [%s]", ret, koeQueue.front().c_str()); + koeQueue.erase(koeQueue.begin()); + continue; + } if(len) { calcGainAverage(wav[tri_index], len); M5.Speaker.playRaw(wav[tri_index], len, 8000, false, 1, m5spk_virtual_channel, false); tri_index = tri_index < 2 ? tri_index + 1 : 0; } + delay(2); } + if(callbackOnEnd) { callbackOnEnd(); } } } // @@ -54,13 +350,14 @@ void talk_task(void*) namespace aq_talk { -bool setup() +bool initialize(const UBaseType_t priority, const BaseType_t core, aq_talk_callback f) { if(!task_handle) { - xTaskCreateUniversal(talk_task, "aq_talk_task", 4096, nullptr, 1, &task_handle, APP_CPU_NUM); + xTaskCreateUniversal(talk_task, "aq_talk_task", 4 * 1024, nullptr, priority, &task_handle, core); + callbackOnEnd = f; return task_handle - && CAqTkPicoF_Init(workbuf, LEN_FRAME, "XXX-XXX-XXX") == 0; + && CAqTkPicoF_Init(workbuf, LEN_FRAME, "XXX-XXX-XXX") == 0; // } return true; } @@ -82,22 +379,53 @@ bool busy() { return is_talking; } void waitAquesTalk(void) { while (is_talking) { vTaskDelay(1); } + koeQueue.clear(); } void stopAquesTalk(void) { - if (is_talking) { is_talking = false; vTaskDelay(1); } + if (is_talking) + { + M5.Speaker.stop(m5spk_virtual_channel); + is_talking = false; vTaskDelay(1); + } } -void playAquesTalk(const char *koe, uint16_t speed, uint16_t lenPause) +bool playAquesTalk(const char *koe, const uint16_t speed, const uint16_t lenPause) { stopAquesTalk(); - auto ret = CAqTkPicoF_SetKoe(reinterpret_cast(koe), speed, lenPause); + waitAquesTalk(); + + // Split and store queue. (CAqTkPicoF_SetKoe has a length limitation) + koeQueue.clear(); + koeQueue = gob::split(koe, '#'); + koeSpeed = speed; + koeLenPause = lenPause; + WB2_LOGV("queue:%zu", koeQueue.size()); + + if(koeQueue.empty()) { return false; } + + // auto ret = CAqTkPicoF_SetKoe(reinterpret_cast(koe), speed, lenPause); + auto ret = CAqTkPicoF_SetKoe(reinterpret_cast(koeQueue.front().c_str()), speed, lenPause); + WB2_LOGD("Koe %d [%s]", ret, koeQueue.front().c_str()); + koeQueue.erase(koeQueue.begin()); if(ret == 0) { is_talking = true; xTaskNotifyGive(task_handle); } + return ret == 0; } + +const char* weatherCodeToTalk(const jma::weathercode_t wc) +{ + return weatherCodeTable.count(wc) == 1 ? weatherCodeTable.at(wc) : ""; +} + +const char* officeCodeToTalk(const jma::officecode_t oc) +{ + return officeCodeTable.count(oc) == 1 ? officeCodeTable.at(oc) : ""; +} + // } diff --git a/src/aq_talk.hpp b/src/aq_talk.hpp index 31c529c..8dffd43 100644 --- a/src/aq_talk.hpp +++ b/src/aq_talk.hpp @@ -5,12 +5,12 @@ #ifndef AQ_TALK_HPP #define AQ_TALK_HPP -#include +#include "jma/jma_definition.hpp" namespace aq_talk { - -bool setup(); +using aq_talk_callback = void(*)(); +bool initialize(const UBaseType_t priority, const BaseType_t core, aq_talk_callback f = nullptr); void finalize(); bool busy(); @@ -18,8 +18,10 @@ uint32_t getGain(); void waitAquesTalk(void); void stopAquesTalk(void); -void playAquesTalk(const char *koe, uint16_t speed = 100, uint16_t lenPause = 256U); +bool playAquesTalk(const char *koe, const uint16_t speed = 100, const uint16_t lenPause = 0xFFFFU); +const char* weatherCodeToTalk(const jma::weathercode_t wc); +const char* officeCodeToTalk(const jma::officecode_t oc); // } #endif diff --git a/src/cpu_usage.cpp b/src/cpu_usage.cpp new file mode 100644 index 0000000..6e47bbd --- /dev/null +++ b/src/cpu_usage.cpp @@ -0,0 +1,47 @@ + +#include "cpu_usage.hpp" +#include + +namespace +{ +bool initialized = false; +long idle_cnt_0, idle_cnt_1, tick_cnt_0, tick_cnt_1; + +bool IRAM_ATTR function_idle_0(){ ++idle_cnt_0; return true; } +void IRAM_ATTR function_tick_0(){ ++tick_cnt_0; } +bool IRAM_ATTR function_idle_1(){ ++idle_cnt_1; return true; } +void IRAM_ATTR function_tick_1(){ ++tick_cnt_1; } +// +} + +namespace cpu_usage +{ + +bool initialize() +{ + if(initialized) { return false; } + + auto i0= esp_register_freertos_idle_hook_for_cpu(function_idle_0, 0); + auto t0 = esp_register_freertos_tick_hook_for_cpu(function_tick_0, 0); + auto i1 = esp_register_freertos_idle_hook_for_cpu(function_idle_1, 1); + auto t1 = esp_register_freertos_tick_hook_for_cpu(function_tick_1, 1); + initialized = (i0 == ESP_OK) && (t0 == ESP_OK) && (i1 == ESP_OK) && (t1 == ESP_OK); + return initialized; +} + +void reset() +{ + idle_cnt_0 = idle_cnt_1 = tick_cnt_0 = tick_cnt_1 = 0; +} + +float cpu0() +{ + return (tick_cnt_0 ? (idle_cnt_0 * 100.0f / tick_cnt_0) : 100.0f); +} + +float cpu1() +{ + return (tick_cnt_1 ? (idle_cnt_1 * 100.0f / tick_cnt_1) : 100.0f); +} +// +} diff --git a/src/cpu_usage.hpp b/src/cpu_usage.hpp new file mode 100644 index 0000000..584362b --- /dev/null +++ b/src/cpu_usage.hpp @@ -0,0 +1,14 @@ + +#ifndef CPP_USAGE_HPP +#define CPP_USAGE_HPP + +namespace cpu_usage +{ +bool initialize(); + +void reset(); + +float cpu0(); +float cpu1(); +} +#endif diff --git a/src/gob_sprite.hpp b/src/gob_sprite.hpp deleted file mode 100644 index 0b9756f..0000000 --- a/src/gob_sprite.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - LGFX_Sprite extension - Support partial transfer (without affine transformation) - */ -#ifndef GOB_SPRITE_HPP -#define GOB_SPRITE_HPP - -#include - -namespace gob -{ - -class Sprite : public lgfx::LGFX_Sprite -{ - public: - Sprite(LovyanGFX* parent) : LGFX_Sprite(parent) {} - Sprite() : LGFX_Sprite() {} - - /*! - @brief partial transfer from LGFX_Sprite to LovyanGFX - @param dst Target - @param dx Destination x-coordinate - @param dy Destination y-coordinate - @param width Width to transfer - @param height Height to transfer - @param sx Source x-coordinate - @param sy Source y-coordinate - @param transp Transparent color or palette index - */ - template - void pushPartial(LovyanGFX* dst, - const int32_t dx, const int32_t dy, - const int32_t width, const int32_t height, - const int32_t sx, const int32_t sy, - const T& transp) - { - push_partial(dst, dx, dy, width, height, sx, sy, _write_conv.convert(transp) & _write_conv.colormask); - } - - /*! - @brief partial transfer from LGFX_Sprite to LovyanGFX without transparention - @param dst Target - @param dx Destination x-coordinate - @param dy Destination y-coordinate - @param width Width to transfer - @param height Height to transfer - @param sx Source x-coordinate - @param sy Source y-coordinate - */ - void pushPartial(LovyanGFX* dst, - const int32_t dx, const int32_t dy, - const int32_t width, const int32_t height, - const int32_t sx, const int32_t sy) - { - push_partial(dst, dx, dy, width, height, sx, sy); - } - - protected: - /* - @note Partial transfer is implemented by clipping destination and then shifting coordinate and pushing. - */ - void push_partial(LovyanGFX* dst, - const int32_t dx, const int32_t dy, - const int32_t width, const int32_t height, - const int32_t sx, const int32_t sy, - const uint32_t transp = ::lgfx::pixelcopy_t::NON_TRANSP) - { - std::int32_t cx,cy,cw,ch; - dst->getClipRect(&cx,&cy,&cw,&ch); - dst->setClipRect(dx, dy, width, height); - - ::lgfx::pixelcopy_t p(_img, dst->getColorDepth(), getColorDepth(), dst->hasPalette(), _palette, transp); - dst->pushImage(dx - sx, dy - sy, this->width(), this->height(), &p, _panel_sprite.getSpriteBuffer()->use_dma()); - - dst->setClipRect(cx, cy, cw, ch); - } -}; -// -} -#endif diff --git a/src/himawari/himawari.cpp b/src/himawari/himawari.cpp new file mode 100644 index 0000000..d17e5f8 --- /dev/null +++ b/src/himawari/himawari.cpp @@ -0,0 +1,57 @@ + + +#include "himawari.hpp" +#include "utility.hpp" + +namespace +{ +PROGMEM const char band_B13[] = "B13 (Infrared)"; +PROGMEM const char band_B03[] = "B03 (Visible)"; +PROGMEM const char band_B08[] = "B08 (Water Vapor)"; +PROGMEM const char band_B07[] = "B07 (Short Wave Infrared)"; +PROGMEM const char band_DayMicrophysicsRGB[] = "Day Microphysics RGG"; +PROGMEM const char band_NightMicrophysicsRGB[] = "Night Microphysics RGB"; +PROGMEM const char band_DustRGB[] = "Dust RGB"; +PROGMEM const char band_AirmassRGB[] = "Airimass RGB"; +PROGMEM const char band_DaySnowFogRGB[] = "Day Snow-Fog RGB"; +PROGMEM const char band_NaturalColorRGB[] = "Natural Color RGB"; +PROGMEM const char band_TrueColorRGB[] = "True Color RGB (Enhanced)"; +PROGMEM const char band_TrueColorReproductionImage[] = "True Color Reproduction Image"; +PROGMEM const char band_DayConvectiveStormRGB[] = "Day Convective Storm RGB"; +PROGMEM const char band_Sandwich[] = "Sandwich"; +PROGMEM const char band_B03CombinedWithB13[] = "B03 combined with B13"; +PROGMEM const char band_B03AndB13AtNight[] = "B03 and B13 at night"; +PROGMEM const char band_HeavyRainfallPotentialAreas[] = "Heavy rainfall potential areas"; + +PROGMEM const char* bandTable[] = +{ + band_B13, + band_B03, + band_B08, + band_B07, + band_DayMicrophysicsRGB, + band_NightMicrophysicsRGB, + band_DustRGB, + band_AirmassRGB, + band_DaySnowFogRGB, + band_NaturalColorRGB, + band_TrueColorRGB, + band_TrueColorReproductionImage, + band_DayConvectiveStormRGB, + band_Sandwich, + band_B03CombinedWithB13, + band_B03AndB13AtNight, + band_HeavyRainfallPotentialAreas, +}; +// +} + +namespace himawari +{ + +String bandToString(const Band band) +{ + return bandTable[gob::to_underlying(band)]; +} +// +} diff --git a/src/himawari/himawari.hpp b/src/himawari/himawari.hpp new file mode 100644 index 0000000..19dad07 --- /dev/null +++ b/src/himawari/himawari.hpp @@ -0,0 +1,45 @@ + +#ifndef HIMAWARI_HPP +#define HIMAWARI_HPP + +#include + +namespace himawari +{ +// Band type +enum class Band : uint8_t +{ + B13, // Infrared + B03, // Visible + B08, // Water Vapor + B07, // Short Wave Infrared + DayMicrophysicsRGB, + NightMicrophysicsRGB, + DustRGB, + AirmassRGB, + DaySnowFogRGB, + NaturalColorRGB, + TrueColorRGB, // Enhanced + TrueColorReproductionImage, + DayConvectiveStormRGB, + Sandwich, + B03CombinedWithB13, + B03AndB13AtNight, + HeavyRainfallPotentialAreas, + Max +}; +// Area +enum class Area : uint8_t +{ + FullDisk, + Japan, + Australia, + NewZealand, + Max +}; + +String bandToString(const Band band); + +// +} +#endif diff --git a/src/himawari/himawari_screen.cpp b/src/himawari/himawari_screen.cpp new file mode 100644 index 0000000..13c90f5 --- /dev/null +++ b/src/himawari/himawari_screen.cpp @@ -0,0 +1,33 @@ +/* + Render himawari image + */ +#ifdef ARDUINO_M5STACK_Core2 + +#include "himawari_screen.hpp" +#include "wb2/wxbeacon2_log.hpp" +#include "res/resource.h" + +void HimawariScreen::render(m5gfx::M5GFX* dst, const bool force) +{ + if(!isShow() || !force) { return; } + if(_jpg) + { + auto ret = dst->drawJpg(_jpg, -1, 0, 0, 0, 0, 64, 24, 0.5f, 0.5f); + WB2_LOGD("drawJpg %d", ret); + } + + // Day of forecast + String s = _odt.toLocalDateTime().toString("%m/%d %H:%M"); + auto ofont = dst->getFont(); + dst->setFont(&tickerFont); + dst->setTextColor(TFT_BLACK); + dst->setCursor(9,9); + dst->printf("%s", s.c_str()); + dst->setCursor(8,8); + dst->setTextColor(TFT_WHITE); + dst->printf("%s", s.c_str()); + dst->setFont(ofont); + dst->setTextColor(TFT_WHITE, TFT_BLACK); +} + +#endif diff --git a/src/himawari/himawari_screen.hpp b/src/himawari/himawari_screen.hpp new file mode 100644 index 0000000..f28f351 --- /dev/null +++ b/src/himawari/himawari_screen.hpp @@ -0,0 +1,36 @@ +/* + Render himawari image + */ +#ifdef ARDUINO_M5STACK_Core2 +# ifndef HIMAWARI_SCREEN_HPP +# define HIMAWARI_SCREEN_HPP + +#include +#include + +class HimawariScreen +{ + public: + HimawariScreen() = default; + + inline bool isShow() const { return _show; } + inline void show() { show(true); } + inline void hide() { show(false); } + + void set(const goblib::datetime::OffsetDateTime& odt, const uint8_t* jpg) + { + _odt = odt; _jpg = jpg; + } + void render(m5gfx::M5GFX* dst, const bool force); + + private: + inline void show(bool b) { _show = b; } + + private: + bool _show{}; + goblib::datetime::OffsetDateTime _odt{}; + const uint8_t* _jpg{}; +}; + +# endif +#endif diff --git a/src/himawari/himawari_task.cpp b/src/himawari/himawari_task.cpp new file mode 100644 index 0000000..a437f53 --- /dev/null +++ b/src/himawari/himawari_task.cpp @@ -0,0 +1,297 @@ +/* + Request image of Weather Satellite "Himawari" + M5Stack Core2 only +*/ +#ifdef ARDUINO_M5STACK_Core2 + +#include +#include +#include +#include +#include "himawari_task.hpp" +#include "utility.hpp" +#include "wb2/wxbeacon2_log.hpp" + +using goblib::datetime::ZoneOffset; +using goblib::datetime::LocalDateTime; +using goblib::datetime::OffsetDateTime; + +namespace +{ +TaskHandle_t himawariTask; +volatile bool progressHimawari = false; +volatile himawari::Band requestBand; +volatile himawari::Area requestArea; +volatile int8_t requestHour; +volatile int8_t requestMinute; +OffsetDateTime requestOdt; +himawari::image_callback callbackOnImage; +himawari::progress_callback callbackOnProgress; +uint8_t* jpg; +constexpr size_t blockSize = 1024 * 4; +constexpr time_t ADJUST_GET_TIME = 30 * 60; + +PROGMEM const char band_B13[] = "b13"; +PROGMEM const char band_B03[] = "b03"; +PROGMEM const char band_B08[] = "b08"; +PROGMEM const char band_B07[] = "b07"; +PROGMEM const char band_DayMicrophysicsRGB[] = "dms"; +PROGMEM const char band_NightMicrophysicsRGB[] = "ngt"; +PROGMEM const char band_DustRGB[] = "dst"; +PROGMEM const char band_AirmassRGB[] = "arm"; +PROGMEM const char band_DaySnowFogRGB[] = "dsl"; +PROGMEM const char band_NaturalColorRGB[] = "dnc"; +PROGMEM const char band_TrueColorRGB[] = "tre"; +PROGMEM const char band_TrueColorReproductionImage[] = "trm"; +PROGMEM const char band_DayConvectiveStormRGB[] = "cve"; +PROGMEM const char band_Sandwich[] = "snd"; +PROGMEM const char band_B03CombinedWithB13[] = "vir"; +PROGMEM const char band_B03AndB13AtNight[] = "irv"; +PROGMEM const char band_HeavyRainfallPotentialAreas[] = "hrp"; + +PROGMEM const char* bandTable[] = +{ + band_B13, + band_B03, + band_B08, + band_B07, + band_DayMicrophysicsRGB, + band_NightMicrophysicsRGB, + band_DustRGB, + band_AirmassRGB, + band_DaySnowFogRGB, + band_NaturalColorRGB, + band_TrueColorRGB, + band_TrueColorReproductionImage, + band_DayConvectiveStormRGB, + band_Sandwich, + band_B03CombinedWithB13, + band_B03AndB13AtNight, + band_HeavyRainfallPotentialAreas, +}; + +PROGMEM const char area_FullDisk[] = "fd_"; +PROGMEM const char area_Japan[] = "jpn"; +PROGMEM const char area_Australia[] = "aus"; +PROGMEM const char area_NewZealand[] = "nzl"; + +PROGMEM const char* areaTable[] = +{ + area_FullDisk, + area_Japan, + area_Australia, + area_NewZealand +}; + +PROGMEM const char HIMAWARI_URI_FORMAT[] = "https://www.data.jma.go.jp/mscweb/data/himawari/img/%s/%s_%s_%02d%02d.jpg"; +// DigiCert Global Root CA of www.data.jma.go.jp. +// Expire at Mon, 10 Nov 2031 00:00:00 GMT +PROGMEM const char root_ca_ECC[] = + R"***(-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +)***"; + +void failed() +{ + if(callbackOnImage) { callbackOnImage(nullptr, requestBand, requestOdt); } + progressHimawari = false; +} + +void himawari_task(void*) +{ + for(;;) + { + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + + // Connect WiFi + int8_t ctry = 3; + do + { + WiFi.mode(WIFI_STA); + WiFi.begin(); + int tcount = 20; + while(tcount-- > 0 && WiFi.status() != WL_CONNECTED) + { + delay(500); + } + if(WiFi.status() == WL_CONNECTED) { break; } + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); + WB2_LOGD("Retry begin"); + delay(10); + }while(ctry--); + + if(WiFi.status() != WL_CONNECTED) + { + WB2_LOGE("Failed to connect WiFi"); + failed(); + continue; + } + + // Get image + size_t jpgsz{}, off{}; + HTTPClient http; + WiFiClientSecure client; + client.setCACert(root_ca_ECC); + do + { + char url[128]; + snprintf(url ,sizeof(url), HIMAWARI_URI_FORMAT, + areaTable[gob::to_underlying(requestArea)], + areaTable[gob::to_underlying(requestArea)], + bandTable[gob::to_underlying(requestBand)], + requestHour, requestMinute); + url[sizeof(url)-1] = '\0'; + WB2_LOGI("Connect to [%s]", url); + + int8_t gtry = 3; + int httpcode = 0; + do + { + if(!http.begin(client, url)) + { + WB2_LOGE("Failed to begin"); + continue; + } + httpcode = http.GET(); + if(httpcode >= 0) { break; } + // HTTPClient internal error, to retry. + WB2_LOGE("%s", http.errorToString(httpcode).c_str()); + client.stop(); + http.end(); + delay(100); + }while(gtry--); + + if(httpcode != HTTP_CODE_OK) + { + WB2_LOGE("Failed to GET %d", httpcode); + failed(); + break; + } + + size_t szTmp = jpgsz = http.getSize(); + WB2_LOGD("jpgsz:%zu ava:%zu", jpgsz, client.available()); + + jpg = static_cast(malloc(jpgsz)); + if(!jpg) + { + WB2_LOGE("Failed to allocate"); + failed(); + break; + } + + gtry = 16; + do + { + while(http.connected() && client.available()) + { + size_t read = std::min(blockSize, szTmp); + while(read) + { + auto len = client.readBytes(jpg + off, read); + read -= len; + off += len; + WB2_LOGD("len:%zu off:%zu ava:%zu", len, off, client.available()); + delay(100); // Insert appropriate delay to continue reading the stream. + } + szTmp -= std::min(blockSize, szTmp); + if(callbackOnProgress) { callbackOnProgress(off, jpgsz); } + delay(100); + } + WB2_LOGD("http:%d", http.connected()); + if(off < jpgsz) { WB2_LOGD("Not enough read"); delay(500); } + }while(off < jpgsz && gtry--); + + WB2_LOGD("off:%zu/%zu", off, jpgsz); + }while(0); + + client.stop(); + http.end(); + + WB2_LOGD("WiFi disconnect"); + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); + + if(callbackOnImage) { callbackOnImage((off == jpgsz) ? jpg : nullptr, requestBand, requestOdt); } + + progressHimawari = false; + } +} + +bool request(const LocalDateTime& ldt, const himawari::Area area, const himawari::Band band) +{ + if(himawari::busy()) { return false; } + + if(jpg) {free(jpg); jpg = nullptr; } + + // Himawari images are generated every 10 minutes. + // Latest is more than 20~30 minutes ago. + auto ldt2 = LocalDateTime::ofEpochSecond((ldt.toEpochSecond(ZoneOffset::UTC) - ADJUST_GET_TIME) / 600 * 600, ZoneOffset::UTC); + WB2_LOGI("%s", ldt2.toString().c_str()); + + requestBand = band; + requestArea = area; + requestHour = ldt2.hour(); + requestMinute = ldt2.minute(); + progressHimawari = true; + xTaskNotifyGive(himawariTask); + return true; +} +// +} + +namespace himawari +{ + +bool initialize(const UBaseType_t priority, const BaseType_t core, image_callback ic, progress_callback pc) +{ + if(!himawariTask) + { + xTaskCreateUniversal(himawari_task, "himawari_task", 8 * 1024, nullptr, priority, &himawariTask, core); + callbackOnImage = ic; + callbackOnProgress = pc; + } + return himawariTask != nullptr; +} + +bool busy() +{ + return progressHimawari; +} + + +bool request(const goblib::datetime::OffsetDateTime& odt, const Area area, const Band band) +{ + // Convert to local date-time in UTC. + auto ldt = odt.withOffsetSameEpoch(ZoneOffset::UTC).toLocalDateTime(); + auto ldt2 = LocalDateTime::ofEpochSecond((ldt.toEpochSecond(ZoneOffset::UTC) - ADJUST_GET_TIME) / 600 * 600, ZoneOffset::UTC); + + requestOdt = OffsetDateTime::of(ldt2, ZoneOffset::UTC).withOffsetSameEpoch(odt.offset()); + + WB2_LOGI("%s => %s", odt.toString().c_str(), ldt.toString().c_str()); + WB2_LOGI("odt:%s", requestOdt.toString().c_str()); + return ::request(ldt, area, band); +} +// +} +#endif diff --git a/src/himawari/himawari_task.hpp b/src/himawari/himawari_task.hpp new file mode 100644 index 0000000..bdd6705 --- /dev/null +++ b/src/himawari/himawari_task.hpp @@ -0,0 +1,25 @@ +/* + Request image of Weather Satellite "Himawari" + M5Stack Core2 only +*/ +#ifdef ARDUINO_M5STACK_Core2 +# ifndef HIMAWARI_TASK_HPP +# define HIMAWARI_TASK_HPP + +#include "himawari.hpp" +#include + +namespace himawari +{ +using image_callback = void(*)(const uint8_t* p, const Band band, const goblib::datetime::OffsetDateTime& odt); +using progress_callback = void(*)(const size_t readed, const size_t size); + +bool initialize(const UBaseType_t priority, const BaseType_t core, image_callback ic, progress_callback pc); +bool busy(); + +bool request(const goblib::datetime::OffsetDateTime& odt, const Area = Area::Japan, const Band = Band::B13); // odt with ZoneOffset + +// +} +# endif +#endif diff --git a/src/jma/jma_definition.cpp b/src/jma/jma_definition.cpp new file mode 100644 index 0000000..91f984e --- /dev/null +++ b/src/jma/jma_definition.cpp @@ -0,0 +1,773 @@ + +#include "jma_definition.hpp" +#include +#include +#include + +namespace +{ + +// Weatcher code string +#if 1 + +PROGMEM const char wc_100[] = "晴"; +PROGMEM const char wc_101[] = "晴時々曇"; +PROGMEM const char wc_102[] = "晴一時雨"; +PROGMEM const char wc_103[] = "晴時々雨"; +PROGMEM const char wc_104[] = "晴一時雪"; +PROGMEM const char wc_105[] = "晴時々雪"; +PROGMEM const char wc_106[] = "晴一時雨か雪"; +PROGMEM const char wc_107[] = "晴時々雨か雪"; +PROGMEM const char wc_108[] = "晴一時雨か雷雨"; +PROGMEM const char wc_110[] = "晴後時々曇"; +PROGMEM const char wc_111[] = "晴後曇"; +PROGMEM const char wc_112[] = "晴後一時雨"; +PROGMEM const char wc_113[] = "晴後時々雨"; +PROGMEM const char wc_114[] = "晴後雨"; +PROGMEM const char wc_115[] = "晴後一時雪"; +PROGMEM const char wc_116[] = "晴後時々雪"; +PROGMEM const char wc_117[] = "晴後雪"; +PROGMEM const char wc_118[] = "晴後雨か雪"; +PROGMEM const char wc_119[] = "晴後雨か雷雨"; +PROGMEM const char wc_120[] = "晴朝夕一時雨"; +PROGMEM const char wc_121[] = "晴朝の内一時雨"; +PROGMEM const char wc_122[] = "晴夕方一時雨"; +PROGMEM const char wc_123[] = "晴山沿い雷雨"; +PROGMEM const char wc_124[] = "晴山沿い雪"; +PROGMEM const char wc_125[] = "晴午後は雷雨"; +PROGMEM const char wc_126[] = "晴昼頃から雨"; +PROGMEM const char wc_127[] = "晴夕方から雨"; +PROGMEM const char wc_128[] = "晴夜は雨"; +PROGMEM const char wc_130[] = "朝の内霧後晴"; +PROGMEM const char wc_131[] = "晴明け方霧"; +PROGMEM const char wc_132[] = "晴朝夕曇"; +PROGMEM const char wc_140[] = "晴時々雨で雷を伴う"; +PROGMEM const char wc_160[] = "晴一時雪か雨"; +PROGMEM const char wc_170[] = "晴時々雪か雨"; +PROGMEM const char wc_181[] = "晴後雪か雨"; +PROGMEM const char wc_200[] = "曇"; +PROGMEM const char wc_201[] = "曇時々晴"; +PROGMEM const char wc_202[] = "曇一時雨"; +PROGMEM const char wc_203[] = "曇時々雨"; +PROGMEM const char wc_204[] = "曇一時雪"; +PROGMEM const char wc_205[] = "曇時々雪"; +PROGMEM const char wc_206[] = "曇一時雨か雪"; +PROGMEM const char wc_207[] = "曇時々雨か雪"; +PROGMEM const char wc_208[] = "曇一時雨か雷雨"; +PROGMEM const char wc_209[] = "霧"; +PROGMEM const char wc_210[] = "曇後時々晴"; +PROGMEM const char wc_211[] = "曇後晴"; +PROGMEM const char wc_212[] = "曇後一時雨"; +PROGMEM const char wc_213[] = "曇後時々雨"; +PROGMEM const char wc_214[] = "曇後雨"; +PROGMEM const char wc_215[] = "曇後一時雪"; +PROGMEM const char wc_216[] = "曇後時々雪"; +PROGMEM const char wc_217[] = "曇後雪"; +PROGMEM const char wc_218[] = "曇後雨か雪"; +PROGMEM const char wc_219[] = "曇後雨か雷雨"; +PROGMEM const char wc_220[] = "曇朝夕一時雨"; +PROGMEM const char wc_221[] = "曇朝の内一時雨"; +PROGMEM const char wc_222[] = "曇夕方一時雨"; +PROGMEM const char wc_223[] = "曇日中時々晴"; +PROGMEM const char wc_224[] = "曇昼頃から雨"; +PROGMEM const char wc_225[] = "曇夕方から雨"; +PROGMEM const char wc_226[] = "曇夜は雨"; +PROGMEM const char wc_228[] = "曇昼頃から雪"; +PROGMEM const char wc_229[] = "曇夕方から雪"; +PROGMEM const char wc_230[] = "曇夜は雪"; +PROGMEM const char wc_231[] = "曇海上海岸は霧か霧雨"; +PROGMEM const char wc_240[] = "曇時々雨で雷を伴う"; +PROGMEM const char wc_250[] = "曇時々雪で雷を伴う"; +PROGMEM const char wc_260[] = "曇一時雪か雨"; +PROGMEM const char wc_270[] = "曇時々雪か雨"; +PROGMEM const char wc_281[] = "曇後雪か雨"; +PROGMEM const char wc_300[] = "雨"; +PROGMEM const char wc_301[] = "雨時々晴"; +PROGMEM const char wc_302[] = "雨時々止む"; +PROGMEM const char wc_303[] = "雨時々雪"; +PROGMEM const char wc_304[] = "雨か雪"; +PROGMEM const char wc_306[] = "大雨"; +PROGMEM const char wc_308[] = "雨で暴風を伴う"; +PROGMEM const char wc_309[] = "雨一時雪"; +PROGMEM const char wc_311[] = "雨後晴"; +PROGMEM const char wc_313[] = "雨後曇"; +PROGMEM const char wc_314[] = "雨後時々雪"; +PROGMEM const char wc_315[] = "雨後雪"; +PROGMEM const char wc_316[] = "雨か雪後晴"; +PROGMEM const char wc_317[] = "雨か雪後曇"; +PROGMEM const char wc_320[] = "朝の内雨後晴"; +PROGMEM const char wc_321[] = "朝の内雨後曇"; +PROGMEM const char wc_322[] = "雨朝晩一時雪"; +PROGMEM const char wc_323[] = "雨昼頃から晴"; +PROGMEM const char wc_324[] = "雨夕方から晴"; +PROGMEM const char wc_325[] = "雨夜は晴"; +PROGMEM const char wc_326[] = "雨夕方から雪"; +PROGMEM const char wc_327[] = "雨夜は雪"; +PROGMEM const char wc_328[] = "雨一時強く降る"; +PROGMEM const char wc_329[] = "雨一時みぞれ"; +PROGMEM const char wc_340[] = "雪か雨"; +PROGMEM const char wc_350[] = "雨で雷を伴う"; +PROGMEM const char wc_361[] = "雪か雨後晴"; +PROGMEM const char wc_371[] = "雪か雨後曇"; +PROGMEM const char wc_400[] = "雪"; +PROGMEM const char wc_401[] = "雪時々晴"; +PROGMEM const char wc_402[] = "雪時々止む"; +PROGMEM const char wc_403[] = "雪時々雨"; +PROGMEM const char wc_405[] = "大雪"; +PROGMEM const char wc_406[] = "風雪強い"; +PROGMEM const char wc_407[] = "暴風雪"; +PROGMEM const char wc_409[] = "雪一時雨"; +PROGMEM const char wc_411[] = "雪後晴"; +PROGMEM const char wc_413[] = "雪後曇"; +PROGMEM const char wc_414[] = "雪後雨"; +PROGMEM const char wc_420[] = "朝の内雪後晴"; +PROGMEM const char wc_421[] = "朝の内雪後曇"; +PROGMEM const char wc_422[] = "雪昼頃から雨"; +PROGMEM const char wc_423[] = "雪夕方から雨"; +PROGMEM const char wc_425[] = "雪一時強く降る"; +PROGMEM const char wc_426[] = "雪後みぞれ"; +PROGMEM const char wc_427[] = "雪一時みぞれ"; +PROGMEM const char wc_450[] = "雪で雷を伴う"; + +#else + +PROGMEM const char wc_100[] = "CLEAR"; +PROGMEM const char wc_101[] = "PARTLY CLOUDY"; +PROGMEM const char wc_102[] = "CLEAR, OCCASIONAL SCATTERED SHOWERS"; +PROGMEM const char wc_103[] = "CLEAR, FREQUENT SCATTERED SHOWERS"; +PROGMEM const char wc_104[] = "CLEAR, SNOW FLURRIES"; +PROGMEM const char wc_105[] = "CLEAR, FREQUENT SNOW FLURRIES"; +PROGMEM const char wc_106[] = "CLEAR, OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES"; +PROGMEM const char wc_107[] = "CLEAR, FREQUENT SCATTERED SHOWERS OR SNOW FLURRIES"; +PROGMEM const char wc_108[] = "CLEAR, OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER"; +PROGMEM const char wc_110[] = "CLEAR, PARTLY CLOUDY LATER"; +PROGMEM const char wc_111[] = "CLEAR, CLOUDY LATER"; +PROGMEM const char wc_112[] = "CLEAR, OCCASIONAL SCATTERED SHOWERS LATER"; +PROGMEM const char wc_113[] = "CLEAR, FREQUENT SCATTERED SHOWERS LATER"; +PROGMEM const char wc_114[] = "CLEAR,RAIN LATER"; +PROGMEM const char wc_115[] = "CLEAR, OCCASIONAL SNOW FLURRIES LATER"; +PROGMEM const char wc_116[] = "CLEAR, FREQUENT SNOW FLURRIES LATER"; +PROGMEM const char wc_117[] = "CLEAR,SNOW LATER"; +PROGMEM const char wc_118[] = "CLEAR, RAIN OR SNOW LATER"; +PROGMEM const char wc_119[] = "CLEAR, RAIN AND/OR THUNDER LATER"; +PROGMEM const char wc_120[] = "OCCASIONAL SCATTERED SHOWERS IN THE MORNING AND EVENING, CLEAR DURING THE DAY"; +PROGMEM const char wc_121[] = "OCCASIONAL SCATTERED SHOWERS IN THE MORNING, CLEAR DURING THE DAY"; +PROGMEM const char wc_122[] = "CLEAR, OCCASIONAL SCATTERED SHOWERS IN THE EVENING"; +PROGMEM const char wc_123[] = "CLEAR IN THE PLAINS, RAIN AND THUNDER NEAR MOUTAINOUS AREAS"; +PROGMEM const char wc_124[] = "CLEAR IN THE PLAINS, SNOW NEAR MOUTAINOUS AREAS"; +PROGMEM const char wc_125[] = "CLEAR, RAIN AND THUNDER IN THE AFTERNOON"; +PROGMEM const char wc_126[] = "CLEAR, RAIN IN THE AFTERNOON"; +PROGMEM const char wc_127[] = "CLEAR, RAIN IN THE EVENING"; +PROGMEM const char wc_128[] = "CLEAR, RAIN IN THE NIGHT"; +PROGMEM const char wc_130[] = "FOG IN THE MORNING, CLEAR LATER"; +PROGMEM const char wc_131[] = "FOG AROUND DAWN, CLEAR LATER"; +PROGMEM const char wc_132[] = "CLOUDY IN THE MORNING AND EVENING, CLEAR DURING THE DAY"; +PROGMEM const char wc_140[] = "CLEAR, FREQUENT SCATTERED SHOWERS AND THUNDER"; +PROGMEM const char wc_160[] = "CLEAR, SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS"; +PROGMEM const char wc_170[] = "CLEAR, FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS"; +PROGMEM const char wc_181[] = "CLEAR, SNOW OR RAIN LATER"; +PROGMEM const char wc_200[] = "CLOUDY"; +PROGMEM const char wc_201[] = "MOSTLY CLOUDY"; +PROGMEM const char wc_202[] = "CLOUDY, OCCASIONAL SCATTERED SHOWERS"; +PROGMEM const char wc_203[] = "CLOUDY, FREQUENT SCATTERED SHOWERS"; +PROGMEM const char wc_204[] = "CLOUDY, OCCASIONAL SNOW FLURRIES"; +PROGMEM const char wc_205[] = "CLOUDY FREQUENT SNOW FLURRIES"; +PROGMEM const char wc_206[] = "CLOUDY, OCCASIONAL SCATTERED SHOWERS OR SNOW FLURRIES"; +PROGMEM const char wc_207[] = "CLOUDY, FREQUENT SCCATERED SHOWERS OR SNOW FLURRIES"; +PROGMEM const char wc_208[] = "CLOUDY, OCCASIONAL SCATTERED SHOWERS AND/OR THUNDER"; +PROGMEM const char wc_209[] = "FOG"; +PROGMEM const char wc_210[] = "CLOUDY, PARTLY CLOUDY LATER"; +PROGMEM const char wc_211[] = "CLOUDY, CLEAR LATER"; +PROGMEM const char wc_212[] = "CLOUDY, OCCASIONAL SCATTERED SHOWERS LATER"; +PROGMEM const char wc_213[] = "CLOUDY, FREQUENT SCATTERED SHOWERS LATER"; +PROGMEM const char wc_214[] = "CLOUDY, RAIN LATER"; +PROGMEM const char wc_215[] = "CLOUDY, SNOW FLURRIES LATER"; +PROGMEM const char wc_216[] = "CLOUDY, FREQUENT SNOW FLURRIES LATER"; +PROGMEM const char wc_217[] = "CLOUDY, SNOW LATER"; +PROGMEM const char wc_218[] = "CLOUDY, RAIN OR SNOW LATER"; +PROGMEM const char wc_219[] = "CLOUDY, RAIN AND/OR THUNDER LATER"; +PROGMEM const char wc_220[] = "OCCASIONAL SCCATERED SHOWERS IN THE MORNING AND EVENING, CLOUDY DURING THE DAY"; +PROGMEM const char wc_221[] = "CLOUDY OCCASIONAL SCCATERED SHOWERS IN THE MORNING"; +PROGMEM const char wc_222[] = "CLOUDY, OCCASIONAL SCCATERED SHOWERS IN THE EVENING"; +PROGMEM const char wc_223[] = "CLOUDY IN THE MORNING AND EVENING, PARTLY CLOUDY DURING THE DAY,"; +PROGMEM const char wc_224[] = "CLOUDY, RAIN IN THE AFTERNOON"; +PROGMEM const char wc_225[] = "CLOUDY, RAIN IN THE EVENING"; +PROGMEM const char wc_226[] = "CLOUDY, RAIN IN THE NIGHT"; +PROGMEM const char wc_228[] = "CLOUDY, SNOW IN THE AFTERNOON"; +PROGMEM const char wc_229[] = "CLOUDY, SNOW IN THE EVENING"; +PROGMEM const char wc_230[] = "CLOUDY, SNOW IN THE NIGHT"; +PROGMEM const char wc_231[] = "CLOUDY, FOG OR DRIZZLING ON THE SEA AND NEAR SEASHORE"; +PROGMEM const char wc_240[] = "CLOUDY, FREQUENT SCCATERED SHOWERS AND THUNDER"; +PROGMEM const char wc_250[] = "CLOUDY, FREQUENT SNOW AND THUNDER"; +PROGMEM const char wc_260[] = "CLOUDY, SNOW FLURRIES OR OCCASIONAL SCATTERED SHOWERS"; +PROGMEM const char wc_270[] = "CLOUDY, FREQUENT SNOW FLURRIES OR SCATTERED SHOWERS"; +PROGMEM const char wc_281[] = "CLOUDY, SNOW OR RAIN LATER"; +PROGMEM const char wc_300[] = "RAIN"; +PROGMEM const char wc_301[] = "RAIN, PARTLY CLOUDY"; +PROGMEM const char wc_302[] = "SHOWERS THROUGHOUT THE DAY"; +PROGMEM const char wc_303[] = "RAIN,FREQUENT SNOW FLURRIES"; +PROGMEM const char wc_304[] = "RAINORSNOW"; +PROGMEM const char wc_306[] = "HEAVYRAIN"; +PROGMEM const char wc_308[] = "RAINSTORM"; +PROGMEM const char wc_309[] = "RAIN,OCCASIONAL SNOW"; +PROGMEM const char wc_311[] = "RAIN,CLEAR LATER"; +PROGMEM const char wc_313[] = "RAIN,CLOUDY LATER"; +PROGMEM const char wc_314[] = "RAIN, FREQUENT SNOW FLURRIES LATER"; +PROGMEM const char wc_315[] = "RAIN,SNOW LATER"; +PROGMEM const char wc_316[] = "RAIN OR SNOW, CLEAR LATER"; +PROGMEM const char wc_317[] = "RAIN OR SNOW, CLOUDY LATER"; +PROGMEM const char wc_320[] = "RAIN IN THE MORNING, CLEAR LATER"; +PROGMEM const char wc_321[] = "RAIN IN THE MORNING, CLOUDY LATER"; +PROGMEM const char wc_322[] = "OCCASIONAL SNOW IN THE MORNING AND EVENING, RAIN DURING THE DAY"; +PROGMEM const char wc_323[] = "RAIN, CLEAR IN THE AFTERNOON"; +PROGMEM const char wc_324[] = "RAIN, CLEAR IN THE EVENING"; +PROGMEM const char wc_325[] = "RAIN, CLEAR IN THE NIGHT"; +PROGMEM const char wc_326[] = "RAIN, SNOW IN THE EVENING"; +PROGMEM const char wc_327[] = "RAIN,SNOW IN THE NIGHT"; +PROGMEM const char wc_328[] = "RAIN, EXPECT OCCASIONAL HEAVY RAINFALL"; +PROGMEM const char wc_329[] = "RAIN, OCCASIONAL SLEET"; +PROGMEM const char wc_340[] = "SNOWORRAIN"; +PROGMEM const char wc_350[] = "RAIN AND THUNDER"; +PROGMEM const char wc_361[] = "SNOW OR RAIN, CLEAR LATER"; +PROGMEM const char wc_371[] = "SNOW OR RAIN, CLOUDY LATER"; +PROGMEM const char wc_400[] = "SNOW"; +PROGMEM const char wc_401[] = "SNOW, FREQUENT CLEAR"; +PROGMEM const char wc_402[] = "SNOWTHROUGHOUT THE DAY"; +PROGMEM const char wc_403[] = "SNOW,FREQUENT SCCATERED SHOWERS"; +PROGMEM const char wc_405[] = "HEAVYSNOW"; +PROGMEM const char wc_406[] = "SNOWSTORM"; +PROGMEM const char wc_407[] = "HEAVYSNOWSTORM"; +PROGMEM const char wc_409[] = "SNOW, OCCASIONAL SCCATERED SHOWERS"; +PROGMEM const char wc_411[] = "SNOW,CLEAR LATER"; +PROGMEM const char wc_413[] = "SNOW,CLOUDY LATER"; +PROGMEM const char wc_414[] = "SNOW,RAIN LATER"; +PROGMEM const char wc_420[] = "SNOW IN THE MORNING, CLEAR LATER"; +PROGMEM const char wc_421[] = "SNOW IN THE MORNING, CLOUDY LATER"; +PROGMEM const char wc_422[] = "SNOW, RAIN IN THE AFTERNOON"; +PROGMEM const char wc_423[] = "SNOW, RAIN IN THE EVENING"; +PROGMEM const char wc_425[] = "SNOW, EXPECT OCCASIONAL HEAVY SNOWFALL"; +PROGMEM const char wc_426[] = "SNOW, SLEET LATER"; +PROGMEM const char wc_427[] = "SNOW, OCCASIONAL SLEET"; +PROGMEM const char wc_450[] = "SNOW AND THUNDER"; +#endif + +const std::map weatherCodeTable = +{ + { 100, wc_100 }, + { 101, wc_101 }, + { 102, wc_102 }, + { 103, wc_103 }, + { 104, wc_104 }, + { 105, wc_105 }, + { 106, wc_106 }, + { 107, wc_107 }, + { 108, wc_108 }, + { 110, wc_110 }, + { 111, wc_111 }, + { 112, wc_112 }, + { 113, wc_113 }, + { 114, wc_114 }, + { 115, wc_115 }, + { 116, wc_116 }, + { 117, wc_117 }, + { 118, wc_118 }, + { 119, wc_119 }, + { 120, wc_120 }, + { 121, wc_121 }, + { 122, wc_122 }, + { 123, wc_123 }, + { 124, wc_124 }, + { 125, wc_125 }, + { 126, wc_126 }, + { 127, wc_127 }, + { 128, wc_128 }, + { 130, wc_130 }, + { 131, wc_131 }, + { 132, wc_132 }, + { 140, wc_140 }, + { 160, wc_160 }, + { 170, wc_170 }, + { 181, wc_181 }, + { 200, wc_200 }, + { 201, wc_201 }, + { 202, wc_202 }, + { 203, wc_203 }, + { 204, wc_204 }, + { 205, wc_205 }, + { 206, wc_206 }, + { 207, wc_207 }, + { 208, wc_208 }, + { 209, wc_209 }, + { 210, wc_210 }, + { 211, wc_211 }, + { 212, wc_212 }, + { 213, wc_213 }, + { 214, wc_214 }, + { 215, wc_215 }, + { 216, wc_216 }, + { 217, wc_217 }, + { 218, wc_218 }, + { 219, wc_219 }, + { 220, wc_220 }, + { 221, wc_221 }, + { 222, wc_222 }, + { 223, wc_223 }, + { 224, wc_224 }, + { 225, wc_225 }, + { 226, wc_226 }, + { 228, wc_228 }, + { 229, wc_229 }, + { 230, wc_230 }, + { 231, wc_231 }, + { 240, wc_240 }, + { 250, wc_250 }, + { 260, wc_260 }, + { 270, wc_270 }, + { 281, wc_281 }, + { 300, wc_300 }, + { 301, wc_301 }, + { 302, wc_302 }, + { 303, wc_303 }, + { 304, wc_304 }, + { 306, wc_306 }, + { 308, wc_308 }, + { 309, wc_309 }, + { 311, wc_311 }, + { 313, wc_313 }, + { 314, wc_314 }, + { 315, wc_315 }, + { 316, wc_316 }, + { 317, wc_317 }, + { 320, wc_320 }, + { 321, wc_321 }, + { 322, wc_322 }, + { 323, wc_323 }, + { 324, wc_324 }, + { 325, wc_325 }, + { 326, wc_326 }, + { 327, wc_327 }, + { 328, wc_328 }, + { 329, wc_329 }, + { 340, wc_340 }, + { 350, wc_350 }, + { 361, wc_361 }, + { 371, wc_371 }, + { 400, wc_400 }, + { 401, wc_401 }, + { 402, wc_402 }, + { 403, wc_403 }, + { 405, wc_405 }, + { 406, wc_406 }, + { 407, wc_407 }, + { 409, wc_409 }, + { 411, wc_411 }, + { 413, wc_413 }, + { 414, wc_414 }, + { 420, wc_420 }, + { 421, wc_421 }, + { 422, wc_422 }, + { 423, wc_423 }, + { 425, wc_425 }, + { 426, wc_426 }, + { 427, wc_427 }, + { 450, wc_450 }, +}; + +#if 0 +struct JMA_Prefecures +{ + jma::officecode_t representative; // Representative value of offices. + std::vector offices; +}; +const JMA_Prefecures prefectures[] = +{ + { 16000, { 16000, 11000, 13000, 14030, 14100, 15000, 12000, 17000 } }, + { 40000, { 40000, 60000, 70000, 20000, 50000, 30000 } }, + { 130000, { 130000,120000,140000,190000, 90000,100000,110000, 80000,200000 } }, + { 150000, { 150000,170000,180000,160000 } }, + { 230000, { 230000,240000,220000,210000 } }, + { 270000, { 270000,300000,260000,250000,280000,290000 } }, + { 340000, { 340000,310000,330000,320000 } }, + { 370000, { 370000,380000,360000,390000 } }, + { 400000, { 400000,440000,410000,430000,420000,350000 } }, + { 460100, { 460100,450000,460040 } }, + { 471000, { 471000,473000,474000,472000 } }, +}; +#endif + + +// Office code string +#if 1 +# if 0 +PROGMEM const char ocloc_11000[] = "宗谷地方"; +PROGMEM const char ocloc_12000[] = "上川・留萌地方"; +PROGMEM const char ocloc_13000[] = "網走・北見・紋別地方"; +PROGMEM const char ocloc_14100[] = "釧路・根室地方"; +PROGMEM const char ocloc_14030[] = "十勝地方"; +PROGMEM const char ocloc_15000[] = "胆振・日高地方"; +PROGMEM const char ocloc_16000[] = "石狩・空知・後志地方"; +PROGMEM const char ocloc_17000[] = "渡島・檜山地方"; +PROGMEM const char ocloc_20000[] = "青森県"; +PROGMEM const char ocloc_30000[] = "岩手県"; +PROGMEM const char ocloc_40000[] = "宮城県"; +PROGMEM const char ocloc_50000[] = "秋田県"; +PROGMEM const char ocloc_60000[] = "山形県"; +PROGMEM const char ocloc_70000[] = "福島県"; +PROGMEM const char ocloc_80000[] = "茨城県"; +PROGMEM const char ocloc_90000[] = "栃木県"; +PROGMEM const char ocloc_100000[] = "群馬県"; +PROGMEM const char ocloc_110000[] = "埼玉県"; +PROGMEM const char ocloc_120000[] = "千葉県"; +PROGMEM const char ocloc_130000[] = "東京都"; +PROGMEM const char ocloc_140000[] = "神奈川県"; +PROGMEM const char ocloc_150000[] = "新潟県"; +PROGMEM const char ocloc_160000[] = "富山県"; +PROGMEM const char ocloc_170000[] = "石川県"; +PROGMEM const char ocloc_180000[] = "福井県"; +PROGMEM const char ocloc_190000[] = "山梨県"; +PROGMEM const char ocloc_200000[] = "長野県"; +PROGMEM const char ocloc_210000[] = "岐阜県"; +PROGMEM const char ocloc_220000[] = "静岡県"; +PROGMEM const char ocloc_230000[] = "愛知県"; +PROGMEM const char ocloc_240000[] = "三重県"; +PROGMEM const char ocloc_250000[] = "滋賀県"; +PROGMEM const char ocloc_260000[] = "京都府"; +PROGMEM const char ocloc_270000[] = "大阪府"; +PROGMEM const char ocloc_280000[] = "兵庫県"; +PROGMEM const char ocloc_290000[] = "奈良県"; +PROGMEM const char ocloc_300000[] = "和歌山県"; +PROGMEM const char ocloc_310000[] = "鳥取県"; +PROGMEM const char ocloc_320000[] = "島根県"; +PROGMEM const char ocloc_330000[] = "岡山県"; +PROGMEM const char ocloc_340000[] = "広島県"; +PROGMEM const char ocloc_350000[] = "山口県"; +PROGMEM const char ocloc_360000[] = "徳島県"; +PROGMEM const char ocloc_370000[] = "香川県"; +PROGMEM const char ocloc_380000[] = "愛媛県"; +PROGMEM const char ocloc_390000[] = "高知県"; +PROGMEM const char ocloc_400000[] = "福岡県"; +PROGMEM const char ocloc_410000[] = "佐賀県"; +PROGMEM const char ocloc_420000[] = "長崎県"; +PROGMEM const char ocloc_430000[] = "熊本県"; +PROGMEM const char ocloc_440000[] = "大分県"; +PROGMEM const char ocloc_450000[] = "宮崎県"; +PROGMEM const char ocloc_460100[] = "鹿児島県"; +PROGMEM const char ocloc_460040[] = "奄美地方"; +PROGMEM const char ocloc_471000[] = "沖縄本島地方"; +PROGMEM const char ocloc_472000[] = "大東島地方"; +PROGMEM const char ocloc_473000[] = "宮古島地方"; +PROGMEM const char ocloc_474000[] = "八重山地方"; +# else +// +PROGMEM const char ocloc_16000[] = "札幌"; +PROGMEM const char ocloc_40000[] = "仙台"; +PROGMEM const char ocloc_130000[] = "東京"; +PROGMEM const char ocloc_150000[] = "新潟"; +PROGMEM const char ocloc_170000[] = "金沢"; +PROGMEM const char ocloc_230000[] = "名古屋"; +PROGMEM const char ocloc_270000[] = "大阪"; +PROGMEM const char ocloc_340000[] = "広島"; +PROGMEM const char ocloc_390000[] = "高知"; +PROGMEM const char ocloc_400000[] = "福岡"; +PROGMEM const char ocloc_471000[] = "那覇"; + +# endif +#else + +PROGMEM const char ocloc_11000[] = "SOYA"; // Region +PROGMEM const char ocloc_12000[] = "KAMIKAWA RUMOI"; // Region +PROGMEM const char ocloc_13000[] = "ABASHIRI"; // Region +PROGMEM const char ocloc_14100[] = "KUSHIRO NEMURO"; // Region +PROGMEM const char ocloc_14030[] = "TOKACHI"; // Region +PROGMEM const char ocloc_15000[] = "IBURI HIDAKA"; // Region +PROGMEM const char ocloc_16000[] = "ISHIKARI SORACHI"; // Region +PROGMEM const char ocloc_17000[] = "OSHIMA HIYAMA"; // Region +PROGMEM const char ocloc_20000[] = "AOMORI"; +PROGMEM const char ocloc_30000[] = "IWATE"; +PROGMEM const char ocloc_40000[] = "MIYAGI"; +PROGMEM const char ocloc_50000[] = "AKITA"; +PROGMEM const char ocloc_60000[] = "YAMAGATA"; +PROGMEM const char ocloc_70000[] = "FUKUSHIMA"; +PROGMEM const char ocloc_80000[] = "IBARAKI"; +PROGMEM const char ocloc_90000[] = "TOCHIGI"; +PROGMEM const char ocloc_100000[] = "GUNMA"; +PROGMEM const char ocloc_110000[] = "SAITAMA"; +PROGMEM const char ocloc_120000[] = "CHIBA"; +PROGMEM const char ocloc_130000[] = "TOKYO"; +PROGMEM const char ocloc_140000[] = "KANAGAWA"; +PROGMEM const char ocloc_150000[] = "NIIGATA"; +PROGMEM const char ocloc_160000[] = "TOYAMA"; +PROGMEM const char ocloc_170000[] = "ISHIKAWA"; +PROGMEM const char ocloc_180000[] = "FUKUI"; +PROGMEM const char ocloc_190000[] = "YAMANASHI"; +PROGMEM const char ocloc_200000[] = "NAGANO"; +PROGMEM const char ocloc_210000[] = "GIFU"; +PROGMEM const char ocloc_220000[] = "SHIZUOKA"; +PROGMEM const char ocloc_230000[] = "AICHI"; +PROGMEM const char ocloc_240000[] = "MIE"; +PROGMEM const char ocloc_250000[] = "SHIGA"; +PROGMEM const char ocloc_260000[] = "KYOTO"; +PROGMEM const char ocloc_270000[] = "OSAKA"; +PROGMEM const char ocloc_280000[] = "HYOGO"; +PROGMEM const char ocloc_290000[] = "NARA"; +PROGMEM const char ocloc_300000[] = "WAKAYAMA"; +PROGMEM const char ocloc_310000[] = "TOTTORI"; +PROGMEM const char ocloc_320000[] = "SHIANE"; +PROGMEM const char ocloc_330000[] = "OKAYAMA"; +PROGMEM const char ocloc_340000[] = "HIROSHIMA"; +PROGMEM const char ocloc_350000[] = "YAMAGUCHI"; +PROGMEM const char ocloc_360000[] = "TOKUSHIMA"; +PROGMEM const char ocloc_370000[] = "KAGAWA"; +PROGMEM const char ocloc_380000[] = "EHIME"; +PROGMEM const char ocloc_390000[] = "KOUCHI"; +PROGMEM const char ocloc_400000[] = "FUKUOKA"; +PROGMEM const char ocloc_410000[] = "SAGA"; +PROGMEM const char ocloc_420000[] = "NAGASAKI"; +PROGMEM const char ocloc_430000[] = "KUMAMOTO"; +PROGMEM const char ocloc_440000[] = "OOITA"; +PROGMEM const char ocloc_450000[] = "MIYAZAKI"; +PROGMEM const char ocloc_460100[] = "KAGOSHIMA"; +PROGMEM const char ocloc_460040[] = "AMAMI"; // Islands +PROGMEM const char ocloc_471000[] = "OKINAWA"; // Islands +PROGMEM const char ocloc_472000[] = "DAITOU"; // Islands +PROGMEM const char ocloc_473000[] = "MIYAKO"; // Islands +PROGMEM const char ocloc_474000[] = "YAEYAMA"; // Islands +#endif + +#if 0 +const std::map officeCodeTable = +{ + // 北海道 + { 11000, ocloc_11000 }, + { 12000, ocloc_12000 }, + { 13000, ocloc_13000 }, + { 14100, ocloc_14100 }, + { 14030, ocloc_14030 }, + { 15000, ocloc_15000 }, + { 16000, ocloc_16000 }, + { 17000, ocloc_16000 }, + // 東北 + { 20000, ocloc_20000 }, + { 30000, ocloc_30000 }, + { 40000, ocloc_40000 }, + { 50000, ocloc_50000 }, + { 60000, ocloc_60000 }, + { 70000, ocloc_70000 }, + // 関東 + { 80000, ocloc_80000 }, + { 90000, ocloc_90000 }, + { 100000, ocloc_100000 }, + { 110000, ocloc_110000 }, + { 120000, ocloc_120000 }, + { 130000, ocloc_130000 }, + { 140000, ocloc_140000 }, + // 北陸、甲信 + { 150000, ocloc_150000 }, + { 160000, ocloc_160000 }, + { 170000, ocloc_170000 }, + { 180000, ocloc_180000 }, + { 190000, ocloc_190000 }, + { 200000, ocloc_200000 }, + // 東海 + { 210000, ocloc_210000 }, + { 220000, ocloc_220000 }, + { 230000, ocloc_230000 }, + { 240000, ocloc_240000 }, + // 近畿 + { 250000, ocloc_250000 }, + { 260000, ocloc_260000 }, + { 270000, ocloc_270000 }, + { 280000, ocloc_280000 }, + { 290000, ocloc_290000 }, + { 300000, ocloc_300000 }, + // 中国 + { 310000, ocloc_310000 }, + { 320000, ocloc_320000 }, + { 330000, ocloc_330000 }, + { 340000, ocloc_340000 }, + { 350000, ocloc_350000 }, + // 四国 + { 360000, ocloc_360000 }, + { 370000, ocloc_370000 }, + { 380000, ocloc_380000 }, + { 390000, ocloc_390000 }, + // 九州 + { 400000, ocloc_400000 }, + { 410000, ocloc_410000 }, + { 420000, ocloc_420000 }, + { 430000, ocloc_430000 }, + { 440000, ocloc_440000 }, + { 450000, ocloc_450000 }, + { 460100, ocloc_460100 }, + { 460040, ocloc_460040 }, + // 沖縄 + { 471000, ocloc_471000 }, + { 472000, ocloc_472000 }, + { 473000, ocloc_473000 }, + { 474000, ocloc_474000 }, +}; + +#else + +const std::map officeCodeTable = +{ + { 16000, ocloc_16000 }, + { 40000, ocloc_40000 }, + { 130000, ocloc_130000 }, + { 150000, ocloc_150000 }, + { 170000, ocloc_170000 }, + { 230000, ocloc_230000 }, + { 270000, ocloc_270000 }, + { 340000, ocloc_340000 }, + { 390000, ocloc_390000 }, + { 400000, ocloc_400000 }, + { 471000, ocloc_471000 }, +}; + +#endif + +// Weather code to weather icon +const std::map iconTable = +{ + { 100, 100 }, + { 101, 101 }, + { 102, 102 }, + { 103, 102 }, + { 104, 104 }, + { 105, 104 }, + { 106, 102 }, + { 107, 102 }, + { 108, 102 }, + { 110, 110 }, + { 111, 110 }, + { 112, 112 }, + { 113, 112 }, + { 114, 112 }, + { 115, 115 }, + { 116, 115 }, + { 117, 115 }, + { 118, 112 }, + { 119, 112 }, + { 120, 102 }, + { 121, 102 }, + { 122, 112 }, + { 123, 100 }, + { 124, 100 }, + { 125, 112 }, + { 126, 112 }, + { 127, 112 }, + { 128, 112 }, + { 130, 100 }, + { 131, 100 }, + { 132, 101 }, + { 140, 102 }, + { 160, 104 }, + { 170, 104 }, + { 181, 115 }, + { 200, 200 }, + { 201, 201 }, + { 202, 202 }, + { 203, 202 }, + { 204, 204 }, + { 205, 204 }, + { 206, 202 }, + { 207, 202 }, + { 208, 202 }, + { 209, 200 }, + { 210, 210 }, + { 211, 210 }, + { 212, 212 }, + { 213, 212 }, + { 214, 212 }, + { 215, 215 }, + { 216, 215 }, + { 217, 215 }, + { 218, 212 }, + { 219, 212 }, + { 220, 202 }, + { 221, 202 }, + { 222, 212 }, + { 223, 201 }, + { 224, 212 }, + { 225, 212 }, + { 226, 212 }, + { 228, 215 }, + { 229, 215 }, + { 230, 215 }, + { 231, 200 }, + { 240, 202 }, + { 250, 204 }, + { 260, 204 }, + { 270, 204 }, + { 281, 215 }, + { 300, 300 }, + { 301, 301 }, + { 302, 302 }, + { 303, 303 }, + { 304, 300 }, + { 306, 300 }, + { 308, 308 }, + { 309, 303 }, + { 311, 311 }, + { 313, 313 }, + { 314, 314 }, + { 315, 314 }, + { 316, 311 }, + { 317, 313 }, + { 320, 311 }, + { 321, 313 }, + { 322, 303 }, + { 323, 311 }, + { 324, 311 }, + { 325, 311 }, + { 326, 314 }, + { 327, 314 }, + { 328, 300 }, + { 329, 300 }, + { 340, 400 }, + { 350, 300 }, + { 361, 411 }, + { 371, 413 }, + { 400, 400 }, + { 401, 401 }, + { 402, 402 }, + { 403, 403 }, + { 405, 400 }, + { 406, 406 }, + { 407, 406 }, + { 409, 403 }, + { 411, 411 }, + { 413, 413 }, + { 414, 414 }, + { 420, 411 }, + { 421, 413 }, + { 422, 414 }, + { 423, 414 }, + { 425, 400 }, + { 426, 400 }, + { 427, 400 }, + { 450, 400 }, +}; + +// +} + +namespace jma +{ +const char* weatherCodeToString(const weathercode_t wc) +{ + return weatherCodeTable.count(wc) == 1 ? weatherCodeTable.at(wc) : ""; +} + +const char* officesCodeToString(const officecode_t oc) +{ + return officeCodeTable.count(oc) == 1 ? officeCodeTable.at(oc) : ""; +} + +int16_t weatherCodeToIcon(const weathercode_t wc) +{ + return iconTable.count(wc) == 1 ? iconTable.at(wc) : 0; +} + +// +} diff --git a/src/jma/jma_definition.hpp b/src/jma/jma_definition.hpp new file mode 100644 index 0000000..ef4811f --- /dev/null +++ b/src/jma/jma_definition.hpp @@ -0,0 +1,17 @@ +#ifndef JMA_DEFINITION_HPP +#define JMA_DEFINITION_HPP + +#include + +namespace jma +{ + +using officecode_t = uint32_t; +using weathercode_t = uint16_t; + +const char* weatherCodeToString(const weathercode_t wc); +const char* officesCodeToString(const officecode_t oc); +int16_t weatherCodeToIcon(const weathercode_t wc); +// +} +#endif diff --git a/src/jma/jma_forecast.cpp b/src/jma/jma_forecast.cpp new file mode 100644 index 0000000..d12771d --- /dev/null +++ b/src/jma/jma_forecast.cpp @@ -0,0 +1,169 @@ + +#include "jma_forecast.hpp" +#include "utility.hpp" +#include +#include +#include + +namespace jma +{ +// +String Area::toString() const +{ + String s = "name:" + _name + ", code:" + String(_code); + return s; +} + +// +Reliability Reliability::parse(const char* s) +{ + if(!s || !s[0] || s[1]) { return Reliability(Rank::MAX); } + int v = *s - 'A'; + return Reliability((v >= 0 && v < gob::to_underlying(Rank::MAX)) ? (Rank)v : Rank::MAX); +} + +String Reliability::toString() const +{ + static constexpr char tbl[] = { 'A', 'B', 'C', '-'}; + auto v = gob::to_underlying(_rank); + return String((v < gob::to_underlying(Rank::MAX)) ? tbl[v] : tbl[gob::to_underlying(Rank::MAX)]); +} + +// +String Forecast::toString() const +{ + String s; + s += "publishingOffice:" + _publishingOffice + '\n'; + s += "reportDatetime:" + _reportDatetime.toString() + '\n'; + s += "timeSeries[0]:Weather\n" + _tsWeather.toString() + '\n'; + s += "timeSeries[1]:Pop\n" + _tsPop.toString() + '\n'; + s += "timeSeries[2]:Temp\n" + _tsTemp.toString(); + return s; +} + + +String Forecast::TimeSeriesWeather::toString() const +{ + String s; + s = "timeDefine:[" + gob::join(_timeDefines) + "]\n"; + s += gob::join(_areas, "\n"); + return s; +} + +String Forecast::TimeSeriesWeather::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "weatherCodes:[" + gob::join(_weatherCodes) + "]\n"; + s += "weathers:[" + gob::join(_weathers) + "]\n"; + s += "winds:[" + gob::join(_winds) + "]\n"; + s += "waves:[" + gob::join(_waves) + "]"; + return s; +} + +String Forecast::TimeSeriesPop::toString() const +{ + String s; + s = "timeDefine:[" + gob::join(_timeDefines) + "]\n"; + s += gob::join(_areas, "\n"); + return s; +} + +String Forecast::TimeSeriesPop::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "pops:[" + gob::join(_pops) + "]"; + return s; +} + +String Forecast::TimeSeriesTemp::toString() const +{ + String s; + s = "timeDefine:[" + gob::join(_timeDefines) + "]\n"; + s += gob::join(_areas, "\n"); + return s; +} + +String Forecast::TimeSeriesTemp::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "temps:[" + gob::join(_temps) + "]"; + return s; +} + +// +String WeeklyForecast::toString() const +{ + String s; + s += "publishingOffice:" + _publishingOffice + '\n'; + s += "reportDatetime:" + _reportDatetime.toString() + '\n'; + s += "timeSeries[0]:Weather\n" + _tsWeather.toString() + '\n'; + s += "timeSeries[1]:Temp\n" + _tsTemp.toString() + '\n'; + s += "tempAverage\n" + _tempAverage.toString() + '\n'; + s += "precipAverage:\n" + _precipAverage.toString(); + return s; +} + +String WeeklyForecast::TimeSeriesWeather::toString() const +{ + String s; + s = "timeDefine:[" + gob::join(_timeDefines) + "]\n"; + s += gob::join(_areas, "\n"); + return s; +} + +String WeeklyForecast::TimeSeriesWeather::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "weatherCodes:[" + gob::join(_weatherCodes) + "]\n"; + s += "pops:[" + gob::join(_pops) + "]\n"; + s += "reliabilities:[" + gob::join(_reliabilities) + ']'; + return s; +} + +String WeeklyForecast::TimeSeriesTemp::toString() const +{ + String s; + s = "timeDefine:[" + gob::join(_timeDefines) + "]\n"; + s += gob::join(_areas, "\n"); + return s; +} + +String WeeklyForecast::TimeSeriesTemp::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "tempsMin:[" + gob::join(_tempsMin) + "]\n"; + s += "tempsMinUpper[:" + gob::join(_tempsMinUpper) + "]\n"; + s += "tempsMinLower:[" + gob::join(_tempsMinLower) + "]\n"; + s += "tempsMax:[" + gob::join(_tempsMax) + "]\n"; + s += "tempsMaxUpper:[" + gob::join(_tempsMaxUpper) + "]\n"; + s += "tempsMaxLower:[" + gob::join(_tempsMaxLower) + "]"; + return s; +} + +String WeeklyForecast::TempAverage::toString() const +{ + String s = gob::join(_areas, "\n"); + return s; +} + +String WeeklyForecast::TempAverage::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "min:" + String(_min) + ", max:" + String(_max); + return s; +} + +String WeeklyForecast::PrecipAverage::toString() const +{ + String s = gob::join(_areas, "\n"); + return s; +} + +String WeeklyForecast::PrecipAverage::Areas::toString() const +{ + String s = _area.toString() + '\n'; + s += "min:" + String(_min) + ", max:" + String(_max); + return s; +} +// +} diff --git a/src/jma/jma_forecast.hpp b/src/jma/jma_forecast.hpp new file mode 100644 index 0000000..04066d4 --- /dev/null +++ b/src/jma/jma_forecast.hpp @@ -0,0 +1,167 @@ + +#ifndef JMA_FORECAST_HPP +#define JMA_FORECAST_HPP + +#include "jma_definition.hpp" +#include +#include +#include +using goblib::datetime::OffsetDateTime; + +namespace jma +{ + +struct Area +{ + String _name{}; + uint32_t _code{}; + String toString() const; +}; + +struct Reliability +{ + enum class Rank : uint8_t { A, B, C, MAX }; + + explicit Reliability(const Rank r) : _rank(r) {} + explicit Reliability(const char* s) { *this = parse(s); } + static Reliability parse(const char* s); + String toString() const; + private: + Rank _rank{Rank::C}; +}; + +// +struct Forecast +{ + struct TimeSeriesWeather + { + struct Areas + { + Area _area{}; + std::vector _weatherCodes; + std::vector _weathers; + std::vector _winds; + std::vector _waves; + String toString() const; + }; + std::vector _timeDefines; + std::vector _areas; + String toString() const; + }; + struct TimeSeriesPop + { + struct Areas + { + Area _area{}; + std::vector _pops; + String toString() const; + }; + std::vector _timeDefines; + std::vector _areas; + String toString() const; + }; + struct TimeSeriesTemp + { + struct Areas + { + Area _area{}; + std::vector _temps; // Pair 2 elements. [low,high,low,high...] + String toString() const; + }; + std::vector _timeDefines; // Same as _temps length + std::vector _areas; + String toString() const; + }; + + + String _publishingOffice{}; + OffsetDateTime _reportDatetime{}; + TimeSeriesWeather _tsWeather{}; + TimeSeriesPop _tsPop{}; + TimeSeriesTemp _tsTemp{}; + + String toString() const; + + // + bool existsTopWeatherCodes() const { return !_tsWeather._areas.empty() && !_tsWeather._areas[0]._weatherCodes.empty(); } + const std::vector& TopWeatherCodes() const { return _tsWeather._areas[0]._weatherCodes; } + const std::vector& TopWeatherTime() const { return _tsWeather._timeDefines; } + + bool existsTopTemp() const { return !_tsTemp._areas.empty() && !_tsTemp._areas[0]._temps.empty(); } + const std::vector& TopTemp() const { return _tsTemp._areas[0]._temps; } + const std::vector& TopTempTime() const { return _tsTemp._timeDefines; } +}; + + +// 週間予報 +struct WeeklyForecast +{ + struct TimeSeriesWeather + { + struct Areas + { + Area _area; + std::vector _weatherCodes; + std::vector _pops; + std::vector _reliabilities; + String toString() const; + }; + std::vector _timeDefines; + std::vector _areas; + String toString() const; + }; + + struct TimeSeriesTemp + { + struct Areas + { + Area _area; + std::vector _tempsMin; + std::vector _tempsMinUpper; + std::vector _tempsMinLower; + std::vector _tempsMax; + std::vector _tempsMaxUpper; + std::vector _tempsMaxLower; + String toString() const; + }; + std::vector _timeDefines; + std::vector _areas; + String toString() const; + }; + struct TempAverage + { + struct Areas + { + Area _area{}; + float _min{}; + float _max{}; + String toString() const; + }; + std::vector _areas; + String toString() const; + }; + struct PrecipAverage + { + struct Areas + { + Area _area{}; + float _min{}; + float _max{}; + String toString() const; + }; + std::vector _areas; + String toString() const; + }; + + String _publishingOffice; + OffsetDateTime _reportDatetime{}; + TimeSeriesWeather _tsWeather{}; + TimeSeriesTemp _tsTemp{}; + TempAverage _tempAverage; + PrecipAverage _precipAverage; + String toString() const; +}; + +// +} +#endif diff --git a/src/jma/jma_forecast_handler.cpp b/src/jma/jma_forecast_handler.cpp new file mode 100644 index 0000000..baa5e42 --- /dev/null +++ b/src/jma/jma_forecast_handler.cpp @@ -0,0 +1,441 @@ + +#include +#include "jma_forecast_handler.hpp" +#include "wb2/wxbeacon2_log.hpp" + +using goblib::json::ElementPath; +using goblib::json::ElementValue; +using goblib::json::ElementBase; +using goblib::json::Element; +using Delegater = goblib::json::DelegateHandler::Delegater; +using goblib::datetime::OffsetDateTime; + +// Custom helper for specific types. +template struct CustomElement : public Element +{ + CustomElement(const char*k, T* vp) : Element(k, vp) {} + virtual void store(const ElementValue& ev, const int index = -1) override { _store(ev, index); } + + // OffsetDateTime + template::value, std::nullptr_t>::type = nullptr> + void _store(const ElementValue& ev, const int) { *(this->value) = OffsetDateTime::parse(ev.getString()); } + // vector + template::value && std::is_same::value, std::nullptr_t>::type = nullptr> + void _store(const ElementValue& ev, const int) { this->value->emplace_back(ev.getString()); } + // vector + template::value && std::is_same::value, std::nullptr_t>::type = nullptr> + void _store(const ElementValue& ev, const int) { this->value->emplace_back(ev.getString()); } +}; + +// Handler +void JMAHandler::startObject(const ElementPath& path) +{ + // WB2_LOGV("%s:index:%d count:%d", path.toString().c_str(), path.getIndex(), path.getCount()); + Delegater* obj = nullptr; + // pushDelegater if top level object in top array. + if(path.getCount() == 1) + { + switch(path.getIndex()) + { + case 0: obj = new Forecast(_forecast); break; + case 1: obj = new WeeklyForecast(_weeklyForecast); break; + } + if(obj) { pushDelegater(obj); return; } + WB2_LOGE("Missing object"); + } + DelegateHandler::startObject(path); +} + +// Area +void JMAHandler::Area::value(const ElementPath& path, const ElementValue& value) +{ + Element e_name { "name", &_v._name }; + Element e_code { "code", &_v._code }; + ElementBase* elements[] = { &e_name, &e_code }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == path.getKey()) { e->store(value); return; } } +} + +// ForeeCast +Delegater* JMAHandler::Forecast::startObject(const ElementPath& path) +{ + // WB2_LOGV("%s:index:%d count:%d", path.toString().c_str(), path.getIndex(), path.getCount()); + Delegater* obj = nullptr; + switch(path.getIndex()) + { + case 0: obj = new TimeSeriesWeather(_v._tsWeather); break; + case 1: obj = new TimeSeriesPop(_v._tsPop); break; + case 2: obj = new TimeSeriesTemp(_v._tsTemp); break; + } + return obj ? obj : Delegater::startObject(path); +} + +void JMAHandler::Forecast::value(const ElementPath& path, const ElementValue& value) +{ + Element e_publishingOffice { "publishingOffice", &_v._publishingOffice }; + CustomElement e_reportDatetime { "reportDatetime", &_v._reportDatetime }; + ElementBase* elements[] = { &e_publishingOffice, &e_reportDatetime }; + WB2_LOGV("[%s] %d <%s>", path.toString().c_str(), value.isString(), value.getString()); + for(auto& e : elements) { if(*e == path.getKey()) { e->store(value); return; } } + WB2_LOGE("oops!"); +} + +// Forecast::TimeSeriesWeather +Delegater* JMAHandler::Forecast::TimeSeriesWeather::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TimeSeriesWeather::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesWeather::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + CustomElement e_td { "timeDefines", &_v._timeDefines }; + ElementBase* elements[] = { &e_td }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// Forecast::TimeSeriesWeather::Areas +Delegater* JMAHandler::Forecast::TimeSeriesWeather::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesWeather::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_codes { "weatherCodes", &_v._weatherCodes }; + // Element e_weathers { "weathers", &_v._weathers }; + // Element e_winds { "winds", &_v._winds }; + // Element e_waves { "waves", &_v._waves }; + // ElementBase* elements[] = { &e_codes, &e_weathers, &e_winds, &e_waves }; + ElementBase* elements[] = { &e_codes }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) {if(*e == parent->getKey()) { e->store(value); return; }} +} + +// Forecast::TimeSeriesPop +Delegater* JMAHandler::Forecast::TimeSeriesPop::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TimeSeriesPop::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesPop::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + CustomElement e_td { "timeDefines", &_v._timeDefines }; + ElementBase* elements[] = { &e_td }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// Forecast::TimeSeriesPop::Areas +Delegater* JMAHandler::Forecast::TimeSeriesPop::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesPop::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_pops { "pops", &_v._pops }; + ElementBase* elements[] = { &e_pops }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// Forecast::TimeSeriesTemp +Delegater* JMAHandler::Forecast::TimeSeriesTemp::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TimeSeriesTemp::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesTemp::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + CustomElement e_td { "timeDefines", &_v._timeDefines }; + ElementBase* elements[] = { &e_td }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// Forecast::TimeSeriesTemp::Areas +Delegater* JMAHandler::Forecast::TimeSeriesTemp::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::Forecast::TimeSeriesTemp::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_temps { "temps", &_v._temps }; + ElementBase* elements[] = { &e_temps }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForeeCast +Delegater* JMAHandler::WeeklyForecast::startObject(const ElementPath& path) +{ + Delegater* obj = nullptr; + auto parent = path.getParent(); + + if(String("timeSeries") == parent->getKey()) + { + switch(path.getIndex()) + { + case 0: obj = new TimeSeriesWeather(_v._tsWeather); break; + case 1: obj = new TimeSeriesTemp(_v._tsTemp); break; + } + } + else if(String("tempAverage") == path.getKey()) + { + obj = new TempAverage(_v._tempAverage); + } + else if(String("precipAverage") == path.getKey()) + { + obj = new PrecipAverage(_v._precipAverage); + } + return obj ? obj : Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::value(const ElementPath& path, const ElementValue& value) +{ + Element e_publishingOffice { "publishingOffice", &_v._publishingOffice }; + CustomElement e_reportDatetime { "reportDatetime", &_v._reportDatetime }; + ElementBase* elements[] = { &e_publishingOffice, &e_reportDatetime }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == path.getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::TimeSeriesWeather +Delegater* JMAHandler::WeeklyForecast::TimeSeriesWeather::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TimeSeriesWeather::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TimeSeriesWeather::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + CustomElement e_td { "timeDefines", &_v._timeDefines }; + ElementBase* elements[] = { &e_td }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::TimeSeriesWeather::Areas +Delegater* JMAHandler::WeeklyForecast::TimeSeriesWeather::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TimeSeriesWeather::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_codes { "weatherCodes", &_v._weatherCodes }; + Element e_pops { "pops", &_v._pops }; + CustomElement e_reliabilities { "reliabilities", &_v._reliabilities }; + ElementBase* elements[] = { &e_codes, &e_pops, &e_reliabilities }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) {if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::TimeSeriesTemp +Delegater* JMAHandler::WeeklyForecast::TimeSeriesTemp::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TimeSeriesTemp::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TimeSeriesTemp::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + CustomElement e_td { "timeDefines", &_v._timeDefines }; + ElementBase* elements[] = { &e_td }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::TimeSeriesTemp::Areas +Delegater* JMAHandler::WeeklyForecast::TimeSeriesTemp::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TimeSeriesTemp::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_tempsMin { "tempsMin", &_v._tempsMin }; + Element e_tempsMinU { "tempsMinUpper", &_v._tempsMinUpper }; + Element e_tempsMinL { "tempsMinLower", &_v._tempsMinLower }; + Element e_tempsMax { "tempsMax", &_v._tempsMax }; + Element e_tempsMaxU { "tempsMaxUpper", &_v._tempsMaxUpper }; + Element e_tempsMaxL { "tempsMaxLower", &_v._tempsMaxLower }; + ElementBase* elements[] = { &e_tempsMin, &e_tempsMinU, &e_tempsMinL, &e_tempsMax, &e_tempsMaxU, &e_tempsMaxL }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::TempAverage +Delegater* JMAHandler::WeeklyForecast::TempAverage::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new TempAverage::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TempAverage::value(const ElementPath& path, const ElementValue& value) +{ + // No value is obtained. +} + +// WeeklyForecast::TempAverage::Areas +Delegater* JMAHandler::WeeklyForecast::TempAverage::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::TempAverage::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_min { "min", &_v._min }; + Element e_max { "max", &_v._max }; + ElementBase* elements[] = { &e_min, &e_max }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +// WeeklyForecast::PrecipAverage +Delegater* JMAHandler::WeeklyForecast::PrecipAverage::startObject(const ElementPath& path) +{ + auto parent = path.getParent(); + if(parent && String("areas") == parent->getKey()) + { + _v._areas.emplace_back(); + return new PrecipAverage::Areas(_v._areas.back()); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::PrecipAverage::value(const ElementPath& path, const ElementValue& value) +{ +} + +// WeeklyForecast::PrecipAverage::Areas +Delegater* JMAHandler::WeeklyForecast::PrecipAverage::Areas::startObject(const ElementPath& path) +{ + if(String("area") == path.getKey()) + { + return new JMAHandler::Area(_v._area); + } + return Delegater::startObject(path); +} + +void JMAHandler::WeeklyForecast::PrecipAverage::Areas::value(const ElementPath& path, const ElementValue& value) +{ + auto parent = path.getParent(); + if(!parent) { return; } + + Element e_min { "min", &_v._min }; + Element e_max { "max", &_v._max }; + ElementBase* elements[] = { &e_min, &e_max }; + // WB2_LOGV("[%s] <%s>", path.toString().c_str(), value.toString().c_str()); + for(auto& e : elements) { if(*e == parent->getKey()) { e->store(value); return; } } +} + +#if 0 +namespace +{ +const char jma_json[] = +R"***( +[{"publishingOffice":"金沢地方気象台","reportDatetime":"2023-01-10T11:00:00+09:00","timeSeries":[{"timeDefines":["2023-01-10T11:00:00+09:00","2023-01-11T00:00:00+09:00","2023-01-12T00:00:00+09:00"],"areas":[{"area":{"name":"加賀","code":"170010"},"weatherCodes":["200","101","101"],"weathers":["くもり 所により 夕方 まで 雨か雪","晴れ 昼前 から 夕方 くもり","晴れ 時々 くもり"],"winds":["北の風 海上 では 北西の風 やや強く","南の風 海上 では 南西の風 やや強く","南の風 後 南西の風"],"waves":["3メートル うねり を伴う","2メートル 後 1.5メートル","1.5メートル 後 1メートル"]},{"area":{"name":"能登","code":"170020"},"weatherCodes":["200","111","201"],"weathers":["くもり 所により 夕方 まで 雨か雪","晴れ 昼前 から くもり","くもり 時々 晴れ"],"winds":["北西の風 やや強く 後 西の風","南の風 海上 では 南西の風 やや強く","南の風"],"waves":["4メートル 後 3メートル うねり を伴う","2.5メートル 後 2メートル","2メートル"]}]},{"timeDefines":["2023-01-10T12:00:00+09:00","2023-01-10T18:00:00+09:00","2023-01-11T00:00:00+09:00","2023-01-11T06:00:00+09:00","2023-01-11T12:00:00+09:00","2023-01-11T18:00:00+09:00"],"areas":[{"area":{"name":"加賀","code":"170010"},"pops":["30","10","0","10","10","0"]},{"area":{"name":"能登","code":"170020"},"pops":["30","10","10","20","20","10"]}]},{"timeDefines":["2023-01-10T09:00:00+09:00","2023-01-10T00:00:00+09:00","2023-01-11T00:00:00+09:00","2023-01-11T09:00:00+09:00"],"areas":[{"area":{"name":"金沢","code":"56227"},"temps":["6","6","0","9"]},{"area":{"name":"輪島","code":"56052"},"temps":["4","5","0","9"]}]}]},{"publishingOffice":"金沢地方気象台","reportDatetime":"2023-01-10T11:00:00+09:00","timeSeries":[{"timeDefines":["2023-01-11T00:00:00+09:00","2023-01-12T00:00:00+09:00","2023-01-13T00:00:00+09:00","2023-01-14T00:00:00+09:00","2023-01-15T00:00:00+09:00","2023-01-16T00:00:00+09:00","2023-01-17T00:00:00+09:00"],"areas":[{"area":{"name":"石川県","code":"170000"},"weatherCodes":["101","101","201","203","202","206","206"],"pops":["","20","40","70","60","50","50"],"reliabilities":["","","C","A","B","C","C"]}]},{"timeDefines":["2023-01-11T00:00:00+09:00","2023-01-12T00:00:00+09:00","2023-01-13T00:00:00+09:00","2023-01-14T00:00:00+09:00","2023-01-15T00:00:00+09:00","2023-01-16T00:00:00+09:00","2023-01-17T00:00:00+09:00"],"areas":[{"area":{"name":"金沢","code":"56227"},"tempsMin":["","2","4","7","4","3","4"],"tempsMinUpper":["","5","5","9","6","5","6"],"tempsMinLower":["","1","2","3","1","1","2"],"tempsMax":["","14","16","16","9","8","8"],"tempsMaxUpper":["","16","18","18","13","11","11"],"tempsMaxLower":["","13","15","14","7","6","6"]}]}],"tempAverage":{"areas":[{"area":{"name":"金沢","code":"56227"},"min":"1.2","max":"7.1"}]},"precipAverage":{"areas":[{"area":{"name":"金沢","code":"56227"},"min":"39.9","max":"67.2"}]}}] +)***"; +// +} +void test_json() +{ + JMAHandler handler; + goblib::json::StreamingParser parser(&handler); + for(auto& e : jma_json) { parser.parse(e); } + WB2_LOGD("%s", handler._forecast.toString().c_str()); + WB2_LOGD("%s", handler._weeklyForecast.toString().c_str()); + +} +#endif diff --git a/src/jma/jma_forecast_handler.hpp b/src/jma/jma_forecast_handler.hpp new file mode 100644 index 0000000..c856bf3 --- /dev/null +++ b/src/jma/jma_forecast_handler.hpp @@ -0,0 +1,194 @@ +#ifndef JMA_FORECAST_PARSER_HPP +#define JMA_FORECAST_PARSER_HPP + +#include +#include +#include +#include "jma_forecast.hpp" + +// JSON handler for JMA forecast +class JMAHandler : public goblib::json::DelegateHandler +{ + using ElementPath = goblib::json::ElementPath; + using ElementValue = goblib::json::ElementValue; + + public: + class Area : public Delegater + { + public: + Area(jma::Area& target) : _v(target) {} + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Area& _v; + }; + // + class Forecast : public Delegater + { + // + class TimeSeriesWeather : public Delegater + { + // + class Areas : public Delegater + { + public: + Areas(jma::Forecast::TimeSeriesWeather::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesWeather::Areas& _v; + }; + public: + TimeSeriesWeather(jma::Forecast::TimeSeriesWeather& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesWeather& _v; + }; + // + class TimeSeriesPop : public Delegater + { + public: + class Areas : public Delegater + { + public: + Areas(jma::Forecast::TimeSeriesPop::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesPop::Areas& _v; + }; + TimeSeriesPop(jma::Forecast::TimeSeriesPop& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesPop& _v; + }; + // + class TimeSeriesTemp : public Delegater + { + public: + class Areas : public Delegater + { + public: + Areas(jma::Forecast::TimeSeriesTemp::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesTemp::Areas& _v; + }; + TimeSeriesTemp(jma::Forecast::TimeSeriesTemp& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast::TimeSeriesTemp& _v; + }; + + public: + Forecast(jma::Forecast& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::Forecast& _v; + }; + + // + class WeeklyForecast : public Delegater + { + // + class TimeSeriesWeather : public Delegater + { + // + class Areas : public Delegater + { + public: + Areas(jma::WeeklyForecast::TimeSeriesWeather::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TimeSeriesWeather::Areas& _v; + }; + public: + TimeSeriesWeather(jma::WeeklyForecast::TimeSeriesWeather& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TimeSeriesWeather& _v; + }; + // + class TimeSeriesTemp : public Delegater + { + public: + class Areas : public Delegater + { + public: + Areas(jma::WeeklyForecast::TimeSeriesTemp::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TimeSeriesTemp::Areas& _v; + }; + TimeSeriesTemp(jma::WeeklyForecast::TimeSeriesTemp& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TimeSeriesTemp& _v; + }; + // + class TempAverage : public Delegater + { + public: + class Areas : public Delegater + { + public: + Areas(jma::WeeklyForecast::TempAverage::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TempAverage::Areas& _v; + }; + TempAverage(jma::WeeklyForecast::TempAverage& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::TempAverage& _v; + }; + // + class PrecipAverage : public Delegater + { + public: + class Areas : public Delegater + { + public: + Areas(jma::WeeklyForecast::PrecipAverage::Areas& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::PrecipAverage::Areas& _v; + }; + PrecipAverage(jma::WeeklyForecast::PrecipAverage& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast::PrecipAverage& _v; + }; + + public: + WeeklyForecast(jma::WeeklyForecast& target) : _v(target) {} + virtual Delegater* startObject(const ElementPath& path) override; + virtual void value(const ElementPath& path, const ElementValue& value) override; + private: + jma::WeeklyForecast& _v; + }; + + public: + void startObject(const ElementPath& path) override; + + jma::Forecast _forecast{}; + jma::WeeklyForecast _weeklyForecast{}; +}; + +#if 0 +void test_json(); +#endif + +#endif diff --git a/src/jma/jma_task.cpp b/src/jma/jma_task.cpp new file mode 100644 index 0000000..a35f1ae --- /dev/null +++ b/src/jma/jma_task.cpp @@ -0,0 +1,196 @@ + +#include +#include +#include +#include +#include +#include "jma_task.hpp" +#include "jma_forecast_handler.hpp" +#include "wb2/wxbeacon2_log.hpp" +#include "utility.hpp" + +namespace +{ +// Request JMA forcast by WiFi +TaskHandle_t forecastTask; +volatile bool progressForecast = false; +jma::forecast_callback callbackOnForecast; +jma::progress_callback callbackOnProgress; +PROGMEM const char JMA_FORECAST_URI_FORMAT[] = "https://www.jma.go.jp/bosai/forecast/data/forecast/%06d.json"; + +// DigiCert Global Root CA of www.jma.go.jp. +// Exxpire at Mon, 10 Nov 2031 00:00:00 GMT. +PROGMEM const char root_ca_JMA[] = + R"***(-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= + -----END CERTIFICATE----- +)***"; + +// Cities from which data is obtained. +PROGMEM const jma::officecode_t requestTable[] = +{ + 16000, // Sapporo + 40000, // Sendai + 130000, // Tokyo + 150000, // Niigata + 170000, // Kanazawa + 230000, // Nagoya + 270000, // Oosaka + 340000, // Hiroshima + 390000, // Kochi + 400000, // Fukuoka + 471000, // Okinawa +}; + +void end() +{ + JMAHandler dummy; + callbackOnForecast(0 /* End */ , dummy._forecast, dummy._weeklyForecast); +} + +void jma_forecast_task(void*) +{ + for(;;) + { + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + + // Connect WiFi + int8_t ctry = 3; + do + { + WiFi.mode(WIFI_STA); + WiFi.begin(); + int tcount = 20; + while(tcount-- > 0 && WiFi.status() != WL_CONNECTED) + { + delay(500); + } + if(WiFi.status() == WL_CONNECTED) { break; } + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); + WB2_LOGD("Retry begin"); + delay(10); + }while(ctry--); + + if(WiFi.status() != WL_CONNECTED) + { + WB2_LOGE("Failed to connect WiFi"); + progressForecast = false; + end(); + continue; + } + + // Get each JSON. + for(uint8_t index = 0; index < gob::size(requestTable); ++index) + { + char url[128]; + snprintf(url, sizeof(url), JMA_FORECAST_URI_FORMAT, requestTable[index]); + url[sizeof(url) - 1] = '\0'; + + WB2_LOGI("Connect to [%s]", url); + + HTTPClient http; + WiFiClientSecure client; + client.setCACert(root_ca_JMA); + do + { + int8_t gtry = 3; + int httpcode = 0; + // https GET + do + { + if(!http.begin(client, url)) + { + WB2_LOGE("Failed to begin"); + continue; + } + httpcode = http.GET(); + if(httpcode >= 0) { break; } + + // HTTPClient internal error, to retry. + WB2_LOGE("%s", http.errorToString(httpcode).c_str()); + client.stop(); + http.end(); + delay(100); + }while(gtry--); + + if(httpcode != HTTP_CODE_OK) + { + WB2_LOGD("Failed to GET() %d", httpcode); + break; + } + + // parse JSON + JMAHandler handler; + goblib::json::StreamingParser parser(&handler); + while(client.available()) { parser.parse(client.read()); } + + if(callbackOnForecast) { callbackOnForecast(requestTable[index], handler._forecast, handler._weeklyForecast); } + }while(0); + + client.stop(); + http.end(); + if(callbackOnProgress) { callbackOnProgress(index + 1, gob::size(requestTable)); } + delay(10); + } + + WB2_LOGD("WiFi disconnect"); + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); + end(); + progressForecast = false; + } +} +// +} + +namespace jma +{ + +bool initializeForecast(const UBaseType_t priority, const BaseType_t core, forecast_callback fc, progress_callback pc) +{ + if(!forecastTask) + { + xTaskCreateUniversal(jma_forecast_task, "forecast_task", 8 * 1024, nullptr, priority, &forecastTask, core); + callbackOnForecast = fc; + callbackOnProgress = pc; + } + return forecastTask != nullptr; +} + +bool busyForecast() +{ + return progressForecast; +} + +// Kick jma_forecast_task +bool requestForecast() +{ + if(busyForecast()) { return false; } + + progressForecast = true; + xTaskNotifyGive(forecastTask); + return true; +} + +// +} diff --git a/src/jma/jma_task.hpp b/src/jma/jma_task.hpp new file mode 100644 index 0000000..affe184 --- /dev/null +++ b/src/jma/jma_task.hpp @@ -0,0 +1,19 @@ + +#ifndef JMA_TASK_HPP +#define JMA_TASK_HPP + +#include "jma_forecast.hpp" + +namespace jma +{ +using forecast_callback = void(*)(const officecode_t oc, const Forecast& fc, const WeeklyForecast& wfc); +using progress_callback = void(*)(const size_t readed, const size_t size); + +bool initializeForecast(const UBaseType_t priority, const BaseType_t core, forecast_callback fc, progress_callback pc); +void finalizeForecast(); + +bool requestForecast(); +bool busyForecast(); + +} +#endif diff --git a/src/main.cpp b/src/main.cpp index 96d7ec3..57fc27c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,35 +8,178 @@ */ #include #include - -#include +#include #include +#include // esp_bt_controller_mem_release +#include // esp_random() is hardware RNG. (No random seed initialization is required) #include -#include -#include -#include "wxbeacon2_ble.hpp" -#include "wxbeacon2_log.hpp" +#include "utility.hpp" #include "aq_talk.hpp" #include "ponko_avatar.hpp" #include "wni_ticker.hpp" +#include "weather_map.hpp" +#include "progress.hpp" +#include "wb2/wxbeacon2_task.hpp" +#include "wb2/wxbeacon2_log.hpp" +#include "jma/jma_task.hpp" +#include +#include "cpu_usage.hpp" + +#include +#include + +#ifdef ARDUINO_M5STACK_Core2 +#include "himawari/himawari.hpp" +#include "himawari/himawari_task.hpp" +#include "himawari/himawari_screen.hpp" +#endif #include #include +#include +#include +#include + +#if __has_include () +#include +#else // esp_idf_version.h has been introduced in Arduino 1.0.5 (ESP-IDF3.3) +#define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) +#define ESP_IDF_VERSION ESP_IDF_VERSION_VAL(3,2,0) +#endif + +using goblib::datetime::LocalTime; +using goblib::datetime::LocalDateTime; +using goblib::datetime::OffsetDateTime; -// Settings namespace { -// Auto talking interval time (Unit:second) -constexpr uint16_t TALKING_INTERVAL_SEC = 60 * 3; -// Measurement interval time (Unit:second) for broadcast mode -constexpr uint16_t MEASUREMENT_INTERVAL_BROADCAST_SEC = 60 * 3; -// turnon LED when got advertise data. -constexpr bool TURNON_LED = false; -} +// Automatic request interval. +#ifdef M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC +# define AUTO_REQUEST_INTERVAL_SEC (M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC) +#else +# define AUTO_REQUEST_INTERVAL_SEC (5 * 60) +#endif -namespace +// Automatic talk interval +#ifdef M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC +# define AUTO_TALK_INTERVAL_SEC (M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC) +#else +# define AUTO_TALK_INTERVAL_SEC (1 * 60) +#endif + +// NTP serve URL +PROGMEM const char ntp0[] = "ntp.nict.jp"; +PROGMEM const char ntp1[] = "ntp.jst.mfeed.ad.jp"; +PROGMEM const char ntp2[] = "time.cloudflare.com"; +const char* ntpURLTable[] = { ntp0, ntp1, ntp2 }; // DON'T USE PROGMEM! (because it will be shuffled later) + +// For configurate time +#ifndef M5S_WXBEACON2_TIMEZONE_LOCATION +#define M5S_WXBEACON2_TIMEZONE_LOCATION "Asia/Tokyo" +#endif + +Avatar* avatar; +Ticker* ticker; +WeatherMap* weatherMap; +#ifdef ARDUINO_M5STACK_Core2 +HimawariScreen* himawariScreen; +#endif +ProgressIcon* progress; +bool forceRender = true; // Force rendering all + +// For task settings. (piority low:0) [Beware of WDT] +constexpr UBaseType_t advertisePriority = 1; +constexpr BaseType_t advertiseCore = 0; // NimBLE task must be core 0. see also https://gitter.im/NimBLE-Arduino/community?source=orgpage + +constexpr UBaseType_t forecastPriority = 1; +constexpr BaseType_t forecastCore = 0; + +constexpr UBaseType_t himawariPriority = 1; +constexpr BaseType_t himawariCore = 0; + +constexpr UBaseType_t aqtalkPriority = 1; +constexpr BaseType_t aqtalkCore = 1; + +constexpr UBaseType_t speakerPriority = 1; +constexpr BaseType_t speakerCore = 0; + +// +bool existsBeacon = false; +WxBeacon2::AdvertiseData advertiseData; +bool updatedAdvertise = false; +M5Timer timer; +int_fast8_t requestTimerId{-1}, talkTimerId{-1}; + +// +struct Weather { + jma::officecode_t oc; + jma::weathercode_t wc; + int8_t lowTemp, highTemp; + + String toString() const + { + char buf[128]; + // low == temp means Iinvalid data.(The lowest highest temperature on the day of the announcement is invalid) + if(lowTemp != highTemp) + { + snprintf(buf, sizeof(buf), "[%s] %s %d℃/%d℃", + jma::officesCodeToString(oc), + jma::weatherCodeToString(wc), + highTemp, lowTemp); + } + else + { + snprintf(buf, sizeof(buf), "[%s] %s", + jma::officesCodeToString(oc), + jma::weatherCodeToString(wc)); + } + buf[sizeof(buf)-1] = '\0'; + return String(buf); + } + String toColorString() const + { + char buf[128]; + // low == temp means Iinvalid data.(The lowest highest temperature on the day of the announcement is invalid) + if(lowTemp != highTemp) + { + snprintf(buf, sizeof(buf), "#@1[%s] %s #@2%d℃#@3%d℃",// @"#n" Palette NO of text for ticker. + jma::officesCodeToString(oc), + jma::weatherCodeToString(wc), + highTemp, lowTemp); + } + else + { + snprintf(buf, sizeof(buf), "#@1[%s] %s", + jma::officesCodeToString(oc), + jma::weatherCodeToString(wc)); + } + buf[sizeof(buf)-1] = '\0'; + return String(buf); + } +}; +std::map > forecast; +OffsetDateTime requestForecastDatetime; +bool updatedForecast = false; + +// +#ifdef ARDUINO_M5STACK_Core2 +const uint8_t* himawariImage = nullptr; +himawari::Band himawariBand; +OffsetDateTime himawariDatetime; +bool updatedHimawari = false; +#endif + +// Ticker text +PROGMEM const char DEFAULT_TICKER_TITLE[] = "Ponko"; +PROGMEM const char DEFAULT_TICKER_TEXT[] = "WEATHEROID Type A Airi "; +PROGMEM const char NOTICE_TICKER_TEXT[] = "Press and hold C to put the WxBeacon2 into the broadcast mode. "; +PROGMEM const char NOT_EXISTS_BEACON_TICKER_TEXT[] = "WxBeacon2 IS NOT EXISTS. "; +PROGMEM const char REQUEST_TICKER_TITLE[] = "Request..."; +PROGMEM const char REQUEST_ADV_TICKER_TEXT[] = "Waiting receive Advertise. "; +PROGMEM const char REQUEST_FORECAST_TICKER_TEXT[] = "Waiting receive forecast. "; + // Get std::string that formatted with args. #if 0 template std::string formatString(const char* fmt, Args... args) @@ -44,7 +187,7 @@ template std::string formatString(const char* fmt, Args... arg size_t sz = snprintf(nullptr, 0U, fmt, args...); // calculate length char buf[sz + 1]; snprintf(buf, sizeof(buf), fmt, args...); - return std::string(buf, buf + sz + 1); + return std::string(buf, buf + sz); } #else std::string formatString(const char* fmt, ...) @@ -56,219 +199,106 @@ std::string formatString(const char* fmt, ...) char buf[sz + 1]; vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - return std::string(buf, buf + sz + 1); + return std::string(buf, buf + sz); } #endif -// NTP serve URL -const char* ntpURL[] = -{ - "ntp.nict.jp", - "ntp.jst.mfeed.ad.jp", - "time.cloudflare.com", -}; - -// For configurate time -#ifdef M5S_WXBEACON2_GMT_OFFSET_HOUR -long gmtOffsetSec = 3600 * M5S_WXBEACON2_GMT_OFFSET_HOUR; -#else -long gmtOffsetSec = 3600 * 9; // JST(GMT+9) as default. -#endif - -#ifdef M5S_WXBEACON2_DAYLIGHT_OFFSET_SEC -long daylightOffsetSec = M5S_WXBEACON2_DAYLIGHT_OFFSET_SEC; -#else -long daylightOffsetSec = 0; // 0 as default -#endif - -#ifdef M5S_WXBEACON2_WIFI_HOST_NAME -#define G_STRINGFY_(s) #s -#define G_STRINGFY(s) G_STRINGFY_(s) -const char* WIFI_HOST_NAME = G_STRINGFY(M5S_WXBEACON2_WIFI_HOST_NAME); -#else -const char* WIFI_HOST_NAME = nullptr; -#endif - -// Client -WxBeacon2Client* wb2Client = nullptr; -NimBLEAddress wb2address; // detected wxbeacon2 address - -/* - WxBeacon2Client with scoped - Call disconnect on destruct. -*/ -struct ScopedWB2Client +struct ESP32RNG { - ScopedWB2Client(WxBeacon2Client& client) : _client(client) {} - ~ScopedWB2Client() { _client.disconnect(); } - WxBeacon2Client& client() { return _client; } - private: - WxBeacon2Client& _client; + using result_type = uint32_t; + static result_type min() { return 0; } + static result_type max() { return gob::size(ntpURLTable); } + result_type operator()() { return esp_random() % max(); } }; -/* - Change broadcast mode - @warning Changing to broadcast mode will not work with the WNI application. - @warning If you want to link with the WNI application, call the changeDefaultSetting function. - @warning If the beacon mode is changed, all data stored in WxBeacon2 will be lost. - */ -bool changeBeaconMode() +// Configurate Time by NTP. +void configTime() { - if(!wb2Client) { WB2_LOGE("Client null"); return false; } - if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } - - ScopedWB2Client wb2(*wb2Client); - - WB2_LOGI("connect to : %s", wb2address.toString().c_str()); - if(!wb2.client().isConnected() && !wb2.client().connect(wb2address)) + // WiFi connect + WiFi.begin(); // Connect to credential in Hardware. (ESP32 saves the last WiFi connection) + int tcount = 20; + while(tcount-- > 0 && WiFi.status() != WL_CONNECTED) { - WB2_LOGE("Failed to connect"); - return false; + M5.Display.printf("."); + delay(500); } - - WxBeacon2::ADVSetting setting; - if(!wb2.client().getADVSetting(setting)) + if(WiFi.status() != WL_CONNECTED) { - WB2_LOGE("Failed ti get setting"); - return false; + WB2_LOGE("Failed to connect WiFi"); + abort(); } - setting._beaconMode = (uint8_t)WxBeacon2::BeaconMode::GeneralBroadcaster2; + std::shuffle(std::begin(ntpURLTable), std::end(ntpURLTable), ESP32RNG()); + auto ptz = goblib::datetime::locationToPOSIX(M5S_WXBEACON2_TIMEZONE_LOCATION); + WB2_LOGI("tz:[%s] [%s] [%s] [%s]", ptz ? ptz : "NONE", ntpURLTable[0], ntpURLTable[1], ntpURLTable[2]); - if(wb2.client().setADVSetting(setting)) + configTzTime(ptz ? ptz : "", ntpURLTable[0], ntpURLTable[1], ntpURLTable[2]); + // waiting for time synchronization { - return wb2.client().setMeasurementInterval(MEASUREMENT_INTERVAL_BROADCAST_SEC); + std::tm discard{}; + getLocalTime(&discard, 10 * 1000); } - return false; + WiFi.disconnect(true); + WiFi.mode(WIFI_OFF); } -/* - Change default mode (for WNI Application) - @warning If the beacon mode is changed, all data stored in WxBeacon2 will be lost. - */ -bool changeDefaultSetting() +// +bool canRequest() { - if(!wb2Client) { WB2_LOGE("Client null"); return false; } - if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } - - ScopedWB2Client wb2(*wb2Client); - - WB2_LOGI("connect to : %s", wb2address.toString().c_str()); - if(!wb2.client().isConnected() && !wb2.client().connect(wb2address)) - { - WB2_LOGE("Failed to connect"); - return false; - } - - // Need set interval and time inforamtion, - if(wb2.client().setADVSetting(WxBeacon2::ADVSetting::DEFAULT_SETTING)) - { - delay(500); - std::tm t; - getLocalTime(&t); - if(wb2.client().setTimeInformation(t)) - { - delay(500); - return wb2.client().setMeasurementInterval(WxBeacon2::MeasurementInterval::DEFAULT_VALUE); - } - } - return false; +#ifdef ARDUINO_M5STACK_Core2 + return !himawari::busy() && !updatedHimawari && +#else + return +#endif + !busyAdvertise() && !updatedAdvertise && + !jma::busyForecast() && !updatedForecast; } -/* turnon LED 1 second */ -bool turnOnLED() +// -------------------------------- +// Request advertise +void _requestAdvertise() { - if(!wb2Client) { WB2_LOGE("Client null"); return false; } - if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } - - ScopedWB2Client wb2(*wb2Client); - - WB2_LOGI("connect to : %s", wb2address.toString().c_str()); - if(!wb2.client().isConnected() && !wb2.client().connect(wb2address)) + if(canRequest()) { - WB2_LOGE("Failed to connect"); - return false; + requestAdvertise(); + ticker->setTitle(REQUEST_TICKER_TITLE); } - return wb2.client().setLED(1); -} - -// -TaskHandle_t advertiseTask; -WxBeacon2::AdvertiseData advertiseData; -volatile bool updatedAdvertise = false; -volatile bool advertiseBusy = false; -time_t lastUpdate = -1; - -// Task of get advertise data from WxBeacon2. -void wb2_advertise_task(void*) -{ - NimBLEScan* scan = NimBLEDevice::getScan(); - WxBeacon2AdvertiseCallbacks cb; - scan->setAdvertisedDeviceCallbacks(&cb); - scan->setInterval(1000); - scan->setWindow(900); - scan->setActiveScan(true); - - for(;;) + else { - ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); - - cb.clear(); - - WB2_LOGI("Start scanning"); - scan->start(60, false); - while(scan->isScanning()) { delay(100); } - WB2_LOGI("End of scanning. detected :%d", cb.detected()); - - if(cb.detected()) - { - wb2address = cb.address(); - advertiseData = cb.data(); - lastUpdate = time(nullptr); - if(TURNON_LED) { turnOnLED(); } - } - updatedAdvertise = cb.detected(); - advertiseBusy = false; - scan->clearResults(); + WB2_LOGI("Busy"); } } -// Kick adverstise_task -void getAdvertiseAsync() +// Callback on get advertise. +void callbackOnAdvertise(const bool exists, const WxBeacon2::AdvertiseData& ad) { - if(!advertiseBusy) - { - advertiseBusy = true; - updatedAdvertise = false; - xTaskNotifyGive(advertiseTask); - } + existsBeacon = exists; + updatedAdvertise = true; + advertiseData = ad; } -// Getting comms? -bool busyAdvertise() { return advertiseBusy; } - -// -Avatar* avatar; -Ticker* ticker; -bool forceFace = true; // Force rendering of the face. - -// play voice +// Play advertise void playAdvertiseData(const WxBeacon2::AdvertiseData& data) { - if(data.format() != WxBeacon2::ADVFormat::E) - { - WB2_LOGE("Illegal format"); - return; - } + forceRender = true; + avatar->closeup(); + weatherMap->hide(); +#ifdef ARDUINO_M5STACK_Core2 + himawariScreen->hide(); +#endif + ticker->setTitle("WxBeacon2"); + aq_talk::stopAquesTalk(); + auto de = data.getE(); - if(!de) + if(!existsBeacon || data.format() != WxBeacon2::ADVFormat::E || !de) { - WB2_LOGE("Failed to get E"); + ticker->setText(existsBeacon ? NOTICE_TICKER_TEXT : NOT_EXISTS_BEACON_TICKER_TEXT); + ticker->setColor(Ticker::Color::Purple); return; } - auto s = formatString("kion do." - "situdo pa-sento." + auto vs = formatString("kion do." + "situdo pa-sento." "akarusa rukkusu." "yu-bui ." "kiatu hekutopasukaru." @@ -276,7 +306,7 @@ void playAdvertiseData(const WxBeacon2::AdvertiseData& data) "fukaisisu- ." "neccyu-syoukikendo " "desu." - , + , (float)de->temperature(), (float)de->relativeHumidity(), (int)de->ambientLight(), @@ -286,11 +316,10 @@ void playAdvertiseData(const WxBeacon2::AdvertiseData& data) (float)de->discomfortIndex(), (float)de->heatstroke() ); + aq_talk::playAquesTalk(vs.c_str(), 120); - WB2_LOGV("PLAY:[%s]", s.c_str()); - aq_talk::playAquesTalk(s.c_str(), 110); - - auto ts = formatString("TEMP %3.1fdegC HUM %3.1f%% AL %dlx UV %3.1f PRESURE %4.1fhPa N %3.1fdB DCMFT %3.1f WBGT %3.1f ", + // auto ts = formatString("TEMP %3.1fdegC HUM %3.1f%% AL %dlx UV %3.1f PRESURE %4.1fhPa N %3.1fdB DCMFT %3.1f WBGT %3.1f ", + auto ts = formatString("#@1気温:#@2%3.1f#@1℃ 湿度#@2:%3.1f#@1%% 明度:#@2%d#@1lx UV指数:#@2%3.1f #@1気圧:#@2%4.1f#@1hPa 騒音:#@2%3.1f#@1dB 不快指数:#@2%3.1f #@1WBGT:#@2%3.1f ", (float)de->temperature(), (float)de->relativeHumidity(), (int)de->ambientLight(), @@ -300,113 +329,307 @@ void playAdvertiseData(const WxBeacon2::AdvertiseData& data) (float)de->discomfortIndex(), (float)de->heatstroke() ); - WB2_LOGV("TICKER:[%s]", s.c_str()); + ticker->setLevelWBGT(de->heatstroke()); // Set telop color. ticker->setText(ts.c_str()); } -constexpr char DEFAULT_TICKER_TEXT[] = "WEATHEROID Type A Airi"; -constexpr char NOTICE_TICKER_TEXT[] = "Press and hold C to put the WxBeacon2 into the broadcast mode. "; - -#if 0 -bool test_connect() +// -------------------------------- +// Request forecast +void _requestForecast() { - if(!wb2Client) { WB2_LOGE("Client null"); return false; } - if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } - - ScopedWB2Client wb2(*wb2Client); + if(canRequest()) + { +#if 0 + // TEST + forecast.clear(); + OffsetDateTime odt = OffsetDateTime::now(); + requestForecastDatetime = odt; + const jma::officecode_t requestTable[] = + { + 16000, // Sapporo + 40000, // Sendai + 130000, // Tokyo + 150000, // Niigata + 170000, // Kanazawa + 230000, // Nagoya + 270000, // Oosaka + 340000, // Hiroshima + 390000, // Kochi + 400000, // Fukuoka + 471000, // Okinawa + }; + + auto& wv = forecast[odt]; + jma::weathercode_t wc = 200; + for(auto& e : requestTable) + { + wv.push_back({e, wc++, -12, 38}); + } + updatedForecast = true; + return; +#endif - WB2_LOGI("connect to : %s", wb2address.toString().c_str()); - if(!wb2.client().isConnected() && !wb2.client().connect(wb2address)) + forecast.clear(); + auto odt = OffsetDateTime::now(); + if(odt.toLocalTime() > LocalTime(17, 0, 0)) + { + auto ldt = odt.toLocalDateTime(); + auto epoch = ldt.toEpochSecond(odt.offset()) + 86400; // next day + ldt = LocalDateTime::ofEpochSecond(epoch, odt.offset()); + odt = OffsetDateTime::of(ldt, odt.offset()); + } + requestForecastDatetime = odt; + WB2_LOGI("request forecast:%s", odt.toString().c_str()); + + jma::requestForecast(); + progress->initRatio(); + progress->showProgress(); + + ticker->setTitle(REQUEST_TICKER_TITLE); + } + else { - WB2_LOGE("Failed to connect"); - return false; + WB2_LOGI("Busy"); } +} - std::string str; - auto b = wb2.client().getDeviceName(str); - printf("%d DeviceName:%s\n", b, str.c_str()); - - WxBeacon2::GenericAccesssService::Appearance app; - b = wb2.client().getAppearance(app); - printf("%d Appearnce:%x\n", b, app._category); - - WxBeacon2::GenericAccesssService::PeripheralPreferredConnectionParameters params; - b = wb2.client().getPeripheralPreferredConnectionParameters(params); - printf("%d params:%x/%x/%x/%x\n", b, - params._intervalMin, params._intervalMax, params._slaveLatency, params._timeout); - - b = wb2.client().getModelNumber(str); - printf("%d ModelNumber:[%s]\n", b, str.c_str()); - b = wb2.client().getSerialNumber(str); - printf("%d SerialNumber:[%s]\n", b, str.c_str()); - b = wb2.client().getFirmwareRevision(str); - printf("%d FirmRev:[%s]\n", b, str.c_str()); - b = wb2.client().getHardwareRevision(str); - printf("%d HardRev:[%s]\n", b, str.c_str()); - b = wb2.client().getManufacturerName(str); - printf("%d ManufacturerName:[%s]\n", b, str.c_str()); - - return true; +// Callback on progess +void callbackOnProgressForecast(const size_t readed, const size_t size) +{ + float ratio = (float)readed / size; + progress->setRatio(ratio); } -bool test_getLatestPageData() +// Callback on get forecast. +void callbackOnForecast(const jma::officecode_t oc, const jma::Forecast& fc, const jma::WeeklyForecast& wfc) { - if(advertiseData.format() == WxBeacon2::ADVFormat::E) { WB2_LOGE("Not recording mode"); return false; } - - if(!wb2Client) { WB2_LOGE("Client null"); return false; } - if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } + if(oc == 0) + { + progress->hideProgress(); + updatedForecast = true; + return; + } - ScopedWB2Client wb2(*wb2Client); + if(fc.existsTopWeatherCodes() && fc.existsTopTemp()) + { + auto& wcodes = fc.TopWeatherCodes(); + auto& timedef = fc.TopWeatherTime(); + auto& temps = fc.TopTemp(); + auto& timedefTemps = fc.TopTempTime(); + assert(wcodes.size() == timedef.size()); + assert(temps.size() == timedefTemps.size()); + + WB2_LOGV("wcodes:%zu temps:%zu", wcodes.size(), temps.size()); + + for(uint8_t i = 0; i < wcodes.size(); ++i) + { + Weather weather { oc, wcodes[i], 0, 0 }; + + auto odt = timedef[i]; + auto& v = forecast[odt]; // create if empty. + + auto it = std::find_if(timedefTemps.begin(), timedefTemps.end(), + [&odt](const OffsetDateTime& odtTemps) + { + return odt.toLocalDate() == odtTemps.toLocalDate(); + }); + auto idx = std::distance(timedefTemps.begin(), it); + // Store low/high temps if exists. + if(idx < timedefTemps.size()) + { + weather.lowTemp = temps[idx]; + weather.highTemp = temps[idx+1]; + } + v.push_back(weather); + WB2_LOGV("%s:%u:%u %d/%d", odt.toString().c_str(), weather.oc, weather.wc, weather.lowTemp, weather.highTemp); + } + } + else + { + WB2_LOGD("Failed %d/%d",fc.existsTopWeatherCodes(),fc.existsTopTemp()); + } +} - WB2_LOGI("connect to : %s", wb2address.toString().c_str()); - if(!wb2.client().isConnected() && !wb2.client().connect(wb2address)) +// Play forecast +void playForecast() +{ + forceRender = true; +#ifdef ARDUINO_M5STACK_Core2 + himawariScreen->hide(); +#endif + avatar->wipe(72, 32, 0.30f); + weatherMap->setDatetime(requestForecastDatetime); + + if(forecast.empty()) { - WB2_LOGE("Failed to connect"); - return false; + avatar->closeup(); + weatherMap->hide(); + ticker->setTitle("ERROR"); + ticker->setColor(Ticker::Color::Purple); + ticker->setText(DEFAULT_TICKER_TEXT); + return; } - WxBeacon2::LatestPage lpage; - if(!wb2.client().getLatestPage(lpage)) { WB2_LOGE("Failed to get latest page"); return false; } - printf("Latest: %d,%d\n", lpage._page, lpage._row); + String ts; + ts.reserve(256); + auto vs = formatString("no/tenki'o/osirase'simasu ", + requestForecastDatetime.month(), requestForecastDatetime.day()); - int retryCount = 3; - WxBeacon2::ResponseFlag flag = { 2 }; - do + weatherMap->clearIcon(); + for(auto& e : forecast) // each date-time { - if(!wb2.client().requestPage(lpage._page, lpage._row)) { continue; } // request - for(;;) // get response flag + WB2_LOGV("%s:[%s] %zu", requestForecastDatetime.toString().c_str(), e.first.toString().c_str(), e.second.size()); + + if(e.first.toLocalDate() != requestForecastDatetime.toLocalDate()) { continue; } // Skip data. + + auto wv = e.second; + std::sort(wv.begin(), wv.end(), [](const Weather& a, const Weather& b) { return a.oc < b.oc; }); // Ascend officecode_t + for(auto& w : wv) { - wb2.client().getResponseFlag(flag); - if((int)flag._updateFlag != 0) { break; } - delay(10); + ts += w.toColorString() + ' '; + vs += formatString("%s %s #", aq_talk::officeCodeToTalk(w.oc), aq_talk::weatherCodeToTalk(w.wc)); + + weatherMap->addIcon(w.oc, w.wc); } - }while((int)flag._updateFlag == 2 && retryCount--); - if((int)flag._updateFlag != 1) { WB2_LOGE("Failed to request or get response"); return false; } + ts += " "; + } + aq_talk::playAquesTalk(vs.c_str(), 120); + + ticker->setTitle("Weather"); + ticker->setText(ts.c_str()); + ticker->setColor(Ticker::Color::Green); + weatherMap->show(); +} - int cnt = lpage._row + 1; - while(cnt--) +// -------------------------------- +#ifdef ARDUINO_M5STACK_Core2 +// Request himawari image +void _requestHimawari() +{ + if(canRequest()) { - WxBeacon2::ResponseData data; - if(!wb2.client().getResponseData(data)) { WB2_LOGE("Failed to get response data"); return false; } - time_t t = flag._time32 + lpage._interval * data._data._row; - auto lt = std::localtime(&t); - printf("DATA: row:%02d time:%4d/%02d/%02d %02d:%02d:%02d\n", - data._data._row, - lt->tm_year + 1900, - lt->tm_mon + 1, - lt->tm_mday, - lt->tm_hour, - lt->tm_min, - lt->tm_sec); +#if 0 + himawari::request(OffsetDateTime::now(), + (himawari::Area)(esp_random() % gob::to_underlying(himawari::Area::Max)), + (himawari::Band)(esp_random() % gob::to_underlying(himawari::Band::Max)) + ); +#else + himawari::request(OffsetDateTime::now(), + himawari::Area::Japan, + (himawari::Band)(esp_random() % gob::to_underlying(himawari::Band::Max)) + ); +#endif + progress->initRatio(); + progress->showProgress(); + progress->setRatio(0.0f); + ticker->setTitle(REQUEST_TICKER_TITLE); + } + else + { + WB2_LOGD("busy"); } - return true; +} + +// Callback on progress +void callbackOnProgressHimawari(const size_t readed, const size_t size) +{ + float ratio = (float)readed / size; + progress->setRatio(ratio); +} + +// Callback on get himawwri image. +void callbackOnHimawariImage(const uint8_t* ptr, const himawari::Band band, const OffsetDateTime& odt) +{ + progress->hideProgress(); + himawariImage = ptr; + himawariBand = band; + himawariDatetime = odt; + updatedHimawari = true; +} + +PROGMEM static const char talkHimawari[] = "kisyou'eisei'himawarino 'gazouo 'gorannkudasai"; + +// Draw himawari image +void drawHimawari() +{ + forceRender = true; + weatherMap->hide(); + himawariScreen->set(himawariDatetime, himawariImage); + + if(!himawariImage) + { + himawariScreen->hide(); + avatar->closeup(); + ticker->setTitle("ERROR"); + ticker->setColor(Ticker::Color::Purple); + ticker->setText(DEFAULT_TICKER_TEXT); + return; + } + aq_talk::playAquesTalk(talkHimawari, 120); + himawariScreen->show(); + avatar->wipe(204, 152 , 0.25f); + ticker->setTitle("Satellite"); + String ts = himawari::bandToString(himawariBand) + " "; + ticker->setText(ts.c_str()); + ticker->setColor(Ticker::Color::Green); } #endif + +PROGMEM static const char t0[] = "minnasa--n,ponnbanwa,weza-roido'taipuei,airi'desu"; +PROGMEM static const char t1[] = "konsyu-no/saikaiwa,'kaniza"; +PROGMEM static const char t2[] = "weza-roido'una'na-i wa arimasen"; +const char* talkTable[] = { t0, t1, t2 }; +void talkRandom() +{ + if(!aq_talk::busy()) + { + auto idx = esp_random() % gob::size(talkTable); + aq_talk::playAquesTalk(talkTable[idx], 110); + } +} + +// -------------------------------- +// Callback on End of aqtalk. +void callbackOnEndAqTalk() +{ + timer.restartTimer(talkTimerId); + WB2_LOGV("restart talkRandom timer"); +} + +// -------------------------------- +// Timer +void timerCallbackRequest() +{ + if(canRequest()) + { +#ifdef ARDUINO_M5STACK_Core2 + _requestHimawari(); +#else + _requestAdvertise(); +#endif + return; + } + // Retry + requestTimerId = timer.setTimeout(1000 /*ms*/, timerCallbackRequest); + WB2_LOGI("Retry timercallback %d", requestTimerId); +} + +void resetRequestTimer() +{ + timer.deleteTimer(requestTimerId); + requestTimerId = timer.setTimeout(M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC * 1000 /*ms*/, timerCallbackRequest); + WB2_LOGV("Reset request timer %d", requestTimerId); +} + // } +// Setup void setup() { + WB2_LOGI("Top of setup free:%u internal:%u", esp_get_free_heap_size(), esp_get_free_internal_heap_size()); + WB2_LOGI("PSRAM:size:%u free:%u", ESP.getPsramSize(), ESP.getFreePsram()); + // log level esp_log_level_set("wifi", (esp_log_level_t)0); esp_log_level_set("NimBLE", (esp_log_level_t)0); @@ -414,228 +637,234 @@ void setup() esp_log_level_set("NimBLEDevice", (esp_log_level_t)0); esp_log_level_set("NIMBLE_NVS", (esp_log_level_t)0); + // Incrase internal heap. + esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); + // - M5.begin(); + M5.begin(); auto bd = M5.getBoard(); - WB2_LOGV("board : %x", bd); // 2:M5Stack Basic/Gray 3:Core2 - + WB2_LOGI("M5.board : %x", bd); // 2:M5Stack Basic/Gray 3:Core2 + if (M5.Display.width() < M5.Display.height()) + { + M5.Display.setRotation(M5.Display.getRotation() ^ 1); + } auto scfg = M5.Speaker.config(); - scfg.task_priority = 2; - scfg.task_pinned_core = 0; + scfg.task_priority = speakerPriority; + scfg.task_pinned_core = speakerCore; M5.Speaker.config(scfg); M5.Speaker.begin(); +#ifdef NDEBUG M5.Speaker.setVolume(bd == m5::board_t::board_M5Stack ? 128 : 64); +#else + M5.Speaker.setVolume(bd == m5::board_t::board_M5Stack ? 80 : 40); +#endif + delay(500); - - if (M5.Display.width() < M5.Display.height()) - { - M5.Display.setRotation(M5.Display.getRotation() ^ 1); - } - M5.Display.setBrightness(30); + M5.Display.setBrightness(40); M5.Display.clear(); - M5.Display.fillScreen(TFT_DARKGREY); - M5.Display.setCursor(0,0); - M5.Display.printf("Wifi Connect"); - if(WIFI_HOST_NAME && WIFI_HOST_NAME[0]) - { - WiFi.setHostname(WIFI_HOST_NAME); - } - - // WiFi connect - WiFi.begin(); // Connect to credential in Hardware. (ESP32 saves the last Wifi connection) - int tcount = 10; - while(tcount-- > 0 && WiFi.status() != WL_CONNECTED) - { - delay(500); - M5.Display.printf("."); - } - if(WiFi.status() != WL_CONNECTED) - { - WB2_LOGE("Failed to connect WiFi"); - abort(); - } - - // Configurate local time. - M5.Display.setCursor(0,0); - M5.Display.printf("Configurate time"); - - configTime(gmtOffsetSec, daylightOffsetSec, ntpURL[0]); - std::tm t; - if(getLocalTime(&t)) - { - WB2_LOGI("Configurate time : %4d/%02d/%02d (%d) %02d:%02d:%02d", - t.tm_year + 1900, - t.tm_mon + 1, - t.tm_mday, - t.tm_wday, - t.tm_hour, - t.tm_min, - t.tm_sec); - } - WiFi.disconnect(true); - WiFi.mode(WIFI_OFF); - - M5.Display.fillScreen(TFT_DARKGREEN); - - // BLE - NimBLEDevice::init(""); - xTaskCreateUniversal(wb2_advertise_task, "advertise_task", 8192, nullptr, 1, &advertiseTask, 1); - assert(advertiseTask); - - // get advertise from WxBeacon2 - auto ret = aq_talk::setup(); - WB2_LOGD("aq_talk::setup : %d", ret); + // Avatar,Ticker and WeatherMap avatar = new Avatar(); assert(avatar); - ticker = new Ticker(); assert(ticker); + ticker->setTitle(DEFAULT_TICKER_TITLE); ticker->setText(DEFAULT_TICKER_TEXT); + weatherMap = new WeatherMap(); + assert(weatherMap); +#ifdef ARDUINO_M5STACK_Core2 + himawariScreen = new HimawariScreen(); + assert(himawariScreen); +#endif + progress = new ProgressIcon(); + assert(progress); + + // ConfigTime + configTime(); + M5.Display.fillScreen(TFT_DARKGREEN); - wb2Client = new WxBeacon2Client(); - assert(wb2Client); + // WxBeacon2 / Forecast / Himawari + initilizeAdvertise(advertisePriority, advertiseCore, callbackOnAdvertise); + jma::initializeForecast(forecastPriority, forecastCore, callbackOnForecast, callbackOnProgressForecast); +#ifdef ARDUINO_M5STACK_Core2 + himawari::initialize(himawariPriority, himawariCore, callbackOnHimawariImage, callbackOnProgressHimawari); +#endif - getAdvertiseAsync(); - while(busyAdvertise()) { delay(100); } - if(!updatedAdvertise) - { - WB2_LOGE("Not detected WxBeacon2"); - abort(); - } - if(updatedAdvertise && advertiseData.format() != WxBeacon2::ADVFormat::E) + // AquesTalk + auto ret = aq_talk::initialize(aqtalkPriority, aqtalkCore, callbackOnEndAqTalk); + WB2_LOGD("aq_talk::setup : %d", ret); + + // { - WB2_LOGE("WxBeacon2 beacon mode is not broadcast2"); - ticker->setLevel(Ticker::Level::Purple); - ticker->setText(NOTICE_TICKER_TEXT); - + goblib::datetime::LocalDateTime ldt = goblib::datetime::LocalDateTime::now(); + WB2_LOGI("Configurated time : %s (%s)", ldt.toString().c_str(), M5S_WXBEACON2_TIMEZONE_LOCATION); + WB2_LOGI("End of setup free:%u internal:%u large:%u large internal:%u", + esp_get_free_heap_size(), esp_get_free_internal_heap_size(), + heap_caps_get_largest_free_block(MALLOC_CAP_DMA), + heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL)); + WB2_LOGI("PSRAM:size:%u free:%u", ESP.getPsramSize(), ESP.getFreePsram()); + WB2_LOGI("ESP-IDF Version %d.%d.%d", + (ESP_IDF_VERSION>>16) & 0xFF, (ESP_IDF_VERSION>>8)&0xFF, ESP_IDF_VERSION & 0xFF); + WB2_LOGI("gob_datetime Version %s", GOBLIB_DATETIME_VERSION_STRING); + WB2_LOGI("gob_json Version %s", GOB_JSON_VERSION_STRING); } - - auto mem = esp_get_free_heap_size(); - WB2_LOGV("end of setup %u", mem); -} + M5.Display.startWrite(); // Occupy DMA Bus -namespace -{ - bool longPressA, longPressB,longPressC; + cpu_usage::initialize(); + + // Get advertise from WxBeacon2. + _requestAdvertise(); + + // Timer callback + requestTimerId = timer.setTimeout(M5S_WXBEACON2_AUTO_REQUEST_INTERVAL_SEC * 1000 /*ms*/, timerCallbackRequest); + talkTimerId = timer.setInterval(M5S_WXBEACON2_AUTO_TALK_INTERVAL_SEC * 1000 /*ms*/, talkRandom); + + // Setting for hold time(ms) + M5.BtnA.setHoldThresh(1500); + M5.BtnB.setHoldThresh(1500); + M5.BtnC.setHoldThresh(1500); } +// Main loop void loop() { + auto start = millis(); M5.update(); - // WARNING : If the beacon mode is changed, all data stored in WxBeacon2 will be lost. - /* - C button - long press : Set beacon mode to GeneralBroadcaster2 (for me) - press : show/hide ticker - */ - if(!longPressC && M5.BtnC.pressedFor(1000)) + if(canRequest()) { - longPressC = true; - WB2_LOGI("Set beacon mode to broadcast mode"); - auto b = changeBeaconMode(); - if(b) + // WARNING : If the beacon mode is changed, all data stored in WxBeacon2 will be lost. + // WARNING : After the mode change, Abort system. + /* + C button + long press : Set beacon mode to GeneralBroadcaster2 for this application. + click : show/hide ticker + */ + if(M5.BtnC.wasHold()) { - ticker->setLevel(Ticker::Level::Blue); - ticker->setText(DEFAULT_TICKER_TEXT); - ticker->show(true); - getAdvertiseAsync(); + WB2_LOGI("Set beacon mode to broadcast mode"); + auto b = changeBeaconMode(); + WB2_LOGI("Result : %d", b); + abort(); } - WB2_LOGI("result : %d", b); - } - if(M5.BtnC.wasReleased()) - { - if(!longPressC) + else if(M5.BtnC.wasClicked()) { ticker->show(!ticker->isShow()); - forceFace = true; + forceRender = true; } - longPressC = false; - } - - /* - B button - long press : Set default setting for WNI aplication. - press : (none) - */ - if(!longPressB && M5.BtnB.pressedFor(1000)) - { - longPressB = true; - WB2_LOGI("Set default settins"); - aq_talk::stopAquesTalk(); - auto b = changeDefaultSetting(); - if(b) + /* + B button + long press : Set default setting for WNI aplication. + click : (none) + */ + if(M5.BtnB.wasHold()) { - ticker->setLevel(Ticker::Level::Purple); - ticker->setText(NOTICE_TICKER_TEXT); - ticker->show(true); + WB2_LOGI("Set default settings"); + aq_talk::stopAquesTalk(); + auto b = changeDefaultSetting(); + WB2_LOGI("Result : %d", b); + abort(); } - WB2_LOGI("result : %d", b); - } - if(M5.BtnB.wasReleased()) - { - if(!longPressB) + else if(M5.BtnB.wasClicked()) { - // test_connect(); - // test_getLatestPageData(); - #if 0 - // TEST - auto lv = ticker->level() + 1; - if(lv > 3) { lv = 0; } - ticker->setLevel((Ticker::Level)lv); - #endif + /* Nop */ } - longPressB = false; - } - - /* - A button - long press : (none) - press : Obtain data force. - */ - if(!longPressA && M5.BtnA.pressedFor(1000)) - { - longPressA = true; - } - if(M5.BtnA.wasReleased()) - { - if(!longPressA) + /* + A button + long press : Obtain forecast force. + click : Obtain beacon data force. + */ + if(M5.BtnA.wasHold()) { - if(!busyAdvertise()) - { - aq_talk::stopAquesTalk(); - getAdvertiseAsync(); - } + _requestForecast(); + } + else if(M5.BtnA.wasClicked()) + { + _requestAdvertise(); } - longPressA = false; - } - - // Obtain data at intervals. - time_t t = time(nullptr); - if(!busyAdvertise() && lastUpdate > 0 && std::difftime(t, lastUpdate) >= TALKING_INTERVAL_SEC) - { - getAdvertiseAsync(); } + time_t now{}; + std::time(&now); + // Play latest advertise data if exists. if(updatedAdvertise) { + resetRequestTimer(); updatedAdvertise = false; playAdvertiseData(advertiseData); - auto de = advertiseData.getE(); - if(de) { ticker->setLevelWBGT(de->heatstroke()); } } - // + // Play latest forecast + if(updatedForecast) + { + resetRequestTimer(); + updatedForecast = false; + playForecast(); + } + + // Draw himawari image +#ifdef ARDUINO_M5STACK_Core2 + if(updatedHimawari) + { + resetRequestTimer(); + updatedHimawari = false; + drawHimawari(); + } +#endif + + // Update avatar->pump(); ticker->pump(); +#ifdef ARDUINO_M5STACK_Core2 + progress->pump(busyAdvertise(), (jma::busyForecast() || himawari::busy())); +#else + progress->pump(busyAdvertise(), jma::busyForecast()); +#endif - M5.Display.startWrite(); // Occupy DMA Bus - avatar->render(&M5.Display, forceFace); forceFace = false; - ticker->render(&M5.Display); - M5.Display.endWrite(); // Do render to display + // Rendering + { + weatherMap->render(&M5.Display, forceRender); +#ifdef ARDUINO_M5STACK_Core2 + himawariScreen->render(&M5.Display, forceRender); +#endif + avatar->render(&M5.Display, forceRender); + ticker->render(&M5.Display); + progress->render(&M5.Display); + forceRender = false; + +#if !defined(NDEBUG) && defined(M5S_WXBEACON2_DEBUG_INFO) + M5.Display.setCursor(128, 120); +# ifdef ARDUINO_M5STACK_Core2 + M5.Display.printf("a:%d f:%d h:%d aq:%d s:%d", + busyAdvertise(), jma::busyForecast(), himawari::busy(), + aq_talk::busy(), M5.Speaker.isPlaying()); +# else + M5.Display.printf("a:%d f:%d aq:%d s:%d", + busyAdvertise(), jma::busyForecast(), aq_talk::busy(), M5.Speaker.isPlaying()); +# endif + M5.Display.setCursor(128, 128); + M5.Display.printf("ih:%06u ilf:%06u", + esp_get_free_internal_heap_size(), + heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL)); + M5.Display.setCursor(128, 136); + M5.Display.printf("c0:%03.1f c1:%03.1f", cpu_usage::cpu0(), cpu_usage::cpu1()); + M5.Display.setCursor(128, 144); + M5.Display.printf("tmR:%02d tmT:%02d tmA:%02d", requestTimerId, talkTimerId, timer.getNumAvailableTimers()); + + cpu_usage::reset(); +#endif + } - delay(1000/30); // Keep about 30 FPS + timer.run(); + + // Keep about 30 FPS. + auto end = millis(); +#ifdef M5S_WXBEACON2_DEBUG_INFO + if((end - start) > (1000/30)) + { + WB2_LOGD("over:%lu", (end - start) - (1000/30)); + } +#endif + delay((end - start) >= (1000/30) ? 1 : (1000/30) - (end -start)); } - diff --git a/src/ponko_avatar.cpp b/src/ponko_avatar.cpp index 127b7c8..e8c12ff 100644 --- a/src/ponko_avatar.cpp +++ b/src/ponko_avatar.cpp @@ -4,50 +4,46 @@ #include "ponko_avatar.hpp" #include "aq_talk.hpp" #include "res/resource.h" +#include "wb2/wxbeacon2_log.hpp" #include +namespace +{ +void drawFace(m5gfx::M5GFX* dst, int16_t x, int16_t y, float zoom = 1.0f) +{ + dst->drawBmp(ponko_face_bmp, -1, x, y, 0, 0, 0, 0, zoom, zoom); +} + +// +} Avatar::Avatar() - : _face(nullptr) - , _offMouth(nullptr) + : _offMouth(nullptr) , _mouth{nullptr,nullptr} , _mouthRatio(0) , _lastMouthRatio(0) + , _wipe(false) + , _wipeX(0) + , _wipeY(0) { - _face = new gob::Sprite(); - assert(_face && "_face is nullptr"); - _face->createFromBmp(ponko_face_bmp, ponko_face_bmp_len); - + // close auto mc = new LGFX_Sprite(); assert(mc && "mc is nullptr"); mc->createFromBmp(ponko_mouth_close_bmp, ponko_mouth_close_bmp_len); - _mouth[Close] = mc; - + mc->setPivot(mc->width() * 0.5f + 0.5f, 0); // center,top + _mouth[Close] = mc; + + // open auto mo = new LGFX_Sprite(); assert(mo && "mo is nullptr"); mo->createFromBmp(ponko_mouth_open_bmp, ponko_mouth_open_bmp_len); - mo->setPivot(mo->width()/2, 0); - + mo->setPivot(mo->width() * 0.5f + 0.5f, 0); // center,top _mouth[Open] = mo; // offscreen for mouth _offMouth= new LGFX_Sprite(); assert(_offMouth && "_offMouth is nullptr"); - _offMouth->createFromBmp(ponko_mouth_open_bmp, ponko_mouth_open_bmp_len); // same as mouth open/close bitmap palette and width/height - - // check - assert(mc->width() == mo->width() && "different widths"); - assert(mc->height() == mo->height() && "different heights"); - assert(_offMouth->width() == mo->width() && "different widths"); - assert(_offMouth->height() == mo->height() && "different heights"); - - assert(_face->getPaletteCount() == 16 && "not 4bpp"); - assert(mc->getPaletteCount() == 16 && "not 4bpp"); - assert(mo->getPaletteCount() == 16 && "not 4bpp"); - assert(_offMouth->getPaletteCount() == 16 && "not 4bpp"); - - assert(memcmp(_face->getPalette(), mc->getPalette(), sizeof(RGBColor) * 16) == 0 && "diffrent palettes"); - assert(memcmp(mc->getPalette(), mo->getPalette(), sizeof(RGBColor) * 16) == 0 && "diffrent palettes"); - assert(memcmp(mo->getPalette(), _offMouth->getPalette(), sizeof(RGBColor) * 16) == 0 && "diffrent palettes"); + _offMouth->createFromBmp(ponko_mouth_open_bmp, ponko_mouth_open_bmp_len); // same as open + _offMouth->setPivot(_offMouth->width() * 0.5f + 0.5f, _offMouth->height() * 0.5f + 0.5f); // center } Avatar::~Avatar() @@ -55,7 +51,6 @@ Avatar::~Avatar() delete _offMouth; delete _mouth[Open]; delete _mouth[Close]; - delete _face; } void Avatar::pump() @@ -67,7 +62,6 @@ void Avatar::pump() } auto gain = aq_talk::getGain(); - float f = gain / 12000.0f; float ratio = std::min(1.0f, _lastMouthRatio + f / 2.0f); @@ -75,12 +69,12 @@ void Avatar::pump() _mouthRatio = ratio; } -void Avatar::render(m5gfx::M5GFX* dst, bool forceFace) +void Avatar::renderCloseup(m5gfx::M5GFX* dst, bool force) { - if(forceFace) { _face->pushSprite(dst, 0, 0); } - - _offMouth->clear(); - _face->pushPartial(_offMouth, 0, 0, MOUTH_WIDTH, MOUTH_HEIGHT, MOUTH_X, MOUTH_Y); + if(force) { drawFace(dst, 0, 0); } + + _offMouth->drawBmp(ponko_face_bmp, -1, 0, 0, _offMouth->width(), _offMouth->height(), MOUTH_X, MOUTH_Y); + if(_mouthRatio != 0.0f) { auto s = _mouth[Open]; @@ -98,3 +92,33 @@ void Avatar::render(m5gfx::M5GFX* dst, bool forceFace) } _offMouth->pushSprite(dst, MOUTH_X, MOUTH_Y); } + +void Avatar::renderWipe(m5gfx::M5GFX* dst, bool force) +{ + if(force) + { + drawFace(dst, _wipeX, _wipeY, _wipeScale); + dst->drawRect(_wipeX, _wipeY, 320 * _wipeScale, 240 * _wipeScale, TFT_WHITE); + } + + _offMouth->drawBmp(ponko_face_bmp, -1, 0, 0, _offMouth->width(), _offMouth->height(), MOUTH_X, MOUTH_Y); + if(_mouthRatio != 0.0f) + { + auto s = _mouth[Open]; + s->pushRotateZoom(_offMouth, + 0 + s->width() * (s->getPivotX() / s->width()), + 0 + s->height() * (s->getPivotY() / s->height()), + 0.0f, 1.0f, _mouthRatio, + 0); + + } + else + { + auto s = _mouth[Close]; + s->pushSprite(_offMouth, 0, 0, 0); + } + _offMouth->pushRotateZoom(dst, + _wipeX + MOUTH_X * _wipeScale + _offMouth->getPivotX() * _wipeScale, + _wipeY + MOUTH_Y * _wipeScale + _offMouth->getPivotY() * _wipeScale, + 0.0f, _wipeScale, _wipeScale, 0); +} diff --git a/src/ponko_avatar.hpp b/src/ponko_avatar.hpp index b0f582d..3165971 100644 --- a/src/ponko_avatar.hpp +++ b/src/ponko_avatar.hpp @@ -4,28 +4,50 @@ #ifndef PONKO_AVATAR_HPP #define PONKO_AVATAR_HPP +/* + Ponko avatar + */ #include -#include "gob_sprite.hpp" +#include"jma/jma_definition.hpp" +#include +#include class Avatar { public: + struct IconInfo { jma::officecode_t oc; jma::weathercode_t wc; }; + Avatar(); virtual ~Avatar(); void pump(); - void render(m5gfx::M5GFX* dst, bool forceFace = false); + void render(m5gfx::M5GFX* dst, const bool force = false) + { + _wipe ? renderWipe(dst, force) : renderCloseup(dst, force); + } + // Change rendering type. + void closeup() { _wipe = false; } + void wipe(const int16_t x, const int16_t y, const float scale) + { + _wipe = true; _wipeX = x; _wipeY = y; _wipeScale = scale; + } + constexpr static int16_t MOUTH_X = 136; - constexpr static int16_t MOUTH_Y = 168; + constexpr static int16_t MOUTH_Y = 168; constexpr static int16_t MOUTH_WIDTH = 48; constexpr static int16_t MOUTH_HEIGHT = 32; private: - enum {Close, Open, Max }; - gob::Sprite* _face; - LGFX_Sprite* _offMouth; - LGFX_Sprite* _mouth[Max]; - float _mouthRatio, _lastMouthRatio; + void renderCloseup(m5gfx::M5GFX* dst, bool forceRender = false); + void renderWipe(m5gfx::M5GFX* dst, bool forceRender = false); + + enum : uint8_t {Close, Open, Max }; + LGFX_Sprite* _offMouth{}; + LGFX_Sprite* _mouth[Max]{}; + float _mouthRatio{}, _lastMouthRatio{}; + bool _wipe{}; + float _wipeScale{}; + int16_t _wipeX{}, _wipeY{}; }; #endif diff --git a/src/progress.cpp b/src/progress.cpp new file mode 100644 index 0000000..4aa8eff --- /dev/null +++ b/src/progress.cpp @@ -0,0 +1,69 @@ +/* + Icon indicating access to WiFi or BT in progress. + Progress bar for download. + */ + +#include "progress.hpp" +#include "res/resource.h" + +namespace +{ +#if 0 +constexpr int16_t ICON_X = 284; +constexpr int16_t ICON_Y = 160; +#else +constexpr int16_t ICON_X = 4; +constexpr int16_t ICON_Y = 160; +#endif + +inline int32_t roundTrip(const int32_t c) +{ + // return ( (c & 256) + ( (c & 255) ^ (0 - ((c >> 8) & 1)) ) ); + //return ( (c & 128) + ( (c & 127) ^ (0 - ((c >> 7) & 1)) ) ); + return ( (c & 32) + ( (c & 31) ^ (0 - ((c >> 5) & 1)) ) ); +} + +#if 0 +constexpr int16_t PROGRESS_X = 4; +#else +constexpr int16_t PROGRESS_X = 40; +#endif +constexpr int16_t PROGRESS_Y = 180; +constexpr int16_t PROGRESS_WIDTH = 80; +constexpr int16_t PROGRESS_HEIGHT = 8; +constexpr uint16_t PROGRESS_BG_CLR = TFT_BLACK; +constexpr uint16_t PROGRESS_FG_CLR = TFT_SKYBLUE; +// +} + +ProgressIcon::ProgressIcon() +{ + _btSprite = new LGFX_Sprite(); + assert(_btSprite); + _btSprite->createFromBmp(bt_bmp, bt_bmp_len); + + _wifiSprite = new LGFX_Sprite(); + assert(_wifiSprite); + _wifiSprite->createFromBmp(wifi_bmp, wifi_bmp_len); +} + +void ProgressIcon::render(m5gfx::M5GFX* dst) +{ + auto v = roundTrip(_cnt); + _btSprite->setPaletteColor (1, v * 8, v * 8, v * 8); + _wifiSprite->setPaletteColor(1, v * 8, v * 8, v * 8); + + if(_bt) { _btSprite->pushSprite(dst, ICON_X, ICON_Y, 0); } + if(_wifi) { _wifiSprite->pushSprite(dst, ICON_X, ICON_Y, 0); } + + if(_showProgress && _ratio != _prevRatio) + { + _prevRatio = _ratio; + int16_t wid = _ratio >= 100.0f ? PROGRESS_WIDTH - 2 : (PROGRESS_WIDTH - 2)* _ratio; + dst->drawRect(PROGRESS_X, PROGRESS_Y, PROGRESS_WIDTH, PROGRESS_HEIGHT, TFT_WHITE); + dst->fillRect(PROGRESS_X + 1, PROGRESS_Y + 1, + wid, PROGRESS_HEIGHT - 2, PROGRESS_FG_CLR); + dst->fillRect(PROGRESS_X + 1 + wid, PROGRESS_Y + 1, + PROGRESS_WIDTH - 2 - wid, PROGRESS_HEIGHT - 2, PROGRESS_BG_CLR); + } +} diff --git a/src/progress.hpp b/src/progress.hpp new file mode 100644 index 0000000..5dc9eea --- /dev/null +++ b/src/progress.hpp @@ -0,0 +1,34 @@ +/* + Icon indicating access to WiFi or BT in progress. + Progress bar for download. + */ +#ifndef PROGRESS_HPP +#define PROGRESS_HPP + +#include + +class ProgressIcon +{ + public: + ProgressIcon(); + + inline void pump(const bool bt, const bool wifi) { _bt = bt; _wifi = wifi; ++_cnt; } + + inline void showProgress() { showProgress(true); } + inline void hideProgress() { showProgress(false); } + inline void showProgress(const bool b) { _showProgress = b; } + + inline void initRatio() { _ratio = 0.0f; _prevRatio = -1.0f; } + inline void setRatio(const float ratio) { _ratio = ratio; } + + void render(m5gfx::M5GFX* dst); + + private: + bool _bt{}, _wifi{}, _showProgress{}; + uint16_t _cnt{}; + float _ratio{}, _prevRatio{}; + LGFX_Sprite* _btSprite{}; + LGFX_Sprite* _wifiSprite{}; + +}; +#endif diff --git a/src/res/bt.cpp b/src/res/bt.cpp new file mode 100644 index 0000000..a8957f0 --- /dev/null +++ b/src/res/bt.cpp @@ -0,0 +1,23 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t bt_bmp[] = { + 0x42, 0x4d, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, + 0xf0, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x61, + 0xce, 0x00, 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x79, 0xce, 0x00, 0x00, 0x3d, + 0xfc, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x07, + 0xf0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, + 0xf0, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x3d, + 0xfc, 0x00, 0x00, 0x79, 0xce, 0x00, 0x00, 0xf1, 0xcf, 0x00, 0x00, 0x61, + 0xce, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x01, + 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const size_t bt_bmp_len = 190; diff --git a/src/res/dummy_face.cpp b/src/res/dummy_face.cpp new file mode 100644 index 0000000..1508a09 --- /dev/null +++ b/src/res/dummy_face.cpp @@ -0,0 +1,3217 @@ + +#include "resource.h" +#include + +extern PROGMEM const uint8_t ponko_face_bmp[] __attribute__((weak)) = { + 0x42, 0x4d, 0x76, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x55, 0x55, 0x00, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 +}; +extern const size_t ponko_face_bmp_len __attribute__((weak)) = 38518; diff --git a/src/res/dummy_logo.cpp b/src/res/dummy_logo.cpp new file mode 100644 index 0000000..5c2a729 --- /dev/null +++ b/src/res/dummy_logo.cpp @@ -0,0 +1,29 @@ + +#include "resource.h" +#include + +extern PROGMEM const uint8_t logo_bmp[] __attribute__((weak)) = { + 0x42, 0x4d, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, + 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x42, 0x47, + 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x03, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x3f, + 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xf0, 0x7f, 0xff, + 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf0, 0x71, 0xe2, 0x08, 0x08, 0x71, 0xe2, + 0x08, 0x00, 0x31, 0xe3, 0xc8, 0x00, 0x31, 0xe3, 0xcf, 0xf0, 0x31, 0x22, + 0x0f, 0xf0, 0x31, 0x22, 0x0f, 0xf0, 0x11, 0x22, 0x7f, 0xc0, 0x11, 0x22, + 0x7c, 0x00, 0x11, 0x22, 0x0c, 0x04, 0x11, 0x22, 0x08, 0x7c, 0x01, 0x23, + 0xf8, 0xfe, 0x01, 0x23, 0xf8, 0xfe, 0x00, 0x03, 0xf8, 0xfe, 0x00, 0x03, + 0xf8, 0x03, 0x00, 0x03, 0xf8, 0x03, 0x01, 0xe3, 0xfc, 0x03, 0x07, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xe0, 0x03, 0xff, + 0xfe, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x01, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +extern const size_t logo_bmp_len __attribute__((weak)) = 258; diff --git a/src/res/dummy_mc.cpp b/src/res/dummy_mc.cpp new file mode 100644 index 0000000..5a87219 --- /dev/null +++ b/src/res/dummy_mc.cpp @@ -0,0 +1,81 @@ + +#include "resource.h" +#include + +extern PROGMEM const uint8_t ponko_mouth_close_bmp[] __attribute__((weak)) = { + 0x42, 0x4d, 0x76, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x55, 0x55, 0x00, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 +}; +extern const size_t ponko_mouth_close_bmp_len __attribute__((weak)) = 886; diff --git a/src/res/dummy_mo.cpp b/src/res/dummy_mo.cpp new file mode 100644 index 0000000..0ba83b9 --- /dev/null +++ b/src/res/dummy_mo.cpp @@ -0,0 +1,81 @@ + +#include "resource.h" +#include + +extern PROGMEM const uint8_t ponko_mouth_open_bmp[] __attribute__((weak)) = { + 0x42, 0x4d, 0x76, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0x55, 0x55, 0x00, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, + 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x34, 0x34, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x00, 0x44, + 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x00, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 +}; +extern const size_t ponko_mouth_open_bmp_len __attribute__((weak)) = 886; diff --git a/src/res/jpmap.cpp b/src/res/jpmap.cpp new file mode 100644 index 0000000..7a3ce9e --- /dev/null +++ b/src/res/jpmap.cpp @@ -0,0 +1,213 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t jpmap_bmp[] = { + 0x42, 0x4d, 0x9e, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x78, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x88, 0x10, 0x00, 0xa0, 0x50, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xf8, + 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x03, 0xff +}; +const size_t jpmap_bmp_len = 2462; diff --git a/src/res/resource.h b/src/res/resource.h index 04e23ff..2f49949 100644 --- a/src/res/resource.h +++ b/src/res/resource.h @@ -1,23 +1,127 @@ -#ifndef RESOURCE_HPP -#define RESOURCE_HPP +#ifndef RESOURCE_H +#define RESOURCE_H +#include #include #include /* WARNING : face, close, and open image must have the same palettes, and palette index 0 must be a transparent color. */ -// face 4bpp +// face 4bpp bmp3 extern const uint8_t ponko_face_bmp[]; extern const size_t ponko_face_bmp_len; -// mouth(close) 4bpp +// mouth(close) 4bpp bmp3 extern const uint8_t ponko_mouth_close_bmp[]; extern const size_t ponko_mouth_close_bmp_len; -// mouth(open)4bpp +// mouth(open) 4bpp bmp3 extern const uint8_t ponko_mouth_open_bmp[]; extern const size_t ponko_mouth_open_bmp_len; -// WARNING : 1bpp palette 0 is background, 1 is foreground +// 1bpp bmp3 palette 0 is background, 1 is foreground extern const uint8_t logo_bmp[]; extern const size_t logo_bmp_len; +extern const uint8_t jpmap_bmp[]; +extern const size_t jpmap_bmp_len; + +// 1bpp WifI/BT icon +extern const uint8_t wifi_bmp[]; +extern const size_t wifi_bmp_len; +extern const uint8_t bt_bmp[]; +extern const size_t bt_bmp_len; + +// Text font +extern const lgfx::U8g2font titleFont; +extern const lgfx::U8g2font tickerFont; + +// Weather icon 2bpp png +extern const uint8_t w100_png[]; +extern const size_t w100_png_len; + +extern const uint8_t w101_png[]; +extern const size_t w101_png_len; + +extern const uint8_t w102_png[]; +extern const size_t w102_png_len; + +extern const uint8_t w104_png[]; +extern const size_t w104_png_len; + +extern const uint8_t w110_png[]; +extern const size_t w110_png_len; + +extern const uint8_t w112_png[]; +extern const size_t w112_png_len; + +extern const uint8_t w115_png[]; +extern const size_t w115_png_len; + +extern const uint8_t w200_png[]; +extern const size_t w200_png_len; + +extern const uint8_t w201_png[]; +extern const size_t w201_png_len; + +extern const uint8_t w202_png[]; +extern const size_t w202_png_len; + +extern const uint8_t w204_png[]; +extern const size_t w204_png_len; + +extern const uint8_t w210_png[]; +extern const size_t w210_png_len; + +extern const uint8_t w212_png[]; +extern const size_t w212_png_len; + +extern const uint8_t w215_png[]; +extern const size_t w215_png_len; + +extern const uint8_t w300_png[]; +extern const size_t w300_png_len; + +extern const uint8_t w301_png[]; +extern const size_t w301_png_len; + +extern const uint8_t w302_png[]; +extern const size_t w302_png_len; + +extern const uint8_t w303_png[]; +extern const size_t w303_png_len; + +extern const uint8_t w308_png[]; +extern const size_t w308_png_len; + +extern const uint8_t w311_png[]; +extern const size_t w311_png_len; + +extern const uint8_t w313_png[]; +extern const size_t w313_png_len; + +extern const uint8_t w314_png[]; +extern const size_t w314_png_len; + +extern const uint8_t w400_png[]; +extern const size_t w400_png_len; + +extern const uint8_t w401_png[]; +extern const size_t w401_png_len; + +extern const uint8_t w402_png[]; +extern const size_t w402_png_len; + +extern const uint8_t w403_png[]; +extern const size_t w403_png_len; + +extern const uint8_t w406_png[]; +extern const size_t w406_png_len; + +extern const uint8_t w411_png[]; +extern const size_t w411_png_len; + +extern const uint8_t w413_png[]; +extern const size_t w413_png_len; + +extern const uint8_t w414_png[]; +extern const size_t w414_png_len; #endif diff --git a/src/u8g2_font_profont22_tr.cpp b/src/res/u8g2_font_profont22_tr.cpp similarity index 98% rename from src/u8g2_font_profont22_tr.cpp rename to src/res/u8g2_font_profont22_tr.cpp index d2b6bcc..e1bdbe4 100644 --- a/src/u8g2_font_profont22_tr.cpp +++ b/src/res/u8g2_font_profont22_tr.cpp @@ -21,8 +21,9 @@ THE SOFTWARE. */ #include "u8g2_font_profont22_tr.h" +#include -const uint8_t u8g2_font_profont22_tr[1704] = +PROGMEM const uint8_t u8g2_font_profont22_tr[1704] = "`\0\4\4\4\5\4\5\5\14\26\0\374\16\374\20\376\2N\4\177\6\213 \5\0\20r!\11\342\30" "rxP\210\0\42\11fTs\20BO\4#\25\252\220r\221H\210\220\7E$\22\42\344A\21\211" "\204\10\1$$*\321q\22(\314\14\212\21\42\212\10!\42h\204\250C\247D\14\22BDH\11\21" diff --git a/src/u8g2_font_profont22_tr.h b/src/res/u8g2_font_profont22_tr.h similarity index 100% rename from src/u8g2_font_profont22_tr.h rename to src/res/u8g2_font_profont22_tr.h diff --git a/src/res/w100.cpp b/src/res/w100.cpp new file mode 100644 index 0000000..c7b06f0 --- /dev/null +++ b/src/res/w100.cpp @@ -0,0 +1,40 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w100_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x03, 0x00, 0x00, 0x00, 0xa1, 0x9d, 0x6d, 0x77, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0xbf, + 0xb2, 0xb3, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, + 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, 0x54, 0x4b, 0x00, + 0x00, 0x00, 0x48, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, + 0x01, 0xfb, 0xff, 0xff, 0xff, 0x30, 0xd4, 0xff, 0xff, 0xff, 0x0f, 0x4a, + 0xfc, 0xab, 0x07, 0x12, 0xf3, 0x2a, 0x81, 0x44, 0x5f, 0x21, 0x90, 0x38, + 0xfe, 0x18, 0x48, 0xbc, 0x2b, 0x07, 0x12, 0x7f, 0xec, 0x81, 0xc4, 0x0f, + 0x79, 0x20, 0x21, 0xc0, 0x01, 0x23, 0xc0, 0x5c, 0xb0, 0x04, 0x58, 0x09, + 0x58, 0x31, 0x58, 0x1b, 0xd8, 0x00, 0xb0, 0x51, 0x70, 0x93, 0xc1, 0x16, + 0x81, 0x00, 0x00, 0x8b, 0x53, 0x3e, 0x47, 0xdd, 0xc3, 0xf0, 0x13, 0x00, + 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, + 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, + 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, + 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, + 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, + 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w100_png_len = 389; diff --git a/src/res/w101.cpp b/src/res/w101.cpp new file mode 100644 index 0000000..f481977 --- /dev/null +++ b/src/res/w101.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w101_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x16, 0x06, 0x43, 0x85, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x73, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x4d, 0xcf, 0x31, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xd0, 0x6f, 0x02, 0x89, + 0xa3, 0x8b, 0x77, 0x30, 0x9e, 0xc2, 0xae, 0x4c, 0x84, 0xd0, 0xfb, 0x18, + 0x4f, 0xe2, 0x48, 0x38, 0xa5, 0x6d, 0x05, 0xb1, 0xd3, 0x0b, 0x7c, 0x7e, + 0x03, 0xd0, 0xc7, 0xb3, 0x4d, 0xc4, 0xca, 0xa4, 0xc8, 0x3f, 0x78, 0xca, + 0xab, 0x61, 0xe2, 0xf8, 0x82, 0x28, 0xb6, 0x0c, 0x5a, 0xc6, 0x2c, 0xb3, + 0x2c, 0x70, 0xae, 0xd6, 0x32, 0xa0, 0x57, 0xd9, 0x20, 0xe1, 0x54, 0xaf, + 0xa2, 0xcf, 0x29, 0x55, 0x14, 0x2d, 0x3c, 0x52, 0xc1, 0xa6, 0x2b, 0x62, + 0x30, 0xc8, 0xd2, 0x70, 0x77, 0x9c, 0x98, 0x05, 0xcc, 0x3b, 0x1a, 0x36, + 0x8c, 0x13, 0x2d, 0x64, 0x29, 0x96, 0x66, 0xff, 0xe2, 0xfe, 0x7e, 0xf3, + 0x00, 0x45, 0x3c, 0x2f, 0x60, 0xa0, 0xa0, 0x5f, 0x89, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, + 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, + 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, + 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, + 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, + 0x42, 0x60, 0x82 +}; +const size_t w101_png_len = 435; diff --git a/src/res/w102.cpp b/src/res/w102.cpp new file mode 100644 index 0000000..5d9b93c --- /dev/null +++ b/src/res/w102.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w102_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0x00, + 0x55, 0xff, 0x4a, 0xcc, 0xc3, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x73, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x4d, 0xcf, 0x3b, 0x0a, 0x80, 0x30, 0x10, 0x04, 0xd0, 0x11, 0x0c, 0x58, + 0xda, 0x78, 0x87, 0xe0, 0x29, 0xdc, 0xd6, 0x4a, 0x42, 0x72, 0x1f, 0xb1, + 0xf4, 0x14, 0x62, 0x15, 0xf6, 0x94, 0x66, 0xc7, 0xf8, 0x99, 0xea, 0xb1, + 0xd9, 0x0f, 0x01, 0x9e, 0xb8, 0xc4, 0x2c, 0x18, 0x92, 0x18, 0xe2, 0x0f, + 0x4e, 0x96, 0x1b, 0x4d, 0x9a, 0x6e, 0x88, 0x48, 0xed, 0x41, 0xed, 0xa1, + 0x4b, 0xfa, 0x1e, 0x6d, 0xab, 0x9a, 0x3f, 0xd8, 0x53, 0xd4, 0x2d, 0xb3, + 0x39, 0x28, 0x32, 0xc7, 0x43, 0x86, 0xe7, 0xc2, 0xb0, 0x1a, 0xca, 0x89, + 0x19, 0xe8, 0x78, 0x74, 0x66, 0xc5, 0xc0, 0xf1, 0xb2, 0x7f, 0xdc, 0x7d, + 0xc5, 0x5b, 0xf1, 0x27, 0x11, 0xd5, 0xe0, 0x0c, 0xaa, 0xc7, 0xfb, 0x9b, + 0x0b, 0xa6, 0xd2, 0x32, 0x7d, 0xd5, 0x85, 0xde, 0x44, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, + 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, + 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, + 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, + 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, + 0x42, 0x60, 0x82 +}; +const size_t w102_png_len = 435; diff --git a/src/res/w104.cpp b/src/res/w104.cpp new file mode 100644 index 0000000..239668b --- /dev/null +++ b/src/res/w104.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w104_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0xaa, + 0xaa, 0xff, 0x0d, 0x07, 0xe6, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xcf, 0x3d, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xe0, 0x6a, 0x60, 0x71, + 0x62, 0xf1, 0x12, 0x9e, 0xc2, 0xae, 0x4c, 0xc4, 0xd0, 0xfb, 0x78, 0x14, + 0xc6, 0xa6, 0xa7, 0x94, 0xb6, 0xf8, 0x93, 0xf8, 0xa6, 0x2f, 0xf0, 0x4a, + 0x03, 0xc0, 0x9d, 0x48, 0x96, 0x02, 0x2b, 0xa1, 0xa2, 0x7e, 0x10, 0xb1, + 0x38, 0x26, 0xda, 0x1d, 0x88, 0x38, 0x3a, 0x30, 0x3a, 0xe6, 0x9e, 0x94, + 0x20, 0x04, 0x11, 0x7e, 0xa1, 0x57, 0x95, 0x17, 0xb6, 0xf2, 0xd1, 0x66, + 0xb6, 0x71, 0x47, 0x7f, 0xd0, 0xd1, 0x57, 0x64, 0xef, 0x20, 0x65, 0x3b, + 0x51, 0x9c, 0xa0, 0x20, 0xda, 0xfe, 0xf0, 0x0e, 0x55, 0xd1, 0xa9, 0xa8, + 0x10, 0x69, 0xcf, 0x6f, 0x2e, 0xfc, 0x52, 0x32, 0xf1, 0x86, 0xd6, 0x92, + 0x7d, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, + 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w104_png_len = 427; diff --git a/src/res/w110.cpp b/src/res/w110.cpp new file mode 100644 index 0000000..6548d02 --- /dev/null +++ b/src/res/w110.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w110_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x16, 0x06, 0x43, 0x85, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x67, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x63, 0x60, 0x80, 0x01, 0xd6, 0xd0, 0x50, 0xad, 0x55, 0xab, 0x56, 0x2d, + 0x60, 0x10, 0x85, 0x30, 0x56, 0x80, 0x18, 0x5e, 0x18, 0x8c, 0x20, 0x28, + 0x83, 0x15, 0xca, 0x60, 0x65, 0x65, 0x59, 0xb5, 0x82, 0x09, 0xc8, 0x70, + 0x0c, 0x11, 0x01, 0x6a, 0x06, 0x4b, 0x85, 0x6a, 0x2d, 0x60, 0xd0, 0x60, + 0x10, 0x0d, 0x61, 0x84, 0x30, 0x44, 0x04, 0x18, 0x1c, 0xbd, 0x1a, 0x60, + 0x0c, 0x06, 0xa8, 0x94, 0x06, 0x03, 0x03, 0x07, 0x58, 0xb1, 0x02, 0x98, + 0x01, 0xd4, 0xbe, 0x00, 0xcc, 0x00, 0x1a, 0xb8, 0x02, 0xac, 0x06, 0x6e, + 0x05, 0xc2, 0x52, 0x2c, 0xee, 0x81, 0x38, 0x15, 0xee, 0x78, 0x18, 0x00, + 0x00, 0x96, 0x8b, 0x39, 0x9d, 0x27, 0xed, 0xf7, 0x33, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, + 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, + 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, + 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, + 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, + 0x42, 0x60, 0x82 +}; +const size_t w110_png_len = 423; diff --git a/src/res/w112.cpp b/src/res/w112.cpp new file mode 100644 index 0000000..a2029a3 --- /dev/null +++ b/src/res/w112.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w112_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0x00, + 0x55, 0xff, 0x4a, 0xcc, 0xc3, 0x3a, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0x8e, 0xb1, 0x0d, 0xc0, 0x20, 0x0c, 0x04, 0x1d, 0x29, 0x96, 0x52, + 0xa6, 0x80, 0x1d, 0x22, 0xb6, 0xa0, 0x8b, 0x28, 0x11, 0xde, 0x27, 0x35, + 0x53, 0x50, 0x22, 0x4f, 0x19, 0x1b, 0x87, 0x34, 0x7c, 0x75, 0xd2, 0xbf, + 0xdf, 0x0f, 0x30, 0x85, 0x44, 0x81, 0x99, 0x1b, 0x78, 0x83, 0xae, 0x90, + 0x16, 0xc8, 0x12, 0x51, 0x40, 0x81, 0xe7, 0x02, 0x8f, 0xb8, 0x33, 0x83, + 0x40, 0x2c, 0x4e, 0x12, 0x87, 0x5a, 0x14, 0x9a, 0x42, 0xd9, 0x28, 0x68, + 0xb3, 0x3b, 0x21, 0xde, 0x13, 0x12, 0x68, 0x58, 0x2d, 0x2b, 0x94, 0x70, + 0xad, 0xdf, 0xf9, 0x80, 0x51, 0x68, 0x56, 0xee, 0xa2, 0xf1, 0x74, 0xc2, + 0xba, 0xc7, 0xa6, 0xfe, 0xe3, 0xa7, 0x5e, 0xc7, 0x55, 0x3c, 0x7b, 0x44, + 0x75, 0x3e, 0x6f, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w112_png_len = 429; diff --git a/src/res/w115.cpp b/src/res/w115.cpp new file mode 100644 index 0000000..6ab4d7f --- /dev/null +++ b/src/res/w115.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w115_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x00, 0xaa, + 0xaa, 0xff, 0x0d, 0x07, 0xe6, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0x8e, 0xbb, 0x0d, 0x80, 0x30, 0x0c, 0x44, 0x0d, 0xc2, 0x0d, 0x15, + 0x45, 0xb2, 0x03, 0xca, 0x16, 0x69, 0x53, 0x46, 0xf1, 0x3e, 0x8c, 0x92, + 0x32, 0xf2, 0x94, 0xf8, 0x43, 0x68, 0xc0, 0xd5, 0x93, 0x7d, 0xe7, 0x3b, + 0x80, 0x39, 0x48, 0x94, 0x98, 0xb9, 0x43, 0x74, 0x18, 0x0a, 0xe5, 0x03, + 0x95, 0xc7, 0xae, 0x80, 0x95, 0xfb, 0x2a, 0x80, 0xb8, 0xf1, 0x05, 0x02, + 0xb9, 0x05, 0x07, 0x42, 0x4a, 0x06, 0x6d, 0xa1, 0xa4, 0x9a, 0x70, 0x40, + 0x2e, 0xea, 0x32, 0x30, 0x97, 0x9e, 0x5e, 0x31, 0xc0, 0x29, 0x7f, 0xc4, + 0xae, 0x10, 0xa2, 0x3c, 0xb4, 0x8d, 0x46, 0xb8, 0x86, 0x9e, 0xac, 0xbf, + 0x3e, 0x5e, 0xf5, 0x2d, 0x3f, 0xe7, 0x06, 0xe8, 0x30, 0x3a, 0x7a, 0xb4, + 0x50, 0xcc, 0xb5, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w115_png_len = 429; diff --git a/src/res/w200.cpp b/src/res/w200.cpp new file mode 100644 index 0000000..33e9e8b --- /dev/null +++ b/src/res/w200.cpp @@ -0,0 +1,35 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w200_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x88, 0xb8, 0x49, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x03, 0x33, + 0x84, 0x72, 0x88, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, + 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, 0x54, 0x4b, 0x00, 0x00, + 0x00, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x75, 0xcf, 0xb1, 0x0d, + 0xc0, 0x30, 0x08, 0x04, 0x40, 0xf6, 0x1f, 0x25, 0x14, 0x6c, 0x90, 0xec, + 0xc3, 0x08, 0x14, 0x7e, 0xfb, 0x8d, 0x89, 0x62, 0x4b, 0xf9, 0xea, 0x0a, + 0x5e, 0x80, 0x60, 0x45, 0xe2, 0x9a, 0x31, 0xf1, 0x84, 0xee, 0xb8, 0x17, + 0x14, 0x9e, 0x30, 0x44, 0xe2, 0x41, 0x2b, 0x20, 0x81, 0x5f, 0xd8, 0x80, + 0x13, 0x63, 0x16, 0x41, 0x70, 0x77, 0xfb, 0xc2, 0x36, 0x78, 0x81, 0x75, + 0x65, 0xe9, 0x3c, 0x6c, 0xe2, 0x3d, 0xbe, 0xde, 0xe9, 0xf5, 0x15, 0x9c, + 0x44, 0x62, 0xea, 0x30, 0xbf, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, + 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, + 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, + 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, + 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w200_png_len = 335; diff --git a/src/res/w201.cpp b/src/res/w201.cpp new file mode 100644 index 0000000..08b4b40 --- /dev/null +++ b/src/res/w201.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w201_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xff, + 0xaa, 0x00, 0x34, 0xe7, 0x85, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x72, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0xcf, 0x3d, 0x0a, 0x80, 0x30, 0x0c, 0x05, 0xe0, 0x67, 0x41, 0x90, + 0x4e, 0x22, 0x75, 0x77, 0x2c, 0x3d, 0x85, 0xa3, 0x38, 0x15, 0xa9, 0x97, + 0xf2, 0x14, 0x8e, 0x21, 0xa7, 0x34, 0x89, 0xb4, 0x38, 0x98, 0xe9, 0x23, + 0x3f, 0xaf, 0x14, 0xa8, 0xd5, 0x9f, 0x56, 0x19, 0xf3, 0x8b, 0xf2, 0x45, + 0xae, 0xb0, 0x35, 0x41, 0x41, 0xf7, 0x03, 0xcd, 0x11, 0xa0, 0x30, 0x13, + 0xe6, 0x15, 0x08, 0x06, 0xe9, 0x86, 0x94, 0x22, 0x82, 0x60, 0xf2, 0x31, + 0x62, 0x54, 0x5c, 0x44, 0x86, 0x83, 0x3c, 0xe9, 0xa8, 0xdb, 0x6f, 0x47, + 0xf6, 0xe8, 0xb6, 0xb8, 0xc1, 0xd0, 0x3a, 0x49, 0x77, 0x0c, 0x7a, 0x65, + 0xd0, 0x1c, 0x41, 0x61, 0x4d, 0xee, 0x15, 0xcc, 0x77, 0xfb, 0xcd, 0x03, + 0xea, 0x17, 0x2c, 0x73, 0xaf, 0xc2, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x25, + 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x31, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, 0x00, + 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb5, 0xa7, + 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82 +}; +const size_t w201_png_len = 434; diff --git a/src/res/w202.cpp b/src/res/w202.cpp new file mode 100644 index 0000000..16c4ef7 --- /dev/null +++ b/src/res/w202.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w202_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x00, + 0x55, 0xff, 0x34, 0x59, 0xa3, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0xcf, 0x3d, 0x0a, 0xc0, 0x20, 0x0c, 0x06, 0xd0, 0xcf, 0xa1, 0xd0, + 0xb1, 0x14, 0xbd, 0x83, 0x78, 0x8a, 0xce, 0x4e, 0x52, 0xec, 0x7d, 0xa4, + 0x27, 0x91, 0x4e, 0x92, 0x53, 0x36, 0x89, 0x28, 0x1d, 0x9a, 0xe9, 0x91, + 0x5f, 0x02, 0x8c, 0x70, 0x97, 0x46, 0x1a, 0xc8, 0x5f, 0xa4, 0x01, 0x2c, + 0x1d, 0x19, 0xe6, 0x07, 0xba, 0x27, 0x01, 0x99, 0xa8, 0xc1, 0x1d, 0x03, + 0x9c, 0xb5, 0x84, 0x06, 0xcb, 0xd8, 0x05, 0x9b, 0xa0, 0xc2, 0x2b, 0xce, + 0xc2, 0xe0, 0x92, 0x89, 0x60, 0xc8, 0xd1, 0x58, 0xb8, 0x47, 0xa1, 0xe3, + 0x8c, 0x70, 0xaf, 0xbd, 0x14, 0x66, 0xc6, 0x3f, 0x8a, 0x4c, 0x82, 0x45, + 0x40, 0x54, 0xe7, 0x37, 0x2f, 0x62, 0x62, 0x2e, 0xe1, 0xbc, 0x18, 0x37, + 0x17, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, + 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w202_png_len = 427; diff --git a/src/res/w204.cpp b/src/res/w204.cpp new file mode 100644 index 0000000..5f125f8 --- /dev/null +++ b/src/res/w204.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w204_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xff, 0x73, 0x92, 0x86, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x24, 0xc9, 0x0b, + 0x54, 0x4b, 0x00, 0x00, 0x00, 0x68, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xcf, 0x31, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xd0, 0x8f, 0x09, 0x8b, + 0x93, 0x31, 0x70, 0x09, 0x4f, 0xe1, 0xcc, 0x44, 0x0c, 0xde, 0xc7, 0xa3, + 0x30, 0x36, 0x3d, 0xa5, 0x6d, 0x11, 0x25, 0xb1, 0xd3, 0xcb, 0xe7, 0xd3, + 0xa4, 0x40, 0x1f, 0x7f, 0xda, 0x64, 0xc4, 0x86, 0x32, 0x22, 0x77, 0x58, + 0x28, 0x28, 0xd6, 0x37, 0xb8, 0x0f, 0xba, 0x27, 0x66, 0xa0, 0x30, 0x13, + 0xe2, 0xde, 0x21, 0x69, 0xa0, 0x99, 0x10, 0x04, 0x6b, 0x9d, 0x08, 0xcb, + 0x88, 0x43, 0x21, 0x4f, 0x2e, 0x69, 0x47, 0xf7, 0x27, 0x4d, 0x0c, 0x17, + 0x1a, 0xb6, 0x3f, 0x9e, 0x4e, 0x61, 0xfd, 0xe5, 0x15, 0xcc, 0xf5, 0xbd, + 0xe6, 0x06, 0xe7, 0xee, 0x2f, 0xeb, 0x4a, 0x5c, 0x95, 0x51, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, + 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, + 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, + 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, + 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xb5, 0xa7, 0x05, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, + 0xae, 0x42, 0x60, 0x82 +}; +const size_t w204_png_len = 424; diff --git a/src/res/w210.cpp b/src/res/w210.cpp new file mode 100644 index 0000000..3ed08c9 --- /dev/null +++ b/src/res/w210.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w210_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xff, + 0xaa, 0x00, 0x34, 0xe7, 0x85, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xce, 0x31, 0x0e, 0xc0, 0x20, 0x08, 0x05, 0x50, 0x6a, 0x62, 0xd2, + 0x74, 0xea, 0x50, 0xf6, 0x8e, 0xc4, 0xa3, 0x38, 0x99, 0x46, 0xef, 0xe3, + 0x51, 0x1c, 0x09, 0xa7, 0x2c, 0x4a, 0xac, 0x43, 0x99, 0x5e, 0x04, 0xe4, + 0x03, 0xcc, 0xf2, 0xa5, 0x44, 0x11, 0x69, 0x80, 0x06, 0xee, 0x78, 0x7e, + 0xc8, 0xc2, 0xc1, 0xd0, 0x38, 0xec, 0x0a, 0x28, 0x37, 0x91, 0x22, 0x03, + 0x52, 0x60, 0x02, 0x4c, 0x80, 0xb1, 0x1d, 0x6c, 0xa8, 0x6e, 0xc0, 0xa7, + 0xea, 0x74, 0x06, 0x16, 0xb6, 0xd1, 0xba, 0x3a, 0xfa, 0xf0, 0xa9, 0xad, + 0xb1, 0xae, 0x2f, 0x68, 0x1f, 0xae, 0x13, 0xeb, 0xe8, 0x3f, 0x8f, 0x45, + 0xfd, 0xc2, 0xcf, 0x7a, 0x01, 0x43, 0xd4, 0x37, 0x17, 0x09, 0xcb, 0xf9, + 0x80, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd2, + 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w210_png_len = 427; diff --git a/src/res/w212.cpp b/src/res/w212.cpp new file mode 100644 index 0000000..5d1747b --- /dev/null +++ b/src/res/w212.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w212_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0x00, + 0x55, 0xff, 0x34, 0x59, 0xa3, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xce, 0x31, 0x0a, 0xc0, 0x20, 0x10, 0x04, 0xc0, 0x0d, 0x44, 0x48, + 0x99, 0x42, 0xff, 0x20, 0xfe, 0x22, 0x5d, 0xb0, 0x0a, 0x41, 0xff, 0x93, + 0xda, 0x57, 0x58, 0xca, 0xbd, 0x32, 0xab, 0xa2, 0x10, 0xb2, 0xd5, 0x70, + 0x1c, 0x77, 0x0b, 0x8c, 0xa8, 0x18, 0x9d, 0x88, 0x64, 0x98, 0x8e, 0x52, + 0xe1, 0x7f, 0xb8, 0xb9, 0x52, 0x71, 0x10, 0x8f, 0x25, 0x10, 0x44, 0xb0, + 0xc1, 0x04, 0x68, 0x6e, 0x10, 0x17, 0x8c, 0xcb, 0x3c, 0xd8, 0x80, 0x0e, + 0x75, 0x36, 0xf0, 0x8b, 0x07, 0x6c, 0x83, 0xab, 0x07, 0x35, 0xb0, 0xb8, + 0x94, 0x2c, 0x76, 0x60, 0x95, 0x0a, 0x4e, 0xf4, 0xfc, 0x55, 0x98, 0x0f, + 0xfe, 0x7d, 0x7a, 0xd5, 0x59, 0x7e, 0xe4, 0x05, 0x11, 0x7f, 0x3a, 0x6b, + 0xf2, 0xb5, 0x05, 0x36, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, + 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, + 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x31, 0x2b, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0xd2, 0xeb, 0x91, 0xf9, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w212_png_len = 430; diff --git a/src/res/w215.cpp b/src/res/w215.cpp new file mode 100644 index 0000000..e1ea03f --- /dev/null +++ b/src/res/w215.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w215_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xff, 0x73, 0x92, 0x86, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x69, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0xce, 0x31, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xd0, 0xaf, 0x91, 0xc5, + 0xc9, 0x01, 0xee, 0x60, 0xb8, 0x85, 0x2b, 0x13, 0x21, 0x70, 0x1f, 0x8f, + 0xc2, 0x48, 0x7a, 0x4a, 0x69, 0x2b, 0x2c, 0xda, 0xe9, 0x85, 0x96, 0xfc, + 0x0f, 0x8c, 0x31, 0xa5, 0x78, 0x22, 0xaa, 0x70, 0x8a, 0xc6, 0x08, 0x1f, + 0x24, 0x6a, 0x3b, 0xe3, 0x4a, 0x54, 0x57, 0x06, 0x32, 0xdd, 0xe8, 0xc8, + 0xb0, 0x8a, 0x08, 0xe7, 0x27, 0xe4, 0x26, 0xc2, 0x04, 0xf9, 0xd5, 0x53, + 0x82, 0xac, 0x80, 0xc5, 0x03, 0x27, 0xec, 0xc0, 0x01, 0x6c, 0xf4, 0xbe, + 0x58, 0x81, 0x64, 0xc9, 0x31, 0x43, 0xb3, 0x7e, 0xfa, 0x68, 0xd5, 0x59, + 0x7e, 0xcc, 0x03, 0xeb, 0xc8, 0x37, 0x99, 0x0a, 0x97, 0x6b, 0xcf, 0x00, + 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, + 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, + 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, + 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, + 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, + 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w215_png_len = 425; diff --git a/src/res/w300.cpp b/src/res/w300.cpp new file mode 100644 index 0000000..ed94f8b --- /dev/null +++ b/src/res/w300.cpp @@ -0,0 +1,40 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w300_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x03, 0x00, 0x00, 0x00, 0xa1, 0x9d, 0x6d, 0x77, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xbf, + 0x0c, 0x95, 0xe2, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, + 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, 0x64, 0xdd, 0x00, + 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, + 0x01, 0xfb, 0xff, 0xff, 0xff, 0x30, 0xd4, 0xff, 0xff, 0xff, 0x0f, 0x48, + 0xb4, 0x83, 0x08, 0x66, 0x20, 0xf1, 0x8f, 0x11, 0x48, 0xfc, 0x01, 0x11, + 0x0f, 0x18, 0x80, 0xc4, 0x01, 0x10, 0xd1, 0xc0, 0x50, 0x07, 0x84, 0x0c, + 0x76, 0x0c, 0x35, 0x20, 0x02, 0xc8, 0xaa, 0x83, 0x6a, 0x3b, 0x73, 0x06, + 0x85, 0x00, 0x8b, 0x19, 0x1b, 0xa3, 0x10, 0x20, 0x31, 0xb0, 0x45, 0x20, + 0x00, 0x00, 0xa5, 0x97, 0x36, 0x48, 0x27, 0xcc, 0xec, 0x47, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, + 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, + 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, + 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, + 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, + 0xae, 0x42, 0x60, 0x82 +}; +const size_t w300_png_len = 388; diff --git a/src/res/w301.cpp b/src/res/w301.cpp new file mode 100644 index 0000000..095aa9a --- /dev/null +++ b/src/res/w301.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w301_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xff, + 0xaa, 0x00, 0xba, 0xd7, 0x8f, 0x99, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x72, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x4d, 0xcf, 0x31, 0x0a, 0xc0, 0x20, 0x0c, 0x05, 0xd0, 0x54, 0x10, 0x4a, + 0x67, 0xdd, 0x3b, 0x8a, 0xa7, 0x70, 0x29, 0x94, 0x4e, 0x2a, 0xf6, 0x52, + 0x3d, 0x85, 0xa3, 0xe4, 0x94, 0x35, 0x89, 0x96, 0x06, 0x02, 0x0f, 0x93, + 0x7c, 0x10, 0x60, 0x96, 0xbe, 0xb9, 0x22, 0x58, 0x41, 0xf9, 0x23, 0xea, + 0x81, 0xb0, 0x0c, 0x00, 0x08, 0xc2, 0x44, 0x8f, 0xa0, 0x06, 0x43, 0x8d, + 0xd8, 0x18, 0x85, 0x40, 0x39, 0xc5, 0x7b, 0x07, 0x36, 0x1d, 0x26, 0x6f, + 0x6e, 0xe0, 0x69, 0x32, 0xca, 0x6d, 0xeb, 0x30, 0xe9, 0xb8, 0xaa, 0x12, + 0x9c, 0xbb, 0x5a, 0x79, 0x24, 0x2f, 0x1d, 0x9e, 0x77, 0x08, 0xf3, 0xca, + 0x73, 0x4e, 0x0f, 0x46, 0x4a, 0xd6, 0x04, 0xc4, 0xfa, 0xfd, 0xe6, 0x05, + 0xea, 0x61, 0x2f, 0x91, 0x36, 0xbb, 0x42, 0x8c, 0x00, 0x00, 0x00, 0x25, + 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, + 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, + 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82 +}; +const size_t w301_png_len = 434; diff --git a/src/res/w302.cpp b/src/res/w302.cpp new file mode 100644 index 0000000..af39aad --- /dev/null +++ b/src/res/w302.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w302_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xaa, + 0xaa, 0xaa, 0xe6, 0xa3, 0x29, 0x34, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x4d, 0xcf, 0x3b, 0x0a, 0x80, 0x30, 0x0c, 0x06, 0xe0, 0x5f, 0xb1, 0x20, + 0x4e, 0x0e, 0xe9, 0x1d, 0x8a, 0xa7, 0x70, 0x71, 0x71, 0x6a, 0x4b, 0xbd, + 0x8f, 0x47, 0x71, 0x94, 0x9e, 0x52, 0xf3, 0xf0, 0x91, 0x21, 0x7c, 0x24, + 0xe4, 0x87, 0x00, 0x4f, 0xb9, 0x4d, 0x2a, 0xc2, 0x2b, 0xca, 0x1f, 0xc5, + 0x19, 0x62, 0x63, 0x98, 0xa1, 0x88, 0x30, 0xcc, 0x80, 0xe7, 0x1c, 0x6e, + 0x5d, 0xad, 0x27, 0xc6, 0x07, 0x74, 0x83, 0x18, 0x1c, 0x98, 0xeb, 0x70, + 0x23, 0x2d, 0x94, 0xcf, 0xd6, 0x70, 0x40, 0x57, 0xab, 0x80, 0xd2, 0xb2, + 0xee, 0x1f, 0x82, 0xac, 0x26, 0xa0, 0x17, 0x04, 0x7c, 0x13, 0xb9, 0x2a, + 0x95, 0x93, 0x9d, 0xe2, 0x78, 0xbf, 0xb9, 0x00, 0x33, 0xd2, 0x2f, 0x9e, + 0x1a, 0x44, 0xb8, 0x85, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, + 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, + 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w302_png_len = 430; diff --git a/src/res/w303.cpp b/src/res/w303.cpp new file mode 100644 index 0000000..d77da69 --- /dev/null +++ b/src/res/w303.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w303_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xaa, + 0xaa, 0xff, 0xfd, 0xa2, 0x8c, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x63, 0x60, 0x80, 0x01, 0xd6, 0x50, 0x30, 0x08, 0x60, 0x10, 0x85, 0x30, + 0x42, 0xb0, 0x32, 0x02, 0x58, 0xa1, 0x0c, 0x07, 0x46, 0x28, 0x83, 0x81, + 0x01, 0xc2, 0x70, 0x00, 0x32, 0x40, 0xe6, 0x88, 0x02, 0xb1, 0xc8, 0xaa, + 0x55, 0x2b, 0x18, 0x44, 0x80, 0x0c, 0x16, 0x10, 0x43, 0x00, 0x24, 0xb2, + 0x82, 0x0b, 0x22, 0x12, 0xb4, 0x80, 0x69, 0x05, 0xd8, 0x40, 0x08, 0x23, + 0xd0, 0x55, 0x04, 0xce, 0xf0, 0x02, 0xa9, 0x01, 0x49, 0x79, 0x81, 0x45, + 0x44, 0x02, 0x5d, 0xbd, 0x1a, 0x18, 0x20, 0x0c, 0x2d, 0x30, 0x03, 0x28, + 0x85, 0x60, 0x40, 0xcd, 0x09, 0x59, 0x05, 0xd2, 0xc5, 0x0a, 0x62, 0xac, + 0x5a, 0xb5, 0x00, 0xee, 0x1b, 0x00, 0x7b, 0x80, 0x31, 0x65, 0x50, 0x27, + 0x92, 0xce, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, + 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, + 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, + 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w303_png_len = 428; diff --git a/src/res/w308.cpp b/src/res/w308.cpp new file mode 100644 index 0000000..31bafac --- /dev/null +++ b/src/res/w308.cpp @@ -0,0 +1,40 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w308_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x03, 0x00, 0x00, 0x00, 0xa1, 0x9d, 0x6d, 0x77, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xaa, 0xa4, + 0x0d, 0x30, 0x99, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, + 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xe6, 0x0c, 0x16, 0x09, 0x10, 0x19, 0x9d, 0x33, 0x36, 0x63, 0x00, + 0x00, 0x00, 0x46, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, + 0x01, 0xfb, 0xff, 0xff, 0xff, 0x30, 0xd4, 0xff, 0x3f, 0xff, 0x0f, 0x48, + 0x30, 0x03, 0x89, 0x7f, 0x8c, 0x40, 0xe2, 0x0f, 0x03, 0x90, 0x68, 0x00, + 0x11, 0x0c, 0x0c, 0x76, 0x0c, 0x35, 0x20, 0xa2, 0x8e, 0x01, 0x88, 0xea, + 0xff, 0xff, 0xff, 0x07, 0x25, 0x8c, 0x8d, 0x81, 0x62, 0x69, 0x69, 0x75, + 0x0c, 0x75, 0xef, 0xde, 0xfd, 0x23, 0x46, 0x02, 0x6c, 0x11, 0x08, 0x00, + 0x00, 0x40, 0xd9, 0x37, 0x0a, 0x39, 0xc5, 0x43, 0x25, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, 0x31, 0x35, 0x3a, 0x33, 0x32, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xd9, 0xa1, 0x2f, 0xc7, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, + 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, 0x31, 0x35, 0x3a, 0x33, + 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xa8, 0xfc, 0x97, 0x7b, 0x00, + 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, + 0x31, 0x36, 0x3a, 0x32, 0x35, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x1d, + 0xd3, 0x33, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, + 0x42, 0x60, 0x82 +}; +const size_t w308_png_len = 387; diff --git a/src/res/w311.cpp b/src/res/w311.cpp new file mode 100644 index 0000000..acdaebe --- /dev/null +++ b/src/res/w311.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w311_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xff, + 0xaa, 0x00, 0xba, 0xd7, 0x8f, 0x99, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x77, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0x8e, 0x3b, 0x0e, 0x80, 0x30, 0x0c, 0x43, 0x0d, 0x02, 0x09, 0x31, + 0x31, 0x34, 0x77, 0xa8, 0x72, 0x0a, 0x18, 0x58, 0xd8, 0x40, 0xcd, 0x7d, + 0x38, 0x4a, 0xc7, 0xaa, 0xa7, 0x24, 0xfd, 0x31, 0x80, 0xa7, 0x27, 0xd9, + 0x71, 0x0c, 0x34, 0x8d, 0x22, 0x1c, 0x63, 0xf4, 0xa0, 0x02, 0x21, 0xc1, + 0xf1, 0x85, 0xed, 0x8a, 0x81, 0x13, 0xe0, 0xf2, 0x81, 0x27, 0x90, 0x83, + 0xf1, 0xd6, 0x66, 0x18, 0xd4, 0xb1, 0xa0, 0x15, 0x23, 0xfb, 0x59, 0x33, + 0x40, 0xc7, 0x77, 0x1f, 0xb0, 0x28, 0xac, 0x77, 0x3f, 0xc1, 0x40, 0xdd, + 0x04, 0x5a, 0x28, 0xd9, 0xa2, 0x9d, 0xa8, 0x84, 0x77, 0x32, 0xe5, 0x5c, + 0xc4, 0xe5, 0x42, 0xe3, 0xce, 0xf2, 0x22, 0x41, 0x7d, 0xfa, 0xdf, 0x53, + 0xa7, 0xbe, 0xe3, 0x9b, 0x1e, 0x9f, 0x9d, 0x38, 0xfe, 0xd2, 0xeb, 0xdf, + 0x75, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, + 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w311_png_len = 439; diff --git a/src/res/w313.cpp b/src/res/w313.cpp new file mode 100644 index 0000000..025388d --- /dev/null +++ b/src/res/w313.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w313_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xaa, + 0xaa, 0xaa, 0xe6, 0xa3, 0x29, 0x34, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0xce, 0xbb, 0x0d, 0x80, 0x30, 0x0c, 0x04, 0xd0, 0x03, 0x29, 0x12, + 0x03, 0xc4, 0x3b, 0x44, 0x99, 0x02, 0x0a, 0x9a, 0x74, 0xa0, 0x78, 0x1f, + 0x46, 0x49, 0x19, 0x79, 0x4a, 0xf2, 0x71, 0x52, 0x20, 0x5c, 0x3d, 0x59, + 0xd6, 0xf9, 0x80, 0x31, 0x86, 0xd9, 0x8b, 0x48, 0x02, 0x75, 0xe4, 0x8a, + 0xf0, 0xc5, 0x71, 0x2b, 0xa0, 0x88, 0xb0, 0x22, 0xab, 0x22, 0xa3, 0x60, + 0x87, 0xf1, 0x09, 0x0e, 0x04, 0x2c, 0x0d, 0xb6, 0x20, 0x3c, 0x7d, 0x43, + 0x01, 0xd8, 0x6a, 0x20, 0xbb, 0x86, 0x93, 0x68, 0xc0, 0x26, 0xd4, 0x1b, + 0xe6, 0x98, 0x51, 0x72, 0x6c, 0xbc, 0xfa, 0x8b, 0x89, 0xbf, 0x3e, 0x5a, + 0x75, 0x96, 0x1f, 0xf3, 0x02, 0x42, 0x55, 0x39, 0x9f, 0x4b, 0x6f, 0x67, + 0xae, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, + 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w313_png_len = 427; diff --git a/src/res/w314.cpp b/src/res/w314.cpp new file mode 100644 index 0000000..6ef237e --- /dev/null +++ b/src/res/w314.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w314_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0xaa, + 0xaa, 0xff, 0xfd, 0xa2, 0x8c, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xce, 0x31, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xd0, 0x1f, 0x13, 0x17, + 0x66, 0xb8, 0x83, 0xe1, 0x14, 0x3a, 0xb8, 0xb0, 0x49, 0xe8, 0x7d, 0x3c, + 0x0a, 0x23, 0xe9, 0x29, 0x85, 0x0f, 0x18, 0x13, 0x3b, 0xbd, 0xa1, 0xbf, + 0xfd, 0xc0, 0x9c, 0x55, 0xc4, 0xab, 0x6a, 0x86, 0xeb, 0x28, 0x0d, 0x66, + 0x22, 0x0c, 0x1c, 0x51, 0x8b, 0x69, 0x40, 0xd4, 0xbc, 0x54, 0x24, 0x58, + 0xbd, 0xf1, 0xc5, 0x8e, 0xd5, 0x13, 0xf5, 0xa6, 0x6f, 0x3b, 0xb6, 0x22, + 0x30, 0x05, 0xb8, 0xc0, 0x94, 0xd4, 0x1f, 0xdc, 0x39, 0x9d, 0xf5, 0xc0, + 0x46, 0x28, 0x21, 0x92, 0x08, 0x9b, 0xae, 0xc8, 0x83, 0xc4, 0x48, 0x85, + 0x5f, 0xb1, 0x5e, 0xf5, 0x2d, 0x3f, 0xe7, 0x01, 0x4a, 0xbd, 0x39, 0x9e, + 0x97, 0x78, 0x83, 0x47, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, + 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, + 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w314_png_len = 430; diff --git a/src/res/w400.cpp b/src/res/w400.cpp new file mode 100644 index 0000000..1c7b962 --- /dev/null +++ b/src/res/w400.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w400_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x03, 0x00, 0x00, 0x00, 0xa1, 0x9d, 0x6d, 0x77, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0xf8, + 0xc7, 0xb0, 0x26, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, + 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, 0x64, 0xdd, 0x00, + 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, + 0x01, 0xfb, 0xff, 0xff, 0xff, 0x30, 0x64, 0xff, 0xff, 0x7f, 0x8d, 0xa1, + 0xe8, 0x8f, 0xbd, 0x1f, 0x83, 0xe3, 0x0f, 0xf9, 0x26, 0x86, 0x84, 0x0f, + 0xfc, 0x6c, 0x0c, 0xc1, 0x0f, 0xd8, 0x4f, 0x31, 0x94, 0x3e, 0x60, 0x5f, + 0xc7, 0x50, 0xff, 0x80, 0xfd, 0x1f, 0x43, 0xfd, 0x07, 0x7e, 0x20, 0xf1, + 0x43, 0x1e, 0x48, 0xfc, 0xb1, 0x87, 0xb1, 0xc0, 0x62, 0x60, 0xd9, 0x03, + 0xcc, 0xff, 0x18, 0x4a, 0x0f, 0x30, 0xaf, 0x63, 0x08, 0x3e, 0xc0, 0x7c, + 0x8a, 0x21, 0xe1, 0x00, 0x33, 0x1b, 0x83, 0xe3, 0x03, 0xf6, 0x26, 0x86, + 0xa2, 0x0f, 0xfc, 0x7e, 0x0c, 0xd9, 0x3f, 0xe4, 0xaf, 0x41, 0x2c, 0x02, + 0x01, 0x00, 0xe9, 0x6e, 0x31, 0x8a, 0x08, 0x88, 0x03, 0x62, 0x00, 0x00, + 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, + 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, + 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, + 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, + 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, + 0xae, 0x42, 0x60, 0x82 +}; +const size_t w400_png_len = 424; diff --git a/src/res/w401.cpp b/src/res/w401.cpp new file mode 100644 index 0000000..d9286c1 --- /dev/null +++ b/src/res/w401.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w401_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0xff, + 0xaa, 0x00, 0xc8, 0x34, 0x7a, 0x9d, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x70, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x5d, 0x8f, 0x3d, 0x0a, 0x80, 0x30, 0x0c, 0x85, 0x63, 0xa1, 0x20, 0xdd, + 0xdd, 0x1d, 0x4b, 0x4e, 0xe1, 0x28, 0x4e, 0x52, 0xe2, 0xa5, 0x3c, 0x45, + 0xc7, 0x92, 0x53, 0x9a, 0xbe, 0xa8, 0x88, 0x99, 0x3e, 0x92, 0xf7, 0x43, + 0x88, 0x9e, 0x89, 0x07, 0x66, 0xa7, 0xc9, 0x41, 0x3e, 0x20, 0x74, 0x83, + 0x5f, 0x0d, 0x16, 0xe8, 0xff, 0xd0, 0x73, 0x3a, 0x88, 0x6a, 0x83, 0xd8, + 0xc1, 0xec, 0xc2, 0x9c, 0xb1, 0x29, 0x29, 0x67, 0x68, 0xca, 0xd9, 0xec, + 0x44, 0x34, 0x94, 0x96, 0x1c, 0xb6, 0x1a, 0x1c, 0xd6, 0x39, 0x8c, 0xd0, + 0xf8, 0xc6, 0x5c, 0x0c, 0x8d, 0xe5, 0x30, 0x5c, 0xd6, 0xc8, 0xc8, 0xb1, + 0x66, 0xed, 0xc9, 0xb1, 0x83, 0x6a, 0x7d, 0xbf, 0xb9, 0x00, 0x09, 0xa4, + 0x2b, 0xcb, 0xb3, 0x0d, 0xa7, 0x43, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, + 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, + 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, + 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, + 0x30, 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, + 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, + 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w401_png_len = 432; diff --git a/src/res/w402.cpp b/src/res/w402.cpp new file mode 100644 index 0000000..896fd0b --- /dev/null +++ b/src/res/w402.cpp @@ -0,0 +1,42 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w402_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0xaa, + 0xaa, 0xaa, 0x94, 0x40, 0xdc, 0x30, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x64, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x6d, 0xcf, 0x31, 0x0a, 0x80, 0x30, 0x0c, 0x05, 0xd0, 0xaf, 0xd0, 0xc5, + 0xdd, 0x3b, 0x94, 0x9e, 0xc2, 0xb9, 0x93, 0x48, 0x72, 0x1f, 0x8f, 0xd2, + 0xb1, 0xf4, 0x94, 0x26, 0xfd, 0x55, 0x44, 0xcc, 0xf4, 0x08, 0x3f, 0x1f, + 0x02, 0xdc, 0x13, 0xb4, 0xcf, 0x8e, 0x95, 0x90, 0x37, 0xa6, 0x01, 0xc1, + 0x00, 0x63, 0xbf, 0xf0, 0x8c, 0x17, 0xfa, 0x95, 0xb4, 0x56, 0xfb, 0x86, + 0xb0, 0x8c, 0xb4, 0xc5, 0xb0, 0x21, 0x1c, 0x75, 0x1e, 0x28, 0xf8, 0x20, + 0x9f, 0x60, 0x38, 0x03, 0xb1, 0x9f, 0x13, 0x56, 0x18, 0x09, 0xd5, 0x04, + 0xcf, 0xa8, 0x17, 0x5b, 0x73, 0x20, 0xca, 0xf3, 0xcd, 0x05, 0x2e, 0x4d, + 0x2e, 0x26, 0x8a, 0x0d, 0x74, 0xec, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0x67, 0xa0, 0xb8, 0x68, 0x00, 0x00, 0x00, 0x25, 0x74, + 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, + 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, + 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x32, 0x2b, 0x30, + 0x30, 0x3a, 0x30, 0x30, 0x16, 0xfd, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x28, + 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, + 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, + 0x33, 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w402_png_len = 420; diff --git a/src/res/w403.cpp b/src/res/w403.cpp new file mode 100644 index 0000000..299d67f --- /dev/null +++ b/src/res/w403.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w403_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0x00, + 0x55, 0xff, 0xc8, 0x8a, 0x5c, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x5d, 0xcf, 0xc1, 0x09, 0xc0, 0x20, 0x0c, 0x05, 0xd0, 0xdf, 0x83, 0xd0, + 0x05, 0xba, 0x83, 0x38, 0x85, 0x67, 0x4f, 0x45, 0xd2, 0x7d, 0x3c, 0x77, + 0x0a, 0xf1, 0x24, 0x99, 0xb2, 0x26, 0xd1, 0x52, 0x9a, 0xd3, 0x43, 0xbf, + 0x3f, 0x08, 0xac, 0x71, 0x97, 0xce, 0x89, 0xc3, 0x40, 0x1f, 0x10, 0x26, + 0xec, 0x76, 0x20, 0x6a, 0xfe, 0x0f, 0xe9, 0x11, 0x10, 0x73, 0xd7, 0xb0, + 0x61, 0x3c, 0x27, 0x2e, 0x76, 0x92, 0x19, 0x5e, 0x33, 0xb9, 0x0b, 0x80, + 0x2d, 0xd7, 0x89, 0x04, 0xec, 0x86, 0x32, 0x33, 0x69, 0xf5, 0x84, 0x76, + 0x7b, 0xed, 0x31, 0x8c, 0x8d, 0xc1, 0xb7, 0x2e, 0x20, 0x16, 0x38, 0x01, + 0x73, 0x7d, 0x7f, 0xf3, 0x00, 0x47, 0x82, 0x2d, 0x6f, 0x68, 0x39, 0xd6, + 0x46, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, + 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, + 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xb3, 0x31, + 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, + 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, + 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xe3, + 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w403_png_len = 427; diff --git a/src/res/w406.cpp b/src/res/w406.cpp new file mode 100644 index 0000000..f2ab2bd --- /dev/null +++ b/src/res/w406.cpp @@ -0,0 +1,44 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w406_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x03, 0x00, 0x00, 0x00, 0xa1, 0x9d, 0x6d, 0x77, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x06, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x55, 0xaa, 0xa4, + 0x0d, 0x30, 0x99, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, + 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, + 0x07, 0xe6, 0x0c, 0x16, 0x09, 0x10, 0x20, 0xc2, 0x36, 0xbe, 0x6b, 0x00, + 0x00, 0x00, 0x75, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, + 0x01, 0xfb, 0xff, 0xff, 0xff, 0x30, 0xd4, 0xff, 0xff, 0xff, 0x0f, 0x48, + 0xfc, 0xfb, 0xc7, 0x50, 0xfe, 0xc7, 0xa6, 0x8e, 0x21, 0xf9, 0x87, 0xc4, + 0x3f, 0x06, 0xf7, 0x0f, 0x9c, 0xff, 0x18, 0xfc, 0x0b, 0xf8, 0xdf, 0x31, + 0xd4, 0x19, 0xf0, 0x1f, 0x63, 0xa8, 0x29, 0xe0, 0xef, 0x63, 0xa8, 0xf9, + 0x21, 0x3f, 0x8f, 0xa1, 0xfe, 0x8f, 0x3d, 0x50, 0xf1, 0x0f, 0x79, 0x20, + 0xf1, 0x81, 0x7f, 0x1f, 0x43, 0xf9, 0x03, 0x76, 0x39, 0x86, 0xe4, 0x03, + 0x4c, 0x76, 0x0c, 0xee, 0x07, 0x98, 0xea, 0x18, 0xfc, 0x0f, 0x30, 0xff, + 0x63, 0xa8, 0x7b, 0xc0, 0xfe, 0x0e, 0xa4, 0xe3, 0x18, 0x43, 0xc5, 0x0f, + 0xf9, 0x3e, 0x86, 0xca, 0xff, 0xff, 0xe7, 0x41, 0x2c, 0x02, 0x01, 0x00, + 0x3e, 0xc5, 0x32, 0x81, 0x48, 0x8f, 0xd5, 0xa4, 0x00, 0x00, 0x00, 0x25, + 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, 0x31, 0x35, 0x3a, 0x33, 0x37, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0x8b, 0x99, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, + 0x2d, 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, 0x31, 0x35, 0x3a, 0x33, 0x37, + 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0xfa, 0xc4, 0xb8, 0xdc, 0x00, 0x00, + 0x00, 0x28, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, + 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x32, 0x54, 0x30, 0x39, 0x3a, 0x31, + 0x36, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x14, 0xde, + 0x0d, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, + 0x60, 0x82 +}; +const size_t w406_png_len = 434; diff --git a/src/res/w411.cpp b/src/res/w411.cpp new file mode 100644 index 0000000..05d2640 --- /dev/null +++ b/src/res/w411.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w411_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0xff, + 0xaa, 0x00, 0xc8, 0x34, 0x7a, 0x9d, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0x8e, 0xb1, 0x0d, 0xc0, 0x20, 0x0c, 0x04, 0x3f, 0x48, 0x48, 0x28, + 0x75, 0xd8, 0x01, 0x79, 0x0a, 0xea, 0x54, 0x11, 0xc2, 0xfb, 0x30, 0x8a, + 0x4b, 0xc4, 0x94, 0x01, 0x1c, 0x52, 0x24, 0xae, 0x4e, 0xfe, 0xb7, 0xff, + 0x81, 0x35, 0x96, 0x99, 0x5a, 0x6b, 0x02, 0xaf, 0x50, 0x07, 0x9c, 0x1f, + 0xc8, 0x36, 0xb5, 0x4a, 0x1d, 0xae, 0x2d, 0x49, 0x25, 0x07, 0x1f, 0x91, + 0x25, 0x04, 0x85, 0xae, 0x84, 0x01, 0x4c, 0xb2, 0x4f, 0x0f, 0x53, 0x31, + 0xf3, 0x8a, 0x63, 0x31, 0x6e, 0x6e, 0x14, 0x86, 0x67, 0x4a, 0x80, 0x57, + 0x33, 0x70, 0xe8, 0x79, 0x87, 0xf5, 0xf0, 0x89, 0xe8, 0x59, 0x1a, 0xfa, + 0xef, 0xb3, 0xaa, 0xbe, 0xe5, 0xd7, 0xdc, 0xe9, 0x0f, 0x38, 0x9f, 0xce, + 0xb1, 0xa3, 0x73, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w411_png_len = 429; diff --git a/src/res/w413.cpp b/src/res/w413.cpp new file mode 100644 index 0000000..42ade24 --- /dev/null +++ b/src/res/w413.cpp @@ -0,0 +1,42 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w413_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0xaa, + 0xaa, 0xaa, 0x94, 0x40, 0xdc, 0x30, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x61, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xce, 0xc1, 0x09, 0x80, 0x30, 0x0c, 0x05, 0xd0, 0xaf, 0x50, 0x70, + 0x00, 0xbb, 0x43, 0xe9, 0x14, 0x9e, 0x73, 0x12, 0x69, 0xf6, 0xe9, 0x28, + 0x39, 0x96, 0x4c, 0xa9, 0xb5, 0x89, 0x87, 0xfa, 0x4f, 0x8f, 0xf0, 0x21, + 0x1f, 0xf0, 0x04, 0xe6, 0xac, 0xaa, 0x82, 0x38, 0xd0, 0x3a, 0x68, 0x42, + 0x09, 0xd7, 0xc0, 0xb9, 0x18, 0x0e, 0x14, 0xd5, 0xd5, 0xd0, 0xf0, 0x82, + 0xb3, 0x20, 0xf5, 0x8e, 0xa1, 0x04, 0xa6, 0x6a, 0x17, 0x42, 0xc7, 0xd3, + 0x49, 0xc0, 0x86, 0x08, 0x44, 0xc7, 0x2e, 0x8e, 0x66, 0x9d, 0xf9, 0xd7, + 0x7f, 0x8f, 0x4f, 0xfd, 0xc6, 0x7b, 0x6e, 0x64, 0x2c, 0x38, 0xab, 0xd3, + 0x3e, 0x05, 0xa4, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, + 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, + 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, + 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, + 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, + 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, + 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x37, 0x2b, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w413_png_len = 417; diff --git a/src/res/w414.cpp b/src/res/w414.cpp new file mode 100644 index 0000000..e81aaf8 --- /dev/null +++ b/src/res/w414.cpp @@ -0,0 +1,43 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t w414_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x18, + 0x02, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x3d, 0x17, 0xa7, 0x00, 0x00, 0x00, + 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, + 0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, + 0x26, 0x00, 0x00, 0x80, 0x84, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x80, + 0xe8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0x60, 0x00, 0x00, 0x3a, + 0x98, 0x00, 0x00, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, + 0x09, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xff, 0x00, + 0x55, 0xff, 0xc8, 0x8a, 0x5c, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, + 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x07, 0x74, + 0x49, 0x4d, 0x45, 0x07, 0xe6, 0x0c, 0x14, 0x10, 0x1d, 0x25, 0xbe, 0x0c, + 0x64, 0xdd, 0x00, 0x00, 0x00, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, + 0x65, 0xce, 0x31, 0x0e, 0x80, 0x20, 0x0c, 0x05, 0xd0, 0xcf, 0x40, 0xe2, + 0x01, 0xf4, 0x0e, 0x84, 0x53, 0x30, 0x1a, 0x26, 0x42, 0xec, 0x7d, 0x9c, + 0x39, 0x05, 0x23, 0xe9, 0x29, 0x6d, 0x41, 0x18, 0xb4, 0xd3, 0x4b, 0x29, + 0xed, 0x07, 0x66, 0x59, 0x22, 0xcf, 0xcc, 0x15, 0xc7, 0x40, 0x53, 0xc4, + 0x0f, 0x2e, 0x9b, 0x65, 0x44, 0x90, 0x8c, 0xe0, 0x76, 0x38, 0x02, 0x2e, + 0x66, 0xbc, 0x68, 0xd8, 0x14, 0xe4, 0xab, 0x22, 0x19, 0xf2, 0xba, 0x59, + 0x7e, 0xd1, 0xd9, 0x21, 0x9d, 0x88, 0x31, 0xac, 0x37, 0x64, 0x8f, 0x34, + 0x7d, 0x29, 0x4e, 0xb1, 0xf3, 0x42, 0x7f, 0x0a, 0xc8, 0x4d, 0xaa, 0xdf, + 0x1a, 0xf8, 0xe7, 0x99, 0x51, 0x57, 0xf8, 0x59, 0x0f, 0x8c, 0xd8, 0x3b, + 0x77, 0x47, 0xb3, 0xb6, 0xb2, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, + 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, 0x54, + 0x31, 0x36, 0x3a, 0x32, 0x35, 0x3a, 0x32, 0x39, 0x2b, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0xb3, 0x31, 0x0c, 0x82, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, + 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, + 0x79, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, 0x32, 0x2d, 0x32, 0x30, + 0x54, 0x31, 0x36, 0x3a, 0x32, 0x34, 0x3a, 0x33, 0x32, 0x2b, 0x30, 0x30, + 0x3a, 0x30, 0x30, 0xe3, 0x03, 0x8b, 0x64, 0x00, 0x00, 0x00, 0x28, 0x74, + 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x32, 0x30, 0x32, 0x32, 0x2d, 0x31, + 0x32, 0x2d, 0x32, 0x30, 0x54, 0x31, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, + 0x37, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x13, 0xd0, 0x0e, 0xac, 0x00, + 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +const size_t w414_png_len = 431; diff --git a/src/res/wifi.cpp b/src/res/wifi.cpp new file mode 100644 index 0000000..5f2485a --- /dev/null +++ b/src/res/wifi.cpp @@ -0,0 +1,23 @@ + +#include "resource.h" +#include + +PROGMEM const uint8_t wifi_bmp[] = { + 0x42, 0x4d, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x06, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x1f, + 0xf8, 0x00, 0x04, 0x07, 0xe0, 0x20, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x80, + 0x01, 0xe0, 0x03, 0xe0, 0x07, 0xc0, 0x00, 0xff, 0xff, 0x00, 0xe0, 0x3f, + 0xfc, 0x07, 0x70, 0x07, 0xe0, 0x0e, 0x3c, 0x00, 0x00, 0x3c, 0x1f, 0x00, + 0x00, 0xf8, 0x07, 0xc0, 0x03, 0xf0, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x7f, + 0xfe, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const size_t wifi_bmp_len = 190; diff --git a/src/utility.cpp b/src/utility.cpp new file mode 100644 index 0000000..4c26d8e --- /dev/null +++ b/src/utility.cpp @@ -0,0 +1,29 @@ + +#include"utility.hpp" + +#include +#include + +namespace gob +{ +std::vector split(const String& str, const char delimiter) +{ + std::vector out; + int start = 0; + int end = str.indexOf(delimiter); + + while(end >= 0) + { + out.emplace_back(str.substring(start, end)); + start = end + 1; + end = str.indexOf(delimiter, start); + } + out.emplace_back(str.substring(start)); + return out; +} + + + + +// +} diff --git a/src/utility.hpp b/src/utility.hpp new file mode 100644 index 0000000..9b558d4 --- /dev/null +++ b/src/utility.hpp @@ -0,0 +1,65 @@ +/* + Utility templates + */ +#ifndef UTILITY_HPP +#define UTILITY_HPP + +#include +#include +#include +#include +#include + +namespace gob +{ + +// Size of array. +template constexpr auto size(const C& c) -> decltype(c.size()) { return c.size(); } +template constexpr auto size(const T(&)[N]) noexcept -> size_t { return N; } + +// Underlying +template constexpr typename std::underlying_type::type to_underlying(T e) noexcept +{ + return static_cast::type>(e); +} + +// Exists T.toString()? +template struct has_toString +{ + template static std::true_type check(U*); + static std::false_type check(...); + static T* _cls; + static const bool value = decltype(check(_cls))::value; +}; + +/* Like join function of Ruby. (For Integral, Floating-point, and String) + join({1, 2, 3}, "/"); // "1/2/3" + */ +template::value || std::is_integral::value || std::is_same::value, std::nullptr_t>::type = nullptr> +String join(const std::vector& v, const char* separator = ", ") +{ + + return !v.empty() ? std::accumulate(++v.cbegin(), v.cend(), String(v[0]), + [&separator](const String& a, const T& b) + { + return a + separator + String(b); + }): String(); +} + +// Like join function of Ruby. (For classes that has the toString function.) +template::value, std::nullptr_t>::type = nullptr> +String join(const std::vector& v, const char* separator = ", ") +{ + return !v.empty() ? std::accumulate(++v.cbegin(), v.cend(), v[0].toString(), + [&separator](const String& a, const T& b) + { + return a + separator + b.toString(); + }) : String(); +} + +// Split string +std::vector split(const String& str, const char delimiter = ','); +inline std::vector split(const char* s, const char delimiter = ',') { return split(String(s), delimiter); } +// +} +#endif diff --git a/src/wxbeacon2.cpp b/src/wb2/wxbeacon2.cpp similarity index 92% rename from src/wxbeacon2.cpp rename to src/wb2/wxbeacon2.cpp index 3bbc30f..5f0af4b 100644 --- a/src/wxbeacon2.cpp +++ b/src/wb2/wxbeacon2.cpp @@ -9,12 +9,12 @@ namespace { -template struct is_stdarray :std::false_type {}; -template struct is_stdarray> : std::true_type {}; +template struct is_std_array :std::false_type {}; +template struct is_std_array> : std::true_type {}; template bool string2array(T& a, const std::string& v) { - static_assert(is_stdarray::value, "T must be std::array"); + static_assert(is_std_array::value, "T must be std::array"); a = {}; if(a.empty() || v.empty() || v.length() == 0) { return false; } @@ -26,9 +26,7 @@ template bool string2array(T& a, const std::string& v) bool toLocalTime(std::tm& t, time_t tt) { t = std::tm{}; - std::tm* lt = std::localtime(&tt); - if(lt) { t = *lt; } - return lt; + return localtime_r(&tt, &t) != nullptr; } // diff --git a/src/wxbeacon2.hpp b/src/wb2/wxbeacon2.hpp similarity index 99% rename from src/wxbeacon2.hpp rename to src/wb2/wxbeacon2.hpp index 5ec8bb9..cee1a9f 100644 --- a/src/wxbeacon2.hpp +++ b/src/wb2/wxbeacon2.hpp @@ -43,7 +43,7 @@ class WxBeacon2 }; constexpr static bool validBeaconMode(const BeaconMode bm) { - return (const uint8_t)bm <= (const uint8_t)BeaconMode::EventBeaconADV && bm != BeaconMode::Unused0; + return (uint8_t)bm <= (uint8_t)BeaconMode::EventBeaconADV && bm != BeaconMode::Unused0; } /*! diff --git a/src/wxbeacon2_ble.cpp b/src/wb2/wxbeacon2_ble.cpp similarity index 99% rename from src/wxbeacon2_ble.cpp rename to src/wb2/wxbeacon2_ble.cpp index 0b0bbe9..a19b709 100644 --- a/src/wxbeacon2_ble.cpp +++ b/src/wb2/wxbeacon2_ble.cpp @@ -216,11 +216,12 @@ void WxBeacon2AdvertiseCallbacks::onResult(NimBLEAdvertisedDevice* device) detected = (c->_companyID == WxBeacon2::COMPANY_ID); } - WB2_LOGI("WxBeacon2 %s detected", detected ? "" : "NOT"); + WB2_LOGI("WxBeacon2 detected? %d", detected); if(detected) { _address = device->getAddress(); + WB2_LOGI("address: %s",_address.toString().c_str()); NimBLEDevice::getScan()->stop(); } } diff --git a/src/wxbeacon2_ble.hpp b/src/wb2/wxbeacon2_ble.hpp similarity index 100% rename from src/wxbeacon2_ble.hpp rename to src/wb2/wxbeacon2_ble.hpp diff --git a/src/wxbeacon2_log.hpp b/src/wb2/wxbeacon2_log.hpp similarity index 98% rename from src/wxbeacon2_log.hpp rename to src/wb2/wxbeacon2_log.hpp index ca2d598..c38e8d9 100644 --- a/src/wxbeacon2_log.hpp +++ b/src/wb2/wxbeacon2_log.hpp @@ -6,6 +6,8 @@ #ifndef WXBEACON2_LOG_HPP #define WXBEACON2_LOG_HPP +#ifdef ARDUINO + namespace wxbeacon2 { constexpr char tag[] = "WB2"; @@ -47,5 +49,6 @@ constexpr char tag[] = "WB2"; #endif +#endif // #endif diff --git a/src/wb2/wxbeacon2_task.cpp b/src/wb2/wxbeacon2_task.cpp new file mode 100644 index 0000000..9609703 --- /dev/null +++ b/src/wb2/wxbeacon2_task.cpp @@ -0,0 +1,265 @@ + +#include +#include +#include "wxbeacon2_task.hpp" +#include "wxbeacon2_ble.hpp" +#include "wxbeacon2_log.hpp" + +namespace +{ +constexpr uint16_t MEASUREMENT_INTERVAL_BROADCAST_SEC = 60 * 3; // Interval default. + +TaskHandle_t advertiseTask; +volatile bool exists = false; // Exists WxBeacon2? +volatile bool progressAdvertise = false; +advertise_callback callback_on_advertise; + +NimBLEAddress wb2address; // Detected wxbeacon2 address +WxBeacon2Client* wb2Client = nullptr; + +// WxBeacon2Client Scoped init,connect/disconnect,deinit. +struct ScopedWB2Client +{ + ScopedWB2Client(WxBeacon2Client& client, const NimBLEAddress& addr) : _client(client) + { + NimBLEDevice::init(""); + WB2_LOGI("connect to : %s", addr.toString().c_str()); + if(!_client.isConnected() && !_client.connect(addr)) + { + WB2_LOGE("Failed to connect"); + } + } + ~ScopedWB2Client() + { + _client.disconnect(); + NimBLEDevice::deinit(true); + } + WxBeacon2Client& client() { return _client; } + private: + WxBeacon2Client& _client; +}; + +// Task of get advertise data from WxBeacon2. +void wb2_advertise_task(void*) +{ + for(;;) + { + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + + WB2_LOGI("Start scanning"); + NimBLEDevice::init(""); + delay(100); + NimBLEScan* scan = NimBLEDevice::getScan(); + WxBeacon2AdvertiseCallbacks cb; + scan->setAdvertisedDeviceCallbacks(&cb); + scan->setInterval(1000); + scan->setWindow(900); + scan->setActiveScan(true); + cb.clear(); + + scan->start(60, false); + while(scan->isScanning()) { delay(100); } + + wb2address = cb.address(); + scan->stop(); + scan->clearResults(); + NimBLEDevice::deinit(true); + delay(100); + + WB2_LOGI("End of scanning. detected :%d", cb.detected()); + progressAdvertise = false; + if(callback_on_advertise) { callback_on_advertise(cb.detected(), cb.data()); } + } +} +// +} + +bool initilizeAdvertise(const UBaseType_t priority, const BaseType_t core, advertise_callback f) +{ + if(!advertiseTask) + { + xTaskCreateUniversal(wb2_advertise_task, "advertise_task", 4 * 1024, nullptr, priority, &advertiseTask, core); + if(!wb2Client) { wb2Client = new WxBeacon2Client(); } + callback_on_advertise = f; + } + return (wb2Client != nullptr) && (advertiseTask != nullptr); +} + +bool requestAdvertise() +{ + if(busyAdvertise()) { return false; } + + progressAdvertise = true; + xTaskNotifyGive(advertiseTask); + return true; +} + +bool busyAdvertise() { return progressAdvertise; } + +/* + Change broadcast mode + @warning Changing to broadcast mode will not work with the WNI application. + @warning If you want to link with the WNI application, call the changeDefaultSetting function. + @warning If the beacon mode is changed, all data stored in WxBeacon2 will be lost. + */ +bool changeBeaconMode() +{ + if(!wb2Client || ((uint64_t)wb2address == 0) || busyAdvertise()) { WB2_LOGD("Cannot invoke"); return false; } + + ScopedWB2Client wb2(*wb2Client, wb2address); + if(!wb2.client().isConnected()) + { + WB2_LOGE("Failed to connect"); + return false; + } + + WxBeacon2::ADVSetting setting; + if(!wb2.client().getADVSetting(setting)) + { + WB2_LOGE("Failed ti get setting"); + return false; + } + + setting._beaconMode = (uint8_t)WxBeacon2::BeaconMode::GeneralBroadcaster2; + + if(wb2.client().setADVSetting(setting)) + { + return wb2.client().setMeasurementInterval(MEASUREMENT_INTERVAL_BROADCAST_SEC); + } + return false; +} + +/* + Change default mode (for WNI Application) + @warning If the beacon mode is changed, all data stored in WxBeacon2 will be lost. + */ +bool changeDefaultSetting() +{ + if(!wb2Client || ((uint64_t)wb2address == 0) || busyAdvertise()) { WB2_LOGD("Cannot invoke"); return false; } + + ScopedWB2Client wb2(*wb2Client, wb2address); + if(!wb2.client().isConnected()) + { + WB2_LOGE("Failed to connect"); + return false; + } + + // Need set interval and time inforamtion, + if(wb2.client().setADVSetting(WxBeacon2::ADVSetting::DEFAULT_SETTING)) + { + delay(500); + std::tm t{}; + getLocalTime(&t); + if(wb2.client().setTimeInformation(t)) + { + delay(500); + return wb2.client().setMeasurementInterval(WxBeacon2::MeasurementInterval::DEFAULT_VALUE); + } + } + return false; +} + +/* turnon LED 1 second */ +bool turnOnLED() +{ + if(!wb2Client || ((uint64_t)wb2address == 0) || busyAdvertise()) { WB2_LOGD("Cannot invoke"); return false; } + + ScopedWB2Client wb2(*wb2Client, wb2address); + if(!wb2.client().isConnected()) + { + WB2_LOGE("Failed to connect"); + return false; + } + return wb2.client().setLED(1); +} + +#if 0 +bool test_connect() +{ + if(!wb2Client || ((uint64_t)wb2address == 0) || busyAdvertise()) { WB2_LOGD("Cannot invoke"); return false; } + + ScopedWB2Client wb2(*wb2Client, wb2address); + if(!wb2.client().isConnected()) + { + WB2_LOGE("Failed to connect"); + return false; + } + + std::string str; + auto b = wb2.client().getDeviceName(str); + printf("%d DeviceName:%s\n", b, str.c_str()); + + WxBeacon2::GenericAccesssService::Appearance app; + b = wb2.client().getAppearance(app); + printf("%d Appearnce:%x\n", b, app._category); + + WxBeacon2::GenericAccesssService::PeripheralPreferredConnectionParameters params; + b = wb2.client().getPeripheralPreferredConnectionParameters(params); + printf("%d params:%x/%x/%x/%x\n", b, + params._intervalMin, params._intervalMax, params._slaveLatency, params._timeout); + + b = wb2.client().getModelNumber(str); + printf("%d ModelNumber:[%s]\n", b, str.c_str()); + b = wb2.client().getSerialNumber(str); + printf("%d SerialNumber:[%s]\n", b, str.c_str()); + b = wb2.client().getFirmwareRevision(str); + printf("%d FirmRev:[%s]\n", b, str.c_str()); + b = wb2.client().getHardwareRevision(str); + printf("%d HardRev:[%s]\n", b, str.c_str()); + b = wb2.client().getManufacturerName(str); + printf("%d ManufacturerName:[%s]\n", b, str.c_str()); + + return true; +} + +bool test_getLatestPageData() +{ + if(!wb2Client || ((uint64_t)wb2address == 0) || busyAdvertise()) { WB2_LOGD("Cannot invoke"); return false; } + + if(!wb2Client) { WB2_LOGE("Client null"); return false; } + if((uint64_t)wb2address == 0) { WB2_LOGE("Address not yet obtained"); return false; } + + ScopedWB2Client wb2(*wb2Client, wb2address); + if(!wb2.client().isConnected()) + { + WB2_LOGE("Failed to connect"); + return false; + } + + WxBeacon2::LatestPage lpage; + if(!wb2.client().getLatestPage(lpage)) { WB2_LOGE("Failed to get latest page"); return false; } + printf("Latest: %d,%d\n", lpage._page, lpage._row); + + int retryCount = 3; + WxBeacon2::ResponseFlag flag = { 2 }; + do + { + if(!wb2.client().requestPage(lpage._page, lpage._row)) { continue; } // request + for(;;) // get response flag + { + wb2.client().getResponseFlag(flag); + if((int)flag._updateFlag != 0) { break; } + delay(10); + } + }while((int)flag._updateFlag == 2 && retryCount--); + if((int)flag._updateFlag != 1) { WB2_LOGE("Failed to request or get response"); return false; } + + int cnt = lpage._row + 1; + while(cnt--) + { + WxBeacon2::ResponseData data; + if(!wb2.client().getResponseData(data)) { WB2_LOGE("Failed to get response data"); return false; } + time_t t = flag._time32 + lpage._interval * data._data._row; + auto lt = std::localtime(&t); + printf("DATA: row:%02d time:%4d/%02d/%02d %02d:%02d:%02d\n", + data._data._row, + lt->tm_year + 1900, + lt->tm_mon + 1, + lt->tm_mday, + lt->tm_hour, + lt->tm_min, + lt->tm_sec); + } + return true; +} +#endif diff --git a/src/wb2/wxbeacon2_task.hpp b/src/wb2/wxbeacon2_task.hpp new file mode 100644 index 0000000..a606ad4 --- /dev/null +++ b/src/wb2/wxbeacon2_task.hpp @@ -0,0 +1,19 @@ + +#ifndef WXBEACON2_TASK_HPP +#define WXBEACON2_TASK_HPP + +#include "wxbeacon2.hpp" + +// callback function on get advertise data. +using advertise_callback = void(*)(const bool exists, const WxBeacon2::AdvertiseData& ad); + +bool initilizeAdvertise(const UBaseType_t priority, const BaseType_t core, advertise_callback f); + +bool busyAdvertise(); + +bool requestAdvertise(); +bool turnOnLED(); +bool changeBeaconMode(); +bool changeDefaultSetting(); + +#endif diff --git a/src/weather_map.cpp b/src/weather_map.cpp new file mode 100644 index 0000000..8e812bd --- /dev/null +++ b/src/weather_map.cpp @@ -0,0 +1,109 @@ +/* + Weather map + */ +#include "weather_map.hpp" +#include +#include "wb2/wxbeacon2_log.hpp" +#include "res/resource.h" +#include + +namespace +{ +struct Pos { uint8_t x, y; }; // Half of actual position. +PROGMEM const Pos ocPos[] = { + { 120, 8 }, // sap + { 136, 40 }, // sen + { 128, 72 }, // tok + { 104, 32 }, // nii + { 88, 48 }, // kan + { 104, 80 }, // nag + { 80, 72 }, // osa + { 48, 64 }, // hir + { 48, 84 }, // kou + { 16, 56 }, // fuk + { 8, 32 } // nah +}; + +std::map positionTable = +{ + { 16000, &ocPos[0] }, + { 40000, &ocPos[1] }, + { 130000, &ocPos[2] }, + { 150000, &ocPos[3] }, + { 170000, &ocPos[4] }, + { 230000, &ocPos[5] }, + { 270000, &ocPos[6] }, + { 340000, &ocPos[7] }, + { 390000, &ocPos[8] }, + { 400000, &ocPos[9] }, + { 471000, &ocPos[10] }, +}; + +std::map pngTable = +{ + { 100, w100_png }, + { 101, w101_png }, + { 102, w102_png }, + { 104, w104_png }, + { 110, w110_png }, + { 112, w112_png }, + { 115, w115_png }, + { 200, w200_png }, + { 201, w201_png }, + { 202, w202_png }, + { 204, w204_png }, + { 210, w210_png }, + { 212, w212_png }, + { 215, w215_png }, + { 300, w300_png }, + { 301, w301_png }, + { 302, w302_png }, + { 303, w303_png }, + { 308, w308_png }, + { 311, w311_png }, + { 313, w313_png }, + { 314, w314_png }, + { 400, w400_png }, + { 401, w401_png }, + { 402, w402_png }, + { 403, w403_png }, + { 406, w406_png }, + { 411, w411_png }, + { 413, w413_png }, + { 414, w414_png }, +}; + +// WARNING : Keep largets free heap 50K for decode PNG. +void drawWeatherIcon(m5gfx::M5GFX* dst, jma::officecode_t oc, jma::weathercode_t wc) +{ + auto ic = jma::weatherCodeToIcon(wc); + if(!ic || pngTable.count(ic) == 0 || positionTable.count(oc) == 0) { return; } + + auto png = pngTable.at(ic); + auto pos = positionTable.at(oc); + // WB2_LOGD("%d:%d:%d p:%d", oc, wc, ic, png != nullptr); + auto ret = dst->drawPng(png, -1, pos->x * 2, pos->y * 2); + if(ret == 0) { WB2_LOGV("mem:%u", esp_get_free_internal_heap_size()); } +} +// +} + +void WeatherMap::render(m5gfx::M5GFX* dst, bool force) +{ + if(!isShow() || !force) { return; } + + dst->drawBmp(jpmap_bmp, -1, 0, 0, 0, 0, 0, 0, 2.0f, 2.0f); // Japan map + // Icon + for(auto& e : _icons) + { + drawWeatherIcon(dst, e.oc, e.wc); + } + // Day of forecast + auto ofont = dst->getFont(); + dst->setFont(&tickerFont); + dst->setTextColor(TFT_WHITE); + dst->setCursor(8,8); + dst->printf("%sの天気", _odt.toLocalDate().toString("%m/%d").c_str()); + dst->setFont(ofont); + dst->setTextColor(TFT_WHITE, TFT_BLACK); +} diff --git a/src/weather_map.hpp b/src/weather_map.hpp new file mode 100644 index 0000000..38a48ab --- /dev/null +++ b/src/weather_map.hpp @@ -0,0 +1,42 @@ +/* + Weather map + */ +#ifndef WEATHER_MAP_HPP +#define WEATHER_MAP_HPP + +#include +#include +#include "jma/jma_definition.hpp" +#include + +class WeatherMap +{ + public: + struct IconInfo + { + IconInfo(const jma::officecode_t ocv, const jma::weathercode_t wcv) : oc(ocv), wc(wcv) {} + jma::officecode_t oc{}; + jma::weathercode_t wc{}; + }; + + WeatherMap() { _icons.reserve(16); } + + inline void show() { show(true); } + inline void hide() { show(false); } + + void setDatetime(const goblib::datetime::OffsetDateTime& odt) { _odt =odt; } + inline void clearIcon() { _icons.clear(); } + void addIcon(const jma::officecode_t oc, const jma::weathercode_t wc) { _icons.emplace_back(oc, wc); } + + void render(m5gfx::M5GFX* dst, bool forece = false); + + private: + void show(bool b) { _show = b; } + inline bool isShow() const { return _show; } + + private: + bool _show{false}; + goblib::datetime::OffsetDateTime _odt{}; + std::vector _icons{}; +}; +#endif diff --git a/src/wni_ticker.cpp b/src/wni_ticker.cpp index 007b653..41b943a 100644 --- a/src/wni_ticker.cpp +++ b/src/wni_ticker.cpp @@ -2,23 +2,30 @@ WNI style ticker */ #include "wni_ticker.hpp" +#include "gob_datetime.hpp" +#include "wb2/wxbeacon2_log.hpp" #include "res/resource.h" -#include "u8g2_font_profont22_tr.h" +#include "utility.hpp" #include #include -namespace +using goblib::datetime::LocalTime; + +PROGMEM const uint16_t Ticker::DECOR_FOREGROUND_COLORS[] = { -const lgfx::U8g2font profont22( u8g2_font_profont22_tr ); -// + ::lgfx::color565( 0, 0, 255), // blue + ::lgfx::color565(188, 188, 0), // yellow + ::lgfx::color565(255, 0, 0), // red + ::lgfx::color565(128, 0, 255), // purple + ::lgfx::color565( 64, 144, 48), // green }; -const uint32_t Ticker::DECOR_FOREGROUND_COLORS[] = +PROGMEM const uint16_t Ticker::TELOP_COLORS[] = { - ::lgfx::LGFXBase::color888( 0, 0, 255), // blue - ::lgfx::LGFXBase::color888(188, 188, 0), // yellow - ::lgfx::LGFXBase::color888(255, 0, 0), // red - ::lgfx::LGFXBase::color888(128, 0, 255), // purple + ::lgfx::color565(255, 255, 255), + ::lgfx::color565( 0, 0, 0), + ::lgfx::color565(255, 0, 0), + ::lgfx::color565( 0, 0, 255), }; Ticker::Ticker() @@ -26,51 +33,56 @@ Ticker::Ticker() , _str{} , _twidth(0) , _x(0) + , _speed(2) + , _decorLeftWidth(DECOR_LEFT_WIDTH) , _decorLeft(nullptr) , _decorRight(nullptr) , _logo(nullptr) - , _level(Level::Blue) + , _color(Color::Blue) , _show(true) { // _telop = new LGFX_Sprite(); - _telop->setColorDepth(1); // 1bpp + assert(_telop); + _telop->setPsram(true); + _telop->setColorDepth(2); // 2bpp _telop->createSprite(TELOP_WIDTH, TELOP_HEIGHT); - _telop->setBitmapColor(::lgfx::LGFXBase::color24to16(TELOP_FCLR), ::lgfx::LGFXBase::color24to16(TELOP_BCLR)); + auto pal = _telop->getPalette(); + for(auto& e : TELOP_COLORS) { *pal++ = ::lgfx::LGFXBase::color16to24(e); } _telop->setTextColor(1); - _telop->setFont(&profont22); + _telop->setFont(&tickerFont); // _decorRight = new LGFX_Sprite(); assert(_decorRight); - _decorRight->setColorDepth(1); + _decorRight->setPsram(true); + _decorRight->setColorDepth(1); // 1bpp _decorRight->createSprite(DECOR_RIGHT_WIDTH, DECOR_RIGHT_HEIGHT); - _decorRight->setBitmapColor(::lgfx::LGFXBase::color24to16(DECOR_FOREGROUND_COLORS[_level]), ::lgfx::LGFXBase::color24to16(TELOP_BCLR)); + _decorRight->setBitmapColor(DECOR_FOREGROUND_COLORS[_color], BG_COLOR); _decorRight->setTextColor(1); _decorRight->setFont(&fonts::Font0); // _decorLeft = new LGFX_Sprite(); assert(_decorLeft); - _decorLeft->setColorDepth(2); + _decorLeft->setPsram(true); + _decorLeft->setColorDepth(2); // 4bpp _decorLeft->createSprite(DECOR_LEFT_WIDTH, DECOR_LEFT_HEIGHT); + _decorLeft->setPivot(0,0); //left,top _decorLeft->setPaletteColor(0, 255,0,255); // 0: transparent color - ::lgfx::rgb888_t rgb(DECOR_FOREGROUND_COLORS[_level]); - _decorLeft->setPaletteColor(1, rgb.R8(), rgb.G8(), rgb.B8()); // 1: level color - _decorLeft->setPaletteColor(2, 255, 255, 255); // 2: text color - _decorLeft->setFont(&profont22); + _decorLeft->setPaletteColor(1, DECOR_FOREGROUND_COLORS[_color]); + _decorLeft->setPaletteColor(2, DECOR_TEXT_COLOR); + _decorLeft->setFont(&titleFont); _decorLeft->setTextColor(2); - _decorLeft->clear(); _decorLeft->fillRect(0,0,DECOR_LEFT_WIDTH, DECOR_LEFT_HEIGHT / 2, 1); _decorLeft->fillRect(0,0,DECOR_LEFT_GAP, DECOR_LEFT_HEIGHT, 1); - _decorLeft->drawString("Ponko", 1, 1); // _logo = new LGFX_Sprite(); assert(_logo); _logo->createFromBmp(logo_bmp, logo_bmp_len); - _logo->setPaletteColor(1, rgb.R8(), rgb.G8(), rgb.B8()); // 1: level color + _logo->setPaletteColor(1, DECOR_FOREGROUND_COLORS[_color]); } Ticker::~Ticker() @@ -81,80 +93,101 @@ Ticker::~Ticker() delete _telop; } -void Ticker::setLevel(const Level lv) +void Ticker::setColor(const Color c) { - _level = lv; - ::lgfx::rgb888_t rgb(DECOR_FOREGROUND_COLORS[_level]); - _decorLeft->setPaletteColor (1, rgb.R8(), rgb.G8(), rgb.B8()); - _decorRight->setPaletteColor(1, rgb.R8(), rgb.G8(), rgb.B8()); + _color = c; + _decorLeft->setPaletteColor (1, DECOR_FOREGROUND_COLORS[_color]); + _decorRight->setPaletteColor(1, DECOR_FOREGROUND_COLORS[_color]); } // Set level by WBGT // see also https://www.wbgt.env.go.jp/wbgt.php -void Ticker::setLevelWBGT(float wbgt) +void Ticker::setLevelWBGT(const float wbgt) +{ + Color lv = (wbgt < 25.0f) ? Color::Blue + : (wbgt < 31.0f) ? Color::Yellow + : Color::Red; + setColor(lv); +} + +void Ticker::setTitle(const char* title) { - Level lv = (wbgt < 25.0f) ? Level::Blue - : (wbgt < 31.0f) ? Level::Yellow - : Level::Red; - setLevel(lv); + if(!title || !title[0]) { return; } + + WB2_LOGD("[%s]", title); + + _decorLeft->clear(); // fill 0 + + auto sz = _decorLeft->textWidth(title); + _decorLeft->fillRect(0,0,sz + 4 /* gap 2 + 2 */, DECOR_LEFT_HEIGHT / 2, 1); + _decorLeft->fillRect(0,0,DECOR_LEFT_GAP, DECOR_LEFT_HEIGHT, 1); + _decorLeft->drawString(title, 2, 1); } void Ticker::setText(const char* str) { + WB2_LOGD("[%s]", str); + + _telop->clear(0); + _str.clear(); _x = _telop->width(); - _str[0] = '\0'; _twidth = 0; - - if(str && str[0]) + + _str = gob::split(str, '#'); + for(auto& e : _str) { - strncpy(_str, str, sizeof(_str) - 1); - _str[sizeof(_str) - 1] = '\0'; - _twidth = _telop->textWidth(_str); + if(e.length() == 0) { continue; } + _twidth += _telop->textWidth(e.c_str() + (e[0] == '@' && isdigit(e[1])) * 2); // Command of change palette? + } + + auto twid = _telop->width(); + if(_twidth > twid) + { + auto allot = twid - _twidth % twid; + int16_t left = 0; + std::vector append; + for(auto& e : _str) + { + if(left > twid) { break; } + append.push_back(e); + left += _telop->textWidth(e.c_str() + (e[0] == '@' && isdigit(e[1])) * 2); + } + _str.insert(_str.end(), append.begin(), append.end()); } + // WB2_LOGD("twidth:%d telop:%d str:%zu", _twidth, twid, _str.size()); } void Ticker::pump() { // Telop - _telop->clear(0); if(_str[0]) { - auto bwid = _telop->width(); - _telop->drawString(_str, _x, 0); - // Connect string if string width greater than width of _telop. - if(_twidth > bwid && (_x + _twidth) < bwid) - { - _telop->drawString(_str, _x + _twidth, 0); - } - // Infinity scroll string to left. - _x -= 2; - if(_twidth <= bwid) + _telop->clear(0); + auto twid = _telop->width(); + drawTelop(_x, 0); + + _x -= _speed; + if(_twidth <= twid) { - if(_x < -_twidth) { _x = _telop->width(); } + if(_x < -_twidth) { _x = twid; } } else { if(_x < -_twidth) { _x += _twidth; } } } - + // Localtime - std::tm t; _decorRight->clear(); _logo->pushSprite(_decorRight, 0, 0, 0); - if(getLocalTime(&t)) - { - char clockStr[64]; - snprintf(clockStr, sizeof(clockStr), "%02d:%02d", t.tm_hour, t.tm_min); - clockStr[sizeof(clockStr) - 1] = '\0'; - _decorRight->drawString(clockStr, - _decorRight->width()/2 - _decorRight->textWidth(clockStr) / 2, - _decorRight->height() - (_decorRight->fontHeight() + 2) ); - _decorRight->drawString(clockStr, - _decorRight->width()/2 - _decorRight->textWidth(clockStr) / 2 + 1, - _decorRight->height() - (_decorRight->fontHeight() + 2) ); - - } + LocalTime lt = LocalTime::now(); + auto clockStr = lt.toString("%H;%M"); + _decorRight->drawString(clockStr.c_str(), + _decorRight->width()/2 - _decorRight->textWidth(clockStr) / 2, + _decorRight->height() - (_decorRight->fontHeight() + 2) ); + _decorRight->drawString(clockStr.c_str(), + _decorRight->width()/2 - _decorRight->textWidth(clockStr) / 2 + 1, + _decorRight->height() - (_decorRight->fontHeight() + 2) ); } void Ticker::render(m5gfx::M5GFX* dst) @@ -165,3 +198,20 @@ void Ticker::render(m5gfx::M5GFX* dst) _decorRight->pushSprite(dst, dst->width() - (_decorRight->width() + GAP), dst->height() - _decorRight->height()); _decorLeft->pushSprite(dst, 0, dst->height() - _decorLeft->height(), 0); } + +void Ticker::drawTelop(const int16_t x, const int16_t y) +{ + int16_t left = x; + auto twid = _telop->width(); + + _telop->setTextColor(1); + + for(auto& e : _str) + { + if(left > twid) { break; } + if(e.length() == 0) { continue; } + const char* s = e.c_str(); + if(*s == '@' && isdigit(*(s+1))) { _telop->setTextColor((*(s+1)) - '0'); s += 2; } // Change palette + left += _telop->drawString(s, left, y); + } +} diff --git a/src/wni_ticker.hpp b/src/wni_ticker.hpp index 11b30f9..b65fd25 100644 --- a/src/wni_ticker.hpp +++ b/src/wni_ticker.hpp @@ -6,59 +6,68 @@ #include +//namespace gob { class Sprite; } + class Ticker { public: - enum Level : uint8_t { Blue, Yellow, Red, Purple, Max }; + enum Color : uint8_t { Blue, Yellow, Red, Purple, Green, Max }; Ticker(); virtual ~Ticker(); + void setTitle(const char* title); void setText(const char* str); bool isShow() const { return _show; } - void show(bool b) { _show = b; } + void show(const bool b) { _show = b; } void show() { show(true); } void hide() { show(false); } - Level level() const { return _level; } - void setLevel(const Level lv); - void setLevelWBGT(float wbgt); - - virtual void pump(); - virtual void render(m5gfx::M5GFX* dst); + Color color() const { return _color; } + void setColor(const Color lv); + void setLevelWBGT(const float wbgt); - constexpr static size_t STRING_LEN = 256; - constexpr static int16_t GAP = 2; + void setScrollSpeed(const uint8_t s) { _speed = s; } + void pump(); + void render(m5gfx::M5GFX* dst); + //Decoration left - constexpr static int16_t DECOR_LEFT_WIDTH = 64; + constexpr static int16_t DECOR_LEFT_WIDTH = 160; constexpr static int16_t DECOR_LEFT_HEIGHT = 48; constexpr static int16_t DECOR_LEFT_GAP = 4; //Decoration right constexpr static int16_t DECOR_RIGHT_WIDTH = 32; constexpr static int16_t DECOR_RIGHT_HEIGHT = 48; // Telop + constexpr static int16_t GAP = 2; constexpr static int16_t TELOP_WIDTH = 320 - (DECOR_RIGHT_WIDTH + 2 * GAP + DECOR_LEFT_GAP); constexpr static int16_t TELOP_HEIGHT = 24; // height = fontHeight + (1 + 1) - constexpr static uint32_t TELOP_FCLR = ::lgfx::color888( 0, 0, 0); // palette 1 - constexpr static uint32_t TELOP_BCLR = ::lgfx::color888(255, 255, 255); // palette 0 - - // Decoration foreground colors for each level. - static const uint32_t DECOR_FOREGROUND_COLORS[]; - + // Colors + constexpr static uint16_t BG_COLOR = ::lgfx::color565(255, 255, 255); + constexpr static uint16_t DECOR_TEXT_COLOR = ::lgfx::color565(255, 255, 255); + static const uint16_t DECOR_FOREGROUND_COLORS[]; + static const uint16_t TELOP_COLORS[]; + + private: + void drawTelop(const int16_t x, const int16_t y); + private: // Telop LGFX_Sprite* _telop; - char _str[STRING_LEN + 1/* \0 */]; + // gob::Sprite* _telop2; + // char _str[STRING_LEN + 1/* \0 */]; + std::vector _str; int16_t _twidth; - int16_t _x; + int16_t _x, _speed; // Decoration + int16_t _decorLeftWidth; LGFX_Sprite* _decorLeft; LGFX_Sprite* _decorRight; LGFX_Sprite* _logo; - // Status - Level _level; + + Color _color; bool _show; };