From c94e76d8cb65d285766169c079aeb1158da78f54 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Fri, 5 May 2023 12:51:56 +0200 Subject: [PATCH] 3.28 --- CHANGES.md | 13 +- FlashGBX/FlashGBX_CLI.py | 28 ++- FlashGBX/FlashGBX_GUI.py | 119 +++++++++++-- FlashGBX/GBMemory.py | 99 ++++++++--- FlashGBX/Mapper.py | 6 +- FlashGBX/RomFileAGB.py | 11 +- FlashGBX/RomFileDMG.py | 2 +- FlashGBX/Util.py | 131 ++++++++++---- FlashGBX/__main__.py | 4 + FlashGBX/config/db_AGB.json | 11 ++ FlashGBX/config/db_DMG.json | 2 +- FlashGBX/hw_GBxCartRW.py | 265 +++++++++++++++++++--------- FlashGBX/res/config.zip | Bin 366128 -> 366217 bytes FlashGBX/res/fw_GBxCart_RW_v1_3.zip | Bin 15729 -> 15732 bytes MANIFEST.in | 1 + README.md | 4 +- run.py | 4 + setup.py | 6 +- 18 files changed, 545 insertions(+), 161 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7fe0f92..73fe6ea 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,13 @@ # Release notes +### v3.28 (released 2023-05-05) +- Improved support for the BennVenn MBC3000 RTC cart; can now write to Real Time Clock registers +- Updated the Game Boy Advance lookup database for save types, ROM sizes and checksums +- Improved support for 8M FLASH DACS cartridges; can now backup and restore the boot sector +- Nintendo Power GB-Memory Cartridge (DMG-MMSA-JPN): Added more information to the dump reports +- Nintendo Power GB-Memory Cartridge (DMG-MMSA-JPN): When making a ROM backup, individual games will now also be extracted +- Improved support for e-Reader, Card e-Reader and Card e-Reader+ cartridges; will now prevent overwriting calibration data accidentally +- Minor bug fixes and improvements + ### v3.27 (released 2023-04-26) - Bundles GBxCart RW v1.4/v1.4a firmware version R42+L10 (improves flash cart compatibility) *(thanks wickawack)* - Added support for cartridges with MX29GL128EHT2I and ALTERA CPLD *(thanks Merkin)* @@ -45,7 +54,7 @@ ### v3.22 (released 2023-02-09) - Added support for DRV with AM29LV160DB and ALTERA CPLD *(thanks ccs21)* - Added support for DIY cart with HY29F800 *(thanks Kaede)* -- Added more information to the dump report with Nintendo Power GB-Memory Cartridges (DMG-MMSA-JPN) +- Added more information to the dump report of Nintendo Power GB-Memory Cartridges (DMG-MMSA-JPN) - Updated the Game Boy Advance lookup database for save types, ROM sizes and checksums - Minor bug fixes and improvements @@ -331,7 +340,7 @@ - Previously preliminarily added mapper support including for MBC7 and GBA Video cartridges is now working (requires GBxCart RW firmware version L1+) - Added support for writing compilation ROMs to Nintendo Power GB-Memory Cartridges (DMG-MMSA-JPN); requires a .map file in the same directory as the ROM file; all this can be generated using orangeglo’s [GBNP ROM builder website](https://orangeglo.github.io/gbnp/index.html) - Confirmed support for GB-M968 with 29LV160DB *(thanks bbsan)* -- Added support for ROM backup as well as save data backup and restore for 8M FLASH DACS cartridges; tested with “Hikaru no Go 3 – Joy Carry Cartridge” (AGB-GHTJ-JPN) +- Added support for ROM backup as well as save data backup and restore for 8M FLASH DACS cartridges - Confirmed support for SD007_TSOP_29LV017D with L017D70VC *(thanks marv17)* - Added support for 100BS6600_48BALL_V4 with 6600M0U0BE (the “369IN1” cartridge) *(thanks to BennVenn’s research on Discord)* - Removed broken support for saving and restoring RTC registers of official TAMA5 cartridges inside the save file as it became clear that the year value was not correctly written; more research needed diff --git a/FlashGBX/FlashGBX_CLI.py b/FlashGBX/FlashGBX_CLI.py index 6aed23a..9305481 100644 --- a/FlashGBX/FlashGBX_CLI.py +++ b/FlashGBX/FlashGBX_CLI.py @@ -1057,7 +1057,7 @@ class FlashGBX_CLI(): print("The cartridge save data will now be read{:s} and saved to the following file:\n{:s}".format(s_mbc, os.path.abspath(path))) elif args.action == "restore-save": if not args.overwrite: - answer = input("Restoring save data to the cartridge will erase the previous save.\nDo you want to overwrite it? [y/N]: ").strip().lower() + answer = input("Restoring save data to the cartridge will erase the existing save.\nDo you want to overwrite it? [y/N]: ").strip().lower() if answer != "y": print("Canceled.") return @@ -1073,9 +1073,27 @@ class FlashGBX_CLI(): print("The cartridge save data size will now be examined{:s}.\nNote: This is for debug use only.\n".format(s_mbc)) if self.CONN.GetMode() == "AGB": + if args.action == "restore-save" or args.action == "erase-save": + buffer = None + if self.CONN.GetMode() == "AGB" and "ereader" in self.CONN.INFO and self.CONN.INFO["ereader"] is True: + if self.CONN.GetFWBuildDate() == "": # Legacy Mode + print("This cartridge is not supported in Legacy Mode.") + return + self.CONN.ReadInfo() + if "ereader_calibration" in self.CONN.INFO: + with open(path, "rb") as f: buffer = bytearray(f.read()) + if buffer[0xD000:0xF000] != self.CONN.INFO["ereader_calibration"]: + if not args.overwrite: + if args.action == "erase-save": args.action = "restore-save" + print("Note: Keeping existing e-Reader calibration data.") + buffer[0xD000:0xF000] = self.CONN.INFO["ereader_calibration"] + else: + print("Note: Overwriting existing e-Reader calibration data.") + else: + print("Note: No existing e-Reader calibration data found.") print("Using Save Type “{:s}”.".format(Util.AGB_Header_Save_Types[save_type])) elif self.CONN.GetMode() == "DMG": - if rtc and header["mapper_raw"] in (0x10, 0x110, 0xFE): # RTC of MBC3, HuC-3 + if rtc and header["mapper_raw"] in (0x10, 0x110, 0xFE): # RTC of MBC3, MBC30, HuC-3 print("Real Time Clock register values will also be written if applicable/possible.") try: @@ -1097,7 +1115,11 @@ class FlashGBX_CLI(): self.CONN.TransferData(args={ 'mode':2, 'path':path, 'mbc':mbc, 'save_type':save_type, 'rtc':rtc }, signal=self.PROGRESS.SetProgress) elif args.action == "restore-save": verify_write = args.no_verify_write is False - self.CONN.TransferData(args={ 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':False, 'rtc':rtc, 'verify_write':verify_write }, signal=self.PROGRESS.SetProgress) + targs = { 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':False, 'rtc':rtc, 'verify_write':verify_write } + if buffer is not None: + targs["buffer"] = buffer + targs["path"] = None + self.CONN.TransferData(args=targs, signal=self.PROGRESS.SetProgress) elif args.action == "erase-save": self.CONN.TransferData(args={ 'mode':3, 'path':path, 'mbc':mbc, 'save_type':save_type, 'erase':True, 'rtc':rtc }, signal=self.PROGRESS.SetProgress) elif args.action == "debug-test-save": # debug diff --git a/FlashGBX/FlashGBX_GUI.py b/FlashGBX/FlashGBX_GUI.py index 2dd44b1..bb7a28f 100644 --- a/FlashGBX/FlashGBX_GUI.py +++ b/FlashGBX/FlashGBX_GUI.py @@ -536,8 +536,8 @@ class FlashGBX_GUI(QtWidgets.QWidget): msg_text = "A new version of {:s} has been released!\nVersion {:s} is now available.".format(APPNAME, latest_version) print(msg_text) msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle="{:s} Update Check".format(APPNAME), text=msg_text) - button_open = msgbox.addButton(" Open &release notes ", QtWidgets.QMessageBox.ActionRole) - button_cancel = msgbox.addButton("&OK", QtWidgets.QMessageBox.RejectRole) + button_open = msgbox.addButton(" &Open release notes ", QtWidgets.QMessageBox.ActionRole) + button_cancel = msgbox.addButton("&Close", QtWidgets.QMessageBox.RejectRole) msgbox.setDefaultButton(button_open) msgbox.setEscapeButton(button_cancel) answer = msgbox.exec() @@ -922,7 +922,8 @@ class FlashGBX_GUI(QtWidgets.QWidget): msgbox.exec() else: self.lblStatus4a.setText("Done.") - if ("cart_type" in self.STATUS and "dmg-mmsa-jpn" in self.STATUS["cart_type"]) or ("mapper_raw" in self.CONN.INFO and self.CONN.INFO["mapper_raw"] in (0x105, 0x202, 0x203, 0x205)): + #if ("cart_type" in self.STATUS and "dmg-mmsa-jpn" in self.STATUS["cart_type"]) or ("mapper_raw" in self.CONN.INFO and self.CONN.INFO["mapper_raw"] in (0x105, 0x202, 0x203, 0x205)): + if "mapper_raw" in self.CONN.INFO and self.CONN.INFO["mapper_raw"] in (0x202, 0x203, 0x205): msg = "The ROM backup is complete." msgbox.setText(msg + msg_te) msgbox.exec() @@ -1183,7 +1184,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): self.btnConfig.setEnabled(False) self.lblStatus4a.setText("Preparing...") qt_app.processEvents() - args = { "path":path, "mbc":mbc, "rom_size":rom_size, "agb_rom_size":rom_size, "fast_read_mode":True, "cart_type":cart_type } + args = { "path":path, "mbc":mbc, "rom_size":rom_size, "agb_rom_size":rom_size, "fast_read_mode":True, "cart_type":cart_type, "settings":self.SETTINGS } self.CONN.BackupROM(fncSetProgress=self.PROGRESS.SetProgress, args=args) self.grpStatus.setTitle("Transfer Status") self.STATUS["time_start"] = time.time() @@ -1339,7 +1340,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): hdr = RomFileAGB(buffer).GetHeader() if not hdr["logo_correct"] and (self.CONN.GetMode() == "AGB" or (self.CONN.GetMode() == "DMG" and mbc not in (0x203, 0x205))): - answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "Warning: The ROM file you selected will not boot on actual hardware due to invalid logo data.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) + answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), "Warning: The ROM file you selected will not boot on actual hardware due to invalid boot logo data.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) if answer == QtWidgets.QMessageBox.Cancel: return if not hdr["header_checksum_correct"] and (self.CONN.GetMode() == "AGB" or (self.CONN.GetMode() == "DMG" and mbc not in (0x203, 0x205))): msg_text = "Warning: The ROM file you selected will not boot on actual hardware due to an invalid header checksum (expected 0x{:02X} instead of 0x{:02X}).".format(hdr["header_checksum_calc"], hdr["header_checksum"]) @@ -1374,6 +1375,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): else: args = { "path":path, "cart_type":cart_type, "override_voltage":override_voltage, "prefer_chip_erase":prefer_chip_erase, "fast_read_mode":True, "verify_write":verify_write, "fix_header":fix_header, "mbc":mbc, "flash_offset":flash_offset } self.CONN.FlashROM(fncSetProgress=self.PROGRESS.SetProgress, args=args) + #self.CONN._FlashROM(args=args) self.grpStatus.setTitle("Transfer Status") buffer = None self.STATUS["time_start"] = time.time() @@ -1501,7 +1503,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): if save_type == 0: QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "No save type was selected.", QtWidgets.QMessageBox.Ok) return - save_size = Util.DMG_Header_RAM_Sizes_Flasher_Map[Util.DMG_Header_RAM_Sizes_Map.index(save_type)] + #save_size = Util.DMG_Header_RAM_Sizes_Flasher_Map[Util.DMG_Header_RAM_Sizes_Map.index(save_type)] elif self.CONN.GetMode() == "AGB": setting_name = "LastDirSaveDataAGB" @@ -1537,10 +1539,15 @@ class FlashGBX_GUI(QtWidgets.QWidget): msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="This feature only works with newer GBxCart RW hardware revisions.", standardButtons=QtWidgets.QMessageBox.Ok) msgbox.exec() return - - if self.CONN.GetMode() == "AGB" and self.cmbAGBSaveTypeResult.currentIndex() < len(Util.AGB_Header_Save_Types) and "Batteryless SRAM" in Util.AGB_Header_Save_Types[self.cmbAGBSaveTypeResult.currentIndex()]: + + if self.CONN.GetMode() == "AGB" and self.cmbAGBSaveTypeResult.currentIndex() < len(Util.AGB_Header_Save_Types) and \ + ("Batteryless SRAM" in Util.AGB_Header_Save_Types[self.cmbAGBSaveTypeResult.currentIndex()]) or \ + ("8M DACS" in Util.AGB_Header_Save_Types[self.cmbAGBSaveTypeResult.currentIndex()]): QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), "Stress test is not supported for this save type.", QtWidgets.QMessageBox.Ok) return + if self.CONN.GetMode() == "AGB" and "ereader" in self.CONN.INFO and self.CONN.INFO["ereader"] is True: + QtWidgets.QMessageBox.information(self, "{:s} {:s}".format(APPNAME, VERSION), "Stress test is not supported for this cartridge.", QtWidgets.QMessageBox.Ok) + return answer = QtWidgets.QMessageBox.question(self, "{:s} {:s}".format(APPNAME, VERSION), "The cartridge’s save chip will be tested for potential problems as follows:\n- Read the same data multiple times\n- Writing and reading different test patterns\n\nPlease ensure the cartridge pins are freshly cleaned and the save data is backed up before proceeding.", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Ok) if answer == QtWidgets.QMessageBox.Cancel: return else: @@ -1554,6 +1561,46 @@ class FlashGBX_GUI(QtWidgets.QWidget): QtWidgets.QMessageBox.critical(self, "{:s} {:s}".format(APPNAME, VERSION), "The size of this file is not supported.", QtWidgets.QMessageBox.Ok) return + buffer = None + if self.CONN.GetMode() == "AGB" and "ereader" in self.CONN.INFO and self.CONN.INFO["ereader"] is True: + if self.CONN.GetFWBuildDate() == "": # Legacy Mode + msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="This cartridge is not supported in Legacy Mode.", standardButtons=QtWidgets.QMessageBox.Ok) + msgbox.exec() + return + msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text="") + button_keep = msgbox.addButton(" &Keep existing calibration data ", QtWidgets.QMessageBox.ActionRole) + self.CONN.ReadInfo() + cart_name = "e-Reader" + if self.CONN.INFO["db"] is not None: + cart_name = self.CONN.INFO["db"]["gn"] + if "ereader_calibration" in self.CONN.INFO: + if erase: + buffer = bytearray([0xFF] * 0x20000) + msg_text = "This {:s} cartridge currently has calibration data in place. It is strongly recommended to keep the existing calibration data.\n\nErase everything but the calibration data? Or erase everything?".format(cart_name) + button_overwrite = msgbox.addButton(" &Erase everything ", QtWidgets.QMessageBox.ActionRole) + erase = False # Don’t just erase everything + else: + with open(path, "rb") as f: buffer = bytearray(f.read()) + msg_text = "This {:s} cartridge currently has calibration data in place that is different from this save file’s data. It is strongly recommended to keep the existing calibration data unless you actually need to restore it from a previous backup.\n\nWould you like to keep the existing calibration data, or overwrite it with data from the file you selected?".format(cart_name) + button_overwrite = msgbox.addButton(" &Restore from save data ", QtWidgets.QMessageBox.ActionRole) + button_cancel = msgbox.addButton("&Cancel", QtWidgets.QMessageBox.RejectRole) + msgbox.setText(msg_text) + msgbox.setDefaultButton(button_keep) + msgbox.setEscapeButton(button_cancel) + + if buffer[0xD000:0xF000] != self.CONN.INFO["ereader_calibration"]: + answer = msgbox.exec() + if msgbox.clickedButton() == button_cancel: + return + elif msgbox.clickedButton() == button_keep: + buffer[0xD000:0xF000] = self.CONN.INFO["ereader_calibration"] + elif msgbox.clickedButton() == button_overwrite: + pass + else: + msg_text = "Warning: This {:s} cartridge may currently have calibration data in place. Erasing or overwriting this data may render the “Scan Card” feature unusable. It is strongly recommended to create a backup of the original save data first and store it in a safe place. That way the calibration data can be restored later.\n\nDo you still want to continue?".format(cart_name) + answer = QtWidgets.QMessageBox.warning(self, "{:s} {:s}".format(APPNAME, VERSION), msg_text, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) + if answer == QtWidgets.QMessageBox.No: return + verify_write = self.SETTINGS.value("VerifyData", default="enabled") if verify_write and verify_write.lower() == "enabled": verify_write = True @@ -1565,8 +1612,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): if not test and self.CONN.INFO["has_rtc"]: if self.CONN.GetMode() == "DMG" and mbc in (0x10, 0x110) and not self.CONN.IsClkConnected(): rtc = False - elif (self.CONN.GetMode() == "DMG" and ((mbc == 0xFD and (filesize == save_size + 0x28 or erase)) or (mbc == 0xFE and (filesize == save_size + 0xC or erase)) or (self.CONN.IsClkConnected() and mbc in (0x10, 0x110) and filesize == save_size + 0x30 or erase))) or \ - (self.CONN.GetMode() == "AGB" and (filesize == save_size + 0x10 or erase)): + elif erase or Util.save_size_includes_rtc(mode=self.CONN.GetMode(), mbc=mbc, save_size=filesize, save_type=save_type): msg = "A Real Time Clock cartridge was detected. Do you want the Real Time Clock register values to be also written?" cb = QtWidgets.QCheckBox("&Adjust RTC", checked=True) msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Question, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=msg, standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel) @@ -1791,8 +1837,13 @@ class FlashGBX_GUI(QtWidgets.QWidget): #self.CONN._FlashROM(args=args) else: args = { "path":path, "mbc":mbc, "save_type":save_type, "rtc":rtc, "rtc_advance":rtc_advance, "erase":erase, "verify_write":verify_write } + if buffer is not None: + args["buffer"] = buffer + args["path"] = None self.STATUS["args"] = args self.CONN.RestoreRAM(fncSetProgress=self.PROGRESS.SetProgress, args=args) + #args = { "mode":3, "path":path, "mbc":mbc, "save_type":save_type, "rtc":rtc, "rtc_advance":rtc_advance, "erase":erase, "verify_write":verify_write } + #self.CONN._BackupRestoreRAM(args=args) self.STATUS["time_start"] = time.time() self.STATUS["last_path"] = path self.STATUS["args"] = args @@ -2183,8 +2234,6 @@ class FlashGBX_GUI(QtWidgets.QWidget): if data["db"] != None: if data["db"]['st'] < len(Util.AGB_Header_Save_Types): self.cmbAGBSaveTypeResult.setCurrentIndex(data["db"]['st']) - if data["dacs_8m"] is True: - self.cmbAGBSaveTypeResult.setCurrentIndex(6) if data['empty'] == True: # defaults if data['empty_nocart'] == True: @@ -2201,6 +2250,9 @@ class FlashGBX_GUI(QtWidgets.QWidget): if "3d_memory" in cart_types[1][i]: self.cmbAGBCartridgeTypeResult.setCurrentIndex(i) + if data["dacs_8m"] is True: + self.cmbAGBSaveTypeResult.setCurrentIndex(6) + self.grpDMGCartridgeInfo.setVisible(False) self.grpAGBCartridgeInfo.setVisible(True) @@ -2397,11 +2449,50 @@ class FlashGBX_GUI(QtWidgets.QWidget): if msg_cart_type_s_detail == "": msg_cart_type_s_detail = msg_cart_type_s self.SetProgressBars(min=0, max=100, value=100) show_details = False + + msg_gbmem = "" + if "gbmem_parsed" in header: + msg_gbmem = "
NP GB-Memory Cartridge Data:
" + if isinstance(header["gbmem_parsed"], list): + msg_gbmem += "" \ + "- Write Timestamp: {timestamp:s}
" \ + "- Write Kiosk ID: {kiosk_id:s}
" \ + "- Number of Games: {num_games:d}
" \ + "- Write Counter: {write_count:d}
" \ + "- Cartridge ID: {cart_id:s}
" \ + .format( + timestamp=header["gbmem_parsed"][0]["timestamp"].replace("\0", ""), + kiosk_id=header["gbmem_parsed"][0]["kiosk_id"].replace("\0", ""), + cart_id=header["gbmem_parsed"][0]["cart_id"].replace("\0", ""), + write_count=header["gbmem_parsed"][0]["write_count"], + num_games=header["gbmem_parsed"][0]["num_games"], + ) + for i in range(1, len(header["gbmem_parsed"])): + if header["gbmem_parsed"][i]["menu_index"] == 0xFF: continue + if i == 1: + msg_gbmem += "- Menu ROM: {:s}
".format(header["gbmem_parsed"][i]["title"].replace("\0", "")) + else: + msg_gbmem += "- Game {:d}: {:s}
".format(i - 1, header["gbmem_parsed"][i]["title"].replace("\0", "")) + else: + msg_gbmem += "" \ + "- Write Timestamp: {timestamp:s}
" \ + "- Write Kiosk ID: {kiosk_id:s}
" \ + "- Write Counter: {write_count:d}
" \ + "- Cartridge ID: {cart_id:s}
" \ + "- Game Title: {game_title:s}
" \ + .format( + timestamp=header["gbmem_parsed"]["timestamp"].replace("\0", ""), + kiosk_id=header["gbmem_parsed"]["kiosk_id"].replace("\0", ""), + cart_id=header["gbmem_parsed"]["cart_id"].replace("\0", ""), + write_count=header["gbmem_parsed"]["write_count"], + game_title=header["gbmem_parsed"]["title"], + ) + msg = "The following cartridge configuration was detected:

" if found_supported: dontShowAgain = str(self.SETTINGS.value("SkipAutodetectMessage", default="disabled")).lower() == "enabled" if not dontShowAgain or not canSkipMessage: - temp = "{:s}{:s}{:s}{:s}{:s}".format(msg, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_cart_type_s) + temp = "{:s}{:s}{:s}{:s}{:s}{:s}".format(msg, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_cart_type_s, msg_gbmem) temp = temp[:-4] msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="{:s} {:s}".format(APPNAME, VERSION), text=temp) msgbox.setTextFormat(QtCore.Qt.RichText) @@ -2462,7 +2553,7 @@ class FlashGBX_GUI(QtWidgets.QWidget): self.mnuConfig.actions()[4].setChecked(False) return self.DetectCartridge() - temp = "{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}".format(msg, msg_header_s, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_flash_id_s, msg_cfi_s, msg_cart_type_s_detail, msg_fw) + temp = "{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}{:s}".format(msg, msg_header_s, msg_flash_size_s, msg_save_type_s, msg_flash_mapper_s, msg_flash_id_s, msg_cfi_s, msg_cart_type_s_detail, msg_gbmem, msg_fw) temp = temp[:-4] msgbox.setText(temp) msgbox.setTextFormat(QtCore.Qt.RichText) diff --git a/FlashGBX/GBMemory.py b/FlashGBX/GBMemory.py index 31ed27e..5cf5b11 100644 --- a/FlashGBX/GBMemory.py +++ b/FlashGBX/GBMemory.py @@ -2,7 +2,7 @@ # FlashGBX # Author: Lesserkuma (github.com/lesserkuma) -import datetime, struct, copy +import datetime, struct, copy, zlib, hashlib from . import Util from .RomFileDMG import RomFileDMG @@ -25,30 +25,76 @@ class GBMemoryMap: def ParseMapData(self, buffer_map, buffer_rom=None): data = {} + num_games = 0 try: keys = ["mapper_params", "f_size", "b_size", "game_code", "title", "timestamp", "kiosk_id", "write_count", "cart_id", "padding", "unknown"] values = struct.unpack("=24sHH12s44s18s8sH8s6sH", buffer_map) data = dict(zip(keys, values)) + for i in range(1, 8): + if data["mapper_params"][i*3:i*3+3].hex() != "ffffff": + num_games += 1 + data["mapper_params"] = data["mapper_params"].hex().upper() data["cart_id"] = data["cart_id"].hex().upper() + if buffer_rom is None: return data rom_header = RomFileDMG(buffer_rom[:0x180]).GetHeader() if (rom_header["game_title"] in ("NP M-MENU MENU", "DMG MULTI MENU ")): - keys = ["menu_index", "f_offset", "b_offset", "f_size", "b_size", "game_code", "title", "title_gfx", "timestamp", "kiosk_id", "padding", "comment"] - values = struct.unpack("=BBBHH12s44s384s18s8s23s16s", buffer_rom[0x1C000:0x1C200]) - data_menu = dict(zip(keys, values)) - data["game_code"] = data_menu["game_code"].decode("ASCII", "ignore") - data["title"] = data_menu["title"].decode("SHIFT-JIS", "ignore") - data["timestamp"] = data_menu["timestamp"].decode("ASCII", "ignore") - data["kiosk_id"] = data_menu["kiosk_id"].decode("ASCII", "ignore") + data_list = [] + data["game_code"] = data["game_code"].decode("ASCII", "ignore") + data["title"] = data["title"].decode("SHIFT-JIS", "ignore") + data["timestamp"] = data["timestamp"].decode("ASCII", "ignore") + data["kiosk_id"] = data["kiosk_id"].decode("ASCII", "ignore") + data_list.append(data) + data_list[0]["num_games"] = 0 + + if len(buffer_rom) < 0x100000: return data_list + for i in range(0, 8): + keys = ["menu_index", "f_offset", "b_offset", "f_size", "b_size", "game_code", "title", "title_gfx", "timestamp", "kiosk_id", "padding", "comment"] + if rom_header["game_title"] == "NP M-MENU MENU": + values = struct.unpack("=BBBHH12s44s384s18s8s23s16s", buffer_rom[0x1C000+(i*0x200):0x1C200+(i*0x200)]) + elif rom_header["game_title"] == "DMG MULTI MENU ": + values = struct.unpack("=BBBHH12s44s384s18s8s1559s16s", buffer_rom[0x1C000+(i*0x800):0x1C800+(i*0x800)]) + data_menu = dict(zip(keys, values)) + temp = data_menu + del(temp["title_gfx"]) + del(temp["padding"]) + temp["game_code"] = data_menu["game_code"].decode("ASCII", "ignore") + temp["title"] = data_menu["title"].decode("SHIFT-JIS", "ignore") + temp["timestamp"] = data_menu["timestamp"].decode("ASCII", "ignore") + temp["kiosk_id"] = data_menu["kiosk_id"].decode("ASCII", "ignore") + temp["rom_offset"] = data_menu["f_offset"] * (128 * 1024) + temp["rom_size"] = data_menu["f_size"] * (128 * 1024) + rom_header_game = RomFileDMG(buffer_rom[temp["rom_offset"]:temp["rom_offset"]+temp["rom_size"]]).GetHeader() + temp["header"] = rom_header_game + #if not ("logo_correct" in rom_header_game and rom_header_game["logo_correct"] is True): + # continue + if rom_header_game != {} and len(buffer_rom) >= (temp["rom_offset"] + temp["rom_size"]): + temp["rom_size"] = min(temp["rom_size"], Util.DMG_Header_ROM_Sizes_Flasher_Map[rom_header_game["rom_size_raw"]]) + temp["crc32"] = zlib.crc32(buffer_rom[temp["rom_offset"]:temp["rom_offset"]+temp["rom_size"]]) & 0xFFFFFFFF + temp["sha1"] = hashlib.sha1(buffer_rom[temp["rom_offset"]:temp["rom_offset"]+temp["rom_size"]]).hexdigest() + temp["sha256"] = hashlib.sha256(buffer_rom[temp["rom_offset"]:temp["rom_offset"]+temp["rom_size"]]).hexdigest() + temp["md5"] = hashlib.md5(buffer_rom[temp["rom_offset"]:temp["rom_offset"]+temp["rom_size"]]).hexdigest() + if "db" in rom_header_game and rom_header_game["db"] is not None and rom_header_game["db"]["rc"] == temp["crc32"]: + temp["db_entry"] = rom_header_game["db"] + else: + temp["header"]["db"] = None + Util.dprint("GB-Memory Game {:d}: {:s}".format(i, str(temp))) + data_list.append(temp) + data_list[0]["num_games"] = num_games + if len(data_list[0]["timestamp"]) == 0: + data_list[0]["timestamp"] = data_list[1]["timestamp"] + data_list[0]["kiosk_id"] = data_list[1]["kiosk_id"] + return data_list else: data["game_code"] = data["game_code"].decode("ASCII", "ignore") data["title"] = data["title"].decode("SHIFT-JIS", "ignore") data["timestamp"] = data["timestamp"].decode("ASCII", "ignore") data["kiosk_id"] = data["kiosk_id"].decode("ASCII", "ignore") + return data except: - pass - return data + print("ERROR: Couldn’t parse the GB-Memory Cartridge data.") + return None def ImportROM(self, data): info = {"map":{}, "menu":{}} @@ -116,10 +162,13 @@ class GBMemoryMap: info["menu"]["metadata"]["b_size"] = 1024 game_code = info["rom_header"]["game_code"] - info["menu"]["metadata"]["game_code"] = "{:s} -{:4s}- ".format("CGB" if info["rom_header"]["cgb"] == 0xC0 else "DMG", game_code).encode("ascii") - info["menu"]["metadata"]["title"] = info["rom_header"]["game_title"].encode("ascii").ljust(0x2C) - info["menu"]["metadata"]["timestamp"] = datetime.datetime.now().strftime('%d/%m/%Y%H:%M:%S').encode("ascii") - info["menu"]["metadata"]["kiosk_id"] = "{:s}".format(Util.APPNAME).encode("ascii").ljust(8, b'\xFF') + info["menu"]["metadata"]["game_code"] = "{:s} -{:4s}- ".format("CGB" if info["rom_header"]["cgb"] == 0xC0 else "DMG", game_code).encode("ASCII") + info["menu"]["metadata"]["title"] = info["rom_header"]["game_title"].encode("SHIFT-JIS", "ignore").ljust(0x2C) + if "db" in info["rom_header"] and info["rom_header"]["db"] is not None: + info["menu"]["metadata"]["title"] = info["rom_header"]["db"]["gn"].encode("SHIFT-JIS", "ignore").ljust(0x2C)[:0x2C] + + info["menu"]["metadata"]["timestamp"] = datetime.datetime.now().strftime('%d/%m/%Y%H:%M:%S').encode("ASCII") + info["menu"]["metadata"]["kiosk_id"] = "{:s}".format(Util.APPNAME).encode("ASCII").ljust(8, b'\xFF') info["menu"]["raw"] = bytearray(0x56) data = info @@ -144,15 +193,25 @@ class GBMemoryMap: self.MAP_DATA[0:3] = struct.pack(">I", data["map"]["raw"])[:3] self.MAP_DATA[0x18:0x18+len(data["menu"]["raw"])] = data["menu"]["raw"] - elif info["rom_header"]["game_title"] == "NP M-MENU MENU": + elif info["rom_header"]["game_title"] in ("NP M-MENU MENU", "DMG MULTI MENU "): + if info["rom_header"]["game_title"] == "NP M-MENU MENU": + menu_ver = 0 + elif info["rom_header"]["game_title"] == "DMG MULTI MENU ": + menu_ver = 1 + menu_items = [] rom_offset = 0 ram_offset = 0 for i in range(0, 8): - pos = 0x1C000 + (i * 0x200) - menu_item = data[pos:pos+0x200] keys = ["menu_index", "f_offset", "b_offset", "f_size", "b_size", "game_code", "title", "title_gfx", "timestamp", "kiosk_id", "padding", "comment"] - values = struct.unpack("=BBBHH12s44s384s18s8s23s16s", menu_item) + if menu_ver == 0: # final + pos = 0x1C000 + (i * 0x200) + menu_item = data[pos:pos+0x200] + values = struct.unpack("=BBBHH12s44s384s18s8s23s16s", menu_item) + elif menu_ver == 1: # prototype + pos = 0x1C000 + (i * 0x800) + menu_item = data[pos:pos+0x800] + values = struct.unpack("=BBBHH12s44s384s18s8s1559s16s", menu_item) info = dict(zip(keys, values)) if info["menu_index"] == 0xFF: continue info["rom_data_offset"] = info["f_offset"] * (128 * 1024) @@ -219,8 +278,8 @@ class GBMemoryMap: for i in range(0, len(menu_items)): pos = i * 3 self.MAP_DATA[pos:pos+3] = struct.pack(">I", menu_items[i]["map"]["raw"])[:3] - self.MAP_DATA[0x54:0x66] = struct.pack("=18s", datetime.datetime.now().strftime('%d/%m/%Y%H:%M:%S').encode("ascii")) - self.MAP_DATA[0x66:0x6E] = struct.pack("=8s", "{:s}".format(Util.APPNAME).encode("ascii").ljust(8, b'\xFF')) + self.MAP_DATA[0x54:0x66] = struct.pack("=18s", datetime.datetime.now().strftime('%d/%m/%Y%H:%M:%S').encode("ASCII")) + self.MAP_DATA[0x66:0x6E] = struct.pack("=8s", "{:s}".format(Util.APPNAME).encode("ASCII").ljust(8, b'\xFF')) def MapperToMBCType(self, mbc): if mbc == 0x00: # ROM only diff --git a/FlashGBX/Mapper.py b/FlashGBX/Mapper.py index d11b042..0a438f6 100644 --- a/FlashGBX/Mapper.py +++ b/FlashGBX/Mapper.py @@ -41,7 +41,7 @@ class DMG_MBC: return DMG_MBC1(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr) elif mbc_id in (0x05, 0x06): # 0x06:'MBC2+SRAM+BATTERY', return DMG_MBC2(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr) - elif mbc_id in (0x10, 0x11, 0x12, 0x13, 0x110): # 0x10:'MBC3+RTC+SRAM+BATTERY', 0x13:'MBC3+SRAM+BATTERY', + elif mbc_id in (0x0F, 0x10, 0x11, 0x12, 0x13, 0x110): # 0x10:'MBC3+RTC+SRAM+BATTERY', 0x13:'MBC3+SRAM+BATTERY', return DMG_MBC3(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr) elif mbc_id in (0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E): # 0x19:'MBC5', 0x1B:'MBC5+SRAM+BATTERY', 0x1C:'MBC5+RUMBLE', 0x1E:'MBC5+RUMBLE+SRAM+BATTERY', return DMG_MBC5(args=args, cart_write_fncptr=cart_write_fncptr, cart_read_fncptr=cart_read_fncptr, cart_powercycle_fncptr=cart_powercycle_fncptr, clk_toggle_fncptr=clk_toggle_fncptr) @@ -389,7 +389,7 @@ class DMG_MBC3(DMG_MBC): self.CLK_TOGGLE_FNCPTR(50) self.CartWrite([ [ 0x4000, 0x0C ] ]) self.CLK_TOGGLE_FNCPTR(50) - self.CartWrite([ [ 0xA000, 0x40 ] ]) + self.CartWrite([ [ 0xA000, 0x40 ] ], sram=True) time.sleep(0.1) # Write to registers @@ -398,7 +398,7 @@ class DMG_MBC3(DMG_MBC): self.CartWrite([ [ 0x4000, i ] ]) self.CLK_TOGGLE_FNCPTR(50) data = struct.unpack(" 0: - s += "" \ - "\n== GB-Memory Data ==\n" \ - "* Game Code: {game_code:s}\n" \ - "* Game Title: {title:s}\n" \ - "* Write Timestamp: {timestamp:s}\n" \ - "* Write Kiosk ID: {kiosk_id:s}\n" \ - "* Write Counter: {write_count:d}\n" \ - "* Cartridge Value: {cart_id:s}\n" \ - "* Raw Map Data: {raw_data:s}\n" \ - .format( - game_code=di["gbmem_parsed"]["game_code"], - title=di["gbmem_parsed"]["title"], - timestamp=di["gbmem_parsed"]["timestamp"], - kiosk_id=di["gbmem_parsed"]["kiosk_id"], - cart_id=di["gbmem_parsed"]["cart_id"], - write_count=di["gbmem_parsed"]["write_count"], - raw_data=raw_data - ) + if "gbmem_parsed" in di and di["gbmem_parsed"] is not None and len(di["gbmem_parsed"]) > 0: + if (isinstance(di["gbmem_parsed"], list)): + s += "" \ + "\n== GB-Memory Data (Multi Menu) ==\n" \ + "* Write Timestamp: {timestamp:s}\n" \ + "* Write Kiosk ID: {kiosk_id:s}\n" \ + "* Number of Games: {num_games:d}\n" \ + "* Write Counter: {write_count:d}\n" \ + "* Cartridge ID: {cart_id:s}\n" \ + "* Raw Map Data: {raw_data:s}\n" \ + .format( + timestamp=di["gbmem_parsed"][0]["timestamp"], + kiosk_id=di["gbmem_parsed"][0]["kiosk_id"], + cart_id=di["gbmem_parsed"][0]["cart_id"], + write_count=di["gbmem_parsed"][0]["write_count"], + num_games=di["gbmem_parsed"][0]["num_games"], + raw_data=raw_data + ) + for i in range(1, len(di["gbmem_parsed"])): + if di["gbmem_parsed"][i]["menu_index"] == 0xFF: continue + if di["gbmem_parsed"][i]["header"]["logo_correct"] is False: continue + if i == 1: + s += "\n=== Menu ROM ===\n" + else: + s += "\n=== Game {:d} ===\n".format(i-1) + s += "" \ + "* Game Code: {game_code:s}\n" \ + "* Game Title: {title:s}\n" \ + "* Write Timestamp: {timestamp:s}\n" \ + "* Write Kiosk ID: {kiosk_id:s}\n" \ + "* Location: {location:s}\n" \ + "* ROM Size: {size:s}\n" \ + .format( + game_code=di["gbmem_parsed"][i]["game_code"], + title=di["gbmem_parsed"][i]["title"], + timestamp=di["gbmem_parsed"][i]["timestamp"], + kiosk_id=di["gbmem_parsed"][i]["kiosk_id"], + location="0x{:06X}–0x{:06X}".format(di["gbmem_parsed"][i]["rom_offset"], di["gbmem_parsed"][i]["rom_offset"]+di["gbmem_parsed"][i]["rom_size"]-1), + size="{:s} ({:d} bytes)".format(formatFileSize(di["gbmem_parsed"][i]["rom_size"]), di["gbmem_parsed"][i]["rom_size"]), + ) + if "crc32" in di["gbmem_parsed"][i]: s += "* CRC32: {:08x}\n".format(di["gbmem_parsed"][i]["crc32"]) + if "md5" in di["gbmem_parsed"][i]: s += "* MD5: {:s}\n".format(di["gbmem_parsed"][i]["md5"]) + if "sha1" in di["gbmem_parsed"][i]: s += "* SHA-1: {:s}\n".format(di["gbmem_parsed"][i]["sha1"]) + if "sha256" in di["gbmem_parsed"][i]: s += "* SHA-256: {:s}\n".format(di["gbmem_parsed"][i]["sha256"]) + + if "db_entry" in di["gbmem_parsed"][i] and "crc32" in di["gbmem_parsed"][i] and di["gbmem_parsed"][i]["db_entry"]["rc"] == di["gbmem_parsed"][i]["crc32"]: + s += "* Database Match: {:s} {:s}\n".format(di["gbmem_parsed"][i]["db_entry"]["gn"], di["gbmem_parsed"][i]["db_entry"]["ne"]) + elif isinstance(di["gbmem_parsed"]["game_code"], str): + s += "" \ + "\n== GB-Memory Data (Single Game) ==\n" \ + "* Game Code: {game_code:s}\n" \ + "* Game Title: {title:s}\n" \ + "* Write Timestamp: {timestamp:s}\n" \ + "* Write Kiosk ID: {kiosk_id:s}\n" \ + "* Write Counter: {write_count:d}\n" \ + "* Cartridge ID: {cart_id:s}\n" \ + "* Raw Map Data: {raw_data:s}\n" \ + .format( + game_code=di["gbmem_parsed"]["game_code"], + title=di["gbmem_parsed"]["title"], + timestamp=di["gbmem_parsed"]["timestamp"], + kiosk_id=di["gbmem_parsed"]["kiosk_id"], + cart_id=di["gbmem_parsed"]["cart_id"], + write_count=di["gbmem_parsed"]["write_count"], + raw_data=raw_data + ) else: s += "" \ "* GB-Memory Data: {:s}\n" \ @@ -708,10 +755,10 @@ def GetDumpReport(di, device): return s -def GenerateFileName(mode, header, settings): - fe_ni = False +def GenerateFileName(mode, header, settings=None): + fe_ni = True if settings is not None: - fe_ni = settings.value(key="UseNoIntroFilenames", default="disabled").lower() == "enabled" + fe_ni = settings.value(key="UseNoIntroFilenames", default="enabled").lower() == "enabled" path = "ROM" if mode == "DMG": @@ -724,9 +771,8 @@ def GenerateFileName(mode, header, settings): if settings is not None: path = settings.value(key="FileNameFormatDMG", default=path) fe_sgb = settings.value(key="AutoFileExtensionSGB", default="enabled") - + if len(header["game_code"]) > 0: - path_title = header["game_title"] path_code = header["game_code"] path = "%TITLE%_%CODE%-%REVISION%" if settings is not None: @@ -747,6 +793,12 @@ def GenerateFileName(mode, header, settings): path = path.replace("%CODE%", path_code.strip()) path = path.replace("%REVISION%", path_revision) path = re.sub(r"[<>:\"/\\|\?\*]", "_", path) + if get_mbc_name(header["mapper_raw"]) == "G-MMC1": + if "gbmem_parsed" in header: + if (isinstance(header["gbmem_parsed"], list)): + path += "_{:s}".format(header["gbmem_parsed"][0]["cart_id"]) + else: + path += "_{:s}".format(header["gbmem_parsed"]["cart_id"]) path += ".{:s}".format(path_extension) elif mode == "AGB": path = "%TITLE%_%CODE%-%REVISION%" @@ -766,8 +818,11 @@ def GenerateFileName(mode, header, settings): path += "." + path_extension if fe_ni and header["db"] is not None: - if mode == "DMG" and get_mbc_name(header["mapper_raw"]) == "G-MMC1": - path = "{:s}.{:s}".format(header["db"]["gn"], path_extension) + if mode == "DMG" and get_mbc_name(header["mapper_raw"]) == "G-MMC1" and "gbmem_parsed" in header: + if (isinstance(header["gbmem_parsed"], list)): + path = "NP GB-Memory Cartridge ({:s}).{:s}".format(header["gbmem_parsed"][0]["cart_id"], path_extension) + else: + path = "NP GB-Memory Cartridge ({:s}).{:s}".format(header["gbmem_parsed"]["cart_id"], path_extension) else: path = "{:s} {:s}.{:s}".format(header["db"]["gn"], header["db"]["ne"], path_extension) @@ -783,6 +838,18 @@ def get_mbc_name(id): if id in v: return k return "Unknown mapper type 0x{:02X}".format(id) +def save_size_includes_rtc(mode, mbc, save_size, save_type): + rtc_size = 0x10 + if mode == "DMG": + if get_mbc_name(mbc) in ("MBC3", "MBC30"): rtc_size = 0x30 + elif get_mbc_name(mbc) == "HuC-3": rtc_size = 0x0C + elif get_mbc_name(mbc) == "TAMA5": rtc_size = 0x28 + return (((DMG_Header_RAM_Sizes_Flasher_Map[save_type] + rtc_size) % save_size) != rtc_size) + elif mode == "AGB": + rtc_size = 0x10 + return (((AGB_Header_Save_Sizes[save_type] + rtc_size) % save_size) != rtc_size) + return False + def validate_datetime_format(string, format): try: if string != datetime.datetime.strptime(string, format).strftime(format): diff --git a/FlashGBX/__main__.py b/FlashGBX/__main__.py index 2da855e..a5501f6 100644 --- a/FlashGBX/__main__.py +++ b/FlashGBX/__main__.py @@ -1,2 +1,6 @@ +# -*- coding: utf-8 -*- +# FlashGBX +# Author: Lesserkuma (github.com/lesserkuma) + from . import FlashGBX FlashGBX.main() diff --git a/FlashGBX/config/db_AGB.json b/FlashGBX/config/db_AGB.json index f95da7c..b7e4270 100644 --- a/FlashGBX/config/db_AGB.json +++ b/FlashGBX/config/db_AGB.json @@ -31365,6 +31365,17 @@ "lg": "Ja", "rg": "Japan" }, + "ddd5006e3ff17a60b9fd58e2a2d4fa13ba9f919d": { + "gn": "Hikaru no Go 3 - Senyou Joy Carry Cartridge", + "ne": "(Japan) (Rewritable Cartridge)", + "gc": "GHTJ", + "rc": 1543225974, + "rs": 33554432, + "st": 6, + "ss": 1048576, + "lg": "Ja", + "rg": "Japan" + }, "ba92dc252389b96900bf850593e6175965ce7b7c": { "gn": "Pokemon - Aurora Ticket Distribution", "ne": "(USA) (Kiosk)", diff --git a/FlashGBX/config/db_DMG.json b/FlashGBX/config/db_DMG.json index 20296d6..cf726b2 100644 --- a/FlashGBX/config/db_DMG.json +++ b/FlashGBX/config/db_DMG.json @@ -19082,7 +19082,7 @@ "c26c112cdaf53efb9064e6cee3c474f2cc934782": { "gn": "F-15 Strike Eagle", "ne": "(USA, Europe)", - "gc": "DMG-EGE", + "gc": "DMG-EGX", "rc": 73264780, "rs": 131072, "lg": "En", diff --git a/FlashGBX/hw_GBxCartRW.py b/FlashGBX/hw_GBxCartRW.py index 118ae04..bf1c034 100644 --- a/FlashGBX/hw_GBxCartRW.py +++ b/FlashGBX/hw_GBxCartRW.py @@ -17,7 +17,7 @@ class GbxDevice: DEVICE_NAME = "GBxCart RW" DEVICE_MIN_FW = 1 DEVICE_MAX_FW = 10 - DEVICE_LATEST_FW_TS = { 4:1682502626, 5:1681900614, 6:1681900614 } + DEVICE_LATEST_FW_TS = { 4:1683283512, 5:1681900614, 6:1681900614 } DEVICE_CMD = { "NULL":0x30, @@ -146,7 +146,7 @@ class GbxDevice: self.BAUDRATE = 1700000 dev = serial.Serial(ports[i], self.BAUDRATE, timeout=0.1) self.DEVICE = dev - if not self.LoadFirmwareVersion() or self.FW["pcb_ver"] not in (5, 6, 101): + if not self.LoadFirmwareVersion(): dev.close() self.DEVICE = None self.BAUDRATE = 1000000 @@ -179,7 +179,7 @@ class GbxDevice: elif self.FW["pcb_ver"] in (5, 6, 101) and self.BAUDRATE > 1000000: self.MAX_BUFFER_LEN = 0x2000 else: - self.MAX_BUFFER_LEN = 0x800 + self.MAX_BUFFER_LEN = 0x1000 conn_msg.append([0, "For help please visit the insideGadgets Discord: https://gbxcart.com/discord"]) @@ -273,9 +273,9 @@ class GbxDevice: def IsSupportedMbc(self, mbc): if self.CanPowerCycleCart(): - return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x201, 0x202, 0x203, 0x204, 0x205 ) + return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x201, 0x202, 0x203, 0x204, 0x205 ) else: - return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x202, 0x205 ) + return mbc in ( 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0xFC, 0xFD, 0xFE, 0xFF, 0x101, 0x103, 0x104, 0x105, 0x110, 0x202, 0x205 ) def IsSupported3dMemory(self): return True @@ -514,7 +514,7 @@ class GbxDevice: return self.ReadROM(address, length) def _cart_write(self, address, value, flashcart=False, sram=False): - dprint("Writing to cartridge: 0x{:X} = 0x{:X} (flashcart={:s}, sram={:s})".format(address, value & 0xFF, str(flashcart), str(sram))) + dprint("Writing to cartridge: 0x{:X} = 0x{:X} (args: {:s}, {:s})".format(address, value & 0xFF, str(flashcart), str(sram))) if self.MODE == "DMG": if flashcart: buffer = bytearray([self.DEVICE_CMD["DMG_FLASH_WRITE_BYTE"]]) @@ -714,10 +714,26 @@ class GbxDevice: _mbc.LatchRTC() data["rtc_buffer"] = _mbc.ReadRTC() if _mbc.GetName() == "TAMA5": self._set_fw_variable("DMG_READ_CS_PULSE", 0) - try: - data["rtc_string"] = _mbc.GetRTCString() - except: - data["rtc_string"] = "Invalid data" + try: + data["rtc_string"] = _mbc.GetRTCString() + except: + data["rtc_string"] = "Invalid data" + if _mbc.GetName() == "G-MMC1": + try: + temp = bytearray([0] * 0x100000) + temp[0:0x180] = header + _mbc.SelectBankROM(7) + if data["game_title"] == "NP M-MENU MENU": + gbmem_menudata = self.ReadROM(0x4000, 0x1000) + temp[0x1C000:0x1C000+0x1000] = gbmem_menudata + elif data["game_title"] == "DMG MULTI MENU ": + gbmem_menudata = self.ReadROM(0x4000, 0x4000) + temp[0x1C000:0x1C000+0x4000] = gbmem_menudata + _mbc.SelectBankROM(0) + data["gbmem_parsed"] = (GBMemoryMap()).ParseMapData(buffer_map=_mbc.ReadHiddenSector(), buffer_rom=temp) + except: + print(traceback.format_exc()) + print("{:s}An error occured while trying to read the hidden sector data of the NP GB-Memory cartridge.{:s}".format(ANSI.RED, ANSI.RESET)) elif self.MODE == "AGB": # Unlock DACS carts on older firmware @@ -747,8 +763,8 @@ class GbxDevice: currAddr *= 2 data["rom_size"] = currAddr - if (self.ReadROM(0x1FFE000, 0x0C) == b"AGBFLASHDACS"): - data["dacs_8m"] = True + if (self.ReadROM(0x1FFE000, 0x0C) == b"AGBFLASHDACS"): + data["dacs_8m"] = True if checkRtc and data["logo_correct"] is True and header[0xC5] == 0 and header[0xC7] == 0 and header[0xC9] == 0: _agb_gpio = AGB_GPIO(args={"rtc":True}, cart_write_fncptr=self._cart_write, cart_read_fncptr=self._cart_read, cart_powercycle_fncptr=self.CartPowerCycle, clk_toggle_fncptr=self._clk_toggle) @@ -767,6 +783,23 @@ class GbxDevice: data["has_rtc"] = False data["no_rtc_reason"] = None data["rtc_string"] = "Not available" + + if data["ereader"] is True: + bank = 0 + dprint("Switching to FLASH bank {:d}".format(bank)) + cmds = [ + [ 0x5555, 0xAA ], + [ 0x2AAA, 0x55 ], + [ 0x5555, 0xB0 ], + [ 0, bank ] + ] + self._cart_write_flash(cmds) + temp = self.ReadRAM(address=0xD000, length=0x2000, command=self.DEVICE_CMD["AGB_CART_READ_SRAM"]) + if temp[0:0x14] == b'Card-E Reader 2001\0\0': + data["ereader_calibration"] = temp + else: + data["ereader_calibration"] = None + del(data["ereader_calibration"]) dprint("Header data:", data) data["raw"] = header @@ -808,7 +841,23 @@ class GbxDevice: checkSaveType = False elif self.MODE == "AGB" and "flash_bank_select_type" in cart_type and cart_type["flash_bank_select_type"] > 0: checkSaveType = False - + elif self.MODE == "DMG" and "mbc" in cart_type and cart_type["mbc"] == 0x105: # G-MMC1 + header = self.ReadROM(0, 0x180) + data = RomFileDMG(header).GetHeader() + _mbc = DMG_MBC().GetInstance(args={"mbc":cart_type["mbc"]}, cart_write_fncptr=self._cart_write, cart_read_fncptr=self._cart_read, cart_powercycle_fncptr=self.CartPowerCycle, clk_toggle_fncptr=self._clk_toggle) + temp = bytearray([0] * 0x100000) + temp[0:0x180] = header + _mbc.SelectBankROM(7) + if data["game_title"] == "NP M-MENU MENU": + gbmem_menudata = self.ReadROM(0x4000, 0x1000) + temp[0x1C000:0x1C000+0x1000] = gbmem_menudata + elif data["game_title"] == "DMG MULTI MENU ": + gbmem_menudata = self.ReadROM(0x4000, 0x4000) + temp[0x1C000:0x1C000+0x4000] = gbmem_menudata + _mbc.SelectBankROM(0) + info["gbmem"] = _mbc.ReadHiddenSector() + info["gbmem_parsed"] = (GBMemoryMap()).ParseMapData(buffer_map=info["gbmem"], buffer_rom=temp) + # Save Type and Size if checkSaveType: if self.MODE == "DMG": @@ -871,7 +920,7 @@ class GbxDevice: if save_type is None: checkBatterylessSRAM = True if info["dacs_8m"] is True: - save_size = 1032192 + save_size = 1048576 save_type = 6 elif save_size > 256: # SRAM if save_size == 131072: @@ -1145,17 +1194,17 @@ class GbxDevice: # Read save state for i in range(0, 0x20): - self._cart_write(0xA001, 0x06) # register select and address (high) - self._cart_write(0xA000, i >> 4 | 0x01 << 1) # bit 0 = higher ram address, rest = command - self._cart_write(0xA001, 0x07) # address (low) - self._cart_write(0xA000, i & 0x0F) # bits 0-3 = lower ram address - self._cart_write(0xA001, 0x0D) # data out (high) + self._cart_write(0xA001, 0x06, sram=True) # register select and address (high) + self._cart_write(0xA000, i >> 4 | 0x01 << 1, sram=True) # bit 0 = higher ram address, rest = command + self._cart_write(0xA001, 0x07, sram=True) # address (low) + self._cart_write(0xA000, i & 0x0F, sram=True) # bits 0-3 = lower ram address + self._cart_write(0xA001, 0x0D, sram=True) # data out (high) value1, value2 = None, None while value1 is None or value1 != value2: value2 = value1 value1 = self._cart_read(0xA000) data_h = value1 - self._cart_write(0xA001, 0x0C) # data out (low) + self._cart_write(0xA001, 0x0C, sram=True) # data out (low) value1, value2 = None, None while value1 is None or value1 != value2: @@ -1172,11 +1221,10 @@ class GbxDevice: self.NO_PROG_UPDATE = npu return buffer - def WriteRAM(self, address, buffer, command=None): + def WriteRAM(self, address, buffer, command=None, max_length=256): length = len(buffer) - max_length = 256 num = math.ceil(length / max_length) - dprint("Write 0x{:X} bytes to cartridge RAM in {:d} iteration(s)".format(length, num)) + dprint("Writing 0x{:X} bytes to cartridge RAM in {:d} iteration(s)".format(length, num)) if length > max_length: length = max_length self._set_fw_variable("TRANSFER_SIZE", length) @@ -1272,14 +1320,14 @@ class GbxDevice: self.NO_PROG_UPDATE = True for i in range(0, 0x20): - self._cart_write(0xA001, 0x05) # data in (high) - self._cart_write(0xA000, buffer[i] >> 4) - self._cart_write(0xA001, 0x04) # data in (low) - self._cart_write(0xA000, buffer[i] & 0xF) - self._cart_write(0xA001, 0x06) # register select and address (high) - self._cart_write(0xA000, i >> 4 | 0x00 << 1) # bit 0 = higher ram address, rest = command - self._cart_write(0xA001, 0x07) # address (low) - self._cart_write(0xA000, i & 0x0F) # bits 0-3 = lower ram address + self._cart_write(0xA001, 0x05, sram=True) # data in (high) + self._cart_write(0xA000, buffer[i] >> 4, sram=True) + self._cart_write(0xA001, 0x04, sram=True) # data in (low) + self._cart_write(0xA000, buffer[i] & 0xF, sram=True) + self._cart_write(0xA001, 0x06, sram=True) # register select and address (high) + self._cart_write(0xA000, i >> 4 | 0x00 << 1, sram=True) # bit 0 = higher ram address, rest = command + self._cart_write(0xA001, 0x07, sram=True) # address (low) + self._cart_write(0xA000, i & 0x0F, sram=True) # bits 0-3 = lower ram address value1, value2 = None, None while value1 is None or value1 != value2: value2 = value1 @@ -1329,12 +1377,11 @@ class GbxDevice: self._set_fw_variable("ADDRESS", address >> 1) skip_init = True - if ret != 0x03: - if rumble_stop and i == 1: - dprint("Sending rumble stop command") - self._cart_write(address=0xC6, value=0x00, flashcart=True) - self._write(self.DEVICE_CMD["FLASH_PROGRAM"]) + if ret != 0x03: self._write(self.DEVICE_CMD["FLASH_PROGRAM"]) ret = self._write(data, wait=True) + if rumble_stop and i == 0: + dprint("Sending rumble stop command") + self._cart_write(address=0xC6, value=0x00, flashcart=True) if ret not in (0x01, 0x03): dprint("Flash error at 0x{:X} in iteration {:d} of {:d} while trying to write a total of 0x{:X} bytes (response = {:s})".format(address, i, num, len(buffer), str(ret))) @@ -1715,11 +1762,10 @@ class GbxDevice: { 'read_cfi':[[0x4AAA, 0x98]], 'read_identifier':[[ 0x4AAA, 0xAA ], [ 0x4555, 0x55 ], [ 0x4AAA, 0x90 ]], 'reset':[[ 0x4000, 0xF0 ]] }, { 'read_cfi':[[0x7AAA, 0x98]], 'read_identifier':[[ 0x7AAA, 0xAA ], [ 0x7555, 0x55 ], [ 0x7AAA, 0x90 ]], 'reset':[[ 0x7000, 0xF0 ]] }, { 'read_cfi':[[0, 0x98]], 'read_identifier':[[ 0, 0x90 ]], 'reset':[[ 0, 0xFF ]] }, - #{ 'read_cfi':[[0xAA, 0x9898]], 'read_identifier':[[ 0xAAA, 0xAAAA ], [ 0x555, 0x5555 ], [ 0xAAA, 0x9090 ]], 'reset':[[ 0x0, 0xF0F0 ]] }, - #{ 'read_cfi':[[0x4000, 0x98]], 'read_identifier':[[ 0x4000, 0x90 ]], 'reset':[[ 0x4000, 0xFF ]] }, ] if self.MODE == "DMG": + del(flash_commands[4]) # 0xAAAA is in SRAM space on DMG if limitVoltage: self._write(self.DEVICE_CMD["SET_VOLTAGE_3_3V"]) else: @@ -1768,7 +1814,7 @@ class GbxDevice: d_swap = ( 0, 0 ) elif magic == "RQZ": # D0D1 swapped d_swap = ( 0, 1 ) - if d_swap is not None: + if d_swap is not None and d_swap != ( 0, 0 ): for i in range(0, len(buffer)): buffer[i] = bitswap(buffer[i], d_swap) @@ -1794,7 +1840,7 @@ class GbxDevice: if self.MODE == "DMG": cfi["we"] = we cfi["method_id"] = flash_commands.index(method) - if d_swap is not None: + if d_swap is not None and d_swap != ( 0, 0 ): for k in method.keys(): for c in range(0, len(method[k])): if isinstance(method[k][c][1], int): @@ -1820,11 +1866,11 @@ class GbxDevice: else: for j in range(0, 2): if j == 1: - d_swap = ( 0, 1 ) + #d_swap = ( 0, 1 ) for k in method.keys(): for c in range(0, len(method[k])): if isinstance(method[k][c][1], int): - method[k][c][1] = bitswap(method[k][c][1], d_swap) + method[k][c][1] = bitswap(method[k][c][1], ( 0, 1 )) for i in range(0, len(method['read_identifier'])): self._cart_write(method['read_identifier'][i][0], method["read_identifier"][i][1], flashcart=True) flash_id = self.ReadROM(0, 8) @@ -2284,6 +2330,16 @@ class GbxDevice: self.INFO["dump_info"]["gbmem_parsed"] = (GBMemoryMap()).ParseMapData(buffer_map=temp, buffer_rom=buffer) file.write(temp) file.close() + gbmp = self.INFO["dump_info"]["gbmem_parsed"] + if (isinstance(gbmp, list)) and len(args["path"]) > 2: + for i in range(1, len(gbmp)): + if gbmp[i]["header"] == {} or gbmp[i]["header"]["logo_correct"] is False: continue + settings = None + if "settings" in args: settings = args["settings"] + gbmp_n = Util.GenerateFileName(mode="DMG", header=gbmp[i]["header"], settings=settings) + gbmp_p = "{:s} - {:s}".format(os.path.splitext(args["path"])[0], gbmp_n) + with open(gbmp_p, "wb") as f: + f.write(buffer[gbmp[i]["rom_offset"]:gbmp[i]["rom_offset"]+gbmp[i]["rom_size"]]) else: if "hidden_sector" in self.INFO: del(self.INFO["hidden_sector"]) if "gbmem" in self.INFO["dump_info"]: del(self.INFO["dump_info"]["gbmem"]) @@ -2474,8 +2530,8 @@ class GbxDevice: self._cart_write(0, 0x50) self._cart_write(0, 0xFF) if flash_id != bytearray([ 0xB0, 0x00, 0x9F, 0x00 ]): - print("Warning: Unknown DACS flash chip ID ({:s})".format(' '.join(format(x, '02X') for x in flash_id))) - self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"Couldn’t detect the DACS flash chip.", "abortable":False}) + dprint("Warning: Unknown DACS flash chip ID ({:s})".format(' '.join(format(x, '02X') for x in flash_id))) + self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"Couldn’t detect the DACS flash chip.\nUnknown Flash ID: {:s}".format(' '.join(format(x, '02X') for x in flash_id)), "abortable":False}) return False buffer_len = 0x2000 @@ -2515,6 +2571,7 @@ class GbxDevice: [ self.DEVICE_CMD["AGB_CART_READ_SRAM"], self.DEVICE_CMD["AGB_CART_WRITE_SRAM"] ], # 1M SRAM ] command = commands[args["save_type"]][args["mode"] - 2] + if args["rtc"] is True: extra_size = 0x10 @@ -2539,9 +2596,14 @@ class GbxDevice: buffer = bytearray(f.read()) # Fill too small file - if args["mode"] == 3: - while len(buffer) < save_size: - buffer += bytearray(buffer) + if not (self.MODE == "AGB" and args["save_type"] == 6): # Not DACS + if args["mode"] == 3: + while len(buffer) < save_size: + buffer += bytearray(buffer) + + if self.MODE == "AGB" and "ereader" in self.INFO and self.INFO["ereader"] is True: # e-Reader + buffer[0xFF80:0x10000] = bytearray([0] * 0x80) + buffer[0x1FF80:0x20000] = bytearray([0] * 0x80) # Main loop if not (args["mode"] == 2 and "verify_write" in args and args["verify_write"]): @@ -2572,10 +2634,10 @@ class GbxDevice: start_address = 0 bank_size = 0x10000 if args["save_type"] == 6: # DACS - bank_size = 0xFC000 - end_address = 0xFC000 - else: - end_address = min(save_size, bank_size) + bank_size = min(save_size, 0x100000) + buffer_len = 0x2000 + + end_address = min(save_size, bank_size) if save_size > bank_size: if args["save_type"] == 5: # FLASH 1M @@ -2677,7 +2739,7 @@ class GbxDevice: if agb_flash_chip == 0x1F3D: # Atmel AT29LV512 self.WriteRAM(address=int(pos/128), buffer=buffer[buffer_offset:buffer_offset+buffer_len], command=command) else: - dprint("sector_address:", sector_address) + dprint("pos=0x{:X}, sector_address={:d}".format(pos, sector_address)) cmds = [ [ 0x5555, 0xAA ], [ 0x2AAA, 0x55 ], @@ -2699,32 +2761,66 @@ class GbxDevice: self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"Accessing the save data flash chip failed. Please make sure you selected the correct save type. If you are using a reproduction cartridge, check if it really is equipped with a flash chip for save data, or if it uses SRAM for save data instead.", "abortable":False}) return False if buffer[buffer_offset:buffer_offset+buffer_len] != bytearray([0xFF] * buffer_len): - self.WriteRAM(address=pos, buffer=buffer[buffer_offset:buffer_offset+buffer_len], command=command) + if ("ereader" in self.INFO and self.INFO["ereader"] is True and sector_address == 15): + self.WriteRAM(address=pos, buffer=buffer[buffer_offset:buffer_offset+0xF80], command=command, max_length=0x80) + else: + self.WriteRAM(address=pos, buffer=buffer[buffer_offset:buffer_offset+buffer_len], command=command) elif self.MODE == "AGB" and args["save_type"] == 6: # DACS - if (pos+0x1F00000) in (0x1F00000, 0x1F10000, 0x1F20000, 0x1F30000, 0x1F40000, 0x1F50000, 0x1F60000, 0x1F70000, 0x1F80000, 0x1F90000, 0x1FA0000, 0x1FB0000, 0x1FC0000, 0x1FD0000, 0x1FE0000, 0x1FF0000, 0x1FF2000, 0x1FF4000, 0x1FF6000, 0x1FF8000, 0x1FFA000): - sector_address = pos+0x1F00000 - dprint("sector_address:", hex(sector_address)) + sector_address = pos+0x1F00000 + if sector_address in (0x1F00000, 0x1F10000, 0x1F20000, 0x1F30000, 0x1F40000, 0x1F50000, 0x1F60000, 0x1F70000, 0x1F80000, 0x1F90000, 0x1FA0000, 0x1FB0000, 0x1FC0000, 0x1FD0000, 0x1FE0000, 0x1FF0000, 0x1FF2000, 0x1FF4000, 0x1FF6000, 0x1FF8000, 0x1FFA000, 0x1FFC000): + dprint("DACS: Now at sector 0x{:X}".format(sector_address)) cmds = [ - [ sector_address, 0x60 ], - [ sector_address, 0xD0 ], - [ sector_address, 0x20 ], - [ sector_address, 0xD0 ], - [ sector_address, 0x70 ] + [ # Erase Sector + [ 0, 0x50 ], + [ sector_address, 0x20 ], + [ sector_address, 0xD0 ], + ] ] - for c in cmds: - self._cart_write(c[0], c[1]) - sr = 0 - lives = 20 - while True: - time.sleep(0.1) - sr = struct.unpack("= len(buffer): break data1 = self.INFO["data"][i] - data2 = buffer[:buffer_offset][i] + data2 = buffer[:end_address][i] if data1 != data2: count += 1 if len(msg.split("\n")) <= 10: msg += "- 0x{:06X}: {:02X}≠{:02X}\n".format(i, data1, data2) elif len(msg.split("\n")) == 11: msg += "(more than 10 differences found)\n" + break self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"The save data was written completely, but {:d} byte(s) ({:.2f}%) didn’t pass the verification check.\n\n{:s}".format(count, (count / len(self.INFO["data"]) * 100), msg[:-1]), "abortable":False}) return False else: @@ -3024,8 +3124,9 @@ class GbxDevice: try: gbmem = GBMemoryMap(rom=temp, oldmap=_mbc.ReadHiddenSector()) args["buffer_map"] = gbmem.GetMapData() - except Exception as e: - print("{:s}An error occured while trying to generate the hidden sector data for the NP GB-Memory cartridge.{:s}\n{:s}".format(ANSI.RED, ANSI.RESET, str(e))) + except Exception: + print(traceback.format_exc()) + print("{:s}An error occured while trying to generate the hidden sector data for the NP GB-Memory cartridge.{:s}".format(ANSI.RED, ANSI.RESET)) args["buffer_map"] = False if args["buffer_map"] is False: @@ -3175,7 +3276,7 @@ class GbxDevice: # ↓↓↓ Read Flash ID if "flash_ids" in cart_type: (verified, flash_id) = flashcart.VerifyFlashID() - if not verified: + if not verified and not command_set_type == "BLAZE_XPLODER": print("Note: This cartridge’s Flash ID ({:s}) doesn’t match the cartridge type selection.".format(' '.join(format(x, '02X') for x in flash_id))) else: if flashcart.Unlock() is False: return False @@ -3233,6 +3334,10 @@ class GbxDevice: if x[:-1] not in write_sectors2: write_sectors.append(x) dprint("Forcing sector:", x) + + if len(write_sectors) == 0: + self.SetProgress({"action":"ABORT", "info_type":"msgbox_critical", "info_msg":"No flash sectors were found that would need to be updated for delta flashing.", "abortable":False}) + return False elif "flash_sectors" in args and len(args["flash_sectors"]) > 0: write_sectors = args["flash_sectors"] diff --git a/FlashGBX/res/config.zip b/FlashGBX/res/config.zip index e458d3a41dd2b63e5d5219d6848e185584cfad7e..0289515b68c5c94e121e9d07018042b700bed5a6 100644 GIT binary patch delta 53856 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

