diff --git a/.github/workflows/build-app-wxpython.yml b/.github/workflows/build-app-wxpython.yml index 1b33575ae..f795ef896 100644 --- a/.github/workflows/build-app-wxpython.yml +++ b/.github/workflows/build-app-wxpython.yml @@ -38,7 +38,7 @@ jobs: # p12-password: ${{ secrets.MAC_NOTARIZATION_PASSWORD }} - name: Codesign Binary - run: 'codesign -s "${{ env.MAC_CODESIGN_IDENTITY }}" -v --force --deep --timestamp --entitlements ./payloads/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' + run: 'codesign -s "${{ env.MAC_CODESIGN_IDENTITY }}" -v --force --deep --timestamp --entitlements ./ci_tooling/entitlements/entitlements.plist -o runtime "dist/OpenCore-Patcher.app"' - name: Package Binary run: cd dist; ditto -c -k --sequesterRsrc --keepParent OpenCore-Patcher.app ../OpenCore-Patcher-wxPython.app.zip @@ -47,7 +47,7 @@ jobs: run: xcrun notarytool submit OpenCore-Patcher-wxPython.app.zip --apple-id "${{ env.MAC_NOTARIZATION_USERNAME }}" --password "${{ env.MAC_NOTARIZATION_PASSWORD }}" --team-id "${{ env.MAC_NOTARIZATION_TEAM_ID }}" - name: Generate support package - run: /usr/local/bin/packagesbuild ./payloads/InstallPackage/AutoPkg-Assets-Setup.pkgproj + run: /usr/local/bin/packagesbuild ./ci_tooling/autopkg/AutoPkg-Assets-Setup.pkgproj - name: Prepare App for Upload run: mv ./OpenCore-Patcher-wxPython.app.zip ./OpenCore-Patcher-GUI.app.zip diff --git a/Build-Binary.command b/Build-Binary.command index 6a451da5b..eb9953d3e 100755 --- a/Build-Binary.command +++ b/Build-Binary.command @@ -1,7 +1,7 @@ #!/usr/bin/env python3 - -# Generate stand alone application for OpenCore-Patcher -# Copyright (C) 2022-2023 - Mykola Grymalyuk +""" +Build-Binary.command: Generate stand alone application for OpenCore-Patcher +""" import os import sys @@ -12,7 +12,7 @@ import subprocess from pathlib import Path -from resources import constants +from opencore_legacy_patcher import constants class CreateBinary: @@ -229,7 +229,6 @@ class CreateBinary: "Config", "Drivers", "Icon", - "InstallPackage", "Kexts", "OpenCore", "Tools", @@ -237,10 +236,7 @@ class CreateBinary: ] whitelist_files = [ - "entitlements.plist", - "launcher.sh", - "OC-Patcher-TUI.icns", - "OC-Patcher.icns", + ] diff --git a/CHANGELOG.md b/CHANGELOG.md index ef966b69d..858e34ed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # OpenCore Legacy Patcher changelog ## 1.5.0 +- Restructure project directories + - Python: + - Move logic into `opencore_legacy_patcher` directory + - Use relative imports for local libraries + - Documentation: + - Move images to `docs/images` + - Payloads: + - Remove redundant/unused files bundled in payloads.dmg ## 1.4.3 - Update non-Metal Binaries for macOS Sonoma: diff --git a/OpenCore-Patcher-GUI.command b/OpenCore-Patcher-GUI.command index ad809085a..8cc77a79f 100755 --- a/OpenCore-Patcher-GUI.command +++ b/OpenCore-Patcher-GUI.command @@ -1,6 +1,9 @@ #!/usr/bin/env python3 -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk -from resources import main +""" +PyInstaller Entry Point +""" + +from opencore_legacy_patcher import main if __name__ == '__main__': - main.OpenCoreLegacyPatcher() \ No newline at end of file + main() \ No newline at end of file diff --git a/OpenCore-Patcher-GUI.spec b/OpenCore-Patcher-GUI.spec index 257f4feb6..c3d67bf6d 100644 --- a/OpenCore-Patcher-GUI.spec +++ b/OpenCore-Patcher-GUI.spec @@ -13,7 +13,7 @@ from PyInstaller.building.build_main import Analysis sys.path.append(os.path.abspath(os.getcwd())) -from resources import constants +from opencore_legacy_patcher import constants block_cipher = None @@ -70,7 +70,7 @@ coll = COLLECT(exe, app = BUNDLE(coll, name='OpenCore-Patcher.app', - icon="payloads/OC-Patcher.icns", + icon="payloads/Icon/AppIcons/OC-Patcher.icns", bundle_identifier="com.dortania.opencore-legacy-patcher", info_plist={ "CFBundleName": "OpenCore Legacy Patcher", diff --git a/README.md b/README.md index bf8145209..f53dfe3e4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- OpenCore Patcher Logo + OpenCore Patcher Logo

OpenCore Legacy Patcher

diff --git a/payloads/InstallPackage/AutoPkg-Assets-Setup.pkgproj b/ci_tooling/autopkg/AutoPkg-Assets-Setup.pkgproj similarity index 99% rename from payloads/InstallPackage/AutoPkg-Assets-Setup.pkgproj rename to ci_tooling/autopkg/AutoPkg-Assets-Setup.pkgproj index f2dd2f126..4f8cb3b41 100644 --- a/payloads/InstallPackage/AutoPkg-Assets-Setup.pkgproj +++ b/ci_tooling/autopkg/AutoPkg-Assets-Setup.pkgproj @@ -235,7 +235,7 @@ GID 0 PATH - ../Launch Services/com.dortania.opencore-legacy-patcher.auto-patch.plist + ../../payloads/Launch Services/com.dortania.opencore-legacy-patcher.auto-patch.plist PATH_TYPE 1 PERMISSIONS diff --git a/payloads/InstallPackage/intro.txt b/ci_tooling/autopkg/intro.txt similarity index 100% rename from payloads/InstallPackage/intro.txt rename to ci_tooling/autopkg/intro.txt diff --git a/payloads/InstallPackage/postinstall.sh b/ci_tooling/autopkg/postinstall.sh similarity index 100% rename from payloads/InstallPackage/postinstall.sh rename to ci_tooling/autopkg/postinstall.sh diff --git a/payloads/InstallPackage/preinstall.sh b/ci_tooling/autopkg/preinstall.sh similarity index 100% rename from payloads/InstallPackage/preinstall.sh rename to ci_tooling/autopkg/preinstall.sh diff --git a/payloads/entitlements.plist b/ci_tooling/entitlements/entitlements.plist similarity index 100% rename from payloads/entitlements.plist rename to ci_tooling/entitlements/entitlements.plist diff --git a/data/amfi_data.py b/data/amfi_data.py deleted file mode 100644 index 1dbcf2a5a..000000000 --- a/data/amfi_data.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2022, Mykola Grymalyuk - -# Within AppleMobileFileIntegrity.kext, Apple has a bitmask-based boot-arg (ex. amfi=128) -# Below information is from reversed values in 13.0 Beta 6's AppleMobileFileIntegrity.kext -# Currently only 'amfi=3' has been used by Apple publicly -# - 0x3 used in 11.0.1 dyld source: -# - https://github.com/apple-oss-distributions/dyld/blob/5c9192436bb195e7a8fe61f22a229ee3d30d8222/testing/test-cases/kernel-hello-world.dtest/main.c#L2 - -import enum - -class AppleMobileFileIntegrity(enum.IntEnum): - # Names set are solely for readability - # Internal names are unknown - AMFI_ALLOW_TASK_FOR_PID: int = 0x1 # Allow Task for PID (alt. amfi_unrestrict_task_for_pid=0x1) - AMFI_ALLOW_INVALID_SIGNATURE: int = 0x2 # Reduce sig enforcement (alt. amfi_allow_any_signature=0x1) - AMFI_LV_ENFORCE_THIRD_PARTY: int = 0x4 # Don't mark external binaries as platform binaries - AMFI_UNKNOWN_1: int = 0x8 - AMFI_UNKNOWN_2: int = 0x10 - AMFI_UNKNOWN_3: int = 0x20 - AMFI_UNKNOWN_4: int = 0x40 - AMFI_ALLOW_EVERYTHING: int = 0x80 # Disable sig enforcement and Library Validation (alt. amfi_get_out_of_my_way=0x1) - - -# Internally within AMFI.kext, Apple references 0x2 and 0x80 as both 'Disable signature enforcement' -# However 0x80 is a higher privilege than 0x2, and breaks TCC support in OS (ex. Camera, Microphone, etc prompts) - -# Supported boot-args within AMFI.kext, last compared against 13.0 Beta 6 -# -# Within _initializeAppleMobileFileIntegrity(): -# - amfi_unrestrict_task_for_pid=0x1 -# - amfi_dev_mode_policy=0x1 -# - amfi_allow_any_signature=0x1 -# - amfi_get_out_of_my_way=0x1 -# - amfi_unrestricted_local_signing=0x1 -# - pmap_cs_unrestricted_local_signing=0x1 -# - amfi_ready_to_roll=0x1 -# - cs_enforcement_disable=0x1 -# -# Within AMFIInitializeLocalSigningPublicKey(): -# - -restore -# -# Within macOSPolicyConfigurationInit(): -# - amfi_force_policy=0x1 -# - amfi_block_unsigned_code=0x1 -# - amfi_force_cs_kill=0x1 -# - amfi_hsp_disable=0x1 -# - amfi_hsp_logging=0x1 -# - amfi_allow_bni_as_platform=0x1 -# - amfi_allow_non_platform=0x1 -# - amfi_prevent_old_entitled_platform_binaries=0x1 -# - amfi_allow_only_tc=0x1 -# - amfi_allow_only_tc_override=0x1 -# -# Within configurationSettingsInit() -# - amfi_enforce_launch_constraints=0x1 -# - amfi_allow_3p_launch_constraints=0x1 -# - BATS_TESTPLAN_ID="Custom Team ID" \ No newline at end of file diff --git a/docs/ACCEL.md b/docs/ACCEL.md index 96fd37da5..14a1a669f 100644 --- a/docs/ACCEL.md +++ b/docs/ACCEL.md @@ -46,7 +46,7 @@ Metal is Apple's in-house graphics API that acts as a replacement for OpenGL/Ope By default with the non-Metal acceleration patches, many background blur menus may act distorted when moving a cursor over it. With 0.4.1 and newer, users can enable a new Beta Blur feature to try and resolve the issue: -![](../images/OCLP-GUI-Settings-Beta-Blur.png) +![](./images/OCLP-GUI-Settings-Beta-Blur.png) Do note that enabling beta blurs can be more demanding on slower hardware ## Downloading older non-Metal Apps @@ -190,7 +190,7 @@ A somewhat strange issue on Intel HD3000-based Macs, on 3rd party displays somet | Default Color Profile | Display/Display P3 Profile | | :--- | :--- | -| ![](../images/HD3000-Default-Colors.png) | ![](../images/HD3000-Display-Colors.png) | +| ![](./images/HD3000-Default-Colors.png) | ![](./images/HD3000-Display-Colors.png) | ## Cannot Pair Bluetooth Devices diff --git a/docs/BOOT.md b/docs/BOOT.md index f91a95719..4292dd9b8 100644 --- a/docs/BOOT.md +++ b/docs/BOOT.md @@ -6,7 +6,7 @@ Reboot the machine while holding `Option` to select the EFI Boot entry with the * This will be the Mac Boot Picker -![](../images/efi-boot.png) +![](./images/efi-boot.png) ::: details Note for Mac Pros/Xserves/iMacs with unflashed GPUs @@ -27,7 +27,7 @@ Now you'll want to get a list of drive identifiers. To do so, run the following diskutil list ``` The command should produce a list of drives installed in your system: -![](../images/Unflashed-Boot-1.png) +![](./images/Unflashed-Boot-1.png) Keep track of the drive with the OCLP install. You will need the drive identifer for later. @@ -37,7 +37,7 @@ Run the following command (Replace X with the drive number): ```sh diskutil mount diskXs1 ``` -![](../images/Unflashed-Boot-2.png) +![](./images/Unflashed-Boot-2.png) If everything is correct, the EFI partion should be mounted. Now you'll want to use the `bless` command to set the default boot device: @@ -45,7 +45,7 @@ Now you'll want to use the `bless` command to set the default boot device: bless --mount /Volumes/EFI --setBoot --file /Volumes/EFI/System/Library/CoreServices/boot.efi ``` Once the command is run, it should produce no output. -![](../images/Unflashed-Boot-3.png) +![](./images/Unflashed-Boot-3.png) If the command produces an output, ensure that you've typed it in correctly. @@ -56,7 +56,7 @@ Now that you've loaded OpenCore, "select Install macOS": * This will be the OpenCore Picker -![](../images/oc-boot.png) +![](./images/oc-boot.png) You will soon reach the installer screen! If you enabled verbose mode when building OCLP, a lot of text will run across the screen. From there, it's just like any normal macOS install. For an example of how the boot process looks, see the following video: @@ -64,7 +64,7 @@ You will soon reach the installer screen! If you enabled verbose mode when build If your Mac is looping back into the beginning of the setup after the first reboot, turn it off, start it again and hold `Option`. This time, select the option with a grey hard disk icon, it can say "macOS Installer" or the name you gave the disk during the installer process. Keep repeating this step after every reboot if necessary. -![](../images/oclp-stuck-firstreboot.png) +![](./images/oclp-stuck-firstreboot.png) ::: warning diff --git a/docs/BUILD.md b/docs/BUILD.md index 7a550e745..ead7c7832 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -8,7 +8,7 @@ If you haven't downloaded OpenCore Patcher yet, do so now: Next, run the `OpenCore-Patcher.app`: -![](../images/OCLP-GUI-Main-Menu.png) +![](./images/OCLP-GUI-Main-Menu.png) ::: warning OpenCore configurations are hardware specific. @@ -19,7 +19,7 @@ Here we'll select Build and Install OpenCore and start building: | Start Building | Finished Building | | :--- | :--- | -| ![](../images/OCLP-GUI-Build-Start.png) | ![OCLP GUI Build Finished](../images/OCLP-GUI-Build-Finished.png) | +| ![](./images/OCLP-GUI-Build-Start.png) | ![OCLP GUI Build Finished](./images/OCLP-GUI-Build-Finished.png) | Once it finishes building, you'll want to select the Install OpenCore button: @@ -28,6 +28,6 @@ Once it finishes building, you'll want to select the Install OpenCore button: | Select Drive | Select Partition | | :--- | :--- | -| ![](../images/OCLP-GUI-EFI-Select-Disk.png) | ![](../images/OCLP-GUI-EFI-Select-Partition.png) | +| ![](./images/OCLP-GUI-EFI-Select-Disk.png) | ![](./images/OCLP-GUI-EFI-Select-Partition.png) | # Once finished, head to [Booting OpenCore and macOS](./BOOT.md) diff --git a/docs/DEBUG.md b/docs/DEBUG.md index 69280c8a8..793bc0630 100644 --- a/docs/DEBUG.md +++ b/docs/DEBUG.md @@ -10,7 +10,7 @@ The easiest way to debug yourself is via Patcher Settings. Here there are many d * "Enable OpenCore DEBUG" * "Enable Kext DEBUG" -![](../images/ocdebugimage.png) +![](./images/ocdebugimage.png) When you've enabled these 3 options, rebuild OpenCore and install to your drive. This will provide much greater debug information as well as write logs to the EFI Partition. @@ -18,11 +18,11 @@ When you've enabled these 3 options, rebuild OpenCore and install to your drive. With "Enable OpenCore DEBUG" set, on every boot there will be a .txt file generated on the EFI Partition. To grab these logs, [download and run MountEFI](https://github.com/corpnewt/MountEFI): -![](../images/mountefi.png) +![](./images/mountefi.png) Once you've mounted the EFI Partition of the drive you have macOS on, you should see some nice logs: -![](../images/logs-efi.png) +![](./images/logs-efi.png) ## Obtaining Kernel logs from macOS diff --git a/docs/HOW.md b/docs/HOW.md index 44045313e..c0a3f84a5 100644 --- a/docs/HOW.md +++ b/docs/HOW.md @@ -6,4 +6,4 @@ OpenCore Legacy Patcher itself is actually quite a "dumb" program. It essentiall To understand a bit more of how OpenCore is able to revive older Macs in such a native-like way, we need to go over *how* OpenCore works with your Mac: -![](../images/oc-explained.png) +![](./images/oc-explained.png) diff --git a/docs/ICNS.md b/docs/ICNS.md index 826d6ae01..81af41961 100644 --- a/docs/ICNS.md +++ b/docs/ICNS.md @@ -27,12 +27,12 @@ To generate custom OpenCore icons, you'll need the following: * ResetNVRAM — Reset NVRAM system action or tool (128x128). * Shell — Entry with UEFI Shell name for e.g. OpenShell (128x128). * Tool — Any other tool (128x128). - + Note, for each image we recommend having one of double the size. This ensures that icons are scaled correctly since .icns support dedicated images depending on HiDPI or not. Once you have a custom image you want to use(for example, as a background), download the [latest release of OpenCorePkg](https://github.com/acidanthera/OpenCorePkg/releases) and enter the `Utilities/icnspack/` folder: -![](../images/icnspack-folder.png) +![](./images/icnspack-folder.png) Now `cd` to this folder in terminal and run the following: @@ -42,7 +42,7 @@ Now `cd` to this folder in terminal and run the following: Once done, you'll see your custom icon generated in `icnspack`'s folder: -![](../images/icnspack-done.png) +![](./images/icnspack-done.png) # Custom Mac Boot Picker icons @@ -59,15 +59,15 @@ To generate legacy icons, you'll need the following: Head to [developer.apple's More Downloads page](https://developer.apple.com/download/more/) and search for `Graphics Tools` that is supported by your OS(note for 10.6 and older, the app is hidden inside `Developer Tools`): -![](../images/graphics-download.png) +![](./images/graphics-download.png) Once downloaded, open the disk image and you'll find Icon Composer.app: -![Graphics Open](../images/graphics-open.png) +![Graphics Open](./images/graphics-open.png) Now run the app and simply drag the images to each section as so: -![](../images/icon-SL.png) +![](./images/icon-SL.png) Now save and export the new icns file. @@ -79,7 +79,7 @@ To install, please ensure that Vault was disabled when you built OpenCore. If yo Now that you've verified that you can edit OpenCore safely, you'll need to mount the drive that OpenCore is stored on. To do this, download [MountEFI](https://github.com/corpnewt/MountEFI) and run it: -![](../images/mountefi.png) +![](./images/mountefi.png) Select the drive you installed OpenCore to and mount it. @@ -90,7 +90,7 @@ Select the drive you installed OpenCore to and mount it. Head to `EFI/OC/Resources/Image/` on your drive and you'll see all the custom icons. For Background.icns, we need to ensure the file matches the theme OpenCore has set so we add the prefix `Modern` to it: -![](../images/background-moved.png) +![](./images/background-moved.png) Now reboot and you should see your updated icon(s)! @@ -98,6 +98,6 @@ Now reboot and you should see your updated icon(s)! Updating the Mac Boot Picker icons is actually quite simple. On the root of your drive, simply drop the icon into the root of the drive with the name `.VolumeIcon.icns` -![](../images/mac-icns-drive.png) +![](./images/mac-icns-drive.png) Now reboot and you'll see the new icon! diff --git a/docs/INSTALLER.md b/docs/INSTALLER.md index 11d4aeea9..61aff993e 100644 --- a/docs/INSTALLER.md +++ b/docs/INSTALLER.md @@ -14,17 +14,17 @@ For this guide, we'll be using the standard OpenCore-Patcher (GUI). Once downloaded, open the app and you should be greeted by this menu: -![OCLP GUI Main Menu](../images/OCLP-GUI-Main-Menu.png) +![OCLP GUI Main Menu](./images/OCLP-GUI-Main-Menu.png) First, we'll want to select the "Create macOS Installer" button. This will present you with 2 options: -![](../images/OCLP-GUI-Create-Installer-Menu.png) +![](./images/OCLP-GUI-Create-Installer-Menu.png) For this example, we'll assume you'll need an installer. Selecting this option will download Apple's Installer Catalogs and build a list for you to choose: | Downloading | Listed Installers | Unsupported Installer | | :--- | :--- | :--- | -| ![OCLP GUI Installer Download Catalog](../images/OCLP-GUI-Installer-Download-Catalog.png) | ![OCLP GUI Installer Download Listed Products](../images/OCLP-GUI-Installer-Download-Listed-Products.png) | ![](../images/OCLP-GUI-Installer-Download-Unsupported.png) +| ![OCLP GUI Installer Download Catalog](./images/OCLP-GUI-Installer-Download-Catalog.png) | ![OCLP GUI Installer Download Listed Products](./images/OCLP-GUI-Installer-Download-Listed-Products.png) | ![](./images/OCLP-GUI-Installer-Download-Unsupported.png) Since the patcher officially supports Big Sur and newer for patching, only those entries will be shown. For ourselves, we'll select macOS 12 as that's the latest public release at the time of writing. This will download and install the macOS installer to your applications folder. @@ -32,7 +32,7 @@ Since the patcher officially supports Big Sur and newer for patching, only those | Downloading the Installer | Requesting to install | Finished Installing | | :--- | :--- | :--- | -| ![OCLP GUI Installer Download Progress](../images/OCLP-GUI-Installer-Download-Progress.png) | ![OCLP GUI Installer Needs Installing](../images/OCLP-GUI-Installer-Needs-Installing.png) | ![OCLP GUI Installer Download Finished](../images/OCLP-GUI-Installer-Download-Finished.png) | +| ![OCLP GUI Installer Download Progress](./images/OCLP-GUI-Installer-Download-Progress.png) | ![OCLP GUI Installer Needs Installing](./images/OCLP-GUI-Installer-Needs-Installing.png) | ![OCLP GUI Installer Download Finished](./images/OCLP-GUI-Installer-Download-Finished.png) | Once finished, you can proceed to write the installer onto a USB drive. @@ -40,12 +40,12 @@ Once finished, you can proceed to write the installer onto a USB drive. | Select Downloaded Installer | Select disk to format | | :--- | :--- | -| ![](../images/OCLP-GUI-Installer-Select-Local-Installer.png) | ![](../images/OCLP-GUI-Installer-Format-USB.png) | +| ![](./images/OCLP-GUI-Installer-Select-Local-Installer.png) | ![](./images/OCLP-GUI-Installer-Format-USB.png) | Now the patcher will start the installer flashing! | Flashing | Success Prompt | Finished Flashing | | :--- | :--- | -| ![](../images/OCLP-GUI-Installer-Flashing-Process.png) | ![](../images/OCLP-GUI-Installer-Sucess-Prompt.png) | ![](../images/OCLP-GUI-Installer-Finished-Script.png) | +| ![](./images/OCLP-GUI-Installer-Flashing-Process.png) | ![](./images/OCLP-GUI-Installer-Sucess-Prompt.png) | ![](./images/OCLP-GUI-Installer-Finished-Script.png) | # Once finished, head to [Building and installing OpenCore](./BUILD.md) diff --git a/docs/MONTEREY-DROP.md b/docs/MONTEREY-DROP.md index e12c62bdb..4ea7add7d 100644 --- a/docs/MONTEREY-DROP.md +++ b/docs/MONTEREY-DROP.md @@ -1,4 +1,4 @@ -![](../images/macos-monterey.png) +![](./images/macos-monterey.png) With OpenCore Legacy Patcher v0.1.7 and newer, we've implemented beta macOS Monterey support for users. Please note that Apple has dropped a lot of hardware with this release as well as broken many of our previous patch sets. This page will be used to inform users regarding current issues and will be updated as new patch sets are developed and added to our patcher. diff --git a/docs/POST-INSTALL.md b/docs/POST-INSTALL.md index 60e85d253..fe5ce9bd1 100644 --- a/docs/POST-INSTALL.md +++ b/docs/POST-INSTALL.md @@ -20,7 +20,7 @@ And voila! No more USB drive required. To do this, run the OpenCore Patcher and head to Patcher Settings, then uncheck "Show OpenCore Bootpicker" on the Build tab: -![](../images/OCLP-GUI-Settings-ShowPicker.png) +![](./images/OCLP-GUI-Settings-ShowPicker.png) Once you've toggled it off, build your OpenCore EFI once again and install to your desired drive. Now to show the OpenCore selector, you can simply hold down the "ESC" key while clicking on EFI boot, and then you can release the "ESC" key when you see the cursor arrow at the top left. @@ -34,7 +34,7 @@ Going forward with 0.6.6, SIP settings can be accessed from the Security tab sho | SIP Enabled | SIP Lowered (Root Patching) | SIP Disabled | | :--- | :--- | :--- | -| ![](../images/OCLP-GUI-Settings-SIP-Enabled.png) | ![](../images/OCLP-GUI-Settings-SIP-Root-Patch.png) | ![](../images/OCLP-GUI-Settings-SIP-Disabled.png) | +| ![](./images/OCLP-GUI-Settings-SIP-Enabled.png) | ![](./images/OCLP-GUI-Settings-SIP-Root-Patch.png) | ![](./images/OCLP-GUI-Settings-SIP-Disabled.png) | :::warning @@ -44,9 +44,9 @@ If you're unsure whether you should enable SIP, leave it as-is. Systems where yo ## Applying Post Install Volume Patches -:::warning +:::warning -If you need to use Migration Assistant to bring over data to your new macOS install, it is **highly recommended** to avoid restoring from inside Setup Assistant and waiting to install root patches until after the transfer is complete. If root patches were automatically installed, you can use the options available in the OCLP app to remove them. +If you need to use Migration Assistant to bring over data to your new macOS install, it is **highly recommended** to avoid restoring from inside Setup Assistant and waiting to install root patches until after the transfer is complete. If root patches were automatically installed, you can use the options available in the OCLP app to remove them. Using Migration Assistant while patches are installed can lead to an unbootable system, requiring a reinstall of macOS. @@ -60,7 +60,7 @@ Users can also see whether applicable patches have been installed, date and vers | Automatic install prompt | Status | | :--- | :--- | -| ![](../images/OCLP-GUI-root-patch-update.png) | ![](../images/OCLP-GUI-Root-Patch-Status.png) | +| ![](./images/OCLP-GUI-root-patch-update.png) | ![](./images/OCLP-GUI-Root-Patch-Status.png) | @@ -72,7 +72,7 @@ There is also an option to remove root patches, which may be required in some si | Listing Patches | Patching Finished | | :--- | :--- | -| ![](../images/OCLP-GUI-Root-Patch.png) | ![](../images/OCLP-GUI-Root-Patch-Finished.png) | +| ![](./images/OCLP-GUI-Root-Patch.png) | ![](./images/OCLP-GUI-Root-Patch-Finished.png) | :::warning diff --git a/docs/SONOMA-DROP.md b/docs/SONOMA-DROP.md index 3f7fcb0ea..dad6b06c8 100644 --- a/docs/SONOMA-DROP.md +++ b/docs/SONOMA-DROP.md @@ -1,4 +1,4 @@ -![](../images/sonoma.png) +![](./images/sonoma.png) *Well here we are again, it's always such a pleasure~* @@ -71,7 +71,7 @@ While USB 1.1 may seem unimportant, it handles many important devices on your sy With OpenCore Legacy Patcher v0.6.0+, basic support has been implemented via Root Volume patching. However due to this, users will need to use a USB hub for installation and post-OS updates when patches are cleaned: -![](../images/usb11-chart.png) +![](./images/usb11-chart.png) ::: warning The following systems rely on USB 1.1 diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index c62a23633..2ed8f0388 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -40,7 +40,7 @@ However, if the 🚫 Symbol only appears after the boot process has already star ## Cannot boot macOS without the USB -By default, the OpenCore Patcher won't install OpenCore onto the internal drive itself during installs. +By default, the OpenCore Patcher won't install OpenCore onto the internal drive itself during installs. After installing macOS, OpenCore Legacy Patcher should automatically prompt you to install OpenCore onto the internal drive. However, if it doesn't show the prompt, you'll need to either [manually transfer](https://dortania.github.io/OpenCore-Post-Install/universal/oc2hdd.html) OpenCore to the internal drive's EFI or Build and Install again and select your internal drive. @@ -112,7 +112,7 @@ To work-around this, we recommend that users manually connect using the "Other" ## No Graphics Acceleration -In macOS, GPU drivers are often dropped from the OS with each major release of it. With macOS Big Sur, currently, all non-Metal GPUs require additional patches to gain acceleration. In addition, macOS Monterey removed Graphics Drivers for both Intel Ivy Bridge and NVIDIA Kepler graphics processors. +In macOS, GPU drivers are often dropped from the OS with each major release of it. With macOS Big Sur, currently, all non-Metal GPUs require additional patches to gain acceleration. In addition, macOS Monterey removed Graphics Drivers for both Intel Ivy Bridge and NVIDIA Kepler graphics processors. If you're using OCLP v0.4.4, you should have been prompted to install Root Volume patches after the first boot from installation of macOS. If you need to do this manually, you can do so within the patcher app. Once rebooted, acceleration will be re-enabled as well as brightness control for laptops. @@ -126,14 +126,14 @@ Due to Apple dropping NVIDIA Kepler support in macOS Monterey, [MacBookPro11,3's If you're having trouble with DisplayPort output on Mac Pros, try enabling Minimal Spoofing in Settings -> SMBIOS Settings and rebuild/install OpenCore. This will trick macOS drivers into thinking you have a newer MacPro7,1 and resolve the issue. -![](../images/OCLP-GUI-SMBIOS-Minimal.png) +![](./images/OCLP-GUI-SMBIOS-Minimal.png) ## Volume Hash Mismatch Error in macOS Monterey A semi-common popup some users face is the "Volume Hash Mismatch" error:

- +

