getprop("ro.product.device") == "joyeuse" || abort("E3004: This package is for \"joyeuse\" devices; this is a \"" + getprop("ro.product.device") + "\".");
ui_print("Source: Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.1.0.QJZIDXM:user/release-keys");
ui_print("Target: Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.2.0.QJZIDXM:user/release-keys");
ui_print("Verifying current system...");
getprop("ro.build.fingerprint") == "Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.1.0.QJZIDXM:user/release-keys" ||
    getprop("ro.build.fingerprint") == "Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.2.0.QJZIDXM:user/release-keys" ||
    abort("E3001: Package expects build fingerprint of Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.1.0.QJZIDXM:user/release-keys or Redmi/joyeuse_id/joyeuse:10/QKQ1.191215.002/V11.0.2.0.QJZIDXM:user/release-keys; this device has " + getprop("ro.build.fingerprint") + ".");
show_progress(0.100000, 10);
patch_partition_check("EMMC:/dev/block/bootdevice/by-name/boot:134217728:58c8268a34dc38ce1d1b6eb31d0aa724ce5b164c",
                      "EMMC:/dev/block/bootdevice/by-name/boot:134217728:968f53d0fdf51c58f11c6994b2d2c40087618bfc") ||
    abort("E3005: \"EMMC:/dev/block/bootdevice/by-name/boot:134217728:58c8268a34dc38ce1d1b6eb31d0aa724ce5b164c\" or \"EMMC:/dev/block/bootdevice/by-name/boot:134217728:968f53d0fdf51c58f11c6994b2d2c40087618bfc\" has unexpected contents.");
