فهرست منبع

Merge pull request #47 from zinongli/0.5+load+suica

Luu 10 ماه پیش
والد
کامیت
41e7306321
100فایلهای تغییر یافته به همراه2266 افزوده شده و 0 حذف شده
  1. BIN
      api/.DS_Store
  2. 89 0
      api/metroflip/metroflip_api.h
  3. 91 0
      api/metroflip/metroflip_api_table_i.h
  4. 51 0
      api/suica/suica_assets.h
  5. 990 0
      api/suica/suica_drawings.h
  6. 59 0
      api/suica/suica_loading.h
  7. 18 0
      api/suica/suica_structs.h
  8. 66 0
      api/suica/suica_structs_i.h
  9. 9 0
      application.fam
  10. 13 0
      example_file/suica_example.nfc
  11. 1 0
      files/suica/line_0x00.txt
  12. 36 0
      files/suica/line_0x01.txt
  13. 58 0
      files/suica/line_0x02.txt
  14. 10 0
      files/suica/line_0x1D.txt
  15. 8 0
      files/suica/line_0x82.txt
  16. 50 0
      files/suica/line_0xD5.txt
  17. 6 0
      files/suica/line_0xD6.txt
  18. 65 0
      files/suica/line_0xE3.txt
  19. 45 0
      files/suica/line_0xE4.txt
  20. 30 0
      files/suica/line_0xE5.txt
  21. 14 0
      files/suica/line_0xE6.txt
  22. 19 0
      files/suica/line_0xE7.txt
  23. 20 0
      files/suica/line_0xEF.txt
  24. 27 0
      files/suica/line_0xF0.txt
  25. 21 0
      files/suica/line_0xF1.txt
  26. 26 0
      files/suica/line_0xF2.txt
  27. 14 0
      files/suica/line_0xF3.txt
  28. 11 0
      files/suica/line_0xFA.txt
  29. 419 0
      files/suica/stations.txt
  30. BIN
      images/.DS_Store
  31. BIN
      images/suica/.DS_Store
  32. BIN
      images/suica/Suica_AsakusaA.png
  33. BIN
      images/suica/Suica_BdayCakeIcon.png
  34. BIN
      images/suica/Suica_BigStar.png
  35. BIN
      images/suica/Suica_CardIcon.png
  36. BIN
      images/suica/Suica_ChiyodaC.png
  37. BIN
      images/suica/Suica_CrackingEgg.png
  38. BIN
      images/suica/Suica_DashLine.png
  39. BIN
      images/suica/Suica_EmptyArrowDown.png
  40. BIN
      images/suica/Suica_EmptyArrowRight.png
  41. BIN
      images/suica/Suica_EntrySlider1.png
  42. BIN
      images/suica/Suica_EntrySlider2.png
  43. BIN
      images/suica/Suica_EntrySlider3.png
  44. BIN
      images/suica/Suica_EntryStopL1.png
  45. BIN
      images/suica/Suica_EntryStopL2.png
  46. BIN
      images/suica/Suica_EntryStopL3.png
  47. BIN
      images/suica/Suica_EntryStopR1.png
  48. BIN
      images/suica/Suica_EntryStopR2.png
  49. BIN
      images/suica/Suica_EntryStopR3.png
  50. BIN
      images/suica/Suica_FilledArrowDown.png
  51. BIN
      images/suica/Suica_FilledArrowRight.png
  52. BIN
      images/suica/Suica_GinzaG.png
  53. BIN
      images/suica/Suica_HanzomonZ.png
  54. BIN
      images/suica/Suica_HibiyaH.png
  55. BIN
      images/suica/Suica_JRLogo.png
  56. BIN
      images/suica/Suica_KeikyuKK.png
  57. BIN
      images/suica/Suica_KeikyuLogo.png
  58. BIN
      images/suica/Suica_MarunouchiHonanchoMb.png
  59. BIN
      images/suica/Suica_MarunouchiM.png
  60. BIN
      images/suica/Suica_MinusSign0.png
  61. BIN
      images/suica/Suica_MinusSign1.png
  62. BIN
      images/suica/Suica_MinusSign2.png
  63. BIN
      images/suica/Suica_MinusSign3.png
  64. BIN
      images/suica/Suica_MinusSign4.png
  65. BIN
      images/suica/Suica_MinusSign5.png
  66. BIN
      images/suica/Suica_MinusSign6.png
  67. BIN
      images/suica/Suica_MinusSign7.png
  68. BIN
      images/suica/Suica_MinusSign8.png
  69. BIN
      images/suica/Suica_MinusSign9.png
  70. BIN
      images/suica/Suica_MitaI.png
  71. BIN
      images/suica/Suica_MobileLogo.png
  72. BIN
      images/suica/Suica_NambokuN.png
  73. BIN
      images/suica/Suica_Nothing.png
  74. BIN
      images/suica/Suica_OedoE.png
  75. BIN
      images/suica/Suica_PenguinHappyBirthday.png
  76. BIN
      images/suica/Suica_PenguinTodaysVIP.png
  77. BIN
      images/suica/Suica_PlusSign1.png
  78. BIN
      images/suica/Suica_PlusSign2.png
  79. BIN
      images/suica/Suica_PlusSign3.png
  80. BIN
      images/suica/Suica_PlusStar.png
  81. BIN
      images/suica/Suica_QuestionMarkBig.png
  82. BIN
      images/suica/Suica_QuestionMarkSmall.png
  83. BIN
      images/suica/Suica_RinkaiR.png
  84. BIN
      images/suica/Suica_ShinjukuS.png
  85. BIN
      images/suica/Suica_ShopIcon.png
  86. BIN
      images/suica/Suica_ShopPin.png
  87. BIN
      images/suica/Suica_SmallStar.png
  88. BIN
      images/suica/Suica_StoreFan1.png
  89. BIN
      images/suica/Suica_StoreFan2.png
  90. BIN
      images/suica/Suica_StoreFrame.png
  91. BIN
      images/suica/Suica_StoreLightningHorizontal.png
  92. BIN
      images/suica/Suica_StoreLightningVertical.png
  93. BIN
      images/suica/Suica_StoreP1Counter.png
  94. BIN
      images/suica/Suica_StoreReceiptDashLine.png
  95. BIN
      images/suica/Suica_StoreReceiptFrame1.png
  96. BIN
      images/suica/Suica_StoreReceiptFrame2.png
  97. BIN
      images/suica/Suica_StoreSlidingDoor.png
  98. BIN
      images/suica/Suica_TWRLogo.png
  99. BIN
      images/suica/Suica_ToeiLogo.png
  100. BIN
      images/suica/Suica_TokyoMetroLogo.png

BIN
api/.DS_Store


+ 89 - 0
api/metroflip/metroflip_api.h

@@ -148,6 +148,95 @@ void render_section_header(
     uint8_t suffix_separator_cnt);
 bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString* result);
 
+extern const Icon I_Suica_AsakusaA;
+extern const Icon I_Suica_BigStar;
+extern const Icon I_Suica_ChiyodaC;
+extern const Icon I_Suica_CrackingEgg;
+extern const Icon I_Suica_DashLine;
+extern const Icon I_Suica_EmptyArrowDown;
+extern const Icon I_Suica_EmptyArrowRight;
+extern const Icon I_Suica_EntrySlider1;
+extern const Icon I_Suica_EntrySlider2;
+extern const Icon I_Suica_EntrySlider3;
+extern const Icon I_Suica_EntryStopL1;
+extern const Icon I_Suica_EntryStopL2;
+extern const Icon I_Suica_EntryStopL3;
+extern const Icon I_Suica_EntryStopR1;
+extern const Icon I_Suica_EntryStopR2;
+extern const Icon I_Suica_EntryStopR3;
+extern const Icon I_Suica_FilledArrowDown;
+extern const Icon I_Suica_FilledArrowRight;
+extern const Icon I_Suica_GinzaG;
+extern const Icon I_Suica_HanzomonZ;
+extern const Icon I_Suica_HibiyaH;
+extern const Icon I_Suica_JRLogo;
+extern const Icon I_Suica_KeikyuKK;
+extern const Icon I_Suica_KeikyuLogo;
+extern const Icon I_Suica_MarunouchiHonanchoMb;
+extern const Icon I_Suica_MarunouchiM;
+extern const Icon I_Suica_MinusSign0;
+extern const Icon I_Suica_MinusSign1;
+extern const Icon I_Suica_MinusSign2;
+extern const Icon I_Suica_MinusSign3;
+extern const Icon I_Suica_MinusSign4;
+extern const Icon I_Suica_MinusSign5;
+extern const Icon I_Suica_MinusSign6;
+extern const Icon I_Suica_MinusSign7;
+extern const Icon I_Suica_MinusSign8;
+extern const Icon I_Suica_MinusSign9;
+extern const Icon I_Suica_MitaI;
+extern const Icon I_Suica_MobileLogo;
+extern const Icon I_Suica_NambokuN;
+extern const Icon I_Suica_Nothing;
+extern const Icon I_Suica_OedoE;
+extern const Icon I_Suica_PenguinHappyBirthday;
+extern const Icon I_Suica_PenguinTodaysVIP;
+extern const Icon I_Suica_PlusSign1;
+extern const Icon I_Suica_PlusSign2;
+extern const Icon I_Suica_PlusSign3;
+extern const Icon I_Suica_PlusStar;
+extern const Icon I_Suica_QuestionMarkBig;
+extern const Icon I_Suica_QuestionMarkSmall;
+extern const Icon I_Suica_RinkaiR;
+extern const Icon I_Suica_ShinjukuS;
+extern const Icon I_Suica_ShopPin;
+extern const Icon I_Suica_SmallStar;
+extern const Icon I_Suica_StoreFan1;
+extern const Icon I_Suica_StoreFan2;
+extern const Icon I_Suica_StoreFrame;
+extern const Icon I_Suica_StoreLightningHorizontal;
+extern const Icon I_Suica_StoreLightningVertical;
+extern const Icon I_Suica_StoreP1Counter;
+extern const Icon I_Suica_StoreReceiptDashLine;
+extern const Icon I_Suica_StoreReceiptFrame1;
+extern const Icon I_Suica_StoreReceiptFrame2;
+extern const Icon I_Suica_StoreSlidingDoor;
+extern const Icon I_Suica_TWRLogo;
+extern const Icon I_Suica_ToeiLogo;
+extern const Icon I_Suica_TokyoMetroLogo;
+extern const Icon I_Suica_TokyoMonorailLogo;
+extern const Icon I_Suica_TozaiT;
+extern const Icon I_Suica_VendingCan1;
+extern const Icon I_Suica_VendingCan2;
+extern const Icon I_Suica_VendingCan3;
+extern const Icon I_Suica_VendingCan4;
+extern const Icon I_Suica_VendingFlap1;
+extern const Icon I_Suica_VendingFlap2;
+extern const Icon I_Suica_VendingFlap3;
+extern const Icon I_Suica_VendingFlapHollow;
+extern const Icon I_Suica_VendingMachine;
+extern const Icon I_Suica_VendingPage2Full;
+extern const Icon I_Suica_VendingThankYou;
+extern const Icon I_Suica_YenKanji;
+extern const Icon I_Suica_YenSign;
+extern const Icon I_Suica_YurakuchoY;
+extern const Icon I_Suica_CardIcon;
+extern const Icon I_Suica_ShopIcon;
+extern const Icon I_Suica_VendingIcon;
+extern const Icon I_Suica_TrainIcon;
+extern const Icon I_Suica_BdayCakeIcon;
+extern const Icon I_Suica_UnknownIcon;
+
 /*******************/
 #ifdef __cplusplus
 }

+ 91 - 0
api/metroflip/metroflip_api_table_i.h

