diff --git a/Production/Firmware/aic_pico.uf2 b/Production/Firmware/aic_pico.uf2 index cb107c9..4ebb338 100644 Binary files a/Production/Firmware/aic_pico.uf2 and b/Production/Firmware/aic_pico.uf2 differ diff --git a/firmware/include/nfc.h b/firmware/include/nfc.h index 4d9991f..faeac68 100644 --- a/firmware/include/nfc.h +++ b/firmware/include/nfc.h @@ -29,6 +29,7 @@ typedef enum { CARD_AIC_BANA, CARD_AIC_NESICA, CARD_AIC_VIRTUAL, + CARD_SUICA, CARD_MIFARE, CARD_AIME, CARD_BANA, diff --git a/firmware/src/gui.c b/firmware/src/gui.c index 41c5e30..b41f7e7 100644 --- a/firmware/src/gui.c +++ b/firmware/src/gui.c @@ -145,6 +145,8 @@ static void draw_home_card() center_image(&image_aic_nesica, -24); } else if (card_splash.card == CARD_AIC) { center_image(&image_aic_generic, -24); + } else if (card_splash.card == CARD_SUICA) { + center_image(&image_suica, -24); } else if (card_splash.card == CARD_MIFARE) { center_image(&image_mifare, -24); } else if (card_splash.card == CARD_AIME) { diff --git a/firmware/src/lib/nfc.c b/firmware/src/lib/nfc.c index d83d8b3..569c48f 100644 --- a/firmware/src/lib/nfc.c +++ b/firmware/src/lib/nfc.c @@ -375,7 +375,11 @@ nfc_card_t nfc_detect_card() update_last_card(&card); if (card.card_type == NFC_CARD_FELICA) { - update_card_name(CARD_AIC, false); + if (memcmp(card.syscode, "\x88\xB4", 2) == 0) { + update_card_name(CARD_AIC, false); + } else if (memcmp(card.syscode, "\x00\x03", 2) == 0) { + update_card_name(CARD_SUICA, true); + } } else if (card.card_type == NFC_CARD_MIFARE) { update_card_name(CARD_MIFARE, false); } else if (card.card_type == NFC_CARD_VICINITY) { @@ -522,7 +526,7 @@ bool nfc_felica_read(uint16_t svc_code, uint16_t block_id, uint8_t block_data[16 if (!api[nfc_module].felica_read) { return false; } - + bool read_ok = api[nfc_module].felica_read(svc_code, block_id, block_data); if (read_ok && (svc_code == 0x000b) && (block_id == 0x8082)) { diff --git a/firmware/src/res/image_suica.h b/firmware/src/res/image_suica.h new file mode 100644 index 0000000..96ae94b --- /dev/null +++ b/firmware/src/res/image_suica.h @@ -0,0 +1,313 @@ +const uint8_t image_suica_pixels[] = { + 0x00, 0x01, 0x01, 0x00, 0x12, 0x00, 0x22, 0x66, 0x10, 0x00, 0x00, 0x02, 0x01, 0x00, 0x15, 0x00, + 0x55, 0x67, 0x52, 0x00, 0x10, 0x00, 0x00, 0x01, 0x12, 0x00, 0x55, 0x69, 0x21, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x25, 0x00, 0x55, 0x02, 0x53, 0x00, 0x75, 0x00, 0x55, 0x64, 0x52, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x55, 0x02, 0x57, 0x00, 0xfd, 0x00, 0x36, 0x00, 0x66, 0x02, 0x65, 0x00, 0x55, 0x61, + 0x20, 0x00, 0x15, 0x00, 0x55, 0x02, 0x3f, 0x00, 0xff, 0x04, 0xf5, 0x00, 0x55, 0x61, 0x51, 0x00, + 0x15, 0x00, 0x55, 0x6b, 0x22, 0x00, 0x25, 0x00, 0x55, 0x07, 0x65, 0x00, 0x66, 0x1f, 0x56, 0x00, + 0x55, 0x41, 0x52, 0x00, 0x25, 0x00, 0x55, 0x04, 0x56, 0x00, 0x89, 0x00, 0x9a, 0x00, 0xaa, 0x21, + 0x98, 0x00, 0x65, 0x00, 0x55, 0x3f, 0x52, 0x00, 0x25, 0x00, 0x55, 0x03, 0x58, 0x00, 0xaa, 0x25, + 0xa9, 0x00, 0x75, 0x00, 0x55, 0x2c, 0x73, 0x00, 0xbf, 0x00, 0xfb, 0x00, 0xb9, 0x00, 0x99, 0x04, + 0x88, 0x00, 0x65, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, 0x56, 0x00, 0x9a, 0x00, + 0xaa, 0x26, 0xa8, 0x00, 0x55, 0x2b, 0x7f, 0x00, 0xbe, 0x00, 0xf7, 0x00, 0x3e, 0x00, 0xfb, 0x00, + 0xfa, 0x00, 0xaa, 0x04, 0xa9, 0x00, 0x65, 0x00, 0x55, 0x05, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, + 0x59, 0x00, 0xaa, 0x28, 0x95, 0x00, 0x55, 0x29, 0x5b, 0x00, 0xd6, 0x00, 0xbe, 0x00, 0xe3, 0x00, + 0xde, 0x00, 0xd7, 0x00, 0xbd, 0x00, 0xca, 0x00, 0xaa, 0x04, 0xa7, 0x00, 0x55, 0x05, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x02, 0x6a, 0x00, 0xaa, 0x28, 0xa8, 0x00, 0x55, 0x29, 0xfd, 0x00, 0xed, 0x00, + 0x7d, 0x00, 0xf6, 0x00, 0xdc, 0x00, 0x33, 0x00, 0xee, 0x00, 0xda, 0x00, 0xaa, 0x05, 0x85, 0x00, + 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, 0x9a, 0x00, 0xaa, 0x29, 0x65, 0x00, 0x55, 0x27, + 0x5b, 0x00, 0x7b, 0x00, 0xd3, 0x00, 0x3c, 0x00, 0xc7, 0x00, 0xda, 0x00, 0xf7, 0x00, 0xed, 0x00, + 0x7f, 0x00, 0xaa, 0x05, 0xa6, 0x00, 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, 0xaa, 0x2a, + 0x95, 0x00, 0x55, 0x27, 0x7d, 0x00, 0x3f, 0x00, 0xde, 0x00, 0xfa, 0x00, 0xce, 0x00, 0xea, 0x00, + 0xce, 0x00, 0xef, 0x00, 0xfb, 0x00, 0xca, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x89, 0x00, 0xaa, 0x02, + 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x56, 0x00, 0xaa, 0x2a, 0xa6, 0x00, 0x55, 0x27, + 0xbe, 0x00, 0xdc, 0x00, 0xee, 0x00, 0xca, 0x00, 0xcd, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0xdc, 0x00, + 0xcd, 0x00, 0xda, 0x00, 0x95, 0x00, 0x55, 0x01, 0x8a, 0x00, 0xaa, 0x01, 0x75, 0x00, 0x55, 0x03, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x57, 0x00, 0xaa, 0x2a, 0xa8, 0x00, 0x55, 0x27, 0xf3, 0x00, + 0xcc, 0x00, 0x6f, 0x00, 0xaa, 0x00, 0x96, 0x00, 0x67, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x66, 0x00, + 0x55, 0x01, 0x57, 0x00, 0xaa, 0x01, 0x95, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x58, 0x00, 0xaa, 0x2b, 0x55, 0x26, 0x57, 0x00, 0x3b, 0x00, 0xad, 0x00, 0x4f, 0x00, 0xaa, 0x00, + 0x65, 0x00, 0x86, 0x00, 0xaa, 0x00, 0x9a, 0x00, 0xa9, 0x00, 0xa6, 0x00, 0x68, 0x00, 0x55, 0x00, + 0x56, 0x00, 0x55, 0x00, 0x99, 0x00, 0x89, 0x00, 0xa5, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x58, 0x00, 0xaa, 0x2b, 0x75, 0x00, 0x55, 0x25, 0x53, 0x00, 0xfd, 0x00, 0xad, 0x00, + 0xdd, 0x00, 0xaa, 0x00, 0x64, 0x00, 0x58, 0x00, 0xaa, 0x00, 0x66, 0x00, 0x84, 0x00, 0x95, 0x00, + 0x68, 0x00, 0x55, 0x00, 0x99, 0x00, 0x95, 0x00, 0x78, 0x00, 0x64, 0x00, 0x96, 0x00, 0x55, 0x03, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2b, 0x95, 0x00, 0x55, 0x25, 0x53, 0x00, + 0xed, 0x00, 0xad, 0x00, 0xef, 0x00, 0xaa, 0x00, 0xa8, 0x00, 0x64, 0x00, 0x9a, 0x00, 0x56, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x79, 0x00, 0x56, 0x00, 0x96, 0x00, 0x55, 0x00, 0x66, 0x00, 0x64, 0x00, + 0x86, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2b, 0xa6, 0x00, + 0x55, 0x25, 0x57, 0x00, 0x3f, 0x00, 0xad, 0x00, 0x6d, 0x00, 0xaa, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x9a, 0x00, 0x65, 0x00, 0x64, 0x00, 0x95, 0x00, 0x69, 0x00, 0x55, 0x00, 0x99, 0x00, 0x85, 0x00, + 0x84, 0x00, 0x75, 0x00, 0x76, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x2b, 0xa8, 0x00, 0x55, 0x25, 0x57, 0x00, 0x33, 0x00, 0xaf, 0x00, 0x5f, 0x00, 0xaa, 0x00, + 0x98, 0x00, 0x69, 0x00, 0xaa, 0x00, 0x96, 0x00, 0x88, 0x00, 0xa6, 0x00, 0x56, 0x00, 0x55, 0x00, + 0x56, 0x00, 0x65, 0x00, 0x96, 0x00, 0x88, 0x00, 0x95, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2c, 0x55, 0x26, 0xfd, 0x00, 0xcc, 0x00, 0xfd, 0x00, 0xaa, 0x00, + 0xca, 0x01, 0xac, 0x01, 0xaa, 0x00, 0xb9, 0x00, 0x55, 0x02, 0x57, 0x00, 0xaa, 0x01, 0x85, 0x00, + 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2c, 0x75, 0x00, 0x55, 0x25, + 0x3e, 0x00, 0xdc, 0x00, 0xee, 0x00, 0xca, 0x00, 0xce, 0x00, 0xea, 0x00, 0xad, 0x00, 0xef, 0x00, + 0xce, 0x00, 0xda, 0x00, 0x86, 0x00, 0x55, 0x01, 0x8a, 0x00, 0xaa, 0x01, 0x65, 0x00, 0x55, 0x03, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2c, 0x95, 0x00, 0x55, 0x25, 0x6f, 0x00, + 0x7f, 0x00, 0xdb, 0x00, 0xfa, 0x00, 0xc3, 0x00, 0xda, 0x00, 0xc3, 0x00, 0xdf, 0x00, 0xb3, 0x00, + 0xca, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x89, 0x00, 0xaa, 0x01, 0xa9, 0x00, 0x55, 0x04, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2c, 0xa6, 0x00, 0x55, 0x25, 0x53, 0x00, 0x3b, 0x00, + 0xe3, 0x00, 0x7c, 0x00, 0xc7, 0x00, 0xda, 0x00, 0xf5, 0x00, 0xde, 0x00, 0x7f, 0x00, 0xaa, 0x05, + 0x96, 0x00, 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2c, 0xa8, 0x00, + 0x55, 0x26, 0x3e, 0x00, 0xef, 0x00, 0xbe, 0x00, 0xd5, 0x00, 0xdf, 0x01, 0xfe, 0x00, 0xda, 0x00, + 0xaa, 0x05, 0x65, 0x00, 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2d, + 0x65, 0x00, 0x55, 0x25, 0x57, 0x00, 0xf7, 0x00, 0x3e, 0x00, 0xed, 0x00, 0xee, 0x00, 0xf6, 0x00, + 0xbc, 0x00, 0xaa, 0x05, 0x95, 0x00, 0x55, 0x05, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x2d, 0x75, 0x00, 0x55, 0x26, 0x63, 0x00, 0xde, 0x00, 0xf7, 0x00, 0x3e, 0x00, 0xec, 0x00, + 0xca, 0x00, 0xaa, 0x04, 0x96, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x2d, 0x95, 0x00, 0x55, 0x27, 0x56, 0x00, 0x73, 0x00, 0x37, 0x00, 0x77, 0x00, 0x67, 0x02, + 0x76, 0x01, 0x66, 0x00, 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2d, + 0xa6, 0x00, 0x55, 0x31, 0x65, 0x00, 0x55, 0x00, 0x65, 0x00, 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2d, 0xa8, 0x00, 0x55, 0x30, 0x58, 0x00, 0xa9, 0x00, 0x57, 0x00, + 0xa9, 0x00, 0x65, 0x00, 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2e, + 0x65, 0x00, 0x55, 0x2f, 0x59, 0x00, 0xaa, 0x00, 0x68, 0x00, 0xaa, 0x00, 0x65, 0x00, 0x55, 0x03, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2e, 0x75, 0x00, 0x55, 0x2f, 0x56, 0x00, + 0x87, 0x00, 0x56, 0x00, 0x88, 0x00, 0x55, 0x04, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x2e, 0x95, 0x00, 0x55, 0x38, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2e, + 0xa6, 0x00, 0x55, 0x38, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2e, 0xa9, 0x00, + 0x55, 0x38, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2f, 0x55, 0x38, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2f, 0x85, 0x00, 0x55, 0x37, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x2f, 0x95, 0x00, 0x55, 0x37, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x2f, 0xa6, 0x00, 0x55, 0x37, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x2f, 0xa9, 0x00, 0x55, 0x37, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x30, + 0x65, 0x00, 0x55, 0x36, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x30, 0x85, 0x00, + 0x55, 0x36, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x30, 0x95, 0x00, 0x55, 0x36, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x30, 0xa6, 0x00, 0x55, 0x36, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x30, 0xa9, 0x00, 0x55, 0x36, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x31, 0x65, 0x00, 0x55, 0x35, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x31, 0x85, 0x00, 0x55, 0x35, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x31, 0x95, 0x00, 0x55, 0x35, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x31, + 0xa7, 0x00, 0x55, 0x35, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x31, 0xa9, 0x00, + 0x55, 0x35, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x32, 0x65, 0x00, 0x55, 0x34, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x32, 0x85, 0x00, 0x55, 0x34, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x32, 0xa5, 0x00, 0x55, 0x34, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x32, 0xa7, 0x00, 0x55, 0x34, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x32, 0xa9, 0x00, 0x55, 0x34, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x33, 0x65, 0x00, 0x55, 0x33, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x33, + 0x85, 0x00, 0x55, 0x33, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x33, 0xa5, 0x00, + 0x55, 0x33, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x33, 0xa7, 0x00, 0x55, 0x33, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x33, 0xa9, 0x00, 0x55, 0x33, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x34, 0x65, 0x00, 0x55, 0x32, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x34, 0x85, 0x00, 0x55, 0x32, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x34, 0xa5, 0x00, 0x55, 0x32, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x34, 0xa7, 0x00, 0x55, 0x32, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x34, + 0xa9, 0x00, 0x55, 0x32, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x35, 0x65, 0x00, + 0x55, 0x31, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x35, 0x85, 0x00, 0x55, 0x31, + 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x35, 0xa5, 0x00, 0x55, 0x31, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x35, 0xa7, 0x00, 0x55, 0x31, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x35, 0xa9, 0x00, 0x55, 0x31, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x36, 0x65, 0x00, 0x55, 0x30, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x36, 0x85, 0x00, 0x55, 0x30, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x36, + 0xa6, 0x00, 0x55, 0x1d, 0x66, 0x00, 0x37, 0x00, 0x75, 0x00, 0x55, 0x0f, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x36, 0xa7, 0x00, 0x55, 0x1c, 0x7f, 0x00, 0xee, 0x01, 0xed, 0x00, + 0xb5, 0x00, 0x55, 0x0e, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x36, 0xa9, 0x00, + 0x55, 0x1b, 0x5b, 0x00, 0xee, 0x03, 0xed, 0x00, 0x75, 0x00, 0x55, 0x0d, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x37, 0x65, 0x00, 0x55, 0x1a, 0xbe, 0x00, 0xee, 0x04, 0xd6, 0x00, + 0x55, 0x0d, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x37, 0x85, 0x00, 0x55, 0x19, + 0x57, 0x00, 0xee, 0x05, 0xeb, 0x00, 0x55, 0x0d, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x37, 0xa6, 0x00, 0x55, 0x19, 0x5b, 0x00, 0xee, 0x03, 0xd6, 0x00, 0x5b, 0x00, 0xed, 0x00, + 0x65, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x37, 0xa7, 0x00, + 0x55, 0x19, 0x6d, 0x00, 0xb6, 0x00, 0x6d, 0x00, 0xee, 0x01, 0x33, 0x00, 0xd6, 0x00, 0xee, 0x00, + 0x75, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x37, 0xa9, 0x00, + 0x55, 0x19, 0x6e, 0x00, 0x6f, 0x00, 0x33, 0x00, 0xd7, 0x00, 0x63, 0x00, 0xf5, 0x00, 0x63, 0x00, + 0xee, 0x00, 0x35, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x38, + 0x65, 0x00, 0x55, 0x18, 0x7e, 0x00, 0x37, 0x00, 0x5f, 0x00, 0x54, 0x00, 0x46, 0x00, 0x7d, 0x00, + 0xfe, 0x00, 0xee, 0x00, 0x35, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x38, 0x95, 0x00, 0x55, 0x18, 0x7e, 0x00, 0xeb, 0x00, 0xfd, 0x00, 0x5b, 0x00, 0x33, 0x00, + 0x6e, 0x00, 0xee, 0x01, 0x35, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x38, 0x96, 0x00, 0x55, 0x18, 0x5e, 0x00, 0xee, 0x01, 0x74, 0x00, 0x44, 0x00, 0xbe, 0x00, + 0xee, 0x01, 0x35, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x38, + 0xa8, 0x00, 0x55, 0x18, 0x5f, 0x00, 0xee, 0x01, 0xeb, 0x00, 0x3d, 0x00, 0xee, 0x02, 0xb5, 0x00, + 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x38, 0xa9, 0x00, 0x55, 0x18, + 0x57, 0x00, 0xee, 0x06, 0xeb, 0x00, 0x55, 0x0c, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x39, 0x65, 0x00, 0x55, 0x18, 0xbe, 0x00, 0xee, 0x06, 0x35, 0x00, 0x55, 0x0b, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x39, 0x95, 0x00, 0x55, 0x18, 0x6f, 0x00, 0xee, 0x02, + 0xff, 0x00, 0xee, 0x02, 0xe3, 0x00, 0x55, 0x0b, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x39, 0xa6, 0x00, 0x55, 0x18, 0x5f, 0x00, 0x75, 0x00, 0x45, 0x00, 0x44, 0x01, 0x3e, 0x00, + 0xee, 0x02, 0x35, 0x00, 0x55, 0x0a, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x39, + 0xa7, 0x00, 0x55, 0x18, 0x5d, 0x00, 0x64, 0x00, 0x44, 0x02, 0x5d, 0x00, 0xee, 0x02, 0xe7, 0x00, + 0x55, 0x0a, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x39, 0xa9, 0x00, 0x55, 0x12, + 0x56, 0x00, 0xbb, 0x00, 0x65, 0x00, 0x55, 0x02, 0x5e, 0x00, 0x44, 0x03, 0x43, 0x00, 0xee, 0x02, + 0xed, 0x00, 0x75, 0x00, 0x55, 0x09, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3a, + 0x65, 0x00, 0x55, 0x11, 0x57, 0x00, 0xee, 0x00, 0xd7, 0x00, 0x55, 0x02, 0x6d, 0x00, 0x44, 0x03, + 0x45, 0x00, 0xee, 0x03, 0xd6, 0x00, 0x55, 0x09, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x3a, 0x95, 0x00, 0x55, 0x11, 0x56, 0x00, 0xde, 0x00, 0xee, 0x00, 0x35, 0x00, 0x55, 0x01, + 0x7f, 0x00, 0x44, 0x04, 0xbe, 0x00, 0xee, 0x02, 0xef, 0x00, 0x75, 0x00, 0x55, 0x08, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3a, 0xa6, 0x00, 0x55, 0x12, 0x3e, 0x00, 0xee, 0x00, + 0xef, 0x00, 0x65, 0x00, 0x55, 0x00, 0xbb, 0x00, 0x44, 0x04, 0x7e, 0x00, 0xee, 0x03, 0xd3, 0x00, + 0x55, 0x08, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3a, 0xa8, 0x00, 0x55, 0x12, + 0x5f, 0x00, 0xee, 0x01, 0xdb, 0x00, 0x3b, 0x00, 0xe3, 0x00, 0x44, 0x04, 0x5d, 0x00, 0xee, 0x01, + 0xbf, 0x00, 0xee, 0x01, 0xb6, 0x00, 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x3b, 0x55, 0x13, 0xde, 0x00, 0xee, 0x02, 0xe3, 0x00, 0x44, 0x04, 0x43, 0x00, 0xee, 0x01, + 0x54, 0x00, 0x53, 0x00, 0xde, 0x00, 0xed, 0x00, 0x75, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3b, 0x65, 0x00, 0x55, 0x12, 0x7d, 0x00, 0xee, 0x02, 0xe3, 0x00, + 0x44, 0x04, 0x46, 0x00, 0xee, 0x01, 0xb4, 0x00, 0x44, 0x00, 0x5b, 0x00, 0xee, 0x00, 0xe7, 0x00, + 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3b, 0x95, 0x00, 0x55, 0x12, + 0x57, 0x00, 0xde, 0x00, 0xee, 0x01, 0xe3, 0x00, 0x44, 0x05, 0xfe, 0x00, 0xee, 0x00, 0xef, 0x00, + 0x64, 0x00, 0x44, 0x00, 0x7d, 0x00, 0xee, 0x00, 0x35, 0x00, 0x55, 0x05, 0x51, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3b, 0xa6, 0x00, 0x55, 0x13, 0x7f, 0x00, 0xee, 0x01, 0xef, 0x00, + 0x44, 0x05, 0x6e, 0x00, 0xee, 0x01, 0xeb, 0x00, 0x54, 0x00, 0x45, 0x00, 0xfe, 0x00, 0xe7, 0x00, + 0x55, 0x05, 0x20, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x3b, 0xa8, 0x00, 0x55, 0x14, + 0xbd, 0x00, 0xee, 0x00, 0xed, 0x00, 0x44, 0x05, 0x4b, 0x00, 0xee, 0x02, 0xeb, 0x00, 0x54, 0x00, + 0x4b, 0x00, 0xee, 0x00, 0x75, 0x00, 0x55, 0x04, 0x10, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x05, 0x98, 0x00, 0x66, 0x01, 0x78, 0x00, 0x89, 0x00, 0xaa, 0x13, 0xa8, 0x00, 0x88, 0x02, + 0xaa, 0x19, 0x55, 0x15, 0x77, 0x00, 0x6d, 0x00, 0x54, 0x00, 0x44, 0x04, 0x45, 0x00, 0xde, 0x00, + 0xee, 0x02, 0xe3, 0x00, 0x54, 0x00, 0x3e, 0x00, 0xd5, 0x00, 0x55, 0x03, 0x52, 0x00, 0x10, 0x00, + 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x04, 0x85, 0x00, 0x44, 0x04, 0x46, 0x00, 0x8a, 0x00, + 0xaa, 0x11, 0x94, 0x00, 0x44, 0x01, 0x45, 0x00, 0xaa, 0x19, 0x75, 0x00, 0x55, 0x15, 0x5f, 0x00, + 0x74, 0x00, 0x44, 0x05, 0x6e, 0x00, 0xee, 0x03, 0xd7, 0x00, 0x53, 0x00, 0xeb, 0x00, 0x55, 0x03, + 0x51, 0x00, 0x00, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x44, 0x06, + 0x6a, 0x00, 0xaa, 0x11, 0x94, 0x00, 0x69, 0x00, 0x99, 0x00, 0x55, 0x00, 0xaa, 0x19, 0x95, 0x00, + 0x55, 0x15, 0x57, 0x00, 0xf4, 0x00, 0x44, 0x05, 0x43, 0x00, 0xee, 0x04, 0x35, 0x00, 0xbe, 0x00, + 0x75, 0x00, 0x55, 0x02, 0x51, 0x00, 0x00, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x03, + 0x74, 0x00, 0x44, 0x06, 0x6a, 0x00, 0xaa, 0x11, 0x94, 0x00, 0x8a, 0x00, 0xaa, 0x00, 0x56, 0x00, + 0xaa, 0x19, 0xa6, 0x00, 0x55, 0x15, 0x56, 0x00, 0xd5, 0x00, 0x44, 0x06, 0x3e, 0x00, 0xee, 0x03, + 0xbf, 0x00, 0x6f, 0x00, 0xf5, 0x00, 0x55, 0x02, 0x52, 0x00, 0x00, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x02, 0x56, 0x00, 0x66, 0x00, 0x54, 0x00, 0x44, 0x01, + 0x6a, 0x00, 0xaa, 0x11, 0x94, 0x00, 0x45, 0x00, 0x55, 0x00, 0x45, 0x00, 0xaa, 0x19, 0xa8, 0x00, + 0x55, 0x16, 0xb3, 0x00, 0x44, 0x06, 0x4b, 0x00, 0xee, 0x03, 0x37, 0x00, 0xf3, 0x00, 0xe7, 0x00, + 0x55, 0x02, 0x52, 0x00, 0x00, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, 0xa8, 0x00, + 0x44, 0x01, 0x46, 0x00, 0xaa, 0x02, 0x97, 0x00, 0x64, 0x00, 0x6a, 0x00, 0xaa, 0x11, 0xa5, 0x00, + 0x65, 0x00, 0x55, 0x00, 0x66, 0x00, 0xaa, 0x07, 0x99, 0x00, 0x89, 0x00, 0x9a, 0x00, 0xaa, 0x0f, + 0x55, 0x16, 0x7d, 0x00, 0x54, 0x00, 0x44, 0x06, 0xbe, 0x00, 0xee, 0x02, 0xf5, 0x00, 0x6f, 0x00, + 0xe3, 0x00, 0x55, 0x02, 0x52, 0x00, 0x00, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, + 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x03, 0xa9, 0x00, 0x8a, 0x00, 0xaa, 0x12, 0x9a, 0x02, + 0xaa, 0x05, 0xa9, 0x00, 0x65, 0x00, 0x44, 0x02, 0x56, 0x00, 0x8a, 0x00, 0xaa, 0x05, 0x97, 0x00, + 0x66, 0x01, 0x89, 0x00, 0xaa, 0x03, 0x75, 0x00, 0x55, 0x15, 0x5b, 0x00, 0x34, 0x00, 0x44, 0x06, + 0x5d, 0x00, 0xee, 0x02, 0xe7, 0x00, 0x55, 0x00, 0x33, 0x00, 0x55, 0x03, 0x10, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, 0xa6, 0x00, 0x44, 0x01, 0x47, 0x00, 0xaa, 0x09, 0xa7, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0xa4, 0x00, 0x44, 0x01, 0x7a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x44, 0x01, 0x45, 0x00, 0xaa, 0x05, 0x74, 0x00, 0x44, 0x00, 0x66, 0x00, 0x78, 0x00, 0x66, 0x00, + 0x54, 0x00, 0x6a, 0x00, 0xaa, 0x03, 0xa9, 0x00, 0x64, 0x00, 0x44, 0x03, 0x69, 0x00, 0xaa, 0x02, + 0x95, 0x00, 0x55, 0x15, 0x56, 0x00, 0xe5, 0x00, 0x44, 0x06, 0x46, 0x00, 0xee, 0x02, 0xe3, 0x00, + 0x55, 0x05, 0x10, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, 0xa7, 0x00, 0x44, 0x02, + 0x69, 0x00, 0xaa, 0x08, 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0x94, 0x00, 0x44, 0x01, + 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x68, 0x00, 0x87, 0x00, 0x46, 0x00, 0xaa, 0x04, 0xa6, 0x00, + 0x44, 0x00, 0x8a, 0x00, 0xaa, 0x02, 0xa4, 0x00, 0x5a, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x44, 0x05, + 0x9a, 0x00, 0xaa, 0x01, 0xa6, 0x00, 0x55, 0x16, 0xbb, 0x00, 0x44, 0x07, 0x3e, 0x00, 0xee, 0x01, + 0xeb, 0x00, 0x55, 0x05, 0x10, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, 0xa9, 0x00, + 0x44, 0x03, 0x46, 0x00, 0x68, 0x00, 0x9a, 0x00, 0xaa, 0x05, 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, + 0xaa, 0x01, 0xa4, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, + 0x55, 0x00, 0xaa, 0x04, 0x64, 0x00, 0x59, 0x00, 0xaa, 0x00, 0xa8, 0x00, 0x77, 0x00, 0x89, 0x00, + 0xa5, 0x00, 0x5a, 0x00, 0xaa, 0x03, 0xa8, 0x00, 0x44, 0x00, 0x45, 0x00, 0x65, 0x00, 0x54, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0xa8, 0x00, 0x55, 0x16, 0x5d, 0x00, 0x74, 0x00, 0x44, 0x06, + 0x4d, 0x00, 0xee, 0x02, 0x55, 0x05, 0x10, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x03, + 0x64, 0x00, 0x44, 0x04, 0x45, 0x00, 0x8a, 0x00, 0xaa, 0x04, 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, + 0xaa, 0x01, 0x94, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, + 0x55, 0x00, 0xaa, 0x03, 0xa9, 0x00, 0x45, 0x00, 0x9a, 0x00, 0xa9, 0x00, 0x54, 0x00, 0x44, 0x02, + 0x4a, 0x00, 0xaa, 0x04, 0x58, 0x00, 0x9a, 0x00, 0xaa, 0x00, 0xa8, 0x00, 0x44, 0x01, 0x48, 0x00, + 0xaa, 0x02, 0x55, 0x16, 0x57, 0x00, 0xd5, 0x00, 0x44, 0x06, 0x47, 0x00, 0xee, 0x02, 0x65, 0x00, + 0x55, 0x04, 0x20, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x03, 0xa5, 0x00, 0x44, 0x05, + 0x46, 0x00, 0xaa, 0x04, 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0xa4, 0x00, 0x44, 0x01, + 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa, 0x03, 0xa6, 0x00, + 0x48, 0x00, 0xaa, 0x00, 0xa5, 0x00, 0x47, 0x00, 0x9a, 0x00, 0x88, 0x00, 0x54, 0x00, 0x4a, 0x00, + 0xaa, 0x08, 0x64, 0x00, 0x44, 0x00, 0x47, 0x00, 0xaa, 0x02, 0x75, 0x00, 0x55, 0x16, 0xbb, 0x00, + 0x44, 0x07, 0xde, 0x00, 0xee, 0x01, 0x35, 0x00, 0x55, 0x03, 0x52, 0x00, 0x20, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x04, 0x64, 0x00, 0x44, 0x05, 0x6a, 0x00, 0xaa, 0x03, 0xa6, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0x94, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x46, 0x00, 0xaa, 0x03, 0xa4, 0x00, 0x5a, 0x00, 0xaa, 0x00, 0x74, 0x00, + 0x8a, 0x00, 0xaa, 0x01, 0xa9, 0x00, 0x6a, 0x00, 0xaa, 0x08, 0x64, 0x00, 0x44, 0x00, 0x46, 0x00, + 0xaa, 0x02, 0x95, 0x00, 0x55, 0x16, 0x5f, 0x00, 0x34, 0x00, 0x44, 0x06, 0x3e, 0x00, 0xee, 0x01, + 0x35, 0x00, 0x55, 0x04, 0x20, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x04, 0xa9, 0x00, + 0x64, 0x00, 0x44, 0x04, 0x48, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, + 0xa4, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, + 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x64, 0x00, 0xaa, 0x0a, 0x88, 0x00, 0x66, 0x01, + 0x64, 0x00, 0x44, 0x00, 0x47, 0x00, 0xaa, 0x02, 0xa6, 0x00, 0x55, 0x16, 0x57, 0x00, 0xd6, 0x00, + 0x44, 0x06, 0x6e, 0x00, 0xee, 0x01, 0xf5, 0x00, 0x55, 0x04, 0x21, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x06, 0x96, 0x00, 0x64, 0x00, 0x44, 0x02, 0x46, 0x00, 0xaa, 0x03, 0xa6, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0x94, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x46, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x45, 0x00, + 0xaa, 0x09, 0x65, 0x00, 0x44, 0x04, 0x47, 0x00, 0xaa, 0x02, 0xa8, 0x00, 0x55, 0x17, 0x3f, 0x00, + 0x54, 0x00, 0x44, 0x05, 0x5e, 0x00, 0xee, 0x01, 0xd5, 0x00, 0x55, 0x04, 0x51, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x08, 0x95, 0x00, 0x44, 0x01, 0x45, 0x00, 0xaa, 0x03, 0xa6, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0xa4, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa, 0x03, 0xa4, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, + 0xaa, 0x08, 0x95, 0x00, 0x44, 0x05, 0x48, 0x00, 0xaa, 0x03, 0x55, 0x17, 0x5b, 0x00, 0xb4, 0x00, + 0x44, 0x05, 0x5e, 0x00, 0xee, 0x01, 0xef, 0x00, 0x75, 0x00, 0x55, 0x03, 0x51, 0x00, 0x25, 0x00, + 0x55, 0x01, 0x59, 0x00, 0xaa, 0x09, 0x44, 0x01, 0x45, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x44, 0x01, + 0x4a, 0x00, 0xaa, 0x01, 0x94, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, + 0xaa, 0x00, 0x46, 0x00, 0xaa, 0x03, 0xa4, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x64, 0x00, 0x9a, 0x00, + 0xaa, 0x07, 0x64, 0x00, 0x44, 0x01, 0x69, 0x00, 0x9a, 0x00, 0x64, 0x00, 0x44, 0x00, 0x47, 0x00, + 0xaa, 0x03, 0x75, 0x00, 0x55, 0x17, 0xf6, 0x00, 0x44, 0x05, 0x5e, 0x00, 0xee, 0x02, 0xeb, 0x00, + 0x65, 0x00, 0x55, 0x02, 0x51, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, 0xaa, 0x02, 0xa9, 0x00, + 0x68, 0x00, 0x9a, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x01, 0x45, 0x00, 0xaa, 0x03, 0xa6, 0x00, + 0x44, 0x01, 0x4a, 0x00, 0xaa, 0x01, 0xa4, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x49, 0x00, 0xaa, 0x00, 0x84, 0x00, + 0x5a, 0x00, 0xaa, 0x01, 0xa9, 0x00, 0x6a, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x01, 0x47, 0x00, + 0xaa, 0x01, 0x64, 0x00, 0x44, 0x00, 0x48, 0x00, 0xaa, 0x03, 0x95, 0x00, 0x55, 0x17, 0x7f, 0x00, + 0x44, 0x05, 0x5e, 0x00, 0xee, 0x03, 0xf5, 0x00, 0x55, 0x02, 0x51, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x59, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x00, 0x45, 0x00, 0x69, 0x00, 0x9a, 0x00, 0xa9, 0x00, + 0x84, 0x00, 0x44, 0x01, 0x46, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x44, 0x01, 0x49, 0x00, 0xaa, 0x01, + 0x84, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x46, 0x00, + 0xaa, 0x03, 0xa8, 0x00, 0x47, 0x00, 0xaa, 0x00, 0xa6, 0x00, 0x45, 0x00, 0x78, 0x00, 0x86, 0x00, + 0x54, 0x00, 0x4a, 0x00, 0xaa, 0x02, 0xa8, 0x00, 0x44, 0x01, 0x49, 0x00, 0xaa, 0x01, 0x64, 0x00, + 0x44, 0x00, 0x47, 0x00, 0xaa, 0x03, 0xa6, 0x00, 0x55, 0x17, 0x5b, 0x00, 0x74, 0x00, 0x44, 0x04, + 0x5e, 0x00, 0xee, 0x03, 0x35, 0x00, 0x55, 0x02, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x59, 0x00, + 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x02, 0x45, 0x00, 0x44, 0x03, 0x49, 0x00, 0xaa, 0x03, 0xa8, 0x00, + 0x44, 0x01, 0x46, 0x00, 0x99, 0x00, 0x86, 0x00, 0x44, 0x02, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa, 0x04, 0x54, 0x00, 0x9a, 0x00, 0xaa, 0x00, 0x84, 0x00, + 0x44, 0x01, 0x54, 0x00, 0x5a, 0x00, 0xaa, 0x02, 0xa8, 0x00, 0x44, 0x01, 0x48, 0x00, 0xaa, 0x00, + 0x98, 0x00, 0x44, 0x01, 0x46, 0x00, 0xaa, 0x03, 0xa8, 0x00, 0x55, 0x17, 0x53, 0x00, 0x34, 0x00, + 0x44, 0x04, 0x6e, 0x00, 0xee, 0x02, 0xeb, 0x00, 0x55, 0x03, 0x22, 0x00, 0x25, 0x00, 0x55, 0x01, + 0x58, 0x00, 0xaa, 0x03, 0x44, 0x07, 0x6a, 0x00, 0xaa, 0x04, 0x54, 0x00, 0x44, 0x06, 0x6a, 0x00, + 0xaa, 0x03, 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x00, 0x46, 0x00, 0xaa, 0x04, 0x84, 0x00, 0x49, 0x00, + 0xaa, 0x01, 0x98, 0x00, 0x89, 0x00, 0xa4, 0x00, 0x5a, 0x00, 0xaa, 0x02, 0xa9, 0x00, 0x44, 0x02, + 0x55, 0x00, 0x44, 0x03, 0x8a, 0x00, 0xaa, 0x03, 0x55, 0x15, 0x5b, 0x00, 0x35, 0x00, 0x57, 0x00, + 0xb4, 0x00, 0x44, 0x03, 0x7f, 0x00, 0xdf, 0x00, 0xef, 0x00, 0xff, 0x00, 0xbb, 0x00, 0x75, 0x00, + 0x55, 0x03, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x58, 0x00, 0xaa, 0x03, 0x44, 0x06, 0x46, 0x00, + 0xaa, 0x05, 0x94, 0x00, 0x44, 0x03, 0x45, 0x00, 0x44, 0x01, 0x6a, 0x00, 0xaa, 0x03, 0x94, 0x00, + 0x6a, 0x00, 0xaa, 0x00, 0x55, 0x00, 0xaa, 0x04, 0xa8, 0x00, 0x44, 0x00, 0x69, 0x00, 0xaa, 0x02, + 0x94, 0x00, 0x6a, 0x00, 0xaa, 0x03, 0x64, 0x00, 0x44, 0x05, 0x45, 0x00, 0x9a, 0x00, 0xaa, 0x03, + 0x85, 0x00, 0x55, 0x14, 0x7e, 0x00, 0xe3, 0x00, 0x57, 0x00, 0xb4, 0x00, 0x44, 0x02, 0x6b, 0x00, + 0xd7, 0x00, 0x57, 0x00, 0xb5, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x57, 0x00, + 0xaa, 0x03, 0x65, 0x00, 0x44, 0x04, 0x45, 0x00, 0x8a, 0x00, 0xaa, 0x05, 0xa9, 0x00, 0x54, 0x00, + 0x44, 0x01, 0x45, 0x00, 0x8a, 0x00, 0x44, 0x01, 0x8a, 0x00, 0xaa, 0x03, 0x94, 0x00, 0x45, 0x02, + 0xaa, 0x05, 0x85, 0x00, 0x44, 0x00, 0x66, 0x02, 0x44, 0x00, 0x6a, 0x00, 0xaa, 0x03, 0x95, 0x00, + 0x44, 0x02, 0x46, 0x00, 0x8a, 0x00, 0x54, 0x00, 0x59, 0x00, 0xaa, 0x04, 0x95, 0x00, 0x55, 0x14, + 0x5f, 0x00, 0xee, 0x00, 0xfd, 0x00, 0x74, 0x00, 0x44, 0x01, 0x6b, 0x00, 0xd3, 0x00, 0x45, 0x00, + 0x4d, 0x00, 0x65, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x01, 0x56, 0x00, 0xaa, 0x04, + 0xa9, 0x00, 0x87, 0x00, 0x66, 0x01, 0x68, 0x00, 0x9a, 0x00, 0xaa, 0x07, 0xa8, 0x00, 0x65, 0x00, + 0x66, 0x00, 0x8a, 0x00, 0xaa, 0x07, 0xa6, 0x00, 0x66, 0x01, 0x68, 0x00, 0xaa, 0x05, 0xa9, 0x00, + 0x85, 0x00, 0x44, 0x02, 0x56, 0x00, 0x9a, 0x00, 0xaa, 0x03, 0xa9, 0x00, 0x85, 0x00, 0x55, 0x00, + 0x68, 0x00, 0x9a, 0x00, 0xaa, 0x00, 0xa6, 0x00, 0xaa, 0x05, 0xa5, 0x00, 0x55, 0x15, 0xfe, 0x00, + 0xee, 0x00, 0xb7, 0x00, 0x77, 0x00, 0x3f, 0x00, 0xbb, 0x00, 0xf6, 0x00, 0x44, 0x00, 0x5b, 0x00, + 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, 0xaa, 0x2a, 0x99, 0x00, 0x89, 0x00, 0x9a, 0x00, + 0xaa, 0x12, 0xa5, 0x00, 0x55, 0x15, 0x5b, 0x00, 0xee, 0x00, 0xb3, 0x00, 0x37, 0x00, 0x75, 0x00, + 0x55, 0x00, 0x7b, 0x00, 0xb6, 0x00, 0x33, 0x00, 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, + 0x8a, 0x00, 0xaa, 0x3f, 0x95, 0x00, 0x55, 0x15, 0x53, 0x00, 0xeb, 0x00, 0x55, 0x04, 0x3d, 0x00, + 0xe3, 0x00, 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x02, 0x59, 0x00, 0xaa, 0x3f, 0x65, 0x00, + 0x55, 0x15, 0x57, 0x00, 0x35, 0x00, 0x55, 0x04, 0x5d, 0x00, 0xef, 0x00, 0x55, 0x07, 0x52, 0x00, + 0x25, 0x00, 0x55, 0x02, 0x56, 0x00, 0x9a, 0x00, 0xaa, 0x3d, 0xa7, 0x00, 0x55, 0x1c, 0x57, 0x00, + 0xfe, 0x00, 0xee, 0x00, 0x75, 0x00, 0x55, 0x06, 0x52, 0x00, 0x25, 0x00, 0x55, 0x03, 0x58, 0x00, + 0x9a, 0x00, 0xaa, 0x3b, 0xa8, 0x00, 0x65, 0x00, 0x55, 0x1c, 0x7e, 0x00, 0xef, 0x00, 0xbe, 0x00, + 0x55, 0x07, 0x52, 0x00, 0x25, 0x00, 0x55, 0x04, 0x56, 0x00, 0x67, 0x00, 0x88, 0x39, 0x76, 0x00, + 0x55, 0x1e, 0x63, 0x00, 0x36, 0x00, 0x55, 0x08, 0x52, 0x00, 0x22, 0x00, 0x55, 0x6b, 0x52, 0x00, + 0x15, 0x00, 0x55, 0x6b, 0x51, 0x00, 0x12, 0x00, 0x55, 0x6b, 0x21, 0x00, 0x01, 0x00, 0x55, 0x6b, + 0x10, 0x00, 0x00, 0x00, 0x15, 0x00, 0x55, 0x69, 0x51, 0x00, 0x00, 0x01, 0x01, 0x00, 0x25, 0x00, + 0x55, 0x68, 0x10, 0x00, 0x00, 0x02, 0x11, 0x00, 0x22, 0x67, 0x11, 0x00, 0x00, 0x01, +}; + +const uint32_t image_suica_pal[] = { + // image_suica_pal Pallete (RGB565A8*16) + 0x000000, 0x41ef5d, 0xd2e73c, 0xff9cf3, + 0xffffff, 0xfee73c, 0xffcef7, 0xffbe55, + 0xffa650, 0xff85eb, 0xff6dc5, 0xff7bef, + 0xff53a6, 0xff31a5, 0xff0000, 0xff5aeb, +}; + +const image_t image_suica = { + .width = 220, + .height = 138, + + .pixels = { + .input = image_suica_pixels, + .bits = 4, + .size = sizeof(image_suica_pixels), + .encoding = RLE_RLE, + }, + .pallete = image_suica_pal, +}; diff --git a/firmware/src/res/resource.h b/firmware/src/res/resource.h index 3ab1db5..cf28d8d 100644 --- a/firmware/src/res/resource.h +++ b/firmware/src/res/resource.h @@ -12,6 +12,7 @@ #include "image_aic_konami.h" #include "image_aic_sega.h" #include "image_aic_nesica.h" +#include "image_suica.h" #include "image_mifare.h" #include "image_bana.h" #include "image_aime.h" diff --git a/firmware/tools/image_conv.c b/firmware/tools/image_conv.c index abec91e..0ac2842 100644 --- a/firmware/tools/image_conv.c +++ b/firmware/tools/image_conv.c @@ -3,6 +3,10 @@ * RLE or RLE X can be used. * ENCODE and ENCODE_X are for compression. * ENCODE_PAL converts a 256-color pallete) from 32bit RGBA to RGB565A8. + * + * Transparent PNG is converted by https://lvgl.io/tools/imageconverter, + * Use indexed 8bit or 4bit. + * Even if the image is in 4bit, you can still use RLE 8bit compression. */ #include @@ -10,8 +14,8 @@ #include #include #include -#include "../src/rle.h" -#include "../src/images.h" +#include "../src/rle.c" +#include "suica_220.c" uint16_t buf[2*1024*1024]; uint8_t *output8 = (uint8_t *)buf; @@ -96,31 +100,37 @@ void print_array(size_t size) } /* Work only for arrays */ -#define DO_ENCODE(bits, input, print) \ +#define DO_ENCODE(bits, input, size, name) \ do { \ - size_t size = sizeof(input); \ size_t len = rle_encode_uint##bits(output##bits, (const uint##bits##_t *)input, size); \ + printf("const uint8_t %s[] = {\n", #name); \ printf(" // %s (%zd -> RLE %zd)", #input, size * bits / 8, len * bits / 8); \ - print ? print_array(len * bits / 8) : printf("\n"); \ + print_array(len * bits / 8); \ + printf("};\n\n"); \ } while (0); /* Work only for arrays */ -#define DO_ENCODE_X(bits, input, x, print) \ +#define DO_ENCODE_X(bits, input, x, size, name) \ do { \ - size_t size = sizeof(input); \ size_t len = rle_x_encode_uint##bits(output##bits, (const uint##bits##_t *)input, size, x); \ + printf("const uint8_t %s[] = {\n", #name); \ printf(" // %s (%zd -> RLE(%x) %zd)", #input, size * bits / 8, x, len * bits / 8); \ - print ? print_array(len * bits / 8) : printf("\n"); \ + print_array(len * bits / 8); \ + printf("};\n\n"); \ } while (0); -#define ENCODE(bits, input) DO_ENCODE(bits, input, true) -#define ENCODE_X(bits, input, x) DO_ENCODE_X(bits, input, x, true) -#define TEST_ENCODE(bits, input) DO_ENCODE(bits, input, false) -#define TEST_ENCODE_X(bits, input, x) DO_ENCODE_X(bits, input, x, false) +#define ENCODE(bits, input) DO_ENCODE(bits, input, sizeof(input), input) +#define ENCODE_X(bits, input, x) DO_ENCODE_X(bits, input, x, sizeof(input), input) +#define ENCODE_ALPHA(alpha) \ + to_4bpp(alpha, sizeof(alpha)); \ + DO_ENCODE(8, buf, sizeof(alpha) / 2, alpha); +#define ENCODE_X_ALPHA(alpha, x) \ + to_4bpp(alpha, sizeof(alpha)); \ + DO_ENCODE_X(8, buf, x, sizeof(alpha) / 2, alpha); -void encode_pallette(const uint8_t pallete[256 * 4]) +void encode_pallette(const uint8_t *pallete, size_t size) { - for (int i = 0; i < 256; i++) { + for (int i = 0; i < size / 4; i++) { if (i % 4 == 0) { printf("\n "); } @@ -135,17 +145,22 @@ void encode_pallette(const uint8_t pallete[256 * 4]) } } -#define ENCODE_PAL(pallete) \ - if (sizeof(pallete) != 256 * 4) { \ - printf(" // Error\n"); \ - } else { \ - printf(" // %s Pallete (RGB565A8*256)", #pallete); \ - encode_pallette(pallete); \ +void to_4bpp(const uint8_t *alpha, size_t size) +{ + for (int i = 0; i < size / 2; i++) { + buf[i] = (alpha[i * 2] << 8) | alpha[i * 2 + 1]; } +} + +#define ENCODE_PAL(pallete) \ + printf("const uint32_t %s[] = {\n", #pallete); \ + printf(" // %s Pallete (RGB565A8*%ld)", #pallete, sizeof(pallete) / 4); \ + encode_pallette(pallete, sizeof(pallete)); \ + printf("\n};\n\n"); int main() { - ENCODE(8, bana_logo_pixels); - ENCODE_PAL(bana_logo_pal); + ENCODE(8, image_suica_pixels); + ENCODE_PAL(image_suica_pal); return 0; } diff --git a/res/cards/suica_220.png b/res/cards/suica_220.png new file mode 100644 index 0000000..44e8a9d Binary files /dev/null and b/res/cards/suica_220.png differ diff --git a/res/cards/vicinity_220.png b/res/cards/vicinity_220.png new file mode 100644 index 0000000..fdc737f Binary files /dev/null and b/res/cards/vicinity_220.png differ