apply_patch_space(134217728) || abort("E3006: Not enough free space on /cache to apply patches.");
show_progress(0.100000, 70);
if (range_sha1(map_partition("system"), "70,1,32770,32925,98306,98461,163842,163997,229378,229533,294914,295069,298718,298759,307423,307426,352001,352009,382897,390831,390990,391008,391021,391074,422054,425984,426010,428218,428220,428279,428280,428284,428285,428300,428301,428315,428316,428319,428320,428335,428336,428339,428340,428343,428344,428368,428369,428385,428386,428495,428496,428524,428525,428528,428529,428550,428551,428577,428578,428590,428591,429255,429256,432248,432249,433664,622601,622613,635117,637086,647047") == "e32f694568a5f586e7afdd1f1ae6ae8ef93385ae" || block_image_verify(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat")) then
ui_print("Verified system image...");
else
check_first_block(map_partition("system"));
ifelse (block_image_recover(map_partition("system"), "70,1,32770,32925,98306,98461,163842,163997,229378,229533,294914,295069,298718,298759,307423,307426,352001,352009,382897,390831,390990,391008,391021,391074,422054,425984,426010,428218,428220,428279,428280,428284,428285,428300,428301,428315,428316,428319,428320,428335,428336,428339,428340,428343,428344,428368,428369,428385,428386,428495,428496,428524,428525,428528,428529,428550,428551,428577,428578,428590,428591,429255,429256,432248,432249,433664,622601,622613,635117,637086,647047") && block_image_verify(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat"), ui_print("system recovered successfully."), abort("E1004: system partition fails to recover"));
endif;
if (range_sha1(map_partition("vendor"), "20,1,32770,32843,48519,48520,98306,98379,163842,163915,229378,229451,294914,294987,295007,295008,300453,301430,306208,306282,306283") == "00668cd59b554643536399d256f45830b8a32af5" || block_image_verify(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat")) then
ui_print("Verified vendor image...");
else
check_first_block(map_partition("vendor"));
ifelse (block_image_recover(map_partition("vendor"), "20,1,32770,32843,48519,48520,98306,98379,163842,163915,229378,229451,294914,294987,295007,295008,300453,301430,306208,306282,306283") && block_image_verify(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat"), ui_print("vendor recovered successfully."), abort("E2004: vendor partition fails to recover"));
endif;
if (range_sha1(map_partition("product"), "294,1,84,100,104,108,109,2660,2661,2964,2965,4194,4198,6193,6196,6200,6201,6239,6240,6247,6253,6254,6255,6966,6970,6977,6978,6984,6990,6991,6992,7052,7056,7061,7062,9766,9767,13133,13134,13772,13776,14546,14547,14910,14914,15421,15422,15434,15440,15441,15442,17282,17286,18723,18724,22736,22740,26727,26728,32768,32770,32831,32844,33693,33694,34099,34100,41265,41266,49268,49269,50758,50759,60463,60464,61150,61151,61157,61158,61164,61170,61171,61172,61300,61306,61307,61308,61320,61326,61327,61328,61331,61332,61338,61344,61345,61346,61369,61375,61376,61377,62221,62222,65536,65549,65550,65551,75687,75688,90752,90753,91406,91407,91917,91918,98301,98302,98304,98306,98367,98380,103130,103131,105382,105383,105570,105571,105582,105588,105589,105590,105600,105601,105606,105610,105615,105616,105620,105626,105630,105631,105637,105643,105644,105645,105657,105663,105664,105665,105675,105681,105682,105683,105685,105692,105698,105699,107456,107457,107463,107464,107598,107599,108807,108814,108868,108875,108880,108887,108912,108919,108939,108946,108964,108971,108987,108988,108996,108998,109168,109169,109170,109171,109172,109173,109174,109175,109212,109214,109222,109223,109228,109229,109500,109504,109508,109510,109515,109519,109520,109524,109525,109529,109530,109534,109535,109539,109540,109544,109545,109549,109550,109552,109559,109563,109564,109568,109569,109573,109574,109578,109579,109581,109582,109586,109587,109591,109592,109594,109595,109599,109600,109604,109605,109609,109610,109614,109615,109619,109620,109624,109625,109629,109630,109632,109636,109640,109641,109645,109646,109650,109651,109655,109656,109658,109659,109663,109664,109666,109667,109671,109672,109674,109675,109679,109680,109684,109685,109687,109688,109692,109693,109840,110812,110813,114381,114382,115545,115546,120273,120274,124757,124759,124769,163842,163903,229378,229439,229445,229452,252638,253406,257424,257488,257489") == "2791e754090448b09c1c99b0b95d2f9ba2d3e570" || block_image_verify(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat")) then
ui_print("Verified product image...");
else
check_first_block(map_partition("product"));
ifelse (block_image_recover(map_partition("product"), "294,1,84,100,104,108,109,2660,2661,2964,2965,4194,4198,6193,6196,6200,6201,6239,6240,6247,6253,6254,6255,6966,6970,6977,6978,6984,6990,6991,6992,7052,7056,7061,7062,9766,9767,13133,13134,13772,13776,14546,14547,14910,14914,15421,15422,15434,15440,15441,15442,17282,17286,18723,18724,22736,22740,26727,26728,32768,32770,32831,32844,33693,33694,34099,34100,41265,41266,49268,49269,50758,50759,60463,60464,61150,61151,61157,61158,61164,61170,61171,61172,61300,61306,61307,61308,61320,61326,61327,61328,61331,61332,61338,61344,61345,61346,61369,61375,61376,61377,62221,62222,65536,65549,65550,65551,75687,75688,90752,90753,91406,91407,91917,91918,98301,98302,98304,98306,98367,98380,103130,103131,105382,105383,105570,105571,105582,105588,105589,105590,105600,105601,105606,105610,105615,105616,105620,105626,105630,105631,105637,105643,105644,105645,105657,105663,105664,105665,105675,105681,105682,105683,105685,105692,105698,105699,107456,107457,107463,107464,107598,107599,108807,108814,108868,108875,108880,108887,108912,108919,108939,108946,108964,108971,108987,108988,108996,108998,109168,109169,109170,109171,109172,109173,109174,109175,109212,109214,109222,109223,109228,109229,109500,109504,109508,109510,109515,109519,109520,109524,109525,109529,109530,109534,109535,109539,109540,109544,109545,109549,109550,109552,109559,109563,109564,109568,109569,109573,109574,109578,109579,109581,109582,109586,109587,109591,109592,109594,109595,109599,109600,109604,109605,109609,109610,109614,109615,109619,109620,109624,109625,109629,109630,109632,109636,109640,109641,109645,109646,109650,109651,109655,109656,109658,109659,109663,109664,109666,109667,109671,109672,109674,109675,109679,109680,109684,109685,109687,109688,109692,109693,109840,110812,110813,114381,114382,115545,115546,120273,120274,124757,124759,124769,163842,163903,229378,229439,229445,229452,252638,253406,257424,257488,257489") && block_image_verify(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat"), ui_print("product recovered successfully."), abort("E2004: product partition fails to recover"));
endif;

# ---- start making changes here ----

ui_print("Patching boot image...");
show_progress(0.100000, 10);
patch_partition("EMMC:/dev/block/bootdevice/by-name/boot:134217728:58c8268a34dc38ce1d1b6eb31d0aa724ce5b164c",
                "EMMC:/dev/block/bootdevice/by-name/boot:134217728:968f53d0fdf51c58f11c6994b2d2c40087618bfc",
                package_extract_file("boot.img.p")) ||
    abort("E3008: Failed to apply patch to EMMC:/dev/block/bootdevice/by-name/boot:134217728:968f53d0fdf51c58f11c6994b2d2c40087618bfc");

# ---- radio update tasks ----

ui_print("Patching firmware images...");
package_extract_file("firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64");
package_extract_file("firmware-update/imagefv.elf", "/dev/block/bootdevice/by-name/imagefv");
package_extract_file("firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlib");
package_extract_file("firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hyp");
package_extract_file("firmware-update/km4.mbn", "/dev/block/bootdevice/by-name/keymaster");
package_extract_file("firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tz");
package_extract_file("firmware-update/aop.mbn", "/dev/block/bootdevice/by-name/aop");
package_extract_file("firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_config");
package_extract_file("firmware-update/BTFM.bin", "/dev/block/bootdevice/by-name/bluetooth");
package_extract_file("firmware-update/uefi_sec.mbn", "/dev/block/bootdevice/by-name/uefisecapp");
package_extract_file("firmware-update/NON-HLOS.bin", "/dev/block/bootdevice/by-name/modem");
package_extract_file("firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfw");
package_extract_file("firmware-update/abl.elf", "/dev/block/bootdevice/by-name/abl");
package_extract_file("firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfg");
package_extract_file("firmware-update/storsec.mbn", "/dev/block/bootdevice/by-name/storsec");
package_extract_file("firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xbl");
package_extract_file("firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64bak");
package_extract_file("firmware-update/imagefv.elf", "/dev/block/bootdevice/by-name/imagefvbak");
package_extract_file("firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlibbak");
package_extract_file("firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hypbak");
package_extract_file("firmware-update/km4.mbn", "/dev/block/bootdevice/by-name/keymasterbak");
package_extract_file("firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tzbak");
package_extract_file("firmware-update/aop.mbn", "/dev/block/bootdevice/by-name/aopbak");
package_extract_file("firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_configbak");
package_extract_file("firmware-update/uefi_sec.mbn", "/dev/block/bootdevice/by-name/uefisecappbak");
package_extract_file("firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfwbak");
package_extract_file("firmware-update/abl.elf", "/dev/block/bootdevice/by-name/ablbak");
package_extract_file("firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfgbak");
package_extract_file("firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xblbak");
show_progress(0.600000, 600);

# --- Start patching dynamic partitions ---


# Patch partition system

ui_print("Patching system image after verification.");
block_image_update(map_partition("system"), package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") ||
  abort("E1001: Failed to update system image.");

# Update dynamic partition metadata

assert(update_dynamic_partitions(package_extract_file("dynamic_partitions_op_list")));

# Patch partition product

ui_print("Patching product image after verification.");
block_image_update(map_partition("product"), package_extract_file("product.transfer.list"), "product.new.dat", "product.patch.dat") ||
  abort("E2001: Failed to update product image.");

# Patch partition vendor

ui_print("Patching vendor image after verification.");
block_image_update(map_partition("vendor"), package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat") ||
  abort("E2001: Failed to update vendor image.");

# --- End patching dynamic partitions ---

show_progress(0.100000, 2);

# ---- radio update tasks 2 ----

ui_print("Patching vbmeta dtbo logo binimages...");
package_extract_file("firmware-update/vbmeta_system.img", "/dev/block/bootdevice/by-name/vbmeta_system");
package_extract_file("firmware-update/dtbo.img", "/dev/block/bootdevice/by-name/dtbo");
package_extract_file("firmware-update/vbmeta.img", "/dev/block/bootdevice/by-name/vbmeta");