@@ -74,6 +74,97 @@ static constexpr auto metroflip_api_table = sort(create_array_t<sym_entry>(
 
     API_VARIABLE(I_RFIDDolphinReceive_97x61, Icon),
     API_VARIABLE(I_icon, Icon),
+
+    // Suica
+    API_VARIABLE(I_Suica_AsakusaA, Icon),
+    API_VARIABLE(I_Suica_BigStar, Icon),
+    API_VARIABLE(I_Suica_ChiyodaC, Icon),
+    API_VARIABLE(I_Suica_CrackingEgg, Icon),
+    API_VARIABLE(I_Suica_DashLine, Icon),
+    API_VARIABLE(I_Suica_EmptyArrowDown, Icon),
+    API_VARIABLE(I_Suica_EmptyArrowRight, Icon),
+    API_VARIABLE(I_Suica_EntrySlider1, Icon),
+    API_VARIABLE(I_Suica_EntrySlider2, Icon),
+    API_VARIABLE(I_Suica_EntrySlider3, Icon),
+    API_VARIABLE(I_Suica_EntryStopL1, Icon),
+    API_VARIABLE(I_Suica_EntryStopL2, Icon),
+    API_VARIABLE(I_Suica_EntryStopL3, Icon),
+    API_VARIABLE(I_Suica_EntryStopR1, Icon),
+    API_VARIABLE(I_Suica_EntryStopR2, Icon),
+    API_VARIABLE(I_Suica_EntryStopR3, Icon),
+    API_VARIABLE(I_Suica_FilledArrowDown, Icon),
+    API_VARIABLE(I_Suica_FilledArrowRight, Icon),
+    API_VARIABLE(I_Suica_GinzaG, Icon),
+    API_VARIABLE(I_Suica_HanzomonZ, Icon),
+    API_VARIABLE(I_Suica_HibiyaH, Icon),
+    API_VARIABLE(I_Suica_JRLogo, Icon),
+    API_VARIABLE(I_Suica_KeikyuKK, Icon),
+    API_VARIABLE(I_Suica_KeikyuLogo, Icon),
+    API_VARIABLE(I_Suica_MarunouchiHonanchoMb, Icon),
+    API_VARIABLE(I_Suica_MarunouchiM, Icon),
+    API_VARIABLE(I_Suica_MinusSign0, Icon),
+    API_VARIABLE(I_Suica_MinusSign1, Icon),
+    API_VARIABLE(I_Suica_MinusSign2, Icon),
+    API_VARIABLE(I_Suica_MinusSign3, Icon),
+    API_VARIABLE(I_Suica_MinusSign4, Icon),
+    API_VARIABLE(I_Suica_MinusSign5, Icon),
+    API_VARIABLE(I_Suica_MinusSign6, Icon),
+    API_VARIABLE(I_Suica_MinusSign7, Icon),
+    API_VARIABLE(I_Suica_MinusSign8, Icon),
+    API_VARIABLE(I_Suica_MinusSign9, Icon),
+    API_VARIABLE(I_Suica_MitaI, Icon),
+    API_VARIABLE(I_Suica_MobileLogo, Icon),
+    API_VARIABLE(I_Suica_NambokuN, Icon),
+    API_VARIABLE(I_Suica_Nothing, Icon),
+    API_VARIABLE(I_Suica_OedoE, Icon),
+    API_VARIABLE(I_Suica_PenguinHappyBirthday, Icon),
+    API_VARIABLE(I_Suica_PenguinTodaysVIP, Icon),
+    API_VARIABLE(I_Suica_PlusSign1, Icon),
+    API_VARIABLE(I_Suica_PlusSign2, Icon),
+    API_VARIABLE(I_Suica_PlusSign3, Icon),
+    API_VARIABLE(I_Suica_PlusStar, Icon),
+    API_VARIABLE(I_Suica_QuestionMarkBig, Icon),
+    API_VARIABLE(I_Suica_QuestionMarkSmall, Icon),
+    API_VARIABLE(I_Suica_RinkaiR, Icon),
+    API_VARIABLE(I_Suica_ShinjukuS, Icon),
+    API_VARIABLE(I_Suica_ShopPin, Icon),
+    API_VARIABLE(I_Suica_SmallStar, Icon),
+    API_VARIABLE(I_Suica_StoreFan1, Icon),
+    API_VARIABLE(I_Suica_StoreFan2, Icon),
+    API_VARIABLE(I_Suica_StoreFrame, Icon),
+    API_VARIABLE(I_Suica_StoreLightningHorizontal, Icon),
+    API_VARIABLE(I_Suica_StoreLightningVertical, Icon),
+    API_VARIABLE(I_Suica_StoreP1Counter, Icon),
+    API_VARIABLE(I_Suica_StoreReceiptDashLine, Icon),
+    API_VARIABLE(I_Suica_StoreReceiptFrame1, Icon),
+    API_VARIABLE(I_Suica_StoreReceiptFrame2, Icon),
+    API_VARIABLE(I_Suica_StoreSlidingDoor, Icon),
+    API_VARIABLE(I_Suica_TWRLogo, Icon),
+    API_VARIABLE(I_Suica_ToeiLogo, Icon),
+    API_VARIABLE(I_Suica_TokyoMetroLogo, Icon),
+    API_VARIABLE(I_Suica_TokyoMonorailLogo, Icon),
+    API_VARIABLE(I_Suica_TozaiT, Icon),
+    API_VARIABLE(I_Suica_VendingCan1, Icon),
+    API_VARIABLE(I_Suica_VendingCan2, Icon),
+    API_VARIABLE(I_Suica_VendingCan3, Icon),
+    API_VARIABLE(I_Suica_VendingCan4, Icon),
+    API_VARIABLE(I_Suica_VendingFlap1, Icon),
+    API_VARIABLE(I_Suica_VendingFlap2, Icon),
+    API_VARIABLE(I_Suica_VendingFlap3, Icon),
+    API_VARIABLE(I_Suica_VendingFlapHollow, Icon),
+    API_VARIABLE(I_Suica_VendingMachine, Icon),
+    API_VARIABLE(I_Suica_VendingPage2Full, Icon),
+    API_VARIABLE(I_Suica_VendingThankYou, Icon),
+    API_VARIABLE(I_Suica_YenKanji, Icon),
+    API_VARIABLE(I_Suica_YenSign, Icon),
+    API_VARIABLE(I_Suica_YurakuchoY, Icon),
+    API_VARIABLE(I_Suica_CardIcon, Icon),
+    API_VARIABLE(I_Suica_ShopIcon, Icon),
+    API_VARIABLE(I_Suica_VendingIcon, Icon),
+    API_VARIABLE(I_Suica_TrainIcon, Icon),
+    API_VARIABLE(I_Suica_BdayCakeIcon, Icon),
+    API_VARIABLE(I_Suica_UnknownIcon, Icon),
+    
     API_METHOD(render_section_header, void, (FuriString*, const char*, uint8_t, uint8_t)),
     API_METHOD(mosgortrans_parse_transport_block, bool, (const MfClassicBlock*, FuriString*)),
     API_VARIABLE(I_WarningDolphinFlip_45x42, Icon),

+ 51 - 0
api/suica/suica_assets.h

@@ -0,0 +1,51 @@
+#include <datetime.h>
+#include <stdbool.h>
+#include <furi.h>
+
+#include "suica_structs_i.h"
+
+
+#define SUICA_RAILWAY_NUM 24 // Don't count Unknown
+
+#define SUICA_RAILWAY_UNKNOWN_NAME "Unknown"
+// Railway
+
+static const Railway RailwaysList[] = {
+    // Japan Railway East JRE
+    {0x01, {0, 0}, "Keihin Tohoku", 14, SuicaJR, "JK", 0},
+    {0x01, {0, 0}, "Tokaido Main", 21, SuicaJR, "JT", 0},
+    {0x02, {0, 0}, "Keihin Tohoku", 22, SuicaJR, "JK", 0},
+    {0x02, {0, 0}, "Utsunomiya", 33, SuicaJR, "JU", 0},
+    {0x02, {0, 0}, "Mobile Suica", 1, SuicaMobile, "", 0},
+    {0x1D, {0, 0}, "Negishi", 10, SuicaJR, "JK", 0},
+
+    // Tokyo Waterfront Area Rapid Transit TWR
+    {0x82, {0, 0}, "Rinkai", 8, SuicaTWR, "R", &I_Suica_RinkaiR},
+
+    // Tokyo Monorail
+    {0xFA, {0, 0}, "Tokyo Monorail", 11, SuicaTokyoMonorail, "MO", 0},
+
+    // Keikyu
+    {0xD5, {0, 0}, "Keikyu Main", 50, SuicaKeikyu, "KK", &I_Suica_KeikyuKK},
+    {0xD6, {0, 0}, "Keikyu Airport", 6, SuicaKeikyu, "KK", &I_Suica_KeikyuKK},
+
+    // Tokyo Metro
+    {0xE3, {0, 0}, "Ginza", 19, SuicaTokyoMetro, "G", &I_Suica_GinzaG},
+    {0xE3, {1, 0}, "Chiyoda", 20, SuicaTokyoMetro, "C", &I_Suica_ChiyodaC},
+    {0xE3, {1, 1}, "Yurakucho", 24, SuicaTokyoMetro, "Y", &I_Suica_YurakuchoY},
+    {0xE4, {1, 0}, "Hibiya", 21, SuicaTokyoMetro, "H", &I_Suica_HibiyaH},
+    {0xE4, {2, 1}, "Tozai", 23, SuicaTokyoMetro, "T", &I_Suica_TozaiT},
+    {0xE5, {0, 1}, "Marunouchi", 25, SuicaTokyoMetro, "M", &I_Suica_MarunouchiM},
+    {0xE5, {-5, 1}, "M Honancho", 4, SuicaTokyoMetro, "Mb", &I_Suica_MarunouchiHonanchoMb},
+    {0xE6, {2, 1}, "Hanzomon", 14, SuicaTokyoMetro, "Z", &I_Suica_HanzomonZ},
+    {0xE7, {0, 1}, "Namboku", 19, SuicaTokyoMetro, "N", &I_Suica_NambokuN},
+    
+    // Toei
+    {0xEF, {0, 0}, "Asakusa", 20, SuicaToei, "A", &I_Suica_AsakusaA},
+    {0xF0, {4, 0}, "Mita", 27, SuicaToei, "I", &I_Suica_MitaI},
+    {0xF1, {2, 0}, "Shinjuku", 21, SuicaToei, "S", &I_Suica_ShinjukuS},
+    {0xF2, {3, 0}, "Oedo", 26, SuicaToei, "E", &I_Suica_OedoE},
+    {0xF3, {3, 0}, "Oedo", 14, SuicaToei, "E", &I_Suica_OedoE},
+    // Unknown
+    {0x00, {0, 0}, SUICA_RAILWAY_UNKNOWN_NAME, 1, SuicaRailwayTypeMax, "??", &I_Suica_QuestionMarkBig}
+};

+ 990 - 0
api/suica/suica_drawings.h

@@ -0,0 +1,990 @@
+#include <toolbox/stream/stream.h>
+#include <toolbox/stream/file_stream.h>
+#include "metroflip_i.h"
+#include <flipper_application.h>
+#include "../metroflip/metroflip_api.h"
+#include "suica_assets.h"
+
+#include <lib/nfc/protocols/felica/felica.h>
+#include <lib/nfc/protocols/felica/felica_poller.h>
+#include <lib/nfc/protocols/felica/felica_poller_i.h>
+#include <lib/nfc/helpers/felica_crc.h>
+#include <lib/bit_lib/bit_lib.h>
+
+#define SUICA_STATION_LIST_PATH         APP_ASSETS_PATH("suica/line_")
+#define SUICA_IC_TYPE_CODE              0x31
+#define SERVICE_CODE_HISTORY_IN_LE      (0x090FU)
+#define SERVICE_CODE_TAPS_LOG_IN_LE     (0x108FU)
+#define BLOCK_COUNT                     1
+#define HISTORY_VIEW_PAGE_NUM           3
+#define TERMINAL_NULL                   0x02
+#define TERMINAL_BUS                    0x05
+#define TERMINAL_TICKET_VENDING_MACHINE 0x12
+#define TERMINAL_TURNSTILE              0x16
+#define TERMINAL_MOBILE_PHONE           0x1B
+#define TERMINAL_IN_CAR_SUPP_MACHINE    0x24
+#define TERMINAL_POS_AND_TAXI           0xC7
+#define TERMINAL_VENDING_MACHINE        0xC8
+#define PROCESSING_CODE_RECHARGE        0x02
+#define ARROW_ANIMATION_FRAME_MS        350
+
+typedef enum {
+    SuicaTrainRideEntry,
+    SuicaTrainRideExit,
+} SuicaTrainRideType;
+
+typedef enum {
+    SuicaRedrawScreen,
+} SuicaCustomEvent;
+
+static void suica_draw_train_page_1(
+    Canvas* canvas,
+    SuicaHistory history,
+    SuicaHistoryViewModel* model,
+    bool is_birthday) {
+    // Entry logo
+    switch(history.entry_line.type) {
+    case SuicaKeikyu:
+        canvas_draw_icon(canvas, 2, 11, &I_Suica_KeikyuLogo);
+        break;
+    case SuicaJR:
+        canvas_draw_icon(canvas, 1, 12, &I_Suica_JRLogo);
+        break;
+    case SuicaMobile:
+        canvas_draw_icon(canvas, 4, 15, &I_Suica_MobileLogo);
+        break;
+    case SuicaTokyoMetro:
+        canvas_draw_icon(canvas, 2, 12, &I_Suica_TokyoMetroLogo);
+        break;
+    case SuicaToei:
+        canvas_draw_icon(canvas, 4, 11, &I_Suica_ToeiLogo);
+        break;
+    case SuicaTWR:
+        canvas_draw_icon(canvas, 0, 12, &I_Suica_TWRLogo);
+        break;
+    case SuicaTokyoMonorail:
+        canvas_draw_icon(canvas, 0, 11, &I_Suica_TokyoMonorailLogo);
+        break;
+    case SuicaRailwayTypeMax:
+        canvas_draw_icon(canvas, 5, 11, &I_Suica_QuestionMarkSmall);
+        break;
+    default:
+        break;
+    }
+
+    // Entry Text
+    if(history.entry_line.type == SuicaMobile) {
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 28, 28, "Mobile Suica");
+    } else {
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 26, 23, history.entry_line.long_name);
+
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str(canvas, 2, 34, furi_string_get_cstr(history.entry_station.name));
+    }
+
+    if(!is_birthday) {
+        // Exit logo
+        switch(history.exit_line.type) {
+        case SuicaKeikyu:
+            canvas_draw_icon(canvas, 2, 39, &I_Suica_KeikyuLogo);
+            break;
+        case SuicaJR:
+            canvas_draw_icon(canvas, 1, 40, &I_Suica_JRLogo);
+            break;
+        case SuicaTokyoMetro:
+            canvas_draw_icon(canvas, 2, 40, &I_Suica_TokyoMetroLogo);
+            break;
+        case SuicaToei:
+            canvas_draw_icon(canvas, 4, 39, &I_Suica_ToeiLogo);
+            break;
+        case SuicaTWR:
+            canvas_draw_icon(canvas, 0, 40, &I_Suica_TWRLogo);
+            break;
+        case SuicaTokyoMonorail:
+            canvas_draw_icon(canvas, 0, 39, &I_Suica_TokyoMonorailLogo);
+            break;
+        case SuicaRailwayTypeMax:
+            canvas_draw_icon(canvas, 5, 39, &I_Suica_QuestionMarkSmall);
+            break;
+        default:
+            break;
+        }
+
+        // Exit Text
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 26, 51, history.exit_line.long_name);
+
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str(canvas, 2, 62, furi_string_get_cstr(history.exit_station.name));
+    } else {
+        // Birthday
+        canvas_draw_icon(canvas, 5, 42, &I_Suica_CrackingEgg);
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 28, 56, "Suica issued");
+    }
+
+    // Separator
+    canvas_draw_icon(canvas, 0, 37, &I_Suica_DashLine);
+
+    // Arrow
+    uint8_t arrow_bits[4] = {0b1000, 0b0100, 0b0010, 0b0001};
+
+    // Arrow
+    if(model->animator_tick > 3) {
+        // 4 steps of animation
+        model->animator_tick = 0;
+    }
+    uint8_t current_arrow_bits = arrow_bits[model->animator_tick];
+    canvas_draw_icon(
+        canvas,
+        110,
+        19,
+        (current_arrow_bits & 0b1000) ? &I_Suica_FilledArrowDown : &I_Suica_EmptyArrowDown);
+    canvas_draw_icon(
+        canvas,
+        110,
+        29,
+        (current_arrow_bits & 0b0100) ? &I_Suica_FilledArrowDown : &I_Suica_EmptyArrowDown);
+    canvas_draw_icon(
+        canvas,
+        110,
+        39,
+        (current_arrow_bits & 0b0010) ? &I_Suica_FilledArrowDown : &I_Suica_EmptyArrowDown);
+    canvas_draw_icon(
+        canvas,
+        110,
+        49,
+        (current_arrow_bits & 0b0001) ? &I_Suica_FilledArrowDown : &I_Suica_EmptyArrowDown);
+}
+
+static void
+    suica_draw_train_page_2(Canvas* canvas, SuicaHistory history, SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+
+    // Entry
+    switch(history.entry_line.type) {
+    case SuicaKeikyu:
+        canvas_draw_disc(canvas, 24, 38, 24);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_disc(canvas, 24, 38, 21);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_set_font(canvas, FontKeyboard);
+        canvas_draw_icon(canvas, 16, 24, history.entry_line.logo_icon);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+        canvas_draw_str(canvas, 13, 54, furi_string_get_cstr(buffer));
+        break;
+    case SuicaTokyoMonorail:
+        canvas_draw_rbox(canvas, 8, 22, 34, 34, 7);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_box(canvas, 12, 26, 26, 26);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str_aligned(
+            canvas, 25, 35, AlignCenter, AlignBottom, history.entry_line.short_name);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+        canvas_draw_str(canvas, 14, 51, furi_string_get_cstr(buffer));
+        break;
+    case SuicaJR:
+        if(!furi_string_equal_str(history.entry_station.jr_header, "0")) {
+            canvas_draw_rbox(canvas, 4, 13, 42, 51, 10);
+            canvas_set_color(canvas, ColorWhite);
+            canvas_set_font(canvas, FontPrimary);
+            canvas_draw_str_aligned(
+                canvas,
+                25,
+                24,
+                AlignCenter,
+                AlignBottom,
+                furi_string_get_cstr(history.entry_station.jr_header));
+            canvas_draw_rbox(canvas, 8, 26, 34, 34, 7);
+            canvas_set_color(canvas, ColorBlack);
+            canvas_draw_frame(canvas, 12, 30, 26, 26);
+            canvas_set_font(canvas, FontKeyboard);
+            canvas_draw_str_aligned(
+                canvas, 25, 39, AlignCenter, AlignBottom, history.entry_line.short_name);
+            canvas_set_font(canvas, FontBigNumbers);
+            furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+            canvas_draw_str(canvas, 14, 54, furi_string_get_cstr(buffer));
+        } else {
+            canvas_draw_rframe(canvas, 8, 22, 34, 34, 7);
+            canvas_draw_frame(canvas, 12, 26, 26, 26);
+            canvas_set_font(canvas, FontKeyboard);
+            canvas_draw_str_aligned(
+                canvas, 25, 35, AlignCenter, AlignBottom, history.entry_line.short_name);
+            canvas_set_font(canvas, FontBigNumbers);
+            furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+            canvas_draw_str(canvas, 14, 50, furi_string_get_cstr(buffer));
+        }
+        break;
+    case SuicaTokyoMetro:
+    case SuicaToei:
+        canvas_draw_disc(canvas, 24, 38, 24);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_disc(canvas, 24, 38, 19);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_set_font(canvas, FontBigNumbers);
+        canvas_draw_icon(
+            canvas,
+            17 + history.entry_line.logo_offset[0],
+            22 + history.entry_line.logo_offset[1],
+            history.entry_line.logo_icon);
+        furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+        canvas_draw_str(canvas, 13, 53, furi_string_get_cstr(buffer));
+        break;
+    case SuicaTWR:
+        canvas_draw_circle(canvas, 24, 38, 24);
+        canvas_draw_circle(canvas, 24, 38, 20);
+        canvas_draw_disc(canvas, 24, 38, 18);
+
+        // supplement the circle
+        canvas_draw_line(canvas, 39, 49, 35, 53);
+        canvas_draw_line(canvas, 13, 23, 9, 27);
+        canvas_draw_line(canvas, 39, 27, 35, 23);
+        canvas_draw_line(canvas, 13, 53, 9, 49);
+
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_icon(canvas, 20, 23, history.entry_line.logo_icon);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.entry_station.station_number);
+        canvas_draw_str(canvas, 13, 53, furi_string_get_cstr(buffer));
+        canvas_set_color(canvas, ColorBlack);
+        break;
+    case SuicaRailwayTypeMax:
+        canvas_draw_circle(canvas, 24, 38, 24);
+        canvas_draw_circle(canvas, 24, 38, 19);
+        canvas_draw_icon(canvas, 14, 22, &I_Suica_QuestionMarkBig);
+        break;
+    default:
+        break;
+    }
+
+    // Exit
+    switch(history.exit_line.type) {
+    case SuicaKeikyu:
+        canvas_draw_disc(canvas, 103, 38, 24);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_disc(canvas, 103, 38, 21);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_icon(canvas, 95, 24, history.exit_line.logo_icon);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+        canvas_draw_str(canvas, 92, 54, furi_string_get_cstr(buffer));
+        break;
+    case SuicaTokyoMonorail:
+        canvas_draw_rbox(canvas, 85, 22, 34, 34, 7);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_box(canvas, 89, 26, 26, 26);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str_aligned(
+            canvas, 102, 35, AlignCenter, AlignBottom, history.exit_line.short_name);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+        canvas_draw_str(canvas, 91, 51, furi_string_get_cstr(buffer));
+        break;
+    case SuicaJR:
+        if(!furi_string_equal_str(history.exit_station.jr_header, "0")) {
+            canvas_draw_rbox(canvas, 81, 13, 42, 51, 10);
+            canvas_set_color(canvas, ColorWhite);
+            canvas_set_font(canvas, FontPrimary);
+            canvas_draw_str_aligned(
+                canvas,
+                101,
+                24,
+                AlignCenter,
+                AlignBottom,
+                furi_string_get_cstr(history.exit_station.jr_header));
+            canvas_draw_rbox(canvas, 85, 26, 34, 34, 7);
+            canvas_set_color(canvas, ColorBlack);
+            canvas_draw_frame(canvas, 89, 30, 26, 26);
+            canvas_set_font(canvas, FontKeyboard);
+            canvas_draw_str_aligned(
+                canvas, 102, 39, AlignCenter, AlignBottom, history.exit_line.short_name);
+            canvas_set_font(canvas, FontBigNumbers);
+            furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+            canvas_draw_str(canvas, 91, 54, furi_string_get_cstr(buffer));
+        } else {
+            canvas_draw_rframe(canvas, 85, 22, 34, 34, 7);
+            canvas_draw_frame(canvas, 89, 26, 26, 26);
+            canvas_set_font(canvas, FontKeyboard);
+            canvas_draw_str_aligned(
+                canvas, 102, 35, AlignCenter, AlignBottom, history.exit_line.short_name);
+            canvas_set_font(canvas, FontBigNumbers);
+            furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+            canvas_draw_str(canvas, 91, 50, furi_string_get_cstr(buffer));
+        }
+        break;
+    case SuicaTokyoMetro:
+    case SuicaToei:
+        canvas_draw_disc(canvas, 103, 38, 24);
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_disc(canvas, 103, 38, 19);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_icon(
+            canvas,
+            96 + history.exit_line.logo_offset[0],
+            22 + history.exit_line.logo_offset[1],
+            history.exit_line.logo_icon);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+        canvas_draw_str(canvas, 92, 53, furi_string_get_cstr(buffer));
+        break;
+    case SuicaTWR:
+        canvas_draw_circle(canvas, 103, 38, 24);
+        canvas_draw_circle(canvas, 103, 38, 20);
+        canvas_draw_disc(canvas, 103, 38, 18);
+
+        // supplement the circle
+        canvas_draw_line(canvas, 118, 49, 114, 53);
+        canvas_draw_line(canvas, 118, 27, 114, 23);
+        canvas_draw_line(canvas, 92, 23, 88, 27);
+        canvas_draw_line(canvas, 92, 53, 88, 49);
+
+        canvas_set_color(canvas, ColorWhite);
+        canvas_draw_icon(canvas, 99, 23, history.exit_line.logo_icon);
+        canvas_set_font(canvas, FontBigNumbers);
+        furi_string_printf(buffer, "%02d", history.exit_station.station_number);
+        canvas_draw_str(canvas, 92, 53, furi_string_get_cstr(buffer));
+        canvas_set_color(canvas, ColorBlack);
+        break;
+    case SuicaRailwayTypeMax:
+        canvas_draw_circle(canvas, 103, 38, 24);
+        canvas_draw_circle(canvas, 103, 38, 19);
+        canvas_draw_icon(canvas, 93, 22, &I_Suica_QuestionMarkBig);
+    default:
+        break;
+    }
+
+    uint8_t arrow_bits[3] = {0b100, 0b010, 0b001};
+
+    // Arrow
+    if(model->animator_tick > 2) {
+        // 4 steps of animation
+        model->animator_tick = 0;
+    }
+    uint8_t current_arrow_bits = arrow_bits[model->animator_tick];
+    canvas_draw_icon(
+        canvas,
+        51,
+        32,
+        (current_arrow_bits & 0b100) ? &I_Suica_FilledArrowRight : &I_Suica_EmptyArrowRight);
+    canvas_draw_icon(
+        canvas,
+        59,
+        32,
+        (current_arrow_bits & 0b010) ? &I_Suica_FilledArrowRight : &I_Suica_EmptyArrowRight);
+    canvas_draw_icon(
+        canvas,
+        67,
+        32,
+        (current_arrow_bits & 0b001) ? &I_Suica_FilledArrowRight : &I_Suica_EmptyArrowRight);
+
+    furi_string_free(buffer);
+}
+
+static void
+    suica_draw_birthday_page_2(Canvas* canvas, SuicaHistory history, SuicaHistoryViewModel* model) {
+    UNUSED(history);
+    canvas_draw_icon(canvas, 27, 14, &I_Suica_PenguinHappyBirthday);
+    canvas_draw_icon(canvas, 14, 14, &I_Suica_PenguinTodaysVIP);
+    canvas_draw_rframe(canvas, 12, 12, 13, 52, 2); // VIP frame
+    uint8_t star_bits[4] = {0b11000000, 0b11110000, 0b11111111, 0b00000000};
+
+    // Arrow
+    if(model->animator_tick > 3) {
+        // 4 steps of animation
+        model->animator_tick = 0;
+    }
+    uint8_t current_star_bits = star_bits[model->animator_tick];
+    canvas_draw_icon(
+        canvas, 87, 30, (current_star_bits & 0b10000000) ? &I_Suica_BigStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 90, 12, (current_star_bits & 0b01000000) ? &I_Suica_PlusStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 99, 34, (current_star_bits & 0b00100000) ? &I_Suica_SmallStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 103, 12, (current_star_bits & 0b00010000) ? &I_Suica_SmallStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 106, 21, (current_star_bits & 0b00001000) ? &I_Suica_BigStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 109, 43, (current_star_bits & 0b00000100) ? &I_Suica_PlusStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 117, 28, (current_star_bits & 0b00000010) ? &I_Suica_BigStar : &I_Suica_Nothing);
+    canvas_draw_icon(
+        canvas, 115, 16, (current_star_bits & 0b00000100) ? &I_Suica_PlusStar : &I_Suica_Nothing);
+}
+
+static void suica_draw_vending_machine_page_1(
+    Canvas* canvas,
+    SuicaHistory history,
+    SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+    canvas_draw_icon(canvas, 0, 10, &I_Suica_VendingPage2Full);
+    furi_string_printf(buffer, "%d", history.balance_change);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 98, 39, AlignRight, AlignBottom, furi_string_get_cstr(buffer));
+
+    // Animate Bubbles and LCD Refresh
+    if(model->animator_tick > 14) {
+        // 14 steps of animation
+        model->animator_tick = 0;
+    }
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_line(canvas, 88, 51 + model->animator_tick, 128, 51 + model->animator_tick);
+    switch(model->animator_tick % 7) {
+    case 0:
+        canvas_draw_circle(canvas, 12, 48, 1);
+        canvas_draw_circle(canvas, 23, 39, 2);
+        break;
+    case 1:
+        canvas_draw_circle(canvas, 11, 46, 1);
+        canvas_draw_circle(canvas, 23, 39, 2);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_line(canvas, 24, 37, 22, 37);
+        canvas_draw_line(canvas, 25, 40, 25, 38);
+        canvas_set_color(canvas, ColorWhite);
+        break;
+    case 2:
+        canvas_draw_circle(canvas, 12, 44, 1);
+        canvas_draw_circle(canvas, 24, 50, 1);
+        break;
+    case 3:
+        canvas_draw_icon(canvas, 12, 41, &I_Suica_SmallStar);
+        canvas_draw_circle(canvas, 25, 48, 1);
+        break;
+    case 4:
+        canvas_draw_icon(canvas, 14, 39, &I_Suica_SmallStar);
+        canvas_draw_circle(canvas, 26, 46, 1);
+        break;
+    case 5:
+        canvas_draw_icon(canvas, 24, 43, &I_Suica_SmallStar);
+        canvas_draw_circle(canvas, 16, 38, 2);
+        break;
+    case 6:
+        canvas_draw_icon(canvas, 23, 41, &I_Suica_SmallStar);
+        canvas_draw_circle(canvas, 16, 38, 2);
+        canvas_set_color(canvas, ColorBlack);
+        canvas_draw_line(canvas, 15, 36, 17, 36);
+        canvas_draw_line(canvas, 18, 39, 18, 37);
+        canvas_set_color(canvas, ColorWhite);
+        break;
+    default:
+        break;
+    }
+    furi_string_free(buffer);
+    canvas_set_color(canvas, ColorBlack);
+}
+
+static void suica_draw_vending_machine_page_2(
+    Canvas* canvas,
+    SuicaHistory history,
+    SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+
+    if(model->animator_tick > 42) {
+        // 6 steps of animation
+        model->animator_tick = 0;
+    }
+
+    // Draw Thank You Banner
+    canvas_draw_icon(
+        canvas, 49 - model->animator_tick, -9 + model->animator_tick, &I_Suica_VendingThankYou);
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_box(canvas, 50, 0, 128, 64);
+    canvas_draw_box(canvas, 0, 0, 42, 64);
+
+    // Clock Component
+    canvas_set_color(canvas, ColorWhite); // Erase part of old frame to allow for new frame
+    canvas_draw_line(canvas, 93, 9, 96, 6);
+    canvas_draw_line(canvas, 59, 9, 95, 9);
+    canvas_set_color(canvas, ColorBlack);
+    furi_string_printf(buffer, "%02d:%02d", history.hour, history.minute);
+    canvas_draw_line(canvas, 65, 21, 62, 18);
+    canvas_set_font(canvas, FontKeyboard);
+    canvas_draw_str(canvas, 66, 19, furi_string_get_cstr(buffer));
+    canvas_draw_line(canvas, 93, 21, 96, 18);
+    canvas_draw_line(canvas, 66, 21, 93, 21);
+    canvas_draw_line(canvas, 96, 6, 96, 17);
+    canvas_draw_line(canvas, 62, 12, 62, 17);
+    canvas_draw_line(canvas, 62, 12, 59, 9);
+
+    // Vending Machine
+    canvas_draw_icon(canvas, 4, 12, &I_Suica_VendingMachine);
+
+    // Machine Code
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 75, 35, "Machine");
+    canvas_draw_icon(canvas, 119, 25, &I_Suica_ShopPin);
+    furi_string_printf(
+        buffer, "%01d:%03d:%03d", history.area_code, history.shop_code[0], history.shop_code[1]);
+    canvas_set_font(canvas, FontKeyboard);
+    canvas_draw_str(canvas, 75, 45, furi_string_get_cstr(buffer));
+
+    // Animate Vending Machine Flap
+
+    switch(model->animator_tick % 7) {
+    case 0:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap1);
+        break;
+    case 1:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap2);
+        break;
+    case 2:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap3);
+        break;
+    case 3:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap3);
+        canvas_draw_icon(canvas, 59, 45, &I_Suica_VendingCan1);
+        break;
+    case 4:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap2);
+        canvas_draw_icon(canvas, 74, 48, &I_Suica_VendingCan2);
+        break;
+    case 5:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap1);
+        canvas_draw_icon(canvas, 89, 51, &I_Suica_VendingCan3);
+        break;
+    case 6:
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlapHollow);
+        canvas_draw_icon(canvas, 44, 40, &I_Suica_VendingFlap1);
+        canvas_draw_icon(canvas, 110, 54, &I_Suica_VendingCan4);
+        break;
+    default:
+        break;
+    }
+    furi_string_free(buffer);
+}
+
+static void
+    suica_draw_store_page_1(Canvas* canvas, SuicaHistory history, SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+    furi_string_printf(buffer, "%d", history.balance_change);
+    canvas_draw_icon(canvas, 0, 15, &I_Suica_StoreP1Counter);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas, 98, 39, AlignRight, AlignBottom, furi_string_get_cstr(buffer));
+    canvas_draw_icon(canvas, 59, 27, &I_Suica_StoreReceiptDashLine);
+    // Animate Taxi and LCD Refresh
+    if(model->animator_tick > 11) {
+        // 14 steps of animation
+        model->animator_tick = 0;
+    }
+
+    switch(model->animator_tick % 6) {
+    case 0:
+    case 1:
+    case 2:
+        canvas_draw_icon(canvas, 41, 18, &I_Suica_StoreReceiptFrame1);
+        break;
+    case 3:
+    case 4:
+    case 5:
+        canvas_draw_icon(canvas, 41, 18, &I_Suica_StoreReceiptFrame2);
+        break;
+    default:
+        break;
+    }
+
+    switch(model->animator_tick % 6) {
+    case 0:
+    case 1:
+        canvas_draw_icon(canvas, 0, 24, &I_Suica_StoreLightningVertical);
+        break;
+    case 2:
+    case 3:
+        canvas_draw_icon(canvas, 3, 31, &I_Suica_StoreLightningHorizontal);
+        break;
+    case 4:
+    case 5:
+        canvas_draw_icon(canvas, 0, 24, &I_Suica_StoreLightningVertical);
+        canvas_draw_icon(canvas, 3, 31, &I_Suica_StoreLightningHorizontal);
+        break;
+    default:
+        break;
+    }
+    furi_string_free(buffer);
+}
+
+static void
+    suica_draw_store_page_2(Canvas* canvas, SuicaHistory history, SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+    // Clock Component
+    canvas_set_color(canvas, ColorWhite); // Erase part of old frame to allow for new frame
+    canvas_draw_line(canvas, 93, 9, 96, 6);
+    canvas_draw_line(canvas, 59, 9, 95, 9);
+    canvas_set_color(canvas, ColorBlack);
+    furi_string_printf(buffer, "%02d:%02d", history.hour, history.minute);
+    canvas_draw_line(canvas, 65, 21, 62, 18);
+    canvas_set_font(canvas, FontKeyboard);
+    canvas_draw_str(canvas, 66, 19, furi_string_get_cstr(buffer));
+    canvas_draw_line(canvas, 93, 21, 96, 18);
+    canvas_draw_line(canvas, 66, 21, 93, 21);
+    canvas_draw_line(canvas, 96, 6, 96, 17);
+    canvas_draw_line(canvas, 62, 12, 62, 17);
+    canvas_draw_line(canvas, 62, 12, 59, 9);
+
+    // Machine Code
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 75, 35, "Store");
+    canvas_draw_icon(canvas, 104, 25, &I_Suica_ShopPin);
+    furi_string_printf(
+        buffer, "%01d:%03d:%03d", history.area_code, history.shop_code[0], history.shop_code[1]);
+    canvas_set_font(canvas, FontKeyboard);
+    canvas_draw_str(canvas, 75, 45, furi_string_get_cstr(buffer));
+
+    // Store Frame
+    canvas_draw_icon(canvas, 0, 13, &I_Suica_StoreFrame);
+    // Sliding Door
+    uint8_t door_position[7] = {20, 18, 14, 6, 2, 0, 0};
+    if(model->animator_tick > 20) {
+        // 14 steps of animation
+        model->animator_tick = 0;
+    }
+
+    if(model->animator_tick < 7) {
+        canvas_draw_icon(
+            canvas, -1 - door_position[6 - model->animator_tick], 28, &I_Suica_StoreSlidingDoor);
+    } else if(model->animator_tick < 14) {
+        canvas_draw_icon(
+            canvas, -1 - door_position[model->animator_tick - 7], 28, &I_Suica_StoreSlidingDoor);
+    } else {
+        canvas_draw_icon(canvas, -1, 28, &I_Suica_StoreSlidingDoor);
+    }
+
+    // Animate Neon and Fan
+    switch(model->animator_tick % 4) {
+    case 0:
+    case 1:
+        canvas_draw_icon(canvas, 37, 18, &I_Suica_StoreFan1);
+        break;
+    case 2:
+    case 3:
+        canvas_draw_icon(canvas, 37, 18, &I_Suica_StoreFan2);
+        break;
+    default:
+        break;
+    }
+    furi_string_free(buffer);
+}
+
+static void
+    suica_draw_balance_page(Canvas* canvas, SuicaHistory history, SuicaHistoryViewModel* model) {
+    FuriString* buffer = furi_string_alloc();
+
+    // Balance
+    canvas_set_font(canvas, FontBigNumbers);
+    canvas_draw_icon(canvas, 0, 48, &I_Suica_YenSign);
+    canvas_draw_icon(canvas, 111, 48, &I_Suica_YenKanji);
+
+    furi_string_printf(buffer, "%d", history.balance);
+    canvas_draw_str_aligned(
+        canvas, 109, 64, AlignRight, AlignBottom, furi_string_get_cstr(buffer));
+
+    furi_string_printf(buffer, "%d", history.previous_balance);
+    canvas_draw_str_aligned(
+        canvas, 109, 26, AlignRight, AlignBottom, furi_string_get_cstr(buffer));
+
+    furi_string_printf(buffer, "%d", history.balance_change);
+    canvas_draw_str_aligned(
+        canvas, 109, 43, AlignRight, AlignBottom, furi_string_get_cstr(buffer));
+
+    // Separator
+    canvas_draw_line(canvas, 26, 45, 128, 45);
+    canvas_draw_line(canvas, 26, 46, 128, 46);
+
+    if(history.balance_sign == SuicaBalanceAdd) {
+        // Animate plus sign
+        if(model->animator_tick > 2) {
+            // 9 steps of animation
+            model->animator_tick = 0;
+        }
+        switch(model->animator_tick) {
+        case 0:
+            canvas_draw_icon(canvas, 28, 28, &I_Suica_PlusSign1);
+            break;
+        case 1:
+            canvas_draw_icon(canvas, 27, 27, &I_Suica_PlusSign2);
+            break;
+        case 2:
+            canvas_draw_icon(canvas, 26, 26, &I_Suica_PlusSign3);
+            break;
+        default:
+            break;
+        }
+    } else if(history.balance_sign == SuicaBalanceSub) {
+        // Animate plus sign
+        if(model->animator_tick > 12) {
+            // 9 steps of animation
+            model->animator_tick = 0;
+        }
+        switch(model->animator_tick) {
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign0);
+            break;
+        case 4:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign1);
+            break;
+        case 5:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign2);
+            break;
+        case 6:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign3);
+            break;
+        case 7:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign4);
+            break;
+        case 8:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign5);
+            break;
+        case 9:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign6);
+            break;
+        case 10:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign7);
+            break;
+        case 11:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign8);
+            break;
+        case 12:
+            canvas_draw_icon(canvas, 28, 32, &I_Suica_MinusSign9);
+            break;
+        default:
+            break;
+        }
+    } else {
+        canvas_draw_str(canvas, 30, 28, "=");
+    }
+}
+
+static void suica_history_draw_callback(Canvas* canvas, void* model) {
+    canvas_set_bitmap_mode(canvas, true);
+    SuicaHistoryViewModel* my_model = (SuicaHistoryViewModel*)model;
+    FuriString* buffer = furi_string_alloc();
+    // catch the case where the page and entry are not initialized
+
+    if(my_model->entry > my_model->size || my_model->entry < 1) {
+        my_model->entry = 1;
+    }
+
+    // Get previous balance if we are not at the earliest entry
+    if(my_model->entry < my_model->size) {
+        my_model->history.previous_balance = my_model->travel_history[(my_model->entry * 16) + 10];
+        my_model->history.previous_balance |= my_model->travel_history[(my_model->entry * 16) + 11]
+                                              << 8;
+    } else {
+        my_model->history.previous_balance = 0;
+    }
+    // Calculate balance change
+    if(my_model->history.previous_balance < my_model->history.balance) {
+        my_model->history.balance_change =
+            my_model->history.balance - my_model->history.previous_balance;
+        my_model->history.balance_sign = SuicaBalanceAdd;
+    } else if(my_model->history.previous_balance > my_model->history.balance) {
+        my_model->history.balance_change =
+            my_model->history.previous_balance - my_model->history.balance;
+        my_model->history.balance_sign = SuicaBalanceSub;
+    } else {
+        my_model->history.balance_change = 0;
+        my_model->history.balance_sign = SuicaBalanceEqual;
+    }
+
+    switch((uint8_t)my_model->page) {
+    case 0:
+        switch(my_model->history.history_type) {
+        case SuicaHistoryTrain:
+            suica_draw_train_page_1(canvas, my_model->history, my_model, false);
+            break;
+        case SuicaHistoryHappyBirthday:
+            suica_draw_train_page_1(canvas, my_model->history, my_model, true);
+            break;
+        case SuicaHistoryVendingMachine:
+            suica_draw_vending_machine_page_1(canvas, my_model->history, my_model);
+            break;
+        case SuicaHistoryPosAndTaxi:
+            suica_draw_store_page_1(canvas, my_model->history, my_model);
+            break;
+        default:
+            break;
+        }
+        break;
+    case 1:
+        switch(my_model->history.history_type) {
+        case SuicaHistoryTrain:
+            suica_draw_train_page_2(canvas, my_model->history, my_model);
+            break;
+        case SuicaHistoryHappyBirthday:
+            suica_draw_birthday_page_2(canvas, my_model->history, my_model);
+            break;
+        case SuicaHistoryVendingMachine:
+            suica_draw_vending_machine_page_2(canvas, my_model->history, my_model);
+            break;
+        case SuicaHistoryPosAndTaxi:
+            suica_draw_store_page_2(canvas, my_model->history, my_model);
+            break;
+        default:
+            break;
+        }
+        break;
+    case 2:
+        suica_draw_balance_page(canvas, my_model->history, my_model);
+        break;
+    default:
+        break;
+    }
+
+    // The the banner last so it is on top
+
+    // Draw Top Left Icons
+    canvas_draw_icon(canvas, 0, 0, &I_Suica_CardIcon);
+    switch(my_model->history.history_type) {
+    case SuicaHistoryTrain:
+        canvas_draw_icon(canvas, 20, 0, &I_Suica_TrainIcon);
+        break;
+    case SuicaHistoryHappyBirthday:
+        canvas_draw_icon(canvas, 20, 0, &I_Suica_BdayCakeIcon);
+        break;
+    case SuicaHistoryVendingMachine:
+        canvas_draw_icon(canvas, 21, 0, &I_Suica_VendingIcon);
+        break;
+    case SuicaHistoryPosAndTaxi:
+        canvas_draw_icon(canvas, 19, 0, &I_Suica_ShopIcon);
+        break;
+    default:
+        canvas_draw_icon(canvas, 22, 0, &I_Suica_UnknownIcon);
+        break;
+    }
+
+    // Date
+    furi_string_printf(
+        buffer,
+        "20%02d-%02d-%02d",
+        my_model->history.year,
+        my_model->history.month,
+        my_model->history.day);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str(canvas, 37, 8, furi_string_get_cstr(buffer));
+    // Frame
+    canvas_draw_line(canvas, 33, 0, 33, 6);
+    canvas_draw_line(canvas, 36, 9, 33, 6);
+    canvas_draw_line(canvas, 92, 9, 36, 9);
+    canvas_draw_line(canvas, 93, 9, 96, 6);
+    canvas_draw_line(canvas, 96, 0, 96, 6);
+
+    // Entry Num
+    canvas_draw_box(canvas, 106, 0, 13, 9);
+    furi_string_printf(buffer, "%02d", my_model->entry);
+    canvas_set_font(canvas, FontKeyboard);
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_str(canvas, 107, 8, furi_string_get_cstr(buffer));
+    canvas_set_color(canvas, ColorBlack);
+
+    switch(my_model->page) {
+    case 0:
+        canvas_draw_icon(canvas, 100, 0, &I_Suica_EntrySlider1);
+        break;
+    case 1:
+        canvas_draw_icon(canvas, 100, 0, &I_Suica_EntrySlider2);
+        break;
+    case 2:
+        canvas_draw_icon(canvas, 100, 0, &I_Suica_EntrySlider3);
+        break;
+    default:
+        break;
+    }
+
+    canvas_set_color(canvas, ColorWhite);
+    if(my_model->entry == 1) {
+        canvas_draw_box(canvas, 99, 0, 6, 9);
+        canvas_set_color(canvas, ColorBlack);
+        switch(my_model->page) {
+        case 0:
+            canvas_draw_icon(canvas, 101, 0, &I_Suica_EntryStopL1);
+            break;
+        case 1:
+            canvas_draw_icon(canvas, 101, 0, &I_Suica_EntryStopL2);
+            break;
+        case 2:
+            canvas_draw_icon(canvas, 101, 0, &I_Suica_EntryStopL3);
+            break;
+        default:
+            break;
+        }
+    } else if(my_model->entry == my_model->size) {
+        canvas_draw_box(canvas, 120, 0, 6, 9);
+        canvas_set_color(canvas, ColorBlack);
+        switch(my_model->page) {
+        case 0:
+            canvas_draw_icon(canvas, 120, 0, &I_Suica_EntryStopR1);
+            break;
+        case 1:
+            canvas_draw_icon(canvas, 120, 0, &I_Suica_EntryStopR2);
+            break;
+        case 2:
+            canvas_draw_icon(canvas, 120, 0, &I_Suica_EntryStopR3);
+            break;
+        default:
+            break;
+        }
+    }
+
+    canvas_set_color(canvas, ColorBlack);
+
+    furi_string_free(buffer);
+}
+
+static void suica_view_history_timer_callback(void* context) { 
+    Metroflip* app = (Metroflip*)context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, 0);
+}
+
+static void suica_view_history_enter_callback(void* context) {
+    uint32_t period = furi_ms_to_ticks(ARROW_ANIMATION_FRAME_MS);
+    Metroflip* app = (Metroflip*)context;
+    furi_assert(app->suica_context->timer == NULL);
+    app->suica_context->timer =
+        furi_timer_alloc(suica_view_history_timer_callback, FuriTimerTypePeriodic, context);
+    furi_timer_start(app->suica_context->timer, period);
+}
+
+static void suica_view_history_exit_callback(void* context) {
+    Metroflip* app = (Metroflip*)context;
+    furi_timer_stop(app->suica_context->timer);
+    furi_timer_free(app->suica_context->timer);
+    app->suica_context->timer = NULL;
+}
+
+static bool suica_view_history_custom_event_callback(uint32_t event, void* context) {
+    Metroflip* app = (Metroflip*)context;
+    switch(event) {
+    case 0:
+        // Redraw screen by passing true to last parameter of with_view_model.
+        {
+            bool redraw = true;
+            with_view_model(
+                app->suica_context->view_history,
+                SuicaHistoryViewModel * model,
+                { model->animator_tick++; },
+                redraw);
+            return true;
+        }
+    default:
+        return false;
+    }
+}
+
+static uint32_t suica_navigation_raw_callback(void* _context) {
+    UNUSED(_context);
+    return MetroflipViewWidget;
+}