What this error signifies is that the OS detects that the boot volume's hash does not match what the OS is expecting, this error is generally cosmetic and can be ignored. However if your system starts to crash spontaneously shortly after, you'll want to reinstall macOS fresh without importing any data at first. @@ -150,7 +150,7 @@ Head into the GUI, go to Patcher Settings, and toggle the bits you need disabled | SIP Enabled | SIP Lowered (Root Patching) | SIP Disabled | | :--- | :--- | :--- | -| ![](../images/OCLP-GUI-Settings-SIP-Enabled.png) | ![](../images/OCLP-GUI-Settings-SIP-Root-Patch.png) | ![](../images/OCLP-GUI-Settings-SIP-Disabled.png) | +| ![](./images/OCLP-GUI-Settings-SIP-Enabled.png) | ![](./images/OCLP-GUI-Settings-SIP-Root-Patch.png) | ![](./images/OCLP-GUI-Settings-SIP-Disabled.png) | ## Intermediate issues with USB 1.1 and Bluetooth on MacPro3,1 - MacPro5,1 @@ -199,4 +199,4 @@ Applicable models include: | Mac Pro | Mid 2010 and older | MacPro3,1 - MacPro5,1 | | -![](../images/usb11-chart.png) +![](./images/usb11-chart.png) diff --git a/docs/UNIVERSALCONTROL.md b/docs/UNIVERSALCONTROL.md index debb4e3d0..35cc11149 100644 --- a/docs/UNIVERSALCONTROL.md +++ b/docs/UNIVERSALCONTROL.md @@ -12,7 +12,7 @@ If you meet all the requirements, in most cases you can go to Display Preference | Display Preferences | Universal Control settings | | :--- | :--- | -| ![](../images/UC-enable-1.png) | ![OCLP GUI Build Finished](../images/UC-enable-2.png) | +| ![](./images/UC-enable-1.png) | ![OCLP GUI Build Finished](./images/UC-enable-2.png) | Most Mac models from 2011 and above should work out of the box. However, older Macs like the 2008-2011 MacBook Pros require upgrading the Wi-Fi/Bluetooth card to a newer model. More info in the [requirements section.](#requirements-for-universal-control) @@ -183,7 +183,7 @@ The following models are blacklisted from using Universal Control by Apple: - Macmini7,x - Mac mini 2014 - MacPro6,x - Mac Pro Late 2013 -The hardware in these models are capable of supporting Universal Control, but due to blacklisting, the only solution to use Universal Control on these models is to spoof their SMBIOS. SMBIOS spoofing essentially fools some aspects of macOS to think they are running on a different machine. +The hardware in these models are capable of supporting Universal Control, but due to blacklisting, the only solution to use Universal Control on these models is to spoof their SMBIOS. SMBIOS spoofing essentially fools some aspects of macOS to think they are running on a different machine. With SMBIOS Spoofing, the Universal Control handshake recognizes a different SMBIOS and thus grants a blacklisted Mac to connect to other Macs and iPads with Universal Control. @@ -206,7 +206,7 @@ Ventura has dropped more models which includes all of the blacklisted Macs in qu ::: details macOS Sonoma -Firstly run OpenCore Legacy Patcher. +Firstly run OpenCore Legacy Patcher. Then go to **Settings** and **SMBIOS** tab, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model **one listed next to your native model in the table for spoofed models below.** @@ -214,7 +214,7 @@ Notice that "Allow native models" and "Allow Native Spoofs" **are NOT** enabled | Main Settings view | SMBIOS settings | | :--- | :--- | -| ![](../images/ventura_uc1.png) | ![](../images/ventura_uc2.png) | +| ![](./images/ventura_uc1.png) | ![](./images/ventura_uc2.png) | @@ -238,7 +238,7 @@ Spoofing to any model with native Sonoma support should work, but these are the ::: details macOS Ventura -Firstly run OpenCore Legacy Patcher. +Firstly run OpenCore Legacy Patcher. Then go to **Settings** and **SMBIOS** tab, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model **one listed next to your native model in the table for spoofed models below.** @@ -246,7 +246,7 @@ Notice that "Allow native models" and "Allow Native Spoofs" **are NOT** enabled | Main Settings view | SMBIOS settings | | :--- | :--- | -| ![](../images/ventura_uc1.png) | ![](../images/ventura_uc2.png) | +| ![](./images/ventura_uc1.png) | ![](./images/ventura_uc2.png) | @@ -272,14 +272,14 @@ Spoofing to any model with native Ventura support should work, but these are the Firstly, run OpenCore Legacy Patcher. Secondly, go to **Settings** then the **App** tab and tick **Allow native models**. -[](../images/OCLP-App-Allow-Native-Models.png) +[](./images/OCLP-App-Allow-Native-Models.png) Then, go to **SMBIOS** tab, tick **Allow spoofing native Macs**, set SMBIOS Spoof Level to **Moderate**. Set SMBIOS Spoof Model to **one listed next to your native model in the table for spoofed models below.** | Main Settings view | SMBIOS settings | | :--- | :--- | -| ![](../images/OCLP-SMBIOS-Allow-Native-Spoof.png) | ![](../images/OCLP-smbios-settings.png) | +| ![](./images/OCLP-SMBIOS-Allow-Native-Spoof.png) | ![](./images/OCLP-smbios-settings.png) | ::: details Table for spoofed models (click to expand) diff --git a/docs/UPDATE.md b/docs/UPDATE.md index 0fa4d5a1b..611bc310a 100644 --- a/docs/UPDATE.md +++ b/docs/UPDATE.md @@ -1,10 +1,10 @@ # Updating OpenCore and Patches -With OpenCore Legacy Patcher, there's generally very little reason for users to update the OpenCore installation on their machine unless you feel there's a benefit with new versions for your setup, e.g. Bluetooth has stopped working with a new macOS update. +With OpenCore Legacy Patcher, there's generally very little reason for users to update the OpenCore installation on their machine unless you feel there's a benefit with new versions for your setup, e.g. Bluetooth has stopped working with a new macOS update. For those who do wish to update, simply [download the latest release](https://github.com/dortania/OpenCore-Legacy-Patcher/releases) and rerun the patcher: -![](../images/OCLP-GUI-Main-Menu.png) +![](./images/OCLP-GUI-Main-Menu.png) Then, rebuild your OpenCore build and install again. OpenCore Will now be updated! @@ -17,6 +17,6 @@ nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:opencore-version nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version ``` -![](../images/oclp-version.png) +![](./images/oclp-version.png) From this, we can see that we're running a RELEASE version of OpenCore 0.8.0 built on April 18th, 2022 with Patcher Version 0.4.5! diff --git a/docs/VENTURA-DROP.md b/docs/VENTURA-DROP.md index 8056a4bd2..daff20f20 100644 --- a/docs/VENTURA-DROP.md +++ b/docs/VENTURA-DROP.md @@ -1,4 +1,4 @@ -![](../images/ventura.png) +![](./images/ventura.png) With the release of OpenCore Legacy Patcher v0.5.0 and newer, early support for macOS Ventura has been implemented for most Metal-capable Macs. This page will be used to inform users regarding current issues and will be updated as new patch sets are developed and added to our patcher. @@ -24,7 +24,7 @@ Ventura's release dropped a large amount of Intel hardware, thus requiring the u ## Current status - + For older hardware, see below sections: @@ -64,7 +64,7 @@ For Penryn systems and pre-2013 Mac Pros, USB 1.1 support was outright removed i With OpenCore Legacy Patcher v0.6.0, basic support has been implemented via Root Volume patching. However due to this, users will need to use a USB hub for installation and post-OS updates when patches are cleaned: -![](../images/usb11-chart.png) +![](./images/usb11-chart.png) ::: warning The following systems rely on USB 1.1 diff --git a/docs/WINDOWS.md b/docs/WINDOWS.md index b9a5c0fc1..68bb208f6 100644 --- a/docs/WINDOWS.md +++ b/docs/WINDOWS.md @@ -32,13 +32,13 @@ The following is required for installation: Open Disk Utility in macOS and format the USB Drive as ExFat with the Master Boot Record scheme: -![](../images/windows-mbr-format.png) +![](./images/windows-mbr-format.png) ### Formatting the Target Drive Next, select the drive you wish to install Windows in Disk Utility on and partition it as ExFat (If formatting the entire drive, ensure it's using the GUID Partition Table scheme): -![](../images/windows-partition-1.png) +![](./images/windows-partition-1.png) :::warning @@ -55,7 +55,7 @@ Recommended size is 200MB and the partition format **must** be FAT32 for OpenCor * Note 2: Having different partitions for OpenCore is not required if the Windows boot files detected by the stock Bootpicker are removed. See "Removing the Windows option from the stock bootpicker" for further information. * Note 3: We recommend uninstalling OpenCore from the ESP/EFI Partition when you create this new OpenCore partition to avoid confusion when selecting OpenCore builds in the Mac's boot picker. -![](../images/windows-partition-2.png) +![](./images/windows-partition-2.png) ## Creating the Windows Installer @@ -67,7 +67,7 @@ The latest Windows installation images can be downloaded from Microsoft using th Once the file is downloaded, mount the .iso image: -![](../images/windows-iso.png) +![](./images/windows-iso.png) Then open terminal and use the `rsync` command with the disk image set as the source and your USB drive set as the target. (Replace "CCCOMA_X64" with the mounted image's partition name, and replace "InstallWin10" with your USB Drive's name). @@ -75,11 +75,11 @@ Then open terminal and use the `rsync` command with the disk image set as the so rsync -r -P /Volumes/CCCOMA_X64/ /Volumes/InstallWin10 ``` -![](../images/rsync-progess.png) +![](./images/rsync-progess.png) The `rsync` command will take some time, so get some coffee and sit back. Once finished, the root of the USB drive should look as follows: -![](../images/windows-rsync-done.png) +![](./images/windows-rsync-done.png) * Ensure that these folders and files are in the root of the USB drive, otherwise the USB will not boot. @@ -113,31 +113,31 @@ Once booted into the Windows installer, proceed as you normally would until you When you are prompted to select a drive, select your desired partition and delete it using "Delete". If you want to install Windows to an empty drive, erase every partition currently on the desired drive. After your drive/partition is erased, press "New" to create the Windows system partitions. -![](../images/DISM-1.png) +![](./images/DISM-1.png) You will be prompted to confirm the creation of the system partitions, press "OK". -![](../images/DISM-2.png) +![](./images/DISM-2.png) Once the partitions are created, select the main (largest) partition and press "Format". This will format the partition using the NFTS file system. -![](../images/DISM-3.png) +![](./images/DISM-3.png) After the installer formats the partition, open up the Command Prompt by pressing SHIFT + F10. Then run the `diskpart` command, and `list vol`. This will produce a list of volumes in your system, make sure to keep track of the drive letters of the main Windows partition (largest, NTFS), the EFI partition (100MB, FAT32), and the Windows installer (Usually Drive D). Run `exit` to close diskpart -![](../images/DISM-4.png) +![](./images/DISM-4.png) Now, get a list of available Windows editions by running `dism /Get-WimInfo /WimFile:D:\Sources\install.wim` (substituting D with the Installer Drive Letter). This guide will use Option 6 for Windows 10 Pro. -![](../images/DISM-5.png) +![](./images/DISM-5.png) You can now start the deployment process. Run `dism /Apply-Image /ImageFile:D:\Sources\install.wim /index:6 /ApplyDir:E:`, replacing "D" with the Installer Drive Letter, "6" with the Windows edition option, and "E" with the Windows Partition Drive Letter. -![](../images/DISM-6.png) +![](./images/DISM-6.png) Once `dism` finishes its thing, run `bcdboot E:\Windows`, substituting "E" for the drive letter of the main Windows partition to create the boot files. -![](../images/DISM-7.png) +![](./images/DISM-7.png) Windows is now installed. It should be recognized as "EFI Boot" or "Windows" with a Boot Camp icon in the OCLP Bootpicker. @@ -155,11 +155,11 @@ Start up a command prompt window in the Windows Setup environment by running `cm Next, enter the EFI Folder by running `C:`, substituting "C" for the EFI Partition Drive Letter. Then run `cd EFI` to enter the EFI Partition. Then, run `rmdir Boot /S /Q` to remove the boot files that can be detected by the stock Bootpicker. The OCLP Picker will still be able to detect and boot Windows. -![](../images/DISM-8.png) +![](./images/DISM-8.png) You can verify that the `Boot` folder is removed by running the `dir` command: -![](../images/DISM-9.png) +![](./images/DISM-9.png) If, for whatever reason, you are not able to remove the boot files from the Windows setup, shut down your system, boot into macOS, mount your EFI partition with [MountEFI](https://github.com/corpnewt/MountEFI), and remove the `Boot` folder (it should have a recent file modification date, and contain `Bootx64.efi`). @@ -176,11 +176,11 @@ Once Brigadier is downloaded, move it to your desktop for easy access. Open up a command prompt window as a standard user and run `cd desktop`. -![](../images/BOOTCAMP-1.png) +![](./images/BOOTCAMP-1.png) Then run `.\brigadier.exe --model=MODEL1,1`, replacing "MODEL1,1" with your machine's SMBIOS model. -![](../images/BOOTCAMP-2.png) +![](./images/BOOTCAMP-2.png) Once the Boot Camp software is downloaded, you can install it by executing `Setup.exe` or `\Drivers\Apple\BootCamp.msi` (`BootCamp64.msi` if present). @@ -194,11 +194,11 @@ Once Brigadier is downloaded, move it to your desktop for easy access. Open up a command prompt window as a standard user and run `cd desktop`. -![](../images/BOOTCAMP-1.png) +![](./images/BOOTCAMP-1.png) Then run `.\brigadier.exe --model=MacPro7,1`. This will download the latest BootCamp 6 package. -![](../images/BOOTCAMP-2.png) +![](./images/BOOTCAMP-2.png) Once the Boot Camp software is downloaded, you can install Boot Camp 6 by executing `\Drivers\Apple\BootCamp.msi` in an administrator command prompt window. @@ -210,7 +210,7 @@ If you built OpenCore with Moderate or higher SMBIOS spoofing, you'll get an err | Setup.exe | BootCamp.msi | | :--- | :--- | -| ![](../images/windows-bootcamp-error.png) | ![](../images/windows-bootcamp-msi.png) | +| ![](./images/windows-bootcamp-error.png) | ![](./images/windows-bootcamp-msi.png) | ::: details BootCamp.msi quirks diff --git a/images/BOOTCAMP-1.png b/docs/images/BOOTCAMP-1.png similarity index 100% rename from images/BOOTCAMP-1.png rename to docs/images/BOOTCAMP-1.png diff --git a/images/BOOTCAMP-2.png b/docs/images/BOOTCAMP-2.png similarity index 100% rename from images/BOOTCAMP-2.png rename to docs/images/BOOTCAMP-2.png diff --git a/images/DISM-1.png b/docs/images/DISM-1.png similarity index 100% rename from images/DISM-1.png rename to docs/images/DISM-1.png diff --git a/images/DISM-2.png b/docs/images/DISM-2.png similarity index 100% rename from images/DISM-2.png rename to docs/images/DISM-2.png diff --git a/images/DISM-3.png b/docs/images/DISM-3.png similarity index 100% rename from images/DISM-3.png rename to docs/images/DISM-3.png diff --git a/images/DISM-4.png b/docs/images/DISM-4.png similarity index 100% rename from images/DISM-4.png rename to docs/images/DISM-4.png diff --git a/images/DISM-5.png b/docs/images/DISM-5.png similarity index 100% rename from images/DISM-5.png rename to docs/images/DISM-5.png diff --git a/images/DISM-6.png b/docs/images/DISM-6.png similarity index 100% rename from images/DISM-6.png rename to docs/images/DISM-6.png diff --git a/images/DISM-7.png b/docs/images/DISM-7.png similarity index 100% rename from images/DISM-7.png rename to docs/images/DISM-7.png diff --git a/images/DISM-8.png b/docs/images/DISM-8.png similarity index 100% rename from images/DISM-8.png rename to docs/images/DISM-8.png diff --git a/images/DISM-9.png b/docs/images/DISM-9.png similarity index 100% rename from images/DISM-9.png rename to docs/images/DISM-9.png diff --git a/images/HD3000-Default-Colors.png b/docs/images/HD3000-Default-Colors.png similarity index 100% rename from images/HD3000-Default-Colors.png rename to docs/images/HD3000-Default-Colors.png diff --git a/images/HD3000-Display-Colors.png b/docs/images/HD3000-Display-Colors.png similarity index 100% rename from images/HD3000-Display-Colors.png rename to docs/images/HD3000-Display-Colors.png diff --git a/images/Hash-Mismatch.png b/docs/images/Hash-Mismatch.png similarity index 100% rename from images/Hash-Mismatch.png rename to docs/images/Hash-Mismatch.png diff --git a/images/OC-Build.png b/docs/images/OC-Build.png similarity index 100% rename from images/OC-Build.png rename to docs/images/OC-Build.png diff --git a/images/OC-Patcher.png b/docs/images/OC-Patcher.png similarity index 100% rename from images/OC-Patcher.png rename to docs/images/OC-Patcher.png diff --git a/images/OC-Picker-External.png b/docs/images/OC-Picker-External.png similarity index 100% rename from images/OC-Picker-External.png rename to docs/images/OC-Picker-External.png diff --git a/images/OC-Picker-Internal.png b/docs/images/OC-Picker-Internal.png similarity index 100% rename from images/OC-Picker-Internal.png rename to docs/images/OC-Picker-Internal.png diff --git a/images/OC-Picker-SD.png b/docs/images/OC-Picker-SD.png similarity index 100% rename from images/OC-Picker-SD.png rename to docs/images/OC-Picker-SD.png diff --git a/images/OC-Picker-SSD.png b/docs/images/OC-Picker-SSD.png similarity index 100% rename from images/OC-Picker-SSD.png rename to docs/images/OC-Picker-SSD.png diff --git a/images/OCLP-051-Initial-Support.png b/docs/images/OCLP-051-Initial-Support.png similarity index 100% rename from images/OCLP-051-Initial-Support.png rename to docs/images/OCLP-051-Initial-Support.png diff --git a/images/OCLP-060-Initial-Support.png b/docs/images/OCLP-060-Initial-Support.png similarity index 100% rename from images/OCLP-060-Initial-Support.png rename to docs/images/OCLP-060-Initial-Support.png diff --git a/images/OCLP-App-Allow-Native-Models.png b/docs/images/OCLP-App-Allow-Native-Models.png similarity index 100% rename from images/OCLP-App-Allow-Native-Models.png rename to docs/images/OCLP-App-Allow-Native-Models.png diff --git a/images/OCLP-GUI-Build-Finished.png b/docs/images/OCLP-GUI-Build-Finished.png similarity index 100% rename from images/OCLP-GUI-Build-Finished.png rename to docs/images/OCLP-GUI-Build-Finished.png diff --git a/images/OCLP-GUI-Build-Start.png b/docs/images/OCLP-GUI-Build-Start.png similarity index 100% rename from images/OCLP-GUI-Build-Start.png rename to docs/images/OCLP-GUI-Build-Start.png diff --git a/images/OCLP-GUI-Create-Installer-Menu.png b/docs/images/OCLP-GUI-Create-Installer-Menu.png similarity index 100% rename from images/OCLP-GUI-Create-Installer-Menu.png rename to docs/images/OCLP-GUI-Create-Installer-Menu.png diff --git a/images/OCLP-GUI-EFI-Finished-Install.png b/docs/images/OCLP-GUI-EFI-Finished-Install.png similarity index 100% rename from images/OCLP-GUI-EFI-Finished-Install.png rename to docs/images/OCLP-GUI-EFI-Finished-Install.png diff --git a/images/OCLP-GUI-EFI-Needs-Permission.png b/docs/images/OCLP-GUI-EFI-Needs-Permission.png similarity index 100% rename from images/OCLP-GUI-EFI-Needs-Permission.png rename to docs/images/OCLP-GUI-EFI-Needs-Permission.png diff --git a/images/OCLP-GUI-EFI-Select-Disk.png b/docs/images/OCLP-GUI-EFI-Select-Disk.png similarity index 100% rename from images/OCLP-GUI-EFI-Select-Disk.png rename to docs/images/OCLP-GUI-EFI-Select-Disk.png diff --git a/images/OCLP-GUI-EFI-Select-Partition.png b/docs/images/OCLP-GUI-EFI-Select-Partition.png similarity index 100% rename from images/OCLP-GUI-EFI-Select-Partition.png rename to docs/images/OCLP-GUI-EFI-Select-Partition.png diff --git a/images/OCLP-GUI-Installer-Download-Catalog.png b/docs/images/OCLP-GUI-Installer-Download-Catalog.png similarity index 100% rename from images/OCLP-GUI-Installer-Download-Catalog.png rename to docs/images/OCLP-GUI-Installer-Download-Catalog.png diff --git a/images/OCLP-GUI-Installer-Download-Finished.png b/docs/images/OCLP-GUI-Installer-Download-Finished.png similarity index 100% rename from images/OCLP-GUI-Installer-Download-Finished.png rename to docs/images/OCLP-GUI-Installer-Download-Finished.png diff --git a/images/OCLP-GUI-Installer-Download-Listed-Products.png b/docs/images/OCLP-GUI-Installer-Download-Listed-Products.png similarity index 100% rename from images/OCLP-GUI-Installer-Download-Listed-Products.png rename to docs/images/OCLP-GUI-Installer-Download-Listed-Products.png diff --git a/images/OCLP-GUI-Installer-Download-Progress.png b/docs/images/OCLP-GUI-Installer-Download-Progress.png similarity index 100% rename from images/OCLP-GUI-Installer-Download-Progress.png rename to docs/images/OCLP-GUI-Installer-Download-Progress.png diff --git a/images/OCLP-GUI-Installer-Download-Unsupported.png b/docs/images/OCLP-GUI-Installer-Download-Unsupported.png similarity index 100% rename from images/OCLP-GUI-Installer-Download-Unsupported.png rename to docs/images/OCLP-GUI-Installer-Download-Unsupported.png diff --git a/images/OCLP-GUI-Installer-Finished-Script.png b/docs/images/OCLP-GUI-Installer-Finished-Script.png similarity index 100% rename from images/OCLP-GUI-Installer-Finished-Script.png rename to docs/images/OCLP-GUI-Installer-Finished-Script.png diff --git a/images/OCLP-GUI-Installer-Flashing-Process.png b/docs/images/OCLP-GUI-Installer-Flashing-Process.png similarity index 100% rename from images/OCLP-GUI-Installer-Flashing-Process.png rename to docs/images/OCLP-GUI-Installer-Flashing-Process.png diff --git a/images/OCLP-GUI-Installer-Format-USB.png b/docs/images/OCLP-GUI-Installer-Format-USB.png similarity index 100% rename from images/OCLP-GUI-Installer-Format-USB.png rename to docs/images/OCLP-GUI-Installer-Format-USB.png diff --git a/images/OCLP-GUI-Installer-Needs-Installing.png b/docs/images/OCLP-GUI-Installer-Needs-Installing.png similarity index 100% rename from images/OCLP-GUI-Installer-Needs-Installing.png rename to docs/images/OCLP-GUI-Installer-Needs-Installing.png diff --git a/images/OCLP-GUI-Installer-Select-Local-Installer.png b/docs/images/OCLP-GUI-Installer-Select-Local-Installer.png similarity index 100% rename from images/OCLP-GUI-Installer-Select-Local-Installer.png rename to docs/images/OCLP-GUI-Installer-Select-Local-Installer.png diff --git a/images/OCLP-GUI-Installer-Sucess-Prompt.png b/docs/images/OCLP-GUI-Installer-Sucess-Prompt.png similarity index 100% rename from images/OCLP-GUI-Installer-Sucess-Prompt.png rename to docs/images/OCLP-GUI-Installer-Sucess-Prompt.png diff --git a/images/OCLP-GUI-Main-Menu.png b/docs/images/OCLP-GUI-Main-Menu.png similarity index 100% rename from images/OCLP-GUI-Main-Menu.png rename to docs/images/OCLP-GUI-Main-Menu.png diff --git a/images/OCLP-GUI-Root-Patch-Finished.png b/docs/images/OCLP-GUI-Root-Patch-Finished.png similarity index 100% rename from images/OCLP-GUI-Root-Patch-Finished.png rename to docs/images/OCLP-GUI-Root-Patch-Finished.png diff --git a/images/OCLP-GUI-Root-Patch-Status.png b/docs/images/OCLP-GUI-Root-Patch-Status.png similarity index 100% rename from images/OCLP-GUI-Root-Patch-Status.png rename to docs/images/OCLP-GUI-Root-Patch-Status.png diff --git a/images/OCLP-GUI-Root-Patch.png b/docs/images/OCLP-GUI-Root-Patch.png similarity index 100% rename from images/OCLP-GUI-Root-Patch.png rename to docs/images/OCLP-GUI-Root-Patch.png diff --git a/images/OCLP-GUI-SMBIOS-Minimal.png b/docs/images/OCLP-GUI-SMBIOS-Minimal.png similarity index 100% rename from images/OCLP-GUI-SMBIOS-Minimal.png rename to docs/images/OCLP-GUI-SMBIOS-Minimal.png diff --git a/images/OCLP-GUI-Settings-Beta-Blur.png b/docs/images/OCLP-GUI-Settings-Beta-Blur.png similarity index 100% rename from images/OCLP-GUI-Settings-Beta-Blur.png rename to docs/images/OCLP-GUI-Settings-Beta-Blur.png diff --git a/images/OCLP-GUI-Settings-SIP-Disabled.png b/docs/images/OCLP-GUI-Settings-SIP-Disabled.png similarity index 100% rename from images/OCLP-GUI-Settings-SIP-Disabled.png rename to docs/images/OCLP-GUI-Settings-SIP-Disabled.png diff --git a/images/OCLP-GUI-Settings-SIP-Enabled.png b/docs/images/OCLP-GUI-Settings-SIP-Enabled.png similarity index 100% rename from images/OCLP-GUI-Settings-SIP-Enabled.png rename to docs/images/OCLP-GUI-Settings-SIP-Enabled.png diff --git a/images/OCLP-GUI-Settings-SIP-Root-Patch.png b/docs/images/OCLP-GUI-Settings-SIP-Root-Patch.png similarity index 100% rename from images/OCLP-GUI-Settings-SIP-Root-Patch.png rename to docs/images/OCLP-GUI-Settings-SIP-Root-Patch.png diff --git a/images/OCLP-GUI-Settings-ShowPicker.png b/docs/images/OCLP-GUI-Settings-ShowPicker.png similarity index 100% rename from images/OCLP-GUI-Settings-ShowPicker.png rename to docs/images/OCLP-GUI-Settings-ShowPicker.png diff --git a/images/OCLP-GUI-root-patch-update.png b/docs/images/OCLP-GUI-root-patch-update.png similarity index 100% rename from images/OCLP-GUI-root-patch-update.png rename to docs/images/OCLP-GUI-root-patch-update.png diff --git a/images/OCLP-SMBIOS-Allow-Native-Spoof.png b/docs/images/OCLP-SMBIOS-Allow-Native-Spoof.png similarity index 100% rename from images/OCLP-SMBIOS-Allow-Native-Spoof.png rename to docs/images/OCLP-SMBIOS-Allow-Native-Spoof.png diff --git a/images/OCLP-smbios-settings.png b/docs/images/OCLP-smbios-settings.png similarity index 100% rename from images/OCLP-smbios-settings.png rename to docs/images/OCLP-smbios-settings.png diff --git a/images/UC-enable-1.png b/docs/images/UC-enable-1.png similarity index 100% rename from images/UC-enable-1.png rename to docs/images/UC-enable-1.png diff --git a/images/UC-enable-2.png b/docs/images/UC-enable-2.png similarity index 100% rename from images/UC-enable-2.png rename to docs/images/UC-enable-2.png diff --git a/images/Unflashed-Boot-1.png b/docs/images/Unflashed-Boot-1.png similarity index 100% rename from images/Unflashed-Boot-1.png rename to docs/images/Unflashed-Boot-1.png diff --git a/images/Unflashed-Boot-2.png b/docs/images/Unflashed-Boot-2.png similarity index 100% rename from images/Unflashed-Boot-2.png rename to docs/images/Unflashed-Boot-2.png diff --git a/images/Unflashed-Boot-3.png b/docs/images/Unflashed-Boot-3.png similarity index 100% rename from images/Unflashed-Boot-3.png rename to docs/images/Unflashed-Boot-3.png diff --git a/images/background-moved.png b/docs/images/background-moved.png similarity index 100% rename from images/background-moved.png rename to docs/images/background-moved.png diff --git a/images/build-dist.png b/docs/images/build-dist.png similarity index 100% rename from images/build-dist.png rename to docs/images/build-dist.png diff --git a/images/efi-boot.png b/docs/images/efi-boot.png similarity index 100% rename from images/efi-boot.png rename to docs/images/efi-boot.png diff --git a/images/graphics-download.png b/docs/images/graphics-download.png similarity index 100% rename from images/graphics-download.png rename to docs/images/graphics-download.png diff --git a/images/graphics-open.png b/docs/images/graphics-open.png similarity index 100% rename from images/graphics-open.png rename to docs/images/graphics-open.png diff --git a/images/icns-sl-save.png b/docs/images/icns-sl-save.png similarity index 100% rename from images/icns-sl-save.png rename to docs/images/icns-sl-save.png diff --git a/images/icnspack-done.png b/docs/images/icnspack-done.png similarity index 100% rename from images/icnspack-done.png rename to docs/images/icnspack-done.png diff --git a/images/icnspack-folder.png b/docs/images/icnspack-folder.png similarity index 100% rename from images/icnspack-folder.png rename to docs/images/icnspack-folder.png diff --git a/images/icon-SL.png b/docs/images/icon-SL.png similarity index 100% rename from images/icon-SL.png rename to docs/images/icon-SL.png diff --git a/images/logs-efi.png b/docs/images/logs-efi.png similarity index 100% rename from images/logs-efi.png rename to docs/images/logs-efi.png diff --git a/images/mac-icns-drive.png b/docs/images/mac-icns-drive.png similarity index 100% rename from images/mac-icns-drive.png rename to docs/images/mac-icns-drive.png diff --git a/images/macos-monterey.png b/docs/images/macos-monterey.png similarity index 100% rename from images/macos-monterey.png rename to docs/images/macos-monterey.png diff --git a/images/mountefi.png b/docs/images/mountefi.png similarity index 100% rename from images/mountefi.png rename to docs/images/mountefi.png diff --git a/images/oc-boot.png b/docs/images/oc-boot.png similarity index 100% rename from images/oc-boot.png rename to docs/images/oc-boot.png diff --git a/images/oc-explained.png b/docs/images/oc-explained.png similarity index 100% rename from images/oc-explained.png rename to docs/images/oc-explained.png diff --git a/images/oc-windows-done.png b/docs/images/oc-windows-done.png similarity index 100% rename from images/oc-windows-done.png rename to docs/images/oc-windows-done.png diff --git a/images/oc-windows.png b/docs/images/oc-windows.png similarity index 100% rename from images/oc-windows.png rename to docs/images/oc-windows.png diff --git a/images/ocdebugimage.png b/docs/images/ocdebugimage.png similarity index 100% rename from images/ocdebugimage.png rename to docs/images/ocdebugimage.png diff --git a/images/oclp-stuck-firstreboot.png b/docs/images/oclp-stuck-firstreboot.png similarity index 100% rename from images/oclp-stuck-firstreboot.png rename to docs/images/oclp-stuck-firstreboot.png diff --git a/images/oclp-version.png b/docs/images/oclp-version.png similarity index 100% rename from images/oclp-version.png rename to docs/images/oclp-version.png diff --git a/images/rsync-progess.png b/docs/images/rsync-progess.png similarity index 100% rename from images/rsync-progess.png rename to docs/images/rsync-progess.png diff --git a/images/sonoma.png b/docs/images/sonoma.png similarity index 100% rename from images/sonoma.png rename to docs/images/sonoma.png diff --git a/images/usb11-chart.png b/docs/images/usb11-chart.png similarity index 100% rename from images/usb11-chart.png rename to docs/images/usb11-chart.png diff --git a/images/ventura.png b/docs/images/ventura.png similarity index 100% rename from images/ventura.png rename to docs/images/ventura.png diff --git a/images/ventura_uc1.png b/docs/images/ventura_uc1.png similarity index 100% rename from images/ventura_uc1.png rename to docs/images/ventura_uc1.png diff --git a/images/ventura_uc2.png b/docs/images/ventura_uc2.png similarity index 100% rename from images/ventura_uc2.png rename to docs/images/ventura_uc2.png diff --git a/images/windows-bootcamp-error.png b/docs/images/windows-bootcamp-error.png similarity index 100% rename from images/windows-bootcamp-error.png rename to docs/images/windows-bootcamp-error.png diff --git a/images/windows-bootcamp-msi.png b/docs/images/windows-bootcamp-msi.png similarity index 100% rename from images/windows-bootcamp-msi.png rename to docs/images/windows-bootcamp-msi.png diff --git a/images/windows-iso.png b/docs/images/windows-iso.png similarity index 100% rename from images/windows-iso.png rename to docs/images/windows-iso.png diff --git a/images/windows-mbr-format.png b/docs/images/windows-mbr-format.png similarity index 100% rename from images/windows-mbr-format.png rename to docs/images/windows-mbr-format.png diff --git a/images/windows-partition-1.png b/docs/images/windows-partition-1.png similarity index 100% rename from images/windows-partition-1.png rename to docs/images/windows-partition-1.png diff --git a/images/windows-partition-2.png b/docs/images/windows-partition-2.png similarity index 100% rename from images/windows-partition-2.png rename to docs/images/windows-partition-2.png diff --git a/images/windows-rsync-done.png b/docs/images/windows-rsync-done.png similarity index 100% rename from images/windows-rsync-done.png rename to docs/images/windows-rsync-done.png diff --git a/images/windows-rsync.png b/docs/images/windows-rsync.png similarity index 100% rename from images/windows-rsync.png rename to docs/images/windows-rsync.png diff --git a/opencore_legacy_patcher/__init__.py b/opencore_legacy_patcher/__init__.py new file mode 100644 index 000000000..c19240578 --- /dev/null +++ b/opencore_legacy_patcher/__init__.py @@ -0,0 +1 @@ +from .application_entry import main \ No newline at end of file diff --git a/resources/main.py b/opencore_legacy_patcher/application_entry.py similarity index 92% rename from resources/main.py rename to opencore_legacy_patcher/application_entry.py index e0448c12e..4a950b634 100644 --- a/resources/main.py +++ b/opencore_legacy_patcher/application_entry.py @@ -1,24 +1,31 @@ -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +application_entry.py: Project entry point +""" import os import sys import time import logging import threading + from pathlib import Path -from resources.wx_gui import gui_entry -from resources import ( - constants, - utilities, +from . import constants + +from .wx_gui import gui_entry + +from .detections import ( device_probe, - os_probe, + os_probe +) +from .support import ( + utilities, defaults, arguments, reroute_payloads, commit_info, logging_handler, - analytics_handler, + analytics_handler ) @@ -43,7 +50,7 @@ class OpenCoreLegacyPatcher: Generate base data required for the patcher to run """ - self.constants.wxpython_variant: bool = True + self.constants.wxpython_variant = True # Ensure we live after parent process dies (ie. LaunchAgent) os.setpgrp() @@ -111,3 +118,9 @@ class OpenCoreLegacyPatcher: time.sleep(0.1) arguments.arguments(self.constants) + +def main(): + """ + Main entry point + """ + OpenCoreLegacyPatcher() \ No newline at end of file diff --git a/resources/constants.py b/opencore_legacy_patcher/constants.py similarity index 98% rename from resources/constants.py rename to opencore_legacy_patcher/constants.py index ebf94cbcc..81281d565 100644 --- a/resources/constants.py +++ b/opencore_legacy_patcher/constants.py @@ -1,13 +1,13 @@ -# pylint: disable=multiple-statements -# Defines versioning, file paths and other settings for the patcher -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +constants.py: Defines versioning, file paths and other settings for the patcher +""" -from pathlib import Path -from typing import Optional +from pathlib import Path +from typing import Optional from packaging import version -from resources import device_probe -from data import os_data +from .datasets import os_data +from .detections import device_probe class Constants: @@ -739,23 +739,23 @@ class Constants: @property def app_icon_path(self): - return self.payload_path / Path("OC-Patcher.icns") + return self.payload_path / Path("Icon/AppIcons/OC-Patcher.icns") @property def icon_path_external(self): - return self.payload_path / Path("Icon/External/.VolumeIcon.icns") + return self.payload_path / Path("Icon/DriveIcons/External/.VolumeIcon.icns") @property def icon_path_internal(self): - return self.payload_path / Path("Icon/Internal/.VolumeIcon.icns") + return self.payload_path / Path("Icon/DriveIcons/Internal/.VolumeIcon.icns") @property def icon_path_sd(self): - return self.payload_path / Path("Icon/SD-Card/.VolumeIcon.icns") + return self.payload_path / Path("Icon/DriveIcons/SD-Card/.VolumeIcon.icns") @property def icon_path_ssd(self): - return self.payload_path / Path("Icon/SSD/.VolumeIcon.icns") + return self.payload_path / Path("Icon/DriveIcons/SSD/.VolumeIcon.icns") @property def icon_path_macos_generic(self): diff --git a/opencore_legacy_patcher/datasets/amfi_data.py b/opencore_legacy_patcher/datasets/amfi_data.py new file mode 100644 index 000000000..3a0ab9bfa --- /dev/null +++ b/opencore_legacy_patcher/datasets/amfi_data.py @@ -0,0 +1,63 @@ +""" +amfi_data.py: AppleMobileFileIntegrity Bitmask Data +""" + +""" +Within AppleMobileFileIntegrity.kext, Apple has a bitmask-based boot-arg (ex. amfi=128) +Below information is from reversed values in 13.0 Beta 6's AppleMobileFileIntegrity.kext +Currently only 'amfi=3' has been used by Apple publicly +- 0x3 used in 11.0.1 dyld source: + - https://github.com/apple-oss-distributions/dyld/blob/5c9192436bb195e7a8fe61f22a229ee3d30d8222/testing/test-cases/kernel-hello-world.dtest/main.c#L2 +""" + +import enum + + +class AppleMobileFileIntegrity(enum.IntEnum): + # Names set are solely for readability + # Internal names are unknown + AMFI_ALLOW_TASK_FOR_PID: int = 0x1 # Allow Task for PID (alt. amfi_unrestrict_task_for_pid=0x1) + AMFI_ALLOW_INVALID_SIGNATURE: int = 0x2 # Reduce sig enforcement (alt. amfi_allow_any_signature=0x1) + AMFI_LV_ENFORCE_THIRD_PARTY: int = 0x4 # Don't mark external binaries as platform binaries + AMFI_UNKNOWN_1: int = 0x8 + AMFI_UNKNOWN_2: int = 0x10 + AMFI_UNKNOWN_3: int = 0x20 + AMFI_UNKNOWN_4: int = 0x40 + AMFI_ALLOW_EVERYTHING: int = 0x80 # Disable sig enforcement and Library Validation (alt. amfi_get_out_of_my_way=0x1) + +""" +Internally within AMFI.kext, Apple references 0x2 and 0x80 as both 'Disable signature enforcement' +However 0x80 is a higher privilege than 0x2, and breaks TCC support in OS (ex. Camera, Microphone, etc prompts) + +Supported boot-args within AMFI.kext, last compared against 13.0 Beta 6 + + Within _initializeAppleMobileFileIntegrity(): + - amfi_unrestrict_task_for_pid=0x1 + - amfi_dev_mode_policy=0x1 + - amfi_allow_any_signature=0x1 + - amfi_get_out_of_my_way=0x1 + - amfi_unrestricted_local_signing=0x1 + - pmap_cs_unrestricted_local_signing=0x1 + - amfi_ready_to_roll=0x1 + - cs_enforcement_disable=0x1 + + Within AMFIInitializeLocalSigningPublicKey(): + - -restore + + Within macOSPolicyConfigurationInit(): + - amfi_force_policy=0x1 + - amfi_block_unsigned_code=0x1 + - amfi_force_cs_kill=0x1 + - amfi_hsp_disable=0x1 + - amfi_hsp_logging=0x1 + - amfi_allow_bni_as_platform=0x1 + - amfi_allow_non_platform=0x1 + - amfi_prevent_old_entitled_platform_binaries=0x1 + - amfi_allow_only_tc=0x1 + - amfi_allow_only_tc_override=0x1 + + Within configurationSettingsInit() + - amfi_enforce_launch_constraints=0x1 + - amfi_allow_3p_launch_constraints=0x1 + - BATS_TESTPLAN_ID="Custom Team ID" +""" \ No newline at end of file diff --git a/data/bluetooth_data.py b/opencore_legacy_patcher/datasets/bluetooth_data.py similarity index 89% rename from data/bluetooth_data.py rename to opencore_legacy_patcher/datasets/bluetooth_data.py index da76bf238..7409aa10f 100644 --- a/data/bluetooth_data.py +++ b/opencore_legacy_patcher/datasets/bluetooth_data.py @@ -1,3 +1,7 @@ +""" +bluetooth_data.py: Enum for Bluetooth Chipsets +""" + import enum diff --git a/data/cpu_data.py b/opencore_legacy_patcher/datasets/cpu_data.py similarity index 93% rename from data/cpu_data.py rename to opencore_legacy_patcher/datasets/cpu_data.py index 49a6766b2..fde9221a4 100644 --- a/data/cpu_data.py +++ b/opencore_legacy_patcher/datasets/cpu_data.py @@ -1,3 +1,7 @@ +""" +cpu_data.py: CPU Generation Data +""" + import enum diff --git a/data/css_data.py b/opencore_legacy_patcher/datasets/css_data.py similarity index 99% rename from data/css_data.py rename to opencore_legacy_patcher/datasets/css_data.py index 76cd98835..49ca8735f 100644 --- a/data/css_data.py +++ b/opencore_legacy_patcher/datasets/css_data.py @@ -1,4 +1,9 @@ -# Comprised of https://github.com/sindresorhus/github-markdown-css and additions for OCLP +""" +css_data.py: CSS data for project's update window + +Comprised of https://github.com/sindresorhus/github-markdown-css and additions for OCLP +""" + updater_css = """ diff --git a/data/example_data.py b/opencore_legacy_patcher/datasets/example_data.py similarity index 99% rename from data/example_data.py rename to opencore_legacy_patcher/datasets/example_data.py index 99a1fc086..d0a6dea87 100644 --- a/data/example_data.py +++ b/opencore_legacy_patcher/datasets/example_data.py @@ -1,6 +1,9 @@ -# Example Hardware probe of multiple models -# To be used when running validation tests -from resources import device_probe +""" +example_data.py: Sample Hardware probes, for use in OpenCore Legacy Patcher validation +""" + +from ..detections import device_probe + class MacBook: diff --git a/data/model_array.py b/opencore_legacy_patcher/datasets/model_array.py similarity index 98% rename from data/model_array.py rename to opencore_legacy_patcher/datasets/model_array.py index 3f7fa69e2..ff76d01d8 100644 --- a/data/model_array.py +++ b/opencore_legacy_patcher/datasets/model_array.py @@ -1,5 +1,8 @@ -# Lists all models and required patches -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +model_array.py: Datasets for different models +""" + + SupportedSMBIOS = [ # MacBook "MacBook5,1", diff --git a/data/os_data.py b/opencore_legacy_patcher/datasets/os_data.py similarity index 99% rename from data/os_data.py rename to opencore_legacy_patcher/datasets/os_data.py index bc6e51655..3e16bf5fa 100644 --- a/data/os_data.py +++ b/opencore_legacy_patcher/datasets/os_data.py @@ -1,6 +1,11 @@ -from curses.ascii import isdigit +""" +os_data.py: OS Version Data +""" + import enum +from curses.ascii import isdigit + class os_data(enum.IntEnum): # OS Versions, Based off Major Kernel Version diff --git a/data/pci_data.py b/opencore_legacy_patcher/datasets/pci_data.py similarity index 99% rename from data/pci_data.py rename to opencore_legacy_patcher/datasets/pci_data.py index 53a81e979..35f5585ad 100644 --- a/data/pci_data.py +++ b/opencore_legacy_patcher/datasets/pci_data.py @@ -1,4 +1,8 @@ -# Array of Device IDs for different devices +""" +pci_data.py: PCI Device IDs for different vendors and devices +""" + + class nvidia_ids: # Courteous of envytools as well as MacRumors: # https://envytools.readthedocs.io/en/latest/hw/pciid.html diff --git a/data/sip_data.py b/opencore_legacy_patcher/datasets/sip_data.py similarity index 99% rename from data/sip_data.py rename to opencore_legacy_patcher/datasets/sip_data.py index 393988d7e..74a026bb1 100644 --- a/data/sip_data.py +++ b/opencore_legacy_patcher/datasets/sip_data.py @@ -1,4 +1,10 @@ -from data import os_data +""" +sip_data.py: System Integrity Protection Data +""" + +from . import os_data + + class system_integrity_protection: csr_values = { # Source: macOS 11.4 (XNU's csr.h) diff --git a/data/smbios_data.py b/opencore_legacy_patcher/datasets/smbios_data.py similarity index 99% rename from data/smbios_data.py rename to opencore_legacy_patcher/datasets/smbios_data.py index 78170dff2..011b2100e 100644 --- a/data/smbios_data.py +++ b/opencore_legacy_patcher/datasets/smbios_data.py @@ -1,24 +1,35 @@ -# Defines Model Data -# Terms: -# AAPL: AppleInternal Model (ie. not released to public) -# Board ID: The board ID is a unique identifier for the motherboard. -# Firmware Features: Hex bitmask denoting supported abilities of firmware. (ie. APFS, Large BaseSystem, etc.) -# Secure Boot Model: T2/Apple Silicon Model Identifier -# CPU Generation: Stock CPU supported by the board (generally lowest generation) -# Wireless Model: Driver used for wireless networking -# Bluetooth Model: Chipset model -# Screen Size: Size of the screen in inches (generally lowest size if multiple in same model) -# UGA Graphics: If model needs UGA to GOP conversion -# Ethernet Chipset: Vendor of the ethernet chipset (if multiple unique chipset within Vendor, chipset name is used) -# nForce Chipset: If model uses nForce chipset -# Switchable GPUs: If model uses a GMUX -# Stock GPUs: GPUs variations shipped +""" +smbios_data.py: SMBIOS Dictionary for model data +""" -# Reference: -# https://github.com/acidanthera/OpenCorePkg/blob/master/Library/OcMacInfoLib/AutoGenerated.c +""" +Terms: + AAPL: AppleInternal Model (ie. not released to public) + Board ID: The board ID is a unique identifier for the motherboard. + Firmware Features: Hex bitmask denoting supported abilities of firmware. (ie. APFS, Large BaseSystem, etc.) + Secure Boot Model: T2/Apple Silicon Model Identifier + CPU Generation: Stock CPU supported by the board (generally lowest generation) + Wireless Model: Driver used for wireless networking + Bluetooth Model: Chipset model + Screen Size: Size of the screen in inches (generally lowest size if multiple in same model) + UGA Graphics: If model needs UGA to GOP conversion + Ethernet Chipset: Vendor of the ethernet chipset (if multiple unique chipset within Vendor, chipset name is used) + nForce Chipset: If model uses nForce chipset + Switchable GPUs: If model uses a GMUX + Stock GPUs: GPUs variations shipped + +Reference: + https://github.com/acidanthera/OpenCorePkg/blob/master/Library/OcMacInfoLib/AutoGenerated.c +""" + +from ..detections import device_probe + +from . import ( + cpu_data, + os_data, + bluetooth_data +) -from resources import device_probe -from data import cpu_data, os_data, bluetooth_data smbios_dictionary = { "MacBook1,1": { diff --git a/data/sys_patch_dict.py b/opencore_legacy_patcher/datasets/sys_patch_dict.py similarity index 99% rename from data/sys_patch_dict.py rename to opencore_legacy_patcher/datasets/sys_patch_dict.py index 417b410dc..0227a10bb 100644 --- a/data/sys_patch_dict.py +++ b/opencore_legacy_patcher/datasets/sys_patch_dict.py @@ -1,9 +1,10 @@ -# Dictionary defining patch sets used during Root Volume patching (sys_patch.py) -# Copyright (C) 2022-2023, Mykola Grymalyuk +""" +sys_patch_dict.py: Dictionary defining patch sets used during Root Volume patching (sys_patch.py) +""" import packaging.version -from data import os_data +from . import os_data class SystemPatchDictionary(): diff --git a/data/usb_data.py b/opencore_legacy_patcher/datasets/usb_data.py similarity index 94% rename from data/usb_data.py rename to opencore_legacy_patcher/datasets/usb_data.py index 2ffb7f194..affdfdc98 100644 --- a/data/usb_data.py +++ b/opencore_legacy_patcher/datasets/usb_data.py @@ -1,7 +1,12 @@ +""" +usb_data.py: USB Device IDs for different vendors and devices +""" + + class AppleIDs: # All top case devices use Vendor ID 05ac Modern_AppleUSBTCKeyboard = [ - 0x223, + 0x223, 0x224, 0x225, 0x230, @@ -53,7 +58,7 @@ class AppleIDs: 0x22a, 0x22b ] - + AppleUSBTrackpad = [ 0x20e, 0x20f, @@ -75,7 +80,7 @@ class AppleIDs: ] AppleUSBMultiTouch = [ - 0x223, + 0x223, 0x224, 0x225, 0x230, diff --git a/data/video_bios_data.py b/opencore_legacy_patcher/datasets/video_bios_data.py similarity index 99% rename from data/video_bios_data.py rename to opencore_legacy_patcher/datasets/video_bios_data.py index ef7d2d0aa..3ea6623a2 100644 --- a/data/video_bios_data.py +++ b/opencore_legacy_patcher/datasets/video_bios_data.py @@ -1,11 +1,16 @@ -# iMac MXM adopted legacy video BIOS for device property injection -# create by Internetzel and Ausdauersportler -# -# technical details on -# https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN -# recipe to build a iMac compatible NAVI vBIOS -# https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN/wiki/ObjectInfoNavi -# +""" +vbios_bios_data.py: VBIOS data for iMac MXM +""" + +""" +iMac MXM adopted legacy video BIOS for device property injection +create by Internetzel and Ausdauersportler + +technical details on +https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN +recipe to build a iMac compatible NAVI vBIOS +https://github.com/Ausdauersportler/IMAC-EFI-BOOT-SCREEN/wiki/ObjectInfoNavi +""" RX5500XT_64K = "55AA70E93703000000000000000000000000000000000000E8020000000049424D70D08E000000000000000000000004203736313239353532300000000000000000000000000000C00200000000000031302F31322F32302030353A3330000032000000E9250400E92F040000008C010A000000000000000B000E81871F50000000000001000100013088791E45A879140210BDC16F1CCFF9FF1F000000000000C4AFF83F000000000000000000407338AB467344730C0005003103D031375500F8801042F0DF03002C232020024802488CE600001EA8000F8008F03EA768747871782100210001002CC04C60192000300003800C0C00003610075280180C0E0A00000004F002000000080000000000084018107001000020000000040000001C040000C800000030000000000000084000000000000000000000001C32001C5E049000000000000000000000000000000000E42709401018006400000000C098070000407A01A000280000008010900118000008008081470100F0A11F11300000000020000000000000003131332D454D32344738472D533030004E4156493134005043495F45585052455353004744445236000D0A4E41564931342047616D696E6720585458204131204B394131325143412E534C42203230323020323333332F31343937342020202020202020202020202020202020202020202020202020200D0A000D0A200D0A0028432920313938382D323031382C20416476616E636564204D6963726F20446576696365732C20496E632E0041544F4D42494F53424B2D414D44205645523031372E3030322E3030302E3030302E303030303030004B394131325143412E534C420032313834313436200035333536363420200020202020202020200054554C5F4E41564931345F454D3234475F53414D5F4744365F38475F393557323032303130313254554C5C636F6E6669672E68000000902800020241544F4D00C0370461020D03B5016A040000000087170124E8021C92C292000074C80000504349520210407300001800000000037000021100000000414D442041544F4D42494F53009C4BB41D00000000000000000000000000000000000000000000000001000000000000000000000000000000000000001E0666506651665266536655665666570E1FA314008C0E0800B220E88F2C0BC07514A20200665F665E665D665B665A66596658071FCBE8A92DE87B2B32D28D3EC002895516E83C11E8FF10E85612E8AD02E835280BC0740CE83900E88353E8FB10E8D853E8A900B480E8752B8AC766C1E0108AE3B02066A3D08EE8AC02E80E11E8A22D665F665E665D665B665A66596658071FCB2E8B1E0800833E4904007504891E47041E2E8E1E3F049CFA66C706080165F000F0C70640006A04891E4200C706B4016A04891EB601C7067C00B25C891E7E00C7060C01C560891E0E01C706A804E456891EAA042E8E1E47048BC3A3E656A3F656A308579D1FC3504D49446A041647000000A000B000B800C000000000BB0000E8611066C1E810A3EE02BB0B00E854108D3EC00266894518C300E8D02C80FCA07505E83D00EB1180FC4F7505E8BD41EB07E81247EB02B401E8D72CCFE8AE2CE82000EB02B401E8C92CCBE8A02C80FC4F7505E89741EB07E8EC46EB02B401E8B12CCB1E0666506651665266536655665666570E1F3C0475292EA11A0066C1E0102EA118008D36B2018A3C80EF30B3028BEC895E0C89460466C1E810894600E928013C057518E8262AE8F9292EA108008BEC895610894600895E04E90C013C067532E8880F66D1E08BEC894614BB0200E8920F884618E87C0F6689460CBB0900E8820F33C0668946002E8B16EE02895610E9D6003C0B75240ADB7511B98000BB02008BEC895E0C894E14E9BD008AC7E8D000E834010F84A900E9AE003C17751DE831127406E88B0DE80C17E8EE09E8FA0E33C98BC88BEC894E14E98D003C1875450AFF7510E8B8118BEC89460CE83B0A894E10EB75E8FC117568BB001CE82C2B660BC0745D23C97459E8D011BE001CE8200F744EBE001CB040E86F0FE881118BEC89460CEB443C82751A80FB0575150AFF750AE8C5108BEC894614EB2DE892107418EB263C8E751280FF01740880FF02750880C102E8EB10EB108BECC6461902EB0F8BECC6461901EB0732E48BEC886619665F665E665D665B665A66596658071FC3518AC8B80100D3E059C3E84A2BC30C01C35051B0B6E643B033E642B005E642E4618AE00C03E6618AC4B9C800E81627E6615958C3001E560E1F803E0200807605C6060200808A0E0200C1E109FCC60621000033F632E4AC02E0E2FBF6D4FEC4882621005E1FC300570BC0750FE82A0C7425E82400F6C30474F3EB118BC8E8152523C17412E81100F6C304740A5F8D5C28E84C060BF6C35FC350E8DF0BE86724E875240AC974690AED74108ACDB502E81726B1028D9C4801E89429E87602F6C3047408E8F20CE8D82274458D5C28E869005683C608E8A4225E80FD02751151E804185980FB00754D51B508E8E805598ADD33C9E8F5160AC0753BE837028AEB8D5C2880CD02E83B00740380CD04E8C6058D9CA600E894290AC0741A5683C608E85A225E8ADDB98000E8C016E8D804740533C9E8A105E8FC0158C351B94900E8B42559C351E81A007514E8B9013C01750DB92000E82700750580C901EB0233C959C353E84629663D00FFFFFF750E83C304E83829663DFFFFFF0075005BC3505232D2E8272902D002D466C1E81002D002D483C304E2EC0AD25A58C3E8DF0A8D9C4C01E83901E88D01B513F6C308750CE8070C8AEA80FD137502B50366508D9CB8026633C08AC5E843286658A9C80E7455E86201F6C308740FE80F058D5C28E804017504E87200C3B502E82301E84601F6C30474218D5C28E84901E894037405B503E80B01E86804E8210180FD007548B502E80D01C38D9C6801B80055E85111B502E8FD00C3A90200742DB504E8E000E80301F6C3087403E8B0048D9C680156E83A268BF7E868045EE8D725E8D3008D5C28E8F725E81804C3B501E8B200B502E8BF00E8D000F6C30475108D9C6801B80055E8FC10B502E81700C3E8C600B5028D5C28E86E007502B501E80400E8E003C38D9CB402B102E8B727B502E88300C38D9C4C01E83800E88C00F6C30474238D5C28E88F00E8C5258D9C6801060E07B90700E86C2407E86300E8EE0A8D5C28E8B6258D5C28E85425B80200E8BEFEC3B96100E81224C35381C30501E8BF2724063C025BC3E810003D0104750A5383C318E8AA275BA801C35383C312E89F275BC38D9CB40232C9E83827C38D9CB402E88C27C38D9CB402B101E82627C38D9CB402B101E83427C366508D9C4801E86E278AD86658C3555751B90800BD0000BB08002BD9D1E38D584EE85327E8E301E2EE8D5C4BE84827B903008BD0BF520A8555067417668B058D9AF401E891268B45048D9AF801E89F2683C50883C708E2DF8D7C5EB9040033ED8BDFE812270BC07409E85D01E8970083C51C83C712E2E95532EDE86FFF8D5C28E84EFF3D0104751083C314E8E9262470C0E8048AE8E854FF5D8D9CA600E8D7260AC074468D9CA800E8CC263C02753B66C1E8103C0472338D9CA80032E403D88BFBB904008BDFE8AE260BC07415E8F900A98000750DE82E0083C51C555883F870730883C712490BC975DA595F5DC3200358023C000100000400033C0000088002E0013C002000518D1DE86B268D9A6801E8DC258D5D02E85E268D9A6A01E889008D5D05E851268D9A6E01E87C008D5D08E844268BC88ADC66C1C8108AD080E20F8AF0C0EE048AECC0ED068AFCC0EF0480E70380E40FC0E4040AD480E23F80E4C0C0EC020AF48BC38D9A7401E881258D9A72018BC1E878258D9A760133C08AC6E86D258D9A780133C08AC2E862258D5D0CE8E4258D9A7A01E80F008D5D0FE8D7258D9A7E01E8482559C38BC88AD466C1C8108AF080E60F8AE8C0ED048BC1E82F2583C3028BC2E82725C38D5D11E8A8258AE0BA0600C0E807740380CA808AC4C0E80324033C02750380CA403C0375128AC4D0E8A801740380E2FDA802740380E2FB8BC28D9A8001E8E624C33C01743D8BD00FB6C6243F043C8D9AF801E8D1240FB6C283C01FC1E0038D9AF401E8C1240FB6DEC1EB06C1E3022EF7A7B20B2EF7B7B00B8D9AF601E8A72483C508C310000A000400030005000400100009008D9CA600E814250AC0741F8D9CA80051B103E81800590BDB7410E8FE2432C0663D00030C0075030BDBC333DBC3665052E8E8243C02753980FC03723466C1E81032E43C04762A03C38BD083C3043BDA731FE8C7248AE080E4E0C0EC05241F38CC740832E4FEC003D8EBE30BDB5A6658C333DB5A6658C3518D9CA600E89D240AC0741B8D9CA800B112E818007410E88B2466C1E81080E4077504B001EB0232C00AC059C3665052E872243C70752B66C1E81032E483C30503C38BD03BDA731AE85A2438C8740D66C1E81032E483C00303D8EBE80BDB5A6658C333DB5A6658C35766518D9C68018BFB8BDFE83D000BC9740B668BD1E8970F83C71CEBEC66595FC3505351B90700538BDAE8102483F8005B740966C1E3108BDAE86020595B58C35153B90700E86D205B59C366505383C306E8E9235B8BC866C1E1105383C302E8DB238BC85B6658C38D9C480132C9E87023C357B92000E848205FC3E88301668BCA6652E8C406E8AA1C665A7410E83A06B300E89619663BCA7303668BD18D9CD003E899230BC075448D9C540266B8483F0000E8E822B5016681FA78690000722583C30466B878690000E8D122B5026681FAF0D20000720E83C30466B8F0D20000E8BA22B503B103E8CF01EB4566B9080000006633D2538D9C54028BD35BE83D230BC074226625FFFF000066D1E0538BDAE88A225B66C1CA10FEC266C1CA1083C20483C302E2D766C1CA108AEAB103E88801E83806A801743F8D9CAE03E8FE223C007434E8CF058AEBE85C0132EDE86301E8A2058D9CBB02E8E32233C98AC8E82801663BC2740E51E84301FEC5E8440159E2ECEB03B300C38D9CBB02E8BF22FEC88AE8E82E018D9C4003B90000E85222E8C202E8D200E80F016652E8AD05E8931B665A7504B300EB58E8F60080FD017707E8FA000AED7447E81E03E8281180FB00751DE8A705A8017407B10DE83F19EB30B501E89E05E8250FB500E89605EB21E8BF0080FD017607D0EDE8BB00EBBAE87600E8B300E8B600FECDE8B700EBAAB308C38D9C2901E835226633D28AD066B88C0A000066F7E2E83105E8171B753D66508D9C2801E816223C146658722E66508D9CD003E807220BC06658741FB908008D9CD0038BC1D1E003D8E8F1210BC07502E2ED6625FFFF000066D1E0660BC07503B8483F668BD0C38D9C2A01E8CF21240F8AE80AED7502B501C3B5008D9C3101E8BB21A8017402B501C35351E81F0032E48AC5C1E002598D9C540203D8E89E215BC3B102E81D00C3B102E80D00C3B101E81100C3B101E80100C3538D9CB802E820215BC3538D9CB802E82E215BC333C9E87F1E753C66BA37F1FFFF6633C0E8E30433C0E84703741CA9C80E74F6E83CF7F6C3047505F6C31874E9E8300050E82CF858EBDFE81C007508E831008BC1E81CF8C38D5D2866C1E3108D5C28B94900E87B1DC36650E8B5048BC86658C3665266BAFFFFFFFF33D0E88A04665AC3505352E8E0FF750933C0E8E3028BC8EB1083F902740BE82F0880FB01750383E1FD5A5B58C3566633C066BA00F0FFFFE8520766C1E610E8C4020BC07403E81C00E832075EC36652668BD0E8D2158D9C1C03E8AD208AC2E80820665AC35051E871025032C0E80004E8CC01E898008D9C4003E88D2038E8740A8AC5E8E41FB002E8E50358E8CA00E8A800E88C008D9C4C01E86E208BC88BD38D9C0003E863203BC17405B002E8C003E83BFC8D9C0003E84B158D9CD802E8A91FE88AFF66C1CE108BFE66C1CE10E89500E8D100E824038AE98D9CDC0232C9E8CC1FE80D036625FF0F0000595866BAFFFFFFFF33D0E8950633D2C35366508D9CD402E805208AC4E8601F66585BC35366508D9CD402E8F21F8AE0E84D1F66585BC3E87302E82E028ADDE893168AE98D9C3C0332C9E8771F0BDBC383EC088BECE85502E81002E819168D9C4C03E8BB1F8A4600E8151F83C408C38D9CD402E8AA1F32C0E8051FC3E80A008D9CD00232C9E83C1FC3B5008D1DE8901F668BD08D9C0203E8861F0BC0741C518BC88D9C0603E8781F66C1E0108BC159663BC27504B500EB02B502C3E82B028D9C4003B103E8FD1EE8D5F78D9C4003B102E8F11EE8950180FD007514E8A6FDE88E02E888FD668BD0E87702E88E02EB21E84A02E86C02E8730180FD02B504750B81FA74407605B50866D1EAE86E02E85F02E82B00C366525232ED83C102B80600F7E16633C98BC85A51668BC28ACF66F7E166C1E0035966F7F1668BC8665AC3B500E8EA01E8CC177503E811FD8D9C480332C9E8701EC353E85F0166C1E210E84D018D9CB802E8B91E8AE88D9CB402E8B01E8AC8E8BA148AEB5BC3575353E8D6FFE82B015BE81F15746680FD00752953E8DBFC668BD0E808F78ACD51E8E7FC8AFD59E871FF5BE8791E6625FFFF0000663BC8733932DBEB3880FD027516E86F01E8621774288D1FE8581E3D7440761E32DBEB1D80FD03751553E8D300B303E82F145BE83D1E3BC2760432DBEB0380CB015B5FC3538BF0E8141923F074098BC6E8B3178BF30BDB5BC351E815FDE80F0059C35150E8F7188BC858E8020059C35753E828190BC074098B1D83C7023BC375F78B1D83FBFF740B83C70285D974F28BC3EB0233C00BC05B5FC333C0E8C3FF7413E8A0FF8BDEB9FB00E8111A83C608E85C18EBE8BBF016B85AA5E82E1DC35366508D9C4003E8AB1D8AE866585BC38D9C6903E89E1DC38D9C6403E8961D0BC0C35366508D9CD402E8891D8AC866585BC35366508D9CD502E8791D8AC866585BC3538D5C14E86C1D8BD05BC35366508D5C16E85F1D8BD066585BC35366508D9C5003E84F1D668BD066585BC35366508D9C5403E83E1D668BD066585BC35366508D5C10E82E1D8BC866585BC36650538D9C4103E81E1D5B8AD86658C3538D5C08E8111D5BC353508D9C4C03E8061D8AC8585BC353508D9C4D03E8F81C8AC8585BC35366508D5C0CE8EA1C8BD066585BC35366508D9C0003E8DA1C6633D28BD066585BC38D5C04E8CB1CC3518D5C0432C9E8651C59C38D9C5003E8B81C668BC2E8121CC3538D9C4003B101E84B1C5BC38D9C5403668BC2E8FB1BC353518AE8E8C2FF24FD0AE8E8C2FF595BC366508D9CD802E8801C668BD06658C353665051668BC8BB0000E8E11523C20BC1E8E3155966585BC3BB0000E8CF156625CA0E0000C3E85918E8E817E8C6177506E84317E8CA17C3B001C355B301E82D1A5DC3665366BB04000000E8050033C0665BC35566C1E310BB0000E8101A5DC3E81819BB0A00E88E15C3BB0A00E87E15668BC8E80519BB0A00662BC1E87815C3E829000BC97422E814FBE824076651668BC8BB0700E85615662500FE0000660BC1E8531566590C01C332C0C3E86B020BC97506E8C3FAE8710251E8BCFA66C1E61033C0E89AFD7409E8090375F633C8EBF25823C866C1EE10C3A8107563E8E30666C1E61033C0E880FD7435E85DFD50518BC8E8F90185C15958740D50E8AAFE24033C035875E0EB0C50E89DFEA8015874D5E86AFB50E8CD0758B500E892FEEBC6E8CB01E825FDE83401B100E8410766C1EE10E88706A8207542A8407503E80F0EE86E060AC0750732C9B501E8B20EE89D01E8F7FCE830FEE816147514E862020ADB740DE818FBE87C07B500E842FEEB08E85907B501E838FEE8E600C3E8E615C3E81EFDE89F0633C9E89F016633D26633C0E86CFEE85200B1FFE8840033C0E8C8FC740AE8A5FC50E8C50758EBF132C9E8C401E8B0150BC0C3E8E6FCE867066633C066BA00F0FFFFE8330151B101E88C015933C0E893FC740AE870FC50E85B0758EBF1E8A70DE87F16C3B80200E85CFC742EB107E8CA11B80200E86CF0F6C3047512E84618833D00750AE8591583E0FDE85C15C366B802000000E8E4FDE84EF2C3E8DD13742338E176048ACCEB0638C173028AC8BB0200E8B5138AE1E8B913B104E87D110C01C30C01C351E8B313740C8ACCBB0200E897138AC48AE159C3E8F105C3E8FC05C3E826177518E88100E8DBFB80F901750E51E85306B501E832FD59E8DFFFC3E8D7FF51E8B006B500E821FD59C3B80200E8B4FB7403E82411C3E8B0043BC17C3A8BC1E8F004E8BA0E8BC851E82005E8E40459E8AD0E3BC872028BC18D5C04E82D1932C9B50FE8F80CE8EC15FEC138C172F28D5C04E89F190BC0C333C0C3BB001833C08AC2C1E00203D8C353BB0300E8F9126625FF0F00005BC35366506651668BC8BB0300E8E3126623C2660BC1E8E312665966585BC36650BB0500E8CC1225FF0F8BC86658C3E8381423C86650BB0500E8B7122500F00BC1E8B8126658C3665053BB0600E8A312A8107509BBF016E825193D5AA55B6658C3665053BB0600E8891280F101C0E10424EF0AC1E885125B6658C3536650BBF816E8FB188AC1E8561866585BC353BBF816E8EB1883E0015BC3536650BB0700E85112F6C4016658B0067402B0085BC353BB0700E83D1280E4FE80FD06740380CC01E838125BC36650BB0600E825122440C0E8068AD86658C3C3506651E871FA83EC048BEC6633C06689460033D28DBC68018D1DE889180BC074228BDFB000E8120174148BDFE885F4668B4600663BC872068BD766894E0083C71CEBD50BD2740A8D9C4C01E83CF4E988006633C0668946008DBCF40133D28D1DE843180BC074586650E8A7F03C01665874053D400673436652668BD08D5D04E82418E85D008BCA665A742F568D9C4C018BF1E814F45EB000E89F00741D8D1DE804188BD98B470666C1E0108B4702663B460072068BD16689460083C708EB9F0BD27416568D9C4C018BF2E8DCF35E538D9C620133C0E846175B83C4040BD2665958C3575351E805133B5502751866C1CA108BDA66C1CA103B5D0675090AC0740E3A451B740983C71CE2DE33D2EB028BD70BD2595B5FC3516652E8D1123A651A75090AC0740E3A451B740983C71CE2ED33FFEB000BFF665A59C3C366516652535366C1CE108BDE66C1CE10E859175B668BD0E860F33BCA720A663BCA7205E89FF8750232C05B665A6659C35657E8A7FF8BF7E835F35F5EC36650536651525756518BDEB90800E86813598D5C088BC166C1E0108AC2E86F16F6C20375248BC1247FBFF71A803DFF0F840F013A05750D668B450166B900050200E9960083C705EBE3F6C20174258BC1E870010F84EB0033C98ACC8AD00AC075128D5C086625FFFF000066C1E008E81E16EBB28AE18ACA80E10CC0E90280E2F0C0EA048AEA80FC70722A80FC75732580EC708AC432E450E830028BD85838D8720533C0E99C00E82802E883160BC00F849000EB1B32C0E8E6FE0F8485008D5C168B05E8E2158B450666C1E0108B450250E8480B66C1E1108BC8588D1CE8B01566508D5C04668BC1E8A515665866C1E8106681E1FFFF000066F7E166508D5C06E82D168BC8665866D3E066C1E810408D5C14E89315BF571B83F9017411BF5F1B81F901017408BF671B83F90275158D5C0C668B05E859158D5C10668B4504E84F150BDB5E5F5A66595B6658C3004001900101400190010280029001038002900104400190010540019001068002900107D0025E010D400190010E800290010F80025E011080025E01118002E001128002E00113800290012320049001322004B002332004C002628002E001FF050A050505000000050B060505000000081008080800000056E8CF1280E4013B04740983C604E2F733C0EB058B44020BC05EC3575350E8B21283E90AE8E00083F8057603B80500D1E003C8FBA583C602E2FAB8FFFFAB585B5FC36653516652E84100E8770066C1E810660FB7D866B80000000366D3E86633D266F7F3E8F109665A59665BC3536650BB0700E86A0E0AC066585BC3536650BB0700E85B0EA80166585BC35366508D5C06E8D8148AC866585BC351B90800E82A1159C3538D5C08E8C21424035BC38D5C09E8B814C35153B1018AE88D5C08E84F145B59C3538D1CE8A2145BC3538D5C04E899145BC3538D5C16E890145BC353665233C0E8C2FC665A751BE834007416E815004083F805730DE8D11348E80F00668BC2E8C7135BC3BB001EE85F14C3BB081EC1E00303D8C3BB001EB93200E89610C351E8E2FF0BC074128BC8BB081EE83B14663BC2740783C308E2F30BDB59C3C300C300BB20DFE8E333E88DF6B501E8E507C3BB00DFE8D433E87EF6B500E8D607C380F900750AE84A108AC8B502E81D090BF6742EE862F6B50151E8C00759E8C3075633F6B500E82D075EB501E8CEF6E8FB08E8C409E841F68D9C0003E8AC07E8F50766C1CE10B501E80B07E800FFA840750732C0B501E87E0866C1CE10C3E818F6B501E84B07B500E87907E8DC07B10FE8690AE82600C3E85200E80CF6B500E82F07B500E85D07E881F6E8C60F38C1740A80F90B7405B503E89208C3B110E83B0AE8B3F580FD007406B101E8A40AC3E8A60580FD017507B502E8D505EB03E8F301B10DE8160AB103E85400C3E8D5F50BD27405B100E8420AB102E84200E85BF6A8017412E870F580FD00750AB10CE8EB09B002E89104B100E8570AB10DE81F00C3B107E84C0AE89BF50BD2750CE809F6E8EB0B7509E8F20AC3B107E8FC09C3E8F7F5E8D90B752451E8270A5980F90C751A33D25683C608E8020C5E0AC0750CB90A00E8620F4283FA1E75E8C380FB010F84C500E8A50566C1E1108D9C3501E8AB12A801740551E82B0459E868F5B004E89C0566BA50014050E87605E8B80A757E66BA5001504F8D9C2D01E87F1224063C027502B602B005E87405E854058D5C2803D8E8910A75570AFF7509B00AE85E0532DBEB4A5133C98ACFE8350503C8E83A0559B007E8470566BA5001103033DBE8640A740F518AEB8D9C4401B102E8D01159EB61E80B0566C1C9102BC166C1C1103D80000F8276FFB008E81205EB43518AEB8D9C4401B102E8A6115966BA5001103033DBE8200AEB2C8D5C2803D9538AE9B132515FE8AEF48AE9B1A0BA0080E8DA0980FF015B740AB1A2E8CF0980FF017503B000C3B001C351B10CE8D2FE59B001E8BB045683C608E8E20A5E0AC07504B310EB3FB002E8A604E838007411B003E89C04B001E810037529E82700752466BA0C0090438D9C3001E8AB0966BA200090418D9C3401E89E09E8BD03B009E86E0433DBC3E82FF466BA000090478D9C2801E88309C3B10CE866FEB100E89408B101E88F088D9CAC0366B800000000E89C10B001E8B202740AB504E8CB03B308E93F01B108E8F607E8D202B109E8EE07E8C5018D9CB8036633C0E87110E86001B99001E8980DB001E86302B502E88D03E87401E89F03E8E001B503E87F0333C9E80001F6C5017534B502E87003E82001F6C5047408B501E86F03E9CC008AFD80E703E8E80080E30338FB750DE84C017508B502E85303E9B000E86701FEC1E885F338D975BB8D9CAC03E8A2103C037405E8ED00EB9B8D9CB0036633C0E8EF0F8D9C2A01E88810A840740CB113E84F07B003E8DA01EB0AB10AE84307B002E8CE01B504E8F802E8DF00E80A03E84B01B505E8EA0233C9E86B0080FD077505E88600752E51B504E8D50259F6C5017507B503E8D602EB34E878008AD5E8E600E8700038EA750CE8B4007507B502E8BB02EB19FEC1E8F1F238D975BC8D9CAC03E80E103C047505E85900EB9CB000E86001B10BE8CB068D9CAD03E8F40FB3000AC07402B308C38D9CC003E80F008AE8C3538D9CC403E804005B8AD8C351E8D10FC0E102D3E8240F59C38D9CC203E8C10FA801C38D9CB803E8730FC38D9CB803E8530FC333C933D2E8E9FF38D576028AD5FEC1E874F238D972EE33C98AEA8D9C5C03E8310FB10BE8CE06C3E84DF28D9CB803E87D0F66BA03018083E89E07C351538D9CB003E8260FFEC5E8090F80FD067207B502E8F60133C95B59C36633C08D9CB003E8AC0EC332EDE865FF80E30CC0EB02B7032AFBC0E3038AEB80FB18720380CD20E84BFF80E30338FB72028ADF80FB03750380CD040AEBE860FFC3E8DBF18D9CC00366BA02029045E82F07C3E8CAF166BA000190428D9CB403E81E07E8BAF166BA030190458D9CB803E80E07E8EEF1E8D407753BE8A2F166BA0A0190408D9CBF03E8F6068D9C2801E8C50E3C147220E887F166BA1000904F8D9CD003E8DB06E877F166BA150190408D9CCC03E8CB06C3E866F166BA02018050E8BE06C3E848F18BC26633D2B98C0AF7F1C3E84BF166BA00068050E8A306C3E83EF166BA11018050B004E89406C3E82FF166BA000690408D9CC803E883068D9CC803E8520EC3E8BBFF3C06740E3C0A740A3C1474063C1E740233C0E811F18AE380CC8050E8F9F05866BA00018061E8500633C9E884F00BC07402B5108D9CBC03E8B80D8AC5E8D8F066BA07018050E83006E810F1E8F60675498D9C4803E8F70D0AC0740EE8B9F066BA0A018050B001E80F068D9C2801E8DE0D3C1472258D9CD003E8D30D0BC0741AE83CEC32C98D9CCC03E8670D8AC5E887F066BA15018050E8DF05C38D9CB403B90E00E8F409E8A3FEE88FFEE838FF3C01751CE8D2FD741733C9E8A8FD80FD07750DFEC1E861F038D975EFB501EB02B500E80100C38D9CAC03B102E8160DC3518D9CAC0332C9E80B0D59C3518D9CAC03B101E8FF0C59C38D9C3201E8520D24077515B964008D9CAC03E8440D3C027403B99001E8CA09C332E4B10433D2F6E18BC8E8C709C3518D5C14E8240D66C1E010E8A40159C3538D9C4401E8130D5BC35366508D9C4401E8070D8BC1E8620C66585BC353518D9C44018AE8B103E8950C595BC333C9E82D0938C17305B500E88C00B500E88000FEC1E81A0938C172E6B1148AE9E8120938C17405B503E8E301FEC1E8FB08041438C176E7C383EC0C8BEC0BF6741EE802F866C1C810668946008D5C04E89C0C668946048D5C08E8920C88460A894E088CD066C1E0108BC4BB2B00E8D80783C40CC383EC048BECB002884601884E008CD066C1E0108BC4BB2500E8B90783C404C3BB2300E80800C3BB1700E80100C383EC048BEC894E008CD066C1E0108BC4E8940783C404C3BB2200E8E3FFC3BB2700E8DCFFC3BB2C00E8D5FFC3E81E0C66A90000FFFF744083EC188BEC5551B9040083C302E8060C6689460083C50483C304E2F183C304E8F40B66C1C81066894600595D884E148CD066C1E0108BC4BB3100E8330783C418C3E83FEE8D9CD002E8CB0B8AE8BB2100E876FFC38D9C3C03E8BB0B8AF8E801EE8ADD538D9C4203E8AC0B8AE85BE813EEE8B0EEE896047502B30183EC048BEC884E00887E01885E02886E038CD066C1E0108BC4BB2A00E8D70683C404C383EC108BEC663DF0FFFF03760666B8F0FFFF03668BC86633C066894604668946006689460866B8000000D0660BC16689460C8CD066C1E0108BC4BB3500E8930683C410C383EC088BEC894E0066895602895E068CD066C1E0108BC4BB2D00E8720683C408C33DC07F7604B8C07FC383C03F24C0C351E8010B6633D2B90A00F7F18BC8E8F40A03C16625FFFF0000593D10277303B81027C332D2C380FD027525E84EEE66BB00080000E89A00E842EE66BB03080000E88E006633D266BB01080000E88200C380FD0375106633C08AC16633D266BBFF000000EB365133D2E8E5EC8AD566C1E210E81EED8AF28AD1668BC2660D00000080E859ED80FB047606660D00000008E88FEDE8DDEC6633DB8AD95983EC108BEC6689460466895E08668BC26633D266BB6400000066F7E366894600BB0C008CD066C1E0108BC4E896058BECB30183C410C383EC108BEC6689560066895E04BB2E008CD066C1E0108BC4E87305B30183C410C3C353516650B9687480FB03740BB9A08C80FB007503B978696633D28BD16658595BC36652B30066F7C20000FFFF751A80FD13741580FD147410B30180FD0E7409B30380F9037402B302665AC3B51180FA23740780FA227402B500C3B50280FA23740780FA227402B301C332C980FD007508C746000B01B101C35033C0E87301041489460058B101C3C38BDAB72280FE217402B721C30C01C3E8780966C1E8100BC0741C5383C306E869095B3DE001720F5383C318E85C095BA88075030C01C332C0C3B50CC3B502C350E82601B1030AC07404B10802C858C380FA227505C746007869C3E8EF0080FDFF743583EC0C8BEC884E01886E0080F90F7505E82400EB0F80F910750A8D9C4803E807098846028CD066C1E0108BC4BB0400E8500483C40CC3C36653E8A4EB668BC26633D266BB8C0A000066F7F3665B8AE8886E098D9C4003E8CF0888460288660366C1E810884608E866EB66895604C383EC208BEC80F904750A884E0132C0884600EB56E830EBE87F00884600884E01E8A4EB88560A80F901741880F90B753A8D9C5C03E88308884602E824EB66895604EB27E83DEB886E08E815EB66895604E83FEB885E03E8ACEA886E0251E81C008ACDB001D2E0598846098CD066C1E0108BC4BB4C00E89C0383C420C38D9C3C03E8370832ED3C03740C3C0972093C0E77052C088AE8C3B5FFC35232C080EE2180FA1E7410B00280FA207409B00480FA217402B00602C65AC3C383EC088BEC897E00895E02895604894E068CD066C1E0108BC4BB3600E83C038BEC8B5E028A7E0183C408C35633F666F7C200008000750A5033C08AC68BF032F65853BB041FE81907668BC2BB001FE810075B66F7C200001000750233DB8BD366C1E210BA001F83EC088BEC66895600884E048AC5FEC8884607C6460500C64606008CD066C1E0108BC4BB4E00E8CC028BEC8A5E058A7E0683C4080ADB743251B9900180FB20740580FB807513B90A008BC60AC0740AB990013C017403B9E803E8CF03598BC6FEC48BF080FC0676980ADB5EC38D5C04E829078BD0B502E814007411B50180FA13750AE8610080FA137502B502C380FA14C3E8F9FF740380FA0EC380FA05C380FA02740380FA04C380FA01740380FA02C380FA027503B201C380FA047503B203C3C3B508E8D8FF7402B504C38D5C09E8CA068AC80AC9750332C0C3B502E8DA028AC52402D0E8C38D5C08E8AF068AD0B60183EC108BEC8956028CD066C1E0108BC4BB4F00E8EF018BEC8A560483C410C35383C34CE853065BC35383C34CE8A5055BC356E896018B4438837D20005EC352500FBCD832FF80FB017505BB0024EB0CFECBB80004F7E30500208BD8585AC357E85600740A8B5D02E808000BDB5FC333DB5FC352510BDB741B56E8360103DE5E33C98A4F01803FFF74083A07740603D9EBF033DB0BDB595AC35651E8150132C98D7C083B5D04740C83C710FEC13A4C0672F133FF0BFF595EC35651E8F50032C98D7C083B1D740C83C710FEC13A4C0672F233FF0BFF595EC35651E8D60032C98D7C083B450C740C83C710FEC13A4C0672F133FF0BFF595EC35750E8DBFF8AC38B5D02E86EFF585FC35332C9B301E8E8FF74038A4F020AC95BC35332EDB302E8D7FF74038A6F020AED5BC350578BDAE868FF750433DBEB0DB0148B5D08E834FF74F28B5F025F58C366505351578D1C6625FFFF0000E8B5048BD8E83B0023C37431E875FF0BFF742A6650668B45048D5C0CE899046633C08B058D5C04E88E046658E885FFE893FF8D5C086633C08BC1E87B045F595B6658C356E818008B44045EC356E80F008944045EC3C3BFE0028B3D8B7D0CC3BEE0028B348B7430C31E0E1FBFE0028B3D8B7D0E83C7041FC3BEE0028B348B7410C3BFE0028B3D8B7D2683C704C3BEE0028B348B741AC3BEE0028B348B743AC3BFE0028B3D8B7D0A83C704B90700C3E80100CB83EC068BEC8946006633C0C646040089460206528AD38BC5E8CD165A0783C406C3E880FF66F7451001000000C350E873FFB8010009451058C3E868FF884510C3665383EC488BEC66895E0066894E048CD066C1E0108BC4BB0000E8A3FF83C448665BE86A01E8A40183EC1C8BECC64601078CD066C1E0108BC4BB0D00E881FF83C41CE80E00BB0400E88FFD66C1E810E8A7FFC383EC1C8BECC64601088CD066C1E0108BC4BB0D00E856FF83C41CC3E8F3FE668B5D08668B4D0CC356E826FF668B44085EC383EC048BEC894E008CD066C1E0108BC4BB3800E826FF8BEC8A6E0283C404C3C3B006C3B001C3B005C3B008C35366506633C0E80D0383C304E2F866585BC332C0C3FCE89D0366C1CB10E8F60266C1CB106681C304000400E2E9C3FC66ADE8E20283C304E2F6C3FCE8780366AB83C304E2F6C36650B86400E810006658C36650B850C3D1E1E803006658C352F7E18BCAE8690166538BD966C1E3108BD866B804B10300B20066EFB2046633C066EF66B808B10300B20066EFB20466ED33C96603D8730A66ED66A90000008075F666ED663BC3730C66C1E8103BC172048BC8EBED665B5AC3BB42ECE8C7026633D266BB6400000066F7F3C3665053BB0700E857FC2500023500020BC05B6658C36651B301E8C400E802FE6633C98B4C0866C1E00A0BC97503B92000662BC1E8EBFD66894404894C086659C3561E0E1FE8DAFD668B440466C1E00A1F5EC3C3BEE0028B348B741E83C604B91C00C356E8A6FD8A6C335EC356E89DFD5381C30901E875028AE85B5381C30001E86A025B8AC5668944345EC356E87DFD668B44345381C30801B1018AE8E8F1015B5381C30001B1018AECE8E4015B5381C3020166C1E810E8AB015B5EC356E84CFD8BFE83C7045EC356E841FD8A442480FD007405886C330C028844245EC332C0C3665383EC048BEC8CD066C1E0108BC466895E00BB0600E84DFD8BEC668B460083C404665BC366508CC83D00C0750CBAC303EC8AF00AF67402EB0E532E8B1E1400B220E8D6008AF45B32D266ED6658C32E8B1E1400C30BC9751A4B7416433BDA77098BC88BC22BD2F7F391F7F38BDA8BD12BC9C33BCA721A75103BD8770C2BC38BD82BC92BD2B80100C32BC92BDB9387CAC355562BF68BEE03DB13C97211453BCA72F577043BD876EFF813F64D7820D1D9D1DB2BC31BD1F572F003F64D780CD1E9D1DB03C313D173F1EBDF03C313D18BD88BCA8BC633D25E5DC39350920BC07402F7E2910BC07404F7E303C858F7E303D1C3526650B4808AC766C1E0108AE38AC224FCBAF80C66EF66585AC352BAFC0C66ED5AC352BAFC0C66EF5AC3E831FF9CFAE8CEFFE8E5FF9DC3E824FF9CFAE8C1FFE8E0FF9DC35266536650E806006658665B5AC366C1E31066C1EB0EE8D7FEE89301C3665066C1E31066C1EB10E801FE6603D86681CB000000806658C3526653E80400665B5AC36650E8AAFEE8D4FFE863016658C35251665366508ACB80E3FC80E103C0E103E88DFEE8B7FFE82D0166D3C8585066D3C0E83B016658665B595AC3665051C0E103E8530066D3C88AC566D3C0E8A8FF596658C3665051C0E103E83B0066D3C8598AE86658C3E85F00C3E844FE66C1E31066C1EB0EE8DF00C3E835FE66C1E302E8D400C3526653E80400665B5AC3E820FEE84AFFE8C000C35166528AEB8ACB80E103C0E10380E3FCE8D9FF80F9007414668BD083C304E8CBFF83EB046692660FADD08ADD665A59C3526653E89CFF665B5AC3526653E8A1FF665B5AC36650555266508BEC8B560C895608E8C4FDB20066ED6689460A66585A5DC36650555266508BEC8B560C895608E8A6FD2EA12D03B218EFB20066ED6689460A66585A5DC3665055528BECE889FDB200668B460A66EF8B560889560C668B4604668946085A5D66586658C3665052E866FDB21866ED2EA32D035A6658C36681FBFF00000077048AD3EB09668BC3B20066EFB20466EDC36681FBFF00000077048AD3EB0A6693B20066EF6693B20466EFC3C3C3558BEC53518BF0268B5C14268B4C16E828008D66FC595B5DC353518BF0268B5C2433C9E81400595BC3558BEC53518BF0268B5C08268B4C0AEBD5525657C80600008BF0894EFE8CD08EC0268B7C268A450132E4B920002BC8B8FFFF8BD0E306D1EAD1D8E2FA8A4D0332ED8BFAE306D1E0D1D7E2FAF7D0F7D72621441C26217C1E8CD08EC0268B7C268A4D0132EDB820002BC18BC866C746FAFFFFFFFFE308D16EFCD15EFAE2F88A4D0232ED8BC38B56FEE306D1EAD1D8E2FA2346FA2356FC8A4D0332EDE306D1E0D1D2E2FA2609441C2609541EC95F5E5AC3558BEC53515257508BD8268B7F268A450132E4B920002BC8B8FFFF8BD0E306D1EAD1D8E2FA8A4D02884EF6C646F7008BFA8B4EF6E306D1E0D1D7E2FA2609471C26097F1E8D66F85F5AE9F1FE535152578BD88CD08EC0268B77268A4C0132EDB820002BC18BC8BEFFFF8BD6E306D1EAD1DEE2FA268B7F268A4D0232ED8BC6E306D1E0D1D2E2FAF7D0F7D22621471C2621571E5FE9CC0553568BD88CD28EC2268B7726803C007473803C0175588A440132E426837F1E00754C263B471C75468A046BF0038A840490260147268CD08EC0268B7726803C0974178A0432E46BF0038BC3FF940290268B77268A0432E4EBD18B44012629472626FF4726268B471C268B771EEB1A268B77268A0432E46BF0038A84049026014726E980FF33C033F68BD65E5BC3535152568BD88D7735268B54022689571426C7471600008BF0268B472033D226014714261154168CD18EC126F6472F060F850A0526807F34007522268B7716260B7714751026D1670826D1570A26D1670826D1570A8BC3E87911E9E104268A473432E4058000992689471C2689571E8BC3E8FFFEE9C70453568BD88D7735268A440232E4C1E002268B37268B3403F0268B4708268B5F0A26890426895C025E5BC35352568BD88CD08D77358EC0268A540280FA407321268B770232F6C1E202268B740403F2268B5708268B470A26891426894402E97F0080FA417512268B4708268B570A2689471026895712EB6880FA407512268B4708268B570A2689470C2689570EEB5180FA42750A268B470826894722EB4280FA43750A268A470826884733EB3380FA467512268B5708268B470A268957182689471AEB1C80FA47750A268B470826894724EB0D80FA487508268B4708268947205E5A5BC353568BD88D7735268A440232E42689471426C7471600005E5BC353568BD8268B7702268B74028A0432E42689471426C747160000268B5F0226FF47025E5BC353568BD8268B7702268B74028B342689771426C747160000268B5F0226834702025E5BC353568BD8268B7702268B74028B048B74022689471426897716268B5F0226834702045E5BC35352568BD8E870FF8BF3268B4718268B571AD1EAD1D8D1EAD1D826014714261154168BC3E82B10E94AFF538BD8268B5F0226FF47025BC3538BD8268B5F0226834702025BC353568BD8E86BFF8BF3268B572033C026015714261144168CD28EC2268B472E32C080E4063D0002750732E433D25E5BC3268B472E32C080E4063D000474EB26807F340075088BC3E82F0F5E5BC3268A473432E42689471C26C7471E00008BC3E8EAFC5E5BC3538BD8E8E2FE268B4714C1E002268B1F268B1F03D8268B07268B57025BC3E236D736ED363C37F3360B372537303736375351568BD8E8B0FE8CD28EC226837F1600752226837F1440731B268B7702268B5F14C1E302268B440403D8268B07268B5702E97B05268B7714268B471683C6C083D0FF757183FE08776C03F62EFFA47436268B4710268B5712E95405268B470C268B570EE94905268B4722EB4B268A4F3332EDBB010033D2E306D1E3D1D2E2FA8BC3E92B05268A4F3332EDB8010033D2E306D1E0D1D2E2FAF7D0F7D2E91105268B4718268B571AE90605268B4724EB08268B4720EB0233C033D2E9F30453568BD8E8F4FD8BF3268B4718268B571AD1EAD1D8D1EAD1D826014714261154168BC3E8160E5E5BC333C033D2C353568BD8E8EBFD268B7714260377228B048B54025E5BC3538BD826C6472B04E8ABFD268B4714268B57165BC3538BD826C6472B01E8BBFDEBE9538BD826C6472B00E8D2FDEBDC538BD883C335268A5F01C0EB0380E30732FF03DBFF97928F5BC35352568BD8268A472C32E48BF003F08BC3FF94AE8F268947082689570A268A472D32E48BF003F08BC3FF94C68F2689470426895706E917FD5351568BD8268A4F2B32ED8BF18A8CF68FE30A26D16F0626D15F04E2F6268A4F2B32ED8BF1C1E6028B8CD68F8BB4D88F26214F0426217706268A4F2A32ED8BF18A8CFE8FE30A26D1670426D15706E2F6268B4F08268B770A26894F1426897716E9CA0353515256578BD88CD08EC0268A472B32E48BF0C1E602268A472A8BF88A8DFE8F32ED8B84D68F8B94D88FE306D1E0D1D2E2FAF7D0F7D22621471426215716268A472A32E48BF08A8CFE8F32EDE30A26D16F0A26D15F08E2F6268A472B8BF0C1E6028B84D68F8B94D88F262147082621570A268A472A32E48BF08A8CFE8F32EDE30A26D1670826D1570AE2F6268B4714268B5716260947082609570A5F5E5A595BC35351568BD8268A4F2B32ED8BF18A8CF68FE30A26D16F0626D15F04E2F6268A4F2B32ED8BF1C1E6028B8CD68F8BB4D88F26214F0426217706268A4F2A32ED8BF18A8CFE8FE30A26D16F0A26D15F08E2F6268A4F2B32ED8BF1C1E6028B8CD68F8BB4D88F26214F082621770AE9BB025152578BD88CD08EC026807F2B00741A268A472C32E48BF003F08BC3FF94AE8F268947082689570AEB10268A472C32E48BF003F08BC3FF94BA8F268A472D32E48BF003F08BC3FF94C68F26894704268957068CD28EC226807F2B00744A268A472B32E48BF0C1E602268A472A8BF88A8DFE8F32ED8B84D68F8B94D88FE306D1E0D1D2E2FAF7D0F7D2262147082621570A8BC3E8F9FD268B4704268B5706260947082609570AEB10268B5704268B4706268957082689470A268A472C32E48BF003F08BC3FF94A28F5F5A59C353515256578BD8268A472A32E48BF08A8CFE8F32EDE30A26D1670426D15706E2F68CD08EC0268A472B32E48BF0C1E602268A472A8BF88A8DFE8F32ED8B84D68F8B94D88FE306D1E0D1D2E2FAF7D0F7D22609470426095706268B4704268B5706262147082621570AE956FE558BEC5152508BD8268A472C32E48BF003F08BC3FF94AE8F268947082689570A268A472B8846FA8BC3E8DAFC2689470426895706268A4F2D32ED8BF103F18BC3FF94C68F26894714268957168BC3E844FF8A46FA32E48BF08A8CF68FE30A26D16F1626D15F14E2F6268A572B32F68BF2C1E6028B84D68F8B94D88F2621471426215716268A472A32E48BF08A8CFE8F32EDE30A26D1671426D15716E2F6268B4714268B5716260947082609570A268A472C32E48BF003F08BC3FF94A28F8D66FC5A595DC3518BD8E856FC268A4F2B32ED8BF18A8CF68FE30A26D16F0626D15F04E2F68BC3E8AEFE268A4F2C32ED8BF103F18BC3FF94A28F59C38BD8E822FC8BC3E855FC268B4704268B7706260947082609770A268A472C32E48BF003F08BC3FF94A28FC353568BD8E8F5FB8BC3E828FC268B4704268B7706263147082631770A268A472C32E48BF003F08BC3FF94A28F5E5BC35351568BD8E8C5FB8BC3E8F8FB268B4F04E30A26D1670826D1570AE2F68BC3E846FC268A4F2C32ED8BF103F18BC3FF94A28F5E595BC35351568BD8E88FFB8BC3E8C2FB268B4F04E30A26D16F0A26D15F08E2F6EBC8528BD8E872FB8BC3E8A5FB8BF3268B4704268B5706260147082611540A8BC3E8F1FB268A472C32E48BF003F08BC3FF94A28F5AC3528BD8E83EFB8BC3E871FB8BF3268B4704268B5706262947082619540AEBCA51528BF0E81EFB8BC6E855FC268B4408268B540A268B5C04268B4C06E8DDF22689440C2689540E5A59C3528BD0E8F5FA8BC2E82CFC8BC2E85C085AC35152578BF0E8E1FA8BC6E818FC268B4408268B540A268B5C04268B4C06E81CF22689440C2689540E8CD78EC7268B4408268B540A268B5C04268B4C06E8FDF126895C1026894C12E910FD528BD0E899FA8BC2E8D0FB8BC2E8D3075AC351528BD8E886FA8BC3E8BDFB8CD18EC1268B4708268B570A263B5706750E263B4704750826C64730015A59C38BD0268B470A263B47067208750A263B5704730433C0EB03B80200268847305A59C35152578BD8268A472C32E48BF003F08BC3FF94AE8F268947082689570A8CD08EC0268A472B32E48BF0C1E6028BF88A8DF68F32ED8B84D68F8B94D88FE306D1E0D1D2E2FAF7D0F7D2262147082621570AE94DFC558BEC51525783EC068BD8268A472B32E48BF0C1E6028BF88A8DF68F32ED8B84D68F8946F48B84D88F8946F6E308D166F4D156F6E2F88B7EF48B46F68946F8268A472C32E48BF003F08BC3FF94AE8F268947082689570A8BC3E847F926894704268957068BC7F7D08B56F6F7D2262347082623570A268947142689571626217F088B46F62621470A8CD18D77358EC126803C197312268B4F04E30A26D1670826D1570AE2F6EB10268B4F04E30A26D16F0A26D15F08E2F626217F088B46F82621470A268B5714268B4716260957082609470A268A472C32E48BF003F08BC3FF94A28F8D66FA5FE9A3FC528BD8E8FDF88BC3E834FA268B4708268B570A268557067506268547047405B80300EB03B80100268847305AC3535152568BD8268A4F2D32ED8BF103F1FF94C68F2689470426895706268A472B32E48BF08A8CF68FE30A26D16F0626D15F04E2F6268A472B8BF0C1E6028B84D68F8B94D88F2621470426215706E9BDF9528BD8E8AAFF268B4704268B5706268947182689571A5AC351528BD8E891FF8CD08EC0268B7702268B7402813C5A5A745B268B7702268B7402803C6375E1268B770226FF44028BC3E821F8268947082689570A8BC3E8FAF726894714268957168CD18EC1268B5704268B4706263B470A75AD263B570875A7268B7702268B04260347148BDE268947025A59C3268B5F0226834702025A59C352578BD88CD08EC0268B7702268B74028A540184D2750826C747220000EB2F80FAFF7514268B7702268B3F268B34262B750226897722EB16268B07E8E3028BF08AC232E403C003F08B0426894722268B5F0226834702025F5AC38BD82680672FF9268B7702268B74028A440126884734268B5F022683470203C38BD8268B7702268B74028B740126897720EBE3538BD8268A472C32E424032680672FF9C1E0092609472EE94FF58BD8268B7702268B74028A440132E42689470426C7470600008BC3E84004268B5F022683470202C38BD8268B7702268B74028A440132E42689470426C7470600008BC3E80804EBD653568BD8268B7702268B74028A440132E42689470426C7470600008BC3E80604E986F453568BD8268B7702268B74028A440132E42689470426C7470600008BC3E8F003E963F453568BD8268B77028BDE268B5F028B5F0183C30326015C025E5BC351528BD8268B77022683440202268B07E8A0018BC8268B77288A440132E403C08BF103F0833C00744F268B77288A540132F68BC3E8B00126884731268B7702268B348B4404C1E80832E4247FC1E80232E4241F2680672F07C1E00B2609472E268B37268B472EC1E80BC1E00226010426C647320126894F285A59C3538BD826C64732825BC3578BD88CD68EC626807F2C05740A268A472C263A4730751E268B7702268B7402268B7F02268B3D8B740103F7268B5F02268977025FC3268B5F0226834702035FC35356578BD88CD68EC626807F3001740A268A4730263A472C7520268B7702268B7402268B7F02268B3D8B740103F7268B5F02268977025F5E5BC3268B5F022683470203EBF15356578BD88CD08EC026807F300174E5EBC3558BEC535152578BD8268B7702268B74028A0426C6473D008CD18EC126807F3D087320268B7702268A573D32F6268B7C0203FA8BF303F28A152688543526FE473DEBD5268B7F028AD032F68BF2C1E6028A94239026015502268B7F288A550180E2072688572D268B7F288A5501C0EA0380E2072688572B268B7F288A5501C0EA062688572A8A9422902688572C8D66F85F5A595B5DC353568BD8268B77028BC68B744803F08BD88B741E8BC603C383C0045E5BC353568BD8268B77028BC68B744803F08BD88B7420EBE08AC2C31607558BEC5351565783EC408BF88946B8E8D3FF8BD88946E0268B45028B5F2E03D8895EDE8346DE048BC7E89BFF8946E032F68D46B8E8C4FF8AD032F603D28B5EE003DA833F000F8465018846E98066E7F9C646EC00C746D8000066C746D000000000C746F60000C646EA01EB063C010F858C008A56E98AC232E403C08B5EE003D8833F007475268B45028B1F03D88B470432E48BC883C10932ED80E1FE83F9007407D1E933C050E2FD8BC48BD88946BA85C0744183C008268947048AC232E403C08B5EE003D8268B450203078B5EBA2689078B5EBA268B0783C006268947028B5EBA8B76F6268977068B5EBA895EF6C646EA00EB0AC646EA87EB04C646EA838A46EA32E483F8100F8F99008866EA8A46EA32E485C00F8F83008CD08B5EBA8EC0268B5F02895EE08B5EBA268B5F02803F5B754AC646EA108B5EBA268B5F06895EF68B5EBA268B1F8B470432E48BC883C10932ED80E1FE03E18B5EF6895EBA85DB74AC268B1F8B4704C1E80832E4247FC1E802C1E0028B5EB8262907EB918D46B8E8AFFD8AD08D46B8E82E008ADA32FFC1E3028D46B8FF972090E972FF837EF6000F85C9FE807EEA1074058A46EAEB0232C08D66F85F5EE90BFEC353518BD8268A4F0432EDE886E8595BC353518BD8268A4F0432EDE881E8595BC3538BD8268A470432E4E6805BC353518BD8268A4F0432EDE89ED7595BC3538BD866506652665166268B470866268B571066268B4F0466F7F1662689470C66268957106659665A66585BC3538BD866506652665166268B470866268B4F0466F7E1662689470C66268957106659665A66585BC353578BD8268B5F14E838EB8BD066C1E810925F5BC353578BD8268B4714268B57168BD887D366C1E3108BDAC1E302E836EBEBD85352578BD8268B4708268B570A9266C1E0108BC2268B5F14E85AEA5F5A5BC353528BD8268B471C268B571E9266C1E0108BC2268B5F268B5F01E839EA5A5BC35352568BF0268B5C268B5F01E8C2EA8BD066C1E810922689441C2689541E5E5A5BC3535152578BD8268B4708268B570A9266C1E0108BC28BC8268B4714268B57168BD887D366C1E3108BDAC1E3028BC1E816EA5F5A595BC38BD066C1E81092C31E0666506651665266536655665666570E1F0AC07506E80701E9A8003C017506E83701E99E003C027506E85F02E994003C03750BE891038BEC895E0CE985003C047502EB7D3C05750AE80E048BEC895610EB713C067510E88C038BEC895E0C894E14895610EB5D3C077502EB553C08750AE8D0038BEC887E0DEB493C097502EB413C0A7510E865048BEC894E14897E008C461CEB2F3C0B7502EB273C10750AE85A048BEC895E0CEB1B3C117502EB133C15750FE880048BEC895E0CEB07B84F01EB0232C08BEC894618665F665E665D665B665A66596658071FC3501E2E8E1E47048CD8A3E656A3F656A308572E8E1E3F04A3AA041F58CB0030312E303000564553410003000300000100000000000000000302110C0200009C01000034470000B93F008BDF83C704FC6633C0F366AB8BFBBE3A47B92200F3A4061F8C4F088C47108C4F188C4F1C8C4F2083C722897F0E0E1FE8F9D3B04F32E4C3565157B910006633C0F366AB5F598CDB061FC705BB00C6450207C745044000C745064000C6451B06C6451801C6451A01C6451E0166C7453E0084D7178EDBE8CDCC660BC00F84E100061F668945288CC866C1E010B8F34A6689450C81F9FF810F84C20080E503B201538EDBBE801CE8A5D15B061F0F84B10053E821D466894512C7451608108D5C0CE8BAE86689451F668945368D5C10E8ACE8668945236689453A8D5C08E89EE80AC075035BEB7BE8ECD366C1E8103D5802740D3D5E017408770AC6451708EB04C645170E2EA141048945088D5C04E86DE8668BC866C1E910D3E0894510894532B008D2E08845198D5C14E851E85B3D0003772F538BD8B8000333D2F7F35BFEC888451D8845358845348EDB5753BE801CE85DCC5B5F0BC97505061F8325FE32E4EB02B403B04F8EDB5EC30081FBFF8174680AFF75048BC3EB21F6C70875618BCBB201BE201CE8C7D07455E828D30AC0750E66C1E81080E7800AC7E8D502EB3AE8A4CE7406E815CDE864C6BE201CE8D4CB742DE8A500E82C0066BB201C001CE8EBD2BE001CE8EED266C1E8108BD832C0F6C7807402B040E804CCB04F32E4EB04B04FB403C3560633C08EC0BE201CE8E6D28BC866C1E8108BD0C1E90326890E4A04C1EA04FECA268816840426C60651040026C60650040026C60649046226C7064C0400A026C60685041026C7060C01C5608CC826A30E01075EC3010F000A000000000040050FFF000102030405060708090A0B0C0D0E0F01000F00FCBAC403B80001EFB90400B401BE9649AC86E0EF8AE0FEC4E2F6B80003EFB90900BACE0332E4BE9A498AC4EEAC42EE4AFEC4E2F5BADA03ECB91400BAC00332E4BEA3498AC4EEACEEFEC4E2F7C3BE001CE808D266C1E8108BD8E8D8D17505E8C4D17504B84F00C3B84F03C3E8C6D17453BE001C80FB00741880FB017505E804D2EB1D80FB0275108BC1E8B7D1D3E88BC8E8B4CC742EEB0880FB037524E85BD1E8A1D18BD8D3E35033C0BA00033BDA7705BAFFFFEB04F7F38BD0588BC8B84F00C332C0C3B04FB403C3000ADB75078AEFE882CDEB05E867CD8AF8B04F32E4C300E852D1742CBE001CE871D166C1E810F6C440751D0AFF7505E81E00EB0F80FF017514BB1300E8EBE5D1E88BD0B04F32E4C3B04FB403C332C0C35253665081E2FF02D1E28BC24066C1E0108BC2BB1300E81CE5BB1200E816E566585B5AC39C1E0666506651665266536655665666570E1FE834E6E88AFFE853E68BEC895610894618665F665E665D665B665A66596658071F9DCB0E07BFC88E2E8B0EC68EB84F00C3000ADB7506B704B310EB2680FB017514E859CC752153B1010AFF7402B100E86ECB5BEB0D80FB02750DE886CC8AF8C0E702B04F32E4C3B84F03C30080E3010ADB7505BB0201EB0EE822CC750E33C053E80FBB5B7405B04F32E4C3B04FB403C380FC1D7203CD42C31E0666506651665266536655665666570E1F500FB6C4D1E08BF0582EFF94E04B665F665E665D665B665A66596658071FC30E1F500FB6C4D1E08BF0582EFF94E04BC31A4C3085498566850D4D697C9B7C0E7D917D1F7F237F2C82FD828083E7838285E4858D88264FD48CCE4BCE4BCE4BCE4BCE4BCE4BA48DA771FB722E8E1E3F0480268704F3508AE080E47FE8C4013BD3750258C3BACC03ECB2B4B13026F6470901740CB2D4B120A8017549B509EB06A8017441B50B53E870410AFF5B750B80268804F0082E8804EB2B58800E87040880261004CF080E100489166304C70685040800C606840418C7060C01B2588C0E0E01CD42C380261004CF080E10045853500E1F33C98AC8E8FBCA7406E86CC9E8BBC2B208BE401CE8F4CCBE401CE823C8585B0F846EFF2E8E1E3F040E07E819290E1F5366BB401C001CE82FCFBE001CB020E858C85B2E8E1E3F040E07E8222EE82400E82E3DE8D101E88E01E8B43E0E1FBE001CB010E834C8E8FD2DE8F52DC38BECC6461B00C3E82F00E80A00E8BD00E85200E8620AC35383C30A8B166304B91900B81130EF32C0268A27EF43FEC0E2F75B80C20632C0EEC353BAC40383C305B90400B001268A273C01750380CC20EF43FEC0E2F05B268A4709BAC203EEB2C4B80003EFC38BF383C623BADA0326F64709017502B2BAF606890408741D83C610ECB90400B410B2C080FC1174078AC4EE268A04EE46FEC4E2EFC353EC8BDEB9140032E4B2C08AC4EEFEC4268A07EE43E2F48AC4EE32C0EE1E06E84F2D0BED74091F1EB91000F3A446A4071F5BC35383C337B9090032C0BACE03268A27EF43FEC0E2F75BC3BBE4500E078BD30AE47D01C3E80100C333F680FC037F3C4AF6068904107520A08804240F3C027E243C0874203C06741C3C077418B040F6E403D881C30004C3B040D0ECF6E403D881C38004C3B040F6E403D8C380FC077511F606890410750581C30001C381C30005C3BF664EBE874E33C9E84E00C304800005800006C0000D80020EC0020F800310C00311400512800513C005624001538A1E490480FB077F1032FFD1E32E8B87A34EA26504882666045BC32C3028302D3029302A302E301E3F29302E382575072E035D0133F6C383C7033BFE75EDC31E062E8E1E3F04F6068704807549833E4C04007442A04904B900202E8B3E450426F6473301750E26F6470901751B2E8B3E4304EB143C067E0B2E8B3E4104268A6737B5406633C0EB0666B8200720078EC76633FFF366AB802687047F071FC32E8E1E3F0480FB107503E97A0180FB207503E99B0180FB32751FBACC030AC07509EC0C02B2C2EEE9F300FEC80F85F300EC24FDB2C2EEE9E40080FB3575283C807508800E890440E9D300F6068904400F84D0000AC00F84CA00FEC87506E89807E9BA00E9BD0080FB307403E9960050E8303E8AEFBACC03EC8AC8580AC07530B708F6C10175120AED750BA0100424303C307510B702E98B00A0100424303C307502B702802689046F800E890480EB363C017541802689046FB709F6C1017515B70BA0100424303C30741BB7090AED7415B705EB11A0100424303C307508B70B0AED7402B7038A1E880480E3F00ADF881E8804EB293C02752B802689046F800E890410EBB480FB31751B0AC0740B3C01750C800E890408EB0580268904F78BECC6461A12C380FB3375163C00740B3C0175EC80268904FDEBE5800E890402EBDE80FB3475173C00750780268704FEEBCE3C017507800E870401EBC3C380FB367526BB20FF3C017409BB00DF3C007402EBADE80200EBA89CFABAC403B001EE42EC22C70AC3EE9DC3C3B303B700BACC03ECA8017502B701A088048AE0B104D2EC250F0F8BC88BEC895E0E894E16C6461A12C39CFAC706140094768C0E16009DC3281808000809030002632D2728902BA0BF1F00C70607000000009C8E8F141F96B9A3FF0001020304050607101112131415161708000F000000000000100E00FF501808001001030002635F4F50825581BF1F00C70607000000009C8E8F281F96B9A3FF0001020304050607101112131415161708000F000000000000100E00FF281808004009030002632D2728902B80BF1F00C10000000000009C8E8F140096B9A2FF00131517020406071011121314151617010003000000000000300F00FF501808004001010006635F4F50825480BF1F00C10000000000009C8E8F280096B9C2FF00171717171717171717171717171717010001000000000000000D00FF50180E001000030003A65F4F50825581BF1F004D0B0C0000000083855D280D63BAA3FF000808080808080810181818181818180E000F080000000000100A00FF501D1000A0010F000AE35F4F508254800B3E0040000000000000EA8CDF5000E704E3FF000102030405060708090A0B0C0D0E0F01000F00100000000040050FFF0005111C080B14280E182D322024383F0005080B0E1114181C2024282D32383F070C10151A181615131C252F38332E2A2527292A2C2319102325272A2C2B2A29292D32373B3937343233343535312C272F303233343433333235383A3D3C3A39383839393A373431030507090B0B0A09080D11151917151311111213140F0B071010121314131313121416181A191817161717171815141115151617171717171618191A1B1B1A19191919191A181716020304050706060505070A0C0E0D0C0B090A0A0B0B09060409090A0B0B0B0B0B0A0C0D0E0F0F0E0D0D0D0D0D0E0C0B0A0C0C0C0D0D0D0D0D0C0D0E0F0F0F0F0E0E0E0E0E0E0E0D0C00000000000000002818080020090F0006632D2728902B80BF1F00C00000000000009C8E8F140096B9E3FF0001020304050607101112131415161701000F00000000000000050FFF5018080040010F0006635F4F50825480BF1F00C00000000000009C8E8F280096B9E3FF0001020304050607101112131415161701000F00000000000000050FFF0005111C080B252802071B200F14282C0C11252A141E32360F13272C1B203439060B1F2413182C30090D2126151A2E3313172B301F24383D0E182D322024383F0005111C080B14180005111C080B14180E182D322024383F0E182D322024383F0005111C080B14180005111C080B14180E182D322024383F0E182D322024383F50180E0080010F0006A25F4F50825480BF1F004000000000000083855D280F63BAE3FF000800001818000000080000001800000B0005000000000000000505FF50180E0080010F0006A35F4F50825480BF1F004000000000000083855D280F63BAE3FF000102030405140738393A3B3C3D3E3F01000F00000000000000050FFF28180E000809030002A32D2728902BA0BF1F004D0B0C0000000083855D141F63BAA3FF000102030405140738393A3B3C3D3E3F08000F000000000000100E00FF50180E001001030002A35F4F50825581BF1F004D0B0C0000000083855D281F63BAA3FF000102030405140738393A3B3C3D3E3F08000F000000000000100E00FF281810000808030002672D2728902BA0BF1F004F0D0E000000009C8E8F141F96B9A3FF000102030405140738393A3B3C3D3E3F0C000F080000000000100E00FF501810001000030002675F4F50825581BF1F004F0D0E000000009C8E8F281F96B9A3FF000102030405140738393A3B3C3D3E3F0C000F080000000000100E00FF501810001000030002665F4F50825581BF1F004F0D0E000000009C8E8F280F96B9A3FF000808080808080810181818181818180E000F080000000000100A00FF501D1000A0010F0006E35F4F508254800B3E0040000000000000EA8CDF2800E704C3FF003F3F3F3F3F3F3F3F3F3F3F3F3F3F3F01000F000000000000000501FF501D1000A0010F0006E35F4F508254800B3E0040000000000000EA8CDF2800E704E3FF000102030405140738393A3B3C3D3E3F01000F00000000000000050FFF2818080020010F000E635F4F50825480BF1F00410000000000009C8E8F284096B9A3FF000102030405060708090A0B0C0D0E0F41000F00000000000040050FFFE45000C0000000000000000000000000045700C00000000000000000000000001A00A28E00C000000000000000000000000000000000000000001EE810002E8E1E3F04E8FE36E8D536E8761A1FC32E8E1E3F04C706870460F9C6068A040BA089040C112417A28904B401E8731EA0890480261004CF800E100420C7066304D4030E1FE871B8F7C102007503E8F9B7B80300E857F4C31E2E8E1E3F040E07EB001FC3F6068904087401C353BAC803ECB0FFB2C6EEB2C8803E6304B4752FBE6658B9400033DB9CFA8AC3EE8BFBC1EF0383E70303FE2E8A0542EE2E8A4504EE2E8A4508EEFEC34AE2DF9DE98500268A472BF6068904067431B9F800BF64523C087411B94000BFE4533C3874073C3F7403BF245433DB9CFA8AC3EE2E8A0142EEEEEEFEC34AE2F19DEB493C0874253C38742E3C3F742AB9080033DB51E8CBD3B90800F7C31000740383C718E8670059E2EAEB20E8B4D3B9100033DBE85700EB13B9400033DB51E828008AC3E8B72FFEC359E2F25BC3002A002A002A002A153F153F153F153F002A003F002A003F002A003F8BFBC1EF0283E70F2E8AB556588BFBD1EF83E70F2E8AAD56588BFB83E70F2E8A8D5658C39C8AC3FAEE2E8A0542EE472E8A05EE472E8A05EE47FEC34AE2E79DC300000000000000007E81A581BD99817E7CFED6BAC6FE7C00C6EEFEFE7C38100010387CFE7C381000103810EEEE103800387CFEFE6C10380000183C7E3C180000FFE7C381C3E7FFFF00183C66663C1800FFE7C39999C3E7FF1E0E1E3678CCCC787EC3C37E187E18181E1A1E181870F0603E3E3636F6661E0CDB3C66E7663CDB0080C0F0F8F0C0800002061E3E1E060200183C7E187E3C180066666666660066007FDB7B3B1B1B1B003C66386C6C38CC7800000000FEFEFE00183C7E187E3C187E183C7E1818181800181818187E3C180000181CFE1C180000003070FE703000000000C0C0C0FE0000002466FF662400000010387C7CFE000000FE7C7C381000000000000000000000183C3C18180018006C6C6C00000000006C6CFE6CFE6C6C00187EC07C06FC180000C60C183060C600386C3876CCCC760018183000000000001830606060301800603018181830600000EE7CFE7CEE00000018187E181800000000000018183000000000FE000000000000000000383800060C183060C080007CC6CEDEF6E67C001878181818187E007CC60C183066FE007CC6063C06C67C000C1C3C6CFE0C0C00FEC0FC0606C67C007CC6C0FCC6C67C00FEC6060C181818007CC6C67CC6C67C007CC6C67E06C67C00001C1C00001C1C0000181800001818300C18306030180C000000FE0000FE00006030180C183060007CC6060C180018007CC6C6DEDCC07E00386CC6C6FEC6C600FC66667C6666FC003C66C0C0C0663C00F86C6666666CF800FEC2C0F8C0C2FE00FE62607C6060F0007CC6C0C0DEC67C00C6C6C6FEC6C6C6003C18181818183C003C181818D8D87000C6CCD8F0D8CCC600F06060606062FE00C6EEFED6D6C6C600C6E6E6F6DECEC6007CC6C6C6C6C67C00FC66667C6060F0007CC6C6C6C6D67C06FCC6C6FCD8CCC6007CC6C07C06C67C007E5A181818183C00C6C6C6C6C6C67C00C6C6C6C66C381000C6C6D6D6FEEEC600C66C3838386CC6006666663C18183C00FE860C183062FE007C60606060607C00C06030180C0602007C0C0C0C0C0C7C0010386CC60000000000000000000000FF30301800000000000000780C7CCC7E00E0607C666666FC0000007CC6C0C67C001C0C7CCCCCCC7E0000007CC6FEC07C001C3630FC30307800000076CEC67E067CE0607C666666E6001800381818183C000C001C0C0C0CCC78E060666C786CE6001818181818181C0000006CFED6D6C6000000DC666666660000007CC6C6C67C000000DC66667C60F0000076CCCC7C0C1E0000DC666060F00000007CC07C067C003030FC3030361C000000CCCCCCCC76000000C6C66C3810000000C6C6D6FE6C000000C66C386CC6000000C6C6CE76067C0000FC983064FC000E18187018180E0018181800181818007018180E1818700076DC000000000000001038386C6CFE003C66C0663C18CC7800C600C6C6CE76000E007CC6FEC07C007CC6780C7CCC7E00C600780C7CCC7E00E000780C7CCC7E003838780C7CCC7E0000007CC07C186C387CC67CC6FEC07C00C6007CC6FEC07C00E0007CC6FEC07C006600381818183C007CC6381818183C000000381818183C00C6386CC6FEC6C6003838007CC6FEC6000E00FEC0F8C0FE0000006C9A7ED86E007ED8D8FED8D8DE007CC6007CC6C67C0000C6007CC6C67C0000E0007CC6C67C007CC600C6C6CE760000E000C6C6CE760018003C1818183C00C6386CC6C66C3800C600C6C6C6C67C0000187ED8D87E1800386C60F066F66C00C3663C7E183C18003E63380E633E001C003E613C867C001C0E00780C7CCC7E001C00381818183C00000E007CC6C67C00000E00CCCCDC760000FC00BC6666E600FE00C6E6F6CEC6003E003E6067633D003E0076CEC67E067C1800183060663C000000007C606000000000007C0C0C0000C0CCD8307C360C3EC0CCD8306C3C7E0C180018183C3C180000366CD86C36000000D86C366CD80000228822882288228855AA55AA55AA55AADD77DD77DD77DD77181818181818181818181818F81818181818F818F818181836363636F636363600000000FE3636360000F818F81818183636F606F636363636363636363636360000FE06F63636363636F606FE00000036363636FE0000001818F818F800000000000000F8181818181818181F00000018181818FF00000000000000FF181818181818181F18181800000000FF00000018181818FF18181818181F181F1818183636363637363636363637303F00000000003F30373636363636F700FF0000000000FF00F736363636363730373636360000FF00FF0000003636F700F73636361818FF00FF00000036363636FF0000000000FF00FF18181800000000FF363636363636363F00000018181F181F00000000001F181F181818000000003F36363636363636FF3636361818FF18FF18181818181818F8000000000000001F181818FFFFFFFFFFFFFFFF00000000FFFFFFFFF0F0F0F0F0F0F0F00F0F0F0F0F0F0F0FFFFFFFFF00000000000066DCD8DC66000078CCF8CCC6CC0000FE62606060E00000FE6C6C6C6C6C00FEC6603060C6FE00007ED8CCCCD8700000666666667CC0000076DC1818183800FE386CC66C38FE00386CC6FEC66C3800386CC6C66C6CEE003E603866C6CC780000007EDBDB7E0000067CDEF6E67CC0003860C0F8C06038007CC6C6C6C6C6C60000FE00FE00FE000018187E1818007E0030180C1830007E000C1830180C007E000C1E1818181818181818181818783000000018007E0018000076DC0076DC00007CC6C67C00000000000000181800000000000000180000001F181818F8381800D86C6C6C0000000070D830F80000000000007C7C7C7C000000000000000000001D000000002466FF66240000000000000010000000000000000000000000000000000000007E81A58181BD9981817E0000000000007CFEFED6FEFEBAC6FE7C000000000000006CEEFEFEFEFE7C38100000000000000010387CFE7C3810000000000000000000103838106CEE6C103800000000000010387C7CFEFEFE6C1038000000000000000000183C3C3C18000000000000FFFFFFFFFFE7C3C3C3E7FFFFFFFFFFFF00000000183C6666663C180000000000FFFFFFFFE7C3999999C3E7FFFFFFFFFF00001E0E1E3678CCCCCCCC780000000000003C6666663C187E1818180000000000001E1A1E1818181878F8700000000000003E363E363676F6660E1E0C000000000018DB7E3C66663C7EDB180000000000000080E0F0FCFEFCF0E08000000000000000020E3E7EFE7E3E0E02000000000000183C7E181818187E3C18000000000000666666666666660066660000000000007FDBDBDBDB7B1B1B1B1B0000000000007CC6C6607CF6DE7C0CC6C67C00000000000000000000FEFEFEFE000000000000183C7E1818187E3C187E000000000000183C7E18181818181818000000000000181818181818187E3C180000000000000000000C0EFF0E0C00000000000000000000003070FE7030000000000000000000000000C0C0C0FE00000000000000000000002466FF6624000000000000000000103838387C7CFEFE0000000000000000FEFE7C7C7C3838100000000000000000000000000000000000000000000000183C3C3C3C1818001818000000000036363636140000000000000000000000006C6C6CFE6C6CFE6C6C6C00000000000018187CC6C0783C06C67C18180000000000000062660C183066C6000000000000386C3830767ECCCCCC7600000000000C0C0C18000000000000000000000000000C18303030303030180C00000000000030180C0C0C0C0C0C18300000000000000000006C38FE386C000000000000000000000018187E18180000000000000000000000000000000C0C0C1800000000000000000000FE0000000000000000000000000000000000001818000000000000000002060C183060C0800000000000007CC6C6CEDEF6E6C6C67C0000000000001878181818181818187E0000000000007CC6C6060C183060C6FE0000000000007CC606063C060606C67C0000000000000C1C3C6CCCCCFE0C0C1E000000000000FEC0C0C0FC060606C67C0000000000007CC6C0C0FCC6C6C6C67C000000000000FEC6060C1830303030300000000000007CC6C6C67CC6C6C6C67C0000000000007CC6C6C6C67E0606C67C0000000000000000000C0C00000C0C000000000000000000000C0C00000C0C0C180000000000000C183060C06030180C00000000000000000000FE00FE000000000000000000006030180C060C1830600000000000007CC6C60C1818180018180000000000007CC6C6C6DEDEDEDCC07E000000000000386CC6C6C6FEC6C6C6C6000000000000FC6666667C66666666FC0000000000003C66C2C0C0C0C0C2663C000000000000F86C6666666666666CF8000000000000FE6660647C64606066FE000000000000FE6660647C64606060F00000000000007CC6C6C0C0C0CEC6C67C000000000000C6C6C6C6FEC6C6C6C6C60000000000003C18181818181818183C0000000000003C181818181818D8D870000000000000C6C6CCD8F0F0D8CCC6C6000000000000F06060606060606266FE000000000000C6C6EEEEFED6D6D6C6C6000000000000C6C6E6E6F6DECECEC6C60000000000007CC6C6C6C6C6C6C6C67C000000000000FC666666667C606060F00000000000007CC6C6C6C6C6C6D6D67C060000000000FC6666667C786C6666E60000000000007CC6C0C0701C0606C67C0000000000007E5A181818181818183C000000000000C6C6C6C6C6C6C6C6C67C000000000000C6C6C6C6C6C6C66C3810000000000000C6C6C6D6D6D6FEEEC6C6000000000000C6C6C66C38386CC6C6C600000000000066666666663C1818183C000000000000FEC6860C183060C2C6FE0000000000007C60606060606060607C000000000000000080C06030180C06020000000000007C0C0C0C0C0C0C0C0C7C000000000010386CC6000000000000000000000000000000000000000000000000FF0000001818180C00000000000000000000000000000000780C7CCCCCDC76000000000000E060607C6666666666FC0000000000000000007CC6C0C0C0C67C0000000000001C0C0C7CCCCCCCCCCC7E0000000000000000007CC6C6FEC0C67C0000000000001C363030FC303030307800000000000000000076CEC6C6CE7606C67C00000000E060607C6666666666E60000000000001818003818181818183C0000000000000C0C001C0C0C0C0C0CCCCC7800000000E0606066666C786C66E60000000000001818181818181818181C0000000000000000006CFED6D6C6C6C6000000000000000000DC6666666666660000000000000000007CC6C6C6C6C67C000000000000000000DC666666667C6060F00000000000000076CCCCCCCC7C0C0C1E00000000000000DC6660606060F00000000000000000007CC6C07C06C67C000000000000303030FC30303030361C000000000000000000CCCCCCCCCCCC76000000000000000000C6C6C6C66C3810000000000000000000C6C6D6D6D6FE6C000000000000000000C6C66C386CC6C6000000000000000000C6C6C6C6CE7606C67C00000000000000FE860C183062FE0000000000000E18181870181818180E00000000000018181818001818181818000000000000701818180E181818187000000000000076DC00000000000000000000000000000000001038386C6CFE000000000000003C66C0C0C0C6663C180CCC3800000000C60000C6C6C6C6C6CE7600000000000C1830007CC6C6FEC0C67C00000000003078CC00780C7CCCCCDC76000000000000CC0000780C7CCCCCDC76000000000060301800780C7CCCCCDC760000000000386C3800780C7CCCCCDC7600000000000000007CC6C0C0C67C180C6C380000003078CC007CC6C6FEC0C67C000000000000CC00007CC6C6FEC0C67C000000000030180C007CC6C6FEC0C67C0000000000006600003818181818183C0000000000183C66003818181818183C0000000000000000003818181818183C0000000000C600386CC6C6C6FEC6C6C600000000386C3800386CC6C6FEC6C6C6000000000C183000FE60607C606060FE000000000000000066DB1B7FD8D8DF760000000000007ED8D8D8D8FED8D8D8DE00000000003078CC007CC6C6C6C6C67C000000000000C600007CC6C6C6C6C67C000000000030180C007CC6C6C6C6C67C00000000003078CC00C6C6C6C6C6CE76000000000060301800C6C6C6C6C6CE76000000000018003C181818181818183C0000000000C6007CC6C6C6C6C6C6C67C0000000000C600C6C6C6C6C6C6C6C67C00000000000018187CC6C0C0C67C18180000000000386C6060F060606066F66C0000000000666666663C187E183C18180000000000003E6363301C0663633E001C00000000000000003E63380E633E001C000000000C183000780C7CCCCCDC7600000000000C1830003818181818183C00000000000C1830007CC6C6C6C6C67C000000000018306000CCCCCCCCCCDC7600000000000076DC00BC6666666666E6000000000076DC00C6C6E6F6DECEC6C60000000000211E001E3360606763331D0000000000423C003B6666663E06663C00000000000030300030303060C6C67C00000000000000000000007E6060600000000000000000000000007E060606000000000000606062666C183060DC360C183E000000606062666C18366EDE367E06060000000018180018183C3C3C3C18000000000000000000366CD86C360000000000000000000000D86C366CD800000000000011441144114411441144114411441144AA55AA55AA55AA55AA55AA55AA55AA55DD77DD77DD77DD77DD77DD77DD77DD771818181818181818181818181818181818181818181818F818181818181818181818181818F818F8181818181818181836363636363636F6363636363636363600000000000000FE36363636363636360000000000F818F818181818181818183636363636F606F63636363636363636363636363636363636363636363636360000000000FE06F636363636363636363636363636F606FE000000000000000036363636363636FE00000000000000001818181818F818F8000000000000000000000000000000F81818181818181818181818181818181F000000000000000018181818181818FF000000000000000000000000000000FF1818181818181818181818181818181F181818181818181800000000000000FF000000000000000018181818181818FF181818181818181818181818181F181F181818181818181836363636363636373636363636363636363636363637303F000000000000000000000000003F303736363636363636363636363636F700FF00000000000000000000000000FF00F73636363636363636363636363637303736363636363636360000000000FF00FF00000000000000003636363636F700F736363636363636361818181818FF00FF000000000000000036363636363636FF00000000000000000000000000FF00FF181818181818181800000000000000FF3636363636363636363636363636363F000000000000000018181818181F181F000000000000000000000000001F181F1818181818181818000000000000003F363636363636363636363636363636FF36363636363636361818181818FF18FF181818181818181818181818181818F80000000000000000000000000000001F1818181818181818FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0FFFFFFFFFFFFFFFFF00000000000000000000000076DCD8D8D8D8DC7600000000000078CCCCD8FCC6C6C6C6CC000000000000FE666260606060606060000000000000000000FE6C6C6C6C6C6C000000000000FEC6623018183062C6FE0000000000000000007ED8CCCCCCD870000000000000000066666666667C60C080000000000000000076DC1818181818000000000000FE38386CC6C66C3838FE00000000000000386CC6C6FEC6C66C38000000000000386CC6C6C6C66C6C6CEE0000000000003E60603C66C6C6C6CC780000000000000000007EDBDBDB7E000000000000000002067CCEDEF6F67C60C0000000000000001C3060607C6060301C0000000000007CC6C6C6C6C6C6C6C6C60000000000000000FE0000FE0000FE00000000000000000018187E181800007E00000000000030180C060C183000007E0000000000000C18306030180C00007E00000000000000000C1E1A18181818181818181818181818181818181818587830000000000000001818007E001818000000000000000000000076DC0076DC0000000000000078CCCC7800000000000000000000000000000000001818000000000000000000000000000000180000000000000000001F1818181818D8D87838180000000000D86C6C6C6C6C0000000000000000000070D8183060F8000000000000000000000000007E7E7E7E7E7E0000000000000000000000000000000000000000001D00000000002466FF66240000000000002F0000000103060C183060C080000000003000007EC3C3C3DBDBC3C3C37E000000004D0000C3C3E7FFFFDBDBC3C3C300000000540000FF99181818181818183C00000000560000C3C3C3C3C3C3C3663C1800000000570000C3C3C3C3DBDBDBDBFF6600000000580000C3C3C3663C3C66C3C3C300000000590000C3C3C3C3663C1818183C000000005C00000080C06030180C060301000000006D000000000066FFDBDBDBC3C300000000760000000000C3C3C3C3663C1800000000770000000000C3C3DBDBDBFF66000000000000C560C30BDB7403E946015732C0B94000F3AA5FBB928E26891D268C4D022E8E1E3F0457BE4904B91E0083C704FC8A042688054647E2F75FA08404FEC026884522A185042689452357E8D91B5F26885D2526887D268A1E4904E8FC05740580FB137F1D32FFD1E32E8A876A8E32E40AC0740140268945272E8A876B8E26884529A185048A168404FEC2F6E2B2003DC8007E15B2013D5E017E0EB2023D90017E07B2033DE0017E002688552A8A2687048AC42401C0E00480E402D0E40AE080F410A08904240A0AE0E89408B2C0B030EE42EC2408C0E0020AC40C012688452DB00326884531E877081E0632D2C41EA8048CC18CCE3BCE743426C577048CD90BF1740380CA1026C5770C8CD90BF1740380CA0826C577088CD90BF1740380CA0426C577108CD90BF1740380CA01071F26885532B003BAC403E8E4048AE0C0EC028AD48AF2D0EE81E204042503030BC22689452B8BECC6461A1BC30AC0740FFEC87436FEC874568BECC6461A00C3B82000F6C101740383C060F6C102740383C03AF6C104740305030383C03FC1E8068BEC89460EC6461A1CC38BFB83C720F6C1017403E88500F6C1027403E8EF00F6C1047403E8F8018BECC6461A1CC3F6C1017406E81615E82501F6C1027403E88501F6C1047403E81202EBDC8AC4EE42ECAAFEC44AE2F5C3E86B04BDC003B9150032E4EC87EA8AC4EE42ECAAFEC44A87EAE2F0EC87EAB020EEC3268A0588044746E2F7C3268A25EF47FEC0E2F7C3B2C08AC4EE268A0547FEC4EEE2F4C39CFA51578BC72BC32689078BF7E80A04EC2688440126895441B2CEEC26884402B2CCEC26884409B2CAEC26884404B2C4EC26880483C705B90400B401E870FF268A04EE8BFE83C70A268B544132E4B91900E85BFF268A4401EEE85FFFB2CE32E4B90900E849FF268A4402EE5F5983C7609DC39CFA8BC72BC32689470251572E8E1E3F04A010042430AABE4904B91E00F3A4BE8404B107F3A4BEA804B104F3A4BE1400B104F3A4BE7400B104F3A4BE7C00B104F3A4BE0C01B104F3A45F5983C73A9DC39CFA268B3F03FB8BF7518BFE83C705BAC403B80001EFB001B90400E807FF47B2C2268A4409EEB2C4B80003EF268A04EE268B5441B81100EFB11932C0E8E6FE268A4401EE80C206268A4404EEECB11532E4E8DBFEB020EEB10932C0B2CEE8C5FE268A4402EE599DC39CFA268B7F0203FB06512E8E1E3F04268A0580261004CF0806100447BE4904B91E00E88EFEBE8404B107E886FEBEA804B104E87EFEBE1400B104E876FEBE7400B104E86EFEBE7C00B104E866FEBE0C01B104E85EFE59079DC39CFA8BC72BC326894704E8A605B2C0B034EE42EC268805BAC803EC26884501504A4AEC2688450283C703B900034232C0EE4242ECAAE2FC584AEE9DC39CFA268B770403F3E86C05B2C0B034EE268A04EEBAC603268A4402EE56424283C60332C0EE42B90003268A04EE46E2F95EFECA268A4401EE9DC3BACC03EC24FE0AC4B2C2EEC3E8A812B2C086C4EEEB00EB0086C4EEEB00EB00B020EEC3508AE080E480802687047F08268704247F8AE03C077E1E26F647330175173C2374133C32740F3C33740BB40326F64709017502B40788264904BAB403800E87040226F64709017407B2D480268704FD89166304C7064E040000C606620400B90800BF5004FC061E0733C0F3AB07268A0732E4A34A04268A4701A28404268A4702A38504268B4703A34C04268B471486C4A3600458C35232E433D2B00DCD17F6C429750832E433D2B00ACD175AC3061E602E8E1E3F042E830E490400756E803E0005017467C6060005018A1E620432FFD1E38BFB8B8550048A3E62045032F68A0E840432ED41518B0E4A0432D2E8A6FFF6C429753D515289955004B408E8B0D40AC07502B02033D232E4CD17F6C429751F5AFEC259E2DEFEC659E2CAE877FF32C0A200055889855004E8AF03611F07CF5A5959B0FFEBEA522AF538C67D0232C02E8E0641045AC3A08504F6E38AF78BD88BCABAC403B8020FEFB402E86D008BD132ED8AE68AC6F3AA03FD8ACA4B75F732E4E85700C3538A1E62040BC075040ADB7403E835035B8BF82BD181C201018AC332E4C38AC632F62BEA0ADB742A2AC3F62685048BC852B401E82000B2C4B8020FEF5A1E061F8BC18BCAF3A403F503FD4875F51FE881FFC38AD8EBF8BACE03B005EE42EC24FC0AC4EE4AC39CFAEE42EB00EC4A9DC31E2E8E1E3F048B16630480C2061FC31E2E8E1E3F048B1663041FC350BACC03ECB2D4A8017502B2B458C3E8EEFF80C206C31E2E8E1E3F04803E4904037413803E490402740C803E4904017405803E4904001FC3502E8E064304A0100424303C3074052E8E064504580BC07403E8E10103064E0481C201012BD132ED8B2E4A048BF88BF08BC5F6E3D1E0D1E50ADB75028ADE38F37E028ADEC3FC8AD88BC1E8B3FF03F03A164A047406061FE81B00C3061FE84000C3FC8AD88AC18AE6E895FFF7DD2BF0061FE80100C3538ACE2ACB32ED32F62BEA2BEAE30E8AE18BCAF3A503F503FDFECC75F458B0208ACAF3AB03FDFECB75F6C3538AC62AC37406F6E28BC8F3A5588BC8F6E291B020F3ABC38BD8E82E002E8E1E45048AC322DFD3E3A8807403301CC3F6D78A3422F70ADE881CC38AFCE80C002E8E1E45048A04D2E822C7C3B028F6E2F6C201740305D81F8BF1C1EE0280FF057F0C03F0F6D180E103D0E1B703C3D1EE03F0F6D180E107B701C3FC8AD82E8E0645048BC1E8860075028ADE03F0E82400C3FC8AD82E8E0645048AC18AE6E86D0075028ADEF7DD81C6F00081C7F0002BF0E80100C38ACE2ACBE32C518ACA5657D1E9F3A513C9F3A48ACA2BF12BF981C6002081C70020D1E9F3A513C9F3A45F5E03F503FD59E2D48AC78AE78ACA57D1E9F3AB13C9F3AA8ACA2BF981C70020D1E9F3AB13C9F3AA5F03FDFECB75DEC3E8B00081C201012BD138F3760232DB51B102D2E6D2E35932EDBD5000803E4904067404D0E2D1E0061F8BF88BF0B050F6E30ADBC352538ADF32FFD1E38B875004E80E0050D1EBA14C04F7E35B03C35B5AC3528BD0A04A04F6E432F603C2D1E05AC38BE883E50F2E8AA6427A8BE8C1ED0483E50F2E8A86427AC300030C0F30333C3FC0C3CCCFF0F3FCFF268B0486E0BA0080F6C4C074020AD6D0EEC1E00275F288560045C38B1663048AC586E0EF8AE1FEC0EFC3528BD08AC4F6264A04C1E00232F603C25AC3538ADF32FFD1E38B875004D1EBE802005BC3528BD032F6528AC4F6268504F7264A045A03C20ADB740803064C04FECB75F85AC3528BD0A04A04F6E432F603C2D1E003064E04D1F88BC8B40EE891FF5AC38BC2F7264A048BF9C1EF0303F80AFF740A8AC732E4F7264C0403F880E107B480D2ECC3E8F0FCECC3E8F8FFB2C0B020EEC3E8EFFFB2C032C0EEC3C43EA80426C47D048CC50BEFC353B00EE895FC8AE0B00FE88EFC8BD8B80EAAEFB80F55EFB00EE87FFC3CAA740DB00FE876FC3C55740432C05BC3B00E8AE7EFFEC08AE3EFB0010AC05BC38AEE8A368504061F0ADB74258AC52AC3F6E68BC85232F6C1E2028BC2D1E22BD5518BC8F3A52BFA2BF259E2F45AE80500C38ADDEBF88AC6F6E38BC88AC78AE032F6C1E2028BDAD1E28BF12BD58BCBF3AB2BFA4E75F7C32E8E1E3F04890E60048AC52460A8207406B9001EE99400F6068704010F858B00803E4904077406E819FC7401C3F6068704087403CD42C38A3685048AD6FECA38CD7E1F0AC974648AE98ACEFEC9EB5C38D174588ACE80FD037C048AE9D0EDFEC9EB4980F9037E448AE12AE50AE4750A38CA7438FECA38CA74328AC50AC138F07E0A80FC027E1280FD027FC880FC037DBF8AD6FECA38D174138ACEFEC9FEC98AE92AEC80FE087F04FEC1FEC5B40AE805FEC32E8E1E3F04A2620432E48BF0F7264C04A34E048BC8E87AFB7407803E4904077702D1F9B40CE8DCFDD1E68B845004E827FEC32E8E1E3F048A264904E8359F7407C70650040000C3E848FB740B80FC0774067708E877FCC3E89FFBC380FC137C03741FC3E84EFA8AD88BC1E885FA8B2E4A0452F6268504F7E58BF703F05AE890FAC3E830FA8AD88BC1E867FAC1E703528B2E4A04C1E503F7268504F7E58BF703F05AE855FEC32E8E1E3F048A264904E8E1FA740C80FC077407774080FC037F04E853FBC3E81EFCC3E8EAF98AD88AC18AE6FEC4E81DFA2B3E4A04C1E70352F7268504F7264A04C1E0038BF72BF05A8B2E4A04C1E503F7DDE800FEC380FC137C0374C6C3E8AFF98AD88AC18AE6FEC4E8E2F9528B2E4A04F7268504F7E52BFD8BF72BF05AF7DDE8E9F9C32E8E1E3F042E8E064504E85DFA7411803E4904077C182E8E0643047403E9B100E849FC8BD8268B078BEC89461AC3A15004E8B7FC8BF0BB08002BE38BEC803E490406751FB90400268A0488460045268A8400208846004583C650E2EBB80002B280EB17D1E6B90400E856FC81C60020E84FFC81EEB01FE2F0EBE22BEBC43E0C0132F680FB0E750926837DFE107502B680161F8BF58BCBF6C6807401475657F3A65F5E7423FEC003FBF6C680740147FECA75E2FECC740F2E8E1E3F04C43E7C00B080B280EBCB32C08BE503E38BEC89461AC3803E4904137C057502EB5AC32E8E064104E818FC8BF08B1E85042BE38BECB80508B90500BACE03803E49040F721AF6068704607513B40AF7C601007502B405B007EFB80518B90501EF518BCB268A04F6D08846004503364A04E2F158EFB8000132D2E944FF2E8E064104A150048BD032F6528AC432E4F7264A04F72685045A03C28BF08B1E85042BE38BEC538B3E4A044FC1E703C1E603B9080032E4268A04D0E40AC0740380CC0146E2F18866004503F74B75E35BB8000132D2E9ECFE33EDEB03BD01002E8E1E3F042E8E0645048A264904E8C4F8740F2E8E06430480FC0774057C3DE90B028AE38BF08ADF32FFD1E38B8750048BD0A04A04F6E432F603C28BF8D1E70ADB740BD0EBA14C0403F8FECB75FA8BC60BED7503F3ABC3AA47E2FCC3502E8E064504A15004E8EEFA8BF8A050048A264A048BE858A8807408247FC5367C00EB04C5360C018AFC32E4C1E00303F080FF067469D1E78AF3B05580E303F6E38AD88AF88BC550B204F6C6807527ACE855FA23C3ABACE84EFA23C3268985FE1F83C74EFECA75E783EE0881EF3E0158E87200E2D2C3ACE82EFA23C3263105ACE825FA23C3263185002083C750FECA75E583EE0881EF3E0158E84900E2A9C38BC550B204F6C380741FAC263005AC263085002083C750FECA7FEF83EE0881EF3F0158E82000E2DAC3ACAAAC268885FF1F83C74FFECA7FF183EE0881EF3F0158E80300E2BDC3FEC038E0720632C081C7F000C38A168504F6E28BF032F68BEA660FB6065104F6E2660FB7164A0483FA647503BA680083FA5A7503BA600081FAAF007503BAB00052F7E2660FB7F8660FB60650046603F866C1CF1003FA66C1C70381CF00FF66C1C7105A8AE24AC1E203A0500450C5060C0103F02E8E064104585751509CFC8BCDE83B00B508AC8AE08AC7D0E473028AC32688056647FECD75EF6603FAE2E29D58595F83C708FEC038E0720E5132C08BCD4903FA83C708E2F9592BF5E2BCC3065233C08EC066C1C7108BC766C1C710E8A49A741638E074120FB6D0E88BC98AE066C1C7108BF866C1C7105A07C380FC137C0B0F8418FF80FC620F8411FFE80100C380FC11750680E38080CB0F50538ADF32FFD1E38B9750045B2E8E064104E807F98BF88B2E85045832F6528B364A04568A268504C5360C0180FC0E7509837CFE107503B41046F6E403F0B603F6C380756DB2C4B8020FEF5A5850524A8AE0575151578BCD32C0AA03FAE2FB5F47FEC438D4760A32E48BCD4903FA47E2FB59E2E0595FBAC403B0028AE3EF5B4B5A51578BCDAC268A25AA03FBE2F75F472BF5423BD3760A33D28BCD4903FB47E2FB59E2DDBACE03B80300EFB2C4B8020FEFC3B2CEB80318EFEBBC2E8E1E3F04803E6304B4740BBACC03ECA8017504CD42C3C3E8D1F80AFF751C8AE380E41F80266604E008266604E82D008A1E660480E320B105D2EBE891F57419A0660424DF80E30174020C20A2660424100C020AD8E85300C3E87EF8C3535080E30F8AFBD0E381E310070ADFE860F5740EB4008AC3E82CF30BED740326881D8AC3E80B000BED740426885D10585BC38AE01E2E8E1E3F04803E4904331F7F088AC4B411E8FEF2C3E830F8C39CFAE89F05B2C0B90300B4018AC4EE8AC3EE0BED74044726881DFEC480C302E2EBB020EE9DC32E8E1E3F048A264904E8F2F4740A80FC0777067403E8C0F5C380FC137C03744CC38AD8E8BBF7BACE03B008EF2E8E1E4104F6C380751CB2C4B802FFEF8A25C605008AE3EF8A25B4FF8825EFB2CEB808FFEFC3B80318EFB2C4B0028AE3EF8A25B4FF8825EFB2CEB80300EFEBE1502E8E064104A14A04C1E003F7E203C18BF858268805C32E8E1E3F048A264904E86FF4740F80FC07770B7408E85FF58BEC89461AC380FC137C037429C3E835F78ACC2E8E1E4104BACE0332FFB80403EFD0E78A1D22D9740380CF01FECC7DF08BEC887E1AC3A14A04C1E003F7E203C18BF82E8E1E41048A058BEC88461AC32E8E1E3F048A3E62048ACFD0E132EDBE500403F18B148A0E49043C0D764A2E8E064504E8EEF375338A1E4A048AF88AC6F6E38ACA03C8D1E1030E4E048BF98AC7AAD1E941FEC238DA735989148B166304B00E8AE5EF8AE1FEC0EFC32E8E06430480F90774C3E98300750432D2EB0F3C0A751D3A3684047503E99300FEC68914E892F3750580F9077F058BC2E84CF6C33C077504E8C581C33C0875830AD274DEFECAEBDA32FF32D22BCB3A3684047406FEC603CBEB9589148B166304B00E8AE5EF8AE1FEC0EF2BFB2BFB268A6502508B3E4E048BF3D1E603F7A08404F6E38BC8061FF3A58BCB58B020F3ABC3B90100B40AE8BCC6FEC23A164A0474038914C332FF32D289143A368404742EFEC6EBED89142E8E064504E8FCF2740E2E8E06430480F907740432FFEB108BC2E8ADF58BF9D1E74F8B1E4A04EB9133C98A3684048A164A04FECAB001E970F72E8E1E3F04F6068704087403CD42C3E876F68BECC6461B00C32E8E1E3F048ADF32FFD1E389975004D0EB381E620475058BC2E85CF5C32E8E1E3F048ADF32FFD1E38B9750048B0E60048BEC894E16895612C32E8E1E3F04A0870424800A0649048A264A04F606870408752DE85DF27407803E4904077F21518ACC8A2E8404BEDB8581FEE48574102E3B0C740583C603EBF024802E0A4402598A3E62048BEC89461A895E0E894E16895612C3841823842B33842A322E8E1E3F043C047F1B5052BACC03ECA8015A587408803E6304D47408C3803E6304B475F83C1C73F432E48BE8D1E52EFFA617864F866F868186B686008600860086DB86F386F78600860086008600860086008625870086298744870086838700869187AC87B387BF87E387803E4904137415E8BFF48BC386E0E870EF0BED74078AC732FF268801E893F4C3E8A6F48AC7E844FC0BED74F026887D11EBEA803E49041374E306E88CF41F0BED74078BF2B91100F3A48BF2E8DE0132E4B91000B2C09CFA8AC4EEACEE9DFEC4E2F4ACE807FCEBB580FB0177B0E843F4B2C0B030E8FBF024F780266504DF80FB0074070C08800E650420EEEB90E89D018AC3B2C0E8DBF08BC8EEB020EE8BEC884E0FE978FFB311EBE48BFAE805F4B9100032E4B2C08AC49CFAEE42EC268805FEC44AEE9D47E2EE9CFAB011EE42EC9D268805E8E3F3EB5AE8CE00C38BFA518BC3268A35268A6D01268A4D02E8CA0083C7034359E2E8C30ADB751AE8B6F3B2C0B030E86EF0247FF6C70174020C80B430E870EEEB1DFECB751CE898F3B2C0B030E850F0EEA8807503C0E702B4348AC7E851EEE87FF3C38AC3E8D1008BEC894E16887613C38BFA518BC3E8C30026883526886D0126884D0283C7034359E2E8C3BAC6038AC3EEC3BAC603EC32E48BEC89460EC3E83FF3B2C0B034E8F7EF8AF8EEB030E8EFEFB301A8807505B300C0EF028BEC895E0EEB9C518BC3E87300E82A008AC3E852004359E2EEC3F6068904027403E816008AC3E83900C3F6068904027403E806008AC3E82E00C350B01EF6E650B03BF6E550B00BF6E15903C15903C1B164F6F180FC327C02FEC08AF08AE88AC858C352E839005A538BDABAC8039CFAEE428AC7EE8AC5EE8AC1EE9D5BC3E81F00539CFABAC703EE4242EC8AF8EB00EB00EC8AE8EB00EB00EC8AC88AF79D5BC35051E881F2B9FF7FECA8087502E2F95958C32E8E1E3F048BF8240F81E7F000C1EF0383FF067F182EFFA5A788AF88C4886289BE893C0374083C047F03E8CF01C3BAC403B0038AE3EFC33C0477F2505350528B166304B007E8EBEE8AE0D0EC80E401A840740380CC02B012E8D8EE40A38504B009E8CFEEA8807404D12E8504A185048BD03DF401731BBAE0013DC2017313BA90013D7C01730BBA5E013D4A017303BAC800891685045A58C6068404FFE85D015B588ADF32FF0AC0740EB30E3C017408B3083C027402B3108ACB8AE981E9010280F9087E0481E90101871E850453E85BF25BE88502C30AC07411FEC8741AFEC87438FEC8743CFEC87440C3892E7C008C067E00C38CC88EC0FECA0ADB740732FF2E8A97A289890E850488168404892E0C018C060E01C3000D182AE80903B90E00EBD6BDB258B90800EBCABDC560B91000EBC20AC075BD8B0E85048A16840480FF07773580FF0177100AFF7506C42E7C00EB26C42E0C01EB2080FF02750B8CCD8EC52E8B2EA471EB100E078ADF32FF80EB02D1E32E8BAF158A8BC58BEC894E1689561289460A8C461EC3C560B258B25CB260C560C57053068A264904E8C7C3268A4702268A6733F6C4017422BDC5603C107D0EE871028C060E013C0E7D07BDB2588C0E0E01892E0C01E81001EB2DB4843C107D13B4813C0E740D7F15B4023C08740580CC80EB0A26F6470501740380E47F86C432DBE80600E8C901075BC38BF88BF2BACE03ECB80500EFB80604EFB2C4ECB80204EFB80407EF8BD68BC750247F0AC074220E0733D2B900013C047507B710BDC560EB10FEC87507B70EE8E801EB05B708BDB258E82D0058A8807400BAC403B80203EFB80402EFB2CCECA801B8060E7502B40AB2CE50EC58EFB004EE32C0EEB80510EFC3FC0BC97501C380FF0E750A26837EFE10750380CD801E061F2E8E0641048BFAC1E705B0405380E303F6E35BF6C3047402042086E08BD003FA8BF5E32832C086FB32FF51F6C5807401468BCBF3A483FB207407B920002BCBF3AA59F6C580740146FEC975DE1FC38A264904500657C43EA80426C47D0C8CC50BEF74308BEF83C707268A053CFF742438E0740347EBF28BFD268A05FEC8A28404268B4501A3850426C47D03893E0C018C060E015F0758C326F64733017401C3C41EA80426C45F088CC00BC3741FBF0B00268A013CFF7415473806490475F2268A0732E4870685048BD8E80100C38B1663048A268504FECC80E41F9CFA80FAD4740BB014EE42EC24E00AC4EE4AB009EE42EC24E00AC4EE9D8AC88BC38A168504F6F2803E8404FF7507A28404FE0E8404F6E2F6C1807402D1E0488AE0B0128B166304EFA04A048A268404FEC4F6E4D1E0050001A34C04C38A264904500657C43EA80426C47D088CC50BEF744A8BEF83C70B268A053CFF743E38E0740347EBF28BFD268A3D268A5D01268B4D02268B5504268A450A3CFF7402FEC850A08404FEC0F6268504A3850458A2840426C47D068BEF32C0E8DBFD5F0758C3505351522EA149040BC074092E8B2EA4710E07EB08B83011B702E8C7BE5A595B58C33C047C01C3E3FD532E8E1E3F0486FB32FFD1E38BFB81C750048B355B8915568BF05153268A4600453C0D7F1F750432D2EB403C0A74323C077505E83179EB623C0875080AD2745AFECAEB27F7C602007405268A5E0045B90100B409E864BEFEC23A164A04720C32D289153A3684047306FEC68915EB2B50E8ADEA7508B80008E840BEEB09803E49040774F132E4863E6204538AFC55E825005D5B863E6204588B155B59E2155AF7C60100750289158B053A3E62047503E834EDC3E964FF33C98A3684048A164A04FECAB80106E8F3BDC32E8E1E3F040AC0750DE818008BEC895E0EC6461A1AC33C017509E841008BECC6461A1AC3A08A04BFA28E2E3A057204BBFFFFC332E4D1E003F82E8B5D040ADB74050AFF7504C386FBC3A0100424303C307406F6C30175EFC3F6C30174E9C3BFA28E2E8A0D32C083C7042E3B1D741286FB2E3B1D740B83C702FEC038C87EEBB0FFA28A04C3BB0800F606890402740EBB0700BACC03ECA8017418BB0800BAB403E8DFEC7421B701E88CE980FAD4741786FBC3BAD403E8CAEC740CB702E877E980FAB4740286FBC30F080F080F080F08030103010101000801010101010101010F010F080F0400020F0201010F01FF01FFE00F00000000070208FF0E00003F00100108000000000100020201000404010005020500060106050600080108000702070607CA003400900096000000000000005F57C390506652E8F4FFFFFF81EF100000002E8B0766BAF80CEF66BAFC0CED32C0668BF8665A58C366B84F03665266565357500AFF7544E8C8FFFFFF6633F666BB5300E848000000C1E810F6C440752B6681E2FF0266D1E2668BC26640C1E010668BC266BB1300E83000000066BB1200E827000000665832E46650585F5B665E665AC39066B84F03C39066B84F03C3906652E811000000ED665AC3906652E805000000EF665AC390668BD75033C0668BC36603C6C1E002EF6683C20458C3AA379D379D379D378837883788378837CA3341346B34AC35AB35AB35F1355636863643376C376C37E335D635D635D635D635D635F1355636863643377137B7376C376C37FFFFFFFFFFFF0000FFFF0000FFFF0000FF000000FF000000FF000000FF000000000008100008101800081018CE3101CE3102DC4503BC4503F33203A73203CF3104E83104F83104CE3103000000007B3900027B3901027B3902027B3903027B3904027B390502753B0002753B0102753B0202753B0302753B0402753B0502AA3B0002AA3B0102AA3B0202AA3B0302AA3B0402AA3B0502E53D0002E53D0102E53D0202E53D0302E53D0402E53D0502E53D0002E53D0102E53D0202E53D0302E53D0402E53D0502AC3C0002AC3C0102AC3C0202AC3C0302AC3C0402AC3C0502E83C0002E83C0102E83C0202E83C0302E83C0402E83C0502593C0002593C0102593C0202593C0302593C0402593C05028D3C00028D3C01028D3C02028D3C03028D3C04028D3C05023D40000070400100704002005D4000004B3F0002443D0002443D0102443D0202443D0302443D0402443D0502633F0002B8410500B8410100B8410000B8410200F9410000F94102003E420000CE3E0002CE3E0102CE3E0202CE3E0302CE3E0402CE3E05028A400000B240000033410000AE410000923D0002923D0102923D0202923D0302923D0402923D0502AD410001AD410001B13A0002B13A0102B13A0202B13A0302B13A0402B13A0502D2400000AE410000AE410000AE410000E33F0000D53B0002D53B0102D53B0202D53B0302D53B0402D53B0502043C0002043C0102043C0202043C0302043C0402043C05023A3C00023A3C01023A3C02023A3C03023A3C04023A3C0502F540000018410000D63C0102D63C0202323D0102323D0202A60002010C930000000000000CAB00003293000000004294000000000C95449900000000000000000000000028A07E93EC93D0981494000020C3000000000000000000000000E4A056A1CAA100000EA2000054C20000DEA2B4A474A5D2A614A7BABF0000000028A70000DEBC00000ABFEEA80000C6AA0000000000006CC13ABE0000000000000000000000000000000000000000000000000000000020AE2CAF62BA82BC00004A000201000000004CD144C314D20CC440C448C668DD92C800009CC456CAA8C43AC8C2CA00001CC548DD000034DD000030C50AC678DC0000000010C680D2000000000000C8DC000000002500020100083700004BE50004491900020502060000005215523D5218521A0D655300025B004B000101000037000042210063001F006301390063033F00630245005A5A5B030540000005042D1940001505400201020C00400200000D005B020000E30D5B020000E70D5B020000E80D5B006E0002010C083700003D2500004422003D250006445D003D2500044458005538005B01050000616001003CE5010080492A000105000062600100010101000156004003A940000105000061600100010201004002E500015B02E500015B01050000616001003CE50100804965005B280002010000370000010500006CA80100020000010002010100010500006DA8010002000201005B2E0002010000370000521603014100150541100102600F41030140001B0540100102620F400105F30FE10A602D5BCA0002010404370000660C030C4100002D0A41422D0D4204003D240006004431002D0D4208003E0A42414519005520005B5600430324430500030446000033054601000000010200004603000001000D020100442D054602000000010200004603244304004BE5000149AA0007020100452D05460100000001020000464A02010044449000032943000EA200444398000329430008A2004533054603000000010200004601020100005B0D020100440104000000003DA5000144C400070201004543C9000D020100445BC303010710083700003D2501FF44A1033D250119469D033D250102479D033D25011445A1033D05000000000044FD01661B5600023DA501024941005608404353003DA50103494E00560840435300030C4018003E0D400000446200030A02404366000EE501804BE5010249740002A9020255280203010000030546A86100003DA50100448D0003054650C300005CA50F5EF3085528013E0500404B4C0047A7001B05000143BC002C6501013E0500A025260048BC001505000143A700142D01044BE5018049EB00210502800000007C0240007E0240467C0540100000007E0540350C00000302024043EE00560002270200462105410000010027024046030A42403E054100000000491601030D40010056080143400103024046030201410302034127024041030240033E054100000000491E0127020103030A014027024603030A0301030A0140038A0142270200463305401000000015054005038A034066FF2D0D42AB035600400321400133254014152540012D0A4240030C4800004A25065E044423025600404BE50130449B014A25F15D0144DC0143A3014A25F15D0149DC010300400B5E090D40F0FF3E1A400349DC013C02075E0149DC013C0A0A5E0349DC010300400C5E092540703E29400149DC013C02085E0244E0010EE501013A00004BE501014475034BE5010249FD013D25020446FD0155280252233A000002010302020502000003040221020132250214524D020102033D050000000000449D033DA50100444E0202010302020502000F030002210201322502144BE501304448020EE50201524D0201020366FF2D0D42AB035600400321400133254014152540012D0A4240030C480000030540000038003E0500C0C62D0047A0025EA540CF203E0500E067350047A0025EA540CF103E050000093D0047A00209A540CF5CB20F5EC34003054020001C243DA5010044BB0203054010000C125C9A105E0300405C1A0B5E0F00035CA20B5E8F40560040032940010F2540014BE5018049E5020F6540015C0A0C5E8BFE40078D0D5E0FE03E8D010000490A033E0D030000490A0307E50E5EFE430F030DE50E5E014AE50E5E014927034A650C5E0149270307E50E5EEF432C030DE50E5E100102075E010102085E027C050200EC04007E0240462705400A0000000102095E40010A0A5E033A00003DA50100449D0303010002020502000103040221020132250214524D020202003A00003D250204469D030225030202E103020261030102B9030108A503040EB1030202010200522E3A00005B0225010B4375037A18000000D800B001880260033804000000010002000300040005007300020100003700003D65000144720056004003214000212540DC030A48400105B63A000100005C052D3BCFFFFFFF200000005C05403BCFFFFFFF200000005600400321400021254080030A48405C050150FFFCFFFF0003000056004003214000150540195C025050FFFFFFF1403A00005B5B00E4060201080437000042290063071302630817005A5A5B0D25C839025C253447FC010125320100010542350000000001054035000000000105463500000000010544350000000001054A3500000000010548350000000001054E350000000001054C3500000000010552350000000001055035000000000105613500000000010563350000000001056535000000000105673500000000010569350000000001057235010000000105DF39021000000105B33A000000000105B13A001B5D050105063B350013000105073B361100000105083B41E601000105093B0000000001050A3B0000082C01050C3B0204000001051F3B5E4E010001050A3B0000082C01050D3BA401000001050F3BA40100000105143B000200000105153B49D200000105183B200000000105193B240D000001051C3B0000000001051D3B000000000105ED3A000092060105EE3AAA0800E00105C939FE0100000105CA391E0500000105CB39BA0400000105CC39240400000105CD39A20800000105CE39FE0100000105CF391E0500000105D039BA0400000105D139240400000105D239A20800000105D339FE0100000105D4391E0500000105D539BA0400000105D639240400000105D739A20800000105D839FE0100000105D9391E0500000105DA39BA0400000105DB39240400000105DC39A20800000D25C839020D25DA4101012533470001253147000125324700012545480001658B4FF05B01051F35FFFFFFFF010520351F00000001053B016402120001053001A0861100010531013C000108018D8338640001258238010125320100010542350000000001054035000000000105463500000000010544350000000001054A3500000000010548350000000001054E350000000001054C3500000000010552350000000001055035000000000105613500000000010563350000000001056535000000000105673500000000010569350000000001057235010000000105DF39021000000105B33A0000000001058F3B1000000001056B3C200000000105473D300000000105233E40000000550001200D01DC00030A48400105B13A001B5D050105063B350013000105073B361100000105083B41E601000105093B0000000001050A3B0000082C01050C3B0204000001051F3B5E4E010001050A3B0000082C01050D3BA401000001050F3BA40100000105143B000200000105153B49D200000105183B200000000105193B240D000001051C3B0000000001051D3B000000000105ED3A000092060105EE3AAA0800E02C0501010000003D0D01050045FE025608480105C939FE0100000105CA391E0500000105CB39BA0400000105CC39240400000105CD39A20800000105CE39FE0100000105CF391E0500000105D039BA0400000105D139240400000105D239A20800000105D339FE0100000105D4391E0500000105D539BA0400000105D639240400000105D739A20800000105D839FE0100000105D9391E0500000105DA39BA0400000105DB39240400000105DC39A20800000D25C8390255000166FF2D0D42DA06030C4800000D25DA4101200D011B00030A4840012133470101213147010121324701200D010400030A48400121454801200D011000030A4840030D4000F00F614001016A8B4F402C0D0101002D0D4202003D25010545600456084855000152172C2501013D25010545BE040205010502000052296608030C410C003E0D41000044020501A5150103010513011027000001011401010D251501014A6515010244FA040101420101010146010101014A010101014E01010101520101550001524E5C05DD5D00F0FFFFAA0A00005C056353FFFFFF00000000305C056553FFFFFF00000000305C056753FFFFFF00000000305C056953FFFFFF00000000305C056B53FFFFFF00000000305C056D53FFFFFF00000000305C053155EEFFC0FF110001005C053156EEFFC0FF110001005C053157EEFFC0FF110001005C053159EEFFC0FF110001005C05315AEEFFC0FF1100010001059A550100000001059A560100000001059A570100000001059A590100000001059A5A0100000002250107523302050100070000550002524D2C2501013D25010645E805661603A40006002D0D420800030A00423EA50000447906030A4200030C0104003E0D0121214425063E0D012122496D06030C40080066162D0A424003244000003E2540FF446D063E25401449650603044002004C054000010000446D063E0D01212244620601A5596101436D06436D062D0C4201004330062D0D00100033A500014305066616030C4104004C0D410200448D060DA54C0002521601015339020101543903010555390000000003014101150541180102C40041030141011B0541080102C900410300415539010259394103014003330140022D02404101025A39405B7A0A0000006B01D60241040B29BC000201000466FF5608472D0D42740003214700092547F042224763005B00636056006320360063904E0063A03E0063B046005A5A5B2D0D423000435B002D0D422400435B002D0D423C00435B002D0D421800435B002D0D420C0003214700092547072D0A42472D0A4247030C4800005B7ABC000000800000018001000280020000000100020003000400050000DC00B801940270034C0400006B01D60241040B29762A0000D800B00188026003380400005A00B4000E016801C20172000101000037000056004003214000210D406B01030248400125AC41013D650002494C00010DBD4101005400BB410D25AE41010105AD411100000007A5AC41FE0105AF4111011101436E000105B141000000010105B541000000010105AF41110111015400AD41010DBD4100013A00005B7300010100003700005214030041C041331A4141038A4041030041C141331A4141030A40413E0540000000004936000305407008000F0E2500B052143D650000446D000102164D400105174D000000000105184D000000000105194D000000005C05144D8FFF0FFF310000005B0725144DFE5B0043000101000037000052143D650001443A000D65015003542001504AA5015001491B0054200F5056004020250001030A484007E5E8397F433F000D250150013A00005B00CF000201000037000042290063001B0063011B006302AA005A5A5B66FF5608402D0D42C30003214000152540012D0A4240030C4800003D6500004472000D25CC00013A0000018DC000000251020105C600000010000105C80000005000010DC30002005420CA000105C20000010000431A000725CC00FE3A00000D25CA00010125C2000107A5C100FE0D25D500010D65D500014A65D500014493005408D5005400C6005400C800431A005C65D400FC0201A1C000002BA5C000010DA5C100015B7A0C00000002002C002D002E002F0000D501030104003700006608030546102700003DA50002491E00020200465B0305400C0000002121400066FF2D0D4281012D0A4240030440000003044104000304000800010200004003884001000318400100098D40FF013E8D40000049990001020000410300400100090540FF0100003E0D4000004982000305460071020043BC00210240460300410100090541001E00001B05410943B4007C0240467E054000000100030041010009054100F000001B05410C75024041030246403DA5000149C800020200465B3DE50000490B0156004003294000210D400A00030241002D024041010200004003004101000905410000F0071B05411402E200413DE50000490B01020500102700005B5600400339400055380066FF2D0D4259013E0C400200472C012D0D420800431C01330C400400210C4006002D0C40000003094200550000020A00407C054640420F007E014000020200405B7A7C00FFFF070000000000C8003F000800190040065F0040003200800C7E006000640000327F007F006400116C0100006C01004C6C01000D6E0100006E0100486E01000D70010000700100487001000D6E0100006E0100486E01000D7E0100007E0100487E01000E72010000720100497201000EB0010000B0010049B0010000BF0002030400370000560046560000032100005520003D650003442C003D65000D46B40002290000322500080E25006052145C222855F80002220000030D41010066FF2D0D42BB002D0A424103240000003DE2000048A0003E250004446F000322460033254601152546040F254601333900003E250001448C003E250002448500032546210365002F439000036500130379460033654601152D46030F65460152140102014D460152004D005400054D5400FF4C3A00005B7A040003020104005E01010404083700003D6502014927014BA50203492A0052250205000000000002050100050200432F005528025225033800C400034800C9000E2502905214082502070D05B43A111101005C25B33A0B0103214102152541040D22B33A410D65B63A015C25DB3AFD01030241001B054108010ACB3A41010ACF3A41150500180102CA3A000102CE3A004BA5020349A0002B05CA3A000010002B05CE3A00005000010DA73A8000010DB13A0003010D0C3B010301050A3B0000082801050B3B0000080001E5EF3A0801E5EE3AE05400A93A0119AA3A000189AA3A000119AE3A000189AE3A00070DA53AFFF866FF2D0D424F01030C4000003E0D40FFFF440E013D8C010000440E012D0D42030043F1000124A53A02000109C73A010725B33AFE0725DB3AFE3A00005B0E25029052143D650200493C010D25B33A014348013D6502104448010109C73A013A00005B7A0F00010001010103010502020008FFFF0842000101000037000052143D65000144210054204B504A654B5001491600433E005C4D1B50FEFF00014AA5015001443E000D254B50014A654B50014436003A00005B1300010300003700000E2500A052143A00005B00C6010101001856004003214005210D408000030A4840370000010D47500D003D8D010D00462C000119475001018D48504001010D49502C01030941002D194100038A41412D8D4101001B1D4102011A485041330D410100010AEA4F415408EC4F0199EC4F02031941003309410256184103B14104331A4141018AEB4F4103194100330941022D1A41412D0941004B2504104498002D094100010AEB4F4103214104092541021B2541010122ED4F41030941012D194101330D410100010AEF4F415408F74F0199F74F03031941013309410356184103B94104331A4141018AF64F4103194101330941032D1A41412D0941014B25042044FC002D094101010AF64F4103214104092541041B2541020122F84F413D65050044210107650150EF4326010D65015010030046EB4F020002F64F56004003214005210D400100030A4840560040030940023D650500495301330D4002001505400F5600413D8D020D00486B01030D410D00331941020F0240410FE540800102E8394056004003214005210D406B01030A48400109C341000189C341010109C441000189C441010102C041460101C141025400BE410131BE410401B1BE41045400BF410139BF410401B9BF41043A00005BD80101010000370000560041033941010925410F3E254107491C005B560040036240410102585340030A464266FF2D0D42C001152541022D0A4241030C4800000705905D00000100030C48020003054050C300005600410321410027024041150540100325400201026253400105635340000030030A42465608480D255A530154005953560041037141010FE5418001027253410369410003A5410101027253414B25010144D5000371410003A5410201027253410379410003A541030102725341030540003101002DA9400101026E5340430801037141010F65410103A5410201027253410305400011010001026E53400305400130000003A9400101026F53405CA55853CF100D2558530102650002560040032940012D254004210540C80000005600410321410027024041030A4140330D4101003E0D41000044AC0151644A255B53044432014A655B533149AC01026500014B25010149AC0101057253010003803D65010149730102A800725343AC0156004103194100560040030A40413B02400328407253036840725303A840725303E8407253040200402DA541042D0D4104003EA94101457A010D255A530201255853025101540058535B7A18000000000004000200080004000C0006001000080014000A004600020200043700005530003225000120250008560848032248400DA5D5530102A000D45308A500034A25D45302443C005C0DD553FFFE01004342000D0DD55301013A00005B1403010500003700000E25006052140825000F422900630F530063110902631266026301CC026300F5026308D8016309B901630AC0016313C8016314D001630BE001630CBC02630DE801631001025A5A43B50154009A55010D2B551F003DA500004472003DA5000244A2013DA5000549A2015400C9553D250200498100022502023225020101E1C955024A25CC550149B5017B0501008000007E05408C0A000056004603294602270240460765D055FE0105D155008000000102D255400DE5D355100D65285504510107652855FB5101032140021525400501E2CA55405420CE5502A0022855030A464808A5020756004003314002210D408000038A4640030A4840038840EA4F030840EF4F2D054001000100039841EB4F031841F64F030A484601020C564001020D5641031A4846030040EB4F331A4040330840BE41330840BE41030041F64F331A4141330841BF41330841BF41030A4846010A0F5641018A0F5640031A4846030040EC4F338A4040030041F74F338A41414A25ED4F014485010FE540804A25F84F014491010FE54180030A4846011A0E5641019A0E564043B50107E528552F0D65285504510107652855FB51013A00005B5420D85543B5010125D8550143B5010125D8550243B5010125D8550343B5010725C855EF43B5010D25C8551043B5010D65D05501510A0725CD55FE510A010DCC55010251C843B5010D25DE551043B50101696F55023DA500034925024A2535551049250201A56F5502432A0201B16F55003D250200443F0232250201142502045CE16F558F023DA50005444D023DA50000495E0202A5000003394000332540010122CB554002E002705543B50102E00270554BE5020144B50102B0006F553DA50000448C023DA50005448C0202E5000443950202E000CB552CE500013DA5000244A3023DA5000349AC0254007055500243B50102A50000033143004A626F554444B5015408CC5551C80D25CD5501513243B5010D257055013DA5000044E102010DA1550F0143B501033943000302404433254001010AA1554043B5015400A15507257055FE070D6F55FF8007253555EF5420C8555420D85543B5010C01010604003700004229006307EA00630125006300C000630BED006304F2005A5A43050102650010524D3D65000044E6000265001152044BE5020149E6003DA50000495700030100000265000F553800524D020200000265000A550802524D3DA500004970000265000B524D4379000265000E524D43AD0020050164000000020501141E00022C2101000301000002020040520C26050064000000020201400202000002650001550802524D5105026500015204510A02650009524D43E6000265001252044BE5020144E60002650008524D0265000052043DA5000049E60002650000524D3A00005B43E600524D43E6006606022900000268004E00028C00200052335B0229000052335B350B020208003700003D25000344220B66FF2D0D42290B56004003214000152540012D0A4240030C4800003D650010497400026500013D25000445220B4AA5F95D0144220B026500004AA5155E0249220B0D25165E010705155EFFFFFBFF3DE50004456D004AA5155E0144220B0265000143220B3D2500044885000305000101010143C5004AA5F95D01447B004AA5155E0249220B0D25165E010705155EFFFFFBFF030500010100003DE5000144C500030500010100003DE5000244C500030500010101014229006307EF00630ADD0463014D056300DA0663097C086308EC09630B9F0A630E4D0A630F0E015A5A5B0105FD5D000000000105EE5D004000005C05F05DFFFF0FFF0000400043220B4AA5F95D0149220B4A25005E014942013C25F95D004942013C71F95D0049420108E50001030040F15D092540013E39400044220B5420F95D074DF15DDFFE4A65F15D40494C010D05035E010101010D25005E010DA5005E200D25005E010D05035E0101010103394000092540015C22F15DFE405C65005EC1060D25025E080DE5005EA05C05065EBBBBFFFF333300005C05035EF7F7F7F70202020266072D0C420A005600402025000C2D0A4240032440090003624040038A40405C02045EF8F8F8F8400321430003A246443DA500004415020305400400000066072D0C42040003044100003E054100000000444C024CA4460600490D022D0D420C0043EE010324400700434C020305400500000066072D0C42080003044100003E054100000000444C024CA44604004942022D0D4244004323022D0D42080003244005001505400E5C02005EFF3FFEFF400765005EFE3DA500004900035C050B5EFFFF8FFF000020000D050C5E010100005C050B5E0F00FFFF401600000D050E5E000000010105075E0500666601050A5E020000000105095EF32001000105085EF3DF000001050D5E000000005C050B5EFFFFF8FF000000005C050C5E8FFFFFFF200000000D050E5E0000001007050C5EFBFFFFFF01050F5E3E0008000105105E3E0018240105115E3E0000000105125E3E0034004390035C050B5EFFFF8FFF000010000D050C5E010100005C050B5E0F00FFFF600A00000D050E5E000000010105075E010052F854000A5E0105095EE90900000105085E5C0F000001050D5E000000005C050B5EFFFFF8FF0000040007050C5E8FFFFFFF0D050E5E000000100D050C5E0400000001050F5E3E000C000105105E3E0080880105115E3E0000000105125E3E0034000DA5065E080D25F35D010D65F15D204A65F15D40499F030DA5F15D010725005EFE0705035EFEFEFEFE4AE5005E1044B90366072D0C420C0003044000003E0540FFFFFFFF44EB030104F45D00000104F55D04002D0D42080043C8030105F45D382000000105F55D0C0000005600014A05035E2020202044240451022D0501010000003E0501A086010049FE030125F95D0343220B0D05005E00010000030040045E0905400700000021054003000000030541212000002D0241400102F45D41030041F55D0105F45D840000000102F55D41030541222000002D0241400102F45D41030041F55D0105F45D850000000102F55D413D25000445C004030040005E09054000C001001B05400A0105F45D21000000030041F55D0925410F0F2241400F2541800105F45D210000000102F55D415600413DA5000044CF04030D4101015CA20B5EF8410D65005E0143220B030A464866072D0C420A005600402025000C2D0A424020250002030A484001042E5D000007E52D5DFC030A4846030540010101013D250004452F054AA5F95D01442F054AA5065E01492F05090540FFFFFEFE0D02035E40510503024000690540FFFFFFFF0702035E4051C851C843220B4A25FC5D0149220B3C25F95D0049220B4C250001446C050D05065E040000004C650001447B050D05065E400000004CA50001448A050D05065E000400004CE500014499050D05065E0040000003024000150540040D02035E405600014A25FC5D0149220B0302400015054005030041035E09024140090540202020203E02414044EB0551022D0501010000003E0501A086010049A9050125F95D0443220B0302400015054004690540FFFFFFFF0702035E405600014A25FC5D0149220B0302400015054005030041035E090241403E05410000000044400651022D0501010000003E0501A08601004902060125F95D0543220B5600014A25FC5D0149220B4A250C5E80496E0651022D0501010000003E0501A08601004943060125F95D0643220B030A414856004003214000030A48400D25600101510A030A48410D25E85D034A25E85D04448D060D65F15D124A65F15D04449A064C25000144AE060D65F05D104C65000144BA060D65F05D204CA5000144C6060D65F05D404CE5000144D2060D65F05D800171F95D0043220B4A05065E4444000044220B0765F15DFD0725E85DFD030A414856004003214000030A484007256001FE030A48414C2500014416070705065EFBFFFFFF4C6500014425070705065EBFFFFFFF4CA500014434070705065EFFFBFFFF4CE500014443070705065EFFBFFFFF07650C5EFE5400085E5400095E030040065E4C2500014467075E0540FCFFFFFF030000004C6500014479075E0540CFFFFFFF300000004CA50001448B075E0540FFFCFFFF000300004CE50001449D075E0540FFCFFFFF003000003C02065E404451080102065E4003024000150540040D02035E405600014A25FC5D0149FC070302400015054005030041035E09024140090540202020203E02414044FC0751022D0501010000003E0501A086010049BA070125F95D0743220B0302400015054004690540FFFFFFFF0702035E405600014A25FC5D014951080302400015054005030041035E090241403E05410000000044510851022D0501010000003E0501A08601004913080125F95D0843220B0302400015054002690540FFFFFFFF0702035E400302400015054001090540020202020D02035E4043220B4A25FC5D0149220B56004020250002030A4148030248400DE52E5D10030A48413DA5000044A8080D65F05DF00DA5F05D010DA5E95D013DA5000044C4084A05065E3333000044D5090302400015054001690540FFFFFFFF0702035E400302400015054002090540040404040D02035E40030040065E4C25000144FF08090540FCFFFFFF4C650001440D09090540CFFFFFFF4CA50001441B09090540FFFCFFFF4CE50001442909090540FFCFFFFF0102065E4003024000150540040D02035E405600014A25FC5D0149220B0302400015054005030041035E09024140090540202020203E02414044800951022D0501010000003E0501A0860100493E090125F95D0943220B0302400015054004690540FFFFFFFF0702035E405600014A25FC5D0149220B0302400015054005030041035E090241403E05410000000044D50951022D0501010000003E0501A08601004997090125F95D0A43220B0302400015054003090540080808080D02035E4043220B0302400015054003690540FFFFFFFF0702035E4007A5F05DFE4C25000144110A0765F05DEF4C650001441D0A0765F05DDF4CA5000144290A0765F05DBF4CE5000144350A0765F05D7F07A5E95DFE56004020250002030A484007E52E5DEF43220B0321430003A2464466072D0C4204003DA5000344710A66072D0C4206003DA5000249220B03044100003E05410000000044220B3D020141468F0A4CA446060049970A2D0D420C0043710A030441080043FE0A08A5001B66072D0C4208000321430003A2464403044100003E05410000000044220B3D02014146D00A4CA446040049D80A2D0D42440043B20A2D0D4208003DA400000044F90A03244100003E25411844F90A2D0D42060043DD0A03044101005C020F5E0000FCFF415C02105E0000FCFF415C02115E0000FCFF415C02125E0000FCFF413A00005B7A0C000000D800B001880260033804001F02010200003700003D0D00000044CE01560041032141010925410F150D4102030A404266FF2D0D4207022D0A4241030C4802000DA5905D015408905D030C48000003F94101153D41045CBA10548F41030A42404A251054014981000D0D105401010D251054104A2510542044670007251054EF4A251054204974000D25135440560041030941003B0241033B41001B25410401A211544103694101152D4104012A1154415600400FE54080037340000102165440560040036B40000102165440036340000102165440037B40000965400F01021654403E254104471001332541042D054604000000036340000102165440036B40000102165440037340000102165440037B4000010216544043D7000D251354020D25115401032940012125400A2D2540644A251454014942015114332540013E2540004926010265010143CA014A051454F08FFF004454010265010243CA0101051654010000800300401654026A014002B801145408A5011F3DA50100467C010265010343CA0132A501013D8D00000044CA013DA5010044CA0103314101031940005618403B02400328401654036840165403A840165403E8401654040200403E25410447CA01332541042D054604000000439D013A00005B66FF2D0D420702030C480000018D18543200010519547A1C020001051A5410113D102D0D4204002C2500013D25000649D5015608485B7A1800000000001C0004003800080054000C00700010008C001400005C00010200040225010403314100090D410F00150D410166FF2D0D4250002D0A4241030C48000007A5905DFE010D905D111150024A0D935D0100494100022501135408905D5400925D3A00005B7A0C000000040008000C00100014005B01020104043700004221006307290063034E006302600063048400630C1201630D1B015A5A435A01010D455D9F0F66060124475D3000014C475D31000324463B003E254600445A015420475D5B0DE5475D015C05435DFFFFFFFD110003005B0DE5475D014A25445D024472000DA5435D010DA5435D025C05435DEFFFFFFD010000005B4A055300000200004494000D254B5D013D8D00000044110103054680F0FA0256004103194100210541FF0F0000270246403E05410000000044C4002D0D400100018A455D4056004103194100210240412702464001A54A5D0C010A4A5D4015054004560041032941002D0D410100210240411B054008010A485D400DE5485DC007254B5DFE4A654B5D014909015B0105435D000003005B0DE5475D014A05435D010000004441014A05435D10000000494E014A05445D010000004936015C05435DFFFFFEFF000002005B5C05435DEFFFFDFD010000005B00D00002010000010500C2000000E001053E26430000005C057E1238FFFFFF430000005C057E18F8FFFFFF030000005C057F12F8FFFFFF030000005C057F18F8FFFFFF03000000010517742D0B150003004026743E0540F900000049700001050BF000001200010525CE3021210343CF003E0540F6000000498D0001050BF000002100010525CE2301102343CF003E0540F000000049AA0001050BF000003300010525CE3120312043CF003E05400F00000049C70001050BF00000CC00010525CE2031203143CF00010525CE203120135BAF0003020C003700000301000003010101030102025216030146001B0546080202000002020101020202023D6502004936002C2202463DE502004941002CA202463D65020249480003014003090540000000FC3E0540000000D0496E00010563C000000040550000552002437200540063C0010164C00056004003214002010265C040010166C00103314002010267C0400101E8C0033D65020144A6003DE5020144A60051024AE5A0218049A6005B00B201020200003700003D250101448D003D250102448E003D2501034433003D2501004993013D050000000000495E003A00005B523C03004024013EF94000445A004AA524011044410003F9400001022401404AA52401104452005538005B5420A453523C03004024013E3940004489004AA52401084470000339400001022401404AA52401084481005538005B5B66FF2D0D429A0156004103394101152541022D0A42413D65010B49010120050064000000030C48020003004140010F254110090D41DFFF030C4800004A0501500100000044EA00030C4802003C0241014049EA003C02400141449301030C48020007254001EF0102410140010A400141439301560040038D400C003D650118442401038D403E003D65011944240103A9400133A540140331400109254003152540040F0D4001015600410329410133254114030C4800004A05015001000000447101030C4802004A254001104971013C22430141497101031A48403C0A000140449301031A484007250001FE030C4802000122430141070D4001EFFF031A4840010A0001403A00005B7A180000000000800004000001080080010C000002100080021400E700010808000301000002050005000100522920050064000000030246400202000003010000553800030540003200003D05000000000044640003024046270140003E05409C180000475300030540003200003E0540C8000000466400030540C800000066FF2D0D42C7003E0C400200477B002D0D420800436B00330C400000030C0106003E0D011900499A00270D403200210D400200439F00270C4006002D0C40040002E20040330C400400210C4006002D0C40000027024640020A004002B200405B7A2000C8004006080019004006800C40003200800C381860006400003200327F00640000CB00010100003700003D65000144610056004020250010030A484007258F4FFD4A258F4F04492000521407254650FE4A65465001492F0003214000210D40DC00030A48400725B43AFE56004003214000210D406B01030A484007258541EF43C70056004020250010030A48400D258F4F024A258F4F0444710052140D254650014A6546500144800056004003214000210D40DC00030A48400D25B43A0156004003214000210D406B01030A48400D2585411056004003214000210D405A00030A48400D254C4D013A00005B00240001010000370000030041E30D330541010000001B05410B01020600410D251F0E035BC8000201D6098002A000E0012D00100060000A0002000000000008080600123CA00F2003000158021C00280080000100040000000000000000006A3C6419000440010003260018008800030006000000000000000600553C302A00050802C003280060007000010003000000000000000000E93C302A0005980100042A0030007000010003000000000000000000EA3C8F2F7805D0011A04270058009000030004000000000000000200EB3C483F40063002B00432004000C000010003000000000000000000EC3C3400020100000000002A002A00002A2A2A00002A002A2A15002A2A2A15151515153F153F15153F3F3F15153F153F3F3F153F3F3F5C00020100000000000000000000000000000000000000000000000006000000C8320000000034210000B80B000000007D0000010000000000FFFF0000000000000000000000000000000000000000000000000000000000000000000C00020100000000800000007400010110010612110116121301066A1401166A1601065517011655190106EA1A0116EA650116E966010AE921010A1222010A6A23010A5524010AEA450116EB46010AEB750116EC76010AECD2011670D4010A70D8011671D9010A71E2011672E4010A72E8011673E9010A73F5011674F6010A74140002010200080080000002000400084000FFFFDA0001048A0E05001331580021220000B70000000800000014326B001E210000BE0000000200000013337E001E220000C5000000000200001334910020210000CC000000000400001335A40021210000D300000000080000010491000204020003040200230602000000FF010492000204030003040200230602000000FF010493000204040003040200230602000000FF010494000204050003040200230602000000FF010490000204010003040200230602000000FF14060F000000FF14060F000000FF14060F000000FF14060F000000FF14060F000000FF050001010000380004030400000024F40000102788130000000000000000C2014E0C01010000550000001027000000020501000606000000000000000000F20105030E00360046005A01A201307500000C003F053A400000409C00000C003F053E000000FFFFFF000C003F05F380000000000000FFFFFF000C003F053E00000000000000483F00003F004400001600000004011F00000004022C00000004033E00000004081B500000040925600000040A35900000041021B0000004112FF0000004182A40010004786900003F004400001600000004011F00000004022C00000004033E00000004081B500000040925600000040A35900000041021B0000004112FF0000004182A40010004F0D200003F004400001E00000004012600000004023000000004033E00000004082240000004092C600000040A37700000041027900000041132C0000004182E00010004683C01003F004400001E00000004012600000004023000000004033E00000004082240000004092C600000040A37700000041027900000041132C0000004182E0001000400000000000102030203000100070500000102030203000100070500000102030203000100070500000102030203000100070500000102030203000100070500000102030203000100070500083000009B0000000730000046250000083100009B0000000731000046250000083200009B0000000732000046250000083300009B00000007330000462500005600000005000000FFFFFFFF0000000058000205010A01000C02040264C0000065C0000066C0000067C00000E8C00000A021000042EC0000102700000C04000000000000000000000000000000000000000000000000000000000000000000000000000000000000C401020500000000000000000000000000000000245053505B4809DF160000000000000000000000400400000000030000000000010000000060000000300400000000000400000000E0000000000000000000000500000000010000000A0300000000000700000040040000400B0300000000000900000008000000E4C90000000000001100000000100100001005000000000012000000005000000020060000000000140000000030000000100300000000002100000010000000000B030000000000230000000050000000000200000000002D00000000F0000000400300000000002E0000000080000000900400000000003500000038000000ECC900000000000036000000004000000070060000000000370000000010000000B0060000000000380000004004000000050300000000003A0000000062000000C00600000000003B0000000003000000220700000000003D00000000400000002507000000000003000000006000000065070000000000420000000008000000C5070000000000010000000000000004010000000000000000000001012C0000C540736900550069000000900100007C99050000000000000000000000000000000000000000006C000201B55D000000000100B55D000008080200B55D000010100300B55D000018140400B55D00001A180500B55D00001C1C0600915D000008089000955D000008089100995D0000080892009D5D000008089300A15D000008089400A55D000008089500A95D0000080897008A060C0001E2011D0900007E3A00007D00080000001B000000000000000000007100000000000000000000000000010000000A0000006C070000F30400003E040000F3040000F30400006B030000F304000004050000040500002A0300000000000000000000000000000000000000000000000000002C010000300100003001000030010000300100006400000030010000340100002C0100002C010000000000000000000000000000000000000000000000000000800000000E0000001E00000001010101010101010100010101010000000000000000000000000000000000009808000098080000980800007E040000980800007E040000980800007E040000A203000014000000AC0D0000AC0D00006400000069000000020000000000000001000000010000000100000064000000640000006400000064000000640000006400000064000000640000006400000064000000000000000000000000000000200300002003000020030000BC02000020030000BC02000020030000BC02000071020000320000002003000020030000190000003200000000000000000000000000000000000000000000001900000023000000190000002300000019000000230000001900000023000000190000002300000000000000000000000000000008000000FBEFFFA7230600005F000000000000000000000000000000790000000000000000000000000000000F000000660000006E006900690073007300730073000000000000000000000000000000FC700000FF0100004B004B000000000000000000A50AA50AF00AF00AF8116810800000000000020000000000000000000DE04D3EFCDEA6BD7498273F000002000000803F000000000CE5243E8CDB083EE145073F010104000000803F000000000CE5243E8CDB083EE145073F010002002289923FBD35B03CF77520BE2731803F1D38E73D01000200331B643FC8EF0D3E000000004A7B033FDAACBA3E01000200BADA5A3F9CE1463E764FAE3FE86A03C03199C23F010002007BA05D3FBB0F003E3945C73D780BA43E0000C03E0200020000000000000000000000000000000000000000000200020000000000000000000000000000000000000000002C016C07E803E803E803E803E803E803E803E803E803E803E803E803E803E8033001F304E803E803E803E803E803E80330013E04B004B004B004B004B004B0043001F304E803E803E803E803E803E8036400F40171026B033001F304E803E803E803E803E803E80334010405E803E803E803E803E803E8032C010405E803E803E803E803E803E8032C012A03200320032003200320032003D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D001D0016C07F3046B033E04F304F304040504052A03D001000303033001FB01F00AF00A280A480D480D480D8813181518151815F401F401F40100000000D0010000010200005B00000800000003040451006B02000000000000000032003C0000009001900190019001900190019001900190011E00DC05800CAC0D5500DC0501000102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EC4CA13C6EC0E73C81785D3D73637A3D583934BC1361C33C000000000000000000000000000000000000000000000000000000000000000000000000000000000C010C0101010000000000000C010C0100020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000001E0046000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB00000000000000000000000000000000000000190019006F060000C5060000350700006F060000C5060000350700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C8000405000000000000000000000100000000000000000000010200000000000000000000020301000000000000000000030401000000000000000000040504000000000000000000050604000000000000000000060704000000000000000000070000E718E7180002010300000000960000002A000000160000001B000000FF0005000500FF00FFFFFF0001201F0001201F00011421000000000090010000008001000000000000000000000000000000000000000000000000000000000000000000000000006C0003030000021130750000CC55010000200000312C00004C000000200352034605BC0200000000800000000000000000000000000000000000000000000000DC05000084038403460584030000000000000000000000000000000000000000000000000000000000000000F70902044B0057003F061F072B090000000000000100080400200000FF00000000000000000000000000000033000070080472008108000000040400C00000004B345A4146333235424D0000000000FFFFFF00000000001C000000514C01005F4C01005E4C0100604C0100614C01008140010082400100834001008440010085400100864001008740010088400100894001008A4001008C4001008D4001008E400100904001009140010094400100954001009640010097400100A3400100A440010098400100A1400100A8610000000000002501000000000000BA08000040000000090905030D0005000202000208000000050303000500000011040500000001010100010100111800DB0100000A0A00001E0000001E00000043512A020F0000000C000A0A080300011F2A0C001E00000009F1130F1E0000000000000050C30000000000002D04000000000000BA080000400000000A0F0905170008000202000208000000050404000800000011040500000001010100010100121800B60300000A0A00003C0000003C000000455136021E0000000C000A0A090300011F2A0C003C000000C9F1130F3C00000000000000F82401000000000045080000000000003A090000400000000D170D0723000C00040400020C000000050505000C00000021060500000001010100010100151800910500000A0A00005A0000005A000000485146022D0000000C000A0A0C0300011F2A0C005A00000089F2130F5A00000000000000CC55010000000000550A0000000000004A090000400000000F1B0F0929000E000404000210000000050606000E000000218805000000010101000101001718007F0600000A0A0000690000006900000049515002350000000C000A0A0E0300011F2A0C00690000000AF3130F6900000000000000A0860100000000005D0C0000000000005A09000040000000101E0F092D000F0004040002100000000506060010000000210806000000010101000101001818006C0700000A0A000078000000780000004A5156023C0000000C000A0A0F0300011F2A0C00780000004AF3130F780000000000000048E80100000000007E00000000000000EA090000400200001426130D3900130006060002140000000607070014000000318A06000000010101000101001B1800470900000D0D000096000000960000004D5166024B0000000C000A0D130400011F2A0C00960000000AF4130F960000000000000040130200000000000704000000000000FA09000040030000152D170F4400170006060002180000000708080018000000310C07000000010101000101001B1800180A00000F0F0000B4000000B40000004F5178025A0000000C000A0F140500011F2A0C00B4000000CBF4130FB400000000000000785D0200000000000F04000000000000FA09000040030000162D170F4400170006060002180000000708080018000000310C07000000010101000101001C1800810B00000F0F0000B4000000B40000004F5178025A0000000C000A0F150500011F2A0C00B4000000CBF4130FB40000000000000020BF0200000000001F080000000000008A0900004003000018341B114E001A000808000220000000070909001C000000318E07000000010101000101001E18005C0D000012120000D2000000D200000052518602690000000C000A12170500011F2A0C00D20000008BF5130FD200000000000000B024030000000000280B0000000000009A090000400300001A3C1F135A001E000808000220000000080A0A001F000000311008000000010101000101001F18004A0F000014140000F0000000F000000054519802780000000C000A14190600011F2A0C00F00000004CF6130FF000000000000000143E030000000000300B000000000000AA090000400300001B412315610021000808000220000000080B0B001F00000031920800000001010100010100201800C60F000016160000FF000000FF00000056519C02800000000C000A161A0600011F2A0C00FF000000CCF6130FFF00000000000000E86E030000000000400B000000000000AA090000400300001D442515660022000A0A000224000000080C0C001F00000031920800000001010100010100221800B3100000171700000E0100000E0100005751A802870000000C000A171C0600011F2A0C000E0100000CF7130F0E01000000000000000000000A000000554C01007CFE000180FE000184FE000188FE0001A0FE0001A4FE0001091C0003C91A0003091B0003FFFFFF0000280000A8498840000004B08002000000000401C0C0C0C0C0C0C0C0C00000008000000080000000FFFFFF0100280000A8498840000004B08002000000000401C0C0C0C0C0C0C0C0D00000008000000090000000FFFFFF0200280000A8498840000004B08002000000000401C0C0C0C0C0C0C0C0D00000008000000090000000FFFFFF0300280000A8498840000004B08002000000000401C0C0C0C0C0C0C0C0C0000000800000008000000000000000400000004F4C0100504C0100514C0100524C0100534C0100544C0100564C0100574C0100584C01005E4C0100604C010000FE000104FE000108FE00010CFE000110FE000114FE000118FE00011CFE000120FE000124FE000128FE00012CFE000130FE000134FE000138FE00013CFE000140FE000144FE000148FE00014CFE000150FE000154FE000158FE000178FE00018CFE000190FE000198FE00019CFE0001A8FE0001B4FE0001B8FE0001BCFE000184FF000188FF00018CFF000190FF000194FF000198FF00019CFF0001A0FF0001A4FF0001A8FF0001ACFF0001ECFF0001F0FF0001F4FF0001F8FF0001021D0003031D00038C1C0003A10400051804000555020005FFFFFF001AA720000500000000002A000000060600040000F425E50F0000000000000000000000000000000000000000060003000000030400000305000000009C000408480448040000080000000800171000000F300000220A4C56500501000F0FDE00204004001042000000000000040000000000000038383043080810696600001B2A8C480000000000C0E03886000000000300000000142F2F22222B2B000000000000000000000000000000001C038E03AA028E03E300AA02E3007100E3007100550171001C0355011C038E03CF0030FFFF0C00F30080019000088001050000000E1000403FFF3F0F2B0000002200000010000000120000000000000016000000000000001800000024400100254001002640010024480100254801002648010024400500254005002640050024480500254805002648050024400900254009002640090024480900254809002648090024400D0025400D0026400D0024480D0025480D0026480D00FFFFFF00100000006754130220314576100000001023754664573201100000001023754664573201100000006754130220314576010000001023754664573201010000006754130220314576010000006754130220314576010000001023754664573201000000000050000303000000000010050000020100000000007D00E40C0008700010270000CC55010024F4000050C3000010270000000000006B0000008000000000000000000000000000000000000000000000006C00040205030E002106400000000000FF0005070C000E0000000000000001030E002106400000000000FF0001070C000E0002020000000004030E001006440000000000FF0004070C000E0000030000000002030E001006440000000000FF0002070C000E0000010000000014000202000000000000000000001000000000002000020114001A00000000000800000004000000000000000000000000000000F4000304010B0000D0074E0C00004E0C10270000FF000500FF000001FF00000060CC050070C600001873010070C60000B0CC0000CCF100000ED40000A4000000E8DF0500203005000000000000000000020000000000F00070110100D084000000000000333381017D1A09963014C902600060004788730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55AA5700F10E00000B0064860100000000000000000058001C000000504349520210407300001800000000035700000003800000474F5020414D44205245563A20782E782E782E782E780078787878007878787800000000B3AC0000A02301002698876FBF7D624A5B78E666660E000701444AA5B25C68A698516B03176CE2731798B82923534B48C262944841CE2952D60E02E7338E6CDB555DABBB5555B6D5BB3B54982AB002802AA88CB14D32ECEDBC1C2A5AA156A33FBFBFFCE6705A6DDEF7DB77DDEF7F6EFBE2F77EEF7C3EFDEFB3DFBDFE09FBBBB592471B6E7BB32BFF5FA115FFFFD3EE4A2B41A963F859F18AC3B48F5F1A53DF9CA2A86514B395C18535F7F8368AFDFCBF385EB8987CBF78B8A8FFFA00E4FFE2EF85C628A978D5757E8C7735C54BAFFFF703E2CFA3AA3C3DE8BE750677BF3FE237AA39E8B174FA0CF9F9F5013106DA2BEFF0E0328AC962EA94C3B18C0B0E5861D5F7FD30F51474B4D4451053116DA2BEFF2C3E43CF529B1FCFDEE3CEFEFEEB15F790FCFDF27CDFEFEEEBD053DF95F9FBA1FF1EE4D5F761E7FF6F67FF8F7EB6E94F7ACFCFD9FFE3DE8B6EAF266E152CF57DEAD5F7ADE77BB857DD2EE55C3ABEE415D3F1DCEF7B4571F0BFEBDFFE35F76AFBB6FCF6F884FC3ED5FA57E3F4A299C987C971FA249BED7C0A65D745A0BE5FD1528309F8B43C3DB2B429E2D0D15BAA4CB611684BAB74C62E8EC3F234969BB5682F8B4572D457AD4582D458AD4592F85711737168AE5A8AF5A8B05A8B15A8B25ED7791737168AE5A8AF5A8B05A8B15A8B25F75BF8B9B8B4572D457AD4582D458AD47FF79BD37BB1737168AE5A8AF5A8B05A8B15A8B25EDB7D1737168AE5A8AF5A8B05A8B15A8B25F8EDEC5CDC5A2B96A2BD6A2C16A2C56A2037AD9BBA5B3774B66EE96CDDD2D9BBA5B36E3DF8A44B54AD15CB515E550AD7B3375176390DFFE54572D457AD4582D458AD4592F76B68B60A956322A2D15CB51296A2BCABC5ACEF16B397E045B37BEF45D3E2D15CB515EB5160B5162B5164BFCA585BB8BF1956DB612D46A961BEA961BEA961BEA961BEA961BEA961BE29C95F9F214BB88B1C6F11638DE22C71BC458E3788B1C6F11638D2BFD01FFF5A3791799CA7EB1C1BF58E0DFAC706FD63837EB1C1BF58E0EF16CDDE2D9BBC5B3778B66EF16CDDE2D9BD65CC5CDC5A2B96A2BD6A2C16A2C56A3CD1965D6A374B1C6DD2C71BE82C6CBE82C6CBCC630D750E8BBFD149AFF3293D7A49361E63CF5DE4A2EB8C1FD183C0AE93A9EAAA702BDC54E7AA702C35B49ADA4C0B0A1A9A6A9C12EEAE5BAB96C12E6D2CD83CBB96772CA68FF1771C28980CFFA593EF7D8ECFCAEFB6BD2E77AFFF389C0AE47E0C9ECBE3D0E9F2360D70BDD27A27FC7E26F653638729EDAE41FD5E37C9F3FB4D95A6EDD789E927C4C5EE7BBFD9A2CA29A3F98AFB3556573EE3BF1AF3396549BDDFFE7DFCB7AF39191F6B7395F4364F627551DF66E28B4741F658712472F59EEA7C3CCFF0D7D1C5D5EC0BFECCAFC5BFA7FF17ED3FC5F95F9DFFD78353DE6E5D4F79AC32B7125FD9A2C661F70C07BB927598A0CF3A3735932BE8D9FEEE0DFDF993C6E7B2485252E80ADC48F372E36F3A4E13A292E8F996FE4FDBF07A7D363F5597ADACBCE076F9CAAD77E5D4FF957CFEAB9ECEFA72D4997F1BA8477FDDE6B9385E0FEDC96B3E1C436CAF8BF6F79C1B87BD776F7B8E90E85EEF7966798EA05C52F3EF3D4EC24F57B2EAFCBBC37F57A7E94D77F57DDEA7C1D1F631BD6F737329FA66CAF32DE92A1B95EC7D8EE168BD177FAEF3D8FD1D6CFAFF2319ED5E1D51F6D839FDB87FAF377CC63F7DA1EF2D753E347CD64FCDD53A939E8CADB5F5719E64BCEFB5CFCF7A361211BD261BCBEEA2677BCEDFDF4E9F31AFF810F566713BA95E8D84D4F6797FAD95D65D76BEF95846F45E6E33A0CE76DE206DFD6A9B7FA7825597F57DD52BEE855F6E15F730AFB9757D94AFBE360556F7D5F76CAFB84AFBF4D5F7E3ABEDEABEE9D5F742AFB9F57DB857DCCABEDA2BEE4D5F652BEF8CAB99FC257DDC2BEED95F7095F7E9ABEFC757DBD57DE895F79B57D9CAFB6CAFB9857DCBABECA57DA7F9B9C8D0AC511D4774565CAEC0A30A76144D12EF2B2654F958C2B3D14BFC95F1BCEAF35CEAF8EE757C7F3ABF56B577654E859F375FEC15DE5515C29CF05894B63FB00B1A057173EB5BD1AB55DFF4FFF90CFFFCFFFFDD3FF1D4CC01B4D0B3CA1598013DA159B0E2BC707BCC80C34A1F73E55487968183A82A90AD2053A856F748562C3A5F161C978E0F3324A3D613C8D3A00C0D3936BC693ECC93E8E1F1E54E060F181E71E5365392F4717A5DA15920E7BA02B3414680A3C37DA80F346568399D1FF961E74AA62BB90DAC42DBFC5F60E7324F78926F3A00DE7FAD11FDF88CE3C1FDC85C9855106A3481DF62008FE9DA6EE69EA29BB9A4A9A3D034348F70A9F9D68F499FA5A4D034779FD1E850CFE868E2DBB9D1E81A533C6993A4A552CB3347534751A40CE4C4D4CF4DF857C6CDF4D7F8F9EA3D052135B9DCCCEB47351514D50AE9F414744854521FDDB4EC2929A973E7D25368E2EFF4400C85876D4B46D3B0A3A8A956E67EA298FA6A2A6A58BA266B279A9FE6EA0EA767BF0AE676D4D507D180F34B51479FD0776D2A4FCF92BE5E98F5A9914BF49DCD1B4A640F8A33E5E99A7739FA7A7A4D1E856AE02D53D368EA541DCCA2A2A3A9A9686D1E8E909A08E9F93A6434717B4483834A2D1071F2B7F7FC064EC7A6A540371C9A14B4BCDAF3B4D5150853800B9840F1E370DCE990A80DAA2E5FB10E2CA3683C0B474421D9B47A4A4A2A3BF1C4407CC88D2AE3F2483C794750D3354D4CD283B9CFABB60DBE7F40D15BBA0A4EF28CAEBF4752853D3D32DC1F17BFE7F3F519FEE68CFA38BD5EEE98331CCE5FEC73F51A30E2469407E7C3AA2FC9062DBFFB6FF16FD413F279FA4A542A28F996E6D1D2D1F36E22DBF5FA3EE3474DA5D1B4CA52F774FA2123F409D1054CE331B358EC7F57D6369B33253A6B9C9E43461CB21DC350194FD03045C95F42852683F42867F32DAABA9C4CCE396F18DAA1FAB50FCBEC50DD4D1CF022D8BA3E3741D52BE31DA068D0694E0F85363CD8E4E46383E87BEFE25FC3977697C34073EBC70725EF9D37238BE444885D6C014D3BEC8E885CA040F74FA8B8C51D05961C2EDDC191C5726244748CEA6163AC258B2F7EF4963C20B1DFFD91221D0707C8E412C6E8E4997D61A244D64F8402A7B91DBFD010144F9B0B5E085A8667DC531C98639CCD5B9C96DD4C4C3963A12ACC73D871C742559697A73EDA38CE59EE370E04319976965684E4B259B391C1EA89A71AD5C0699EA88288C8E982C8E45969C7D00B48C8E70289913C1F1C45B48714FB40D66032B85E5DF1057A0504C90BD1CF66F3602646A80EF4E1707226B56801BF483A741912EF46CB3AD4E391C2FDA385470BF707A89AC3970F1C8EB019FE1FD77F98F9BE0108646FAF49B27BCA6B33E3A34176D4E8B98DA4C88BDB81D6999C8D2B5937619E97EC3B13334755DE3D2072CB6E0EF3399AE21C972CE4AECC81F5BA6FB43E54E6F7079674256099BDBB601C64EE6F13FB03167F68ED291FD2141D4DF5CCD030E83AB6BAD160DF43D0869D5EB72D37B13F12725E192EDDC1AC6A318EDD256E9D873E1C6D39B43D9BA4BE1BBFDA212EC16D97C85C247EEA6001591017F602C450075307239A6AD07A3E64064D808D696EE26B0611700585EADE0E8A3D5B0683E97696DD5E220C6B99AB0392B6893F32186392BA2F571838949D868EB6E8EE6FCD1EC22EB3D7270722350D4A47C60E6BABEED8F1E486EBC31B32EB8C9785D7FA8514F26D7175B56292AABC8339F9D7599434A179D91CE92F74C2EB8D8F00A734CD8CF37F74F2DE399BEDBA83D985B667A83986F1EF78C18D44A3C366FB662E0BD75EC2185DE59BC6265648D6F20CD06464E7D67D01957CA16F910E89C85CB38C2EBB34D5C175CEDAE493EDA6D4E3D261F14ED265F783F713C1D63D50688E25EFF13930CC95189E355C7C9ADD4C3CFE1C161CC5EA5D0F36B9980E53D080DAED2DD93959A13A130BED7BC3CBBF0BB2CDF8DDA385F4BDE1CAD9BB83E5357A4EC8CE3474977130E92F90CCEE7BB52131A5B4391CD81303897EBC4980CEBCCEC0CEC5435775316AE2C07B30E467E11C97D2E66AF5DC170D0D469D9BB469C4B3B0D743AFDDBB83D4EE3EA1EDEDD3A4B7D17B86D0E4B92ED2E169F04742958BD68DF845D6D2B21EF6D590104EEF9EE713EA18B74DEFB4DCF86B765EF2833BB26AA1ADA8319DEE2C4EF870D24CF707A35DCDE3ECC20531F98392C2FA9BF104F624D7CD2B60311603522EB3E61C9F5BDF975BC41203AFF1C23AC190819530C66F410E4E92BE4FC007770C4B769E50192FBBDA024735E385AF1492A7D2EF09D0002B9F2D086D87278AB535FE31D30DD85AE97E974DF82874C01C46FFB0711B1438A40D44EB5600EF5E90E46A599C956357E52A046E4D7FECA64E739D93B59D9718FAD6B3A0A59625277005AA291EE4A7E9758A0A90704086D10C6DFAC8B9E4FB50E15BBC03113BE7DD090CE3DE00A93892C24A5688362736A7E3F582501F297ABF5811ED3572381E9A496D0E4A316A458E9DAA0C206DE7F52913529B7D2A1E50E8BFB722BAC20647521D4A6CDFB326387905372E3F5609D2DC175C90DA27EAF431796653B60E13AA5EC2A591895A43909AB74FBD095D98988589E8F9E3B4975D606A3EC8D145F092E18DED0BAD18DC15EC0825F56389F24419721D071A9F5B8521FC5D18404CD47C9D683F1C9BA915854C5894182395F915F366365A5C0094B6C1F895DA57A6B6F664828E93B72EBB287D6BE1CF9E701B3A7B1C210B6F4CDC35FD529D69E36B0501F5D983D37DD61398CF961CA905C8D205E9DEE3C07A6639F3433E5EB9F0EB8E98720EABB522A21BF1AA3C510A66FD91C71EED365A550980868BA7949AB94D29028A8395629FC63A56452F089ABE902D12489C2588DC18DF708350D089D37D01A8938EA1E066AE47A51D933D189D2E3C9D2FC911427CD81E484B861E2AF0BEE0B0AF184469EA2847A3811E318F1270C61B00E94F4D79ED5E396FBF3F0D5E251E9E7A849C087961D6CBEA235E1A8CFB435FE6DB407C546A9C02CCBD75B269F62B7386C83AA0ED9C53B93362C8A200C40AA3628ECDB9DD25C464A15934312DC27FCC098D42A7AB8F5B56783AB257DFD4A1D3DA4A90C874F831A90C393540E7CD2606F8D6C440BA120741CD35A70271C4CD072410B6C096CFC13721701F1E3BC4E2992136ED58A62AF5F095FAF4058BFC36F46EE4627CC45E7726F08BCEE8FE82318CA31865EBA47E2F944CF2D0C2E7B74FE46E02A1ADB1F850883C8519C950508308CD02A27E5E2C9CA6ED2BAD34D859E806CFA5C62D660B9465ADB912A2CB330DABFCD4DAB53F3ABB51C44FEDD17AE6567BC13D8E09859B6AFD96B888B4B5392CEB5AA16158CCF19DA99DA0A7EFB4B3E6B0BE7227B597227F413F2D26B813C95DBA4B8C725C576970CE9BC2E87782B4EE090BB723950A800227870E323A6E999975BB521617D484D0F4FEED3E191239EF3A4B708F963C8C9D81110BBB4F41A48B709D7864AEFC62775700335A4AACB246FC41A26A8525284BA9A40F6A29A123E5891043CA9D07C013A081BD6DE590E7A58E9B5C7CADF591D5762268F39E30DAD47143BCCE6FB73FA005FD9FC8B8E8F54A210D4A63A43FECBBA7512CDDB7E0D43F540FC28EBD1D7EC2F1C952833AA91ED67CE128BCE8B44FB4684E3AB3538DC5646D0E7DDE34016BE0392E51EE1EEBD324C119706A35A3B4B51C2179BA6ADCC83D72E2319D54725960401B2BBB811DB282BC0F4AF057816EAA881F627ECDD957FEDEE46F47D1E2A53F6EE078E89DF5E77149DF495E730996D196DC99953607F7FB063F9BB00303D077628DECB66CEADB73E38315DA062A24F80D2CA809B0EDC6A3EC4D1A9A6E74197101DB3DFEE4560CD5FCC0D4101133B9BF5264799AB2B80084B503CE537A8AC258FA24EE780418D265C50D6CD47D4AC202060346998660147950C5B3757056BBB1BBD54C92AF8040EA0E7A601B37EAE1907BCF4316E7295ACC3B0E8968A7013B47D79953D0E3CC82E4D022C703A0C4B635FF4C744B174DF6BA5FA434F982313DB93E5047FDD907F0CACC11A8DF2C4978C81F61ADBD7124A2F5394126E9DEE8C9CDA975BB7230D3DC499759B151B83E88813C7CF035691447F778B1447768F712E18D38FE94313F66E87211EEE093A569B8BCCEBB005B4CC431871ADBB8D31ECC515FD01153CCAC3743AF4EC98660E83DC0353F239353BEF3DC5547F1E9068B68C5EAF50A1024C08BC3DBDDF6E9517BB806787141EA60D47B92A1F6A0271FD908947D010229A2EBA74F9B2193902EC9FE017585DFFDC2E951CC5693308103AA1057AB8BEB43AAECC4E41C4E571391B515F7C2D0F6744D3A95AE6C4D6284888F21A828D41812EE8A5CE1695D19F93FC1A899ABD7497267A0EB47A6DCC07B244239E538F6D71B03E53672D349D39A978043E2D710FFDD41CB9E5D72E32B6C4F6065F6D1540D9CFB8AB904DD25C13607CE1942F52D45D1B0023441DBCE02C2B3EC12019BA9932EB6908417400E75EE9C3FA9A74F2D6E2CC7CD0B324180984317AF097BEAB17A5DA8A3F017E75E510ABAE0E896EE1FE34E8964737DD0137A33A043541305D7658F0735D39FC58EB552D118CADB043041CD5C0DC29D644378A2981EF7B6DC2BDEEABD3523984C9DEDA21F42E941E3DE829F29ABD388A1ED3B3B49DA75C015F757FD1E7CA386D53DD1F1E3D2BD3B05143C0024D938A9030978DC36DECC40083A51EE8F7BF98A0B6D22BF06AA950EADB0EEE426AF62EC30E301AB3381C0A6FC12F57EC109C184F259821805A81843323578A3DDD7DB713BA9D97177FFF9898C0A5F4032D3E9C34D5E4D36A439ECFD38F3B9FA510F079C1428943F410169BA938FC68697EC6DC427C1CD7F32146004CB047F9840030E990E6150286B7D1077B05CD39F1AE207CE8D70DC197DB554ABCD9C50FDB509FDE2BD1AE22035EFDCB8BD491EAC9BAE1412975BD9079489A9985EBBE12103C4DBA3AA14691D45BD3A0CAF883C089B5058C3C7D66BC5FA6475439AB42979C92945C2E60AD27963F22F788E6D7B881C135B7EC22B5E8E7A0F6A7B96D45F79E703C40C150FF20AA2F0C4A77C72F5DBD44DF0589939F09F828A8E883839202214FAEF6C4C0E83E156D93302BDF5981CA3AFC0E52A3CB06AEA6157D67449E86D0741CC0254B402857225F1DA40FC4329BDB0F683B17F2A47DBFE44289E093D11332A74103F53A600788BBEFF620CE3DB89066A9B28157ABFCA2907866F4F1C6A3FB09C9F02F0504D422821AA71036A282EA7FC18B9BF5459ED64D45C224CBC5B7241DE7704C993928D0D77A9FE5CC4590368410145BF274D81219ECEB6467665FCEE993851F155C81B6B61649D45767357BF5EFC922B52F7C129EFABC5BE9290709EB8999E4813C5562C1B3D7CA3811E128E04658F4FBCC51455658203B7A7998FE6BD68756C413F67DAC51DE26C913370C0E94104E35E74399A74609876FC420846222812F6ED945CEAC5DF1C25DB693BDD150D8DA4EE9977E0BAB3607903DC0E71B726A56EEE0EA08937ACE01E625BCABFE220256DC9ED00AE4EA80F16312DDF708B07DE254C4AC6C5366D4B3271C54C362E5B9D547E04CBEB2755760246AE6737B516B356166E92B01806EE66AE5CC0DB1ADBC12157E39DC1ABB621875738C756D91F1CE916665A38C62E87809E464DCBF9FC6197D62AE906CE22427EDEFD43A3B8A08B01D87B2C143CCB6D6A24F1C3392CAB39E0299042BFD2EE0E49A0708D57C9122092A290249D8A410509E0C41115F9855166BE75A11548802F7B260436FC89FC472F430D89C8E4E846D1DC1FD2A33363099A6AE41999267FE217E542F879D21140E173983DD81D75B5A6A459D75C625EF45C4FB218935B7EF901394C04D585DF9EAE64E471FD429BE97595A47E0756D7D3536916B46DA26B1E9190AF2896A30413584832B3B8635FEC54A6C2764AD353F0851606A3FBF9240EB53C6212E80768E927C0433A6AC1E2358D7C10B57F58D7C20F5067E301D83F59AFEA143AF4F402F86F944D38D47B5D12722117D2BE385995B84E8C27CB27A6C4866753B61820C2C6B22487D585F238408F29BEA7C20F47F76009B3878E0E7337E515095B3C7DCACCA1CFBC3018579274C2D5D30F78BAE66F1BC71F7810C5BA73E583CCC1F38EA098BDE24CC70C859CF25B99E0C76242280F7E1D713C96D473112C071487D61AD5205A8C45AED01D5574FACE4E7A6F1486A947A0EFBAEFC9E83DA84003475326476836A29C9DD279160B72CEE93CD11E78DA9FDB9B37FBE10BDB99F2F5FE90D0E8AA648E83FA468FB1189E5C0E2EBC6698A7E575C286CDC990823450748DC17AEDE043F53732C4F98366FD6F149A160CBAEAC251BEB178622176F7951951BF033278E513724C4DACD9C991ADF72A17CEECD4766480D076107ABF7E7722EBA0B77DC3393A5FB860D204185DD042404EC82A876D8A3B4197B9843A8F71661301C8C4FDCD9909005A9DB63A26EE2B575F7A8C254D5C83D58F48FABA8C2999AD5C9FDD891AFD84982C4C5CCBFDD7A46099394C028CD6E27FD514375D2138BD466D3D78C1E0361AF5C4C26E93C03353932983930900A5E2A359FDA40D4C78C03181E2C713D7EB9227AFD3224F5A9900F503C58D1F3FA59C68ED5B39727AFD72C1E9F845DB35FE69ACC1AFC1BB64FB9EC8901EACCBAEF7BF84627EF015B27F4B92480FF1ACC91D7A7FE20E290838C28FFB317FF4D47F5C9914E4457725234D6641842FFC4B32661E0D816EF7204268C8F5CA68BCFFC42A685323837366AC8210CB06237C120D31A3864B2E0860F0DAF982435D963D4E1AE946D5DCDFAC4B543009F9A30AFC13A4116AC638C9317D7B650E68BAE3B46730B67496D4D6DD31F1A744B035B750CD0E406D6B97013FBB01FA1C817B303B95C310BE25819009B25E01E61A8F4C280B145409EC7F9287B1E4A87B169A914332EB4AC25FAE21F3F903BD64B3007A2A5AC4B63AC7852A082951A82C982C7197B3620FB0D0FDA0414B480E056F4F82D1D47FFC2430849F3748E719BA07075D2352ABBA757782BC3B4505F6066C457820EF1C165B6F8E244B435AE1D8078C42E15EA4C181C9354008E81AB4788923F332F694C2E3580E01B4228196D0AD926037E1265997A0A5FCE92FCE84113586FF324BF9F0BFF0D4BFA06237F9B0A3DB0EDF44C83C540D1A98C845331E2734182482C900C739834AD79638ED11AFE95ACD0828D86FE9C2FE8FE3130BE38DED501DAFAA744162E1976A3B2D635174B9887B7C3CB2E917D3EA5ECF85ECD5BBC0E682264917D4F1098E183FAC42567BD0C1E40306E1FA89721F7E113133BAC0FBE605F753F19257CEB42962C94BD5A1884B1B00B1980B132D275FC8078F1E443C7A7241E216082FAE0285B4A98FFB8BA0E95E127392A3AEFEF235275DC9782A57E788C9F7EB1E5804393C47BDFB93D8CB129A2C13DD6045B5EDA9F186C03A421B03606E5C0238D2DA3C6F6A7E0EFAC411740450C5E246B1681A6209C3C99A166E810D2C2DE01BB8C3BF9DFB43D621FCE84A5437700E096581C339378DF7C7F3F3CC2C32A91BB4983B1562F119474C372F12950500EF90E3BC47A62F5D96FB4BD74EF2CD7FDC6B1F70CB896D693BE0B0B1E1B306164087A8BF547DB6B585583346B9EA396F0C4129CB13F08B01F02B18F9846A5F6A87CB0F0809891DDCE6009D7F0FDD159427DFFA841801BD6B64FA5C10263F523C22AB766F12270C56FCE4977FE53568BB9B23A2A66464767320DBF3A061AAF3182FD01E644DD84B4A4AF9CA2129E77E7F6AF12ECD7C2FBA20B789F6B318D3BC186C1E30BA3A0D4310571707493867B8C4929DBA408FCE310A9F5E921F49F3A080E3CD4686423F94188F8EA2509A2845EF0CE8E674BB8474E56B577F57C41A5FB5CD8DB087F1FE1300C426702C590C26D12DFC78253FAC1986F8E04134D7CC06398E5CF0313D5A7D2E585633C00E7ACEB5C60A5B26A0F5F18389991BFC6862665826BF2C44BF675AE39E1ADC1A3DD24704A7B6B32084887200ACDB3B1E160814AFC605FEF62D3A918AB2EC081BA639BFC47B53606AB8241E2DB5EBC8C606D8E24BEF06671A3C5E3357F332FCC17026D7679494D728EAFE6E256DCA0C8177D0E65ECE77E84A3DEF17443F8C34A3094B08F6717929303E34BAEC92F3985C43E18B36204F62D40926FD8373FE6C56E7C260191B53085B009A36559B25216C3EF3C8DD98F2DE72FE5778C06B6849A9E32BA20B800B79535C01961019A75B25146FEF8C91855472DC2052718BD58C3164B280D2078048D4D075449B188AB2020209602F94516E3335B36B4CD0A1167EA4E2E8692B39E736757AC9989BF2C74119B7F667977A4D557029166F3D307B0145F370D68B343DFD5A6CC0630452430A0EDF0E554810D0B5C402358B6B8A6A5A49880C4341F006DDFB18F3A2599CDC971525930D0F84315A3D7E6C19DD11C0FAD0BAE249842B288EA65DD2340050957783A5C2BA1818E972ABF59BEEA3400DC5550948676169CD51335DAC28E7612CF7B27AA56EF9E04E09D30D1D18C4FFD8091971832BA21B7A59E833B09D41CB5C4D5C811FE6F43D757CB815050FA41E33FDA0A802E05401FC83C683E50F147F607879EF878D0A21E29FF6878EE8545151B5150F5E0783F001E10B90F1A4C8078D2E5812A89FED0F1779B0F1C5DA87887781E2F3001E3E6B90F1F3E403C7D19657BB2B6C0B7F1C45A4D628DD425D8B38ADE5033A83DB954301FC55827741C039F7A049E4C099652797BEF924CE5161C2AF37D66691658354E5884E7D42131DABCB26C59A18CDEEC7AE238BAD7C528FCB509D379566806D8A6B0EDBD9A1DC1CFB624024993701C9FFE5AF1DEBC0F6859A8C0050166C626B2840400847ED8822C254455016484162024144E5859581A2415B08D60CC5EDF63AD5D0D7E36C052B2A39599C9304AA82577E450F4DF5E4C42288DC4F00E4B78F1162D45B312ABC57B23DE2BE12E0BD2222BA11AEC613D231CEEDAC90D68C84BD8295A5C6B33230624C6E186BC7426017C0D720D49084C5829AA49ACC0260613256CE56138294A32C44321B04E623579F7339667F5008E9C099036E2DDE1B372B587E02FAC5EF2B0151F405804F78AC5E8C718DF6E8337302CC166C8F3E73EB262E9F5DAE42C80C2A63FAC0732EBB9535735FD671C20B77D39619B2A9E724061C743EADE56F7ACCF98856C13531E56CEB33F0A2DB0756133B3D362831F4D99F225D750334B6DC8DE275F9623FA69F4720A4FDA6F688592879910D56688B10539161AE76F91043BDD55FC83344DE04CE2669E748AF9BA9AB7878E795B9E667E284F1DF61839E3A01D0764A682C6A3057AE18AF1DD3B15374372CA498BF59581821BA7B9CC820630106EC497144AFA80753AA07544D0015F1E43980556F00FE881638BCF95525AF5905E58A719E9AE3D83EF93EF78959C3C00648F8FBF4C05FA5FC0C8E9C" diff --git a/resources/amfi_detect.py b/opencore_legacy_patcher/detections/amfi_detect.py similarity index 96% rename from resources/amfi_detect.py rename to opencore_legacy_patcher/detections/amfi_detect.py index d57d593fb..0b2122287 100644 --- a/resources/amfi_detect.py +++ b/opencore_legacy_patcher/detections/amfi_detect.py @@ -1,9 +1,11 @@ -# Determine AppleMobileFileIntegrity's OS configuration -# Copyright (C) 2022-2023, Mykola Grymalyuk +""" +amfi_detect.py: Determine AppleMobileFileIntegrity's OS configuration +""" import enum -from resources import utilities -from data import amfi_data + +from ..support import utilities +from ..datasets import amfi_data class AmfiConfigDetectLevel(enum.IntEnum): diff --git a/resources/device_probe.py b/opencore_legacy_patcher/detections/device_probe.py similarity index 99% rename from resources/device_probe.py rename to opencore_legacy_patcher/detections/device_probe.py index d045d3bd9..b17f1b36a 100644 --- a/resources/device_probe.py +++ b/opencore_legacy_patcher/detections/device_probe.py @@ -1,18 +1,25 @@ -# Hardware probing -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +device_probe.py: Hardware probing +""" -import binascii import enum import itertools import subprocess import plistlib import hashlib + from pathlib import Path from dataclasses import dataclass, field from typing import Any, ClassVar, Optional, Type, Union -from resources import utilities, ioreg -from data import pci_data, usb_data +from . import ioreg + +from ..support import utilities + +from ..datasets import ( + pci_data, + usb_data +) def class_code_to_bytes(class_code: int) -> bytes: diff --git a/resources/ioreg.py b/opencore_legacy_patcher/detections/ioreg.py similarity index 99% rename from resources/ioreg.py rename to opencore_legacy_patcher/detections/ioreg.py index fbdc42093..a149533a7 100644 --- a/resources/ioreg.py +++ b/opencore_legacy_patcher/detections/ioreg.py @@ -1,5 +1,6 @@ -# PyObjc Handling for IOKit -# Copyright (C) 2020-2022, Dhinak G +""" +ioreg.py: PyObjc Handling for IOKit +""" from typing import NewType, Union import objc diff --git a/resources/os_probe.py b/opencore_legacy_patcher/detections/os_probe.py similarity index 98% rename from resources/os_probe.py rename to opencore_legacy_patcher/detections/os_probe.py index c2cf30b77..5cd753037 100644 --- a/resources/os_probe.py +++ b/opencore_legacy_patcher/detections/os_probe.py @@ -1,8 +1,10 @@ -# Probe for OS data +""" +os_probe.py: OS Host information +""" import platform -import subprocess import plistlib +import subprocess class OSProbe: diff --git a/resources/build/bluetooth.py b/opencore_legacy_patcher/efi_builder/bluetooth.py similarity index 94% rename from resources/build/bluetooth.py rename to opencore_legacy_patcher/efi_builder/bluetooth.py index e0dc5a9ee..41c92a360 100644 --- a/resources/build/bluetooth.py +++ b/opencore_legacy_patcher/efi_builder/bluetooth.py @@ -1,12 +1,20 @@ -# Class for handling Bluetooth Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +bluetooth.py: Class for handling Bluetooth Patches, invocation from build.py +""" import logging import binascii -from resources import constants, device_probe -from resources.build import support -from data import smbios_data, bluetooth_data +from . import support + +from .. import constants + +from ..detections import device_probe + +from ..datasets import ( + smbios_data, + bluetooth_data +) class BuildBluetooth: diff --git a/resources/build/build.py b/opencore_legacy_patcher/efi_builder/build.py similarity index 94% rename from resources/build/build.py rename to opencore_legacy_patcher/efi_builder/build.py index df8011a2a..568b3bcea 100644 --- a/resources/build/build.py +++ b/opencore_legacy_patcher/efi_builder/build.py @@ -1,19 +1,35 @@ -# Class for generating OpenCore Configurations tailored for Macs -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +build.py: Class for generating OpenCore Configurations tailored for Macs +""" import copy import pickle -import plistlib import shutil -import zipfile import logging +import zipfile +import plistlib from pathlib import Path from datetime import date -from resources import constants, utilities -from resources.build import bluetooth, firmware, graphics_audio, support, storage, smbios, security, misc -from resources.build.networking import wired, wireless +from .. import constants + +from ..support import utilities + +from .networking import ( + wired, + wireless +) +from . import ( + bluetooth, + firmware, + graphics_audio, + support, + storage, + smbios, + security, + misc +) def rmtree_handler(func, path, exc_info) -> None: diff --git a/resources/build/firmware.py b/opencore_legacy_patcher/efi_builder/firmware.py similarity index 98% rename from resources/build/firmware.py rename to opencore_legacy_patcher/efi_builder/firmware.py index 866ec2c10..e6efee743 100644 --- a/resources/build/firmware.py +++ b/opencore_legacy_patcher/efi_builder/firmware.py @@ -1,5 +1,6 @@ -# Class for handling CPU and Firmware Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +firmware.py: Class for handling CPU and Firmware Patches, invocation from build.py +""" import shutil import logging @@ -7,9 +8,18 @@ import binascii from pathlib import Path -from resources import constants, generate_smbios, device_probe -from resources.build import support -from data import smbios_data, cpu_data, os_data +from . import support + +from .. import constants + +from ..support import generate_smbios +from ..detections import device_probe + +from ..datasets import ( + smbios_data, + cpu_data, + os_data +) class BuildFirmware: diff --git a/resources/build/graphics_audio.py b/opencore_legacy_patcher/efi_builder/graphics_audio.py similarity index 99% rename from resources/build/graphics_audio.py rename to opencore_legacy_patcher/efi_builder/graphics_audio.py index 756f0deaf..dce88af68 100644 --- a/resources/build/graphics_audio.py +++ b/opencore_legacy_patcher/efi_builder/graphics_audio.py @@ -1,5 +1,6 @@ -# Class for handling Graphics and Audio Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +graphics_audio.py: Class for handling Graphics and Audio Patches, invocation from build.py +""" import shutil import logging @@ -7,9 +8,20 @@ import binascii from pathlib import Path -from resources import constants, device_probe, utilities -from resources.build import support -from data import smbios_data, model_array, os_data, cpu_data, video_bios_data +from . import support + +from .. import constants + +from ..support import utilities +from ..detections import device_probe + +from ..datasets import ( + smbios_data, + model_array, + os_data, + cpu_data, + video_bios_data +) class BuildGraphicsAudio: diff --git a/resources/build/misc.py b/opencore_legacy_patcher/efi_builder/misc.py similarity index 98% rename from resources/build/misc.py rename to opencore_legacy_patcher/efi_builder/misc.py index 8c2cd2974..2334fff49 100644 --- a/resources/build/misc.py +++ b/opencore_legacy_patcher/efi_builder/misc.py @@ -1,5 +1,6 @@ -# Class for handling Misc Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +misc.py: Class for handling Misc Patches, invocation from build.py +""" import shutil import logging @@ -7,15 +8,24 @@ import binascii from pathlib import Path -from resources import constants, device_probe, generate_smbios, utilities -from resources.build import support -from data import model_array, smbios_data, cpu_data +from . import support + +from .. import constants + +from ..support import generate_smbios +from ..detections import device_probe + +from ..datasets import ( + model_array, + smbios_data, + cpu_data +) class BuildMiscellaneous: """ Build Library for Miscellaneous Hardware and Software Support - +xw Invoke from build.py """ diff --git a/resources/build/networking/wired.py b/opencore_legacy_patcher/efi_builder/networking/wired.py similarity index 96% rename from resources/build/networking/wired.py rename to opencore_legacy_patcher/efi_builder/networking/wired.py index 9b31fec6e..b0360db0b 100644 --- a/resources/build/networking/wired.py +++ b/opencore_legacy_patcher/efi_builder/networking/wired.py @@ -1,9 +1,17 @@ -# Class for handling Wired Networking Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +wired.py: Class for handling Wired Networking Patches, invocation from build.py +""" -from resources import constants, device_probe -from resources.build import support -from data import smbios_data, cpu_data +from .. import support + +from ... import constants + +from ...detections import device_probe + +from ...datasets import ( + smbios_data, + cpu_data +) class BuildWiredNetworking: diff --git a/resources/build/networking/wireless.py b/opencore_legacy_patcher/efi_builder/networking/wireless.py similarity index 98% rename from resources/build/networking/wireless.py rename to opencore_legacy_patcher/efi_builder/networking/wireless.py index 0ef2af82e..c52313b55 100644 --- a/resources/build/networking/wireless.py +++ b/opencore_legacy_patcher/efi_builder/networking/wireless.py @@ -1,11 +1,17 @@ -# Class for handling Wireless Networking Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +wireless.py: Class for handling Wireless Networking Patches, invocation from build.py +""" import logging -from resources import constants, device_probe, utilities -from resources.build import support -from data import smbios_data +from .. import support + +from ... import constants + +from ...datasets import smbios_data +from ...support import utilities +from ...detections import device_probe + class BuildWirelessNetworking: diff --git a/resources/build/security.py b/opencore_legacy_patcher/efi_builder/security.py similarity index 95% rename from resources/build/security.py rename to opencore_legacy_patcher/efi_builder/security.py index 6783c1e82..6eb1819d5 100644 --- a/resources/build/security.py +++ b/opencore_legacy_patcher/efi_builder/security.py @@ -1,11 +1,16 @@ -# Class for handling macOS Security Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +security.py: Class for handling macOS Security Patches, invocation from build.py +""" import logging import binascii -from resources import constants, utilities, device_probe -from resources.build import support +from . import support + +from .. import constants + +from ..support import utilities +from ..detections import device_probe class BuildSecurity: diff --git a/resources/build/smbios.py b/opencore_legacy_patcher/efi_builder/smbios.py similarity index 98% rename from resources/build/smbios.py rename to opencore_legacy_patcher/efi_builder/smbios.py index ce527505d..e692e0b9b 100644 --- a/resources/build/smbios.py +++ b/opencore_legacy_patcher/efi_builder/smbios.py @@ -1,5 +1,6 @@ -# Class for handling SMBIOS Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +smbios.py: Class for handling SMBIOS Patches, invocation from build.py +""" import ast import uuid @@ -10,9 +11,19 @@ import subprocess from pathlib import Path -from resources import constants, utilities, generate_smbios -from resources.build import support -from data import smbios_data, cpu_data, model_array +from . import support + +from .. import constants + +from ..support import ( + utilities, + generate_smbios +) +from ..datasets import ( + smbios_data, + cpu_data, + model_array +) class BuildSMBIOS: diff --git a/resources/build/storage.py b/opencore_legacy_patcher/efi_builder/storage.py similarity index 97% rename from resources/build/storage.py rename to opencore_legacy_patcher/efi_builder/storage.py index 62d61f5a1..e7b10410f 100644 --- a/resources/build/storage.py +++ b/opencore_legacy_patcher/efi_builder/storage.py @@ -1,11 +1,21 @@ -# Class for handling Storage Controller Patches, invocation from build.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +storage.py: Class for handling Storage Controller Patches, invocation from build.py +""" import logging -from resources import constants, device_probe, utilities -from resources.build import support -from data import model_array, smbios_data, cpu_data +from . import support + +from .. import constants + +from ..support import utilities +from ..detections import device_probe + +from ..datasets import ( + model_array, + smbios_data, + cpu_data +) class BuildStorage: diff --git a/resources/build/support.py b/opencore_legacy_patcher/efi_builder/support.py similarity index 98% rename from resources/build/support.py rename to opencore_legacy_patcher/efi_builder/support.py index 8b2449088..732ee7636 100644 --- a/resources/build/support.py +++ b/opencore_legacy_patcher/efi_builder/support.py @@ -1,5 +1,6 @@ -# Utility class for build functions -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +support.py: Utility class for build functions +""" import shutil import typing @@ -10,7 +11,7 @@ import subprocess from pathlib import Path -from resources import constants, utilities +from .. import constants class BuildSupport: diff --git a/resources/analytics_handler.py b/opencore_legacy_patcher/support/analytics_handler.py similarity index 97% rename from resources/analytics_handler.py rename to opencore_legacy_patcher/support/analytics_handler.py index fbdac3e2f..93813365d 100644 --- a/resources/analytics_handler.py +++ b/opencore_legacy_patcher/support/analytics_handler.py @@ -1,9 +1,19 @@ +""" +analytics_handler.py: Analytics and Crash Reporting Handler +""" + +import json import datetime import plistlib -from pathlib import Path -import json -from resources import network_handler, constants, global_settings +from pathlib import Path + +from .. import constants + +from . import ( + network_handler, + global_settings +) DATE_FORMAT: str = "%Y-%m-%d %H-%M-%S" diff --git a/resources/arguments.py b/opencore_legacy_patcher/support/arguments.py similarity index 96% rename from resources/arguments.py rename to opencore_legacy_patcher/support/arguments.py index e22888296..e95cb729e 100644 --- a/resources/arguments.py +++ b/opencore_legacy_patcher/support/arguments.py @@ -1,3 +1,7 @@ +""" +arguments.py: CLI argument handling +""" + import sys import time import logging @@ -7,11 +11,25 @@ import subprocess from pathlib import Path -from data import model_array, os_data -from resources.build import build -from resources.sys_patch import sys_patch, sys_patch_auto -from resources import defaults, utilities, validation, constants -from resources.wx_gui import gui_entry +from .. import constants + +from ..wx_gui import gui_entry +from ..efi_builder import build + +from ..datasets import ( + model_array, + os_data +) +from ..sys_patch import ( + sys_patch, + sys_patch_auto +) +from . import ( + utilities, + defaults, + validation +) + # Generic building args diff --git a/resources/bplist.py b/opencore_legacy_patcher/support/bplist.py similarity index 100% rename from resources/bplist.py rename to opencore_legacy_patcher/support/bplist.py diff --git a/resources/commit_info.py b/opencore_legacy_patcher/support/commit_info.py similarity index 95% rename from resources/commit_info.py rename to opencore_legacy_patcher/support/commit_info.py index af64465fe..0f7b21892 100644 --- a/resources/commit_info.py +++ b/opencore_legacy_patcher/support/commit_info.py @@ -1,7 +1,11 @@ -# Parse Commit Info from binary's info.plist +""" +commit_info.py: Parse Commit Info from binary's info.plist +""" + +import plistlib from pathlib import Path -import plistlib + class ParseCommitInfo: diff --git a/resources/defaults.py b/opencore_legacy_patcher/support/defaults.py similarity index 96% rename from resources/defaults.py rename to opencore_legacy_patcher/support/defaults.py index abbcbaf55..19d34b960 100644 --- a/resources/defaults.py +++ b/opencore_legacy_patcher/support/defaults.py @@ -1,14 +1,19 @@ -# Generate Default Data +""" +defaults.py: Generate default data for host/target +""" + import subprocess -from resources import ( +from .. import constants + +from ..detections import device_probe + +from . import ( utilities, - device_probe, generate_smbios, - global_settings, - constants + global_settings ) -from data import ( +from ..datasets import ( smbios_data, cpu_data, os_data @@ -25,16 +30,16 @@ class GenerateDefaults: self.host_is_target: bool = host_is_target # Reset Variables - self.constants.sip_status: bool = True - self.constants.secure_status: bool = False - self.constants.disable_cs_lv: bool = False - self.constants.disable_amfi: bool = False - self.constants.fu_status: bool = True + self.constants.sip_status = True + self.constants.secure_status = False + self.constants.disable_cs_lv = False + self.constants.disable_amfi = False + self.constants.fu_status = True - self.constants.fu_arguments: str = None + self.constants.fu_arguments = None - self.constants.custom_serial_number: str = "" - self.constants.custom_board_serial_number: str = "" + self.constants.custom_serial_number = "" + self.constants.custom_board_serial_number = "" if self.host_is_target is True: for gpu in self.constants.computer.gpus: diff --git a/resources/generate_smbios.py b/opencore_legacy_patcher/support/generate_smbios.py similarity index 97% rename from resources/generate_smbios.py rename to opencore_legacy_patcher/support/generate_smbios.py index ad541b9cf..a4100aaeb 100644 --- a/resources/generate_smbios.py +++ b/opencore_legacy_patcher/support/generate_smbios.py @@ -1,8 +1,18 @@ -from data import smbios_data, os_data, cpu_data -from resources import utilities +""" +generate_smbios.py: SMBIOS generation for OpenCore Legacy Patcher +""" import logging +from . import utilities + +from ..datasets import ( + smbios_data, + os_data, + cpu_data +) + + def set_smbios_model_spoof(model): try: smbios_data.smbios_dictionary[model]["Screen Size"] diff --git a/resources/global_settings.py b/opencore_legacy_patcher/support/global_settings.py similarity index 94% rename from resources/global_settings.py rename to opencore_legacy_patcher/support/global_settings.py index 7ce87d7d1..d69c2c488 100644 --- a/resources/global_settings.py +++ b/opencore_legacy_patcher/support/global_settings.py @@ -1,13 +1,18 @@ -# Alternative to Apple's 'defaults' tool -# Store data in '/Users/Shared' -# This is to ensure compatibility when running without a user -# ie. during automated patching +""" +global_settings.py: Library for querying and writing global enviroment settings + +Alternative to Apple's 'defaults' tool +Store data in '/Users/Shared' +This is to ensure compatibility when running without a user +ie. during automated patching +""" + +import os +import logging +import plistlib +import subprocess from pathlib import Path -import plistlib -import logging -import os -import subprocess class GlobalEnviromentSettings: diff --git a/resources/install.py b/opencore_legacy_patcher/support/install.py similarity index 98% rename from resources/install.py rename to opencore_legacy_patcher/support/install.py index 68daa7640..9bb45c3f8 100644 --- a/resources/install.py +++ b/opencore_legacy_patcher/support/install.py @@ -1,6 +1,6 @@ -# Installation of OpenCore files to ESP -# Usage solely for TUI -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +install.py: Installation of OpenCore files to ESP +""" import logging import plistlib @@ -9,8 +9,11 @@ import applescript from pathlib import Path -from resources import utilities, constants -from data import os_data +from . import utilities + +from .. import constants + +from ..datasets import os_data class tui_disk_installation: diff --git a/resources/integrity_verification.py b/opencore_legacy_patcher/support/integrity_verification.py similarity index 94% rename from resources/integrity_verification.py rename to opencore_legacy_patcher/support/integrity_verification.py index b249d02d0..69db79ca9 100644 --- a/resources/integrity_verification.py +++ b/opencore_legacy_patcher/support/integrity_verification.py @@ -1,7 +1,9 @@ -# Validate the integrity of Apple downloaded files via .chunklist and .integrityDataV1 files -# Based off of chunklist.py: -# - https://gist.github.com/dhinakg/cbe30edf31ddc153fd0b0c0570c9b041 -# Copyright (C) 2021-2023, Dhinak G, Mykola Grymalyuk +""" +integrity_verification.py: Validate the integrity of Apple downloaded files via .chunklist and .integrityDataV1 files + +Based off of chunklist.py: +- https://gist.github.com/dhinakg/cbe30edf31ddc153fd0b0c0570c9b041 +""" import enum import hashlib diff --git a/resources/kdk_handler.py b/opencore_legacy_patcher/support/kdk_handler.py similarity index 98% rename from resources/kdk_handler.py rename to opencore_legacy_patcher/support/kdk_handler.py index 0306a5e47..d99897b47 100644 --- a/resources/kdk_handler.py +++ b/opencore_legacy_patcher/support/kdk_handler.py @@ -1,22 +1,26 @@ -# Module for parsing and determining best Kernel Debug Kit for host OS -# Copyright (C) 2022-2023, Dhinak G, Mykola Grymalyuk +""" +kdk_handler.py: Module for parsing and determining best Kernel Debug Kit for host OS +""" -import datetime -from pathlib import Path -from typing import cast -import tempfile -import plistlib - -import packaging.version -import requests - -import subprocess import os - import logging +import plistlib +import requests +import tempfile +import subprocess +import packaging.version -from resources import utilities, network_handler, constants -from data import os_data +from typing import cast +from pathlib import Path + +from .. import constants + +from ..datasets import os_data + +from . import ( + utilities, + network_handler +) KDK_INSTALL_PATH: str = "/Library/Developer/KDKs" KDK_INFO_PLIST: str = "KDKInfo.plist" @@ -89,7 +93,7 @@ class KernelDebugKitObject: self._get_latest_kdk() - def _get_remote_kdks(self) -> list or None: + def _get_remote_kdks(self) -> list: """ Fetches a list of available KDKs from the KdkSupportPkg API Additionally caches the list for future use, avoiding extra API calls @@ -247,7 +251,7 @@ class KernelDebugKitObject: self.success = True - def retrieve_download(self, override_path: str = "") -> network_handler.DownloadObject or None: + def retrieve_download(self, override_path: str = "") -> network_handler.DownloadObject: """ Returns a DownloadObject for the KDK @@ -381,7 +385,7 @@ class KernelDebugKitObject: return True - def _local_kdk_installed(self, match: str = None, check_version: bool = False) -> str or None: + def _local_kdk_installed(self, match: str = None, check_version: bool = False) -> str: """ Checks if KDK matching build is installed If so, validates it has not been corrupted diff --git a/resources/logging_handler.py b/opencore_legacy_patcher/support/logging_handler.py similarity index 98% rename from resources/logging_handler.py rename to opencore_legacy_patcher/support/logging_handler.py index e368fb79d..65ad16131 100644 --- a/resources/logging_handler.py +++ b/opencore_legacy_patcher/support/logging_handler.py @@ -1,3 +1,7 @@ +""" +logging_handler.py: Initialize logging framework for program +""" + import os import sys import pprint @@ -10,7 +14,12 @@ import applescript from pathlib import Path from datetime import datetime -from resources import constants, analytics_handler, global_settings +from .. import constants + +from . import ( + analytics_handler, + global_settings +) class InitializeLoggingSupport: diff --git a/resources/macos_installer_handler.py b/opencore_legacy_patcher/support/macos_installer_handler.py similarity index 99% rename from resources/macos_installer_handler.py rename to opencore_legacy_patcher/support/macos_installer_handler.py index 8d0984912..e1459d0c6 100644 --- a/resources/macos_installer_handler.py +++ b/opencore_legacy_patcher/support/macos_installer_handler.py @@ -1,15 +1,22 @@ -# Handler for macOS installers, both local and remote +""" +macos_installer_handler.py: Handler for macOS installers, both local and remote +""" -from pathlib import Path -import plistlib -import subprocess -import tempfile import enum import logging +import plistlib +import tempfile +import subprocess import applescript -from data import os_data -from resources import network_handler, utilities +from pathlib import Path + +from ..datasets import os_data + +from . import ( + network_handler, + utilities +) APPLICATION_SEARCH_PATH: str = "/Applications" diff --git a/resources/network_handler.py b/opencore_legacy_patcher/support/network_handler.py similarity index 97% rename from resources/network_handler.py rename to opencore_legacy_patcher/support/network_handler.py index a6029ce9d..522f40b07 100644 --- a/resources/network_handler.py +++ b/opencore_legacy_patcher/support/network_handler.py @@ -1,7 +1,9 @@ -# Library dedicated to Network Handling tasks including downloading files -# Primarily based around the DownloadObject class, which provides a simple -# object for libraries to query download progress and status -# Copyright (C) 2023, Mykola Grymalyuk +""" +network_handler.py: Library dedicated to Network Handling tasks including downloading files + +Primarily based around the DownloadObject class, which provides a simple +object for libraries to query download progress and status +""" import time import requests @@ -10,9 +12,11 @@ import logging import enum import hashlib import atexit + +from typing import Union from pathlib import Path -from resources import utilities +from . import utilities SESSION = requests.Session() @@ -218,7 +222,7 @@ class DownloadObject: self._download(display_progress) - def download_simple(self, verify_checksum: bool = False) -> str or bool: + def download_simple(self, verify_checksum: bool = False) -> Union[str, bool]: """ Alternative to download(), mimics utilities.py's old download_file() function diff --git a/resources/reroute_payloads.py b/opencore_legacy_patcher/support/reroute_payloads.py similarity index 95% rename from resources/reroute_payloads.py rename to opencore_legacy_patcher/support/reroute_payloads.py index e974e7e76..263352906 100644 --- a/resources/reroute_payloads.py +++ b/opencore_legacy_patcher/support/reroute_payloads.py @@ -1,15 +1,19 @@ -# Reroute binaries to tmp directory, and mount a disk image of the payloads -# Implements a shadowfile to avoid direct writes to the dmg -# Copyright (C) 2022, Mykola Grymalyuk +""" +reroute_payloads.py: Reroute binaries to tmp directory, and mount a disk image of the payloads +Implements a shadowfile to avoid direct writes to the dmg +""" -import plistlib -from pathlib import Path -import subprocess -import tempfile import atexit +import plistlib +import tempfile +import subprocess + import logging -from resources import constants +from pathlib import Path + +from .. import constants + class RoutePayloadDiskImage: diff --git a/resources/updates.py b/opencore_legacy_patcher/support/updates.py similarity index 94% rename from resources/updates.py rename to opencore_legacy_patcher/support/updates.py index 9b12df530..4e5e220e5 100644 --- a/resources/updates.py +++ b/opencore_legacy_patcher/support/updates.py @@ -1,13 +1,19 @@ -# Copyright (C) 2022, Mykola Grymalyuk -# Check whether new updates are available for OpenCore Legacy Patcher binary -# Call check_binary_updates() to determine if any updates are available -# Returns dict with Link and Version of the latest binary update if available -import logging -from typing import Optional, Union +""" +updates.py: Check for OpenCore Legacy Patcher binary updates +Call check_binary_updates() to determine if any updates are available +Returns dict with Link and Version of the latest binary update if available +""" + +import logging + +from typing import Optional, Union from packaging import version -from resources import constants, network_handler +from . import network_handler + +from .. import constants + REPO_LATEST_RELEASE_URL: str = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest" diff --git a/resources/utilities.py b/opencore_legacy_patcher/support/utilities.py similarity index 98% rename from resources/utilities.py rename to opencore_legacy_patcher/support/utilities.py index b44244814..addf1493e 100644 --- a/resources/utilities.py +++ b/opencore_legacy_patcher/support/utilities.py @@ -1,20 +1,29 @@ -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +utilities.py: Utility functions for OpenCore Legacy Patcher +""" -import argparse -import atexit -import binascii -import logging -import math import os -import plistlib import re +import math +import atexit import shutil +import logging +import argparse +import binascii +import plistlib import subprocess -from pathlib import Path import py_sip_xnu -from data import os_data, sip_data -from resources import constants, ioreg +from pathlib import Path + +from .. import constants + +from ..detections import ioreg + +from ..datasets import ( + os_data, + sip_data +) def hexswap(input_hex: str): @@ -553,7 +562,7 @@ def elevated(*args, **kwargs) -> subprocess.CompletedProcess: return subprocess.run(["/usr/bin/sudo"] + [args[0][0]] + args[0][1:], **kwargs) -def fetch_staged_update(variant: str = "Update") -> (str, str): +def fetch_staged_update(variant: str = "Update") -> tuple[str, str]: """ Check for staged macOS update Supported variants: diff --git a/resources/validation.py b/opencore_legacy_patcher/support/validation.py similarity index 97% rename from resources/validation.py rename to opencore_legacy_patcher/support/validation.py index 4385a29dd..d4fb8ef44 100644 --- a/resources/validation.py +++ b/opencore_legacy_patcher/support/validation.py @@ -1,11 +1,25 @@ +""" +validation.py: Validation class for the patcher +""" + import logging import subprocess + from pathlib import Path -from resources.sys_patch import sys_patch_helpers -from resources.build import build -from resources import constants, network_handler -from data import example_data, model_array, sys_patch_dict, os_data +from . import network_handler + +from .. import constants + +from ..sys_patch import sys_patch_helpers +from ..efi_builder import build + +from ..datasets import ( + example_data, + model_array, + sys_patch_dict, + os_data +) class PatcherValidation: diff --git a/resources/sys_patch/sys_patch.py b/opencore_legacy_patcher/sys_patch/sys_patch.py similarity index 95% rename from resources/sys_patch/sys_patch.py rename to opencore_legacy_patcher/sys_patch/sys_patch.py index d91e86799..f701c28be 100644 --- a/resources/sys_patch/sys_patch.py +++ b/opencore_legacy_patcher/sys_patch/sys_patch.py @@ -1,36 +1,39 @@ -# Framework for mounting and patching macOS root volume -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +sys_patch.py: Framework for mounting and patching macOS root volume +""" -# System based off of Apple's Kernel Debug Kit (KDK) -# - https://developer.apple.com/download/all/ +""" +System based off of Apple's Kernel Debug Kit (KDK) +- https://developer.apple.com/download/all/ -# The system relies on mounting the APFS volume as a live read/write volume -# We perform our required edits, then create a new snapshot for the system boot +The system relies on mounting the APFS volume as a live read/write volume +We perform our required edits, then create a new snapshot for the system boot -# The manual process is as follows: -# 1. Find the Root Volume -# 'diskutil info / | grep "Device Node:"' -# 2. Convert Snapshot Device Node to Root Volume Device Node -# /dev/disk3s1s1 -> /dev/disk3s1 (strip last 's1') -# 3. Mount the APFS volume as a read/write volume -# 'sudo mount -o nobrowse -t apfs /dev/disk5s5 /System/Volumes/Update/mnt1' -# 4. Perform edits to the system (ie. create new KernelCollection) -# 'sudo kmutil install --volume-root /System/Volumes/Update/mnt1/ --update-all' -# 5. Create a new snapshot for the system boot -# 'sudo bless --folder /System/Volumes/Update/mnt1/System/Library/CoreServices --bootefi --create-snapshot' +The manual process is as follows: + 1. Find the Root Volume + 'diskutil info / | grep "Device Node:"' + 2. Convert Snapshot Device Node to Root Volume Device Node + /dev/disk3s1s1 -> /dev/disk3s1 (strip last 's1') + 3. Mount the APFS volume as a read/write volume + 'sudo mount -o nobrowse -t apfs /dev/disk5s5 /System/Volumes/Update/mnt1' + 4. Perform edits to the system (ie. create new KernelCollection) + 'sudo kmutil install --volume-root /System/Volumes/Update/mnt1/ --update-all' + 5. Create a new snapshot for the system boot + 'sudo bless --folder /System/Volumes/Update/mnt1/System/Library/CoreServices --bootefi --create-snapshot' -# Additionally Apple's APFS snapshot system supports system rollbacks: -# 'sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot' -# Note: root volume rollbacks are unstable in Big Sur due to quickly discarding the original snapshot -# - Generally within 2~ boots, the original snapshot is discarded -# - Monterey always preserves the original snapshot allowing for reliable rollbacks +Additionally Apple's APFS snapshot system supports system rollbacks: + 'sudo bless --mount /System/Volumes/Update/mnt1 --bootefi --last-sealed-snapshot' +Note: root volume rollbacks are unstable in Big Sur due to quickly discarding the original snapshot +- Generally within 2~ boots, the original snapshot is discarded +- Monterey always preserves the original snapshot allowing for reliable rollbacks -# Alternative to mounting via 'mount', Apple's update system uses 'mount_apfs' directly -# '/sbin/mount_apfs -R /dev/disk5s5 /System/Volumes/Update/mnt1' +Alternative to mounting via 'mount', Apple's update system uses 'mount_apfs' directly + '/sbin/mount_apfs -R /dev/disk5s5 /System/Volumes/Update/mnt1' -# With macOS Ventura, you will also need to install the KDK onto root if you plan to use kmutil -# This is because Apple removed on-disk binaries (ref: https://github.com/dortania/OpenCore-Legacy-Patcher/issues/998) -# 'sudo ditto /Library/Developer/KDKs//System /System/Volumes/Update/mnt1/System' +With macOS Ventura, you will also need to install the KDK onto root if you plan to use kmutil +This is because Apple removed on-disk binaries (ref: https://github.com/dortania/OpenCore-Legacy-Patcher/issues/998) + 'sudo ditto /Library/Developer/KDKs//System /System/Volumes/Update/mnt1/System' +""" import logging import plistlib @@ -40,10 +43,20 @@ import applescript from pathlib import Path from datetime import datetime -from resources import constants, utilities, kdk_handler -from resources.sys_patch import sys_patch_detect, sys_patch_auto, sys_patch_helpers, sys_patch_generate +from .. import constants -from data import os_data +from ..datasets import os_data + +from ..support import ( + utilities, + kdk_handler +) +from . import ( + sys_patch_detect, + sys_patch_auto, + sys_patch_helpers, + sys_patch_generate +) class PatchSysVolume: diff --git a/resources/sys_patch/sys_patch_auto.py b/opencore_legacy_patcher/sys_patch/sys_patch_auto.py similarity index 98% rename from resources/sys_patch/sys_patch_auto.py rename to opencore_legacy_patcher/sys_patch/sys_patch_auto.py index a4367696c..dd703e7c5 100644 --- a/resources/sys_patch/sys_patch_auto.py +++ b/opencore_legacy_patcher/sys_patch/sys_patch_auto.py @@ -1,23 +1,36 @@ -# Copyright (C) 2022, Mykola Grymalyuk -# Copyright (c) 2023 Jazzzny +""" +sys_patch_auto.py: Library of functions for launch services, including automatic patching +""" import wx import wx.html2 -import requests -import markdown2 + +import hashlib import logging import plistlib +import requests +import markdown2 import subprocess import webbrowser -import hashlib from pathlib import Path +from . import sys_patch_detect -from resources import utilities, updates, global_settings, network_handler, constants -from resources.sys_patch import sys_patch_detect -from resources.wx_gui import gui_entry, gui_support -from data import css_data +from .. import constants + +from ..datasets import css_data + +from ..wx_gui import ( + gui_entry, + gui_support +) +from ..support import ( + utilities, + updates, + global_settings, + network_handler +) class AutomaticSysPatch: diff --git a/resources/sys_patch/sys_patch_detect.py b/opencore_legacy_patcher/sys_patch/sys_patch_detect.py similarity index 98% rename from resources/sys_patch/sys_patch_detect.py rename to opencore_legacy_patcher/sys_patch/sys_patch_detect.py index 5e05d03df..abdbe4325 100644 --- a/resources/sys_patch/sys_patch_detect.py +++ b/opencore_legacy_patcher/sys_patch/sys_patch_detect.py @@ -1,18 +1,32 @@ -# Hardware Detection Logic for Root Patching -# Returns a dictionary of patches with boolean values -# Used when supplying data to sys_patch.py -# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk +""" +sys_patch_detect.py: Hardware Detection Logic for Root Patching +""" import logging import plistlib +import py_sip_xnu +import packaging.version + from pathlib import Path -import packaging.version -import py_sip_xnu +from .. import constants -from data import cpu_data, model_array, os_data, sip_data, smbios_data -from resources import (amfi_detect, constants, device_probe, kdk_handler, - network_handler, utilities) +from ..detections import ( + amfi_detect, + device_probe +) +from ..support import ( + kdk_handler, + network_handler, + utilities +) +from ..datasets import ( + cpu_data, + model_array, + os_data, + sip_data, + smbios_data +) class DetectRootPatch: diff --git a/resources/sys_patch/sys_patch_generate.py b/opencore_legacy_patcher/sys_patch/sys_patch_generate.py similarity index 98% rename from resources/sys_patch/sys_patch_generate.py rename to opencore_legacy_patcher/sys_patch/sys_patch_generate.py index ea8010771..77ecb3a4c 100644 --- a/resources/sys_patch/sys_patch_generate.py +++ b/opencore_legacy_patcher/sys_patch/sys_patch_generate.py @@ -1,8 +1,15 @@ -# Generate patch set for use in sys_patch.py +""" +sys_patch_generate.py: Class for generating patch sets for the current host +""" + import logging -from resources import constants, utilities, device_probe -from data import sys_patch_dict +from .. import constants + +from ..datasets import sys_patch_dict +from ..support import utilities +from ..detections import device_probe + class GenerateRootPatchSets: """ diff --git a/resources/sys_patch/sys_patch_helpers.py b/opencore_legacy_patcher/sys_patch/sys_patch_helpers.py similarity index 98% rename from resources/sys_patch/sys_patch_helpers.py rename to opencore_legacy_patcher/sys_patch/sys_patch_helpers.py index eeccbe912..047f0b0d4 100644 --- a/resources/sys_patch/sys_patch_helpers.py +++ b/opencore_legacy_patcher/sys_patch/sys_patch_helpers.py @@ -1,17 +1,25 @@ -# Additional support functions for sys_patch.py -# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk +""" +sys_patch_helpers.py: Additional support functions for sys_patch.py +""" -import plistlib import os import logging +import plistlib import subprocess from typing import Union from pathlib import Path from datetime import datetime -from data import os_data -from resources import bplist, constants, generate_smbios, utilities +from .. import constants + +from ..datasets import os_data + +from ..support import ( + bplist, + generate_smbios, + utilities +) class SysPatchHelpers: diff --git a/resources/wx_gui/gui_about.py b/opencore_legacy_patcher/wx_gui/gui_about.py similarity index 95% rename from resources/wx_gui/gui_about.py rename to opencore_legacy_patcher/wx_gui/gui_about.py index 107427f15..0b0be744e 100644 --- a/resources/wx_gui/gui_about.py +++ b/opencore_legacy_patcher/wx_gui/gui_about.py @@ -1,12 +1,14 @@ -# About frame, just to sat +""" +gui_about.py: About frame +""" import wx import wx.adv import logging -from resources.wx_gui import gui_support +from .. import constants -from resources import constants +from ..wx_gui import gui_support class AboutFrame(wx.Frame): diff --git a/resources/wx_gui/gui_build.py b/opencore_legacy_patcher/wx_gui/gui_build.py similarity index 97% rename from resources/wx_gui/gui_build.py rename to opencore_legacy_patcher/wx_gui/gui_build.py index fd5525ce5..a6caaf3fb 100644 --- a/resources/wx_gui/gui_build.py +++ b/opencore_legacy_patcher/wx_gui/gui_build.py @@ -1,12 +1,17 @@ -# Generate UI for Building OpenCore +""" +gui_build.py: Generate UI for Building OpenCore +""" + import wx import logging import threading import traceback -from resources import constants -from resources.build import build -from resources.wx_gui import ( +from .. import constants + +from ..efi_builder import build + +from ..wx_gui import ( gui_main_menu, gui_install_oc, gui_support diff --git a/resources/wx_gui/gui_cache_os_update.py b/opencore_legacy_patcher/wx_gui/gui_cache_os_update.py similarity index 97% rename from resources/wx_gui/gui_cache_os_update.py rename to opencore_legacy_patcher/wx_gui/gui_cache_os_update.py index 83888adc0..1f3f0e39d 100644 --- a/resources/wx_gui/gui_cache_os_update.py +++ b/opencore_legacy_patcher/wx_gui/gui_cache_os_update.py @@ -1,5 +1,5 @@ """ -UI to display to users before a macOS update is applied +gui_cache_os_update.py: UI to display to users before a macOS update is applied Primarily for caching updates required for incoming OS (ex. KDKs) """ @@ -11,8 +11,9 @@ import threading from pathlib import Path -from resources import constants, kdk_handler, utilities -from resources.wx_gui import gui_support, gui_download +from .. import constants +from ..support import kdk_handler, utilities +from ..wx_gui import gui_support, gui_download class OSUpdateFrame(wx.Frame): diff --git a/resources/wx_gui/gui_download.py b/opencore_legacy_patcher/wx_gui/gui_download.py similarity index 96% rename from resources/wx_gui/gui_download.py rename to opencore_legacy_patcher/wx_gui/gui_download.py index fb5a45656..aca36e9aa 100644 --- a/resources/wx_gui/gui_download.py +++ b/opencore_legacy_patcher/wx_gui/gui_download.py @@ -1,16 +1,19 @@ -# Generate UI for downloading files +""" +gui_download.py: Generate UI for downloading files +""" + import wx import logging -from resources import ( - constants, +from .. import constants + +from ..wx_gui import gui_support + +from ..support import ( network_handler, utilities ) -from resources.wx_gui import gui_support - - class DownloadFrame(wx.Frame): """ @@ -67,7 +70,7 @@ class DownloadFrame(wx.Frame): self.download_obj.download() while self.download_obj.is_active(): - + percentage: int = round(self.download_obj.get_percent()) if percentage == 0: percentage = 1 diff --git a/resources/wx_gui/gui_entry.py b/opencore_legacy_patcher/wx_gui/gui_entry.py similarity index 94% rename from resources/wx_gui/gui_entry.py rename to opencore_legacy_patcher/wx_gui/gui_entry.py index 3c6e648db..d5de49bd8 100644 --- a/resources/wx_gui/gui_entry.py +++ b/opencore_legacy_patcher/wx_gui/gui_entry.py @@ -1,11 +1,17 @@ -# Entry point for the wxPython GUI +""" +gui_entry.py: Entry point for the wxPython GUI +""" + import wx import sys import atexit import logging -from resources import constants -from resources.wx_gui import ( +from .. import constants + +from ..sys_patch import sys_patch_detect + +from ..wx_gui import ( gui_cache_os_update, gui_main_menu, gui_build, @@ -13,7 +19,6 @@ from resources.wx_gui import ( gui_sys_patch_start, gui_update, ) -from resources.sys_patch import sys_patch_detect class SupportedEntryPoints: diff --git a/resources/wx_gui/gui_help.py b/opencore_legacy_patcher/wx_gui/gui_help.py similarity index 96% rename from resources/wx_gui/gui_help.py rename to opencore_legacy_patcher/wx_gui/gui_help.py index 5907ebfb7..177aeb38e 100644 --- a/resources/wx_gui/gui_help.py +++ b/opencore_legacy_patcher/wx_gui/gui_help.py @@ -1,11 +1,14 @@ -# Generate UI for help menu +""" +gui_help.py: GUI Help Menu +""" + import wx import logging import webbrowser -from resources import constants +from .. import constants -from resources.wx_gui import gui_support +from ..wx_gui import gui_support class HelpFrame(wx.Frame): diff --git a/resources/wx_gui/gui_install_oc.py b/opencore_legacy_patcher/wx_gui/gui_install_oc.py similarity index 98% rename from resources/wx_gui/gui_install_oc.py rename to opencore_legacy_patcher/wx_gui/gui_install_oc.py index 58182d653..af4fa413c 100644 --- a/resources/wx_gui/gui_install_oc.py +++ b/opencore_legacy_patcher/wx_gui/gui_install_oc.py @@ -1,11 +1,22 @@ +""" +gui_install_oc.py: Frame for installing OpenCore to disk +""" + import wx -import threading import logging +import threading import traceback -from resources.wx_gui import gui_main_menu, gui_support, gui_sys_patch_display -from resources import constants, install -from data import os_data +from .. import constants + +from ..datasets import os_data +from ..support import install + +from ..wx_gui import ( + gui_main_menu, + gui_support, + gui_sys_patch_display +) class InstallOCFrame(wx.Frame): diff --git a/resources/wx_gui/gui_macos_installer_download.py b/opencore_legacy_patcher/wx_gui/gui_macos_installer_download.py similarity index 98% rename from resources/wx_gui/gui_macos_installer_download.py rename to opencore_legacy_patcher/wx_gui/gui_macos_installer_download.py index 81e30aa45..152b6a34c 100644 --- a/resources/wx_gui/gui_macos_installer_download.py +++ b/opencore_legacy_patcher/wx_gui/gui_macos_installer_download.py @@ -1,25 +1,34 @@ +""" +gui_macos_installer_download.py: macOS Installer Download Frame +""" + import wx +import locale import logging import threading import webbrowser -import locale from pathlib import Path -from resources.wx_gui import ( +from .. import constants + +from ..datasets import ( + os_data, + smbios_data, + cpu_data +) +from ..wx_gui import ( gui_main_menu, gui_support, gui_download, gui_macos_installer_flash ) -from resources import ( - constants, +from ..support import ( macos_installer_handler, utilities, network_handler, integrity_verification ) -from data import os_data, smbios_data, cpu_data class macOSInstallerDownloadFrame(wx.Frame): @@ -51,7 +60,7 @@ class macOSInstallerDownloadFrame(wx.Frame): Convert icon to bitmap """ return wx.Bitmap(wx.Bitmap(icon, wx.BITMAP_TYPE_ICON).ConvertToImage().Rescale(size[0], size[1], wx.IMAGE_QUALITY_HIGH)) - + def _macos_version_to_icon(self, version: int) -> int: """ Convert macOS version to icon @@ -143,20 +152,20 @@ class macOSInstallerDownloadFrame(wx.Frame): """ Display available installers in frame """ - + bundles = [wx.BitmapBundle.FromBitmaps(icon) for icon in self.icons] - + self.frame_modal.Destroy() self.frame_modal = wx.Dialog(self, title="Select macOS Installer", size=(460, 500)) # Title: Select macOS Installer title_label = wx.StaticText(self.frame_modal, label="Select macOS Installer", pos=(-1,-1)) title_label.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD)) - + # macOS Installers list id = wx.NewIdRef() - + self.list = wx.ListCtrl(self.frame_modal, id, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_NO_HEADER | wx.BORDER_SUNKEN) self.list.SetSmallImages(bundles) @@ -226,7 +235,7 @@ class macOSInstallerDownloadFrame(wx.Frame): checkboxsizer = wx.BoxSizer(wx.HORIZONTAL) checkboxsizer.Add(self.showolderversions_checkbox, 0, wx.ALIGN_CENTRE | wx.RIGHT, 5) - + sizer = wx.BoxSizer(wx.VERTICAL) sizer.AddSpacer(10) sizer.Add(title_label, 0, wx.ALIGN_CENTRE | wx.ALL, 0) @@ -253,15 +262,15 @@ class macOSInstallerDownloadFrame(wx.Frame): wx.MessageDialog(self.frame_modal, "Download link copied to clipboard", "", wx.OK | wx.ICON_INFORMATION).ShowModal() - + def on_select_list(self, event): if self.list.GetSelectedItemCount() > 0: self.select_button.Enable() - self.copy_button.Enable() + self.copy_button.Enable() else: self.select_button.Disable() self.copy_button.Disable() - + def on_download_installer(self, installers: dict) -> None: """ Download macOS installer @@ -322,7 +331,7 @@ class macOSInstallerDownloadFrame(wx.Frame): self._validate_installer(list(installers.values())[selected_item]['integrity']) - + def _validate_installer(self, chunklist_link: str) -> None: """ Validate macOS installer diff --git a/resources/wx_gui/gui_macos_installer_flash.py b/opencore_legacy_patcher/wx_gui/gui_macos_installer_flash.py similarity index 99% rename from resources/wx_gui/gui_macos_installer_flash.py rename to opencore_legacy_patcher/wx_gui/gui_macos_installer_flash.py index a0c78c864..689ad7828 100644 --- a/resources/wx_gui/gui_macos_installer_flash.py +++ b/opencore_legacy_patcher/wx_gui/gui_macos_installer_flash.py @@ -1,3 +1,7 @@ +""" +gui_macos_installer_flash.py: macOS Installer Flash Frame +""" + import wx import time import logging @@ -8,15 +12,21 @@ import subprocess from pathlib import Path -from resources.wx_gui import gui_main_menu, gui_build, gui_support -from resources import ( - constants, +from .. import constants + +from ..datasets import os_data + +from ..wx_gui import ( + gui_main_menu, + gui_build, + gui_support +) +from ..support import ( macos_installer_handler, utilities, network_handler, kdk_handler, ) -from data import os_data class macOSInstallerFlashFrame(wx.Frame): diff --git a/resources/wx_gui/gui_main_menu.py b/opencore_legacy_patcher/wx_gui/gui_main_menu.py similarity index 98% rename from resources/wx_gui/gui_main_menu.py rename to opencore_legacy_patcher/wx_gui/gui_main_menu.py index c38f10c93..5f609d5dc 100644 --- a/resources/wx_gui/gui_main_menu.py +++ b/opencore_legacy_patcher/wx_gui/gui_main_menu.py @@ -1,19 +1,31 @@ -# Generate GUI for main menu -# Portions of this file Copyright (c) 2023 Jazzzny +""" +gui_main_menu.py: Generate GUI for main menu +""" import wx import wx.html2 -import markdown2 -import requests + import sys import logging +import requests +import markdown2 import threading import webbrowser import subprocess from pathlib import Path -from resources.wx_gui import ( +from .. import constants + +from ..support import ( + global_settings, + updates +) +from ..datasets import ( + os_data, + css_data +) +from ..wx_gui import ( gui_build, gui_macos_installer_download, gui_support, @@ -22,12 +34,6 @@ from resources.wx_gui import ( gui_sys_patch_display, gui_update, ) -from resources import ( - constants, - global_settings, - updates -) -from data import os_data, css_data class MainFrame(wx.Frame): diff --git a/resources/wx_gui/gui_settings.py b/opencore_legacy_patcher/wx_gui/gui_settings.py similarity index 99% rename from resources/wx_gui/gui_settings.py rename to opencore_legacy_patcher/wx_gui/gui_settings.py index 1316dcff2..8b86a0ac8 100644 --- a/resources/wx_gui/gui_settings.py +++ b/opencore_legacy_patcher/wx_gui/gui_settings.py @@ -1,26 +1,32 @@ +""" +gui_settings.py: Settings Frame for the GUI +""" + +import os import wx import wx.adv import pprint import logging import py_sip_xnu import subprocess -import os from pathlib import Path -from resources.sys_patch.sys_patch import PatchSysVolume -from resources.wx_gui import ( +from .. import constants + +from ..sys_patch import sys_patch + +from ..wx_gui import ( gui_support, gui_update ) -from resources import ( - constants, +from ..support import ( global_settings, defaults, generate_smbios, network_handler ) -from data import ( +from ..datasets import ( model_array, sip_data, smbios_data, @@ -1322,7 +1328,7 @@ Hardware Information: wx.MessageDialog(self.parent, "Please relaunch as Root to mount the Root Volume", "Error", wx.OK | wx.ICON_ERROR).ShowModal() else: #Don't need to pass model as we're bypassing all logic - if PatchSysVolume("",self.constants)._mount_root_vol() == True: + if sys_patch.PatchSysVolume("",self.constants)._mount_root_vol() == True: wx.MessageDialog(self.parent, "Root Volume Mounted, remember to fix permissions before saving the Root Volume", "Success", wx.OK | wx.ICON_INFORMATION).ShowModal() else: wx.MessageDialog(self.parent, "Root Volume Mount Failed, check terminal output", "Error", wx.OK | wx.ICON_ERROR).ShowModal() @@ -1332,7 +1338,7 @@ Hardware Information: wx.MessageDialog(self.parent, "Please relaunch as Root to save changes", "Error", wx.OK | wx.ICON_ERROR).ShowModal() else: #Don't need to pass model as we're bypassing all logic - if PatchSysVolume("",self.constants)._rebuild_root_volume() == True: + if sys_patch.PatchSysVolume("",self.constants)._rebuild_root_volume() == True: wx.MessageDialog(self.parent, "Root Volume saved, please reboot to apply changes", "Success", wx.OK | wx.ICON_INFORMATION).ShowModal() else: wx.MessageDialog(self.parent, "Root Volume update Failed, check terminal output", "Error", wx.OK | wx.ICON_ERROR).ShowModal() \ No newline at end of file diff --git a/resources/wx_gui/gui_support.py b/opencore_legacy_patcher/wx_gui/gui_support.py similarity index 98% rename from resources/wx_gui/gui_support.py rename to opencore_legacy_patcher/wx_gui/gui_support.py index 70942e915..6fc3cbf75 100644 --- a/resources/wx_gui/gui_support.py +++ b/opencore_legacy_patcher/wx_gui/gui_support.py @@ -1,21 +1,30 @@ -import datetime -import logging -import os -import plistlib -import random -import subprocess -import sys -import threading -import time -from pathlib import Path +""" +gui_support.py: Utilities for interacting with wxPython GUI +""" +import os +import wx +import sys +import time +import logging +import plistlib +import threading +import subprocess import applescript import packaging.version -import wx -from data import model_array, os_data, smbios_data -from resources import constants, device_probe -from resources.wx_gui import gui_about +from pathlib import Path + +from .. import constants + +from ..wx_gui import gui_about +from ..detections import device_probe + +from ..datasets import ( + model_array, + os_data, + smbios_data +) def get_font_face(): diff --git a/resources/wx_gui/gui_sys_patch_display.py b/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py similarity index 98% rename from resources/wx_gui/gui_sys_patch_display.py rename to opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py index 78b57eeae..898d04645 100644 --- a/resources/wx_gui/gui_sys_patch_display.py +++ b/opencore_legacy_patcher/wx_gui/gui_sys_patch_display.py @@ -1,19 +1,20 @@ +""" +gui_sys_patch_display.py: Display root patching menu +""" -import wx import os +import wx import logging import plistlib import threading from pathlib import Path -from resources import ( - constants, -) -from resources.sys_patch import ( - sys_patch_detect -) -from resources.wx_gui import ( +from .. import constants + +from ..sys_patch import sys_patch_detect + +from ..wx_gui import ( gui_main_menu, gui_support, gui_sys_patch_start, diff --git a/resources/wx_gui/gui_sys_patch_start.py b/opencore_legacy_patcher/wx_gui/gui_sys_patch_start.py similarity index 98% rename from resources/wx_gui/gui_sys_patch_start.py rename to opencore_legacy_patcher/wx_gui/gui_sys_patch_start.py index 20efae159..5a28496ed 100644 --- a/resources/wx_gui/gui_sys_patch_start.py +++ b/opencore_legacy_patcher/wx_gui/gui_sys_patch_start.py @@ -1,3 +1,6 @@ +""" +gui_sys_patch_start.py: Root Patching Frame +""" import wx import sys @@ -10,20 +13,21 @@ import subprocess from pathlib import Path -from resources import ( - constants, - kdk_handler, -) -from resources.sys_patch import ( +from .. import constants + +from ..datasets import os_data +from ..support import kdk_handler + +from ..sys_patch import ( sys_patch, sys_patch_detect ) -from resources.wx_gui import ( +from ..wx_gui import ( gui_main_menu, gui_support, gui_download, ) -from data import os_data + class SysPatchStartFrame(wx.Frame): diff --git a/resources/wx_gui/gui_update.py b/opencore_legacy_patcher/wx_gui/gui_update.py similarity index 98% rename from resources/wx_gui/gui_update.py rename to opencore_legacy_patcher/wx_gui/gui_update.py index 7c76e35af..81db2eab5 100644 --- a/resources/wx_gui/gui_update.py +++ b/opencore_legacy_patcher/wx_gui/gui_update.py @@ -1,4 +1,7 @@ -# Generate UI for updating the patcher +""" +gui_update.py: Generate UI for updating the patcher +""" + import wx import sys import time @@ -9,9 +12,13 @@ import subprocess from pathlib import Path -from resources.wx_gui import gui_download, gui_support -from resources import ( - constants, +from .. import constants + +from ..wx_gui import ( + gui_download, + gui_support +) +from ..support import ( network_handler, updates ) diff --git a/payloads/OC-Patcher.icns b/payloads/Icon/AppIcons/OC-Patcher.icns similarity index 100% rename from payloads/OC-Patcher.icns rename to payloads/Icon/AppIcons/OC-Patcher.icns diff --git a/payloads/Icon/External/.VolumeIcon.icns b/payloads/Icon/DriveIcons/External/.VolumeIcon.icns similarity index 100% rename from payloads/Icon/External/.VolumeIcon.icns rename to payloads/Icon/DriveIcons/External/.VolumeIcon.icns diff --git a/payloads/Icon/Internal/.VolumeIcon.icns b/payloads/Icon/DriveIcons/Internal/.VolumeIcon.icns similarity index 100% rename from payloads/Icon/Internal/.VolumeIcon.icns rename to payloads/Icon/DriveIcons/Internal/.VolumeIcon.icns diff --git a/payloads/Icon/SD-Card/.VolumeIcon.icns b/payloads/Icon/DriveIcons/SD-Card/.VolumeIcon.icns similarity index 100% rename from payloads/Icon/SD-Card/.VolumeIcon.icns rename to payloads/Icon/DriveIcons/SD-Card/.VolumeIcon.icns diff --git a/payloads/Icon/SSD/.VolumeIcon.icns b/payloads/Icon/DriveIcons/SSD/.VolumeIcon.icns similarity index 100% rename from payloads/Icon/SSD/.VolumeIcon.icns rename to payloads/Icon/DriveIcons/SSD/.VolumeIcon.icns diff --git a/payloads/OC-Patcher-TUI.icns b/payloads/OC-Patcher-TUI.icns deleted file mode 100644 index 9d0607431..000000000 Binary files a/payloads/OC-Patcher-TUI.icns and /dev/null differ diff --git a/payloads/launcher.sh b/payloads/launcher.sh deleted file mode 100755 index 57152644b..000000000 --- a/payloads/launcher.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -cd "$(dirname "$0")" - -chmod +x OpenCore-Patcher -open OpenCore-Patcher \ No newline at end of file