nnn9gol3%I%+7v~p>s3sfWAyH%P*()}p zft^PTQ!PM+Of0%%)mf)_|FYWpKI4D636n5_NFk1eNyA6e783{50;Pit5o!}>t+S>@ zlWtENza&48d%GIvP#lU-vT)4<4|3_Fi#m%63{&hnIT|oUfA3aXmz+(#UT`4ZEkX9( z)$&%|yndenEl=}(SpwDt0(sZ>xpPjNL_r*ac!*0*mTZyw&Qn2J3~>A6gy2$PGUzPQ_0X;v(ahSV}jLNrAz zMXkGdvng!cfB3STxyY6-mDvvz_s_YJ&oM{Isd*+b_joM2=pw|ptTsUUK4XDPuDjsd08e?%DBhqg?^oI_*BN588S`}^}! ztY@f^kX)L-AL^(C0%|?Mcnsn}goRobpE+47GoNt=4#-^yJ{Qz`{I-y z6OH=%RSQk1NYguqK}at(Xja+!_HKPN7CEmy8|oYy#VHaQnDOEcMIY7!BD(iJr&gHI zkV|%HeVu++>QPWQrU| zUSvuQ%E6w_K_jT4bgx>tg;3Nim~l~C{r=MUe_gPoI|-_O%9~nhuqRR;>FYg2c}0sZL)BqR_C3@^qANl9ZJvvD(GWNGT% zvkbvjn^y1K1LoLa^yaSL+P%5!LzzIp58#9x+H{#f9$hy&e@O_p^{GV);O1SqS&4i9@c4FY=F*<8F#A(K z&o)f}!vy0L@5|-Rtz0Zz-5EB%aMIveEYmtlB*99ZZEF`lu}wNQ*@^1 z7+z`lavRaXLiT8(nWi5ElmO2Lk3AwA7fF8Ybp;eCXGR=oziQ&CK3eU;} zGF2)`cFFA%vhe+ln|}N1)Mt71f1Sr?IkQ0lDJ7$^S`NZpuY_ zgXpuAj$guVy+CL`@biD8E`YQDIJleI`llP95UV7sBOj`l>1?|u9H-R(o`G&A15=~6uNC=D(qY_9IaP{FO zr&Jof*2b&`z=912Zku&?rC&YXf8fLZ(alN-x*$8Q%iTf@a$lAP-kzXlL)Icp1cI0^ zCToF+9;!BGRT3GHHaxWqe-5OYJ!Q;3#{B3yd~oPLh^Te2cpbsr8Ru-6S}4o}2@Wx} z4r3G?O^HdMEbZm{Rde?f%$NYW~R_@lN19f-5b4#5ovQ0`=m)DsS8E(nKmt0lMw`^f%l%Y2-vieguVvN#a>+5Y<4Q z*wLyAVN))13Ut*=e|*93#&x@WJ5EFz?^c@fb%gTGJ})-Xawr5UU`Lp;yipw$A((46 z!IBsWmgY-dfWlW+NL>DLM5?v-iFc=cG(R3FdiBO|@k<=nb^Wz(S-Th_jGkR1_FPSlMY@ zJP|j`#q_W<$K6sC3A3mBA)qzZ7Lf{}s%-!mR)!*le=$gh&W>}?#mvrH8r^EN?JoiS zY!jH9YY^d)SFU7f(yES@LPZ(V8;wDw*D*VSk1CDJQ+|Bw;i0t4s^SheHt~46D`mvX z&upof0h0&j)D~?PsW65kHDszs~ydU zPwRbHe{@ol907RID)=DYzRI{S8PZkRb90`f;hfbxGhWVu16r_XmLXmg6s)21r3m$!|{BoPQTg zmZ8I&Rdwg~%}JB)yGxn7kGCgQ`vpqd%k{qXJI8$y8HS?3kz%&BF?%!&EgEAdU0lPY{BT96g0nBwDmq{xc#8qye<7b_4OahQoP^i-8nFffK$j# ze~(m#qZBNr))GQfYqc_gJGa(MWg-m0PW_?{@wf(sA9`6Ist$|v`_Fcw$e)zWtL zg*Nhtl48ODFHhHNv5uV!R;~nv+)croqL1Kdy?U8sP`0gyG1jKT0uXyB3xW6h?ETk| zcWdQ%aqs&}3GZL!l<(i(J}gP(zUJvUe;N)IEleEz<^J_LN}Cgl^d4PFu$OdbEv?Kk zQoLq&-S6Md*z(ug*$p#EJfzKOnqG)Ax^&GUgT^dvc4K5$uB@{IM|`<2Yk6zOQtgRD zf4$*13?=8#LxE_TbTJyEbaSN+*uBqgkWjfA_89|YTws|W$_l$2Z$2EZpN_vRf4uTz z0RfhWt1UU&4_5B)n|Dum^qcQ)W|@Nw^2-x~?~XHvKK$eV@kqMN5fuT#vO0CLF_Lv8 zY9T_fSx`zm*Q5PeE`}5QTiANfn`n%F$}cCNUr|vUbUG@pAoTDQ|r5 zTR(nQb>kddYN-Gmdc4I{2e}ZG(S|F4R7j?D!KfjaJx8(-)vXh^xApd~`>wWgnm1w* z0YyL3m*{*zkG zC6`Qc%4`JHh6(HFa`8yMf4ORl$n&dTKHmRnpYi9=Is#{qbi|i$C7@^pJv&=Vo-Q=C zG0&FRy-gY#s#vzk!Ow24-uJSWUp!A4=4W)~gQqK_u^$;&j;ZVePTZ>oJQ@vj_ke&Z zDBQ*@9Py+Ns}r9u7utzSsk|xcwCv43Pd0>NL7Hw9e880%6KCm;e;9(8Z8r7Rdl8bN z0TA8Dsr08@`R(e-)t|3!PE)_@g8Y3iUC+;Cqp1cWz`%H9RhZCZG_T%5Jwd3cNqB~1 z)z(I4Yw24R$nts}oB00K>pwk==M=Jkc8&*8OiIx3!<;a!tzI-9l-S%kFh?OCl^V{G z)dWa+j_sN}KGeshe`mdK0lvL?;249D4k@K*qIj9z=4@CBHZ0z<_pCHCv9v*Esr_b$#6IKC$t>8ESP)2$+^NF>E5Y~!7->^f1cpi>)g}ZvSMhLE9lKq z;@)`=ZS+nMRRhuZNZwa!?-Q-J>MTCG3>4N14U)yt!o`cw#*35b3qShp!*Ub#`&YEj zflUk7S;I*WDc{#pVy2lQLQHR~?TKO)dNl+jov75yB_-A45+1DsQ2U~zpMAEW5m7LY zw3m0GQaX7le@px&7J{9>t{N40 zJ72WVH!qqvF|o%10n~;QXNTU&X$34Hh&e`c+D-!4QjYuS5^cK3O3-gaaNBUOt$;6fyqm=*{H1_VVFl;lJUHR!!X?>xSZ7;-Tl@Wrd&e6ce^+4P2xjaUNh zz%--}63!86U0T?B+nuQcbhURncg^we0!8e6^kRFSSfc26e=is@te#=>c3{-|jQ}*V`vuGXv=W%NBy5Cb$(I zJZtZ@jU;YX!RkniaY8BL(^l_1!<&{xf0#nBFdsO>)i_flVnPeB$rZJEL{=1IDRovT z!u_&i{c8RC#`@#is|8FpUcK*P-{0@!E&Ms1gRVq?js1wUoX^5c6(oJO#@J^|Q5&th zt5=eV-l3GOVAeO@mcOr+f?t=X>I6@i&Kuk@X^M&2OUEQ9v_7~)cW@G^vls6ce?_>p z93sI?S*Kp~W&i&7>r>HkFDn1%o59o&(~z(OWk2er_T)i0yJ*)QR!7S$vofe@t=hdb zc`CpAz<#;UblKvsQW)Iu2s*bwp!77$;z%$Yn@>ZrR)+E@3{~4@ZaS6=|J8Tz%In*k zeYWeF?Fz=J>~e%Iork975J>g{e_XRm3~9YXE2T!CVhyQWeC&7S{`UGrDsumxb@Zk# zIPV|bFOAc_P8ICCihgdJ;Q@DrNH~P_Hg;C+vvO~RQkxDNBv?&)n{!ZFFLsd?{j18c zq;{_#-<5^O{_WVeEWU}Y&7IPYu?}ks;yI*y%?cE&@!*o(nm32$MFbqSe?I)_6hyq; zXLoE)v1f!Z9s<6U?&{TRsnM#o;HfACSQ@|(vQCl#V|#ZlT7zqqbrrO`+fPhza$+Ox z;OZhI$E&Oi6}_>ywX)Tm7{=wj;JOoo5J{GI1F&*i|;z|+9($oYjJYL!BI!6@XV zw;X^~JT*`gG^fvg@!_v;*8=g0+Aa{fYC(tz2fB5x zW<_gM>^41WZIVXGJVT)k?J{S%NR!{QGVC+@T=X9uM2!^W%W{9C}4kE)TjSErn zTDe0Js?oTOyf_=}fAvXAwPvkVt$A((KjBWHUonf3Pl|HabinB z)0jlT0RacZDFIQlas!(&ObcPmnOJIvE|x^@I&qK9+YZ8|^;@kkY6{qchWC<#U5nI{WPFSd zt;Ei2e|`up*&s8Sh+*$*m>2Q0|Y23 zF$pja#H7?xdeu%`P-jCOc1EOY7@TpQZ@BRL!q+GTz6%eU9JC*JUVrvGZwnN<)L%LDxoZDuG9 ze?$-(O$oq#L*hyfjDywJyDIIG0LHQrhqu!B86nW?Gw!jN7W+ z`-aE+jq;od%Wuv+2rzLagv0EFJ=9_}f78~ZK`j$}Vy|V(Ab>$-3T<*@ll`l_f zzVCfmQ^bASXEV<&7y;P>%_^};>7};PWeWFXv9vbWE-w4Ojr*k)()M-#KHVH*Nnj#- zF||7OCSk1zqexQt>@cci!|5e!8KwB&K;Mx83LQFX$Lf}A7-hc{ac()-A8WY1h zhSOlCMBZJBA=WM((6R1iy-Lyab&ed`cEnvH`vnag*e*g)(BEbRH$6j%Ae+7Y7W7OV< zNK2tCl-4;W$w0;Np>Xr_-L1dPge#^8I}p9xc9Y^g2ZCspp{?;uz~n-mP^uOifLOPo z@+V~-c)u>USHE2VoqNv0@3+-JWn%Fc2N5zmLc(wnoYk6gU{fC5tr}6Zj#xU)Eg1C# z2VUN*6AEF)a_tN@H!2%uf1xgf2MTPp=$xt8lbTFu)7-U}TAKyq9O`uhg$bDM%N@2uh zjKGUMe^cI!J|6acfA@3g6(kF04n82gLNuBi77vG_*c(o%T(tEr+!?`Trgi&(-Fpw~ zx!MPEkTD=0LHU)6$gFKnYDKw|7r@z33#E+OqEDUx?Wxk>&Ik2RXP-L&I8ctUV_602 zEkd;lj;2z2;;_WwiiNu{VYm7OD(?2W?X&vN8<9`WWbh-Ie^bVopoJo{^J(N?TDk3{!DBPLV*|XYpaG)&^+RR!3@+>b)eo z*GZGRZ0jL6*K>Y#l23n*8@dq_Q|3@|KI{gG)npq{5~f%K>gha#%ajHbEr*TTWIHAP zlV4qZ`gX~}f5-jGaC0U|x5ppbC^?8z7?>RPM>_~%h{NDE8JKAj!=N5AMOta0#7q}7 zOb-h^(O;Grf7~vKz*?KVxm!DRcehuc?K&=>o}(W)nbnm-4{?jKQJ*D7VM^qfDm15Q z*O*9YO_1%P_W$YC$JaME%Vga?!#4!=D(vQw^zz4Ge*iI)^=ekp3K5&uIvPwmshc1M zxir{k_p;7US-ol2A$hWBzPMaCW^|k_Gf>%Jc=OgrbqualT`Ri5oZIvK)glPE1o-Xs zbGH8mw7@74oEgV?=q1_7OG*G11fvWpTEM)(90^Fs(&jeNy1QNFhJSgtN!&LI%KwY8 z@6&U9e}JH3AZuPqXdaPNo~;nEa2I8m({#$Tlwjnd1l*|V5NLaSJZ;|ZU#;70oeX@g zmz?2303^@RL;cTx^uMtXRB&2Ih7NKY?lmE%bx@k4Vnj*46e3Q8qM-zXB- zvJ3{Vv;!8QZ0X@iA> z97nbSS}~NtGcqNThe7E&zD-+q<*Y9Ef9v;!S*% z5t=fvf57OyN8^0rR4AA|ERGxvnqZYGA;QdT9)fKQWeaE~JlZf|9Db1!zPr0xfB*6< z?C;i}bGlJg3^C(ygza^B$fzhM3SmDIt$Gq&rV84QrXBV5Qb5 zfyAvhuF7O&l{G`3bYS0gv{C+se+W+j^#kJBZ2**+$qZJej+w1W>MT+lTJ}B+`o%!@ z`f|Ug`S@E|Ic)!SRo|VsY-_px&dyi-ycxvCX3m*MHc^8)DtDXat+!&c1XzLA0DNjo z>m`_>Z{7K*j{C=}d3XPBQn%;qsEww1Du-Jf7XvHFEPc%G3h1>=NT$(-f8-o9a!#2B zQQ8h~b}h(e#yJTYfRD`AiW~Fjqw{QQrX zx#UwOpBJM^1jPw8wu`Ype?tU9n_|u?T*J}9lz<&8YXEqaY8+Fxq-b~b?neu61U=(O ze6}etB7?I^`f<(0GBe!Ws92%Oy_?Qatx)gESYb#ejk?2$vy-qfe{(f~f+OT1QKcZ) z!QF~gEP_7A^bt8VGL*O^4~W>>y)uDc;YYLzEUvVA_uuHpmDek=f6ZUPa9p&cGd^>}RqGWrIYNNne~xbZpT; zp(wGU01gdq8WMucprwbq)XNRjUN1M&d;LM#_tj-HbqlJb><4I|reQaXNUgOr1{tm6 zD5dwn>JB4orm4{wK3*NcDU%iEQp>U$609Pd5%lAmW0qRFC)^x_noGPw>jpOk7=9AgI0lnyq@ zSk;??`}17cf4Sj&L-iz1te|jAg^#(TI0j}(tU8Hw8X|yUR+r(1Im*S0_vY&*BYIA- z5gQsrCR9Z|-Zn#sJ{0QcF@<7isYMB`&8P`QsL*T}^Jy3Mor*Y5rInlmDd147(WP~) z9&M^5DRA*#TNZ#(OD~Sr zo;#I>DH3{!zNBZv&`_OJs12^271&5;<)&HG`^46_PL=yF@7~>v?>&6DNc-XOvCn?E zLC&R600QnBAKPEQ9aVa5uALnKiMW>PASG$GGH^_*$y0Xtw)4zv9U~Cq)9G$%n964dR18U5;q_xIz?sZ9Ipl?nUJ+xxPgS7UW(v*j=uGE zGL6s~Bc+b;VRQ7XL1h#&24*YNvlF%_ff=9u;731LXR|)~;hX2I%SMYE*f=eWk0(x! znmD{x)e!NVpuz6aumUxT*1C7Wi@U6?Ah1u$f1CB?zuvbN8x3k;XHx?^P^ThNA?WCm z&AW^&fry?(3bQ;<@}Z2P**v98pi2+$}?sRUym?B}-`@RmBU) zEH!ut%nw+-f7hH#O|v_vlb{_3!j$kxfSBEL&g#8EA6TNwh=LPGS1%Vy-u4K;S3db< zf0683)Q%Tn+S~E4GitmTnr4j%h9jk$9KbWuW(AM56as5DtM%4K<(k#VF5t_59*>Vp z!SmNAjrJwdTIudT`t4Wy+}O+^Lpr-B`T^J&7}q(FrD8|K9J90-<{4Th1|yCDY?qag z<%R#*-QD`a|64|GS)S|h*YU7ZIOwyVe|>Tua+$f>lhWqrwReV)CRBzC5wvRKedFPVxTzu$AhR;f)LG0r5A^yhZ+0eH=gof<4mNP` zBe41qD5ZeIk%RHsAnNkM}!cvK%+d5iqHzF!mg)BC>f4%<$Pv#J3iA4yeeE7VEW zV^S6vj$=`G?{gPeJJO8vNFBHkBtnB0}~=1k%7Tkv{Oniqm*V%Mo|XBIt^*4LsjX` z`*ul|cy|?Ec$yYshbJ4B2on@nl_Mv^($f^`Y}iIfYooaac+IXg3fB_Ce=_u21lvd- zzqX3q##U)0|U^U6-xBNFp5xOu{MJml|-|cO=Z+5mv4T* zDYtv8Tj#O`Xao#N6bI_5e^$X@YAd6oT2=8;in&8^%udCz%<4@q>Z#Wcx`60XpP5Yi9u{ z;k_him*JV_L?|?ft((ruAMOmE+JRq=*QcZ1S4x0=zWnyw7h@Dpv?IDtWsKI+tUycb z+_*MmF3S%sC1F-Cj>&j2()!os<@nJOcCN*&HC6mJh(o-e%_@Ib#Px1U=Fmg4Vl) zhajYeXDu|0davnj%|`f;z->PKhp+CgmQ3Nz=*uhe<%wCK*6YVT%d^2?Avhoe!pn7! zDMt)rE0~(ZS;(tn7O+_&`y_JEy)NuaO+GtIO;`jZB^(b(vVwq~IDf>aW;E#B%Vg`L zijrByK8a`JzR!)F8|t(3$jc(bnB)+#FA}9?&#b1Rf~`e2m|4NXpw1yVqm_B_u9v<- zcK6+1ug+dWM-vM<)HpF??Gr1bI@Qvk#Ha|NHk%ruAVX!GCRXG~mcKs!zt5g$QPnZcSg3zqM(&vqt*+^GOzxFtq?b#Hc?_ z1``YgG6qs^EsIyIoq8SV>;v0Q!=JuxHv9)@iGfBh*GcPxaey--#PG;6dIp9TZYi@- z_3E?Y6UFqEpY!^!*SFt$PRw*Jo{Y}w&YZ^wqxzswB%jsPm4C2lQcx1BkI@2i`cSU^ zZD5#vJLeDQv(*5S&R}o|F+6~=6Ev~`1#r0f#P=m@u3TD3&iWxN%ty;o{NU;j*EjFJ zrIhfLE9a|0U`*m7FE1BD6QtH^pQTH!*-sB{$toz5BwUEy=Iro9^maVW%BCr`pwtxPKe@@Qr+U)N$q;!aPH&r z>W6)C?(yyYzPj!o&&Nl0l$GdZB?09r=i_pSq>mabx1ZF2LNK|@=%=&b6vPeg3Trg=r%>^qGZgkFAk zwb?p{Qh)S0Z3gxxEHR`PV2>$dW<#VWHNghh{(bq$=2tMvJna`tfNf2Q@FfZ?#K5P0=)J$g@Mt?FQ>zql0I~gQTkS8pD-*5inx{te4 zwQbMY;PajU2}T0Ji&?U!kFFZCU=+0CDw@KsW40PlxYdGQ*>>2!^ErRT=XVq)TUZ>R zfq}uK5(3p{>yvqO_vxfQBD#BILA(@u`~2bUo3V07e0jYdfOkuMs+QYt284E=0NFO1 zB7ez2;D{7RF=JtwvoW$jahIA5F z8quhtP3<&9vZ_cA%!wDb=I#CU-4gBHFMl1E<&mR(AAJigc0z%WBiwvhCeeh(O=Xw} zxs{?MCMWg!3_~QclYdd6 z_d2_b+PsfMsmf$@d31Yuv(M_>0Cd8bSzV5lHiqc%lvGP6Lh|4etrRfDLLMCldG67O z-J2D>I>&VqDuJ8u%SXR?7E~&wMIo5(MxCKi17S9+K1NBGnNK0W{x!OHiiMsR+MUBW zg(QJ7`2Q-~Fj8Ab6|IG(b{*i+q7R{xMYw+X{}rwi`K^d?zzxc=Tt}r%p!^hSn8{Io67D`#c^1T!edy+-f;vl zi`F(Ep0s-{d0dx0XJJEz6pm=({NgvQE0u~tqc|uc8AzCEX(gSe*QUwEV}D%ULU#-9 z@p}&^KCnH8Z-|h@oWKd;rG`(#+8QG1%p~Ft!EF?V95xx$fhShb-G+a7ul#5u$bjz3 zhx(&gsA3NWt)sPQ!E<_|;H)rCV%xyodT`djwcv1a@&o-_v@zQ335{AdgE>OHXM#o_ z*#c@rq{MR__}l2?Nq-Oiun~}96G63ab>Y=t&s|vm@c;IKF)J{2vSHd&hmNQ`N=HzZ z%%%cTFMN3W=I-h}J=vafa866c$O=es;2hAjj*PWKCqg2djswc%GAK!n3t)?Q%I>%S zGJLJOEF|USdO^{wj8|XnJPYST3gju`sT_wIx~JX%he@sU5-wyT9gD}v3We$#%U+-beXGgav}Tp7_*JQQ_p2W9yQjR^rke~A z=y*ViNG++f(SM_Ooz-(ndI}_SOF$~7&6~9ky#q@JVcGsayj`a}*K);A-Y)Fr`!>=! zFq|b5$vxu;kSr7(#)ukCrL@Y_sP{|(7z{isFkrNAyGa+1c0bEMKac#B6_LR0#f=eZ z4Mz?%3?v&9OADSY2`9`xx&SF@<*fs^3zyQz_je2B`hPCA`&Z{kc2*rK*tyArQKamN9i|FWB`1hClq^>KFHWi0)V0H~bh%hA4RG+SHgTX~vpBgh{ov z)Y(P7aw5(2M%;IQ_75iu=ZJL@baD-oBOSpEY7;|IGt2OT18R@346^1HNNm;hV%xti zkK<|~e1H1ndYp(3`_=b;v*L^Q?4S)yoq;1V<>lxYko2mN$2 zQ{U^v&h_}^hBYJHHALf3hqh*BH7g#icBLR2qXx`c)lf%M@(~xO_~*CtZkg*?{osW}_T|u4aCOIjs!o(<|U` zD1Wn&iOp)oCl3{fW?ZDV5l?#Xy@!nldza%}tIsKgjgXEmheWG6V1nArdcrkPBgGy{ zT!v2N)(Y9hl-J+?e)Hk&^exrn-)`6q7!?8Sf(HGvdi-41rbHTZP7{P#a2R!}gB(>P zxdsMU*S^oS|LKY$nMj(yINFtl1SV-2oqwpIcuWSV)*4gAL9Kfom!-gk{iBwh@!ybNu4|* zf?&?_plmKInUYiPCV6-8rWX`>C4 zKA$|hYjW|NoAuM}jRfkzbfK5~?3a!^6fA>D25PH1OT%!9379#uQ*Ex|A2`o@8|