+ 59 - 0
api/suica/suica_loading.h

@@ -0,0 +1,59 @@
+#include "../../metroflip_i.h"
+#include <lib/nfc/protocols/felica/felica.h>
+#include "suica_structs_i.h"
+
+void suica_add_entry(SuicaHistoryViewModel* model, const uint8_t* entry) {
+    if(model->size <= 0) {
+        model->travel_history =
+            (uint8_t*)malloc(3 * FELICA_DATA_BLOCK_SIZE); // Each entry is 16 bytes
+        model->size = 0;
+        model->capacity = 3;
+    }
+    // Check if resizing is needed
+    if(model->size == model->capacity) {
+        size_t new_capacity = model->capacity * 2; // Double the capacity
+        uint8_t* new_data =
+            (uint8_t*)realloc(model->travel_history, new_capacity * FELICA_DATA_BLOCK_SIZE);
+        model->travel_history = new_data;
+        model->capacity = new_capacity;
+    }
+
+    // Copy the 16-byte entry to the next slot
+    for(size_t i = 0; i < FELICA_DATA_BLOCK_SIZE; i++) {
+        model->travel_history[(model->size * FELICA_DATA_BLOCK_SIZE) + i] = entry[i];
+    }
+
+    model->size++;
+}
+
+void load_suica_data(void* context, FlipperFormat* format) {
+    Metroflip* app = (Metroflip*)context;
+    app->suica_context = malloc(sizeof(SuicaContext));
+    app->suica_context->view_history = view_alloc();
+    view_set_context(app->suica_context->view_history, app);
+    view_allocate_model(
+        app->suica_context->view_history, ViewModelTypeLockFree, sizeof(SuicaHistoryViewModel));
+    SuicaHistoryViewModel* model = view_get_model(app->suica_context->view_history);
+
+    uint8_t* byte_array_buffer = (uint8_t*)malloc(FELICA_DATA_BLOCK_SIZE);
+            FuriString* entry_preamble = furi_string_alloc();
+    // Read the travel history entries
+    for(uint8_t i = 0; i < SUICA_MAX_HISTORY_ENTRIES; i++) {
+        furi_string_printf(entry_preamble, "Travel %02X", i);
+        // For every line in the flipper format file
+        // We read the entire line's hex and store it in the byte_array_buffer
+        if(!flipper_format_read_hex(
+               format,
+               furi_string_get_cstr(entry_preamble),
+               byte_array_buffer,
+               FELICA_DATA_BLOCK_SIZE))
+            break;
+        uint8_t block_data[16] = {0};
+        for(size_t j = 0; j < FELICA_DATA_BLOCK_SIZE; j++) {
+            block_data[j] = byte_array_buffer[j];
+        }
+        suica_add_entry(model, block_data);
+    }
+    furi_string_free(entry_preamble);
+    free(byte_array_buffer);
+}