L^z&{|WnD&vVRP`Q8gcz?abe7hJxU%lFJ*RiF#_{#}EO*J5({{SWvNAHQKoG$yVQmI-FryVAIiHmy?*t0cRP0FryFuy5`R`oez_W3 zT2uFzUaoz32z5}os*$5|b4nLp`#xrcR0IV@6$>#uUvzt+= z=~${FRSdqUJ6*rNzWvMHP8iiW^R1v8F{B@eOnG>lMAReHJG9;vfXcvGodyD7pQS*# z=$hYL*QKaBO8e^Si@Tef@qccooWQH|@dtJ#j1ZO=%jeb%#Zo(y=@?a^lGWjLOzfdJ z3-rvU7nQQ|aNWmyq@Af$#*dPrx%RqYh^%J5+=LF;|gIl(VKBqM9F(neKk6F#OmVYnZ&M!au$=fBP zd3c`k$*Xhxe`rP`!C~cb${J7xD;gWlI$XxOAVsUWkz|F^WVXvF=>BneasRk)=lt>f z#pQHxl{|8AvzlZd%{ny=(1>nQD`uHi!pqR%EM;qVyL-G@ixht<_kEx3e>$@rNk}pC z5Yz>vVehVOwnn{WAAcn)XzhTb*^n9r)G?msV!NvgruOsG@cljy{(OFJ5m6}A>`y72)>%wcd!4Pa_iEZN}^sXN|m9oQ)eAsD@5n&jfR6Z5r3)QV)_1y$j;Lj#zX)oJWiF` z5PK`xl3aQKxJ!YW-6n&Xjh37#vX#bYU%frGXMcIU-bSB~*RM}X86V%2KK3oiIjUSk z3=Iy!zyh*3sOQi*I1^?e?N|)UsM>m_(}3yQ6}i5Bx8N=AZvShpbDfx4K}buaRMs-~ z-CwWA5`X&jl`!%->lRxr$-r>4_xa*;~nx2UmIWYQ2l6mgkCGHU|@VRNo2-9@C#ma}NIJ}5aa z7|q80{ksK5u$KBx@XPni2=)5DKkV}*H*f+?Hh&L4;L8j)i5XIhxDqAe!toEU>cc0xKZ^s1;3002R zJ%717X|mMOnrPPpnw0~?bUnxcZP_coKxUPdSn>VA?N@bQLxfr z=2{DKnY}Rd!ZwQqwj#oQ@lf2|e?68;F@0FHAlVVH`@FE7qlM%RK$!hp)jLl8?=lh>u*?R<6{^m=`93?S@RkhSU{S!D(P8u){Z_i=FrQl z=jQ5rKV4BI&xw?Nx{Z`f*bL;b9%9r|JM%#H0@!KPK6Rnd`+#etmtKSbcrH&Ieq-d%L`7D}6!V z8<3u3LdnFyNl_1+3+)+UIs*!E8(2n@F;$4lEXcs1I;h44?dhBAua?03Pk+ly`l6Sy z{Az6jeZ#u@o{*FF`E-s~R8<88=Og2|rIj`-&5WrnlH3KbQL!e_8%Tp$0PKSL=e~{G zg^qSnXkLEyoQ-yl_9H`L4@5n@(*{Baw%#?MM{7wX*>pYjqS+9HA^1X~;cOxHEyFL* z^8;{H6gpH>h#H}yRAiKpW`7goRMs~ZY6&uWWeXb@#}!amOLVAQ0S!ns??ZMl>*CPD1Ao8o%eMJ_j9g2qLf}y_`)c3~IE-ZRQDi zkZ}J592#0W$$rwcU$(Y!GAf8E)rp28XU=% zOHb=1Yyz3jp)@KY*NI&Wd$)?U^lH9kX}ErTyk3&zWeQ~#zd0$g?-OBI-T35uNz92t z!4D0?L3THCi4l{jNrFibs~S9`ARte|-Mi3kkKfG?teK;!Hl+TM?R* z8={XEGm1DG&vhXpQ!ZoJ#oon(rE2ue!0Y1Cf85)5xX;0dlz)m&NpU3bfMG}|wMS30 zTB)YC)gtscxvrM z=!v`c@6S2j=Kw?`QDSn_<58_rqfWhJgF@4INXJ_0pov3u)H(*@6Zz@m!-**SJ4+kj z_VxO!r7L{`rRg?1ry`UJQC4{VeM3O&eotR4l3%F6{Ba)3N>j`_ls7>{rz<- zx6fINa{!_yLkRluhAMVTDpDD}6dh?kMkAW7F$qU&wW$Zxi<|cG{>hv6!>I1hKRds1 zF%r~L@Cd4Vdk4?KN>oO7AJRGoPvSmnj;xk7W|`Am^?zI4*_QkMw=d>So~-*{kISmT zq%Qr032KTwqNiu01_YH7XJCy~pbG)f`^OVI(cAmKo+y`oRNn0D?QH;xrjEcyM@oKE zBz3w9)KRiyN}*_@bu(ulRFJGfKIOx!g*o(_j>C^1T3M$5=KbB9lQ#?ZUgJJJYFAEs<$hP4mH0#{#@n^R!6vpabX=@c*|&QLxe zDSuup&^kkB3`Q1IU<(*k`q0@y-OXEnqD8aMq;XorXU7U>-DDTKr#YzInrMy;2?xAsmejdbDU_UJ)TS&ojTLpK*3oCMw~K>5 z7LBFbwJUPMTm0f}|MJbUFblxqSrNgX&*Nt!W=uGq%4n?!WF+0yN*`GYS(BMAT7RTL zNd+?1Ee_~rVM;Hnh}7HLZ-~XeSoHkfj(t4Pzo*SOQZfc5zWklcGJWs_9SEwLI8sJO z2)8zS*6!e`)Ia3L?-w-FZTVZdACG1AX?Ixjd%6@GcGAEjRe5Z!5H#zkpra&uag-pa z-L+Zcs?n`o%tMbgEnAe*`+~??Tz|VSi!k@~KUO}_$17gE{LxoSIJ(vVR+vD!-sd21 zu*e4Pm?lRYB<}2kfMQe%*MVpgt%WMrg5gy-FZeY1qp#mCeU!V0ySM9-y(zWa?&pU4 zy=-tjpeByu2VPFo6dy6!v{E)Khz+JP!?4E1#lpO956`L0x&&f3Hw*Y`sej6hel_pz zSM|b&_Y*>=eYw&RtZ37lv1%5N@9a5Pu@#mCQvmgs^N4gWQM8$%wxX^oAb~#nC|RPU zjjW>MS$k3TE!YMP6c7j;aRl^BHVw?XH&IJNFQFnjdNV9NnVNZ<0vmTu@WzL4hPKAI z*|QQKZyFXUm;jJ3E@{pwF@HyvWSl93b&Tv-nCg&WIK6wX1IKoLWob*ixo%fKZ)0Jl zX|H#U4z2cYhNux$lob!*G?~X3s-?MUcmT_ov+~rzy#!$BoTmFe{x(h7+JBa&2&xGQ z<{^5Nk|5BfD_Bq&iI!5br?L`P89 zJgg7wKv89KI<$dFty%c=lFZfGl&o6^-s_LvT&d@2n6Fn<^Aeiv)kpaKIr$)` z0HHJHkq%x|8MPyiGJjj|-GIF1EQO85!c=ucp$oeHMdp5j~WPJa} z4^MdVlT9|Swu8~~zy8Q?$DmDBhN;Mb)Ur#6W`#~Rp-IK*(!`rt%MQoBZ(rIr7AI%qu||6vdO z`0ZcTt9&^r`_IQYs0Te%)k6-&ni=ZNm9u%PSV6N`&41B)j3|bUwb7)w%t;q5&G(tj z2`ct_P1gRhyij+m*Xx`0Fy7sLXP;x|n%N{0dji*bd-Wey@1K_I z_hjC;EA{OA-~RS_jsN|={`P`UF^wGcNW_X50A}RG-h%4v*`V1 zQ||BfZPiWS31X#h?cSMfEAuV%8oFN)0Q`TB%$~Y-ifP&yP>f{QwY42lfNoXUy;f zO>2@8HF=5^$0FIJfKlfXYV`?(!|i*K#QWR#HJP7$gmU%C-IsGcFl)PaH)G=O&pCid z*ndQk;^k!1Z9*S?n4!)|+R6wbsw1peqY?}q`>47NSeBFfxb*yfczvdwzayLeY!f+C z1cKS22^G^)N}mH;?-Zk=dLKGlbAiMjtx7H2^Fp8I;j61p-uAKQ%WoR#WF8sF{?cwA zo4QMsq%xe-MkQ|Ervvb;o!Mud0v8GN-GALbcE(w+HjFtMZfT$gw4|^~uvVL8cq>B( zmqFSj)G;O*6Ct7PEAj98?4LhT-}i8M`Gv}Jc(z%&nFec9GQ(kRqR_cJhZ$7aU*F%i z8lP{fV4SL;$Ab3RL!>3vK@`;-QjryXG=rc>9Ucwh+oIlm#{YivE~J44Ssba{!+)q2 z5IDS6VQ=CT;@G2Bu4tvCPpEhi`>ln??>+pxu)Ve-Zf;hk;O8WO=e>IaQgX69TuB-< zI7B7PHNr=mgHa6|PnlMmjUMbKACl%<$jWaQZr$g&a^5&j06r+>2KP50}8S)Yfc$nfT_E_`20;;|~QJ&c_>$EN!# zip0dmN0O-mDZ@#o`?QD=1G^5M1BwcJNgGwFZ~a;aq1xS2y}bI--PaHQiF<#x7E;zr zVfn3P*0+>>o}Cl(Fa$cX=@HK)HEV4SM3N+dr6N?4F2#$FY0*Zc!}b}xS%09)?^ZJB zc3p0ES^ou{Wl@=y3G4?nQfXpgwhEZRrIi6v!*eoPlbYUIZ4Cl0z%O54{dAQ3_l#gy z^Z{|UZzwaq823x0vhn9fKmGWlFL=vmXelLg67qS^V&@`|_JM<)0rNZporh#Iq%?%_KqmByZKt&7kw;8_%D&wIo z5QOi(2b1oJRKAc6fQM8JBk<*u2NQJEAraA9!!RE#qe;u)(F$7n{mBFe~V!3=ES_nQfbbpIB6`9`6?ZttDhR35VUkeZBnu z>UVGd@sFFaZ@cLxh#^f+6hBl#A*U`vs?-X$$>~+SvzIjOD9P>;1{LR+m zs~_H6kJ}gC#Xq{>?f}n_vlLM0aOWfByKCYv=caq@br8eyeNef9kj16^%fs_US#m^h(ab*sR6KX2pscw$Uy~ zGZwaz^{RVZF!b+EssX3w-{SWdWAy6{qN`GM$B&e-4o1?KxTA(ooLJS1# z)g-rum&eED%Kho}+qTp4pKeHV!9ocA$eWT(T4ZRH(JK_oVN6!$s1%h#P<_wZw?13Kn0HS-Df>M7-FYs1A&_2BKp zI^1&#u9wQ-Q^%H}&;io&PU3$OKeGHVHY>KbioX#)cDYXs0eAJZL~w70>2C zHrcjd#p@*jT6td9w*FV|mS*=_i#jpgE{l3M`rU%kx-YMHI<^r8RCnM6Is#qp)1Yxg zAAfTesby3X>BEh&DRT;ni_QK-`}O{MsWrWMFR;4H{$FlqGK4S<GiIddwX|ir=hjY!V_m!k$|8%wL4n{8vm^AN_y-#tLPqy|Iln;1L)4fG6KR3 zAq=*&`$p5)bfdNn7>WN*)guO8y*8<{o*nhF2 z-M1Fc85pUAK_W+VV|-Z0^o)qsZMs5(Y`~2ZdL!eB>^A#FH2rd|=Dr@w7|k-awMDZ1 zU?=+CV|dPEYyyEKLcaiX$pzd!lp;VD+L9`bhA|6CtJF0zz(-Q_skI&f_?5uOL_sxJ zug+d)Hm^mnPmS5ffSScdSaMKjqkq98BPqA_pHF`My-z;hGb6-0O z5J5@0{*w%1=vf97YF(VlNGQeJCtFlP=>>`b>;)=;_Yr*ZU8{=A$Q`zG#xx20~0BCF)}^?Ru{dbe4j z_k>z-Q1d9kEs=aq<6$=ZBTgTqEWyL6ulVxHI_hWV<%b9$Q$Nzt3Yt-C1r8zA(h9M2 z=|Lu7U^Os6+~$Rl?W^&}`@0V@(Ie~flhgRx>)UcTt6E^6le>+>f`3t-v=z@E>Oaj} zW+(v*m%+2h?6qN9t(`L}v>q{g^RedzY`^Dm+&{TciYKN#^1(f4Kx5NM)uQDJli7y3 zQ*CKcO7k)5Q}FIMgRXu9pKY#q)MP%3EFm40uB=HrCvow?*gDD>01n!!$t+aMh^Pt4 zAs4UXby-ApZWd45?|&`6;%~0IW6lX^>}V07Lf79hF}bi08)-rn*`koPF$zyHHZRf4 zf-faO-Ygf)!_rE;`Q@D7`TV~08~%UPM}Ebd0MyVF6|P5&>Qj4$rH>FN1|d^vqfCL4 zqj9N`{W6ZO_Y3Lc=Fg`($tlD8_b~pRyXCz8C}`~DdBEse#ecCWiAR|e8_!V()(TTm zQWT^|77l*wZdolh+N(7aI923N7tP8^ z!cnV|x1p4XI=5BVU*G&Qje6KuH#t`+QwfSNvm7MS? z7x~>e|JXFc!}WU8-P*EXolzWX7wg_fKy6Z|c99Tk-LR{Fq=R~5^nChmq3(X^p7fKl zrU?5M(0_)43_=m4hjbqis}sh=NgNK%T@@p>phGhoG{j*rUi6FZUX`U;)W%=R`>PJ6 zjSM8Yr&CxQ2o9i*Xi#W$i8-|eX!bJ5YjCA3jWLq4Zng54De#{!@!kC{wcX$S_Pnzi zXd;pa#C9brjmpviCrt4OozP}!T1%RnLe??o*nj`nTj|P=KfVBkhd{vpRJxM6lBh{- z5HbT|jy7Y=-ZYyFHZCa_i1<6-|8h|1%e>>nc6qpc{rcgyUsp8T&T}OhChPUa^A>^w zoM&~K6{EHcv4nz_nUx26lxV6ExHdsHHhkss4^;=zYFi#9x_H4#nIpGWL_mVN(yuV)vr+2sa>m21(49({k);b(6;YS2Z z2ZGKbh|*hta_xyQ2F*Tg zKF!qy)VWFvIs%IyGYA_}0BA5sg?|>-K)s31(UNHP3DPToYq{`#d0AHBj(w5%Gup^t zu|kGxT<_aKrA6qJq2di|pQDZ*qnne2t7d33(2Fdhy;?;TPC?5~ZNF!99(t3TArl_q zk4URLrBE5-Ejxx$Eww6g9nG?9YR`uF@wdKj$vmU&B!H>7(xF~mQ!}a2jDH80(nqhX zke%8D7EQ)Bb1LLVAAaAO;SGP+%-mV7ZF^_1XTwrFE>Gtt8vwP9-*`hH_0!ccuWZXkz zrp?M+!o0(}YKFVPD3T&m#(&I<^z7N~-^xROc>iHw@03CR^uCwd<=1zMY{)6DzJIvC z-S<^=GgZy%Le58+RM0YddRA-IGI_ddZL`tfuqLe(BAEQu$W~}C${$aVem#}|?QS0? zJHr%8ph#*LS=H8N_owd@pO^TNyhC*S?qD1R@PX{BdN;dZ&W z7wTnsy$^$L+)_{|SO|{T7Y;<$Y9poBR2icYKtft;NF|KKxrlGS%lDprIcM?nwI}_9 zC1!q#m(a7=$lP%#0H+?8?2qV$=U{B3r6RZ)Q{xHQp_OVzG_B1op7qdLie`VhS$^tG zKALxKyLsRK#p`c>_J8);rd4)oPA;=BhNQ-Dp3=8~%b&+7 z1$fFL-TFf(gcFk;U!>71wNiU>YZV=-r&%TJ=-s3E@LH7ev45}jfyA@##5kXuLjn(H zK)8N9gRNsVQBy)~Ifbw%)ZSvwsZooTIzeRrvp*izoGZc-gF1Q=U2D$WfN5X};>M$> znhRDfMoLmFoQD^&wthPWWi`^C2HFsTcd>Wut56J z{nF9dx9c~8s|rDY!AA;fVQHO5_XgIByGTr+kx0gaTYoRa+S0bY>euf^d-dj_^qn?| z&p!SBCLs_2mDEEviBU$iNj(THOA1*++N{}%)*-dc(YX+BU;XdLvZ(Io>f8EuQNh`> z#XsFnVJQYi+SQwU)Lv%LNS__0Ik*7~pG}$$5S;?OWLz-p{<3;0{bsEUJ>|+f_m{>@ zL;;ZFqJN>mHae9iU$!KY#!CU-7Q~;IngeRD>{sK=zAdY=1v( zlwND0;!}W`q!^9nSv4oN!HPVYOV&qf#Xl;4dA0LeIQL^_Hx$M|IC3vQbypCv3MrFh zlx&~~Fl!LZQ76WThFd!D{ryHCeb4^>*_NdMfs%CGDvdjF4C9K@q`KmrT*)}aX5gaoeB8wy5`p0myn+XrF)`TN;sfibECg&cQwoh>se7Z~A_ z1Bjq=t2}^FY?clU+ngIbyyQst@BTPWBKhSc{&@Orz05y-xE*&VlbwJ4SHG;~)mU6< z7H-@(zOnDqoy*iRsIp+F9dSwixpIoeZZQiyQ|NDn>yX!RD zC_)$ucm(LRltk@9PDp{=u+KO*MDoF0XS`BcFe&kD%a)=h&iKiuR^mHD^7sfO0fdb+GR@E z7yss6t7+pfOUzDiK(1~;0)OBr-FpNTlbNK_6H#GS;UP@b`S*T_jrA<2h7%bax1O!iOS2(K zPUtzy^lsud+Nd)dbE5D!IPHFbJ`SqC>Zg7Q7<8!3^So)z{pY$t915*Gx{w~K7i zs=~bd`u!!0J;k%My7@emML@JHdZE8r{_v_?#gxU@tlX~phW-98A9ud`YD{u|&A17Jnb8HNr+&k9C$xduJCjn0 zAu$X_9gQ_QhkrC}-tqBo_%DEex_!8P`Q=+$w{#G3K^N zwlo#ro@(EJ-OHVL1kX7OCcuEj`H7^7|E?Fpj3iLH)PL;Fv2q*Yh&I)+v=P;~XI>c6 zuHbI>L3;$(Cz~W9IT$XB9M_Jh&q1@+GLyPjMT+#vHlSk1WGka6iuVg*<-4UF{KwK4 z;ojBito-@?U&cBUyqO!_b1iJh2`cJ_$$Gquo)txy&?IJn2h!{^z_d4zZmLb3=u(W} zFJog;^M6&h^7qcO33lT!KT?(%(@i+*EJ9=C==UG ziMc0P-4BZyT|zWEGB}oI60I?|Y^b#tE))WTcEfr+%zM7odkc3$!0VG$bD1fGqBhNF zS_SZ;gxH8W%wZ5y+Ps)5cv!`2&!day%U^!u8-F)HJk1)c|N8m+`**iHl?9)Ff8))I z2yWzg;M`WOoohxC0}dsRT5D_3A={XtL&zxyUYLpB_VKVfQLdoA^Yd|c3Y}W%YoB0Q z8c#G?d4Aq7CrfZcJDygEYNuMs8KA{*fljl9cA2GgX2sOmFt$Ud%Td;DzPI?3l)g_B z=zsZnOOTV%mC*Ql_aWt8Qpwtc9;6)!lhN>0IALUyt|E9TxAn*J!9MJhyOZ%vUrM!0 z75dFnzQ}o3kl8^3Lyw=$!6`P}Bduap=~YJ}jF3LCH4I~C?Y_aaxH|sq-Je!_$CWI0dz$iFj8GR&d0oc; zR`HBCt83KQd5wO4F-fWdPIAP6tXS*da0DQj zg;u_6=WnW`fat0sa&@;e6$smaVQOW%Sml8+J5=n@O3&zhw2wae5`=A@ep^7?0@$>g z0|k)r&`m(|?8;nmc7LhCHsO-QaNGOhJGN4EKdz*5`TXYo?G#8p;lZ5l74O6%-VdArY2@Wr{w3#w2uiPI5>-<%#+H8smr zj-KL^b0Q8H*k_@}2sSQO)_>hXW&NbRy}e&#K$p$2$LaUQd78@-=|E_9ZROdiGIfX0 z=_pZJucKB>XwV5tP!vG;V z4D*I_mTHq)Z(*T=;xXoY^zm1P{l0VMZ+vF}(ae?f$l9OWu}}ArMt_iPsyhLR)kd?< zG2H7UxKw^Q-Nz@c%aSaWHuk*u?{8Qxq>2V{;LU?(mC)HNs2GoC(yjA^S-clV3uWx~ z=)>=P>EGYn1E9hlCWofR;p8yv!et6o5FhA{HXKV=l7TS#h;8lQ$ICHu|L)=D)1B{o zLpnzdcj1g9vaU)#1b++$(&W-GEv!H?i`8Mts9ws}b@l$`?b;Sz#}(G)e)IVvtg#2c zCW{VItNh4INi@Alg0i9+ESC%~hcCMcvo^RSvHh>^H#0~Z$Wr}ij zR%%#eFwqc2ufdjK2{vg!<|xM-j-G7WW_m` zI(A=NexH(OZ`3f@F*z8JkC#5U1UW0{@FA2@dlRr2QVG0j0rOhDe{804HJ!VCwNr8K z#ZS-0p2&a&6YxL;-WnnR7sDQPuD@qa)!s)Zi9S0v7M`#H@Pox4_k;Y!9yatA$VPt? z#Q{XGkHkG2Vt>@u0lI<@Lqvp`)|9ihF=ifU`|=u7Uia;J*Xei;b{Es2h;) z>L)z1zaEu6c4i`qB0dPB8dnCavwG<@9H2l)wLZ2JPD>TxeyNPUC`({l)>(*m`_|ot z@GZ{4a6sp9vb1K5TqjKQ=_zxhCKZD*Q~Qjp7tOgv^M7awrWSJN%e4}+bhUa}gpkJV ztM_Zm?)3NnBq8qu^@}r5XzpnYDA(gcWowCuMxuy)G&dreQ%aYFmaH-xj*EkQDOB&d zd474mYrqXjIj#s@xdJNz zClfj!((xi^acQlY79g{rDZQ1}`-Gw@=%viQjV3oht|EWD*eHrq8l<`E;o?Zmf?P)= z_~bD4$`f+*(WY~k(y{d*ZyyD)J$IEfo*Q@=D@w%4}8S&4Sp5Kz=fAW`A zv-F}@@V#_`3kPazIC?o8Yc1pSARLubPC2%VoY|lFzKnlHkvrG%#bp%K!eh@&wqcv zDj5Ib_U;em!${q?e)0DA-@5t!?c(RQlRERodHF~Hl|h5!dI|#?h7YvprZIg&W*{<5 z>rh$1wZQNLaJIMp7SVYzG6|GjTzOngc^kjm??~D=S5i0SwM40|sF*S#q--Ngva~BL zq)p3hQHb{RXfY~f8G}fOFcpIk^1f{%`%*{@qSE`EL-&~aeER3RJlk(M=l*eT_3Kp5 zU<(VIBcc}7lKp3wk(Z?>b9P-l>1rf7Wv_g_y0zy1Sx=3cuW-=uO)MPSTgC5kF}0Yl zpliLcVr7y2;bo_it0!1*egCdWxcg>)*vy^TY7HagEQ9PWbTwuB4fco@?OU}d@ApEd z!uw8MdtKFh43+nQciJRq~o4Zbui#7ge5cc;!PhXYH@Hq8{ z#KED(qGZx;`KGp#Yl|X&-EsR%UuE*@?R!Leqq3i=^mN{ta!jeo*3Q(&?UxmAM1^ez z@69s0e|y#E`fjy+j=k1Ifr4$@zLJTVMbz@cbKWdJIZ8?WmWjc}thX88hALS(Pnq{- z;U>?e=BiV+D?eX+^!;5$t6b|0uBpZ7eMMAuqnD)Ea=~b|_TtH^_j#6;=1-grEuj6z zM{kGT5{)Msvsx~6_j-DM4$o0t_B>6iXtHM|Rd2dURG)S;ErGMEz<9ye*Ipkv`<*je zCzv_NTFZXXnQyTz#J)q+eOnixL0dalg=kg+JJb(XSLs$3s~s8|^K?;4gv)Pz*N^m^I=HzlM&cbXxSgC0i8nbEvsl?x*eEXN z)ixi1Ux%*DxNO&Fc`+)o@6+?vY32UKuj4wKhRLbuEmnK1C)ZeYC;#9I;aIcG%oPDQ z>I-AS_{(FOXAX^eV3clfy5qt4e;T^K`7K`{xe(bMm3A?-EN5@Z*5b=&yJ~tjF82*N zEpckI9bNdkL(b@ds5xeRa#rUX8jUoO)uj!Rx!ZT_trsW%W4= zJT6J5e{KJK{pBs4)~O2bj86MYE>1t=x_ZyOG~>0i6D>y^{O8II{d}zlXVf2=ROeA{ zckVc+2L(L)kB(>G-Nmu__IOW;CnX;+-0z?rZDXtCp6PYo#X_=XTm8$UN%x)mobK;+ zNT1-Jb?H%X%*Wo&7xx+_pWbo1CHL}g&x@kJJfE|!In3SBMl^Dp0$jg)W_fN=b@-eH zjr_bwImhR%6=S~u^Po^>OpetEIr=8I=;p%Ib2Uv_xrD$acxJ1$tb zKlsRl@Z7SK^SBP_M;{)FH#nnGwrK6Cr~3kK$&UNw zT4WQ~tW>CPENS9Ol;^vr`8IJE*l~GQ95oJyBg4swD{x$&XQ<%0h{qA%8q68O(MO#A z6XCxTMsssnJ;UDC&^yrIPnH2W94<%5(XOwuGLPsF4k9-q=C;EUH!_ww*Z4(fCV_?S zL<4f%h&FHWUO4MU#!zUQwB5-BO1`F_5OX&|f;%ywrdoCX&}zaRccRJd zgV!{!bCtpGti#}L#R3)ipX)7!MIK}v)jq9<_A;8?9z>fP1E)R6cuG{t;(dtoWDbIk zCkD0T_DT&No_kfhSR;^b#5RoG13!1@AnuVz)llVeW+~uD~)c#Pc_O zlSV3_ae%*QJhGm}2d~2n&LslSEfHu#b|8^cc(`VKjsBP>uFbqYsXdgIjXJ@|G~n1e zqD4hl_S0hir_vwH?NWgPjQ7SmZ#r{^Vc)a7iI{)4jHL%bjyD-bz5kP;%V}En3`6iFmdk5f_4;f7b%JXP1gR88^$qqUX zChM{9vP6~$M}oidf&fGpaI#%nu-x1T|cbQ;Sx;uBgRx* zB}*jJgyY|E)Q?Q0>hy@z@f8W~|6rIuZWh&S7GL9!_a~prm^B>jUQJ22W_O zIk1{>0hnykO_&>iTQ*K^kkp(?6Y{s9geLMW69boZs8_^*AAI#l|#7?cjQbT6_fXbi1 z@r}5Um(y6ySK5545n=*~Doh9@LaK)&D~<59NuZ+e^J{vjOdBJcq@>SV!qTMkETw z`R4^=x@&Nb#$O2)XfuNgLJ(gEdLfwe@@5wIMx005Au$B&?(SfTTeP7N-iF}3Ox+cK z1QPSj-wL4j4c6x$iuJ9&($8qX-cWRWh6|y%WecV%NmI*)VOtTM0 z4?@FnRr7`8)7SbXMYjOqDF00y7%1V?YiQY=QPNNpuZ z^K81{_GYZ!!!ce5Ob*99Ru-zX!8!uRrr$kai36c99CL;oV>Ruxw-aO|(3{)a zkBhlc5EOyZwgfe4xC;?j9>pQh8iDg3*~2hOk$7uAfSHjf4!@{Qi$iJX5*(qSu-O_k z^bjF_1tAbkh$b|L;-ZQSoLfVjk5WjZ_fyyCdDEyZe!+wTgatNZa+Z51?CSq!<(J*O> zK*V`d6d@xTb6+T8iF-6rt_1gEh!9j`@FDSGn5NWb7lZ5!mG7*M3Xz4R7|b|5f|Z;{ z3HKGW#E?l;LMMYq$K%>eh{dLS)d?7@6Ls+Nz=`jCd=cP>YcjM5j>cg{SKhGn1Ejg1pf`?~Qavssq_%lm zu$c`b;9DFS2Ju_);n3O6vS*Ryztkr1r#2ZuKV8(QF>AG@<}vX|uN5)05Z1<{+u>M0 zE#}rkSv)bK1Pn*vPT8A)d4^kxXjgdxu68ZF zO~7rn^AZE;ZpGCeKZd}&(YV_FTTxtTuG^mi_HMIm!~I2ISvwHnE_) z4X?5#Q%2I}h1)Pw8zgMQ2jT7`{SaPd+py+U@QRk+9I5w1ssTpZF^}>@n72oo_u@N9i)pp}V;XG3@*#wj_^;*Tehf8Y7WX7DHx58>xo zqon3BJJ9?$*zQ2Hc?F9nAVsx4v&r6e5THJF)%=P8RCLu(PzfTScW zG64QeLaBcQgDa*W{sD2G(XXJIjMeY!WQpa;nA>s&fj%2t;( zEgZ12;ze*W4a>8cH-R=!--Rvo(B>B~JRR@3z)BYPN=JMjY)!|Yv-AvU{ke4Pa0R?e z#}G={48(+(l7TIBEhSK~6fd$38Q6lYf{`>s0n*%;@K*-j36XIuu9%5j(X?8(Gx)T0=TNzq1Y>tOIMe35nh(2t9`ArQO^3-nuR+@DT_AFLd;Iy{Q} txg1U-pMxKketw}D;{p$Nk&y~s+bUYuhBtAOni!{27SW`xxf1-~^nV+TY@7f9 delta 53615 zcmV(&K;gfMtroDX78p=V0|XQR000O8$_9;A!$AB~+DZZd6{Ud~g%|;~7y<+}f7p$z z3Zi=?{sGt$R5>ikIfx65`1dVvZOj=9b!=903YdX9(my zN`3zOwsfV`i_gYhtv>(EW`szHf6*{c_}_bAhf&}Hgp5#nBkhQ7&M_L~tkc@4;m!Q? zWdpJSyyL*Gc#o7DqUacg_XKyV+@dT=HB56hAeq&?CwsRJHA{kVi5htdDA@w^_usks ztSlv&S}xb04y`ta#PG$(>;HdI4$T;sPpqvMpX?|@zwpAQa$`<`$e8CTe?zZYMuFio zjET5qw=NAOQW%Fu^VUj_lk$LdlBQhNa=p;eUX6uT;J}Jeu9rER>m@_6cAebZ+>ZUl zO}l z>FIa_c#o@F@ov*=h-B_?p5Vl4wlT?O0J~H!L#1GX8Um`fG6Gcgf8Arhl%-#O`PbU) zAAF8ib7{G}{A{nvU)$VniDt=RXT98vTN}!yBx!3P*rFJ;rs*AdOl~#9`aJ35^jGMc ziuGDDI7ncr&hKnBTBUGY=?o&F(74+|hy5cfC5EAv>cFz%ov2t-5i3=%6@ndm)sy(~ zx6;V3<*{cLf}^J%f1%sKzD~zr0g)3T&-9?g-aB;DWS%uzRCk#nK^5JHXc{)^%}#;E z1?-<;?f`kLQABi4LdWxf)IJ7fQ|MqsnxqbdUb|yg0W+PhIZuO(1IVRc^oym`wFBbu z%ZhmULKL&}Kx9cC>`*hhcQn%J(y(_-SM}0Eo0`B$Km7~De`S7qr-y!hQ?VvfR8~1t zil@~f5pAY1&q6&qjo}b;=%6N4gUDTCkB5GJd~Nq95Fv)(Gr3wZ8f{dkK~1B1s+$Qlo2~mC zb3_yck&_7Nf6&nVQNH|&u>nuKnUPjlOI@yjNV7i9=&9xNvSzU51Bc& z_gOsg^xXn>1a^;CdTXOq5dlWkGkK+`q7$qvX!w_ce|uF7a;)yIL{S0U%1M+Y>l5f= z-5GFr5Pw%z)awT1ad~KOe6@VMeE;nh{nk61=)nUxMC42dm>6;l%2~99;(!?Qz{Hgp zX@so|_j=kzF|4uDbHBX>4=Ys;FXZ+~SxVQxJ{Es}9WJvNJ7!g0c(BP^BZUMI?@J8b zT@s)af7O&BF-j^}RcwJn-Kw`LX$TDfb{y`%29A4=`Gf7sM^TIvJnIv20F+6?gaELK zNn+PtgCMOWr4__ce4ISycmnqJz#omfAE7^1xd;Y9tUW_>;F;7c97xHAz?oGc0+ zExh$g6-kmuL)g9?cH&-AB)@*sv&*`na`Exye=Ycf(Tp?lOz9AeLQ-cZOLvD_W^;4$ zLCHwK31tSy$*B5p_P;6DOH%QzZcS#um~Mj# ze?(67CY*D$$<&0h17S=LIH_b`lL6(k^2s6R`}(-}^y2c51i&JaFLper-r2kvITba+ z^gPxr7)7yn8Qg(=NT-Tkuwffos?ZP_QBQ}a{-@0MJ8Pfl#addfhdk(5I?Y~P1+cX3 z-#P95&Zce$M8*z==ZRbchCu71P8bcae^nT*a&ytZQnFfA4nsI8jQ9s(EIj7l{E{ns zcQKFatF;;LowBy*Jy?b>KfSuMY~DSVO}aa&IGsl}Bc%5Mz|DpZ)FO%;(OL@hZU%+> z#8yt8kX%p5cgv}GW{e#Oj~fp?iA;&*JSTyuFqiDpApvVgC<-`hnl$rLTY{E}e|i$2 ztV6WdqkXoHnmv0xzPlae`^WiTN@TZ8^z*=+P<#ai4TeZoh90d-#pVOlqhl$(7TOcQ zeK5YgSVoWbhHW4GWjQ2*F@T;mZ0n-~l~S8`uLVuOOHL}7O_hVuxo6=DtAmmwl+Pr)jpdRWwQY4>M@9?mXj*h1^Hjc?C@84y!6BM&FAB{O&Yf!>dg=( zMn-_7o$FavOHyy7#E~^E0qP6|O&*4>Y1)QYZ`&=FSD&qQ*|j-!k?D0=f12XkXJc7* zxU6TtzNj}Vo5Ejo|MzpFue|m25oAM$gp4y#(Gs>6n$_4msI;)!5Tt`PEdm6S^!f@GcH&P zTPrO?X^;VD=lXZxRw~xZi*FY)lV!x{#f3&{8PeDsz`ZkOuWlG>e=?JSg8qjIGafld zfiUneB)5oYFcPTKm`=0U6lhzUeR0iZF9S!vZ75o{lk{=*2Y3D7d7(9Lp~t{qr{ifW zBGg1Y>c%xkh_DlG=r}c^kL@+>Qad_pHi0n$9n9w7QjvnP3ySpF9p^n^w_C7_s+gqF ze*ka0!8VR&g!jxhXq|^)dz2Ki+-b-tT{X#c#i2KEGN19_)~QPOv-ARi0^VGu6F28Fo94tEwl^AChgd&ez(2F{y}tO) zDIsjYKX=^h$z}`!NqC0PgW|yPZB;vTl1@zp1bL)HmzK?&$S~dw`r_-$@xw}lvJ#bT zj9@SRO@A{aYoPl%@Ygw3d|Ip(qS1dLu?1Ce&CDW!F%4?$$G_%?mTrxe8h)Yl9@lrl zecW5dj^ZL@aR%G~pjEq(cBoV(aZ*f7EeaiA7}lgd;{No$|AqS8gRT7|ld7HwA@1>s zie7s+nm`zyVPy#AAOr((9<^$%6zO{PhC|M1A0y)QMcr33uyM|XdS1vg@O zfsVz33YLO`|3NIc|M6O6N=Ta3)I<|5IVO?W$lkhi*62{{J&0xBX?fwzjhA2zb0Imy zY01D)*FJEfj+n!x=WNg>3Sy60#a+AI1^iOfzv+iM=puqUz&?(znVHg((a+%|njn@j zp|k_JX^bo*YmVro*~&#P$k@1p8IHfpZ*qE{}y_~M5pOuAWmaW4;l=f!b(ar5;Z1oFyu zgcZay?JPD>T8UAaN7qBc%g~m=j57$Ks2Wa3-k+nn>SJX^`(*^|>qUPK-!IjatE=mO z5hcEQyyOH?TmXUcj8URavdSjTBeSytV!|QR^`td!{(9$~xe>t| zo3x!nB1GajVg{UzyF=$mqYyuLVtFfk(4wr;xj;};sq329c>n%R8NaG3DQai z0p%cWW_zI@%BXij`_|LPF3vqn6V=Xv77o+8u65Kz$&?{8kXumcK;1jF!2$moE!~Rt znPapRmdn>URLefy8wq9g@6hi)gRj~vY_Oyz;CH^oxg1e*zS zbYsFMd(r;BG44-m;=cYDPnQR@@!DZ#LT3NV(*=i-~&VP$BJB4y$sej^!WH~Md`%Xf7wn@<-(EKI(wd^UgXaHl^wzU72MBa!hOhL2;I zPVdvjxQ+@LrR!9e-Wt#pMAX*%Zs=E+OB>(^cR_nhdXkWd9sy?nOGvG22`DwKD?@f_ zby%fV=O{pk1p(tuZ56u>{MF49#L$6F`TyxCVVolhmReho+X%18y|_NNTVX`q4Pb>%VLeduRNzl;wx@ zPhPmXZtJ3&NAGe7HaTrWROT~f>9S4<6)M03Ya5kHmY`mo)Wc;o26MQldmeX3Kbw5E znnaRO{6Eo86s=qt5N6k@Ar3GdaWZf#Gcwsr=G~Y7L;?kWH{qtJ7iN+Q?Ej0SK%CJt z!n(q2U5#00ml0A&PZ>2c)p)m$Tvue5kH<1;{!LjZ{@++xz#dteNx%90*B$5~Psugl5%xrUNv@Wv&-;-2c8;>l+I_tNr zKYnv-ReTkH$x&5YF(g8W&eS{6pvll8jaqND&agoRt(6=E26Ge}DZ9n-;mwmTUOf5c zCyyR}y{sAkc3J-N%Ce<;uSIMckBOZiSoxfd5;Vh@f`>|J6qTH`w-AQXYZl~6Qz7+! zgs@fr7XOj@nL`Lbn9rksgvul|1=0{3lS|I5LerankCKW_XS2UdiInU9$awPYQTn*P zwd4A&=Z^;g$jwpAL{E0f%bzfrD%<|1Ym=mrP6HL1)h<#agQgqvAj||DwaHeazau(* z$-lLI;xLN|DxM~A&_CfpMsV7{Q@uz5Y(7J52KH(#keS%oQyluxT5_Dy(&M+Q>A|s@ z5K zas&AF@?E*UIV>saW2K;Zf6qqL73r1}J_1R9DbL2-*0f3!N(GjlmL?gT7@UJSTUMF1 zcft+8r(b;Lk*7aCj7XO2WzeW^V~E3Yj3v(c7N3IUr+3EJ->enokC)XL$C%%F_N7;k zFcShW$x)9gK{_h!TZXWHnoU#-K=Q7FXF)EU*&f_87RpJ z4Dw&(aropr$wS$tIUp)eFPZ~u>!kvJalnDb*{u(XZOrk^)n^M;@h{X%SD%;bL+JI~ zr)A-^yyd=rmub^zmS~KiejZ9k%{50AmfLXg88>!tUCcN$K?^^jql%pKAygG6i5|47fDYE9Z6+UQmKW+TrsPEB!c@W z(Nbq4>w3?qe>(uD(PJW5B+#AVZ_^O_1p-kj)dD8WgP=iaQ~_u}MeRO>0jjI-xAT2- ze_KHu^QokYEnmw23&CX|8lf~UY=hlL9pb6x0x8+WEP9N-4F}d$V1H*6FaA(ITZm0> z4$SlqN-f`%9S4Co>l6f3T*%IU#uwST%`z2RPYM}TMH&poSp)_Hu@)Fp|5ow8wopB| zxqRg11KZ$-S2x$oT=HeV)yo}oaC5k&Iw_yY%a!n|B%{q3G_W{is<;kuAXl|Q#bt}~ zpO5;}zch%v{nm>+bb3s}O_rho#CR^9s<+V?2%BMZ2CUp`Z`u%yFopYn0Kt&E>-6p? z`sJe&O-d>#r1<|(*1{;Gqa}CAp4@AZ@C1NC(My;bBkBALJLtvI4EfyEkGH1XKv*V)#NW11w>RLRnc16G9!VWSH=M`22u!Mb%(ZQ13rY%Lq*vvIw;rUT>h z<=PN`@%GL2c>C5XdPTZ_@l5U{optbKoS+10kR{9msL&bP-`H*3WCVEo$P^$+ag57q&Jg)m-EKnSg zBL=phUTPJlVQ&WIetDpP6QI+QVF#FTB;>t@|V^!8|1*L_^Cn!MdUH=DT= zC=ro!Kd4=%`S3$O{R~h`0|XQR000O8NUVicv$JAsW>Nx&a7zNWa7zQLrGME}SINW! z4x7>|myVd$WSEZ8c{mLpvxyki!Z~>2un zLliGEM3E=5!UPo7fH;DJYT43+C`;EA?pe`gwtqGP7$=p1gni^T z=)QXQr~BKR4}91sRo%OXlU7w(pf(SylGB$$rdRtc`{6n04%Cg*!;ioUf@{v=QmSK8 z)Y6I#Xn=($c#=4cE@h8pUp>_nzCFs#O0)5-eBy^&rVUFM&*SftW@7@iF`&D2smh@usQ2xoce({}e{ruJIHB?$5Qg3%f=Np!a7Acg#lJ!M39bIHvo2VG!|Rkv9irhBcf5cT zzAb;edbiv|Yolg`B&`Q%)yG_lW6ST>&0W>J%F-dYy;&}977an+%i21BNSr-GJg)EsaElv<}oYh9yf z(kC3}L#<-#KwnGxrzX)|>7%b8v%ieHeSaILn@8Rf(It*Fs9Zd4)GReZ)EX3;FboGZ zk?z*f8qB!3+^+f;YugyaN=h>|dRC=}Bi;8u9*AU3qdz%!vxZv-}W zEdIdk)@wU25CW!SV8;Jpcx&b;(VVLGfSwFcnpgv&&YoB_Q6lPmituVJsE_gRC4VHa z?&Y|7?dKtZlLQhb9w{qkofPk(^uUM^ysHaPi@p#o*Jdhzh=o)~)l?Jc0r0hP!PFuogf1_d{SMg^+V^a?me8(qR` zr<~;V!i#V2Z|B38BGRAVUHxsR6P&{_h*i=Ik`I(q$Y-Gng}@>jR)JJgs()Fq*WMT+ zSV6}{dvc72b!z$DV#0DI{rVT*+_wo^Yz73Ynjgs!#k@raq6x*2oXJX&$sEP9RuyDW zM%5=HdR~ z_GbL6EdRr`qyO{U(_rr?_kU|$;`{e2AMJB)r1NGzvVt>+9FK^@hiV;^Rx6ICa{_dN zIb2{GmTY~r*?n7UdB1>2+6NZzos>eaU!PG5sam)`*}dP-DAX}sI|_H>fi^;gXmsyB z`#=hJY*V3MJaMZoFU_c9 zqcq#SCm(g|*XM;)aeoe@06Idp;67ydG~*fBEdplr*%1x9M{jl39+-TgBRp>x28^r6 z`?c}gAKL;FyLx!PCcG!2;JfRqhrcg$3~S+W?Z4gJU#}_Hb1tzB@&c8J%>DQ!W)>Qw zR=^@H&1OTS0<&tV#KEPOI_>Fe;KY10+p*vlxh&8)pmGOapcV3E?0WR%sru|1)|`RXTEf4IFl zVO4%}Hx_#HHQM^diHUL@b1pZ3d|XFA_nopIUku7KlYbnV&8wi@8(7oiEWJ`8Z8Ve;nTzjT`qPK$ zoaus9ot-^iUXrJZ>WD$ejj5|^u(;}MEUg3~+DvX`@3Nm;s5;l95)en01UXiyx~NgL z0;NmkVt-yr(?V8FQNa^}%f!)VuURfY)DMsMD@15<_`f~p>iX&C?Y0z8$>W--wOav9 z>KWQ1r`0>rao@*C&pcSD*c@T|Jzbx*qG;FJ$}r^G&rh0-W*y zuR&6BSN#B*oYRtPuO%_O2iSzdtwxl5+L%4=@_+f3^NE8U8DEMZkgApnP-ohJ$?DOV zs)JJ{RF_Fn%`YWu7iGVzSKs>L0~^Vy`hKc^o=WY@R_xn=pKa*_C4}G*Sz4n6wGMNR zR-FQhRvM#Gr!J}$D>d!fw?k8Zd$=oW)pp$P*@jQsQo=KI(V^%S@M(Q|_%eIU2 z`bW^geIjPfb$|>c)YoJzoe>TZ`67& z=EQ_ytU?E}g=zxYJJe3zsuqWA4HQXp6n|kgnqy9`7X*!eTdMg>I`^C_f1}~#AYsIO zco;CM*E&k=bxK;4){Ru5vve6?(uWH6hW{<&IgJPZcwE(T!tO4Ork%9uug?iElmgWb zjWfBK#TZ4V53Dt-14W}+QoO?`o<*?2*k%$pYl~&K4&Lhx=Y@+Ii7~#M)f#aSRewO8 zSq&L!T2v6G8Do~I-IWUB&UJtM6F+CXU}kp<;ym)1Ybj+;$R<6(KuwFOMJ?XQ8xBv; z$i7u`eSBCkVQSSehPfhLVQiw)Tx_0y_PCuXr>H?DRy;auUH zk{#XcP&+hq3?tDt$LPJ1B#~;1Dy-ZnMoojcO_AS}$D4=i@$kF`=o{KpxqmZ7QIC%f z8t1IosCLT?BSoP`+(B!pM(z^UN~!-<+UJDr7&mXrn&mHC;`^0--td-QOCr$W2)2W$ z1pp~v1Og6@NG*ly?6b`lg}uz~w%wS;fUA|KB9q<@9^U>8LMz5s8(yL~8kw~uQ*|BD4wyUzeUcXMEKU^#?T z0joSw=5*4|bry&s)G4f1kVqUrbwEDFIkGezZg2j+5}rNBPwZUH%RE36;kcjFMu}6W zjx2Q;;$WRQ^z>5Kg6uiRW$*g-ZoGedJHGO2W7EDZu?_MGP&85Sz<-t`5~f<|(Q6x$ zvz1AmI7S#NK~(I0WZecCn?M6R1mjREXjJKqxQBC5c7oI@ z1|V~~XMxFy1KlsYyWFki?YGZ5O|g-S%3#qzInL;iSrG*}9o&dgO2+~z=%KSSN_AFg zPXe0G{QKcK!isNl(|;`iK~X!zme*!*7{+8H9Zds>dXr>s?lc$!4UsQ4WMKz;w@v~4 zThRZ_<4rH`_8D?6O_XY81bHZeoiJHAr1qInC5S#~3>R+fVu=b)L$-FT%=Gnx4AJgw z`1X1F?9RlbPKU-8rpBn&Ikmc{peolMS%_ydLjdyVuw(f#vQe|)z*=lk~O9Ci~L z$f}k{t}XYOs1ET6Zc%yI>GNCBnaBi!v;$PE zM%ia=6K$rENzGcL7iV=bfx%E@dTdv{lvB$pXIbw0GT;08&y=rn_UyqN{Q=PgM zKPXR__2wLCN*)@B_z6|$uYUsNh2A|3iVln9D%rqk0)K0%-X;@OYE|XJhu*D2TB|Rc+5ibsnamSkJVpme<}T2J6oXh=w&HyXTPIZZ24nPkvHb6!z+GQCIsZ*v zMSE8XzuWuU$M-u!mJOaj8Inj2(EVzW7Cb_{68NM@liGN;ED+hU4DE`r_52^K$eXv1 zyYZTD&VRuKfx_m82m@iXY62~hNU>IvUQK5$B864!sLoW>FIZ)6-hS==Ss1Q28{LdR zCHHiB@pYuLfML?;6?K-Jm<(fPWeZX-X{|wqZqLuRSIwC}UhPa?e|VnqxuHvB&>`+& z7{olOb;qeHnngOGbFnNXlMKV)g39Nc-}&Zp^nZ70ORNh&D~BW*f@#JPkdu@_DqeHc z%w9cFRY#c&Q(0j&oyKB$aaz9kVx5G!e!SmvP&VWNkwjn;`Ev4rQew4Vxd2$s6ygHX zBPLL5i8A{zy;%0+-BK9%<<-0KfeUlrnBkiZdjJI|u-e7#vVY2u)d$o-p3;Y#vP~H3 zIDdnsbK?R!+cesCop1lNhTE&M(&NMZ@`k;+zP)?@oapZyB@n_CE`A)5uR}8;ibAKD zAmJ6GRu)IgC~X)e_lt}F_ImEyf}fs;-l2(!7DpyMRU7w_2^iE`3#zk1X}vbCENK8E zJm&>s_wJjkAoi*e^XB&P?%jA;!n(WCuYc}$-I?coXO?6aN0gV+>7zzP8#zigw~~a= zDV-xaLBa5894)q;!w>iTzcJKH60t%6uCEp->8q=ojY<2?*3UMDax`I2^W#;VMi!D& z5V;j{XT+WkfQ14WhD;PL7lZ=kZTZ7W$g?)Mme*koD!#qonHG7n)9Bmx_vU@)-G6mK zcQRMPBPBMEhERd30MyA)tWu0Y=mTd@snJ3(w+?eR-d$fUTlCMlyq}D}F2&D>_J@6L zbglyu=@`I>2fV0ZFiTMLL8E3#bvGr3QazwM*U$*Viwaw7drP#x*b>4r5NXhnetXVt z(u7N?Rb}*6pvtV68S3oAJ(z5pL4W+S*Z%7JH%sPybEz%LnFE(`DN~kDuh%FIE zmjNDw3In^%imOQ$Cf%c(7ftPLUfjE1d9{B1a)D{>+ku#eWjLy423o z+l65NUAF4TCH8sw(_SC`^(KVM0MG*x~dwd4>|yEy)RdCdA%ySiCU)4%3C zelgybHD_MkVo{^rXVq^vbs3~!^Q1!qAEV+7)CN%;hDe~*Q>=>(jH61zb_nR zPey5L{+6mYbERg_jc;9oPPv=mwoxN?XoJO zu7Wvx6VvmKJ*NkwlF1Pz-Gr)~m=M#VFi^S$)F4nM9p;(cW^BtCS8rFg!c%Yc$NSFH z_wYQeMg}AZJtXPl!zz-rI!3KN25T)eyEOG#8y3!rin)cwefwKWD0}^ll_z{9|G2(h z8>+8ppB;1_Zn&Z;bAKLE_K7~7)oeypA_X6jSw`=Z`fQG#qTyq&9sB*{d$f@PFiLR1 z<0)Ux5^4+?C1$48%uWq^>y^dR6B{B}zaW=tcPm+BTfAc2KgSY2vqVKhoD+}JFo&0b z!bzG^8Y9ozBiroWSc-*aXs7Kv^7Gqz`>^t?wcCgL6-2i(YJdNF>BlTF;iqY6m)|bG zI|(8`T-EC*?cHc(k*m6&1K<%P)a^O}1#-Q{0 z?d=}4>GxzK)()90dW15v&00mgjasP!Qy*<$G;Eyd13HgUQsiQ%N`Lk9B@ukiY1V% zv}I#n$=X@JJ7ICZ|4{z^cvsdS;tykWygj>mX>6Vun`{<>PKU;s<^(sW+@@oT+KbfT zfCeR^4CLB|18ui(T$NQg@bN>HY2Q|zYr&wHiw5A!2TNKtqcK^>n8u2eI#TZgnJW00 z!)(lG{(q6he^~pT%WtCqBg*O&FYc@jm=Z8YW$M(ZPOL45&oLa@Br~r7QrnYS0lT|V z-#bS*2w7C{nFdE_ONX@4r*nd>*+7=CS)$oA&CY|VSHLzd@1qk%>;3vre6}W;D=+I8 zt3J(I?|vvt2Kw&mi{)#dVdoGHWEQc6L#dmx28kCF=Wak{Qp}tKCSoLXi>chRZ%3)u zv-R-m%Ndn7-`sxy^l;vn_&IZTTO_@X;KsZ_k532&vb8;gSYC{F3J6#xcyTrXe zTz=Yjy54MJUJ@iowwFgz5;83-aP&5F3W-aYyN?P5v^N0(sJ0Dx%b(iqyJhU@>hH^) z^}X^iZq{&j4Rhug^$%EgiBZZZrZ5Vkj}SGbPsQ;3 z?->5gawC5+7NM<&KU|N8tG3U!b4ZY(s32n=L76i3$+Lttj^SvdaRV;Ez@xMnnl5IS zA^Y|9D(La>@P4uB%WL5~Wx+0%r|*OX?D%l|@w?#!)%or>zW2lPyTK>|%zuw1mWoVK zdkJn-Yq~3YCdTwi!z;I0MzG`sb0FzI3Kr7qHEe|WVP+xA498}O4RaYW$D$HH2n zDWy!dY&FP+_Bt}eS}9V!mYluggo}&d?c>Akhw04|e0E&@{RA%m!Q*2s>%qKztUCjo zb7T|;JD8=wu>$mL2-2EKaDUX+a8_t(&}LL5N2m}ypVZX;(QO~Ee!ff#kGp44oPX~} z-`Wz)qne3que&1*=ba2{2OJbIVGIi%K4v+=F^U#a7E7!b`}J-tY2@wAv!0)g_6KJq zvc_@BC*j_PXpi8UYU-p>N4C=4Gf8J;je`B7R_r@j8%7uiQ8a`j(SMChO^!Z9TXycm zI%lnI4s9e;xz--Vpg%c`vBU)J54E&i$>lj{N(5YkgI-QjAcI3o9UK|y1jfoJSVl?X zDVbBstpA|xI=bsfi|Ai58`uD+a#)gKhMZydMI$Ura})rx;J4HLY{Kg&k6UW6M~>%s zs@|6>+`5-OVfn5P{(q;N@h}5K$FL*Ct^$<^RVMK;5*g5lI(Ao^tw}T`X^lT&{=W41 zoCQXcApty&WXG+Is6Nwc3B)2aQNtt$>eS#E*nu7Wq5|9AeC_5dOQHW}P4B<*l^4au zKikY38X`)d9|(&xD^n0oLFmLnb9Pckb*Y61t3w@}7qU>-%YQ1YOdV@E`NxkZvf{PO z_%duI!BOX z9GCmUiab)a4}Tn5Gmz*+rS}N2&%9J`L#4vnfO}}_QTK0I>qCIoy1xtBOCLBs=K+cyd zx%U<Vqeab`4G=%EX*X^j-?QiSK^8EjP&|~dWu1Vh(2_f} z8c~IS6n|8`4lHag0YPz5qrO{&G(V&}`w4DWFU}7hr<;bc9=T*l8)Z*%FJ8l1X<3z1 zeR^%svNrLU?IL)--4%EKYJ0hhV*>EYn;J+)szF^G#%RH9P$mKgGnsIpMi1x@IN`H zsgVQ@vs&gfhjbJnE#gDQC|Emd8O9erECahAv{d)(@pEje0*MBvzc`S@Mg>TVvU$T9 z)PH9ez!J5j07X`^hE#T0yk?b4L>ryKv=&YJOC}piPe%*gJdI-n|&K466at z5a)=Jml4_8bYH=tjS+(%>7*HrQLHJSPC72o+%Q zBP17DTFEgII#1Ki-6R-;MH|`hSiiM)xqo(jk?&n<$$#B-tDX~pQDPFHAK@GnMT;&D zDwAwh6@Y#khDfTKQ9&IfK5F*P%XI@o4zyH6JM?~8gRETBq!|xuG_*?*7=$z+2BrB$ z4SyYAfA#C%E{vg9Z{Kr3{OY>Aef8a?SAT-IzZqYA@wmz=o?hwu`=tVT*)86mGJkJ? z%1N9g;CYDLQeak@NYcAa?NqWzI(rSv=G6-{jJOo|J{5@HjQbPO(Dlx2`45|iJk60s zUcTjuQ~~L8&Qg1dwyw~!^J)2J9pqMQs&7j$54T?|S6q2mbTk$O=2!OEzM(%ONg`!_ zx$Vl8hE|VSMycSvNSQetxNA~m0DpBwvWo}(>ec$SZmbLu>*9|gUg~CAe$j6T|Xn*hw@1xL| zQzc!YmtGXerl|735zn^%Lr-Cc7oKXMg1cl>_w&JYCN-$jC^6i;WMgTNLvnIq2`bs) zOZ-}~$mR7_TXOfCe*cw^XYSjJ_tN7H12-cX0Qm8qH?e3NVI79i=+$IK<*6tmQNS#E zFM$_gy>H&Udwj2{_LYAN6Mv5Ku#P}JT#x6ZgFiYK%3=g$MkGC?;!p*n7-C?9Xx;>i zx>UgKHFWk~#z45B-+x>&Nb9)8!*V73XqoZc=*E4*m5p>uI*Y2|kp~i5YYDAmnLbFo zYfY{;tk7(U%C41LY1`{<2{3zEF1O|9CE#4hd&cYA%`ow&yg7#|Fn7^B`EY%zL zoK$A3wMx+nDwlj1KVJtdzVWN;r7rZtt5XEF{P&etpWS_PpD*X7adIXnkwg5xHD-qz zT8q&H!#Wkpq`=}xX@8xuc7*Utaf&6HTx|c*A}{_vjNE%JwiTZ+rbNg?B*j%*ACf-$ zU>P=h$MDjmOM($#a0M${C(4O+^ZrjSieG;8tBak5!NziAR8IzwXZETkaLh(3MceFD zOu!n|QE3*wn1H@}xSCg^zxw0zI@mutkAXP|m@@P@@0h!rNq?W7T9PfLX78yoM<`8C zFB(oZzdRD#w-A3gPr;mw(CHAREhWVF6y9qE&Y94f z4Y$&!w@_)MWpHz8bJ~}B_l=VD(!^Yg14G!!zxjyIV>(`~wXos?aB zBSk<}sed6*p_UpwP`7!&Qhs_^Zi8`m_iha?A9kkEpT%ah7gEHG?a(w-fU{w3*b3up z)oY!jTV*dE-p%VsESD~|~ z0W)c49%f0cL$oAIVVStyX(#Qcw`J$q-%!G`D1Rft0p>m=%Nbrr6)V+BGXP8WF`58V zH?=xuyEq`XcYT3N{$)A+S9g7_j^8YtiZ|;|`yAP@!-503a2)Vtl#<1b6T&K1@9t$p zk;Y+Ki;Ntl731BWJnPhNMyl8uD1_svYzZV!1YJO}yVKmu&+kqxjhn0cmB0RO-y(fyGvJm231kOkC(%mAWbOlvYjvtQp|ZM8 zo2;FPLVNi#Z$7y3oW(gGr6PlHS5QB!DU&^?8$#4Mi^UAIKISMvwQ_i(G)|Kzv3;MF zx8r`rA@rT^<99cdNP>ct5CsJp?B1JA8IY)wIDhVB#bPwo#G*AU#IEiIj4KG=x)DA**(lBiGWAXF8 z!*E_V3WrETI&c;&ha@5iR%%grv|_ATt@j#(reqB8ad8%I?#Il4_h*}_7Jo@W z7qLTl^!1Xu%R$`m((Q8&XO0~XMC~l|9X2jPOa5Bzp?TTJd05Ev(Gl7 zbZC_Bo-c1r)-D>Yw+yJ%sFVU$>tv`ix^%=E!+TutJKx^DUZo9}Qe;_~4nP0d5;^|u z)a}}TM{On~kR8RG@o-?$XDK?yXn(yYvrM2dO7A9~6GkytE>Eq|H{Vx}Ui}C6c4DFX zP)R=N%iqpL$aO3|zPm+PdnZ5CXFuN5Ux@%cKsz;7Ev?mb^Q==llQt@Sw>MiU{jDQs zQu;}*z)w!P?N`#Dt!Y4d?|)v1AwbncAyj6WAfpcfj^Q7B{`Z`mbMQL~I+DW6JK{WB z`qUXgHD(5;M<1MuRjbmhPB3Qki& zPX~vKQ}M7sl>S`?`+zfEA!5(Dt~M}MvvhYQI9@&~r6L42HHoT7K(3=`tun<5p{k@_ zAmSFZ`xpQ1)GqW z(|25{8_*;Osaqazbn&1L$=!#B^$CM{P8%b}93-{7C>!H;1(tv9^NpWg{pt4RRCxT| z-MD{P;h&3N4=?Jvo?{XzRfx=wphd{JQIQbTUOE*lIwCZ=8_Zw@rV1@_iybTXW$lIk zyY{jkq^q0vQgy%l`42X#pu0W%oX*o?V?$I6I56tUMYB>+$O-xf4a_4OVi4C7GJrwa zMZ@SnXqd&bzVCmc`~SprL;{GgqlCTQs2o##`IhPkk95 zc`sPC0N$@^S+?2V7rf6tS8Ri|a#K*CL-5!pMa7`C=w)UO;;yFDV3tt}Q%@ml{i$}TXW0U8HWTFtf9JU|5s#*n+QGps_tx-j4 z9jyxxc+|?M&vA|y*Z%eE≪m1ua+h7SKPBO#z);R1)ye4It_@D<*>16fm~gm3?9t z_nK%b4EW_fE(CYCJJxR#X@3;F{dxTULa;i?DE5DVxA({3R+vg{;n~{EE?tMC%;rFB zol`?OnBxE7`zL)Sa|kCmHrS{nSRE89cWHs_)teU9mU9r;9Nfl4+uo5^clF)Zmfqmi z%}GDy$K|F!BNqHT&nK-}1)0JQbAPKy>q17U)aNwvnp}DX<~9kWWaz8_Pr0+^7$5xE zci4Y&6Hu_Jaws3kCTtchLDPoPh;%C2eYV0SoPG9+vsSJb_V*ILPu@NJ z=>$#t7rDv(a~9`YTiqwk1V0|A51&$+4K1Y#bhRp3D`V8zT`Pl0*ob=Zh~13qb#YGj zc1y^9zMTqCvQ$5SJ!dPZ(X4ujf--+&6f-t(W-lJq9i9C`OMPud_1m`}MF>7& z`UVmpk_O81^4H4ACqWdSTy18eD0V?KR_Q`4LY587HdVkjPtj+1O_i!vA8BVnfR}yi55-aoh(k@$30-xAW z@4Jvs`Ewr7kO8U1C!px(|LT|Tt~xs;xxRw`AyqBD%%OY+vag^{$ZyxnUP zaNok5>nJmcq8Y#;hI&w9lNO^{!GbuXg;yF(m zsfY6cQn;2m8=Gi#9AKhSM+cpywJIsaM^+#0$q)Qw_0F*H2b-|a5FO-DR0!PY^gb6X zHKZwb8z$UPxmGDM!(-Uk#=UoIIe`yZ!@k?CO7J?J2c!z5MaML-4~*9%dMv!AEYV#KNr^_DE+&^x6x~ zR!31P)(NZR^t{|pS8F}#^YUi=X~`z{nSZXnEs$sypzv~bVfWd>s#hvC00VWFQmBCS zq7d0C_f|=s2%Fxm{9})gSEqqDTIa3a-F|WPzHqj@8Rd1kA79z$*JpoQzku8s4@p7I z!l9*+1N9=UIcWg-WJSiwLsU9VyjYgI+vUY>W1r!lpIxeHWE7_U^7R}EukhZxcjgb=Y-%F$&aj1&K+4{x(_ z32W6LaBKf{`Pqb{`kz)Hk

+4RP6Oy$ZN)&ZJ)nJVo%5R#B(Wpe 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 diff --git a/FlashGBX/res/fw_GBxCart_RW_v1_3.zip b/FlashGBX/res/fw_GBxCart_RW_v1_3.zip index 0f5b15b4117cbcb97cba7077126be5e1f95e0afc..ad95e6ae79d56730f20c82a6da81c92c83551cd4 100644 GIT binary patch delta 7659 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
xIg~2-qBwL zH2gK``;L&lyGZSJVao$V{R3nZHcqoZmsWXt2r|5&*{HhLA}2!yKDW+TxAIT48BJ`4 zHLQ1mY3VCp0;q#Je~;HO&jz3MvlSC=)ra|e5@rYy{3v7}(*NjJr)e+=9_z@@YGsVm zR_$be#xZ3g8YJt3je8cG`wO1PMwh^3qc}e3-S*Gr>|j-_2C#beoM451uPJdIa+l2y zAB`tY^mt}xB~o$VrhBh4GR*-m5Vz!@X<_Mjf8*sx>fOGWd?AG|l_&1II7^X_IuidQ zg_{0NNw<84(b1?Khxi&qlYQA=-WucVZehH2f-7Qw>r@Rx+v)U`3~IV1!mQ9n*HHls z`#2=E>-j_^fF96+g5-E*zU;s3xzCdN3|WKdvB;ed`<${@R6DD#S%f|sS!>q=JnTh- zCxQJz-Ef=8ag@PI0Q0v+dXB1oE*04ik7Br$#p;C|GyD0T_Wjiv#aqJ~3j+9aVP;aM zds#ZT$-)6^{ioO3qD9vm-x{RpT2*cc#*CPA2ov*5ft-2ofrjO%^ue#(fr=(li?y)M z?Bkl)DW=&J-Tnp(^C=Tfc(CQoPK;&SNdHmHb3T1q_sTDfVGQ3(ode|8xneK?(YI5a z_wZ@1qiqfl9^QBiWG(T9o#pPU`uGQ{FHYh!Uj_%>8)ftm^6mo5=rv0zQIdGMHYu+r zIPKgPftKJ$%>>!YTCe$}r>>jP*Uhc&0^h9+Y52GJj>& z#RFr~KI>`7w&YOV8R)8yW05>Uw&CY>>YNF@8rdZ@ps5j%Q=Hi_d7M`AUNw?meC?Wq zk=|G9Q0JmZ^QcR|`)63|)ZdRJvxi|w8q|hAUgTSAVv;REZ#tZA2l=A$LqFODDhsEJ z+G3Jj9gCIMwu=y2E!8Sx0&gIL*I;uN5MSt92RX(l5~Y#L1en$O+FBZ{Qv8^L1@H}X z#MYOcxIkS-%4IJf#W*gbZ+0Y&LBo^bK7PYu^DobCa#c(i)b6s0Xw%Yk!%XP6s#Xbu z##AIaJs!1n8EmFZly|P4Kw*@tUm#2ab88WEFj5xk^Mp0JXw}3$ApX@B>9u{XU9OHC z%pc<}yIQ1uyO?u%83`l8mQT$EB&iP`)ogj=UO=Ln3c)K}V{T94bU&F5ZDMNy9X#Xz zST%1c+0LAYYnnWYake?5suFByU>`$t&~hG-qgcQnQcpzTt0_LkAbu>{JwyAim?!9TBTOu2hkZ6S{n-DL?bPPVrOCt0YMoyuw^ePdw0T-nq=vv}h& zK3WaM*^WF&<#+WHkZPBoIcn@O-cVmU2yh&O2`=Vd13OuNl4M*5o?5gBP&)88?v$>g zV{Td-G3-WW^~chjFcJV`Md=}N!asW@d}sSB(aVWhAbD5a`sbvk);_Cu!-}l+1~bnD zJz?^v*!RRIP+3sU2Rc#R9$yXK$}a?B!z8+H;|`5^phVhskqlrf|7lDSfo2$I>4 z+}R_jpz|4JITCg}5ECvEL#Sa-1q-d!ftpSyb%U)bA&O_pHhh(9n+?Ls0|4B Kv>D?6js71N=Q7Ix delta 7657 zcmX|GbyU<(v?mu)8UYdM5M)707I7&-x{(IymX?k$-QC?O%}PowEw$285=)3kEZzI~ zy>s3>GiT!dap%tG&iULs=bn0_yz5`k1InMWv=$~R>(Xd2FdUUJFz_%iFw87HxUDTb zV-0j&nBT?R=0~(CICF5H44vJ}WGRv)jM^?BXw|qBOdG@*8pvkQZF{$_^R3H+O-@P% z*xK_|$7cX~2c1LEuX!XfnCi6B%2XRLigZCfmc;YPUby<>Ze&*HbL}=hdy(M>__Wme z?5+h=8FHT4t#c=-`BfFV16y0}4i4wm=28Y`F>iUxmu8Jz&ib`QYyLfVpz%e1y)3w< zlh@U*6s21Afg?vXB{6fShh?qm`v{0&h8b?CS=6huT3QH*Hpe-2>YXU}$d9TJx}&aj zUWfz1k5)Ko2CKn>qxS9j>>&x@+r?wn%Yr)SWTiFO3X>N!8VDVor?tEGethr1wYN5? z!qB;a=uzzkZ8#?I)mrm=6!IFtO^mCy{Iq=M)MwzxpNh&t+^ue+KxVY~Ex{Sib-8_57+;Pya4}gtf@4V!oh8P0G8tF{z{!$p+jwo1V;?{9 zcdm3?P=gcvCpIrS`{I1A8YBR`yEiJd;NpgQG9T`@jvWrh{S@=%*w-t#Pbp~?q2yq5 zwb)h$%f{q21{$D*Hr8@uq3O5O=2pbA+Ge=lR*J6{QFAj+ zq_El_FI)HMMNj1HPC4A+%;cBT_-1?{_Hz;E^>u$_?+p-eVe)J*!s;0zuWZ#i6C`E6 z^Jcj@e{z_C>F+U2(ctHIOp^{y$L7pPD^lJg&9G6oPYV)u+c`Hu3~02K1A0%L3Ftesu#5&at_AlpEwBJLF6^CW1lKn>WXW6!o^)qI)4Uu% zBzKZy7bs<+G%CAdIRPu;-6JeAPu=o7%OGKD!{Tfro_Rz(H8+3F4%E9}B;@z*G!Q1O z65K$svIJpkUZ=KG8%zo!SVc}kf!Z2tkvo3Toc@#T7`o+ylFt)Z#>p zN+Zxd58rsjb27~{R0X&_nhgqwKQ7^WUIu;D=N=CgMzRh z_EW0@%gzTpF->CZ91?h;3PSSdGox@fqJVtUxPr$tf3u4Lt^`U=8+u!FEEF_8aQAQ> zdv~Wd7^RB>!vxm~461l6$<}!?n7p1lhL{{YyWC^JidW(hA$=dUE(Mv;d3k;%A25-m zYAVV9EPMm@KIbItb2W3GO~*RkK-?7lbxbx>iB~SqFz01oSJ%C>+IdU(;h7iW3Bc&0 zJ{MWJM=a@K!Nq9^DPtT8{ znDoKjJJmVt6=hNl2yNVrH4TisXrSmzIA?ES^T|hNnT>^)8PE{Y(trPGi=4;0NF=e? zsZC{;>w>SKwK?EEtff)D55!IZEbPmr?#yI}C&O!|lrhLK=a`5)4i{%C9T$Fl`3`u* zN7e}36;??+%^+O(R%;b7EDD1Rj_o5oJE3-8%OM>86OhFtN94USVWqtHM>U${M z-fowEir043{Al91@m4bdgRciv-4WII*>{{^>#Kq-#9@OvMXoV&_(|IC?=Q|I%^@cQ zq~nvTcnE?WQs`G)5F9%`bnH?oqXXM`>H|Hfh)JqA*P8 z*8#$~xPfEbUX`a+ci&am3%qNwwUNQib8XT7j9dRUry~nXxAPsp_80+wnlxtXi;`-A za&kxG0s5lX(JD&cH2^4nZ%YgwYwulk9iot1o4bW>*xagi)7IshNF^hODt6AGiKXz!+4?tjE(18R&Qzb3%_@Bg7 z>l$cL(J1lI!k3Qk(uZ$)C<76~$eA|{4ZeE^eK&;-bEEwH5`OX;%BEk=_Q)oB`nJa` z$Z_3GeP-(h^WNjr&XW$1LZ@(nA{0Gn);QZ3nZwG5oh=2>PU`Hw%(0C-FgO_d$qKhKC7U^l=n@SzwU2tWncn-WsOnk&U;DF0>JI6zu zwGEB&0g@I?M)}*|)~c*Jm+t6yQN#w|Aaz;Ua03m9TGC*V*3wZ^JstB1i_P2E?^u;N z*Zf`8fYGk>Y*5@=R)v1~w~RQSvFK{H1E>X!otY~~LIPNKOCRrbA>lV!#xDjEDKiXQ z?Mv@4X(lbxeCr89ie35czxk$Zsmy)I)FmLlXt``VSDn&M0~;LERR$2{b$|4E#7#K~ zZh6%YOC@mJbPZ+--&}j&LUEHe*-@I%g@k2X0QSztqouyJ>1hWwQE7YW(=9YLTB<81 zEAg7*Q~y$8{-$oP6&wp_-q^V^Fxe!rj1MRHs!~x{zd3W9W3B#Um8i&?=O?LkqlKw> zP?cn}QQHzm62mE~iPaWX5Y|uz6G#6jD97rO%p6ymxs7&bW=$*sSGKa+U2zBn4wJMo z143&0+Ev2i)ylAnG;PKyrZ(~64ni|GJh}v+m72V&iD!ROgIg~C~;P? zn!~PCOPKeZ3|*pLpH^H!QDd5)D9G@Py0PY@@W`&~`{TSN=1^&;l_^F!KFDU2ppH5s zUoZ-6-{@Q4Ci4s(XR+WIJRCd@Mx6))&o1TuX*t`kx9FS-H&hI`aosagz6rIzpf^>6 zA-L{HqSb5Oi-N0P!OKw6KJm%M=It5!vXe*4BTHpHv_qa&h5VxPDqfIFn!^5*tR$cA zkSTEGRVX5@sp+2H*Al9ysj;Z4e?e2%+2CN?aNXkhWpPZs?uIe@_4(vXr58RGVnXalANitA(BmpxsDPt%C+CcGe36wK0IPFi{$!}g!lR) zLhVf{LQE>A4^;OsF4Z@zG7Spdnpd*Z(d6#w6~6kb9C50(Te<0TxAA=|Skir()}xRi zTHvPKdQg3LeZV2+{wtTuXka1+ijYd8&N!Emxr5@XMKaWnf?Y#@{2UMnU%UF`F)*;9 z(Q5|}SWL5`05?>Z(z!1q;8rJF`7yoCh_Jc6UYN2>Uj~LIMoWXsti9#NTPFx*hPxw( zk6*NR=M$^Y2z~XR(lz=sD$b~P4%;JX5wYjt?G^SKarX}srcDgGBDz`Fh~sxgIHHgN zBxY<{5x`K|+o+`jXc?4om_?%Bk}BxKGBf@3=9Vry#7fY$@kH;&~Qa4ZX?eR?X?lOrTWxEnY zVYig0(kA7*YcWg*eM=6XY+s|Rd-bS&`8J^R=i&EX zSSR$obfX$tZ)t_do}x?Y)4Z#%B}`V6zf`r>p36=RJwHpv<1y=McSa_{x_q#z$X-YF zrMzKoy-#am?T;Xdp}3fX))-)#OxTF{z{UlJ=Cte61eF=+&C`DwPtEU;^!-|UU)n7b zJGN*A;4y-Ra+i~-HV&C$L)sb5_N^Kr_gwp)-zpCrptTu|P;P^l~ZoOsE)Y(n@g zk5C#15Z2j<_0iEEOxKS?Qn(AIt`SWcduPz6tg4SoeH+xO+AwU+>*2aGCYf1B^)+m2 zt#QNqtTAAhUfoBxnD*O*W3-M7hxY;BUbYqi*H4`*lgLac52%0E*B{9i4`(qoS+OU$ zPda@3s_r5~+PWn*)ta4h0&Z!jjjHJbw@jo>d|sAI!gqM?OuPKCrj?onX5r8{#zel! zADFu4F7{@SUw?AptMbnY9LuhAp-$U*5ng=`)1{>2dHL6AM+Y{GcNKlh_xsY>UUxE> zfK`zHlHSTq4USAoldyX$-jf{%C#u_{t1sdz&iMZE>-_rIByY~kooc@Z6X&JUh&|eA zcdPHG30xSj7Q-)J8e6|kn)&XuC`A4_TX(}Mbw;H(Q}Q9DWaD^TexSP=T9iuuGQwwv zE6JI_f7x8Xs`M&Z+%vfjeDG)OnB=iyGJsPvXVzm#c*VW9c1@3)qtLA5#)G;|9)O5| z-VHkfJay5z`Ei3ivYm)-%2CawS4~8DEaK0dKt$Q`u2ypNZ_}RLFEAYik94e zdxvn+GA>IVZAO%&SDJmtFMN5*>{mJY5>}x3XeWubrw;}YkCb0iJ+{!=s48lRxmc(Ydpsa=bzw*oTu~RVw8Wd} zS)G@ebwV=1{pL7A1yY!E!r|xKEyjR#I!w8qU{L+OSn`pLo7xT`q7hw-A2f|4(K1~W zhI-K7X_U<6SD3m+3cGGd@IrEoK~c8S(%1Qtj80yrgDNmjnG3l#?ay6cFg)5S=a)~&0+r=zHOkC=cU2W%o{nwZk>%6j zSkbs4V#C}HbT!~0tfMS#ayQ&x$HN<x+_vkjKugc{SD^44gm{$l zVuT-m#W8QhSRdv9X+8Ren7a5kyfhtcQ~v$i;iw#%e`zT{^y8AF>p{*DUmyD&!X>K8 zAD{^3TFBf}F|l2wMD$#Vq$o{yQ}NgUdXYXQnMfM8cBRyz64~f76+=_!@Bin7 zT4$mF4-r0@ldrUrb*=9cECMg8n??h-^fr~0xj7H$XzP957d|)@lmPxJkS)7uS zr2h4JKw0j?!!bVbpQ&p>ME8SG$T;Q4vB)r((g27UMzaSCo9=l>K63j?>mApBeUzzk zeZo5JA-Ro;k$vVt$svZ=YFfw^*&mFpVHKh@0Euvcv3Y;}+bYFUN}z1K^x;WuS;v1)U-{fx)hJ-_1lR{<&GN{j`6FBe{xsCbM>BTPRSJjQ z{V$Gl7AQJSYR;B%@LdscR~Kk=no*9&{!Pq-ADbIpp4>QGi?j>Z=8lyw%ubLzfS1p5 z!6LUu^Kgb7J#gDVbI)~FaDr1krX-7Y-NOwu!FT8TdxgV3##xzozq4GSUY}pwK`E{G zHepqli1Q91m>@E`Et6M^{NM_hU!)7{pz=idUt6_$Etz4Z2Nyxo^4u`iRzXSoG*W^f2q3O5KBxp_TeJzBVH-`3bGp+ z&pU^oxB6m2j4`C4_MS1MzJ#r*h2(wQdB+WvzA<{e=V$T@d#L+^9ob@q0pB3MSqDzy z@1+0-ff>0D381lQOn26|>9vpPfzEY4z;C3MwKB2hS_a$ujD)#m$-BCzDOGf4n;uZz zyAs;Y9R1OHDm#VFxtR4YN>^cj^>i1wkNuSN$9`M;7V3W-3=Q}id_~mu(R*7xO;oqt zs!h{BPvxpS*)QKP(4l&CXNb_a@)f0CT|XemeEzyIJLazaMYXW!@#|*iEo#?uUTo>g z*FS!{NVz8`u2f_v-0!5$%RYH)rhg;-7d9VrA#$kx-gIIr#uDy2GyRNF%0a{_xFF5T z)vkkOlSEn?pk3B?@oxIIri=akrej~{TXR4ZZAVc)#N&<`++fug5MJ7@opHZm=Zyk% zC-hN$9SN0;b%D2QIeqT$;CA1CjH{XDo}QFbTP1fU54Hxba8V1SH<&7)G+#^q_U?_a zd}T!tG3D+P>>Ax|7(i2e1t&ipNELGW*gPMmW0T)EkHz($&9TG^=7v3H()Hlon>9z4 zdgIQAFR+o3>Ar^#0m!kHzN8${52R~68{fU6CXE~N;hxD4waqm$CAoC?`FN*CB>(T$ z5cTFue4W&QuWuAeOVPS`3x^UZ?H|U>k)3@p3Vsiqrtn(jUhj_LWii{qibAy&>yusJ z(-ybBs7%**Nsb>^tHt_a4D4gj7SHotT9#qv50Z#fTXA-!nY5C0*RC5E7r@;qcY!|x zC*qLQZB-rxzC&dC{E>^2e}~h|pQG(AT3(P3 zDg`zan=5hcvGe=xNI6BvRR(mv2OP7vR27gd-K=-;f0wFN|7Z zxQ!1p1(Kw3XU{dd&K#Cm zu$yt%0`HurK?=9N`JvTgkn!#UzcFDe z8L@&y)wUU=(_CQS%d&6KB={^=u=tx(=eXi|L*n9>qf@chW1GAhqWo89ciR^Hhj@Dj zewMw)!=#XOnCcxX4#%KT-?;Get{4;fM$XjdT+&+6V(b#JhJk@XN%X(DlXe|uTQ?W zDueRW5iB#grs3oc&p6DwD9}9+OxeghN0XZ8L^?+Vj;P|dhX454iI%u-4PVvZzA*;5 zPJ-h4xogR9RkQXUZ8(&At{u~_3vttcuPVb0O^F4`T8r&7P7~Kqa z@mJMtw%=KcePOTf_7H!J9FNvOG^xL`1x~H^?BKSKOVHE}I9unWIpx_ zV{!4V@nKmszv98?Tg_ymgPvbJiakE&Sq>1eaFyMI%4$B>QEH>3r?TNL3ZK6~4#NI{ zmk6Pi6<2FYpL8%~{P%F)j#>hXGIUGCV`?dAVpRofoTm>}yhj-S)%IX)>_-)t7#JH^ z7#N@j=|gGH#=*u<9qzEiL(qvgEOzt@gV*+5Eaa&T=8yzT(oHvfpXX_??PRp7E+6~b zN;KPQ(reEB5{YQSPUs>V{nhR8sz=t}To&IK@gueuR?#>Rr}*E@fJjSI$lnya3D14- z@=K>lL3z-}guz{KR9%rk_KRIiBdimunl{5{emA3&u<%?WnuNiCNme~XM^iOvS}nHC zYUidcr+uWV{Ns{Yqf?EZbh2!WH?Oz~c^l0ru%q!9b!`eHrp7^X&%0YUGw+ten{8g4 zJ+@nL3hV|ofRk+Ef!zQY^Ppq~aR%X~MURvd36tfBcUw^OC!`62iTEanUQStv6kn~L zdT-0*b-nuxN+!{K>}rm3lH;g=zHQj6|J7@{G9LX-&5Ncrc$9D8*UExIm-<0F;1vdxvZ&KF5yFKkkbFnL)x_^5#Q@P*VlyTAM$ek~J ze?`E#{jE9gteUmuNx6S|#~5ljHy$bZqx%Boca9RDVvj5~7k%4&c`JTj90_=hB4^4s zuBUx$o7BL6KuQ1XgyW~d`pip3 install "FlashGBX[qt5]"` -* If installation fails, use this command instead:
`pip3 install "FlashGBX[qt6]"` +3. Install FlashGBX with this command:
`pip3 install "FlashGBX[qt6]"` +* If installation fails, use this command instead:
`pip3 install "FlashGBX[qt5]"` * If installation still fails, you can install the minimal version (command line interface) with this command:
`pip3 install FlashGBX` * Pre-made Linux packages and instructions for select distributions are available [here](https://github.com/JJ-Fox/FlashGBX-Linux-builds/releases/latest). diff --git a/run.py b/run.py index 03875a3..643e4d8 100644 --- a/run.py +++ b/run.py @@ -1,3 +1,7 @@ +# -*- coding: utf-8 -*- +# FlashGBX +# Author: Lesserkuma (github.com/lesserkuma) + # Note: This file runs FlashGBX in portable mode. from FlashGBX import FlashGBX diff --git a/setup.py b/setup.py index 20a03c8..647d604 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,14 @@ +# -*- coding: utf-8 -*- +# FlashGBX +# Author: Lesserkuma (github.com/lesserkuma) + import setuptools with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() setuptools.setup( name="FlashGBX", - version="3.27", + version="3.28", author="Lesserkuma", description="Reads and writes Game Boy and Game Boy Advance cartridge data using the GBxCart RW by insideGadgets", url="https://github.com/lesserkuma/FlashGBX",