+ 18 - 0
api/suica/suica_structs.h

@@ -0,0 +1,18 @@
+#include <datetime.h>
+#include <stdbool.h>
+#include <furi.h>
+
+#define SUICA_MAX_HISTORY_ENTRIES 0x15
+typedef enum {
+    SuicaHistoryNull,
+    SuicaHistoryBus,
+    SuicaHistoryPosAndTaxi,
+    SuicaHistoryVendingMachine,
+    SuicaHistoryHappyBirthday,
+    SuicaHistoryTrain
+} SuicaHistoryType;
+
+typedef struct {
+    View* view_history;
+    FuriTimer* timer;
+} SuicaContext;

+ 66 - 0
api/suica/suica_structs_i.h

@@ -0,0 +1,66 @@
+#include <datetime.h>
+#include <stdbool.h>
+#include <furi.h>
+
+typedef enum {
+    SuicaKeikyu,
+    SuicaTokyoMetro,
+    SuicaToei,
+    SuicaJR,
+    SuicaMobile,
+    SuicaTWR,
+    SuicaTokyoMonorail,
+    SuicaRailwayTypeMax,
+} SuicaRailwayCompany;
+
+typedef enum {
+    SuicaBalanceAdd,
+    SuicaBalanceSub,
+    SuicaBalanceEqual,
+} SuicaBalanceChangeSign;
+
+typedef struct {
+    uint8_t station_code;
+    uint8_t station_number;
+    FuriString* name;
+    FuriString* jr_header;
+} Station;
+
+typedef struct {
+    uint8_t line_code;
+    int logo_offset[2];
+    const char* long_name;
+    uint8_t station_num;
+    SuicaRailwayCompany type;
+    const char* short_name;
+    const Icon* logo_icon;
+} Railway;
+
+typedef struct {
+    Railway entry_line;
+    Station entry_station;
+    Railway exit_line;
+    Station exit_station;
+    uint8_t year;
+    uint8_t month;
+    uint8_t day;
+    uint8_t hour;
+    uint8_t minute;
+    uint16_t balance;
+    uint8_t history_type;
+    uint8_t area_code;
+    uint16_t previous_balance;
+    uint16_t balance_change;
+    SuicaBalanceChangeSign balance_sign;
+    uint8_t* shop_code;
+} SuicaHistory;
+
+typedef struct {
+    uint8_t entry; // Which entry we are currently viewing
+    uint8_t page; // Which vertial page we are on
+    uint8_t* travel_history; // Dynamic array for raw 16-byte entries
+    size_t size; // Number of entries currently stored
+    size_t capacity; // Allocated capacity
+    uint8_t animator_tick; // Counter for the animations
+    SuicaHistory history; // Current history entry
+} SuicaHistoryViewModel;

+ 9 - 0
application.fam

@@ -103,6 +103,15 @@ App(
     fal_embedded=True,
 )
 
+App(
+    appid="suica_plugin",
+    apptype=FlipperAppType.PLUGIN,
+    entry_point="suica_plugin_ep",
+    requires=["metroflip"],
+    sources=["scenes/plugins/suica.c"],
+    fal_embedded=True,
+)
+
 App(
     appid="gocard_plugin",
     apptype=FlipperAppType.PLUGIN,

+ 13 - 0
example_file/suica_example.nfc

@@ -0,0 +1,13 @@
+Filetype: Flipper Metroflip File
+Version: 1
+Device type: FeliCa
+Card Type: suica
+Travel History: 
+Travel 00: C8 46 00 00 31 55 85 63 0E B8 00 00 00 00 07 00
+Travel 01: C7 46 00 00 31 55 67 4B EE A9 8C 00 00 00 06 00
+Travel 02: 16 01 00 05 31 54 01 18 FA 01 1B 00 00 00 05 00
+Travel 03: 16 01 00 05 31 53 E3 55 1D 08 1B 00 00 00 04 00
+Travel 04: 16 01 00 05 31 47 82 04 E4 25 1B 00 00 00 03 00
+Travel 05: 1D 01 00 02 31 46 D5 14 EF 0D 62 01 00 00 02 00
+Travel 06: 12 07 00 00 31 45 02 FD 00 00 E8 03 00 00 01 00
+Travel 07: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

+ 1 - 0
files/suica/line_0x00.txt

@@ -0,0 +1 @@
+0x00,0x00,UnknownLine,Unknown,0,0

+ 36 - 0
files/suica/line_0x01.txt

@@ -0,0 +1,36 @@
+0x01,0x01,Tokaido Main,Tokyo,1,TYO
+0x01,0x03,Tokaido Main,Shimbashi,2,SMB
+0x01,0x07,Tokaido Main,Shinagawa,3,SGW
+0x01,0x0D,Tokaido Main,Kawasaki,4,KWS
+0x01,0x12,Tokaido Main,Yokohama,5,YHM
+0x01,0x16,Tokaido Main,Totsuka,6,TTK
+0x01,0x18,Tokaido Main,Ofuna,7,OFN
+0x01,0x19,Tokaido Main,Fujisawa,8,0
+0x01,0x1A,Tokaido Main,Tsujido,9,0
+0x01,0x1B,Tokaido Main,Chigasaki,10,0
+0x01,0x1D,Tokaido Main,Hiratsuka,11,0
+0x01,0x1E,Tokaido Main,Oiso,12,0
+0x01,0x20,Tokaido Main,Ninomiya,13,0
+0x01,0x21,Tokaido Main,Kozu,14,0
+0x01,0x22,Tokaido Main,Kamonomiya,15,0
+0x01,0x23,Tokaido Main,Odawara,16,0
+0x01,0x25,Tokaido Main,Hayakawa,17,0
+0x01,0x26,Tokaido Main,Nebukawa,18,0
+0x01,0x28,Tokaido Main,Manazuru,19,0
+0x01,0x29,Tokaido Main,Yugawara,20,0
+0x01,0x2B,Tokaido Main,Atami,21,0
+,,,,,
+0x01,0x01,Keihin Tohoku,Tokyo,26,TYO
+0x01,0x02,Keihin Tohoku,Yurakucho,25,0
+0x01,0x03,Keihin Tohoku,Shimbashi,24,SMB
+0x01,0x04,Keihin Tohoku,Hamamatsucho,23,HMC
+0x01,0x06,Keihin Tohoku,Tamachi,22,0
+0x01,0x07,Keihin Tohoku,Shinagawa,20,SGW
+0x01,0x08,Keihin Tohoku,Oimachi,19,0
+0x01,0x09,Keihin Tohoku,Omori,18,0
+0x01,0x0B,Keihin Tohoku,Kamata,17,0
+0x01,0x0D,Keihin Tohoku,Kawasaki,16,KWS
+0x01,0x0E,Keihin Tohoku,Tsurumi,15,0
+0x01,0x10,Keihin Tohoku,Shin-koyasu,14,0
+0x01,0x11,Keihin Tohoku,Higashi-kanagawa,13,0
+0x01,0x12,Keihin Tohoku,Yokohama,12,YHM

+ 58 - 0
files/suica/line_0x02.txt

@@ -0,0 +1,58 @@
+0x02,0x01,Keihin Tohoku,Tokyo,26,TYO
+0x02,0x02,Keihin Tohoku,Kanda,27,KND
+0x02,0x03,Keihin Tohoku,Akihabara,28,AKB
+0x02,0x04,Keihin Tohoku,Okachimachi,29,0
+0x02,0x06,Keihin Tohoku,Ueno,30,UEN
+0x02,0x07,Keihin Tohoku,Uguisudani,31,0
+0x02,0x08,Keihin Tohoku,Nippori,32,NPR
+0x02,0x09,Keihin Tohoku,Nishi-Nippori,33,0
+0x02,0x0b,Keihin Tohoku,Tabata,34,0
+0x02,0x0c,Keihin Tohoku,Kami-Nakazato,35,0
+0x02,0x0d,Keihin Tohoku,Oji,36,0
+0x02,0x0e,Keihin Tohoku,Higashi-Jujo,37,0
+0x02,0x10,Keihin Tohoku,Akabane,38,ABN
+0x02,0x11,Keihin Tohoku,Kawaguchi,39,0
+0x02,0x12,Keihin Tohoku,Nishi-Kawaguchi,40,0
+0x02,0x13,Keihin Tohoku,Warabi,41,0
+0x02,0x15,Keihin Tohoku,Minami-Urawa,42,0
+0x02,0x16,Keihin Tohoku,Urawa,43,URW
+0x02,0x17,Keihin Tohoku,Kita-Urawa,44,0
+0x02,0x18,Keihin Tohoku,Yono,45,0
+0x02,0x19,Keihin Tohoku,Saitama-Shintoshin,46,0
+0x02,0x1a,Keihin Tohoku,Omiya,47,OMY
+,,,,,
+0x02,0x01,Utsunomiya,Tokyo,1,TYO
+0x02,0x06,Utsunomiya,Ueno,2,UEN
+0x02,0x10,Utsunomiya,Akabane,4,ABN
+0x02,0x16,Tohoku Main,Urawa,5,URW
+0x02,0x19,Utsunomiya,Saitama-Shintoshin,6,0
+0x02,0x1a,Utsunomiya,Omiya,7,OMY
+0x02,0x1b,Utsunomiya,Toro,8,0
+0x02,0x1c,Utsunomiya,Higashi-Omiya,9,0
+0x02,0x1e,Utsunomiya,Hasuda,10,0
+0x02,0x20,Utsunomiya,Shiraoka,11,0
+0x02,0x21,Utsunomiya,Shin-Shiraaka,12,0
+0x02,0x22,Utsunomiya,Kuki,13,0
+0x02,0x23,Utsunomiya,Higashi-Washinomiya,14,0
+0x02,0x24,Utsunomiya,Kurihashi,15,0
+0x02,0x26,Utsunomiya,Koga,16,0
+0x02,0x27,Utsunomiya,Nogi,17,0
+0x02,0x28,Utsunomiya,Mamada,18,0
+0x02,0x2a,Utsunomiya,Oyama,19,0
+0x02,0x2c,Utsunomiya,Koganei,20,0
+0x02,0x2d,Utsunomiya,Jichi Medical University,21,0
+0x02,0x2e,Utsunomiya,Ishibashi,22,0
+0x02,0x30,Utsunomiya,Suzumenomiya,23,0
+0x02,0x32,Utsunomiya,Utsunomiya,24,0
+0x02,0x34,Utsunomiya,Okamoto,25,0
+0x02,0x35,Utsunomiya,Hoshakuji,26,0
+0x02,0x36,Utsunomiya,Ujiie,27,0
+0x02,0x37,Utsunomiya,Kamasusaka,28,0
+0x02,0x39,Utsunomiya,Kataoka,29,0
+0x02,0x3a,Utsunomiya,Yaita,30,0
+0x02,0x3b,Utsunomiya,Nozaki,31,0
+0x02,0x3c,Utsunomiya,Nishi-Nasuno,32,0
+0x02,0x3e,Utsunomiya,Nasushiobara,33,0
+0x02,0x3f,Utsunomiya,Kuroiso,34,0
+
+0x02,0xfd,Mobile Suica,MobileSuica,1,0

+ 10 - 0
files/suica/line_0x1D.txt

@@ -0,0 +1,10 @@
+0x1D,0x04,Negishi,Hongodai,2,0
+0x1D,0x06,Negishi,Konandai,3,0
+0x1D,0x07,Negishi,Yokodai,4,0
+0x1D,0x08,Negishi,Shin-sugita,5,0
+0x1D,0x09,Negishi,Isogo,6,0
+0x1D,0x0A,Negishi,Negishi,7,0
+0x1D,0x0C,Negishi,Yamate,8,0
+0x1D,0x0D,Negishi,Ishikawacho,9,0
+0x1D,0x0E,Negishi,Kannai,10,0
+0x1D,0x0F,Negishi,Sakuragicho,11,0

+ 8 - 0
files/suica/line_0x82.txt

@@ -0,0 +1,8 @@
+0x82,0x01,Rinkai,Shin-kiba,1,0
+0x82,0x03,Rinkai,Shinonome,2,0
+0x82,0x04,Rinkai,Kokusai-tenjijo,3,0
+0x82,0x05,Rinkai,Tokyo Teleport,4,0
+0x82,0x06,Rinkai,Tennozu Isle,5,0
+0x82,0x07,Rinkai,Shinagawa Seaside,6,0
+0x82,0x08,Rinkai,Oimachi,7,0
+0x82,0x0A,Rinkai,Osaki,8,0

+ 50 - 0
files/suica/line_0xD5.txt

@@ -0,0 +1,50 @@
+0xD5,0x01,Keikyu Main,Sengakuji,7,0
+0xD5,0x02,Keikyu Main,Shinagawa,1,0
+0xD5,0x03,Keikyu Main,Kita-Shinagawa,2,0
+0xD5,0x04,Keikyu Main,Shimbamba,3,0
+0xD5,0x06,Keikyu Main,Aomono-yokocho,4,0
+0xD5,0x07,Keikyu Main,Samezu,5,0
+0xD5,0x08,Keikyu Main,Tachiaigawa,6,0
+0xD5,0x09,Keikyu Main,Omorikaigan,7,0
+0xD5,0x0A,Keikyu Main,Heiwajima,8,0
+0xD5,0x0B,Keikyu Main,Omorimachi,9,0
+0xD5,0x0C,Keikyu Main,Umeyashiki,10,0
+0xD5,0x0D,Keikyu Main,Keikyu Kamata,11,0
+0xD5,0x0E,Keikyu Main,Zoshiki,18,0
+0xD5,0x0F,Keikyu Main,Rokugodote,19,0
+0xD5,0x10,Keikyu Main,Keikyu Kawasaki,20,0
+0xD5,0x11,Keikyu Main,Hatcho-nawate,27,0
+0xD5,0x12,Keikyu Main,Tsurumi-ichiba,28,0
+0xD5,0x13,Keikyu Main,Keikyu Tsurumi,29,0
+0xD5,0x14,Keikyu Main,Kagetsu-sojiji,30,0
+0xD5,0x15,Keikyu Main,Namamugi,31,0
+0xD5,0x16,Keikyu Main,Keikyu Shinkoyasu,32,0
+0xD5,0x17,Keikyu Main,Koyasu,33,0
+0xD5,0x18,Keikyu Main,Kanagawa-shimmachi,34,0
+0xD5,0x19,Keikyu Main,KK Higashi-kanagawa,35,0
+0xD5,0x1A,Keikyu Main,Kanagawa,36,0
+0xD5,0x1B,Keikyu Main,Yokohama,37,0
+0xD5,0x1C,Keikyu Main,Tobe,38,0
+0xD5,0x1D,Keikyu Main,Hinodecho,39,0
+0xD5,0x1E,Keikyu Main,Koganecho,40,0
+0xD5,0x1F,Keikyu Main,Minamiota,41,0
+0xD5,0x20,Keikyu Main,Idogaya,42,0
+0xD5,0x21,Keikyu Main,Gumyoji,43,0
+0xD5,0x22,Keikyu Main,Kamiooka,44,0
+0xD5,0x24,Keikyu Main,Byobugaura,45,0
+0xD5,0x25,Keikyu Main,Sugita,46,0
+0xD5,0x27,Keikyu Main,Keikyu Tomioka,47,0
+0xD5,0x28,Keikyu Main,Nokendai,48,0
+0xD5,0x29,Keikyu Main,Kanazawa-bunko,49,0
+0xD5,0x2A,Keikyu Main,Kanazawa-hakkei,50,0
+0xD5,0x2B,Keikyu Main,Oppama,54,0
+0xD5,0x2C,Keikyu Main,Keikyu Taura,55,0
+0xD5,0x2E,Keikyu Main,Anjinzuka,56,0
+0xD5,0x2F,Keikyu Main,Hemi,57,0
+0xD5,0x30,Keikyu Main,Shioiri,58,0
+0xD5,0x31,Keikyu Main,Yokosuka-chuo,59,0
+0xD5,0x32,Keikyu Main,Kenritsudaigaku,60,0
+0xD5,0x33,Keikyu Main,Horinouchi,61,0
+0xD5,0x34,Keikyu Main,Keikyu Otsu,62,0
+0xD5,0x35,Keikyu Main,Maborikaigan,63,0
+0xD5,0x36,Keikyu Main,Uraga,64,0

+ 6 - 0
files/suica/line_0xD6.txt

@@ -0,0 +1,6 @@
+0xD6,0x01,Keikyu Airport,Keikyu Kamata,11,0
+0xD6,0x02,Keikyu Airport,Kojiya,12,0
+0xD6,0x03,Keikyu Airport,Otorii,13,0
+0xD6,0x04,Keikyu Airport,Anamori-Inari,14,0
+0xD6,0x05,Keikyu Airport,Tenkubashi,15,0
+0xD6,0x06,Keikyu Airport,Haneda-Airport,16,0

+ 65 - 0
files/suica/line_0xE3.txt

@@ -0,0 +1,65 @@
+0xE3,0x2C,Ginza,Asakusa,19,0
+0xE3,0x2D,Ginza,Tawaramachi,18,0
+0xE3,0x2E,Ginza,Inaricho,17,0
+0xE3,0x2F,Ginza,Ueno,16,0
+0xE3,0x30,Ginza,Ueno-hirokoji,15,0
+0xE3,0x31,Ginza,Suehirocho,14,0
+0xE3,0x32,Ginza,Kanda,13,0
+0xE3,0x33,Ginza,Mitsukoshimae,12,0
+0xE3,0x34,Ginza,Nihombashi,11,0
+0xE3,0x35,Ginza,Kyobashi,10,0
+0xE3,0x36,Ginza,Ginza,9,0
+0xE3,0x37,Ginza,Shimbashi,8,0
+0xE3,0x38,Ginza,Toranomon,7,0
+0xE3,0x39,Ginza,Tameike-sannō,6,0
+0xE3,0x3A,Ginza,Akasaka-mitsuke,5,0
+0xE3,0x3B,Ginza,Aoyama-itchōme,4,0
+0xE3,0x3C,Ginza,Gaiemmae,3,0
+0xE3,0x3D,Ginza,Omote-sandō,2,0
+0xE3,0x3E,Ginza,Shibuya,1,0
+,,,,,
+0xE3,0x5E,Chiyoda,Yoyogi-uehara,1,0
+0xE3,0x5D,Chiyoda,Yoyogi-koen,2,0
+0xE3,0x5C,Chiyoda,Meiji-jingumae,3,0
+0xE3,0x5B,Chiyoda,Omotesando,4,0
+0xE3,0x59,Chiyoda,Nogizaka,5,0
+0xE3,0x58,Chiyoda,Akasaka,6,0
+0xE3,0x57,Chiyoda,Kokkai-gijidomae,7,0
+0xE3,0x56,Chiyoda,Kasumigaseki,8,0
+0xE3,0x55,Chiyoda,Hibiya,9,0
+0xE3,0x54,Chiyoda,Nijubashimae,10,0
+0xE3,0x53,Chiyoda,Otemachi,11,0
+0xE3,0x51,Chiyoda,Shin-ochanomizu,12,0
+0xE3,0x50,Chiyoda,Yushima,13,0
+0xE3,0x4F,Chiyoda,Nezu,14,0
+0xE3,0x4E,Chiyoda,Sendagi,15,0
+0xE3,0x4D,Chiyoda,Nishi-Nippori,16,0
+0xE3,0x4C,Chiyoda,Machiya,17,0
+0xE3,0x4A,Chiyoda,Kita-senju,18,0
+0xE3,0x48,Chiyoda,Ayase,19,0
+0xE3,0x47,Chiyoda,Kita-Ayase,20,0
+,,,,,
+0xE3,0x65,Yurakucho,Wakoshi,1,0
+0xE3,0x66,Yurakucho,Chikatetsu-narimasu,2,0
+0xE3,0x68,Yurakucho,Chikatetsu-akatsuka,3,0
+0xE3,0x6A,Yurakucho,Heiwadai,4,0
+0xE3,0x6B,Yurakucho,Hikawadai,5,0
+0xE3,0x6D,Yurakucho,Kotake-mukaihara,6,0
+0xE3,0x6E,Yurakucho,Senkawa,7,0
+0xE3,0x6F,Yurakucho,Kanamecho,8,0
+0xE3,0x70,Yurakucho,Ikebukuro,9,0
+0xE3,0x71,Yurakucho,Higashi-ikebukuro,10,0
+0xE3,0x72,Yurakucho,Gokokuji,11,0
+0xE3,0x73,Yurakucho,Edogawabashi,12,0
+0xE3,0x75,Yurakucho,Iidabashi,13,0
+0xE3,0x76,Yurakucho,Ichigaya,14,0
+0xE3,0x77,Yurakucho,Kojimachi,15,0
+0xE3,0x78,Yurakucho,Nagatacho,16,0
+0xE3,0x79,Yurakucho,Sakuradamon,17,0
+0xE3,0x7A,Yurakucho,Yurakucho,18,0
+0xE3,0x7B,Yurakucho,Ginza-itchome,19,0
+0xE3,0x7C,Yurakucho,Shintomicho,20,0
+0xE3,0x7D,Yurakucho,Tsukishima,21,0
+0xE3,0x7E,Yurakucho,Toyosu,22,0
+0xE3,0x7F,Yurakucho,Tatsumi,23,0
+0xE3,0x80,Yurakucho,Shin-kiba,24,0

+ 45 - 0
files/suica/line_0xE4.txt

@@ -0,0 +1,45 @@
+0xE4,0x25,Hibiya,Kita-senju,22,0
+0xE4,0x27,Hibiya,Minami-senju,21,0
+0xE4,0x28,Hibiya,Minowa,20,0
+0xE4,0x29,Hibiya,Iriya,19,0
+0xE4,0x2A,Hibiya,Ueno,18,0
+0xE4,0x2B,Hibiya,Naka-okachimachi,17,0
+0xE4,0x2C,Hibiya,Akihabara,16,0
+0xE4,0x2D,Hibiya,Kodenmacho,15,0
+0xE4,0x2E,Hibiya,Ningyocho,14,0
+0xE4,0x2F,Hibiya,Kayabacho,13,0
+0xE4,0x30,Hibiya,Hatchobori,12,0
+0xE4,0x31,Hibiya,Tsukiji,11,0
+0xE4,0x32,Hibiya,Higashi-ginza,10,0
+0xE4,0x33,Hibiya,Ginza,9,0
+0xE4,0x34,Hibiya,Hibiya,8,0
+0xE4,0x35,Hibiya,Kasumigaseki,7,0
+0xE4,0x37,Hibiya,Kamiyacho,5,0
+0xE4,0x39,Hibiya,Roppongi,4,0
+0xE4,0x3B,Hibiya,Hiro-o,3,0
+0xE4,0x3D,Hibiya,Ebisu,2,0
+0xE4,0x3E,Hibiya,Naka-meguro,1,0
+,,,,,
+0xE4,0x41,Tozai,Nakano,1,0
+0xE4,0x43,Tozai,Ochiai,2,0
+0xE4,0x45,Tozai,Takadanobaba,3,0
+0xE4,0x47,Tozai,Waseda,4,0
+0xE4,0x48,Tozai,Kagurazaka,5,0
+0xE4,0x49,Tozai,Iidabashi,6,0
+0xE4,0x4A,Tozai,Kudanshita,7,0
+0xE4,0x4B,Tozai,Takebashi,8,0
+0xE4,0x4C,Tozai,Otemachi,9,0
+0xE4,0x4D,Tozai,Nihombashi,10,0
+0xE4,0x4E,Tozai,Kayabacho,11,0
+0xE4,0x50,Tozai,Monzen-nakacho,12,0
+0xE4,0x51,Tozai,Kiba,13,0
+0xE4,0x52,Tozai,Toyocho,14,0
+0xE4,0x53,Tozai,Minami-sunamachi,15,0
+0xE4,0x54,Tozai,Nishi-kasai,16,0
+0xE4,0x55,Tozai,Kasai,17,0
+0xE4,0x57,Tozai,Urayasu,18,0
+0xE4,0x58,Tozai,Minami-gyotoku,19,0
+0xE4,0x59,Tozai,Gyotoku,20,0
+0xE4,0x5A,Tozai,Myoden,21,0
+0xE4,0x5C,Tozai,Baraki-nakayama,22,0
+0xE4,0x5E,Tozai,Nishi-funabashi,23,0

+ 30 - 0
files/suica/line_0xE5.txt

@@ -0,0 +1,30 @@
+0xE5,0x21,Marunouchi,Ikebukuro,25,0
+0xE5,0x23,Marunouchi,Shin-otsuka,24,0
+0xE5,0x24,Marunouchi,Myogadani,23,0
+0xE5,0x26,Marunouchi,Korakuen,22,0
+0xE5,0x27,Marunouchi,Hongo-sanchome,21,0
+0xE5,0x28,Marunouchi,Ochanomizu,20,0
+0xE5,0x29,Marunouchi,Awajicho,19,0
+0xE5,0x2A,Marunouchi,Otemachi,18,0
+0xE5,0x2B,Marunouchi,Tokyo,17,0
+0xE5,0x2C,Marunouchi,Ginza,16,0
+0xE5,0x2D,Marunouchi,Kasumigaseki,15,0
+0xE5,0x2E,Marunouchi,Kokkai-gijidomae,14,0
+0xE5,0x2F,Marunouchi,Akasaka-mitsuke,13,0
+0xE5,0x30,Marunouchi,Yotsuya,12,0
+0xE5,0x31,Marunouchi,Yotsuya-sanchome,11,0
+0xE5,0x32,Marunouchi,Shinjuku-gyoemmae,10,0
+0xE5,0x33,Marunouchi,Shinjuku-sanchome,9,0
+0xE5,0x34,Marunouchi,Shinjuku,8,0
+0xE5,0x35,Marunouchi,Nishi-shinjuku,7,0
+0xE5,0x36,Marunouchi,Nakano-sakaue,6,0
+0xE5,0x37,Marunouchi,Shin-nakano,5,0
+0xE5,0x38,Marunouchi,Higashi-koenji,4,0
+0xE5,0x39,Marunouchi,Shin-koenji,3,0
+0xE5,0x3A,Marunouchi,Minami-asagaya,2,0
+0xE5,0x3C,Marunouchi,Ogikubo,1,0
+,,,,,
+0xE5,0x41,M Honancho,Nakano-sakaue,6,0
+0xE5,0x42,M Honancho,Nakano-shimbashi,5,0
+0xE5,0x43,M Honancho,Nakano-fujimicho,4,0
+0xE5,0x44,M Honancho,Honancho,3,0

+ 14 - 0
files/suica/line_0xE6.txt

@@ -0,0 +1,14 @@
+0xE6,0x21,Hanzomon,Shibuya,1,0
+0xE6,0x22,Hanzomon,Omotesando,2,0
+0xE6,0x23,Hanzomon,Aoyama-itchome,3,0
+0xE6,0x26,Hanzomon,Nagatacho,4,0
+0xE6,0x27,Hanzomon,Hanzomon,5,0
+0xE6,0x28,Hanzomon,Kudanshita,6,0
+0xE6,0x29,Hanzomon,Jimbocho,7,0
+0xE6,0x2B,Hanzomon,Otemachi,8,0
+0xE6,0x2C,Hanzomon,Mitsukoshimae,9,0
+0xE6,0x2D,Hanzomon,Suitengumae,10,0
+0xE6,0x2F,Hanzomon,Kiyosumi-shirakawa,11,0
+0xE6,0x31,Hanzomon,Sumiyoshi,12,0
+0xE6,0x33,Hanzomon,Kinshicho,13,0
+0xE6,0x35,Hanzomon,Oshiage,14,0

+ 19 - 0
files/suica/line_0xE7.txt

@@ -0,0 +1,19 @@
+0xE7,0x24,Namboku,Meguro,1,0
+0xE7,0x25,Namboku,Shirokanedai,2,0
+0xE7,0x26,Namboku,Shirokane-takanawa,3,0
+0xE7,0x28,Namboku,Azabu-juban,4,0
+0xE7,0x29,Namboku,Roppongi-itchome,5,0
+0xE7,0x2A,Namboku,Tameike-sanno,6,0
+0xE7,0x2C,Namboku,Nagatacho,7,0
+0xE7,0x2E,Namboku,Yotsuya,8,0
+0xE7,0x30,Namboku,Ichigaya,9,0
+0xE7,0x32,Namboku,Iidabashi,10,0
+0xE7,0x33,Namboku,Korakuen,11,0
+0xE7,0x34,Namboku,Todaimae,12,0
+0xE7,0x35,Namboku,Hon-komagome,13,0
+0xE7,0x36,Namboku,Komagome,14,0
+0xE7,0x37,Namboku,Nishigahara,15,0
+0xE7,0x38,Namboku,Oji,16,0
+0xE7,0x39,Namboku,Oji-kamiya,17,0
+0xE7,0x3B,Namboku,Shimo,18,0
+0xE7,0x3C,Namboku,Akabane-iwabuchi,19,0

+ 20 - 0
files/suica/line_0xEF.txt

@@ -0,0 +1,20 @@
+0xEF,0x01,Asakusa,Oshiage,20,0
+0xEF,0x02,Asakusa,Honjo-azumabashi,19,0
+0xEF,0x03,Asakusa,Asakusa,18,0
+0xEF,0x04,Asakusa,Kuramae,17,0
+0xEF,0x05,Asakusa,Asakusabashi,16, 0
+0xEF,0x06,Asakusa,Higashi-nihombashi,15,0
+0xEF,0x07,Asakusa,Ningyocho,14,0
+0xEF,0x08,Asakusa,Nihombashi,13,0
+0xEF,0x09,Asakusa,Takaracho,12,0
+0xEF,0x0A,Asakusa,Higashi-ginza,11,0
+0xEF,0x0B,Asakusa,Shimbashi,10,0
+0xEF,0x0C,Asakusa,Daimon,9,0
+0xEF,0x0D,Asakusa,Mita,8,0
+0xEF,0x0E,Asakusa,Sengakuji,7,0
+0xEF,0x0F,Asakusa,Takanawadai,6,0
+0xEF,0x10,Asakusa,Gotanda,5,0
+0xEF,0x11,Asakusa,Togoshi,4,0
+0xEF,0x12,Asakusa,Nakanobu,3,0
+0xEF,0x13,Asakusa,Magome,2,0
+0xEF,0x14,Asakusa,Nishi-magome,1,0

+ 27 - 0
files/suica/line_0xF0.txt

@@ -0,0 +1,27 @@
+0xF0,0x27,Mita,Nishi-takashimadaira,27,0
+0xF0,0x28,Mita,Shin-takashimadaira,26,0
+0xF0,0x29,Mita,Takashimadaira,25,0
+0xF0,0x2A,Mita,Nishidai,24,0
+0xF0,0x2B,Mita,Hasune,23,0
+0xF0,0x2C,Mita,Shimura-sanchome,22,0
+0xF0,0x2D,Mita,Shimura-sakaue,21,0
+0xF0,0x2E,Mita,Motohasunuma,20,0
+0xF0,0x2F,Mita,Itabashi-honcho,19,0
+0xF0,0x30,Mita,Itabashikuyakushomae,18,0
+0xF0,0x31,Mita,Shin-itabashi,17,0
+0xF0,0x32,Mita,Nishi-sugamo,16,0
+0xF0,0x33,Mita,Sugamo,15,0
+0xF0,0x34,Mita,Sengoku,14,0
+0xF0,0x35,Mita,Hakusan,13,0
+0xF0,0x36,Mita,Kasuga,12,0
+0xF0,0x37,Mita,Suidobashi,11,0
+0xF0,0x38,Mita,Jimbocho,10,0
+0xF0,0x39,Mita,Otemachi,9,0
+0xF0,0x3A,Mita,Hibiya,8,0
+0xF0,0x3B,Mita,Uchisaiwaicho,7,0
+0xF0,0x3C,Mita,Onarimon,6,0
+0xF0,0x3D,Mita,Shibakoen,5,0
+0xF0,0x3E,Mita,Mita,4,0
+0xF0,0x40,Mita,Shirokane-takanawa,3,0
+0xF0,0x42,Mita,Shirokanedai,2,0
+0xF0,0x44,Mita,Meguro,1,0

+ 21 - 0
files/suica/line_0xF1.txt

@@ -0,0 +1,21 @@
+0xF1,0x01,Shinjuku,Shinjuku,1,0
+0xF1,0x02,Shinjuku,Shinjuku-sanchome,2,0
+0xF1,0x03,Shinjuku,Akebonobashi,3,0
+0xF1,0x04,Shinjuku,Ichigaya,4,0
+0xF1,0x05,Shinjuku,Kudanshita,5,0
+0xF1,0x06,Shinjuku,Jimbocho,6,0
+0xF1,0x07,Shinjuku,Ogawamachi,7,0
+0xF1,0x08,Shinjuku,Iwamotocho,8,0
+0xF1,0x09,Shinjuku,Bakuro-yokoyama,9,0
+0xF1,0x0A,Shinjuku,Hamacho,10,0
+0xF1,0x0B,Shinjuku,Morishita,11,0
+0xF1,0x0C,Shinjuku,Kikukawa,12,0
+0xF1,0x0D,Shinjuku,Sumiyoshi,13,0
+0xF1,0x0E,Shinjuku,Nishi-ojima,14,0
+0xF1,0x0F,Shinjuku,Ojima,15,0
+0xF1,0x11,Shinjuku,Higashi-ojima,16,0
+0xF1,0x13,Shinjuku,Funabori,17,0
+0xF1,0x15,Shinjuku,Ichinoe,18,0
+0xF1,0x17,Shinjuku,Mizue,19,0
+0xF1,0x19,Shinjuku,Shinozaki,20,0
+0xF1,0x1B,Shinjuku,Motoyawata,21,0

+ 26 - 0
files/suica/line_0xF2.txt

@@ -0,0 +1,26 @@
+0xF2,0x04,Oedo,Morishita,13,0
+0xF2,0x06,Oedo,Kiyosumi-shirakawa,14,0
+0xF2,0x08,Oedo,Monzen-nakacho,15,0
+0xF2,0x0A,Oedo,Tsukishima,16,0
+0xF2,0x0C,Oedo,Kachidoki,17,0
+0xF2,0x0E,Oedo,Tsukiji-shijo,18,0
+0xF2,0x10,Oedo,Shiodome,19,0
+0xF2,0x12,Oedo,Daimon,20,0
+0xF2,0x14,Oedo,Akabanebashi,21,0
+0xF2,0x16,Oedo,Azabu-juban,22,0
+0xF2,0x18,Oedo,Roppongi,23,0
+0xF2,0x1A,Oedo,Aoyama-itchome,24,0
+0xF2,0x1C,Oedo,Kokuritsu-kyogijo,25,0
+0xF2,0x1E,Oedo,Yoyogi,26,0
+0xF2,0x20,Oedo,Shinjuku,27,0
+0xF2,0x22,Oedo,Tochomae,28,0
+0xF2,0x24,Oedo,Nishi-shinjuku-gochome,29,0
+0xF2,0x26,Oedo,Nakano-sakaue,30,0
+0xF2,0x28,Oedo,Higashi-nakano,31,0
+0xF2,0x2A,Oedo,Nakai,32,0
+0xF2,0x2C,Oedo,Ochiai-minami-nagasaki,33,0
+0xF2,0x2E,Oedo,Shin-egota,34,0
+0xF2,0x30,Oedo,Nerima,35,0
+0xF2,0x32,Oedo,Toshimaen,36,0
+0xF2,0x34,Oedo,Nerima-kasugacho,37,0
+0xF2,0x36,Oedo,Hikarigaoka,38,0

+ 14 - 0
files/suica/line_0xF3.txt

@@ -0,0 +1,14 @@
+0xF3,0x03,Oedo,Morishita,13,0
+0xF3,0x05,Oedo,Ryogoku,12,0
+0xF3,0x07,Oedo,Kuramae,11,0
+0xF3,0x09,Oedo,Shin-okachimachi,10,0
+0xF3,0x0B,Oedo,Ueno-okachimachi,9,0
+0xF3,0x0D,Oedo,Hongo-sanchome,8,0
+0xF3,0x0F,Oedo,Kasuga,7,0
+0xF3,0x11,Oedo,Iidabashi,6,0
+0xF3,0x13,Oedo,Ushigome-kagurazaka,5,0
+0xF3,0x15,Oedo,Ushigome-yanagicho,4,0
+0xF3,0x17,Oedo,Wakamatsu-kawada,3,0
+0xF3,0x19,Oedo,Higashi-shinjuku,2,0
+0xF3,0x1B,Oedo,Shinjuku-nishiguchi,1,0
+0xF3,0x1D,Oedo,Tochomae,28,0

+ 11 - 0
files/suica/line_0xFA.txt

@@ -0,0 +1,11 @@
+0xFA,0x01,Tokyo Monorail,Monorail Hamamatsucho,1,0
+0xFA,0x03,Tokyo Monorail,Tennozu Isle,2,0
+0xFA,0x04,Tokyo Monorail,Oi Keibajo Mae,3,0
+0xFA,0x05,Tokyo Monorail,Ryutsu Center,4,0
+0xFA,0x06,Tokyo Monorail,Showajima,5,0
+0xFA,0x07,Tokyo Monorail,Seibijo,6,0
+0xFA,0x09,Tokyo Monorail,Tenkubashi,7,0
+0xFA,0x0A,Tokyo Monorail,Haneda Airport T3,8,0
+0xFA,0x0B,Tokyo Monorail,Shinseibijo,9,0
+0xFA,0x0C,Tokyo Monorail,Haneda Airport T1,10,0
+0xFA,0x0D,Tokyo Monorail,Haneda Airport T2,11,0

+ 419 - 0
files/suica/stations.txt

@@ -0,0 +1,419 @@
+0x01,0x01,Tokaido Main,Tokyo,1,TYO
+0x01,0x03,Tokaido Main,Shimbashi,2,SMB
+0x01,0x07,Tokaido Main,Shinagawa,3,SGW
+0x01,0x0D,Tokaido Main,Kawasaki,4,KWS
+0x01,0x12,Tokaido Main,Yokohama,5,YHM
+0x01,0x16,Tokaido Main,Totsuka,6,TTK
+0x01,0x18,Tokaido Main,Ofuna,7,OFN
+0x01,0x19,Tokaido Main,Fujisawa,8,0
+0x01,0x1A,Tokaido Main,Tsujido,9,0
+0x01,0x1B,Tokaido Main,Chigasaki,10,0
+0x01,0x1D,Tokaido Main,Hiratsuka,11,0
+0x01,0x1E,Tokaido Main,Oiso,12,0
+0x01,0x20,Tokaido Main,Ninomiya,13,0
+0x01,0x21,Tokaido Main,Kozu,14,0
+0x01,0x22,Tokaido Main,Kamonomiya,15,0
+0x01,0x23,Tokaido Main,Odawara,16,0
+0x01,0x25,Tokaido Main,Hayakawa,17,0
+0x01,0x26,Tokaido Main,Nebukawa,18,0
+0x01,0x28,Tokaido Main,Manazuru,19,0
+0x01,0x29,Tokaido Main,Yugawara,20,0
+0x01,0x2B,Tokaido Main,Atami,21,0
+,,,,,
+0x01,0x01,Keihin Tohoku,Tokyo,26,TYO
+0x01,0x02,Keihin Tohoku,Yurakucho,25,0
+0x01,0x03,Keihin Tohoku,Shimbashi,24,SMB
+0x01,0x04,Keihin Tohoku,Hamamatsucho,23,HMC
+0x01,0x06,Keihin Tohoku,Tamachi,22,0
+0x01,0x07,Keihin Tohoku,Shinagawa,20,SGW
+0x01,0x08,Keihin Tohoku,Oimachi,19,0
+0x01,0x09,Keihin Tohoku,Omori,18,0
+0x01,0x0B,Keihin Tohoku,Kamata,17,0
+0x01,0x0D,Keihin Tohoku,Kawasaki,16,KWS
+0x01,0x0E,Keihin Tohoku,Tsurumi,15,0
+0x01,0x10,Keihin Tohoku,Shin-koyasu,14,0
+0x01,0x11,Keihin Tohoku,Higashi-kanagawa,13,0
+0x01,0x12,Keihin Tohoku,Yokohama,12,YHM
+,,,,,
+0x1D,0x04,Negishi,Hongodai,2,0
+0x1D,0x06,Negishi,Konandai,3,0
+0x1D,0x07,Negishi,Yokodai,4,0
+0x1D,0x08,Negishi,Shin-sugita,5,0
+0x1D,0x09,Negishi,Isogo,6,0
+0x1D,0x0A,Negishi,Negishi,7,0
+0x1D,0x0C,Negishi,Yamate,8,0
+0x1D,0x0D,Negishi,Ishikawacho,9,0
+0x1D,0x0E,Negishi,Kannai,10,0
+0x1D,0x0F,Negishi,Sakuragicho,11,0
+,,,,,
+0x82,0x01,Rinkai,Shin-kiba,1,0
+0x82,0x03,Rinkai,Shinonome,2,0
+0x82,0x04,Rinkai,Kokusai-tenjijo,3,0
+0x82,0x05,Rinkai,Tokyo Teleport,4,0
+0x82,0x06,Rinkai,Tennozu Isle,5,0
+0x82,0x07,Rinkai,Shinagawa Seaside,6,0
+0x82,0x08,Rinkai,Oimachi,7,0
+0x82,0x0A,Rinkai,Osaki,8,0
+,,,,,
+0xFA,0x01,Tokyo Monorail,Monorail Hamamatsucho,1,0
+0xFA,0x03,Tokyo Monorail,Tennozu Isle,2,0
+0xFA,0x04,Tokyo Monorail,Oi Keibajo Mae,3,0
+0xFA,0x05,Tokyo Monorail,Ryutsu Center,4,0
+0xFA,0x06,Tokyo Monorail,Showajima,5,0
+0xFA,0x07,Tokyo Monorail,Seibijo,6,0
+0xFA,0x09,Tokyo Monorail,Tenkubashi,7,0
+0xFA,0x0A,Tokyo Monorail,Haneda Airport T3,8,0
+0xFA,0x0B,Tokyo Monorail,Shinseibijo,9,0
+0xFA,0x0C,Tokyo Monorail,Haneda Airport T1,10,0
+0xFA,0x0D,Tokyo Monorail,Haneda Airport T2,11,0
+,,,,,
+0xD6,0x01,Keikyu Airport,Keikyu Kamata,11,0
+0xD6,0x02,Keikyu Airport,Kojiya,12,0
+0xD6,0x03,Keikyu Airport,Otorii,13,0
+0xD6,0x04,Keikyu Airport,Anamori-Inari,14,0
+0xD6,0x05,Keikyu Airport,Tenkubashi,15,0
+0xD6,0x06,Keikyu Airport,Haneda-Airport,16,0
+,,,,,
+0xD5,0x01,Keikyu Main,Sengakuji,7,0
+0xD5,0x02,Keikyu Main,Shinagawa,1,0
+0xD5,0x03,Keikyu Main,Kita-Shinagawa,2,0
+0xD5,0x04,Keikyu Main,Shimbamba,3,0
+0xD5,0x06,Keikyu Main,Aomono-yokocho,4,0
+0xD5,0x07,Keikyu Main,Samezu,5,0
+0xD5,0x08,Keikyu Main,Tachiaigawa,6,0
+0xD5,0x09,Keikyu Main,Omorikaigan,7,0
+0xD5,0x0A,Keikyu Main,Heiwajima,8,0
+0xD5,0x0B,Keikyu Main,Omorimachi,9,0
+0xD5,0x0C,Keikyu Main,Umeyashiki,10,0
+0xD5,0x0D,Keikyu Main,Keikyu Kamata,11,0
+0xD5,0x0E,Keikyu Main,Zoshiki,18,0
+0xD5,0x0F,Keikyu Main,Rokugodote,19,0
+0xD5,0x10,Keikyu Main,Keikyu Kawasaki,20,0
+0xD5,0x11,Keikyu Main,Hatcho-nawate,27,0
+0xD5,0x12,Keikyu Main,Tsurumi-ichiba,28,0
+0xD5,0x13,Keikyu Main,Keikyu Tsurumi,29,0
+0xD5,0x14,Keikyu Main,Kagetsu-sojiji,30,0
+0xD5,0x15,Keikyu Main,Namamugi,31,0
+0xD5,0x16,Keikyu Main,Keikyu Shinkoyasu,32,0
+0xD5,0x17,Keikyu Main,Koyasu,33,0
+0xD5,0x18,Keikyu Main,Kanagawa-shimmachi,34,0
+0xD5,0x19,Keikyu Main,KK Higashi-kanagawa,35,0
+0xD5,0x1A,Keikyu Main,Kanagawa,36,0
+0xD5,0x1B,Keikyu Main,Yokohama,37,0
+0xD5,0x1C,Keikyu Main,Tobe,38,0
+0xD5,0x1D,Keikyu Main,Hinodecho,39,0
+0xD5,0x1E,Keikyu Main,Koganecho,40,0
+0xD5,0x1F,Keikyu Main,Minamiota,41,0
+0xD5,0x20,Keikyu Main,Idogaya,42,0
+0xD5,0x21,Keikyu Main,Gumyoji,43,0
+0xD5,0x22,Keikyu Main,Kamiooka,44,0
+0xD5,0x24,Keikyu Main,Byobugaura,45,0
+0xD5,0x25,Keikyu Main,Sugita,46,0
+0xD5,0x27,Keikyu Main,Keikyu Tomioka,47,0
+0xD5,0x28,Keikyu Main,Nokendai,48,0
+0xD5,0x29,Keikyu Main,Kanazawa-bunko,49,0
+0xD5,0x2A,Keikyu Main,Kanazawa-hakkei,50,0
+0xD5,0x2B,Keikyu Main,Oppama,54,0
+0xD5,0x2C,Keikyu Main,Keikyu Taura,55,0
+0xD5,0x2E,Keikyu Main,Anjinzuka,56,0
+0xD5,0x2F,Keikyu Main,Hemi,57,0
+0xD5,0x30,Keikyu Main,Shioiri,58,0
+0xD5,0x31,Keikyu Main,Yokosuka-chuo,59,0
+0xD5,0x32,Keikyu Main,Kenritsudaigaku,60,0
+0xD5,0x33,Keikyu Main,Horinouchi,61,0
+0xD5,0x34,Keikyu Main,Keikyu Otsu,62,0
+0xD5,0x35,Keikyu Main,Maborikaigan,63,0
+0xD5,0x36,Keikyu Main,Uraga,64,0
+,,,,,
+0xE3,0x2C,Ginza,Asakusa,19,0
+0xE3,0x2D,Ginza,Tawaramachi,18,0
+0xE3,0x2E,Ginza,Inaricho,17,0
+0xE3,0x2F,Ginza,Ueno,16,0
+0xE3,0x30,Ginza,Ueno-hirokoji,15,0
+0xE3,0x31,Ginza,Suehirocho,14,0
+0xE3,0x32,Ginza,Kanda,13,0
+0xE3,0x33,Ginza,Mitsukoshimae,12,0
+0xE3,0x34,Ginza,Nihombashi,11,0
+0xE3,0x35,Ginza,Kyobashi,10,0
+0xE3,0x36,Ginza,Ginza,9,0
+0xE3,0x37,Ginza,Shimbashi,8,0
+0xE3,0x38,Ginza,Toranomon,7,0
+0xE3,0x39,Ginza,Tameike-sannō,6,0
+0xE3,0x3A,Ginza,Akasaka-mitsuke,5,0
+0xE3,0x3B,Ginza,Aoyama-itchōme,4,0
+0xE3,0x3C,Ginza,Gaiemmae,3,0
+0xE3,0x3D,Ginza,Omote-sandō,2,0
+0xE3,0x3E,Ginza,Shibuya,1,0
+,,,,,
+0xE3,0x5E,Chiyoda,Yoyogi-uehara,1,0
+0xE3,0x5D,Chiyoda,Yoyogi-koen,2,0
+0xE3,0x5C,Chiyoda,Meiji-jingumae,3,0
+0xE3,0x5B,Chiyoda,Omotesando,4,0
+0xE3,0x59,Chiyoda,Nogizaka,5,0
+0xE3,0x58,Chiyoda,Akasaka,6,0
+0xE3,0x57,Chiyoda,Kokkai-gijidomae,7,0
+0xE3,0x56,Chiyoda,Kasumigaseki,8,0
+0xE3,0x55,Chiyoda,Hibiya,9,0
+0xE3,0x54,Chiyoda,Nijubashimae,10,0
+0xE3,0x53,Chiyoda,Otemachi,11,0
+0xE3,0x51,Chiyoda,Shin-ochanomizu,12,0
+0xE3,0x50,Chiyoda,Yushima,13,0
+0xE3,0x4F,Chiyoda,Nezu,14,0
+0xE3,0x4E,Chiyoda,Sendagi,15,0
+0xE3,0x4D,Chiyoda,Nishi-Nippori,16,0
+0xE3,0x4C,Chiyoda,Machiya,17,0
+0xE3,0x4A,Chiyoda,Kita-senju,18,0
+0xE3,0x48,Chiyoda,Ayase,19,0
+0xE3,0x47,Chiyoda,Kita-Ayase,20,0
+,,,,,
+0xE3,0x65,Yurakucho,Wakoshi,1,0
+0xE3,0x66,Yurakucho,Chikatetsu-narimasu,2,0
+0xE3,0x68,Yurakucho,Chikatetsu-akatsuka,3,0
+0xE3,0x6A,Yurakucho,Heiwadai,4,0
+0xE3,0x6B,Yurakucho,Hikawadai,5,0
+0xE3,0x6D,Yurakucho,Kotake-mukaihara,6,0
+0xE3,0x6E,Yurakucho,Senkawa,7,0
+0xE3,0x6F,Yurakucho,Kanamecho,8,0
+0xE3,0x70,Yurakucho,Ikebukuro,9,0
+0xE3,0x71,Yurakucho,Higashi-ikebukuro,10,0
+0xE3,0x72,Yurakucho,Gokokuji,11,0
+0xE3,0x73,Yurakucho,Edogawabashi,12,0
+0xE3,0x75,Yurakucho,Iidabashi,13,0
+0xE3,0x76,Yurakucho,Ichigaya,14,0
+0xE3,0x77,Yurakucho,Kojimachi,15,0
+0xE3,0x78,Yurakucho,Nagatacho,16,0
+0xE3,0x79,Yurakucho,Sakuradamon,17,0
+0xE3,0x7A,Yurakucho,Yurakucho,18,0
+0xE3,0x7B,Yurakucho,Ginza-itchome,19,0
+0xE3,0x7C,Yurakucho,Shintomicho,20,0
+0xE3,0x7D,Yurakucho,Tsukishima,21,0
+0xE3,0x7E,Yurakucho,Toyosu,22,0
+0xE3,0x7F,Yurakucho,Tatsumi,23,0
+0xE3,0x80,Yurakucho,Shin-kiba,24,0
+,,,,,
+0xE4,0x25,Hibiya,Kita-senju,22,0
+0xE4,0x27,Hibiya,Minami-senju,21,0
+0xE4,0x28,Hibiya,Minowa,20,0
+0xE4,0x29,Hibiya,Iriya,19,0
+0xE4,0x2A,Hibiya,Ueno,18,0
+0xE4,0x2B,Hibiya,Naka-okachimachi,17,0
+0xE4,0x2C,Hibiya,Akihabara,16,0
+0xE4,0x2D,Hibiya,Kodenmacho,15,0
+0xE4,0x2E,Hibiya,Ningyocho,14,0
+0xE4,0x2F,Hibiya,Kayabacho,13,0
+0xE4,0x30,Hibiya,Hatchobori,12,0
+0xE4,0x31,Hibiya,Tsukiji,11,0
+0xE4,0x32,Hibiya,Higashi-ginza,10,0
+0xE4,0x33,Hibiya,Ginza,9,0
+0xE4,0x34,Hibiya,Hibiya,8,0
+0xE4,0x35,Hibiya,Kasumigaseki,7,0
+0xE4,0x37,Hibiya,Kamiyacho,5,0
+0xE4,0x39,Hibiya,Roppongi,4,0
+0xE4,0x3B,Hibiya,Hiro-o,3,0
+0xE4,0x3D,Hibiya,Ebisu,2,0
+0xE4,0x3E,Hibiya,Naka-meguro,1,0
+,,,,,
+0xE4,0x41,Tozai,Nakano,1,0
+0xE4,0x43,Tozai,Ochiai,2,0
+0xE4,0x45,Tozai,Takadanobaba,3,0
+0xE4,0x47,Tozai,Waseda,4,0
+0xE4,0x48,Tozai,Kagurazaka,5,0
+0xE4,0x49,Tozai,Iidabashi,6,0
+0xE4,0x4A,Tozai,Kudanshita,7,0
+0xE4,0x4B,Tozai,Takebashi,8,0
+0xE4,0x4C,Tozai,Otemachi,9,0
+0xE4,0x4D,Tozai,Nihombashi,10,0
+0xE4,0x4E,Tozai,Kayabacho,11,0
+0xE4,0x50,Tozai,Monzen-nakacho,12,0
+0xE4,0x51,Tozai,Kiba,13,0
+0xE4,0x52,Tozai,Toyocho,14,0
+0xE4,0x53,Tozai,Minami-sunamachi,15,0
+0xE4,0x54,Tozai,Nishi-kasai,16,0
+0xE4,0x55,Tozai,Kasai,17,0
+0xE4,0x57,Tozai,Urayasu,18,0
+0xE4,0x58,Tozai,Minami-gyotoku,19,0
+0xE4,0x59,Tozai,Gyotoku,20,0
+0xE4,0x5A,Tozai,Myoden,21,0
+0xE4,0x5C,Tozai,Baraki-nakayama,22,0
+0xE4,0x5E,Tozai,Nishi-funabashi,23,0
+,,,,,
+0xE5,0x21,Marunouchi,Ikebukuro,25,0
+0xE5,0x23,Marunouchi,Shin-otsuka,24,0
+0xE5,0x24,Marunouchi,Myogadani,23,0
+0xE5,0x26,Marunouchi,Korakuen,22,0
+0xE5,0x27,Marunouchi,Hongo-sanchome,21,0
+0xE5,0x28,Marunouchi,Ochanomizu,20,0
+0xE5,0x29,Marunouchi,Awajicho,19,0
+0xE5,0x2A,Marunouchi,Otemachi,18,0
+0xE5,0x2B,Marunouchi,Tokyo,17,0
+0xE5,0x2C,Marunouchi,Ginza,16,0
+0xE5,0x2D,Marunouchi,Kasumigaseki,15,0
+0xE5,0x2E,Marunouchi,Kokkai-gijidomae,14,0
+0xE5,0x2F,Marunouchi,Akasaka-mitsuke,13,0
+0xE5,0x30,Marunouchi,Yotsuya,12,0
+0xE5,0x31,Marunouchi,Yotsuya-sanchome,11,0
+0xE5,0x32,Marunouchi,Shinjuku-gyoemmae,10,0
+0xE5,0x33,Marunouchi,Shinjuku-sanchome,9,0
+0xE5,0x34,Marunouchi,Shinjuku,8,0
+0xE5,0x35,Marunouchi,Nishi-shinjuku,7,0
+0xE5,0x36,Marunouchi,Nakano-sakaue,6,0
+0xE5,0x37,Marunouchi,Shin-nakano,5,0
+0xE5,0x38,Marunouchi,Higashi-koenji,4,0
+0xE5,0x39,Marunouchi,Shin-koenji,3,0
+0xE5,0x3A,Marunouchi,Minami-asagaya,2,0
+0xE5,0x3C,Marunouchi,Ogikubo,1,0
+,,,,,
+0xE5,0x41,M Honancho,Nakano-sakaue,6,0
+0xE5,0x42,M Honancho,Nakano-shimbashi,5,0
+0xE5,0x43,M Honancho,Nakano-fujimicho,4,0
+0xE5,0x44,M Honancho,Honancho,3,0
+,,,,,
+0xE6,0x21,Hanzomon,Shibuya,1,0
+0xE6,0x22,Hanzomon,Omotesando,2,0
+0xE6,0x23,Hanzomon,Aoyama-itchome,3,0
+0xE6,0x26,Hanzomon,Nagatacho,4,0
+0xE6,0x27,Hanzomon,Hanzomon,5,0
+0xE6,0x28,Hanzomon,Kudanshita,6,0
+0xE6,0x29,Hanzomon,Jimbocho,7,0
+0xE6,0x2B,Hanzomon,Otemachi,8,0
+0xE6,0x2C,Hanzomon,Mitsukoshimae,9,0
+0xE6,0x2D,Hanzomon,Suitengumae,10,0
+0xE6,0x2F,Hanzomon,Kiyosumi-shirakawa,11,0
+0xE6,0x31,Hanzomon,Sumiyoshi,12,0
+0xE6,0x33,Hanzomon,Kinshicho,13,0
+0xE6,0x35,Hanzomon,Oshiage,14,0
+,,,,,
+0xE7,0x24,Namboku,Meguro,1,0
+0xE7,0x25,Namboku,Shirokanedai,2,0
+0xE7,0x26,Namboku,Shirokane-takanawa,3,0
+0xE7,0x28,Namboku,Azabu-juban,4,0
+0xE7,0x29,Namboku,Roppongi-itchome,5,0
+0xE7,0x2A,Namboku,Tameike-sanno,6,0
+0xE7,0x2C,Namboku,Nagatacho,7,0
+0xE7,0x2E,Namboku,Yotsuya,8,0
+0xE7,0x30,Namboku,Ichigaya,9,0
+0xE7,0x32,Namboku,Iidabashi,10,0
+0xE7,0x33,Namboku,Korakuen,11,0
+0xE7,0x34,Namboku,Todaimae,12,0
+0xE7,0x35,Namboku,Hon-komagome,13,0
+0xE7,0x36,Namboku,Komagome,14,0
+0xE7,0x37,Namboku,Nishigahara,15,0
+0xE7,0x38,Namboku,Oji,16,0
+0xE7,0x39,Namboku,Oji-kamiya,17,0
+0xE7,0x3B,Namboku,Shimo,18,0
+0xE7,0x3C,Namboku,Akabane-iwabuchi,19,0
+,,,,,
+0xEF,0x01,Asakusa,Oshiage,20,0
+0xEF,0x02,Asakusa,Honjo-azumabashi,19,0
+0xEF,0x03,Asakusa,Asakusa,18,0
+0xEF,0x04,Asakusa,Kuramae,17,0
+0xEF,0x05,Asakusa,Asakusabashi,16, 0
+0xEF,0x06,Asakusa,Higashi-nihombashi,15,0
+0xEF,0x07,Asakusa,Ningyocho,14,0
+0xEF,0x08,Asakusa,Nihombashi,13,0
+0xEF,0x09,Asakusa,Takaracho,12,0
+0xEF,0x0A,Asakusa,Higashi-ginza,11,0
+0xEF,0x0B,Asakusa,Shimbashi,10,0
+0xEF,0x0C,Asakusa,Daimon,9,0
+0xEF,0x0D,Asakusa,Mita,8,0
+0xEF,0x0E,Asakusa,Sengakuji,7,0
+0xEF,0x0F,Asakusa,Takanawadai,6,0
+0xEF,0x10,Asakusa,Gotanda,5,0
+0xEF,0x11,Asakusa,Togoshi,4,0
+0xEF,0x12,Asakusa,Nakanobu,3,0
+0xEF,0x13,Asakusa,Magome,2,0
+0xEF,0x14,Asakusa,Nishi-magome,1,0
+,,,,,
+0xF0,0x27,Mita,Nishi-takashimadaira,27,0
+0xF0,0x28,Mita,Shin-takashimadaira,26,0
+0xF0,0x29,Mita,Takashimadaira,25,0
+0xF0,0x2A,Mita,Nishidai,24,0
+0xF0,0x2B,Mita,Hasune,23,0
+0xF0,0x2C,Mita,Shimura-sanchome,22,0
+0xF0,0x2D,Mita,Shimura-sakaue,21,0
+0xF0,0x2E,Mita,Motohasunuma,20,0
+0xF0,0x2F,Mita,Itabashi-honcho,19,0
+0xF0,0x30,Mita,Itabashikuyakushomae,18,0
+0xF0,0x31,Mita,Shin-itabashi,17,0
+0xF0,0x32,Mita,Nishi-sugamo,16,0
+0xF0,0x33,Mita,Sugamo,15,0
+0xF0,0x34,Mita,Sengoku,14,0
+0xF0,0x35,Mita,Hakusan,13,0
+0xF0,0x36,Mita,Kasuga,12,0
+0xF0,0x37,Mita,Suidobashi,11,0
+0xF0,0x38,Mita,Jimbocho,10,0
+0xF0,0x39,Mita,Otemachi,9,0
+0xF0,0x3A,Mita,Hibiya,8,0
+0xF0,0x3B,Mita,Uchisaiwaicho,7,0
+0xF0,0x3C,Mita,Onarimon,6,0
+0xF0,0x3D,Mita,Shibakoen,5,0
+0xF0,0x3E,Mita,Mita,4,0
+0xF0,0x40,Mita,Shirokane-takanawa,3,0
+0xF0,0x42,Mita,Shirokanedai,2,0
+0xF0,0x44,Mita,Meguro,1,0
+,,,,,
+0xF1,0x01,Shinjuku,Shinjuku,1,0
+0xF1,0x02,Shinjuku,Shinjuku-sanchome,2,0
+0xF1,0x03,Shinjuku,Akebonobashi,3,0
+0xF1,0x04,Shinjuku,Ichigaya,4,0
+0xF1,0x05,Shinjuku,Kudanshita,5,0
+0xF1,0x06,Shinjuku,Jimbocho,6,0
+0xF1,0x07,Shinjuku,Ogawamachi,7,0
+0xF1,0x08,Shinjuku,Iwamotocho,8,0
+0xF1,0x09,Shinjuku,Bakuro-yokoyama,9,0
+0xF1,0x0A,Shinjuku,Hamacho,10,0
+0xF1,0x0B,Shinjuku,Morishita,11,0
+0xF1,0x0C,Shinjuku,Kikukawa,12,0
+0xF1,0x0D,Shinjuku,Sumiyoshi,13,0
+0xF1,0x0E,Shinjuku,Nishi-ojima,14,0
+0xF1,0x0F,Shinjuku,Ojima,15,0
+0xF1,0x11,Shinjuku,Higashi-ojima,16,0
+0xF1,0x13,Shinjuku,Funabori,17,0
+0xF1,0x15,Shinjuku,Ichinoe,18,0
+0xF1,0x17,Shinjuku,Mizue,19,0
+0xF1,0x19,Shinjuku,Shinozaki,20,0
+0xF1,0x1B,Shinjuku,Motoyawata,21,0
+,,,,,
+0xF2,0x04,Oedo,Morishita,13,0
+0xF2,0x06,Oedo,Kiyosumi-shirakawa,14,0
+0xF2,0x08,Oedo,Monzen-nakacho,15,0
+0xF2,0x0A,Oedo,Tsukishima,16,0
+0xF2,0x0C,Oedo,Kachidoki,17,0
+0xF2,0x0E,Oedo,Tsukiji-shijo,18,0
+0xF2,0x10,Oedo,Shiodome,19,0
+0xF2,0x12,Oedo,Daimon,20,0
+0xF2,0x14,Oedo,Akabanebashi,21,0
+0xF2,0x16,Oedo,Azabu-juban,22,0
+0xF2,0x18,Oedo,Roppongi,23,0
+0xF2,0x1A,Oedo,Aoyama-itchome,24,0
+0xF2,0x1C,Oedo,Kokuritsu-kyogijo,25,0
+0xF2,0x1E,Oedo,Yoyogi,26,0
+0xF2,0x20,Oedo,Shinjuku,27,0
+0xF2,0x22,Oedo,Tochomae,28,0
+0xF2,0x24,Oedo,Nishi-shinjuku-gochome,29,0
+0xF2,0x26,Oedo,Nakano-sakaue,30,0
+0xF2,0x28,Oedo,Higashi-nakano,31,0
+0xF2,0x2A,Oedo,Nakai,32,0
+0xF2,0x2C,Oedo,Ochiai-minami-nagasaki,33,0
+0xF2,0x2E,Oedo,Shin-egota,34,0
+0xF2,0x30,Oedo,Nerima,35,0
+0xF2,0x32,Oedo,Toshimaen,36,0
+0xF2,0x34,Oedo,Nerima-kasugacho,37,0
+0xF2,0x36,Oedo,Hikarigaoka,38,0
+,,,,,
+0xF3,0x03,Oedo,Morishita,13,0
+0xF3,0x05,Oedo,Ryogoku,12,0
+0xF3,0x07,Oedo,Kuramae,11,0
+0xF3,0x09,Oedo,Shin-okachimachi,10,0
+0xF3,0x0B,Oedo,Ueno-okachimachi,9,0
+0xF3,0x0D,Oedo,Hongo-sanchome,8,0
+0xF3,0x0F,Oedo,Kasuga,7,0
+0xF3,0x11,Oedo,Iidabashi,6,0
+0xF3,0x13,Oedo,Ushigome-kagurazaka,5,0
+0xF3,0x15,Oedo,Ushigome-yanagicho,4,0
+0xF3,0x17,Oedo,Wakamatsu-kawada,3,0
+0xF3,0x19,Oedo,Higashi-shinjuku,2,0
+0xF3,0x1B,Oedo,Shinjuku-nishiguchi,1,0
+0xF3,0x1D,Oedo,Tochomae,28,0
+,,,,,
+0x00,0x00,UnknownLine,Unknown,0,0

BIN
images/.DS_Store


BIN
images/suica/.DS_Store


BIN
images/suica/Suica_AsakusaA.png


BIN
images/suica/Suica_BdayCakeIcon.png


BIN
images/suica/Suica_BigStar.png


BIN
images/suica/Suica_CardIcon.png


BIN
images/suica/Suica_ChiyodaC.png


BIN
images/suica/Suica_CrackingEgg.png


BIN
images/suica/Suica_DashLine.png


BIN
images/suica/Suica_EmptyArrowDown.png


BIN
images/suica/Suica_EmptyArrowRight.png


BIN
images/suica/Suica_EntrySlider1.png


BIN
images/suica/Suica_EntrySlider2.png


BIN
images/suica/Suica_EntrySlider3.png


BIN
images/suica/Suica_EntryStopL1.png


BIN
images/suica/Suica_EntryStopL2.png


BIN
images/suica/Suica_EntryStopL3.png


BIN
images/suica/Suica_EntryStopR1.png


BIN
images/suica/Suica_EntryStopR2.png


BIN
images/suica/Suica_EntryStopR3.png


BIN
images/suica/Suica_FilledArrowDown.png


BIN
images/suica/Suica_FilledArrowRight.png


BIN
images/suica/Suica_GinzaG.png


BIN
images/suica/Suica_HanzomonZ.png


BIN
images/suica/Suica_HibiyaH.png


BIN
images/suica/Suica_JRLogo.png


BIN
images/suica/Suica_KeikyuKK.png


BIN
images/suica/Suica_KeikyuLogo.png


BIN
images/suica/Suica_MarunouchiHonanchoMb.png


BIN
images/suica/Suica_MarunouchiM.png


BIN
images/suica/Suica_MinusSign0.png


BIN
images/suica/Suica_MinusSign1.png


BIN
images/suica/Suica_MinusSign2.png


BIN
images/suica/Suica_MinusSign3.png


BIN
images/suica/Suica_MinusSign4.png


BIN
images/suica/Suica_MinusSign5.png


BIN
images/suica/Suica_MinusSign6.png


BIN
images/suica/Suica_MinusSign7.png


BIN
images/suica/Suica_MinusSign8.png


BIN
images/suica/Suica_MinusSign9.png


BIN
images/suica/Suica_MitaI.png


BIN
images/suica/Suica_MobileLogo.png


BIN
images/suica/Suica_NambokuN.png


BIN
images/suica/Suica_Nothing.png


BIN
images/suica/Suica_OedoE.png


BIN
images/suica/Suica_PenguinHappyBirthday.png


BIN
images/suica/Suica_PenguinTodaysVIP.png


BIN
images/suica/Suica_PlusSign1.png


BIN
images/suica/Suica_PlusSign2.png


BIN
images/suica/Suica_PlusSign3.png


BIN
images/suica/Suica_PlusStar.png


BIN
images/suica/Suica_QuestionMarkBig.png


BIN
images/suica/Suica_QuestionMarkSmall.png


BIN
images/suica/Suica_RinkaiR.png


BIN
images/suica/Suica_ShinjukuS.png


BIN
images/suica/Suica_ShopIcon.png


BIN
images/suica/Suica_ShopPin.png


BIN
images/suica/Suica_SmallStar.png


BIN
images/suica/Suica_StoreFan1.png


BIN
images/suica/Suica_StoreFan2.png


BIN
images/suica/Suica_StoreFrame.png


BIN
images/suica/Suica_StoreLightningHorizontal.png


BIN
images/suica/Suica_StoreLightningVertical.png


BIN
images/suica/Suica_StoreP1Counter.png


BIN
images/suica/Suica_StoreReceiptDashLine.png


BIN
images/suica/Suica_StoreReceiptFrame1.png


BIN
images/suica/Suica_StoreReceiptFrame2.png


BIN
images/suica/Suica_StoreSlidingDoor.png


BIN
images/suica/Suica_TWRLogo.png


BIN
images/suica/Suica_ToeiLogo.png


BIN
images/suica/Suica_TokyoMetroLogo.png


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است