diff --git a/.flutter b/.flutter index d211f4286..7f20e5d18 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit d211f42860350d914a5ad8102f9ec32764dc6d06 +Subproject commit 7f20e5d18ce4cb80c621533090a7c5113f5bdc52 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a74ecdbc..0e66c1471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file. - long press actions trigger haptic feedback according to OS settings - target Android 14 (API 34) -- upgraded Flutter to stable v3.13.9 +- upgraded Flutter to stable v3.16.1 ### Fixed diff --git a/android/app/build.gradle b/android/app/build.gradle index bdf0822df..c7b1a4bef 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -68,6 +68,11 @@ android { // if there are some libs in `lib/armeabi-v7a` unmatched by libs in `lib/arm64-v8a`, // so we exclude the extra `neon` libs bundled by `FFmpegKit`. exclude 'lib/armeabi-v7a/*_neon.so' + + // necessary since Flutter v3.16.0 + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' } sourceSets { @@ -240,7 +245,7 @@ dependencies { // huawei flavor only huaweiImplementation "com.huawei.agconnect:agconnect-core:$huawei_agconnect_version" - testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0' + testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.1' kapt 'androidx.annotation:annotation:1.7.0' ksp "com.github.bumptech.glide:ksp:$glide_version" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e5f1500da..140a47077 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -101,18 +101,24 @@ + + tools:targetApi="tiramisu"> - + diff --git a/android/build.gradle b/android/build.gradle index 876287b9c..945160a04 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - kotlin_version = '1.8.21' - ksp_version = "$kotlin_version-1.0.11" + kotlin_version = '1.9.20' + ksp_version = "$kotlin_version-1.0.14" agp_version = '8.1.2' glide_version = '4.16.0' // AppGallery Connect plugin versions: https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-sdk-changenotes-0000001058732550 diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/1.png b/fastlane/metadata/android/cs/images/phoneScreenshots/1.png index ea8be8f13..472bcd0b3 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/1.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/2.png b/fastlane/metadata/android/cs/images/phoneScreenshots/2.png index f684259cf..b1e1fbb7e 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/2.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/3.png b/fastlane/metadata/android/cs/images/phoneScreenshots/3.png index 7940af98c..51d5c294b 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/3.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/4.png b/fastlane/metadata/android/cs/images/phoneScreenshots/4.png index 3ea278277..a7ceeb655 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/4.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/5.png b/fastlane/metadata/android/cs/images/phoneScreenshots/5.png index 6fbd3a037..f65ab3a1a 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/5.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/6.png b/fastlane/metadata/android/cs/images/phoneScreenshots/6.png index e63823d65..92f708e30 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/6.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/cs/images/phoneScreenshots/7.png b/fastlane/metadata/android/cs/images/phoneScreenshots/7.png index 0c8d9c0e7..9844a00a5 100644 Binary files a/fastlane/metadata/android/cs/images/phoneScreenshots/7.png and b/fastlane/metadata/android/cs/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/1.png b/fastlane/metadata/android/de/images/phoneScreenshots/1.png index ff49b0a6e..dee328b8b 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/1.png and b/fastlane/metadata/android/de/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/2.png b/fastlane/metadata/android/de/images/phoneScreenshots/2.png index f43179c6e..f40409037 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/2.png and b/fastlane/metadata/android/de/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/3.png b/fastlane/metadata/android/de/images/phoneScreenshots/3.png index c190bb5bd..0ea3e4fd4 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/3.png and b/fastlane/metadata/android/de/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/4.png b/fastlane/metadata/android/de/images/phoneScreenshots/4.png index 8c1cb648c..d0351b9fe 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/4.png and b/fastlane/metadata/android/de/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/5.png b/fastlane/metadata/android/de/images/phoneScreenshots/5.png index 64e691838..06b031df0 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/5.png and b/fastlane/metadata/android/de/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/6.png b/fastlane/metadata/android/de/images/phoneScreenshots/6.png index 9de79e28b..ca7c88fde 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/6.png and b/fastlane/metadata/android/de/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/de/images/phoneScreenshots/7.png b/fastlane/metadata/android/de/images/phoneScreenshots/7.png index 6d0ff3f96..ff3a19e7a 100644 Binary files a/fastlane/metadata/android/de/images/phoneScreenshots/7.png and b/fastlane/metadata/android/de/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/1.png b/fastlane/metadata/android/el/images/phoneScreenshots/1.png index eefd8f1bb..f0722cbab 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/1.png and b/fastlane/metadata/android/el/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/2.png b/fastlane/metadata/android/el/images/phoneScreenshots/2.png index 96dae9f00..215036deb 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/2.png and b/fastlane/metadata/android/el/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/3.png b/fastlane/metadata/android/el/images/phoneScreenshots/3.png index bc74450d4..74d97a7d9 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/3.png and b/fastlane/metadata/android/el/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/4.png b/fastlane/metadata/android/el/images/phoneScreenshots/4.png index 77e81d3f9..21c1e62d2 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/4.png and b/fastlane/metadata/android/el/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/5.png b/fastlane/metadata/android/el/images/phoneScreenshots/5.png index 24d25bb3f..f767b3be2 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/5.png and b/fastlane/metadata/android/el/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/6.png b/fastlane/metadata/android/el/images/phoneScreenshots/6.png index b8873682f..9bcee393e 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/6.png and b/fastlane/metadata/android/el/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/el/images/phoneScreenshots/7.png b/fastlane/metadata/android/el/images/phoneScreenshots/7.png index be70a0288..931e6370d 100644 Binary files a/fastlane/metadata/android/el/images/phoneScreenshots/7.png and b/fastlane/metadata/android/el/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index da2db556d..ca7edfc76 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png index 3fdfd7a50..37f468cc8 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png index 5c427c13c..f867bbba5 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png index 2074b5ce4..094a087d7 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png index 82206f5be..5709828e3 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png index 1ab68a950..0e2e20374 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png index fd97f6418..0eb452dc8 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/1.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/1.png index 7c0e52710..72009ab1b 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/1.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/2.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/2.png index e46458e7f..61afd897b 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/2.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/3.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/3.png index 7235df192..69ff37cda 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/3.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/4.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/4.png index 7576c4812..6491428e5 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/4.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/5.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/5.png index 0014da392..3d00d4077 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/5.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/6.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/6.png index b50b970eb..f45ac6185 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/6.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/es-MX/images/phoneScreenshots/7.png b/fastlane/metadata/android/es-MX/images/phoneScreenshots/7.png index 59dff9ed5..e8a280a16 100644 Binary files a/fastlane/metadata/android/es-MX/images/phoneScreenshots/7.png and b/fastlane/metadata/android/es-MX/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/1.png b/fastlane/metadata/android/eu/images/phoneScreenshots/1.png index 7f2dca48e..c9b016361 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/1.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/2.png b/fastlane/metadata/android/eu/images/phoneScreenshots/2.png index be2d319a7..4c701a4c6 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/2.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/3.png b/fastlane/metadata/android/eu/images/phoneScreenshots/3.png index 98fa51b08..c7cb9c666 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/3.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/4.png b/fastlane/metadata/android/eu/images/phoneScreenshots/4.png index f2a53a498..847627c87 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/4.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/5.png b/fastlane/metadata/android/eu/images/phoneScreenshots/5.png index 244028de4..2b8914ed8 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/5.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/6.png b/fastlane/metadata/android/eu/images/phoneScreenshots/6.png index 41a3c9e5b..1a9ff9000 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/6.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/eu/images/phoneScreenshots/7.png b/fastlane/metadata/android/eu/images/phoneScreenshots/7.png index 3d99af3ed..b9b6686cc 100644 Binary files a/fastlane/metadata/android/eu/images/phoneScreenshots/7.png and b/fastlane/metadata/android/eu/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/1.png b/fastlane/metadata/android/fr/images/phoneScreenshots/1.png index 40ad40622..1a10f9221 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/1.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/2.png b/fastlane/metadata/android/fr/images/phoneScreenshots/2.png index 111066ff1..21b65b162 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/2.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/3.png b/fastlane/metadata/android/fr/images/phoneScreenshots/3.png index 2a3e59ee1..cc4f7a584 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/3.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/4.png b/fastlane/metadata/android/fr/images/phoneScreenshots/4.png index e4433269e..0bb6490e1 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/4.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/5.png b/fastlane/metadata/android/fr/images/phoneScreenshots/5.png index 3378ac3e7..1388a5333 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/5.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/6.png b/fastlane/metadata/android/fr/images/phoneScreenshots/6.png index 7c792b21b..e3ba684a5 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/6.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/fr/images/phoneScreenshots/7.png b/fastlane/metadata/android/fr/images/phoneScreenshots/7.png index 5c1e6cd36..2699c480b 100644 Binary files a/fastlane/metadata/android/fr/images/phoneScreenshots/7.png and b/fastlane/metadata/android/fr/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/1.png b/fastlane/metadata/android/hu/images/phoneScreenshots/1.png index 7e43417d9..f50f91a94 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/1.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/2.png b/fastlane/metadata/android/hu/images/phoneScreenshots/2.png index f26b68fcc..96a5ccdc8 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/2.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/3.png b/fastlane/metadata/android/hu/images/phoneScreenshots/3.png index 506cafe4c..18a1922bc 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/3.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/4.png b/fastlane/metadata/android/hu/images/phoneScreenshots/4.png index 8e5ebb434..8fa0e498c 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/4.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/5.png b/fastlane/metadata/android/hu/images/phoneScreenshots/5.png index 2a11a7b48..8d8522b2f 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/5.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/6.png b/fastlane/metadata/android/hu/images/phoneScreenshots/6.png index 379e13ee5..54e31b8c7 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/6.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/hu/images/phoneScreenshots/7.png b/fastlane/metadata/android/hu/images/phoneScreenshots/7.png index fe1a650f4..ad7ee0ff0 100644 Binary files a/fastlane/metadata/android/hu/images/phoneScreenshots/7.png and b/fastlane/metadata/android/hu/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/1.png b/fastlane/metadata/android/id/images/phoneScreenshots/1.png index fc94cf155..6eaf2273b 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/1.png and b/fastlane/metadata/android/id/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/2.png b/fastlane/metadata/android/id/images/phoneScreenshots/2.png index 276edee53..dfdd8b26d 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/2.png and b/fastlane/metadata/android/id/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/3.png b/fastlane/metadata/android/id/images/phoneScreenshots/3.png index 0e6eb3db7..fd1bb92dd 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/3.png and b/fastlane/metadata/android/id/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/4.png b/fastlane/metadata/android/id/images/phoneScreenshots/4.png index dbedad8eb..5e575b60d 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/4.png and b/fastlane/metadata/android/id/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/5.png b/fastlane/metadata/android/id/images/phoneScreenshots/5.png index a0efbf155..e8b17d935 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/5.png and b/fastlane/metadata/android/id/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/6.png b/fastlane/metadata/android/id/images/phoneScreenshots/6.png index f1f00ca5e..763d3f053 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/6.png and b/fastlane/metadata/android/id/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/id/images/phoneScreenshots/7.png b/fastlane/metadata/android/id/images/phoneScreenshots/7.png index e3af538e6..e64da42a5 100644 Binary files a/fastlane/metadata/android/id/images/phoneScreenshots/7.png and b/fastlane/metadata/android/id/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/1.png b/fastlane/metadata/android/it/images/phoneScreenshots/1.png index d6b796478..2639a317b 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/1.png and b/fastlane/metadata/android/it/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/2.png b/fastlane/metadata/android/it/images/phoneScreenshots/2.png index 6ba6e70dc..ce01662ee 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/2.png and b/fastlane/metadata/android/it/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/3.png b/fastlane/metadata/android/it/images/phoneScreenshots/3.png index 5ce25cd4d..e83f88660 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/3.png and b/fastlane/metadata/android/it/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/4.png b/fastlane/metadata/android/it/images/phoneScreenshots/4.png index 5da901ece..dd89e1ef6 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/4.png and b/fastlane/metadata/android/it/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/5.png b/fastlane/metadata/android/it/images/phoneScreenshots/5.png index 7fc3c9d00..ee7841838 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/5.png and b/fastlane/metadata/android/it/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/6.png b/fastlane/metadata/android/it/images/phoneScreenshots/6.png index 854b14068..4f405d609 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/6.png and b/fastlane/metadata/android/it/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/it/images/phoneScreenshots/7.png b/fastlane/metadata/android/it/images/phoneScreenshots/7.png index fe36b22d3..e5ac97ce6 100644 Binary files a/fastlane/metadata/android/it/images/phoneScreenshots/7.png and b/fastlane/metadata/android/it/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/1.png b/fastlane/metadata/android/ja/images/phoneScreenshots/1.png index 197d4d7c9..f0295da57 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/1.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/2.png b/fastlane/metadata/android/ja/images/phoneScreenshots/2.png index 80352a8e4..1a09722c2 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/2.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/3.png b/fastlane/metadata/android/ja/images/phoneScreenshots/3.png index 1220cee5a..be1c197fa 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/3.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/4.png b/fastlane/metadata/android/ja/images/phoneScreenshots/4.png index f8c167d72..3c794709f 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/4.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/5.png b/fastlane/metadata/android/ja/images/phoneScreenshots/5.png index 6750f2a99..85da14dba 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/5.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/6.png b/fastlane/metadata/android/ja/images/phoneScreenshots/6.png index 94a630301..1fa22534d 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/6.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/ja/images/phoneScreenshots/7.png b/fastlane/metadata/android/ja/images/phoneScreenshots/7.png index 565e6ebef..859589ec8 100644 Binary files a/fastlane/metadata/android/ja/images/phoneScreenshots/7.png and b/fastlane/metadata/android/ja/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/1.png b/fastlane/metadata/android/ko/images/phoneScreenshots/1.png index dfafa5766..7082f118a 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/1.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/2.png b/fastlane/metadata/android/ko/images/phoneScreenshots/2.png index a90b98b25..656e9d065 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/2.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/3.png b/fastlane/metadata/android/ko/images/phoneScreenshots/3.png index 1f32a2593..653aafa90 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/3.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/4.png b/fastlane/metadata/android/ko/images/phoneScreenshots/4.png index 8530da0b9..49b756274 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/4.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/5.png b/fastlane/metadata/android/ko/images/phoneScreenshots/5.png index 09ff885d5..9deb97f29 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/5.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/6.png b/fastlane/metadata/android/ko/images/phoneScreenshots/6.png index 206370d9b..d95c27b54 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/6.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/ko/images/phoneScreenshots/7.png b/fastlane/metadata/android/ko/images/phoneScreenshots/7.png index 514fa72c2..dd7d136e4 100644 Binary files a/fastlane/metadata/android/ko/images/phoneScreenshots/7.png and b/fastlane/metadata/android/ko/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/1.png b/fastlane/metadata/android/lt/images/phoneScreenshots/1.png index 28589979e..9833ac27c 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/1.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/2.png b/fastlane/metadata/android/lt/images/phoneScreenshots/2.png index 88a3c59ae..3cc6610f8 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/2.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/3.png b/fastlane/metadata/android/lt/images/phoneScreenshots/3.png index 345fb90e6..cc118f076 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/3.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/4.png b/fastlane/metadata/android/lt/images/phoneScreenshots/4.png index b7a0bb546..66aa2f726 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/4.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/5.png b/fastlane/metadata/android/lt/images/phoneScreenshots/5.png index 0408fd3c5..3561b8d1a 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/5.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/6.png b/fastlane/metadata/android/lt/images/phoneScreenshots/6.png index 233411d03..e2495abf0 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/6.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/lt/images/phoneScreenshots/7.png b/fastlane/metadata/android/lt/images/phoneScreenshots/7.png index ba5df9955..849f2e560 100644 Binary files a/fastlane/metadata/android/lt/images/phoneScreenshots/7.png and b/fastlane/metadata/android/lt/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1.png index a0301b619..887823e42 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2.png index c71169bb1..296bd4895 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3.png index b793e51ab..31347e3b2 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4.png index 517d27107..3e9afad93 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/5.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/5.png index 35c2d588d..f900a93fa 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/5.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/6.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/6.png index fff3807fd..05412e6d6 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/6.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/7.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/7.png index 9e548bde8..07d6de655 100644 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/7.png and b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/1.png b/fastlane/metadata/android/nl/images/phoneScreenshots/1.png index 5a9beeef1..5605a8319 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/1.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/2.png b/fastlane/metadata/android/nl/images/phoneScreenshots/2.png index 0d12b0043..d503bd675 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/2.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/3.png b/fastlane/metadata/android/nl/images/phoneScreenshots/3.png index 71352d755..0a43eef47 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/3.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/4.png b/fastlane/metadata/android/nl/images/phoneScreenshots/4.png index 1022676f1..dead88501 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/4.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/5.png b/fastlane/metadata/android/nl/images/phoneScreenshots/5.png index d37238c12..857d999a8 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/5.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/6.png b/fastlane/metadata/android/nl/images/phoneScreenshots/6.png index 2bc15db64..833b7e922 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/6.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/nl/images/phoneScreenshots/7.png b/fastlane/metadata/android/nl/images/phoneScreenshots/7.png index f9c3c461a..b837ed5b3 100644 Binary files a/fastlane/metadata/android/nl/images/phoneScreenshots/7.png and b/fastlane/metadata/android/nl/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/1.png b/fastlane/metadata/android/nn/images/phoneScreenshots/1.png index 8d90d9b37..093c6c39a 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/1.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/2.png b/fastlane/metadata/android/nn/images/phoneScreenshots/2.png index 9fd360a64..2ed257108 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/2.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/3.png b/fastlane/metadata/android/nn/images/phoneScreenshots/3.png index 927ddecd0..57c909e7d 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/3.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/4.png b/fastlane/metadata/android/nn/images/phoneScreenshots/4.png index 825374766..b16da8406 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/4.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/5.png b/fastlane/metadata/android/nn/images/phoneScreenshots/5.png index c9ba7c3e0..77dd8e4f5 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/5.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/6.png b/fastlane/metadata/android/nn/images/phoneScreenshots/6.png index be4769665..486a92c63 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/6.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/nn/images/phoneScreenshots/7.png b/fastlane/metadata/android/nn/images/phoneScreenshots/7.png index 633599ce2..a424a0bcb 100644 Binary files a/fastlane/metadata/android/nn/images/phoneScreenshots/7.png and b/fastlane/metadata/android/nn/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/1.png b/fastlane/metadata/android/pl/images/phoneScreenshots/1.png index 01e38dc7f..8bb698c81 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/1.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/2.png b/fastlane/metadata/android/pl/images/phoneScreenshots/2.png index a1665b69e..e5104fdf0 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/2.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/3.png b/fastlane/metadata/android/pl/images/phoneScreenshots/3.png index b3e2d334c..79e1c8cdc 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/3.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/4.png b/fastlane/metadata/android/pl/images/phoneScreenshots/4.png index d66d85bbf..816a2d78e 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/4.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/5.png b/fastlane/metadata/android/pl/images/phoneScreenshots/5.png index d3f82ec46..754858c02 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/5.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/6.png b/fastlane/metadata/android/pl/images/phoneScreenshots/6.png index cf3ff0987..d8338d257 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/6.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/pl/images/phoneScreenshots/7.png b/fastlane/metadata/android/pl/images/phoneScreenshots/7.png index ed1aa3e5c..9cf6f6cae 100644 Binary files a/fastlane/metadata/android/pl/images/phoneScreenshots/7.png and b/fastlane/metadata/android/pl/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/1.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/1.png index e09364a89..b0c3240de 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/1.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/2.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/2.png index 9ca056b3b..fcd83f21b 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/2.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/3.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/3.png index e2d92740f..72e7a5bd4 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/3.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/4.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/4.png index 7b5f3b674..9e0f5aa79 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/4.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/5.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/5.png index 8fdd9acfa..db56dd16f 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/5.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/6.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/6.png index 90ba8aaf1..3dae76240 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/6.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/7.png b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/7.png index ef878766c..9d7a1bb57 100644 Binary files a/fastlane/metadata/android/pt-BR/images/phoneScreenshots/7.png and b/fastlane/metadata/android/pt-BR/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/1.png b/fastlane/metadata/android/ro/images/phoneScreenshots/1.png index 1bed2e639..b3bb669f5 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/1.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/2.png b/fastlane/metadata/android/ro/images/phoneScreenshots/2.png index c1b1f968c..71931d19b 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/2.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/3.png b/fastlane/metadata/android/ro/images/phoneScreenshots/3.png index bcfa87993..79db3e221 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/3.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/4.png b/fastlane/metadata/android/ro/images/phoneScreenshots/4.png index 7e56c6ef5..a9384fbe6 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/4.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/5.png b/fastlane/metadata/android/ro/images/phoneScreenshots/5.png index fd45fc167..04927bb34 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/5.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/6.png b/fastlane/metadata/android/ro/images/phoneScreenshots/6.png index d4f310193..444c8d903 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/6.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/ro/images/phoneScreenshots/7.png b/fastlane/metadata/android/ro/images/phoneScreenshots/7.png index 2f30e2968..ba3d16585 100644 Binary files a/fastlane/metadata/android/ro/images/phoneScreenshots/7.png and b/fastlane/metadata/android/ro/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/1.png b/fastlane/metadata/android/ru/images/phoneScreenshots/1.png index 59abfcced..f8c5321ef 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/1.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/2.png b/fastlane/metadata/android/ru/images/phoneScreenshots/2.png index 9f0d34127..6bf85ed4f 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/2.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/3.png b/fastlane/metadata/android/ru/images/phoneScreenshots/3.png index 962bb91c8..de4aa071c 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/3.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/4.png b/fastlane/metadata/android/ru/images/phoneScreenshots/4.png index 3add72aab..e5750ff6d 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/4.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/5.png b/fastlane/metadata/android/ru/images/phoneScreenshots/5.png index 4eb0476ff..d257fb384 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/5.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/6.png b/fastlane/metadata/android/ru/images/phoneScreenshots/6.png index 9e44c218f..f698f89ce 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/6.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/ru/images/phoneScreenshots/7.png b/fastlane/metadata/android/ru/images/phoneScreenshots/7.png index 4951e7996..fda462a26 100644 Binary files a/fastlane/metadata/android/ru/images/phoneScreenshots/7.png and b/fastlane/metadata/android/ru/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/1.png b/fastlane/metadata/android/sk/images/phoneScreenshots/1.png index ef90afd5a..97eb00138 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/1.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/2.png b/fastlane/metadata/android/sk/images/phoneScreenshots/2.png index 6ea4b89b9..3c4414785 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/2.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/3.png b/fastlane/metadata/android/sk/images/phoneScreenshots/3.png index c4f5aa63d..f5b6511b1 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/3.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/4.png b/fastlane/metadata/android/sk/images/phoneScreenshots/4.png index 6cc964f12..92e5a9df1 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/4.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/5.png b/fastlane/metadata/android/sk/images/phoneScreenshots/5.png index 43a137851..b99ed6e33 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/5.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/6.png b/fastlane/metadata/android/sk/images/phoneScreenshots/6.png index 615985626..ccf701513 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/6.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/sk/images/phoneScreenshots/7.png b/fastlane/metadata/android/sk/images/phoneScreenshots/7.png index 7855e4838..5534724ad 100644 Binary files a/fastlane/metadata/android/sk/images/phoneScreenshots/7.png and b/fastlane/metadata/android/sk/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/1.png b/fastlane/metadata/android/tr/images/phoneScreenshots/1.png index dd9987e27..a8d768ef9 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/1.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/2.png b/fastlane/metadata/android/tr/images/phoneScreenshots/2.png index 9f7ff6e8e..8ec0ecbb3 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/2.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/3.png b/fastlane/metadata/android/tr/images/phoneScreenshots/3.png index 20de8e056..a667c121c 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/3.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/4.png b/fastlane/metadata/android/tr/images/phoneScreenshots/4.png index da8f76c79..699f1e29f 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/4.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/5.png b/fastlane/metadata/android/tr/images/phoneScreenshots/5.png index 6601ee21a..78acdd853 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/5.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/6.png b/fastlane/metadata/android/tr/images/phoneScreenshots/6.png index 541c304a2..427eebf23 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/6.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/tr/images/phoneScreenshots/7.png b/fastlane/metadata/android/tr/images/phoneScreenshots/7.png index 001da561b..9f297340e 100644 Binary files a/fastlane/metadata/android/tr/images/phoneScreenshots/7.png and b/fastlane/metadata/android/tr/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/1.png b/fastlane/metadata/android/uk/images/phoneScreenshots/1.png index 6bd33fe07..3f73a6652 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/1.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/2.png b/fastlane/metadata/android/uk/images/phoneScreenshots/2.png index 87936023f..dae6783b0 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/2.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/3.png b/fastlane/metadata/android/uk/images/phoneScreenshots/3.png index 4290e81a9..aa8945fa3 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/3.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/4.png b/fastlane/metadata/android/uk/images/phoneScreenshots/4.png index 4a4cb3257..e28441b86 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/4.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/5.png b/fastlane/metadata/android/uk/images/phoneScreenshots/5.png index 7568e56aa..4418e6501 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/5.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/6.png b/fastlane/metadata/android/uk/images/phoneScreenshots/6.png index 66cad9b68..28cf95b24 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/6.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/uk/images/phoneScreenshots/7.png b/fastlane/metadata/android/uk/images/phoneScreenshots/7.png index 5e5198ff0..7d03e2d4d 100644 Binary files a/fastlane/metadata/android/uk/images/phoneScreenshots/7.png and b/fastlane/metadata/android/uk/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/1.png b/fastlane/metadata/android/vi/images/phoneScreenshots/1.png index f6deca26a..b263d13c1 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/1.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/2.png b/fastlane/metadata/android/vi/images/phoneScreenshots/2.png index 12d35f664..078f09ca0 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/2.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/3.png b/fastlane/metadata/android/vi/images/phoneScreenshots/3.png index 4b3faf29e..39fb4faae 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/3.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/4.png b/fastlane/metadata/android/vi/images/phoneScreenshots/4.png index 2f4b7efc4..a905ec4ba 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/4.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/5.png b/fastlane/metadata/android/vi/images/phoneScreenshots/5.png index 41571d022..5fc9215ec 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/5.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/6.png b/fastlane/metadata/android/vi/images/phoneScreenshots/6.png index 06ad94ba0..940c8696b 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/6.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/vi/images/phoneScreenshots/7.png b/fastlane/metadata/android/vi/images/phoneScreenshots/7.png index 7970586a0..8b377e490 100644 Binary files a/fastlane/metadata/android/vi/images/phoneScreenshots/7.png and b/fastlane/metadata/android/vi/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png index d9e7b1573..2903b3606 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png index d8b0242d3..25a6fb2a1 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png index 3f0627ce5..c703cf985 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/4.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/4.png index 124e5943c..a56e416f3 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/4.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/5.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/5.png index ef45bfcfb..3525b251d 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/5.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/6.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/6.png index 462d85e04..c755cf723 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/6.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/7.png b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/7.png index 44b97b4c7..1f7d88739 100644 Binary files a/fastlane/metadata/android/zh-CN/images/phoneScreenshots/7.png and b/fastlane/metadata/android/zh-CN/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/1.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/1.png index 633ed0bed..ccc1c93de 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/1.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/2.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/2.png index 90e4c3b5f..0cc2fad55 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/2.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/3.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/3.png index 3550a8cfd..67eb4b503 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/3.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/4.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/4.png index 312db7cda..5d48b69c5 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/4.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/5.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/5.png index 58d37c151..14916233f 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/5.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/6.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/6.png index ca7ab4559..80467b75e 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/6.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/7.png b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/7.png index 47a958104..6911abd49 100644 Binary files a/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/7.png and b/fastlane/metadata/android/zh-Hant/images/phoneScreenshots/7.png differ diff --git a/lib/model/filters/location.dart b/lib/model/filters/location.dart index 3a22391b5..f66bf26ea 100644 --- a/lib/model/filters/location.dart +++ b/lib/model/filters/location.dart @@ -96,7 +96,7 @@ class LocationFilter extends CoveredCollectionFilter { return Text( flag, style: TextStyle(fontSize: size), - textScaleFactor: 1.0, + textScaler: TextScaler.noScaling, ); } } @@ -108,7 +108,7 @@ class LocationFilter extends CoveredCollectionFilter { return Text( flag, style: TextStyle(fontSize: size), - textScaleFactor: 1.0, + textScaler: TextScaler.noScaling, ); } } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index c57ed4b1b..d3ab7017d 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -10,6 +10,7 @@ import 'package:provider/provider.dart'; class AColors { static const starEnabled = Colors.amber; static const starDisabled = Colors.grey; + static const warning = Colors.amber; static const boraBoraGradient = [ Color(0xff2bc0e4), diff --git a/lib/theme/themes.dart b/lib/theme/themes.dart index 30579055c..eb047011c 100644 --- a/lib/theme/themes.dart +++ b/lib/theme/themes.dart @@ -1,138 +1,245 @@ import 'dart:ui'; -import 'package:aves/model/settings/settings.dart'; import 'package:aves/widgets/aves_app.dart'; -import 'package:aves_model/aves_model.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; class Themes { - static const _tooltipTheme = TooltipThemeData( - verticalOffset: 32, - ); - - static const _appBarTitleTextStyle = TextStyle( + static const _titleTextStyle = TextStyle( fontSize: 20, fontWeight: FontWeight.normal, fontFeatures: [FontFeature.enable('smcp')], ); - static SnackBarThemeData _snackBarTheme(Color accentColor) => SnackBarThemeData( - actionTextColor: accentColor, + // adapted from M3 defaults + static MaterialStateProperty _popupMenuTextStyle(ColorScheme colors, TextTheme textTheme) { + return MaterialStateProperty.resolveWith((states) { + final TextStyle style = textTheme.labelLarge!; + if (states.contains(MaterialState.disabled)) { + return style.apply(color: colors.onSurface.withOpacity(0.38)); + } + return style.apply(color: colors.onSurface); + }); + } + + static TextStyle searchFieldStyle(BuildContext context) => Theme.of(context).textTheme.bodyLarge!; + + static Color overlayBackgroundColor({ + required Brightness brightness, + required bool blurred, + }) { + switch (brightness) { + case Brightness.dark: + return blurred ? Colors.black26 : Colors.black45; + case Brightness.light: + return blurred ? Colors.white54 : const Color(0xCCFFFFFF); + } + } + + static Color _schemeCardLayer(ColorScheme colors) => ElevationOverlay.applySurfaceTint(colors.surface, colors.surfaceTint, 1); + + static Color secondLayerColor(BuildContext context) => _schemeSecondLayer(Theme.of(context).colorScheme); + + // `DialogTheme` M3 defaults use `6.0` elevation + static Color _schemeSecondLayer(ColorScheme colors) => ElevationOverlay.applySurfaceTint(colors.surface, colors.surfaceTint, 6); + + static Color thirdLayerColor(BuildContext context) => _schemeThirdLayer(Theme.of(context).colorScheme); + + static Color _schemeThirdLayer(ColorScheme colors) => ElevationOverlay.applySurfaceTint(colors.surface, colors.surfaceTint, 12); + + static Color _unselectedWidgetColor(ColorScheme colors) => colors.onSurface.withOpacity(0.6); + + static Color backgroundTextColor(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Color.alphaBlend(colors.surfaceTint, colors.onSurface).withOpacity(.5); + } + + static final _typography = Typography.material2021(platform: TargetPlatform.android); + + static ThemeData _baseTheme(ColorScheme colors, bool deviceInitialized) { + return ThemeData( + // COLOR + brightness: colors.brightness, + canvasColor: _schemeSecondLayer(colors), + cardColor: _schemeCardLayer(colors), + colorScheme: colors, + dividerColor: colors.outlineVariant, + indicatorColor: colors.primary, + scaffoldBackgroundColor: colors.background, + // TYPOGRAPHY & ICONOGRAPHY + typography: _typography, + // COMPONENT THEMES + checkboxTheme: _checkboxTheme(colors), + radioTheme: _radioTheme(colors), + sliderTheme: _sliderTheme(colors), + tooltipTheme: _tooltipTheme, + ); + } + + static CheckboxThemeData _checkboxTheme(ColorScheme colors) => CheckboxThemeData( + side: BorderSide(width: 2.0, color: _unselectedWidgetColor(colors)), + ); + + static const _listTileTheme = ListTileThemeData( + contentPadding: EdgeInsets.symmetric(horizontal: 16), + ); + + // adapted from M3 defaults + static RadioThemeData _radioTheme(ColorScheme colors) => RadioThemeData( + fillColor: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.selected)) { + if (states.contains(MaterialState.disabled)) { + return colors.onSurface.withOpacity(0.38); + } + return colors.primary; + } + if (states.contains(MaterialState.disabled)) { + return colors.onSurface.withOpacity(0.38); + } + if (states.contains(MaterialState.pressed)) { + return colors.onSurface; + } + if (states.contains(MaterialState.hovered)) { + return colors.onSurface; + } + if (states.contains(MaterialState.focused)) { + return colors.onSurface; + } + return _unselectedWidgetColor(colors); + }), + ); + + static SliderThemeData _sliderTheme(ColorScheme colors) => SliderThemeData( + inactiveTrackColor: colors.primary.withOpacity(0.24), + ); + + static SnackBarThemeData _snackBarTheme(ColorScheme colors) => SnackBarThemeData( + actionTextColor: colors.primary, behavior: SnackBarBehavior.floating, ); - static final _typography = Typography.material2018(platform: TargetPlatform.android); + static const _tooltipTheme = TooltipThemeData( + verticalOffset: 32, + ); + + // light static final _lightThemeTypo = _typography.black; static final _lightTitleColor = _lightThemeTypo.titleMedium!.color!; static final _lightBodyColor = _lightThemeTypo.bodyMedium!.color!; static final _lightLabelColor = _lightThemeTypo.labelMedium!.color!; static const _lightActionIconColor = Color(0xAA000000); - static const _lightFirstLayer = Color(0xFFFAFAFA); // aka `Colors.grey[50]` - static const _lightSecondLayer = Color(0xFFF5F5F5); // aka `Colors.grey[100]` - static const _lightThirdLayer = Color(0xFFEEEEEE); // aka `Colors.grey[200]` + static const _lightOnSurface = Colors.black; - static ThemeData lightTheme(Color accentColor, bool deviceInitialized) => ThemeData( - colorScheme: ColorScheme.light( - primary: accentColor, - secondary: accentColor, - onPrimary: _lightBodyColor, - onSecondary: _lightBodyColor, + static ThemeData lightTheme(Color accentColor, bool deviceInitialized) { + final colors = ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.light, + primary: accentColor, + onPrimary: _lightBodyColor, + secondary: accentColor, + onSecondary: _lightBodyColor, + onSurface: _lightOnSurface, + ); + final textTheme = _lightThemeTypo; + return _baseTheme(colors, deviceInitialized).copyWith( + // TYPOGRAPHY & ICONOGRAPHY + textTheme: textTheme, + // COMPONENT THEMES + appBarTheme: AppBarTheme( + // `foregroundColor` is used by icons + foregroundColor: _lightActionIconColor, + // `titleTextStyle.color` is used by text + titleTextStyle: _titleTextStyle.copyWith(color: _lightTitleColor), + systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(colors.brightness, colors.background) : null, + ), + dialogTheme: DialogTheme( + titleTextStyle: _titleTextStyle.copyWith(color: _lightTitleColor), + ), + listTileTheme: _listTileTheme.copyWith( + iconColor: _lightActionIconColor, + ), + popupMenuTheme: PopupMenuThemeData( + labelTextStyle: _popupMenuTextStyle(colors, textTheme), + ), + snackBarTheme: _snackBarTheme(colors), + switchTheme: SwitchThemeData( + thumbColor: MaterialStateProperty.resolveWith((states) { + final active = states.contains(MaterialState.selected); + return active ? Colors.white : Colors.grey.shade600; + }), + trackColor: MaterialStateProperty.resolveWith((states) { + final active = states.contains(MaterialState.selected); + return colors.primary.withOpacity(active ? 1 : .1); + }), + trackOutlineColor: MaterialStateProperty.resolveWith((states) { + final active = states.contains(MaterialState.selected); + return active ? colors.primary : colors.onPrimary.withOpacity(.5); + }), + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: _lightLabelColor, ), - brightness: Brightness.light, - // `canvasColor` is used by `Drawer`, `DropdownButton` and `ExpansionTileCard` - canvasColor: _lightSecondLayer, - scaffoldBackgroundColor: _lightFirstLayer, - // `cardColor` is used by `ExpansionPanel` - cardColor: _lightSecondLayer, - dialogBackgroundColor: _lightSecondLayer, - indicatorColor: accentColor, - typography: _typography, - appBarTheme: AppBarTheme( - backgroundColor: _lightFirstLayer, - // `foregroundColor` is used by icons - foregroundColor: _lightActionIconColor, - // `titleTextStyle.color` is used by text - titleTextStyle: _appBarTitleTextStyle.copyWith(color: _lightTitleColor), - systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(Brightness.light, _lightFirstLayer) : null, - ), - listTileTheme: const ListTileThemeData( - iconColor: _lightActionIconColor, - ), - popupMenuTheme: const PopupMenuThemeData( - color: _lightSecondLayer, - ), - snackBarTheme: _snackBarTheme(accentColor), - tabBarTheme: TabBarTheme( - labelColor: _lightTitleColor, - unselectedLabelColor: Colors.black54, - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: _lightLabelColor, - ), - ), - tooltipTheme: _tooltipTheme, - ); + ), + ); + } + + // dark static final _darkThemeTypo = _typography.white; static final _darkTitleColor = _darkThemeTypo.titleMedium!.color!; static final _darkBodyColor = _darkThemeTypo.bodyMedium!.color!; static final _darkLabelColor = _darkThemeTypo.labelMedium!.color!; - static const _darkFirstLayer = Color(0xFF212121); // aka `Colors.grey[900]` - static const _darkSecondLayer = Color(0xFF363636); - static const _darkThirdLayer = Color(0xFF424242); // aka `Colors.grey[800]` + static const _darkOnSurface = Colors.white; - static ThemeData darkTheme(Color accentColor, bool deviceInitialized) => ThemeData( - colorScheme: ColorScheme.dark( - primary: accentColor, - secondary: accentColor, - // surface color is used by the date/time pickers - surface: Colors.grey.shade800, - onPrimary: _darkBodyColor, - onSecondary: _darkBodyColor, + static ThemeData darkTheme(Color accentColor, bool deviceInitialized) { + final colors = ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.dark, + primary: accentColor, + onPrimary: _darkBodyColor, + secondary: accentColor, + onSecondary: _darkBodyColor, + onSurface: _darkOnSurface, + // onSurfaceVariant: Colors.red, + ); + final textTheme = _darkThemeTypo; + return _baseTheme(colors, deviceInitialized).copyWith( + // TYPOGRAPHY & ICONOGRAPHY + textTheme: textTheme, + // COMPONENT THEMES + appBarTheme: AppBarTheme( + // `foregroundColor` is used by icons + foregroundColor: _darkTitleColor, + // `titleTextStyle.color` is used by text + titleTextStyle: _titleTextStyle.copyWith(color: _darkTitleColor), + systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(colors.brightness, colors.background) : null, + ), + dialogTheme: DialogTheme( + titleTextStyle: _titleTextStyle.copyWith(color: _darkTitleColor), + ), + listTileTheme: _listTileTheme, + popupMenuTheme: PopupMenuThemeData( + labelTextStyle: _popupMenuTextStyle(colors, textTheme), + ), + snackBarTheme: _snackBarTheme(colors).copyWith( + backgroundColor: _schemeSecondLayer(colors), + contentTextStyle: TextStyle( + color: _darkBodyColor, ), - brightness: Brightness.dark, - // `canvasColor` is used by `Drawer`, `DropdownButton` and `ExpansionTileCard` - canvasColor: _darkSecondLayer, - scaffoldBackgroundColor: _darkFirstLayer, - // `cardColor` is used by `ExpansionPanel` - cardColor: _darkSecondLayer, - dialogBackgroundColor: _darkSecondLayer, - indicatorColor: accentColor, - typography: _typography, - appBarTheme: AppBarTheme( - backgroundColor: _darkFirstLayer, - // `foregroundColor` is used by icons - foregroundColor: _darkTitleColor, - // `titleTextStyle.color` is used by text - titleTextStyle: _appBarTitleTextStyle.copyWith(color: _darkTitleColor), - systemOverlayStyle: deviceInitialized ? AvesApp.systemUIStyleForBrightness(Brightness.dark, _darkFirstLayer) : null, + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: _darkLabelColor, ), - popupMenuTheme: const PopupMenuThemeData( - color: _darkSecondLayer, - ), - snackBarTheme: _snackBarTheme(accentColor).copyWith( - backgroundColor: Colors.grey.shade800, - contentTextStyle: TextStyle( - color: _darkBodyColor, - ), - ), - tabBarTheme: TabBarTheme( - labelColor: _darkTitleColor, - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: _darkLabelColor, - ), - ), - tooltipTheme: _tooltipTheme, - ); + ), + ); + } + + // black static const _blackFirstLayer = Colors.black; static const _blackSecondLayer = Color(0xFF212121); // aka `Colors.grey[900]` - static const _blackThirdLayer = Color(0xFF303030); // aka `Colors.grey[850]` static ThemeData blackTheme(Color accentColor, bool deviceInitialized) { final baseTheme = darkTheme(accentColor, deviceInitialized); @@ -151,30 +258,4 @@ class Themes { ), ); } - - static Color overlayBackgroundColor({ - required Brightness brightness, - required bool blurred, - }) { - switch (brightness) { - case Brightness.dark: - return blurred ? Colors.black26 : Colors.black45; - case Brightness.light: - return blurred ? Colors.white54 : const Color(0xCCFFFFFF); - } - } - - static Color thirdLayerColor(BuildContext context) { - final isBlack = context.select((v) => v.themeBrightness == AvesThemeBrightness.black); - if (isBlack) { - return _blackThirdLayer; - } else { - switch (Theme.of(context).brightness) { - case Brightness.dark: - return _darkThirdLayer; - case Brightness.light: - return _lightThirdLayer; - } - } - } } diff --git a/lib/widgets/about/about_tv_page.dart b/lib/widgets/about/about_tv_page.dart index a1a944caf..04ebd24c8 100644 --- a/lib/widgets/about/about_tv_page.dart +++ b/lib/widgets/about/about_tv_page.dart @@ -112,7 +112,6 @@ class _ContentState extends State<_Content> { shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(123)), ), - // tileColor: theme.scaffoldBackgroundColor, ); }, itemCount: _Section.values.length, @@ -193,7 +192,7 @@ class _ContentState extends State<_Content> { return Theme( data: theme.copyWith( listTileTheme: listTileTheme.copyWith( - tileColor: theme.scaffoldBackgroundColor, + tileColor: theme.colorScheme.background, ), ), child: const TvLicensePage(), diff --git a/lib/widgets/about/app_ref.dart b/lib/widgets/about/app_ref.dart index 228a62a13..b5db10133 100644 --- a/lib/widgets/about/app_ref.dart +++ b/lib/widgets/about/app_ref.dart @@ -39,12 +39,12 @@ class AppReference extends StatelessWidget { } Widget _buildAvesLine(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return Row( mainAxisSize: MainAxisSize.min, children: [ AvesLogo( - size: _appTitleStyle.fontSize! * textScaleFactor * 1.3, + size: textScaler.scale(_appTitleStyle.fontSize!) * 1.3, ), const SizedBox(width: 8), Text( diff --git a/lib/widgets/about/bug_report.dart b/lib/widgets/about/bug_report.dart index 6a3f39ade..3c8276b15 100644 --- a/lib/widgets/about/bug_report.dart +++ b/lib/widgets/about/bug_report.dart @@ -10,10 +10,12 @@ import 'package:aves/services/common/services.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/styles.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/about/app_ref.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/buttons/outlined_button.dart'; import 'package:aves_model/aves_model.dart'; @@ -77,24 +79,27 @@ class _BugReportState extends State with FeedbackMixin { final info = snapshot.data; if (info == null) return const SizedBox(); - final theme = Theme.of(context); return Container( decoration: BoxDecoration( - color: theme.cardColor, + color: Themes.secondLayerColor(context), border: Border.all( - color: theme.colorScheme.onPrimary, + color: Theme.of(context).dividerColor, + width: AvesBorder.curvedBorderWidth(context), ), - borderRadius: const BorderRadius.all(Radius.circular(8)), + borderRadius: const BorderRadius.all(Radius.circular(16)), ), constraints: const BoxConstraints(maxHeight: 100), margin: const EdgeInsets.symmetric(vertical: 8), clipBehavior: Clip.antiAlias, child: SingleChildScrollView( - padding: const EdgeInsetsDirectional.only(start: 8, top: 4, end: 16, bottom: 4), + padding: const EdgeInsets.all(8), // to show a scroll bar, we would need to provide a scroll controller // to both the `Scrollable` and the `Scrollbar`, but // as of Flutter v3.0.0, `SelectableText` does not allow passing the `scrollController` - child: SelectableText(info), + child: SelectableText( + info, + style: Theme.of(context).textTheme.bodySmall, + ), ), ); }, @@ -122,7 +127,7 @@ class _BugReportState extends State with FeedbackMixin { padding: const EdgeInsets.all(12), decoration: BoxDecoration( border: Border.fromBorderSide(BorderSide( - color: isMonochrome ? context.select((v) => v.neutral) : Theme.of(context).colorScheme.secondary, + color: isMonochrome ? context.select((v) => v.neutral) : Theme.of(context).colorScheme.primary, width: AvesFilterChip.outlineWidth, )), shape: BoxShape.circle, diff --git a/lib/widgets/about/licenses.dart b/lib/widgets/about/licenses.dart index 8ac295659..f5a603673 100644 --- a/lib/widgets/about/licenses.dart +++ b/lib/widgets/about/licenses.dart @@ -88,7 +88,7 @@ class _LicensesState extends State { builder: (context) => Theme( data: Theme.of(context).copyWith( // as of Flutter v3.7.8, `cardColor` is used as a background color by `LicensePage` - cardColor: Theme.of(context).scaffoldBackgroundColor, + cardColor: Theme.of(context).colorScheme.background, ), child: const LicensePage(), ), diff --git a/lib/widgets/about/tv_license_page.dart b/lib/widgets/about/tv_license_page.dart index a6822d725..76eb7a847 100644 --- a/lib/widgets/about/tv_license_page.dart +++ b/lib/widgets/about/tv_license_page.dart @@ -77,7 +77,7 @@ class _TvLicensePageState extends State { final isSelected = index == selectedIndex; final theme = Theme.of(context); return Ink( - color: isSelected ? theme.highlightColor : theme.cardColor, + color: isSelected ? theme.highlightColor : theme.colorScheme.background, child: ListTile( title: Text(packageName), subtitle: Text(MaterialLocalizations.of(context).licensesPackageDetailText(bindings.length)), @@ -219,7 +219,9 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { return true; }()); for (final LicenseEntry license in widget.licenseEntries) { - if (!mounted) return; + if (!mounted) { + return; + } assert(() { Timeline.timeSync('_initLicenses()', () {}, flow: Flow.step(debugFlowId)); return true; @@ -229,7 +231,9 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { Priority.animation, debugLabel: 'License', ); - if (!mounted) return; + if (!mounted) { + return; + } setState(() { _licenses.add(const Padding( padding: EdgeInsets.all(18.0), @@ -298,7 +302,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { ), body: Center( child: Material( - color: theme.cardColor, + color: theme.colorScheme.background, elevation: 4.0, child: Container( constraints: BoxConstraints.loose(const Size.fromWidth(600.0)), @@ -328,7 +332,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { SliverAppBar( automaticallyImplyLeading: false, pinned: true, - backgroundColor: theme.cardColor, + backgroundColor: theme.colorScheme.background, title: _PackageLicensePageTitle( title: title, subtitle: subtitle, diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index dbf118a55..90b3e8876 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -96,18 +96,18 @@ class AvesApp extends StatefulWidget { State createState() => _AvesAppState(); static void setSystemUIStyle(ThemeData theme) { - final style = systemUIStyleForBrightness(theme.brightness, theme.scaffoldBackgroundColor); + final style = systemUIStyleForBrightness(theme.brightness, theme.colorScheme.background); SystemChrome.setSystemUIOverlayStyle(style); } - static SystemUiOverlayStyle systemUIStyleForBrightness(Brightness themeBrightness, Color scaffoldBackgroundColor) { + static SystemUiOverlayStyle systemUIStyleForBrightness(Brightness themeBrightness, Color backgroundColor) { final barBrightness = themeBrightness == Brightness.light ? Brightness.dark : Brightness.light; const statusBarColor = Colors.transparent; // as of Flutter v3.3.0-0.2.pre, setting `SystemUiOverlayStyle` (whether manually or automatically because of `AppBar`) // prevents the canvas from drawing behind the nav bar on Android <10 (API <29), // so the nav bar is opaque, even when requesting `SystemUiMode.edgeToEdge` from Flutter // or setting `android:windowTranslucentNavigation` in Android themes. - final navBarColor = device.supportEdgeToEdgeUIMode ? Colors.transparent : scaffoldBackgroundColor; + final navBarColor = device.supportEdgeToEdgeUIMode ? Colors.transparent : backgroundColor; return SystemUiOverlayStyle( systemNavigationBarColor: navBarColor, systemNavigationBarDividerColor: navBarColor, @@ -493,7 +493,7 @@ class _AvesAppState extends State with WidgetsBindingObserver { ); return mq.copyWith( - textScaleFactor: 1.1, + textScaler: const TextScaler.linear(1.1), padding: newPadding, viewPadding: newViewPadding, navigationMode: NavigationMode.directional, diff --git a/lib/widgets/collection/app_bar.dart b/lib/widgets/collection/app_bar.dart index 5ca14047a..ede4129d6 100644 --- a/lib/widgets/collection/app_bar.dart +++ b/lib/widgets/collection/app_bar.dart @@ -12,6 +12,7 @@ import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/view/view.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/entry_set_action_delegate.dart'; @@ -222,8 +223,8 @@ class _CollectionAppBarState extends State with SingleTickerPr } double get appBarContentHeight { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - double height = kToolbarHeight * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + double height = textScaler.scale(kToolbarHeight); if (settings.useTvLayout) { height += CaptionedButton.getTelevisionButtonHeight(context); } @@ -231,7 +232,7 @@ class _CollectionAppBarState extends State with SingleTickerPr height += FilterBar.preferredHeight; } if (context.read().enabled) { - height += EntryQueryBar.getPreferredHeight(textScaleFactor); + height += EntryQueryBar.getPreferredHeight(textScaler); } return height; } @@ -539,6 +540,7 @@ class _CollectionAppBarState extends State with SingleTickerPr Widget buildItem(EntrySetAction action) => Expanded( child: Material( + color: Colors.transparent, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(8)), ), @@ -682,6 +684,7 @@ class _CollectionAppBarState extends State with SingleTickerPr SearchPageRoute( delegate: CollectionSearchDelegate( searchFieldLabel: context.l10n.searchCollectionFieldHint, + searchFieldStyle: Themes.searchFieldStyle(context), source: collection.source, parentCollection: collection, ), diff --git a/lib/widgets/collection/collection_grid.dart b/lib/widgets/collection/collection_grid.dart index 01b401e71..057052675 100644 --- a/lib/widgets/collection/collection_grid.dart +++ b/lib/widgets/collection/collection_grid.dart @@ -367,7 +367,7 @@ class _CollectionScaler extends StatelessWidget { Widget build(BuildContext context) { final (tileSpacing, horizontalPadding) = context.select((v) => (v.spacing, v.horizontalPadding)); final brightness = Theme.of(context).brightness; - final borderColor = DecoratedThumbnail.borderColor; + final borderColor = DecoratedThumbnail.borderColor(context); final borderWidth = DecoratedThumbnail.borderWidth(context); return GridScaleGestureDetector( scrollableKey: scrollableKey, diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index d0254b809..6a0b9c49a 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -21,6 +21,7 @@ import 'package:aves/services/app_service.dart'; import 'package:aves/services/common/image_op_events.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/durations.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/utils/collection_utils.dart'; import 'package:aves/utils/mime_utils.dart'; import 'package:aves/widgets/common/action_mixins/entry_editor.dart'; @@ -689,6 +690,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware SearchPageRoute( delegate: CollectionSearchDelegate( searchFieldLabel: context.l10n.searchCollectionFieldHint, + searchFieldStyle: Themes.searchFieldStyle(context), source: collection.source, parentCollection: collection, ), diff --git a/lib/widgets/collection/grid/headers/any.dart b/lib/widgets/collection/grid/headers/any.dart index 556380fcc..f2f423829 100644 --- a/lib/widgets/collection/grid/headers/any.dart +++ b/lib/widgets/collection/grid/headers/any.dart @@ -89,8 +89,8 @@ class CollectionSectionHeader extends StatelessWidget { headerExtent = AlbumSectionHeader.getPreferredHeight(context, maxWidth, source, sectionKey); } - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - headerExtent = max(headerExtent, SectionHeader.leadingSize.height * textScaleFactor) + SectionHeader.padding.vertical + SectionHeader.margin.vertical; + final textScaler = MediaQuery.textScalerOf(context); + headerExtent = max(headerExtent, textScaler.scale(SectionHeader.leadingSize.height)) + SectionHeader.padding.vertical + SectionHeader.margin.vertical; return headerExtent; } } diff --git a/lib/widgets/collection/grid/list_details_theme.dart b/lib/widgets/collection/grid/list_details_theme.dart index 6dac8807d..38fe2b901 100644 --- a/lib/widgets/collection/grid/list_details_theme.dart +++ b/lib/widgets/collection/grid/list_details_theme.dart @@ -26,7 +26,7 @@ class EntryListDetailsTheme extends StatelessWidget { final locale = context.l10n.localeName; final use24hour = mq.alwaysUse24HourFormat; - final textScaleFactor = mq.textScaleFactor; + final textScaler = mq.textScaler; final textTheme = Theme.of(context).textTheme; final titleStyle = textTheme.bodyMedium!; @@ -35,7 +35,7 @@ class EntryListDetailsTheme extends StatelessWidget { final titleLineHeightParagraph = RenderParagraph( TextSpan(text: 'Fake Title', style: titleStyle), textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, )..layout(const BoxConstraints(), parentUsesSize: true); final titleLineHeight = titleLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); titleLineHeightParagraph.dispose(); @@ -43,7 +43,7 @@ class EntryListDetailsTheme extends StatelessWidget { final captionLineHeightParagraph = RenderParagraph( TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, strutStyle: AStyles.overflowStrut, )..layout(const BoxConstraints(), parentUsesSize: true); final captionLineHeight = captionLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); @@ -72,7 +72,7 @@ class EntryListDetailsTheme extends StatelessWidget { captionStyle: captionStyle, iconTheme: IconThemeData( color: captionStyle.color, - size: captionStyle.fontSize! * textScaleFactor, + size: textScaler.scale(captionStyle.fontSize!), ), ); }, diff --git a/lib/widgets/collection/query_bar.dart b/lib/widgets/collection/query_bar.dart index 70a7a43e1..cc508042b 100644 --- a/lib/widgets/collection/query_bar.dart +++ b/lib/widgets/collection/query_bar.dart @@ -19,7 +19,7 @@ class EntryQueryBar extends StatefulWidget { @override State createState() => _EntryQueryBarState(); - static double getPreferredHeight(double textScaleFactor) => QueryBar.getPreferredHeight(textScaleFactor); + static double getPreferredHeight(TextScaler textScaler) => QueryBar.getPreferredHeight(textScaler); } class _EntryQueryBarState extends State { @@ -52,9 +52,9 @@ class _EntryQueryBarState extends State { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return Container( - height: EntryQueryBar.getPreferredHeight(textScaleFactor), + height: EntryQueryBar.getPreferredHeight(textScaler), alignment: Alignment.topCenter, child: Selector, bool>( selector: (context, selection) => !selection.isSelecting, diff --git a/lib/widgets/common/action_controls/quick_choosers/common/button.dart b/lib/widgets/common/action_controls/quick_choosers/common/button.dart index e7c74fce7..b4d409d1f 100644 --- a/lib/widgets/common/action_controls/quick_choosers/common/button.dart +++ b/lib/widgets/common/action_controls/quick_choosers/common/button.dart @@ -70,21 +70,30 @@ abstract class ChooserQuickButtonState, U> exten ); } - return GestureDetector( - behavior: HitTestBehavior.opaque, - onLongPressStart: _hasChooser ? _showChooser : null, - onLongPressMoveUpdate: _hasChooser ? _moveUpdateStreamController.add : null, - onLongPressEnd: _hasChooser - ? (details) { - _clearChooserOverlayEntry(); - final selectedValue = _chooserValueNotifier.value; - if (selectedValue != null) { - widget.onChooserValue?.call(selectedValue); + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + return Theme( + data: theme.copyWith( + colorScheme: colorScheme.copyWith( + onSurfaceVariant: colorScheme.onSurface, + ), + ), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onLongPressStart: _hasChooser ? _showChooser : null, + onLongPressMoveUpdate: _hasChooser ? _moveUpdateStreamController.add : null, + onLongPressEnd: _hasChooser + ? (details) { + _clearChooserOverlayEntry(); + final selectedValue = _chooserValueNotifier.value; + if (selectedValue != null) { + widget.onChooserValue?.call(selectedValue); + } } - } - : null, - onLongPressCancel: _clearChooserOverlayEntry, - child: child, + : null, + onLongPressCancel: _clearChooserOverlayEntry, + child: child, + ), ); } diff --git a/lib/widgets/common/action_mixins/feedback.dart b/lib/widgets/common/action_mixins/feedback.dart index 30fd47900..871cca7e6 100644 --- a/lib/widgets/common/action_mixins/feedback.dart +++ b/lib/widgets/common/action_mixins/feedback.dart @@ -4,6 +4,7 @@ import 'dart:math'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/enums/accessibility_timeout.dart'; import 'package:aves/model/settings/settings.dart'; +import 'package:aves/theme/colors.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/widgets/common/action_mixins/overlay_snack_bar.dart'; @@ -11,7 +12,6 @@ import 'package:aves/widgets/common/basic/circle.dart'; import 'package:aves/widgets/common/basic/text/change_highlight.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/entry_viewer_page.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:overlay_support/overlay_support.dart'; @@ -47,7 +47,7 @@ mixin FeedbackMixin { final snackBarContent = _FeedbackMessage( type: type, message: message, - progressColor: theme.colorScheme.secondary, + progressColor: theme.colorScheme.primary, start: start, stop: action != null ? start.add(duration) : null, ); @@ -80,6 +80,7 @@ mixin FeedbackMixin { child: Text(action.label), ) : null, + animation: kAlwaysCompleteAnimation, dismissDirection: DismissDirection.horizontal, onDismiss: () => notificationOverlayEntry?.dismiss(), ), @@ -201,10 +202,11 @@ class _ReportOverlayState extends State> with SingleTickerPr @override Widget build(BuildContext context) { - final progressColor = Theme.of(context).colorScheme.secondary; + final colorScheme = Theme.of(context).colorScheme; + final progressColor = colorScheme.primary; final animate = context.select((v) => v.accessibilityAnimations.animate); - return WillPopScope( - onWillPop: () => SynchronousFuture(false), + return PopScope( + canPop: false, child: StreamBuilder( stream: opStream, builder: (context, snapshot) { @@ -220,7 +222,7 @@ class _ReportOverlayState extends State> with SingleTickerPr width: diameter + 2, height: diameter + 2, decoration: BoxDecoration( - color: Theme.of(context).brightness == Brightness.dark ? const Color(0xBB000000) : const Color(0xEEFFFFFF), + color: colorScheme.brightness == Brightness.dark ? const Color(0xBB000000) : const Color(0xEEFFFFFF), shape: BoxShape.circle, ), ), @@ -238,7 +240,7 @@ class _ReportOverlayState extends State> with SingleTickerPr percent: percent, lineWidth: strokeWidth, radius: diameter / 2, - backgroundColor: Theme.of(context).colorScheme.onSurface.withOpacity(.2), + backgroundColor: colorScheme.onSurface.withOpacity(.2), progressColor: progressColor, animation: animate, center: total != null @@ -331,18 +333,21 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final theme = Theme.of(context); - final contentTextStyle = theme.snackBarTheme.contentTextStyle ?? ThemeData(brightness: theme.brightness).textTheme.titleMedium!; - final fontSize = theme.snackBarTheme.contentTextStyle?.fontSize ?? theme.textTheme.bodyMedium!.fontSize!; - final timerChangeShadowColor = theme.colorScheme.primary; + final colorScheme = theme.colorScheme; + final contentTextStyle = theme.snackBarTheme.contentTextStyle ?? + theme.textTheme.bodyMedium!.copyWith( + color: colorScheme.onInverseSurface, + ); + final timerChangeShadowColor = colorScheme.primary; return Row( children: [ if (widget.type == FeedbackType.warn) ...[ CustomPaint( - painter: _WarnIndicator(), - size: Size(4, fontSize * textScaleFactor), + painter: const _WarnIndicator(AColors.warning), + size: Size(4, textScaler.scale(contentTextStyle.fontSize!)), ), const SizedBox(width: 8), ], @@ -391,13 +396,17 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro } class _WarnIndicator extends CustomPainter { + final Color color; + + const _WarnIndicator(this.color); + @override void paint(Canvas canvas, Size size) { canvas.drawRRect( RRect.fromLTRBR(0, 0, size.width, size.height, Radius.circular(size.shortestSide / 2)), Paint() ..style = PaintingStyle.fill - ..color = Colors.amber, + ..color = color, ); } diff --git a/lib/widgets/common/action_mixins/overlay_snack_bar.dart b/lib/widgets/common/action_mixins/overlay_snack_bar.dart index 1c212f712..515c4a7cf 100644 --- a/lib/widgets/common/action_mixins/overlay_snack_bar.dart +++ b/lib/widgets/common/action_mixins/overlay_snack_bar.dart @@ -1,43 +1,123 @@ -import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:flutter/material.dart'; // adapted from Flutter `SnackBar` in `/material/snack_bar.dart` // As of Flutter v3.0.1, `SnackBar` is not customizable enough to add margin // and ignore pointers in that area, so we use an overlay entry instead. -// This overlay entry is not below a `Scaffold` (which is expected by `SnackBar` +// This overlay entry is not under a `Scaffold` (which is expected by `SnackBar` // and `SnackBarAction`), and is not dismissed the same way. -// This adaptation assumes the `SnackBarBehavior.floating` behavior and no animation. + +const double _singleLineVerticalPadding = 14.0; +const Duration _snackBarDisplayDuration = Duration(milliseconds: 4000); +const Curve _snackBarHeightCurve = Curves.fastOutSlowIn; +const Curve _snackBarM3HeightCurve = Curves.easeInOutQuart; + +const Curve _snackBarFadeInCurve = Interval(0.4, 1.0); +const Curve _snackBarM3FadeInCurve = Interval(0.4, 0.6, curve: Curves.easeInCirc); +const Curve _snackBarFadeOutCurve = Interval(0.72, 1.0, curve: Curves.fastOutSlowIn); + class OverlaySnackBar extends StatefulWidget { final Widget content; + final Color? backgroundColor; + final double? elevation; + final EdgeInsetsGeometry? margin; + final EdgeInsetsGeometry? padding; + final double? width; + final ShapeBorder? shape; + final HitTestBehavior? hitTestBehavior; + final SnackBarBehavior? behavior; final Widget? action; + final double? actionOverflowThreshold; + final bool? showCloseIcon; + final Color? closeIconColor; + final Duration duration; + final Animation? animation; + final VoidCallback? onVisible; final DismissDirection dismissDirection; - final VoidCallback onDismiss; final Clip clipBehavior; + final VoidCallback onDismiss; const OverlaySnackBar({ super.key, required this.content, + this.backgroundColor, + this.elevation, + this.margin, + this.padding, + this.width, + this.shape, + this.hitTestBehavior, + this.behavior, this.action, + this.actionOverflowThreshold, + this.showCloseIcon, + this.closeIconColor, + this.duration = _snackBarDisplayDuration, + this.animation, + this.onVisible, this.dismissDirection = DismissDirection.down, this.clipBehavior = Clip.hardEdge, required this.onDismiss, - }); + }) : assert(elevation == null || elevation >= 0.0), + assert( + width == null || margin == null, + 'Width and margin can not be used together', + ), + assert(actionOverflowThreshold == null || (actionOverflowThreshold >= 0 && actionOverflowThreshold <= 1), 'Action overflow threshold must be between 0 and 1 inclusive'); @override State createState() => _OverlaySnackBarState(); } class _OverlaySnackBarState extends State { + bool _wasVisible = false; + + @override + void initState() { + super.initState(); + widget.animation!.addStatusListener(_onAnimationStatusChanged); + } + + @override + void didUpdateWidget(OverlaySnackBar oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.animation != oldWidget.animation) { + oldWidget.animation!.removeStatusListener(_onAnimationStatusChanged); + widget.animation!.addStatusListener(_onAnimationStatusChanged); + } + } + + @override + void dispose() { + widget.animation!.removeStatusListener(_onAnimationStatusChanged); + super.dispose(); + } + + void _onAnimationStatusChanged(AnimationStatus animationStatus) { + switch (animationStatus) { + case AnimationStatus.dismissed: + case AnimationStatus.forward: + case AnimationStatus.reverse: + break; + case AnimationStatus.completed: + if (widget.onVisible != null && !_wasVisible) { + widget.onVisible!(); + } + _wasVisible = true; + } + } + @override Widget build(BuildContext context) { assert(debugCheckHasMediaQuery(context)); + final bool accessibleNavigation = MediaQuery.accessibleNavigationOf(context); + assert(widget.animation != null); final ThemeData theme = Theme.of(context); final ColorScheme colorScheme = theme.colorScheme; final SnackBarThemeData snackBarTheme = theme.snackBarTheme; final bool isThemeDark = theme.brightness == Brightness.dark; final Color buttonColor = isThemeDark ? colorScheme.primary : colorScheme.secondary; - final SnackBarThemeData defaults = theme.useMaterial3 ? _SnackbarDefaultsM3(context) : _SnackbarDefaultsM2(context); + final SnackBarThemeData defaults = _SnackbarDefaultsM3(context); // SnackBar uses a theme that is the opposite brightness from // the surrounding theme. @@ -63,12 +143,63 @@ class _OverlaySnackBarState extends State { ); final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? defaults.contentTextStyle; + final SnackBarBehavior snackBarBehavior = widget.behavior ?? snackBarTheme.behavior ?? defaults.behavior!; + final double? width = widget.width ?? snackBarTheme.width; + assert(() { + // Whether the behavior is set through the constructor or the theme, + // assert that our other properties are configured properly. + if (snackBarBehavior != SnackBarBehavior.floating) { + String message(String parameter) { + final String prefix = '$parameter can only be used with floating behavior.'; + if (widget.behavior != null) { + return '$prefix SnackBarBehavior.fixed was set in the SnackBar constructor.'; + } else if (snackBarTheme.behavior != null) { + return '$prefix SnackBarBehavior.fixed was set by the inherited SnackBarThemeData.'; + } else { + return '$prefix SnackBarBehavior.fixed was set by default.'; + } + } - final horizontalPadding = FeedbackMixin.snackBarHorizontalPadding(snackBarTheme); - final padding = EdgeInsetsDirectional.only(start: horizontalPadding, end: widget.action != null ? 0 : horizontalPadding); - const singleLineVerticalPadding = 14.0; + assert(widget.margin == null, message('Margin')); + assert(width == null, message('Width')); + } + return true; + }()); - final EdgeInsets margin = snackBarTheme.insetPadding ?? defaults.insetPadding!; + final bool showCloseIcon = widget.showCloseIcon ?? snackBarTheme.showCloseIcon ?? defaults.showCloseIcon!; + + final bool isFloatingSnackBar = snackBarBehavior == SnackBarBehavior.floating; + final double horizontalPadding = isFloatingSnackBar ? 16.0 : 24.0; + final EdgeInsetsGeometry padding = widget.padding ?? EdgeInsetsDirectional.only(start: horizontalPadding, end: widget.action != null || showCloseIcon ? 0 : horizontalPadding); + + final double iconHorizontalMargin = (widget.padding?.resolve(TextDirection.ltr).right ?? horizontalPadding) / 12.0; + + final CurvedAnimation heightAnimation = CurvedAnimation(parent: widget.animation!, curve: _snackBarHeightCurve); + final CurvedAnimation fadeInAnimation = CurvedAnimation(parent: widget.animation!, curve: _snackBarFadeInCurve); + final CurvedAnimation fadeInM3Animation = CurvedAnimation(parent: widget.animation!, curve: _snackBarM3FadeInCurve); + + final CurvedAnimation fadeOutAnimation = CurvedAnimation( + parent: widget.animation!, + curve: _snackBarFadeOutCurve, + reverseCurve: const Threshold(0.0), + ); + // Material 3 Animation has a height animation on entry, but a direct fade out on exit. + final CurvedAnimation heightM3Animation = CurvedAnimation( + parent: widget.animation!, + curve: _snackBarM3HeightCurve, + reverseCurve: const Threshold(0.0), + ); + + final IconButton? iconButton = showCloseIcon + ? IconButton( + icon: const Icon(Icons.close), + iconSize: 24.0, + color: widget.closeIconColor ?? snackBarTheme.closeIconColor ?? defaults.closeIconColor, + onPressed: () => ScaffoldMessenger.of(context).hideCurrentSnackBar(reason: SnackBarClosedReason.dismiss), + ) + : null; + + final EdgeInsets margin = widget.margin?.resolve(TextDirection.ltr) ?? snackBarTheme.insetPadding ?? defaults.insetPadding!; Widget snackBar = Padding( padding: padding, @@ -76,7 +207,7 @@ class _OverlaySnackBarState extends State { children: [ Expanded( child: Container( - padding: widget.action != null ? null : const EdgeInsets.symmetric(vertical: singleLineVerticalPadding), + padding: widget.action != null ? null : const EdgeInsets.symmetric(vertical: _singleLineVerticalPadding), child: DefaultTextStyle( style: contentTextStyle!, child: widget.content, @@ -93,34 +224,62 @@ class _OverlaySnackBarState extends State { ), child: widget.action!, ), + if (showCloseIcon) + Padding( + padding: EdgeInsets.symmetric(horizontal: iconHorizontalMargin), + child: iconButton, + ), ], ), ); - final double elevation = snackBarTheme.elevation ?? defaults.elevation!; - final Color backgroundColor = snackBarTheme.backgroundColor ?? defaults.backgroundColor!; - final ShapeBorder? shape = snackBarTheme.shape ?? defaults.shape; + if (!isFloatingSnackBar) { + snackBar = SafeArea( + top: false, + child: snackBar, + ); + } + + final double elevation = widget.elevation ?? snackBarTheme.elevation ?? defaults.elevation!; + final Color backgroundColor = widget.backgroundColor ?? snackBarTheme.backgroundColor ?? defaults.backgroundColor!; + final ShapeBorder? shape = widget.shape ?? snackBarTheme.shape ?? (isFloatingSnackBar ? defaults.shape : null); snackBar = Material( shape: shape, elevation: elevation, color: backgroundColor, + clipBehavior: widget.clipBehavior, child: Theme( data: effectiveTheme, - child: snackBar, + child: accessibleNavigation || theme.useMaterial3 + ? snackBar + : FadeTransition( + opacity: fadeOutAnimation, + child: snackBar, + ), ), ); - snackBar = Padding( - padding: margin, - child: snackBar, - ); - - snackBar = SafeArea( - top: false, - bottom: false, - child: snackBar, - ); + if (isFloatingSnackBar) { + // If width is provided, do not include horizontal margins. + if (width != null) { + snackBar = Container( + margin: EdgeInsets.only(top: margin.top, bottom: margin.bottom), + width: width, + child: snackBar, + ); + } else { + snackBar = Padding( + padding: margin, + child: snackBar, + ); + } + snackBar = SafeArea( + top: false, + bottom: false, + child: snackBar, + ); + } snackBar = Semantics( container: true, @@ -130,12 +289,49 @@ class _OverlaySnackBarState extends State { key: const Key('dismissible'), direction: widget.dismissDirection, resizeDuration: null, + behavior: widget.hitTestBehavior ?? (widget.margin != null ? HitTestBehavior.deferToChild : HitTestBehavior.opaque), onDismissed: (direction) => widget.onDismiss(), child: snackBar, ), ); - final Widget snackBarTransition = snackBar; + final Widget snackBarTransition; + if (accessibleNavigation) { + snackBarTransition = snackBar; + } else if (isFloatingSnackBar && !theme.useMaterial3) { + snackBarTransition = FadeTransition( + opacity: fadeInAnimation, + child: snackBar, + ); + // Is Material 3 Floating Snack Bar. + } else if (isFloatingSnackBar && theme.useMaterial3) { + snackBarTransition = FadeTransition( + opacity: fadeInM3Animation, + child: AnimatedBuilder( + animation: heightM3Animation, + builder: (context, child) { + return Align( + alignment: AlignmentDirectional.bottomStart, + heightFactor: heightM3Animation.value, + child: child, + ); + }, + child: snackBar, + ), + ); + } else { + snackBarTransition = AnimatedBuilder( + animation: heightAnimation, + builder: (context, child) { + return Align( + alignment: AlignmentDirectional.topStart, + heightFactor: heightAnimation.value, + child: child, + ); + }, + child: snackBar, + ); + } return Hero( tag: '', @@ -148,51 +344,6 @@ class _OverlaySnackBarState extends State { } } -// Hand coded defaults based on Material Design 2. -class _SnackbarDefaultsM2 extends SnackBarThemeData { - _SnackbarDefaultsM2(BuildContext context) - : _theme = Theme.of(context), - _colors = Theme.of(context).colorScheme, - super(elevation: 6.0); - - late final ThemeData _theme; - late final ColorScheme _colors; - - @override - Color get backgroundColor => _theme.brightness == Brightness.light ? Color.alphaBlend(_colors.onSurface.withOpacity(0.80), _colors.surface) : _colors.onSurface; - - @override - TextStyle? get contentTextStyle => ThemeData(brightness: _theme.brightness == Brightness.light ? Brightness.dark : Brightness.light).textTheme.titleMedium; - - @override - SnackBarBehavior get behavior => SnackBarBehavior.fixed; - - @override - Color get actionTextColor => _colors.secondary; - - @override - Color get disabledActionTextColor => _colors.onSurface.withOpacity(_theme.brightness == Brightness.light ? 0.38 : 0.3); - - @override - ShapeBorder get shape => const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(4.0), - ), - ); - - @override - EdgeInsets get insetPadding => const EdgeInsets.fromLTRB(15.0, 5.0, 15.0, 10.0); - - @override - bool get showCloseIcon => false; - - @override - Color get closeIconColor => _colors.onSurface; - - @override - double get actionOverflowThreshold => 0.25; -} - // BEGIN GENERATED TOKEN PROPERTIES - Snackbar // Do not edit by hand. The code between the "BEGIN GENERATED" and @@ -200,8 +351,6 @@ class _SnackbarDefaultsM2 extends SnackBarThemeData { // Design token database by the script: // dev/tools/gen_defaults/bin/gen_defaults.dart. -// Token database version: v0_162 - class _SnackbarDefaultsM3 extends SnackBarThemeData { _SnackbarDefaultsM3(this.context); diff --git a/lib/widgets/common/app_bar/app_bar_title.dart b/lib/widgets/common/app_bar/app_bar_title.dart index a0274db45..cd9f0f97b 100644 --- a/lib/widgets/common/app_bar/app_bar_title.dart +++ b/lib/widgets/common/app_bar/app_bar_title.dart @@ -12,7 +12,7 @@ class InteractiveAppBarTitle extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return GestureDetector( onTap: onTap, // use a `Container` with a dummy color to make it expand @@ -20,7 +20,7 @@ class InteractiveAppBarTitle extends StatelessWidget { child: Container( alignment: AlignmentDirectional.centerStart, color: Colors.transparent, - height: kToolbarHeight * textScaleFactor, + height: textScaler.scale(kToolbarHeight), child: child, ), ); diff --git a/lib/widgets/common/basic/font_size_icon_theme.dart b/lib/widgets/common/basic/font_size_icon_theme.dart index 7b143fcf8..0ef46d6b7 100644 --- a/lib/widgets/common/basic/font_size_icon_theme.dart +++ b/lib/widgets/common/basic/font_size_icon_theme.dart @@ -11,11 +11,11 @@ class FontSizeIconTheme extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final iconTheme = IconTheme.of(context); return IconTheme( data: iconTheme.copyWith( - size: iconTheme.size! * textScaleFactor, + size: textScaler.scale(iconTheme.size!), ), child: child, ); diff --git a/lib/widgets/common/basic/list_tiles/reselectable_radio.dart b/lib/widgets/common/basic/list_tiles/reselectable_radio.dart index f6a33aacf..1f937dab7 100644 --- a/lib/widgets/common/basic/list_tiles/reselectable_radio.dart +++ b/lib/widgets/common/basic/list_tiles/reselectable_radio.dart @@ -60,7 +60,7 @@ class ReselectableRadioListTile extends StatelessWidget { } return MergeSemantics( child: ListTileTheme.merge( - selectedColor: activeColor ?? Theme.of(context).colorScheme.secondary, + selectedColor: activeColor ?? Theme.of(context).colorScheme.primary, child: ListTile( leading: leading, title: title, diff --git a/lib/widgets/common/basic/list_tiles/slider.dart b/lib/widgets/common/basic/list_tiles/slider.dart index 63ea68d52..1a95a2ea6 100644 --- a/lib/widgets/common/basic/list_tiles/slider.dart +++ b/lib/widgets/common/basic/list_tiles/slider.dart @@ -24,44 +24,46 @@ class SliderListTile extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + final listTileTitleTextStyle = ListTileTheme.of(context).titleTextStyle ?? theme.textTheme.bodyLarge!.copyWith(color: theme.colorScheme.onSurface); return SliderTheme( - data: const SliderThemeData( - overlayShape: RoundSliderOverlayShape( + data: SliderTheme.of(context).copyWith( + overlayShape: const RoundSliderOverlayShape( // align `Slider`s on `Switch`es by matching their overlay/reaction radius // `kRadialReactionRadius` is used when `SwitchThemeData.splashRadius` is undefined overlayRadius: kRadialReactionRadius, ), ), - child: DefaultTextStyle( - style: Theme.of(context).textTheme.titleMedium!, - child: Padding( - padding: const EdgeInsets.only(top: 16, bottom: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: titlePadding, - child: Row( - children: [ - Text(title), - const Spacer(), - if (titleTrailing != null) titleTrailing!(context, value), - ], - ), + child: Padding( + padding: const EdgeInsets.only(top: 16, bottom: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: titlePadding, + child: Row( + children: [ + Text( + title, + style: listTileTitleTextStyle, + ), + const Spacer(), + if (titleTrailing != null) titleTrailing!(context, value), + ], ), - Padding( - // match `SwitchListTile.contentPadding` - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Slider( - value: value, - onChanged: onChanged, - min: min, - max: max, - divisions: divisions, - ), + ), + Padding( + // match `SwitchListTile.contentPadding` + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Slider( + value: value, + onChanged: onChanged, + min: min, + max: max, + divisions: divisions, ), - ], - ), + ), + ], ), ), ); diff --git a/lib/widgets/common/basic/markdown_container.dart b/lib/widgets/common/basic/markdown_container.dart index 62c054210..613680250 100644 --- a/lib/widgets/common/basic/markdown_container.dart +++ b/lib/widgets/common/basic/markdown_container.dart @@ -1,4 +1,5 @@ import 'package:aves/model/settings/settings.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/common/fx/borders.dart'; import 'package:flutter/material.dart'; @@ -53,8 +54,11 @@ class MarkdownContainer extends StatelessWidget { return Container( margin: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( - color: Theme.of(context).canvasColor, - border: Border.all(color: Theme.of(context).dividerColor, width: AvesBorder.curvedBorderWidth(context)), + color: Themes.secondLayerColor(context), + border: Border.all( + color: Theme.of(context).dividerColor, + width: AvesBorder.curvedBorderWidth(context), + ), borderRadius: const BorderRadius.all(Radius.circular(16)), ), constraints: BoxConstraints(maxWidth: useTvLayout ? double.infinity : mobileMaxWidth), diff --git a/lib/widgets/common/basic/popup/expansion_panel.dart b/lib/widgets/common/basic/popup/expansion_panel.dart index 9e2b96ccd..3d4501def 100644 --- a/lib/widgets/common/basic/popup/expansion_panel.dart +++ b/lib/widgets/common/basic/popup/expansion_panel.dart @@ -33,9 +33,6 @@ class PopupMenuExpansionPanel extends PopupMenuEntry { } class _PopupMenuExpansionPanelState extends State> { - // ref `_kMenuHorizontalPadding` used in `PopupMenuItem` - static const double _horizontalPadding = 16; - final ValueNotifier _internalExpandedNotifier = ValueNotifier(null); ValueNotifier get expandedNotifier => widget.expandedNotifier ?? _internalExpandedNotifier; @@ -48,11 +45,11 @@ class _PopupMenuExpansionPanelState extends State> @override Widget build(BuildContext context) { - final theme = Theme.of(context); - var style = PopupMenuTheme.of(context).textStyle ?? theme.textTheme.titleMedium!; - if (!widget.enabled) { - style = style.copyWith(color: theme.disabledColor); - } + final style = PopupMenuTheme.of(context).labelTextStyle!.resolve( + { + if (!widget.enabled) MaterialState.disabled, + }, + )!; final animationDuration = context.select((v) => v.expansionTileAnimation); Widget child = ValueListenableBuilder( @@ -75,7 +72,7 @@ class _PopupMenuExpansionPanelState extends State> color: widget.enabled ? null : Theme.of(context).disabledColor, ), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: _horizontalPadding), + padding: const EdgeInsets.symmetric(horizontal: 12), child: MenuRow( text: widget.title, icon: Icon(widget.icon), diff --git a/lib/widgets/common/basic/query_bar.dart b/lib/widgets/common/basic/query_bar.dart index 08203b60a..e2ddb31bc 100644 --- a/lib/widgets/common/basic/query_bar.dart +++ b/lib/widgets/common/basic/query_bar.dart @@ -26,7 +26,7 @@ class QueryBar extends StatefulWidget { @override State createState() => _QueryBarState(); - static double getPreferredHeight(double textScaleFactor) => kToolbarHeight * textScaleFactor; + static double getPreferredHeight(TextScaler textScaler) => textScaler.scale(kToolbarHeight); } class _QueryBarState extends State { diff --git a/lib/widgets/common/basic/text/animated_diff.dart b/lib/widgets/common/basic/text/animated_diff.dart index 06c642224..213a2a58e 100644 --- a/lib/widgets/common/basic/text/animated_diff.dart +++ b/lib/widgets/common/basic/text/animated_diff.dart @@ -117,7 +117,7 @@ class _AnimatedDiffTextState extends State with SingleTickerPr final paragraph = RenderParagraph( TextSpan(text: text, style: widget.textStyle), textDirection: Directionality.of(context), - textScaleFactor: MediaQuery.textScaleFactorOf(context), + textScaler: MediaQuery.textScalerOf(context), strutStyle: widget.strutStyle, )..layout(const BoxConstraints(), parentUsesSize: true); final width = paragraph.getMaxIntrinsicWidth(double.infinity); diff --git a/lib/widgets/common/basic/text/background_painter.dart b/lib/widgets/common/basic/text/background_painter.dart index 465837176..d6a4254e1 100644 --- a/lib/widgets/common/basic/text/background_painter.dart +++ b/lib/widgets/common/basic/text/background_painter.dart @@ -36,7 +36,7 @@ class TextBackgroundPainter extends StatelessWidget { ), textAlign: textAlign, textDirection: Directionality.of(context), - textScaleFactor: MediaQuery.textScaleFactorOf(context), + textScaler: MediaQuery.textScalerOf(context), )..layout(constraints, parentUsesSize: true); final textLength = spans.map((v) => v.text?.length ?? 0).sum; diff --git a/lib/widgets/common/basic/text_dropdown_button.dart b/lib/widgets/common/basic/text_dropdown_button.dart index 8efc50028..e282446c2 100644 --- a/lib/widgets/common/basic/text_dropdown_button.dart +++ b/lib/widgets/common/basic/text_dropdown_button.dart @@ -1,48 +1,58 @@ import 'package:flutter/material.dart'; -class TextDropdownButton extends DropdownButton { - TextDropdownButton({ +class TextDropdownButton extends StatefulWidget { + final List values; + final String Function(T value) valueText; + final IconData Function(T value)? valueIcon; + final T? value; + final Widget? underline; + final bool isExpanded; + final double? itemHeight; + final Color? dropdownColor; + final ValueChanged? onChanged; + + const TextDropdownButton({ super.key, - required List values, - required String Function(T value) valueText, - IconData Function(T value)? valueIcon, - super.value, - super.hint, - super.disabledHint, - required super.onChanged, - super.onTap, - super.elevation, - super.style, - super.underline, - super.icon, - super.iconDisabledColor, - super.iconEnabledColor, - super.iconSize, - super.isDense, - super.isExpanded, - super.itemHeight, - super.focusColor, - super.focusNode, - super.autofocus, - super.dropdownColor, - super.menuMaxHeight, - super.enableFeedback, - super.alignment, - super.borderRadius, - }) : super( - items: values - .map((v) => DropdownMenuItem( - value: v, - child: _buildItem(valueText(v), valueIcon?.call(v), selected: false), - )) - .toList(), - selectedItemBuilder: (context) => values - .map((v) => DropdownMenuItem( - value: v, - child: _buildItem(valueText(v), valueIcon?.call(v), selected: true), - )) - .toList(), - ); + required this.values, + required this.valueText, + this.valueIcon, + this.value, + this.underline, + this.isExpanded = false, + this.itemHeight = kMinInteractiveDimension, + this.dropdownColor, + required this.onChanged, + }); + + @override + State> createState() => _TextDropdownButtonState(); +} + +class _TextDropdownButtonState extends State> { + @override + Widget build(BuildContext context) { + return DropdownButton( + items: widget.values + .map((v) => DropdownMenuItem( + value: v, + child: _buildItem(widget.valueText(v), widget.valueIcon?.call(v), selected: false), + )) + .toList(), + selectedItemBuilder: (context) => widget.values + .map((v) => DropdownMenuItem( + value: v, + child: _buildItem(widget.valueText(v), widget.valueIcon?.call(v), selected: true), + )) + .toList(), + value: widget.value, + style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.normal), + underline: widget.underline, + isExpanded: widget.isExpanded, + itemHeight: widget.itemHeight, + dropdownColor: widget.dropdownColor, + onChanged: widget.onChanged, + ); + } static Widget _buildItem(String text, IconData? icon, {required bool selected}) { final softWrap = selected ? false : null; diff --git a/lib/widgets/common/basic/wheel.dart b/lib/widgets/common/basic/wheel.dart index 1682eb5cb..6007e9dfd 100644 --- a/lib/widgets/common/basic/wheel.dart +++ b/lib/widgets/common/basic/wheel.dart @@ -46,11 +46,11 @@ class _WheelSelectorState extends State> { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); const background = Colors.transparent; final foreground = DefaultTextStyle.of(context).style.color!; final transitionDuration = context.select((v) => v.formTransition); - final itemSize = Size.square(40 * textScaleFactor); + final itemSize = Size.square(textScaler.scale(40)); return FocusableActionDetector( shortcuts: const { diff --git a/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart b/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart index ce2b4c682..aeba82b62 100644 --- a/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart +++ b/lib/widgets/common/behaviour/eager_scale_gesture_recognizer.dart @@ -181,6 +181,14 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { /// {@endtemplate} Offset trackpadScrollToScaleFactor; + /// The number of pointers being tracked by the gesture recognizer. + /// + /// Typically this is the number of fingers being used to pan the widget using the gesture + /// recognizer. + int get pointerCount { + return _pointerPanZooms.length + _pointerQueue.length; + } + late Offset _initialFocalPoint; Offset? _currentFocalPoint; late double _initialSpan; @@ -231,10 +239,6 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { return scale; } - int get _pointerCount { - return _pointerPanZooms.length + _pointerQueue.length; - } - double _computeRotationFactor() { double factor = 0.0; if (_initialLine != null && _currentLine != null) { @@ -354,7 +358,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { for (final _PointerPanZoomData p in _pointerPanZooms.values) { focalPoint += p.focalPoint; } - _currentFocalPoint = _pointerCount > 0 ? focalPoint / _pointerCount.toDouble() : Offset.zero; + _currentFocalPoint = pointerCount > 0 ? focalPoint / pointerCount.toDouble() : Offset.zero; if (previousFocalPoint == null) { _localFocalPoint = PointerEvent.transformPosition( @@ -449,9 +453,9 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity) { velocity = Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity); } - invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity, scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: _pointerCount))); + invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity, scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: pointerCount))); } else { - invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: _pointerCount))); + invokeCallback('onEnd', () => onEnd!(ScaleEndDetails(scaleVelocity: _scaleVelocityTracker?.getVelocity().pixelsPerSecond.dx ?? -1, pointerCount: pointerCount))); } } _state = _ScaleState.accepted; @@ -499,7 +503,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { focalPoint: _currentFocalPoint!, localFocalPoint: _localFocalPoint, rotation: _computeRotationFactor(), - pointerCount: _pointerCount, + pointerCount: pointerCount, focalPointDelta: _delta, )); }); @@ -514,7 +518,7 @@ class EagerScaleGestureRecognizer extends OneSequenceGestureRecognizer { onStart!(ScaleStartDetails( focalPoint: _currentFocalPoint!, localFocalPoint: _localFocalPoint, - pointerCount: _pointerCount, + pointerCount: pointerCount, )); }); } diff --git a/lib/widgets/common/behaviour/pop/scope.dart b/lib/widgets/common/behaviour/pop/scope.dart index c099d79c6..98d8f79f8 100644 --- a/lib/widgets/common/behaviour/pop/scope.dart +++ b/lib/widgets/common/behaviour/pop/scope.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; // as of Flutter v3.3.10, the resolution order of multiple `WillPopScope` is random @@ -15,8 +14,16 @@ class AvesPopScope extends StatelessWidget { @override Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () => SynchronousFuture(handlers.fold(true, (prev, v) => prev ? v(context) : false)), + return PopScope( + canPop: false, + onPopInvoked: (didPop) { + if (didPop) return; + + final shouldPop = handlers.fold(true, (prev, v) => prev ? v(context) : false); + if (shouldPop) { + Navigator.of(context).pop(); + } + }, child: child, ); } diff --git a/lib/widgets/common/fx/highlight_decoration.dart b/lib/widgets/common/fx/highlight_decoration.dart index b888fa5ff..f3a323ad7 100644 --- a/lib/widgets/common/fx/highlight_decoration.dart +++ b/lib/widgets/common/fx/highlight_decoration.dart @@ -22,8 +22,8 @@ class _HighlightDecorationPainter extends BoxPainter { if (size == null) return; final confHeight = size.height; - final paintHeight = confHeight * .4; - final rect = Rect.fromLTWH(offset.dx, offset.dy + confHeight - paintHeight, size.width, paintHeight); + final paintHeight = confHeight * .32; + final rect = Rect.fromLTWH(offset.dx, offset.dy + size.height * .58, size.width, paintHeight); final rrect = RRect.fromRectAndRadius(rect, Radius.circular(paintHeight)); final paint = Paint()..color = decoration.color; canvas.drawRRect(rrect, paint); diff --git a/lib/widgets/common/grid/header.dart b/lib/widgets/common/grid/header.dart index 732fa5c18..18ba54ec6 100644 --- a/lib/widgets/common/grid/header.dart +++ b/lib/widgets/common/grid/header.dart @@ -125,7 +125,9 @@ class SectionHeader extends StatelessWidget { bool hasLeading = false, bool hasTrailing = false, }) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); + final leadingFontSize = leadingSize.height; + final textScaleFactor = textScaler.scale(leadingFontSize) / leadingFontSize; final maxContentWidth = maxWidth - (SectionHeader.padding.horizontal + SectionHeader.margin.horizontal); final paragraph = RenderParagraph( TextSpan( @@ -146,7 +148,7 @@ class SectionHeader extends StatelessWidget { ], ), textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, )..layout(BoxConstraints(maxWidth: maxContentWidth), parentUsesSize: true); final height = paragraph.getMaxIntrinsicHeight(maxContentWidth); paragraph.dispose(); @@ -239,16 +241,25 @@ class _SectionSelectingLeading extends StatelessWidget { data: TooltipTheme.of(context).copyWith( preferBelow: false, ), - child: IconButton( - iconSize: 26, - padding: const EdgeInsetsDirectional.only(end: 6, bottom: 4), - onPressed: onPressed, - tooltip: isSelected ? context.l10n.collectionDeselectSectionTooltip : context.l10n.collectionSelectSectionTooltip, - constraints: BoxConstraints( - minHeight: SectionHeader.leadingSize.height, - minWidth: SectionHeader.leadingSize.width, + child: Padding( + padding: const EdgeInsetsDirectional.only(end: 8, bottom: 6), + child: Theme( + data: Theme.of(context).copyWith( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: IconButton( + iconSize: 26, + visualDensity: const VisualDensity(horizontal: VisualDensity.minimumDensity, vertical: VisualDensity.minimumDensity), + padding: const EdgeInsets.symmetric(horizontal: 7), + onPressed: onPressed, + tooltip: isSelected ? context.l10n.collectionDeselectSectionTooltip : context.l10n.collectionSelectSectionTooltip, + constraints: BoxConstraints( + minHeight: SectionHeader.leadingSize.height, + minWidth: SectionHeader.leadingSize.width, + ), + icon: Icon(isSelected ? AIcons.selected : AIcons.unselected), + ), ), - icon: Icon(isSelected ? AIcons.selected : AIcons.unselected), ), ), ); diff --git a/lib/widgets/common/grid/overlay.dart b/lib/widgets/common/grid/overlay.dart index fe7515494..f50b1a11c 100644 --- a/lib/widgets/common/grid/overlay.dart +++ b/lib/widgets/common/grid/overlay.dart @@ -32,7 +32,7 @@ class GridItemSelectionOverlay extends StatelessWidget { alignment: AlignmentDirectional.topEnd, padding: padding, decoration: BoxDecoration( - color: isSelected ? Theme.of(context).colorScheme.secondary.withOpacity(.6) : Colors.transparent, + color: isSelected ? Theme.of(context).colorScheme.primary.withOpacity(.6) : Colors.transparent, borderRadius: borderRadius, ), duration: duration, diff --git a/lib/widgets/common/grid/sections/mosaic/scale_overlay.dart b/lib/widgets/common/grid/sections/mosaic/scale_overlay.dart index c5df7da96..050995676 100644 --- a/lib/widgets/common/grid/sections/mosaic/scale_overlay.dart +++ b/lib/widgets/common/grid/sections/mosaic/scale_overlay.dart @@ -51,7 +51,7 @@ class MosaicScaleOverlay extends StatelessWidget { alignment: Alignment.center, children: [ _buildBar(extentMax, colorScheme.onPrimary.withOpacity(.1)), - _buildBar(scaledSize.width, colorScheme.secondary), + _buildBar(scaledSize.width, colorScheme.primary), ], ), ), diff --git a/lib/widgets/common/grid/theme.dart b/lib/widgets/common/grid/theme.dart index 53487f19a..134308a0b 100644 --- a/lib/widgets/common/grid/theme.dart +++ b/lib/widgets/common/grid/theme.dart @@ -31,7 +31,7 @@ class GridTheme extends StatelessWidget { final margin = OverlayIcon.defaultMargin.vertical; var iconSize = min(24.0, ((extent - margin) / 5).floorToDouble() - margin); final fontSize = (iconSize * .7).floorToDouble(); - iconSize *= mq.textScaleFactor; + iconSize = mq.textScaler.scale(iconSize); final highlightBorderWidth = extent * .1; final interactiveDimension = min(iconSize * 2, kMinInteractiveDimension); return GridThemeData( diff --git a/lib/widgets/common/identity/aves_app_bar.dart b/lib/widgets/common/identity/aves_app_bar.dart index 0629d5c24..01664c414 100644 --- a/lib/widgets/common/identity/aves_app_bar.dart +++ b/lib/widgets/common/identity/aves_app_bar.dart @@ -32,7 +32,9 @@ class AvesAppBar extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + final textScaler = MediaQuery.textScalerOf(context); final useTvLayout = settings.useTvLayout; return SliverPersistentHeader( floating: !useTvLayout, @@ -45,54 +47,66 @@ class AvesAppBar extends StatelessWidget { child: AvesFloatingBar( builder: (context, backgroundColor, child) => Material( color: backgroundColor, - child: child, + child: InkWell( + // absorb taps while providing visual feedback + onTap: () {}, + onLongPress: () {}, + child: child, + ), ), - child: Column( - children: [ - SizedBox( - height: kToolbarHeight * textScaleFactor, - child: Row( - children: [ - leading != null - ? Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), - child: Hero( - tag: leadingHeroTag, - flightShuttleBuilder: _flightShuttleBuilder, - transitionOnUserGestures: true, - child: FontSizeIconTheme( - child: leading!, + child: Theme( + data: theme.copyWith( + colorScheme: colorScheme.copyWith( + onSurfaceVariant: colorScheme.onSurface, + ), + ), + child: Column( + children: [ + SizedBox( + height: textScaler.scale(kToolbarHeight), + child: Row( + children: [ + leading != null + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Hero( + tag: leadingHeroTag, + flightShuttleBuilder: _flightShuttleBuilder, + transitionOnUserGestures: true, + child: FontSizeIconTheme( + child: leading!, + ), ), - ), - ) - : const SizedBox(width: 16), - Expanded( - child: DefaultTextStyle( - style: Theme.of(context).appBarTheme.titleTextStyle!, - child: Hero( - tag: titleHeroTag, - flightShuttleBuilder: _flightShuttleBuilder, - transitionOnUserGestures: true, - child: AnimatedSwitcher( - duration: context.read().iconAnimation, - child: FontSizeIconTheme( - child: Row( - key: ValueKey(transitionKey), - children: [ - Expanded(child: title), - ...actions, - ], + ) + : const SizedBox(width: 16), + Expanded( + child: DefaultTextStyle( + style: theme.appBarTheme.titleTextStyle!, + child: Hero( + tag: titleHeroTag, + flightShuttleBuilder: _flightShuttleBuilder, + transitionOnUserGestures: true, + child: AnimatedSwitcher( + duration: context.read().iconAnimation, + child: FontSizeIconTheme( + child: Row( + key: ValueKey(transitionKey), + children: [ + Expanded(child: title), + ...actions, + ], + ), ), ), ), ), ), - ), - ], + ], + ), ), - ), - if (bottom != null) bottom!, - ], + if (bottom != null) bottom!, + ], + ), ), ), ), @@ -213,7 +227,7 @@ class _AvesFloatingBarState extends State with RouteAware { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final backgroundColor = theme.appBarTheme.backgroundColor!; + final backgroundColor = theme.appBarTheme.backgroundColor ?? theme.colorScheme.surface; return ValueListenableBuilder( valueListenable: _isBlurAllowedNotifier, builder: (context, isBlurAllowed, child) { diff --git a/lib/widgets/common/identity/aves_donut.dart b/lib/widgets/common/identity/aves_donut.dart index ab587a730..50c967356 100644 --- a/lib/widgets/common/identity/aves_donut.dart +++ b/lib/widgets/common/identity/aves_donut.dart @@ -4,6 +4,7 @@ import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; @@ -85,8 +86,8 @@ class _AvesDonutState extends State with AutomaticKeepAliveClientMixi ), ]; - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final minWidth = avesDonutMinWidth * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final minWidth = textScaler.scale(avesDonutMinWidth); final availableWidth = constraints.maxWidth; final dim = max(minWidth, availableWidth / (availableWidth > 4 * minWidth ? 4 : (availableWidth > 2 * minWidth ? 2 : 1))); @@ -94,7 +95,16 @@ class _AvesDonutState extends State with AutomaticKeepAliveClientMixi width: dim, height: dim, child: Stack( + alignment: Alignment.center, children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(dim)), + child: Container( + width: dim * .7, + height: dim * .7, + color: Themes.secondLayerColor(context), + ), + ), charts.PieChart( series, animate: context.select((v) => v.accessibilityAnimations.animate), @@ -145,7 +155,7 @@ class _AvesDonutState extends State with AutomaticKeepAliveClientMixi Text( formatValue(d.value), style: TextStyle( - color: Theme.of(context).textTheme.bodySmall!.color, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(width: 4), diff --git a/lib/widgets/common/identity/aves_expansion_tile.dart b/lib/widgets/common/identity/aves_expansion_tile.dart index 994d89ac3..b8ef518fb 100644 --- a/lib/widgets/common/identity/aves_expansion_tile.dart +++ b/lib/widgets/common/identity/aves_expansion_tile.dart @@ -46,6 +46,7 @@ class AvesExpansionTile extends StatelessWidget { final animationDuration = context.select((v) => v.expansionTileAnimation); final theme = Theme.of(context); + final colorScheme = theme.colorScheme; return ExpansionTileCard( // key is expected by test driver key: Key('tilecard-$value'), @@ -55,9 +56,8 @@ class AvesExpansionTile extends StatelessWidget { expandable: enabled, initiallyExpanded: initiallyExpanded, finalPadding: const EdgeInsets.symmetric(vertical: 6.0), - baseColor: theme.scaffoldBackgroundColor, - expandedColor: theme.canvasColor, - expandedTextColor: theme.colorScheme.onBackground, + baseColor: theme.colorScheme.background, + expandedTextColor: colorScheme.onBackground, duration: animationDuration, shadowColor: theme.shadowColor, child: Column( diff --git a/lib/widgets/common/identity/aves_filter_chip.dart b/lib/widgets/common/identity/aves_filter_chip.dart index 601aaba16..59ddfb083 100644 --- a/lib/widgets/common/identity/aves_filter_chip.dart +++ b/lib/widgets/common/identity/aves_filter_chip.dart @@ -232,7 +232,7 @@ class _AvesFilterChipState extends State { @override Widget build(BuildContext context) { final decoration = widget.decoration; - final chipBackground = Theme.of(context).scaffoldBackgroundColor; + final chipBackground = Theme.of(context).colorScheme.background; final onTap = widget.onTap != null ? () { @@ -256,16 +256,21 @@ class _AvesFilterChipState extends State { Widget? content; if (widget.showText) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final iconSize = AvesFilterChip.iconSize * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final iconSize = textScaler.scale(AvesFilterChip.iconSize); final leading = widget.leadingOverride ?? filter.iconBuilder(context, iconSize, showGenericIcon: widget.showGenericIcon); final trailing = onRemove != null - ? IconButton( - icon: Icon(AIcons.clear, size: iconSize), - padding: EdgeInsets.zero, - splashRadius: IconTheme.of(context).size, - constraints: const BoxConstraints(), - onPressed: onRemove, + ? Theme( + data: Theme.of(context).copyWith( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: IconButton( + icon: Icon(AIcons.clear, size: iconSize), + padding: EdgeInsets.zero, + splashRadius: IconTheme.of(context).size, + constraints: const BoxConstraints(), + onPressed: onRemove, + ), ) : null; @@ -397,7 +402,7 @@ class _AvesFilterChipState extends State { child: Banner( message: banner.toUpperCase(), location: BannerLocation.topStart, - color: Theme.of(context).colorScheme.secondary, + color: Theme.of(context).colorScheme.primary, child: const SizedBox(), ), ), diff --git a/lib/widgets/common/identity/aves_logo.dart b/lib/widgets/common/identity/aves_logo.dart index cd25fe4d5..2273ef3de 100644 --- a/lib/widgets/common/identity/aves_logo.dart +++ b/lib/widgets/common/identity/aves_logo.dart @@ -22,7 +22,7 @@ class AvesLogo extends StatelessWidget { painter: AvesLogoPainter(), ); if (context.select((v) => v.themeColorMode == AvesThemeColorMode.monochrome)) { - final tint = Color.lerp(theme.colorScheme.secondary, Colors.white, .5)!; + final tint = Color.lerp(theme.colorScheme.primary, Colors.white, .5)!; child = ColorFiltered( colorFilter: ColorFilter.mode(tint, BlendMode.modulate), child: ColorFiltered( diff --git a/lib/widgets/common/identity/buttons/captioned_button.dart b/lib/widgets/common/identity/buttons/captioned_button.dart index d697f1eb1..7417cd866 100644 --- a/lib/widgets/common/identity/buttons/captioned_button.dart +++ b/lib/widgets/common/identity/buttons/captioned_button.dart @@ -41,7 +41,7 @@ class CaptionedButton extends StatefulWidget { final paragraph = RenderParagraph( TextSpan(text: text, style: CaptionedButtonText.textStyle(context)), textDirection: TextDirection.ltr, - textScaleFactor: MediaQuery.textScaleFactorOf(context), + textScaler: MediaQuery.textScalerOf(context), maxLines: CaptionedButtonText.maxLines, )..layout(const BoxConstraints(), parentUsesSize: true); height += paragraph.getMaxIntrinsicHeight(width) + padding.vertical; diff --git a/lib/widgets/common/identity/buttons/outlined_button.dart b/lib/widgets/common/identity/buttons/outlined_button.dart index 9b3ecc2f8..97b715280 100644 --- a/lib/widgets/common/identity/buttons/outlined_button.dart +++ b/lib/widgets/common/identity/buttons/outlined_button.dart @@ -18,11 +18,11 @@ class AvesOutlinedButton extends StatelessWidget { final style = ButtonStyle( side: MaterialStateProperty.resolveWith((states) { return BorderSide( - color: states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.secondary, + color: states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.primary, ); }), foregroundColor: MaterialStateProperty.resolveWith((states) { - return states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.onSecondary; + return states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.onPrimary; }), ); return icon != null diff --git a/lib/widgets/common/identity/buttons/overlay_button.dart b/lib/widgets/common/identity/buttons/overlay_button.dart index ce1aeeffd..0485cce4c 100644 --- a/lib/widgets/common/identity/buttons/overlay_button.dart +++ b/lib/widgets/common/identity/buttons/overlay_button.dart @@ -58,57 +58,66 @@ class _OverlayButtonState extends State { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; final borderRadius = widget.borderRadius; final blurred = settings.enableBlurEffect; final overlayBackground = Themes.overlayBackgroundColor( - brightness: Theme.of(context).brightness, + brightness: colorScheme.brightness, blurred: blurred, ); - return ScaleTransition( - scale: widget.scale, - child: ValueListenableBuilder( - valueListenable: _focusedNotifier, - builder: (context, focused, child) { - final border = AvesBorder.border( - context, - width: AvesBorder.curvedBorderWidth(context) * (focused ? 3 : 1), - ); - return borderRadius != null - ? BlurredRRect( - enabled: blurred, - borderRadius: borderRadius, - child: Material( - type: MaterialType.button, + return Theme( + data: theme.copyWith( + colorScheme: colorScheme.copyWith( + onSurfaceVariant: colorScheme.onSurface, + ), + ), + child: ScaleTransition( + scale: widget.scale, + child: ValueListenableBuilder( + valueListenable: _focusedNotifier, + builder: (context, focused, child) { + final border = AvesBorder.border( + context, + width: AvesBorder.curvedBorderWidth(context) * (focused ? 3 : 1), + ); + return borderRadius != null + ? BlurredRRect( + enabled: blurred, borderRadius: borderRadius, - color: overlayBackground, - child: AnimatedContainer( - foregroundDecoration: BoxDecoration( - border: border, - borderRadius: borderRadius, + child: Material( + type: MaterialType.button, + borderRadius: borderRadius, + color: overlayBackground, + child: AnimatedContainer( + foregroundDecoration: BoxDecoration( + border: border, + borderRadius: borderRadius, + ), + duration: const Duration(milliseconds: 200), + child: widget.child, ), - duration: const Duration(milliseconds: 200), - child: widget.child, ), - ), - ) - : BlurredOval( - enabled: blurred, - child: Material( - type: MaterialType.circle, - color: overlayBackground, - child: AnimatedContainer( - foregroundDecoration: BoxDecoration( - border: border, - shape: BoxShape.circle, + ) + : BlurredOval( + enabled: blurred, + child: Material( + type: MaterialType.circle, + color: overlayBackground, + child: AnimatedContainer( + foregroundDecoration: BoxDecoration( + border: border, + shape: BoxShape.circle, + ), + duration: const Duration(milliseconds: 200), + child: widget.child, ), - duration: const Duration(milliseconds: 200), - child: widget.child, ), - ), - ); - }, + ); + }, + ), ), ); } diff --git a/lib/widgets/common/identity/empty.dart b/lib/widgets/common/identity/empty.dart index 0d617e9ea..dc3a074b3 100644 --- a/lib/widgets/common/identity/empty.dart +++ b/lib/widgets/common/identity/empty.dart @@ -22,7 +22,7 @@ class EmptyContent extends StatelessWidget { @override Widget build(BuildContext context) { - final color = Theme.of(context).colorScheme.secondary.withOpacity(.5); + final color = Theme.of(context).colorScheme.primary.withOpacity(.5); return Padding( padding: safeBottom ? EdgeInsets.only( diff --git a/lib/widgets/common/identity/highlight_title.dart b/lib/widgets/common/identity/highlight_title.dart index 44984ffa9..69b6bba65 100644 --- a/lib/widgets/common/identity/highlight_title.dart +++ b/lib/widgets/common/identity/highlight_title.dart @@ -61,7 +61,7 @@ class HighlightTitle extends StatelessWidget { style: style, ), ], - outlineColor: Theme.of(context).scaffoldBackgroundColor, + outlineColor: Theme.of(context).colorScheme.background, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, diff --git a/lib/widgets/common/map/attribution.dart b/lib/widgets/common/map/attribution.dart index e025d64ea..e050d8a99 100644 --- a/lib/widgets/common/map/attribution.dart +++ b/lib/widgets/common/map/attribution.dart @@ -33,7 +33,7 @@ class Attribution extends StatelessWidget { data: data, selectable: true, styleSheet: MarkdownStyleSheet( - a: TextStyle(color: theme.colorScheme.secondary), + a: TextStyle(color: theme.colorScheme.primary), p: theme.textTheme.bodySmall!.merge(const TextStyle(fontSize: InfoRowGroup.fontSize)), ), onTapLink: (text, href, title) => AvesApp.launchUrl(href), diff --git a/lib/widgets/common/map/buttons/button.dart b/lib/widgets/common/map/buttons/button.dart index 67416d296..f7f383522 100644 --- a/lib/widgets/common/map/buttons/button.dart +++ b/lib/widgets/common/map/buttons/button.dart @@ -22,32 +22,42 @@ class MapOverlayButton extends StatelessWidget { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; final blurred = settings.enableBlurEffect; - return Selector>( - selector: (context, v) => v.scale, - builder: (context, scale, child) => ScaleTransition( - scale: scale, - child: child, + + return Theme( + data: theme.copyWith( + colorScheme: colorScheme.copyWith( + onSurfaceVariant: colorScheme.onSurface, + ), ), - child: BlurredOval( - enabled: blurred, - child: Material( - type: MaterialType.circle, - color: Themes.overlayBackgroundColor(brightness: Theme.of(context).brightness, blurred: blurred), - child: Ink( - decoration: BoxDecoration( - border: AvesBorder.border(context), - shape: BoxShape.circle, - ), - child: Selector( - selector: (context, v) => v.visualDensity, - builder: (context, visualDensity, child) => IconButton( - key: buttonKey, - iconSize: 20, - visualDensity: visualDensity, - icon: icon, - onPressed: onPressed, - tooltip: tooltip, + child: Selector>( + selector: (context, v) => v.scale, + builder: (context, scale, child) => ScaleTransition( + scale: scale, + child: child, + ), + child: BlurredOval( + enabled: blurred, + child: Material( + type: MaterialType.circle, + color: Themes.overlayBackgroundColor(brightness: Theme.of(context).brightness, blurred: blurred), + child: Ink( + decoration: BoxDecoration( + border: AvesBorder.border(context), + shape: BoxShape.circle, + ), + child: Selector( + selector: (context, v) => v.visualDensity, + builder: (context, visualDensity, child) => IconButton( + key: buttonKey, + iconSize: 20, + visualDensity: visualDensity, + icon: icon, + onPressed: onPressed, + tooltip: tooltip, + ), ), ), ), diff --git a/lib/widgets/common/map/buttons/coordinate_filter.dart b/lib/widgets/common/map/buttons/coordinate_filter.dart index 4fe53ea32..938abb715 100644 --- a/lib/widgets/common/map/buttons/coordinate_filter.dart +++ b/lib/widgets/common/map/buttons/coordinate_filter.dart @@ -62,7 +62,9 @@ class _OverlayCoordinateFilterChipState extends State { hintStyle: theme.inputDecorationTheme.hintStyle, ), textInputAction: TextInputAction.search, - style: theme.textTheme.titleLarge, + style: Themes.searchFieldStyle(context), onSubmitted: (_) => widget.delegate.showResults(context), ), ), diff --git a/lib/widgets/common/search/route.dart b/lib/widgets/common/search/route.dart index 93bf133f0..8b5d15452 100644 --- a/lib/widgets/common/search/route.dart +++ b/lib/widgets/common/search/route.dart @@ -50,7 +50,7 @@ class SearchPageRoute extends PageRoute { @override Animation createAnimation() { - final animation = super.createAnimation(); + final Animation animation = super.createAnimation(); delegate.proxyAnimation.parent = animation; return animation; } diff --git a/lib/widgets/common/thumbnail/decorated.dart b/lib/widgets/common/thumbnail/decorated.dart index 6a1616d25..34ddd3709 100644 --- a/lib/widgets/common/thumbnail/decorated.dart +++ b/lib/widgets/common/thumbnail/decorated.dart @@ -14,7 +14,7 @@ class DecoratedThumbnail extends StatelessWidget { final bool isMosaic, selectable, highlightable; final Object? Function()? heroTagger; - static final Color borderColor = Colors.grey.shade700; + static Color borderColor(BuildContext context) => Theme.of(context).dividerColor; static double borderWidth(BuildContext context) => AvesBorder.straightBorderWidth(context); @@ -75,7 +75,7 @@ class DecoratedThumbnail extends StatelessWidget { // so we use `foregroundDecoration` instead foregroundDecoration: BoxDecoration( border: Border.fromBorderSide(BorderSide( - color: borderColor, + color: borderColor(context), width: borderWidth(context), )), ), diff --git a/lib/widgets/common/thumbnail/error.dart b/lib/widgets/common/thumbnail/error.dart index 0ad1eb85f..01320bf54 100644 --- a/lib/widgets/common/thumbnail/error.dart +++ b/lib/widgets/common/thumbnail/error.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/utils/mime_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -36,7 +37,7 @@ class _ErrorThumbnailState extends State { @override Widget build(BuildContext context) { - const color = Colors.blueGrey; + final color = Themes.backgroundTextColor(context); return FutureBuilder( future: _exists, builder: (context, snapshot) { @@ -65,7 +66,7 @@ class _ErrorThumbnailState extends State { } return Container( alignment: Alignment.center, - color: Colors.black, + color: Theme.of(context).colorScheme.background, width: extent, height: extent, child: child, diff --git a/lib/widgets/common/thumbnail/overlay.dart b/lib/widgets/common/thumbnail/overlay.dart index 4c2732778..abbe77111 100644 --- a/lib/widgets/common/thumbnail/overlay.dart +++ b/lib/widgets/common/thumbnail/overlay.dart @@ -67,7 +67,7 @@ class _ThumbnailHighlightOverlayState extends State { builder: (context) => Container( decoration: BoxDecoration( border: Border.fromBorderSide(BorderSide( - color: Theme.of(context).colorScheme.secondary, + color: Theme.of(context).colorScheme.primary, width: context.select((t) => t.highlightBorderWidth), )), ), diff --git a/lib/widgets/debug/app_debug_page.dart b/lib/widgets/debug/app_debug_page.dart index 58869c68f..bd0ab2e00 100644 --- a/lib/widgets/debug/app_debug_page.dart +++ b/lib/widgets/debug/app_debug_page.dart @@ -17,6 +17,7 @@ import 'package:aves/widgets/debug/android_codecs.dart'; import 'package:aves/widgets/debug/android_dirs.dart'; import 'package:aves/widgets/debug/app_debug_action.dart'; import 'package:aves/widgets/debug/cache.dart'; +import 'package:aves/widgets/debug/colors.dart'; import 'package:aves/widgets/debug/database.dart'; import 'package:aves/widgets/debug/general.dart'; import 'package:aves/widgets/debug/media_store_scan_dialog.dart'; @@ -72,6 +73,7 @@ class AppDebugPage extends StatelessWidget { DebugAndroidCodecSection(), DebugAndroidDirSection(), DebugCacheSection(), + DebugColorSection(), DebugAppDatabaseSection(), DebugErrorReportingSection(), DebugSettingsSection(), diff --git a/lib/widgets/debug/colors.dart b/lib/widgets/debug/colors.dart new file mode 100644 index 000000000..f0a6f3471 --- /dev/null +++ b/lib/widgets/debug/colors.dart @@ -0,0 +1,77 @@ +import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; +import 'package:flutter/material.dart'; + +class DebugColorSection extends StatefulWidget { + const DebugColorSection({super.key}); + + @override + State createState() => _DebugColorSectionState(); +} + +class _DebugColorSectionState extends State with AutomaticKeepAliveClientMixin { + @override + Widget build(BuildContext context) { + super.build(context); + + final scheme = Theme.of(context).colorScheme; + final List<(String, Color)> colors = [ + ('primary', scheme.primary), + ('onPrimary', scheme.onPrimary), + ('primaryContainer', scheme.primaryContainer), + ('onPrimaryContainer', scheme.onPrimaryContainer), + ('secondary', scheme.secondary), + ('onSecondary', scheme.onSecondary), + ('secondaryContainer', scheme.secondaryContainer), + ('onSecondaryContainer', scheme.onSecondaryContainer), + ('tertiary', scheme.tertiary), + ('onTertiary', scheme.onTertiary), + ('tertiaryContainer', scheme.tertiaryContainer), + ('onTertiaryContainer', scheme.onTertiaryContainer), + ('error', scheme.error), + ('onError', scheme.onError), + ('errorContainer', scheme.errorContainer), + ('onErrorContainer', scheme.onErrorContainer), + ('background', scheme.background), + ('onBackground', scheme.onBackground), + ('surface', scheme.surface), + ('onSurface', scheme.onSurface), + ('surfaceVariant', scheme.surfaceVariant), + ('onSurfaceVariant', scheme.onSurfaceVariant), + ('outline', scheme.outline), + ('outlineVariant', scheme.outlineVariant), + ('shadow', scheme.shadow), + ('scrim', scheme.scrim), + ('inverseSurface', scheme.inverseSurface), + ('onInverseSurface', scheme.onInverseSurface), + ('inversePrimary', scheme.inversePrimary), + ('surfaceTint', scheme.surfaceTint), + ]; + return AvesExpansionTile( + title: 'Colors', + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Column( + children: colors.map((kv) { + final (text, color) = kv; + return Row( + children: [ + Text(text), + const Spacer(), + Container( + width: 20, + height: 20, + color: color, + ), + ], + ); + }).toList(), + ), + ), + ], + ); + } + + @override + bool get wantKeepAlive => true; +} diff --git a/lib/widgets/dialogs/aves_dialog.dart b/lib/widgets/dialogs/aves_dialog.dart index 8127a61d1..04d68cd9e 100644 --- a/lib/widgets/dialogs/aves_dialog.dart +++ b/lib/widgets/dialogs/aves_dialog.dart @@ -1,5 +1,3 @@ -import 'dart:ui'; - import 'package:aves/model/settings/settings.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; @@ -144,10 +142,6 @@ class DialogTitle extends StatelessWidget { decoration: AvesDialog.contentDecoration(context), child: Text( title, - style: const TextStyle( - fontWeight: FontWeight.normal, - fontFeatures: [FontFeature.enable('smcp')], - ), textAlign: TextAlign.center, ), ); diff --git a/lib/widgets/dialogs/convert_entry_dialog.dart b/lib/widgets/dialogs/convert_entry_dialog.dart index 1721dda61..10fd78821 100644 --- a/lib/widgets/dialogs/convert_entry_dialog.dart +++ b/lib/widgets/dialogs/convert_entry_dialog.dart @@ -97,14 +97,14 @@ class _ConvertEntryDialogState extends State { Widget build(BuildContext context) { final l10n = context.l10n; const contentHorizontalPadding = EdgeInsets.symmetric(horizontal: AvesDialog.defaultHorizontalContentPadding); - final theme = Theme.of(context); - final trailingStyle = TextStyle(color: theme.textTheme.bodySmall!.color); - final trailingChangeShadowColor = theme.colorScheme.onPrimary; + final colorScheme = Theme.of(context).colorScheme; + final trailingStyle = TextStyle(color: colorScheme.onSurfaceVariant); + final trailingChangeShadowColor = colorScheme.onPrimary; // used by the drop down to match input decoration final textFieldDecorationBorder = Border( bottom: BorderSide( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.38), //Color(0xFFBDBDBD), + color: colorScheme.onSurface.withOpacity(0.38), //Color(0xFFBDBDBD), width: 1.0, ), ); diff --git a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart index fd4b72d3f..e2eb254f9 100644 --- a/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_date_dialog.dart @@ -301,6 +301,7 @@ class _EditEntryDateDialogState extends State { initialDate: _customDateTime, firstDate: DateTime(0), lastDate: DateTime(2100), + cancelText: MaterialLocalizations.of(context).cancelButtonLabel.toUpperCase(), confirmText: context.l10n.nextButtonLabel, ); if (_date == null) return; @@ -308,6 +309,7 @@ class _EditEntryDateDialogState extends State { final _time = await showTimePicker( context: context, initialTime: TimeOfDay.fromDateTime(_customDateTime), + cancelText: MaterialLocalizations.of(context).cancelButtonLabel.toUpperCase(), ); if (_time == null) return; diff --git a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart index 2d6196654..a9fae07d1 100644 --- a/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/edit_location_dialog.dart @@ -281,7 +281,7 @@ class _EditEntryLocationDialogState extends State { return Text( l10n.viewerInfoUnknown, style: TextStyle( - color: Theme.of(context).textTheme.bodySmall!.color, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ); } diff --git a/lib/widgets/dialogs/entry_editors/remove_metadata_dialog.dart b/lib/widgets/dialogs/entry_editors/remove_metadata_dialog.dart index a890abc78..272b9576b 100644 --- a/lib/widgets/dialogs/entry_editors/remove_metadata_dialog.dart +++ b/lib/widgets/dialogs/entry_editors/remove_metadata_dialog.dart @@ -113,7 +113,7 @@ class _RemoveEntryMetadataDialogState extends State { ), ), ], - outlineColor: Theme.of(context).scaffoldBackgroundColor, + outlineColor: Theme.of(context).colorScheme.background, ); if (context.select((v) => v.themeColorMode == AvesThemeColorMode.polychrome)) { final colors = context.watch(); diff --git a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart index ffd8556ce..6e55b82c2 100644 --- a/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart +++ b/lib/widgets/dialogs/entry_editors/rename_entry_set_page.dart @@ -60,8 +60,8 @@ class _RenameEntrySetPageState extends State { @override Widget build(BuildContext context) { final l10n = context.l10n; - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final effectiveThumbnailExtent = max(thumbnailExtent, thumbnailExtent * textScaleFactor); + final textScaler = MediaQuery.textScalerOf(context); + final effectiveThumbnailExtent = max(thumbnailExtent, textScaler.scale(thumbnailExtent)); return AvesScaffold( appBar: AppBar( title: Text(l10n.renameEntrySetPageTitle), @@ -146,7 +146,7 @@ class _RenameEntrySetPageState extends State { children: [ Text( sourceName, - style: TextStyle(color: Theme.of(context).textTheme.bodySmall!.color), + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), softWrap: false, overflow: TextOverflow.fade, maxLines: 1, diff --git a/lib/widgets/dialogs/entry_editors/tag_editor_page.dart b/lib/widgets/dialogs/entry_editors/tag_editor_page.dart index 2c280f807..4f3892aa5 100644 --- a/lib/widgets/dialogs/entry_editors/tag_editor_page.dart +++ b/lib/widgets/dialogs/entry_editors/tag_editor_page.dart @@ -6,6 +6,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/expandable_filter_row.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; @@ -36,7 +37,6 @@ class _TagEditorPageState extends State { late final List _topTags; final List _userAddedFilters = []; - static const Color untaggedColor = Colors.blueGrey; static final List _placeholders = [ PlaceholderFilter.country, PlaceholderFilter.state, @@ -70,10 +70,14 @@ class _TagEditorPageState extends State { }); List> sortedTags = _sortCurrentTags(entryCountByTag); - return WillPopScope( - onWillPop: () async { - if (!_isModified) return true; + final untaggedColor = Themes.backgroundTextColor(context); + return PopScope( + canPop: !_isModified, + onPopInvoked: (didPop) async { + if (didPop) return; + + final NavigatorState navigator = Navigator.of(context); final confirmed = await showDialog( context: context, builder: (context) => AvesDialog( @@ -89,7 +93,9 @@ class _TagEditorPageState extends State { routeSettings: const RouteSettings(name: AvesDialog.warningRouteName), ) ?? false; - return confirmed; + if (confirmed) { + navigator.pop(); + } }, child: AvesScaffold( appBar: AppBar( @@ -105,6 +111,7 @@ class _TagEditorPageState extends State { onPressed: () => Navigator.maybeOf(context)?.pop(filtersByEntry), tooltip: l10n.saveTooltip, ), + const SizedBox(width: 16), ], ), body: SafeArea( @@ -176,7 +183,7 @@ class _TagEditorPageState extends State { const SizedBox(width: 8), Text( l10n.filterNoTagLabel, - style: const TextStyle(color: untaggedColor), + style: TextStyle(color: untaggedColor), ), ], ), diff --git a/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart b/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart index 4ec1139ad..213c177f5 100644 --- a/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/cover_selection_dialog.dart @@ -57,8 +57,7 @@ class _CoverSelectionDialogState extends State { static const double appPickerExtent = 32; double tabBarHeight(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - return 64 * max(1, textScaleFactor); + return MediaQuery.textScalerOf(context).clamp(minScaleFactor: 1).scale(64); } static const double tabIndicatorWeight = 2; @@ -401,8 +400,8 @@ class _CoverSelectionDialogState extends State { }) { // cannot use `IconTheme` over `TabBar` to change size, // because `TabBar` does so internally - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final iconSize = IconTheme.of(context).size! * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final iconSize = textScaler.scale(IconTheme.of(context).size!); return Tab( key: key, height: tabBarHeight(context), @@ -440,7 +439,7 @@ class _CoverSelectionDialogState extends State { final paragraph = RenderParagraph( TextSpan(text: _optionLines, style: Theme.of(context).textTheme.titleMedium!), textDirection: TextDirection.ltr, - textScaleFactor: MediaQuery.textScaleFactorOf(context), + textScaler: MediaQuery.textScalerOf(context), )..layout(const BoxConstraints(), parentUsesSize: true); final textWidth = paragraph.getMaxIntrinsicWidth(double.infinity); paragraph.dispose(); diff --git a/lib/widgets/dialogs/filter_editors/pattern_dialog.dart b/lib/widgets/dialogs/filter_editors/pattern_dialog.dart index d027af570..4518c75db 100644 --- a/lib/widgets/dialogs/filter_editors/pattern_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/pattern_dialog.dart @@ -35,7 +35,7 @@ class _PatternDialogState extends State { dimension: MediaQuery.sizeOf(context).shortestSide / 2, child: PatternLock( relativePadding: .4, - selectedColor: colorScheme.secondary, + selectedColor: colorScheme.primary, notSelectedColor: colorScheme.onBackground, pointRadius: 8, fillPoints: true, diff --git a/lib/widgets/dialogs/filter_editors/pin_dialog.dart b/lib/widgets/dialogs/filter_editors/pin_dialog.dart index 9bfdcc0cc..04b9d206b 100644 --- a/lib/widgets/dialogs/filter_editors/pin_dialog.dart +++ b/lib/widgets/dialogs/filter_editors/pin_dialog.dart @@ -52,8 +52,8 @@ class _PinDialogState extends State { pinTheme: PinTheme( activeColor: colorScheme.onBackground, inactiveColor: colorScheme.onBackground, - selectedColor: colorScheme.secondary, - selectedFillColor: colorScheme.secondary, + selectedColor: colorScheme.primary, + selectedFillColor: colorScheme.primary, borderRadius: BorderRadius.circular(8), shape: PinCodeFieldShape.box, ), diff --git a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart index cce0f670f..82f928955 100644 --- a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart @@ -220,8 +220,8 @@ class _LocationInfo extends StatelessWidget { } static double getIconSize(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - return 16 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + return textScaler.scale(16); } } @@ -261,7 +261,7 @@ class _AddressRowState extends State<_AddressRow> { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -274,7 +274,7 @@ class _AddressRowState extends State<_AddressRow> { // addresses can include non-latin scripts with inconsistent line height, // which is especially an issue for relayout/painting of heavy Google map, // so we give extra height to give breathing room to the text and stabilize layout - height: Theme.of(context).textTheme.bodyMedium!.fontSize! * textScaleFactor * 2, + height: textScaler.scale(Theme.of(context).textTheme.bodyMedium!.fontSize!) * 2, child: ValueListenableBuilder( valueListenable: _addressLineNotifier, builder: (context, addressLine, child) { diff --git a/lib/widgets/dialogs/tile_view_dialog.dart b/lib/widgets/dialogs/tile_view_dialog.dart index 2cf1de077..b0111b67c 100644 --- a/lib/widgets/dialogs/tile_view_dialog.dart +++ b/lib/widgets/dialogs/tile_view_dialog.dart @@ -200,8 +200,8 @@ class _TileViewDialogState extends State> with dropdownColor: Themes.thirdLayerColor(context), ); - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final iconSize = IconTheme.of(context).size! * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final iconSize = textScaler.scale(IconTheme.of(context).size!); final isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait; final child = isPortrait ? Column( diff --git a/lib/widgets/editor/control_panel.dart b/lib/widgets/editor/control_panel.dart index 2a3dc2711..531fd2848 100644 --- a/lib/widgets/editor/control_panel.dart +++ b/lib/widgets/editor/control_panel.dart @@ -8,7 +8,6 @@ import 'package:aves/widgets/editor/transform/control_panel.dart'; import 'package:aves/widgets/editor/transform/controller.dart'; import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart'; import 'package:aves_model/aves_model.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -29,13 +28,12 @@ class EditorControlPanel extends StatelessWidget { @override Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () { - if (actionNotifier.value != null) { - _cancelAction(context); - return SynchronousFuture(false); - } - return SynchronousFuture(true); + return PopScope( + canPop: actionNotifier.value == null, + onPopInvoked: (didPop) { + if (didPop) return; + + _cancelAction(context); }, child: Padding( padding: const EdgeInsets.all(padding), diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 2f23da3ea..d51281ac8 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -11,6 +11,7 @@ import 'package:aves/model/source/collection_source.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/theme/durations.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/view/view.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/permission_aware.dart'; @@ -292,6 +293,7 @@ abstract class ChipSetActionDelegate with FeedbackMi SearchPageRoute( delegate: CollectionSearchDelegate( searchFieldLabel: context.l10n.searchCollectionFieldHint, + searchFieldStyle: Themes.searchFieldStyle(context), source: context.read(), ), ), diff --git a/lib/widgets/filter_grids/common/app_bar.dart b/lib/widgets/filter_grids/common/app_bar.dart index 1c837456d..c0a610de0 100644 --- a/lib/widgets/filter_grids/common/app_bar.dart +++ b/lib/widgets/filter_grids/common/app_bar.dart @@ -7,6 +7,7 @@ import 'package:aves/model/selection.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/theme/durations.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/view/view.dart'; import 'package:aves/widgets/common/action_controls/togglers/title_search.dart'; import 'package:aves/widgets/common/app_bar/app_bar_subtitle.dart'; @@ -177,13 +178,13 @@ class _FilterGridAppBarState().enabled) { - height += FilterQueryBar.getPreferredHeight(textScaleFactor); + height += FilterQueryBar.getPreferredHeight(textScaler); } return height; } @@ -446,6 +447,7 @@ class _FilterGridAppBarState extends StatelessWidget { this.heroType = HeroType.onTap, }) : thumbnailExtent = thumbnailExtent ?? extent; - static double tileHeight({required double extent, required double textScaleFactor, required bool showText}) { - return extent + infoHeight(extent: extent, textScaleFactor: textScaleFactor, showText: showText); + static double tileHeight({required double extent, required TextScaler textScaler, required bool showText}) { + return extent + infoHeight(extent: extent, textScaler: textScaler, showText: showText); } // info includes title and content details - static double infoHeight({required double extent, required double textScaleFactor, required bool showText}) { + static double infoHeight({required double extent, required TextScaler textScaler, required bool showText}) { if (!showText) return 0; // height can actually be a little larger or smaller, when info includes icons or non-latin scripts // but it's not worth measuring text metrics, as the widget is flexible enough to absorb the difference - return (AvesFilterChip.fontSize + detailFontSize(extent) + 4) * textScaleFactor + AvesFilterChip.decoratedContentVerticalPadding * 2; + return textScaler.scale(AvesFilterChip.fontSize + detailFontSize(extent) + 4) + AvesFilterChip.decoratedContentVerticalPadding * 2; } static Radius radius(double extent) => Radius.circular(min(AvesFilterChip.defaultRadius, extent / 4)); @@ -111,7 +111,7 @@ class CoveredFilterChip extends StatelessWidget { // album filters themselves do not change, but decoration derived from it does chipKey = ValueKey(appInventory.areAppNamesReadyNotifier.value); } - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return AvesFilterChip( key: chipKey, filter: _filter, @@ -123,7 +123,7 @@ class CoveredFilterChip extends StatelessWidget { padding: EdgeInsets.only( bottom: infoHeight( extent: extent, - textScaleFactor: textScaleFactor, + textScaler: textScaler, showText: showText, ), ), @@ -168,7 +168,7 @@ class CoveredFilterChip extends StatelessWidget { ); } - Color _detailColor(BuildContext context) => Theme.of(context).textTheme.bodySmall!.color!; + Color _detailColor(BuildContext context) => Theme.of(context).colorScheme.onSurfaceVariant; Widget _buildDetails(BuildContext context, CollectionSource source, T filter) { final locale = context.l10n.localeName; diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index abc85db03..c6ea9775e 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -324,10 +324,10 @@ class _FilterGridContentState extends State<_FilterG final target = context.read().staggeredAnimationPageTarget; final tileAnimationDelay = context.read().getTileAnimationDelay(target); - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final tileHeight = CoveredFilterChip.tileHeight( extent: thumbnailExtent, - textScaleFactor: textScaleFactor, + textScaler: textScaler, showText: tileLayout != TileLayout.list, ); return GridTheme( @@ -566,13 +566,13 @@ class _FilterScaler extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final (tileSpacing, horizontalPadding) = context.select((v) => (v.spacing, v.horizontalPadding)); final brightness = Theme.of(context).brightness; return GridScaleGestureDetector>( scrollableKey: scrollableKey, tileLayout: tileLayout, - heightForWidth: (width) => CoveredFilterChip.tileHeight(extent: width, textScaleFactor: textScaleFactor, showText: true), + heightForWidth: (width) => CoveredFilterChip.tileHeight(extent: width, textScaler: textScaler, showText: true), gridBuilder: (center, tileSize, child) => CustomPaint( painter: FixedExtentGridPainter( tileLayout: tileLayout, diff --git a/lib/widgets/filter_grids/common/list_details.dart b/lib/widgets/filter_grids/common/list_details.dart index 872fef703..ea43c32ea 100644 --- a/lib/widgets/filter_grids/common/list_details.dart +++ b/lib/widgets/filter_grids/common/list_details.dart @@ -70,9 +70,9 @@ class FilterListDetails extends StatelessWidget { softWrap: false, overflow: detailsTheme.titleMaxLines == 1 ? TextOverflow.fade : TextOverflow.ellipsis, maxLines: detailsTheme.titleMaxLines, - // `textScaleFactor` is applied to font size and icon size at the theme level, + // `textScaler` is applied to font size and icon size at the theme level, // otherwise the leading icon will be low-res scaled up/down - textScaleFactor: 1, + textScaler: TextScaler.noScaling, ), if (!locked) ...[ const SizedBox(height: FilterListDetailsTheme.titleDetailPadding), diff --git a/lib/widgets/filter_grids/common/list_details_theme.dart b/lib/widgets/filter_grids/common/list_details_theme.dart index 80de6ff7b..049f91c73 100644 --- a/lib/widgets/filter_grids/common/list_details_theme.dart +++ b/lib/widgets/filter_grids/common/list_details_theme.dart @@ -30,18 +30,18 @@ class FilterListDetailsTheme extends StatelessWidget { final locale = context.l10n.localeName; final use24hour = mq.alwaysUse24HourFormat; - final textScaleFactor = mq.textScaleFactor; + final textScaler = mq.textScaler; final textTheme = Theme.of(context).textTheme; final titleStyleBase = textTheme.bodyMedium!; - final titleStyle = titleStyleBase.copyWith(fontSize: titleStyleBase.fontSize! * textScaleFactor); + final titleStyle = titleStyleBase.copyWith(fontSize: textScaler.scale(titleStyleBase.fontSize!)); final captionStyle = textTheme.bodySmall!; - final titleIconSize = AvesFilterChip.iconSize * textScaleFactor; + final titleIconSize = textScaler.scale(AvesFilterChip.iconSize); final titleLineHeightParagraph = RenderParagraph( TextSpan(text: 'Fake Title', style: titleStyle), textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, )..layout(const BoxConstraints(), parentUsesSize: true); final titleLineHeight = titleLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); titleLineHeightParagraph.dispose(); @@ -49,7 +49,7 @@ class FilterListDetailsTheme extends StatelessWidget { final captionLineHeightParagraph = RenderParagraph( TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, strutStyle: AStyles.overflowStrut, )..layout(const BoxConstraints(), parentUsesSize: true); final captionLineHeight = captionLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); @@ -81,7 +81,7 @@ class FilterListDetailsTheme extends StatelessWidget { titleIconSize: titleIconSize, captionIconTheme: IconThemeData( color: captionStyle.color, - size: captionStyle.fontSize! * textScaleFactor, + size: textScaler.scale(captionStyle.fontSize!), ), ); }, diff --git a/lib/widgets/filter_grids/common/overlay.dart b/lib/widgets/filter_grids/common/overlay.dart index 2b520944b..c2fb1f0fb 100644 --- a/lib/widgets/filter_grids/common/overlay.dart +++ b/lib/widgets/filter_grids/common/overlay.dart @@ -41,7 +41,7 @@ class _ChipHighlightOverlayState extends State { builder: (context) => Container( decoration: BoxDecoration( border: Border.fromBorderSide(BorderSide( - color: Theme.of(context).colorScheme.secondary, + color: Theme.of(context).colorScheme.primary, width: widget.extent * .1, )), borderRadius: widget.borderRadius, diff --git a/lib/widgets/filter_grids/common/query_bar.dart b/lib/widgets/filter_grids/common/query_bar.dart index a6a09228b..5e4452b61 100644 --- a/lib/widgets/filter_grids/common/query_bar.dart +++ b/lib/widgets/filter_grids/common/query_bar.dart @@ -17,9 +17,9 @@ class FilterQueryBar extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return Container( - height: getPreferredHeight(textScaleFactor), + height: getPreferredHeight(textScaler), alignment: Alignment.topCenter, child: Selector>, bool>( selector: (context, selection) => !selection.isSelecting, @@ -33,5 +33,5 @@ class FilterQueryBar extends StatelessWidget { ); } - static double getPreferredHeight(double textScaleFactor) => QueryBar.getPreferredHeight(textScaleFactor); + static double getPreferredHeight(TextScaler textScaler) => QueryBar.getPreferredHeight(textScaler); } diff --git a/lib/widgets/filter_grids/common/section_header.dart b/lib/widgets/filter_grids/common/section_header.dart index b275f8549..597f0abf9 100644 --- a/lib/widgets/filter_grids/common/section_header.dart +++ b/lib/widgets/filter_grids/common/section_header.dart @@ -23,7 +23,7 @@ class FilterChipSectionHeader extends StatelessWidget { } static double getPreferredHeight(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - return SectionHeader.leadingSize.height * textScaleFactor + SectionHeader.padding.vertical + SectionHeader.margin.vertical; + final textScaler = MediaQuery.textScalerOf(context); + return textScaler.scale(SectionHeader.leadingSize.height) + SectionHeader.padding.vertical + SectionHeader.margin.vertical; } } diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index 5f55824e1..34bbc477c 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -16,6 +16,7 @@ import 'package:aves/services/common/services.dart'; import 'package:aves/services/global_search.dart'; import 'package:aves/services/intent_service.dart'; import 'package:aves/services/widget_service.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/common/basic/scaffold.dart'; @@ -360,6 +361,7 @@ class _HomePageState extends State { return SearchPageRoute( delegate: CollectionSearchDelegate( searchFieldLabel: context.l10n.searchCollectionFieldHint, + searchFieldStyle: Themes.searchFieldStyle(context), source: source, canPop: false, initialQuery: _initialSearchQuery, diff --git a/lib/widgets/map/address_row.dart b/lib/widgets/map/address_row.dart index 87e7db02a..983d7ca06 100644 --- a/lib/widgets/map/address_row.dart +++ b/lib/widgets/map/address_row.dart @@ -49,13 +49,13 @@ class _MapAddressRowState extends State { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); return Container( alignment: AlignmentDirectional.centerStart, // addresses can include non-latin scripts with inconsistent line height, // which is especially an issue for relayout/painting of heavy Google map, // so we give extra height to give breathing room to the text and stabilize layout - height: Theme.of(context).textTheme.bodyMedium!.fontSize! * textScaleFactor * 2, + height: textScaler.scale(Theme.of(context).textTheme.bodyMedium!.fontSize!) * 2, child: ValueListenableBuilder( valueListenable: _addressLineNotifier, builder: (context, addressLine, child) { diff --git a/lib/widgets/map/info_row.dart b/lib/widgets/map/info_row.dart index 2bbb4eb25..2313c4741 100644 --- a/lib/widgets/map/info_row.dart +++ b/lib/widgets/map/info_row.dart @@ -58,7 +58,7 @@ class MapInfoRow extends StatelessWidget { } static double getIconSize(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - return 16 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + return textScaler.scale(16); } } diff --git a/lib/widgets/navigation/drawer/app_drawer.dart b/lib/widgets/navigation/drawer/app_drawer.dart index b499a33fb..e3c94d672 100644 --- a/lib/widgets/navigation/drawer/app_drawer.dart +++ b/lib/widgets/navigation/drawer/app_drawer.dart @@ -82,11 +82,13 @@ class _AppDrawerState extends State { return Drawer( child: ListTileTheme.merge( - selectedColor: Theme.of(context).colorScheme.secondary, + selectedColor: Theme.of(context).colorScheme.primary, + horizontalTitleGap: 20, + visualDensity: VisualDensity.comfortable, child: Selector( selector: (context, mq) => mq.effectiveBottomPadding, builder: (context, mqPaddingBottom, child) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final iconTheme = IconTheme.of(context); return SingleChildScrollView( controller: _scrollController, @@ -95,7 +97,7 @@ class _AppDrawerState extends State { padding: EdgeInsets.only(bottom: mqPaddingBottom), child: IconTheme( data: iconTheme.copyWith( - size: iconTheme.size! * textScaleFactor, + size: textScaler.scale(iconTheme.size!), ), child: Column( children: drawerItems, @@ -118,9 +120,12 @@ class _AppDrawerState extends State { )); } + final drawerButtonStyle = ButtonStyle( + padding: MaterialStateProperty.all(const EdgeInsetsDirectional.only(start: 12, end: 16)), + ); return Container( - padding: const EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), - color: Theme.of(context).colorScheme.secondary, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + color: Theme.of(context).colorScheme.primary, child: SafeArea( bottom: false, child: Column( @@ -132,12 +137,12 @@ class _AppDrawerState extends State { spacing: 16, crossAxisAlignment: WrapCrossAlignment.center, children: [ - const AvesLogo(size: 56), + const AvesLogo(size: 48), Text( context.l10n.appName, style: const TextStyle( color: Colors.white, - fontSize: 44, + fontSize: 38, fontWeight: FontWeight.w300, letterSpacing: 1.0, fontFeatures: [FontFeature.enable('smcp')], @@ -162,6 +167,7 @@ class _AppDrawerState extends State { // key is expected by test driver key: const Key('drawer-about-button'), onPressed: () => goTo(AboutPage.routeName, (_) => const AboutPage()), + style: drawerButtonStyle, icon: const Icon(AIcons.info), label: Text(context.l10n.drawerAboutButton), ), @@ -169,6 +175,7 @@ class _AppDrawerState extends State { // key is expected by test driver key: const Key('drawer-settings-button'), onPressed: () => goTo(SettingsPage.routeName, (_) => const SettingsPage()), + style: drawerButtonStyle, icon: const Icon(AIcons.settings), label: Text(context.l10n.drawerSettingsButton), ), diff --git a/lib/widgets/navigation/drawer/collection_nav_tile.dart b/lib/widgets/navigation/drawer/collection_nav_tile.dart index c3e3afdda..e0a5029f9 100644 --- a/lib/widgets/navigation/drawer/collection_nav_tile.dart +++ b/lib/widgets/navigation/drawer/collection_nav_tile.dart @@ -13,7 +13,6 @@ class CollectionNavTile extends StatelessWidget { final Widget? leading; final Widget title; final Widget? trailing; - final bool dense; final CollectionFilter? filter; final bool Function() isSelected; @@ -22,10 +21,9 @@ class CollectionNavTile extends StatelessWidget { required this.leading, required this.title, this.trailing, - bool? dense, required this.filter, required this.isSelected, - }) : dense = dense ?? false; + }); @override Widget build(BuildContext context) { @@ -49,7 +47,6 @@ class CollectionNavTile extends StatelessWidget { }, ) : null, - dense: dense, onTap: () => _goToCollection(context), selected: context.currentRouteName == CollectionPage.routeName && isSelected(), ), diff --git a/lib/widgets/navigation/drawer/page_nav_tile.dart b/lib/widgets/navigation/drawer/page_nav_tile.dart index 8315f82a8..8636828b8 100644 --- a/lib/widgets/navigation/drawer/page_nav_tile.dart +++ b/lib/widgets/navigation/drawer/page_nav_tile.dart @@ -1,5 +1,6 @@ import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/about/about_page.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/search/page.dart'; @@ -71,6 +72,7 @@ class PageNavTile extends StatelessWidget { return SearchPageRoute( delegate: CollectionSearchDelegate( searchFieldLabel: context.l10n.searchCollectionFieldHint, + searchFieldStyle: Themes.searchFieldStyle(context), source: context.read(), parentCollection: currentCollection?.copyWith(), ), diff --git a/lib/widgets/navigation/drawer/tile.dart b/lib/widgets/navigation/drawer/tile.dart index dee17e807..10b5a7e92 100644 --- a/lib/widgets/navigation/drawer/tile.dart +++ b/lib/widgets/navigation/drawer/tile.dart @@ -15,8 +15,8 @@ class DrawerFilterIcon extends StatelessWidget { @override Widget build(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final iconSize = 24 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final iconSize = textScaler.scale(24); final _filter = filter; if (_filter == null) return Icon(AIcons.allCollection, size: iconSize); diff --git a/lib/widgets/navigation/nav_bar/nav_bar.dart b/lib/widgets/navigation/nav_bar/nav_bar.dart index bd772bd6e..e4c3a9f3f 100644 --- a/lib/widgets/navigation/nav_bar/nav_bar.dart +++ b/lib/widgets/navigation/nav_bar/nav_bar.dart @@ -81,6 +81,7 @@ class _AppBottomNavBarState extends State { .map((item) => BottomNavigationBarItem( icon: item.icon(context), label: item.label(context), + tooltip: item.label(context), )) .toList(), onTap: (index) => _goTo(context, items, index), diff --git a/lib/widgets/navigation/nav_bar/nav_item.dart b/lib/widgets/navigation/nav_bar/nav_item.dart index fbd916396..f617488ff 100644 --- a/lib/widgets/navigation/nav_bar/nav_item.dart +++ b/lib/widgets/navigation/nav_bar/nav_item.dart @@ -22,8 +22,8 @@ class AvesBottomNavItem extends Equatable { return DrawerFilterIcon(filter: filter); } - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final iconSize = 24 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final iconSize = textScaler.scale(24); return Icon(NavigationDisplay.getPageIcon(route), size: iconSize); } diff --git a/lib/widgets/navigation/tv_rail.dart b/lib/widgets/navigation/tv_rail.dart index e1ef726d5..a54799173 100644 --- a/lib/widgets/navigation/tv_rail.dart +++ b/lib/widgets/navigation/tv_rail.dart @@ -121,7 +121,7 @@ class _TvRailState extends State { focusNode: _focusNode, skipTraversal: true, child: NavigationRail( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, + backgroundColor: Theme.of(context).colorScheme.background, extended: extended, destinations: navEntries .map((v) => NavigationRailDestination( diff --git a/lib/widgets/search/search_delegate.dart b/lib/widgets/search/search_delegate.dart index 290514d4d..6e37f4eb9 100644 --- a/lib/widgets/search/search_delegate.dart +++ b/lib/widgets/search/search_delegate.dart @@ -66,6 +66,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va CollectionSearchDelegate({ required super.searchFieldLabel, + required super.searchFieldStyle, required this.source, this.parentCollection, super.canPop, diff --git a/lib/widgets/settings/common/collection_tile.dart b/lib/widgets/settings/common/collection_tile.dart index abbe133c8..ff5bfefe4 100644 --- a/lib/widgets/settings/common/collection_tile.dart +++ b/lib/widgets/settings/common/collection_tile.dart @@ -44,7 +44,7 @@ class SettingsCollectionTile extends StatelessWidget { if (hasSubtitle) Text( l10n.drawerCollectionAll, - style: textTheme.bodyMedium!.copyWith(color: textTheme.bodySmall!.color), + style: textTheme.bodyMedium!.copyWith(color: theme.colorScheme.onSurfaceVariant), ), ], ), diff --git a/lib/widgets/settings/common/quick_actions/action_panel.dart b/lib/widgets/settings/common/quick_actions/action_panel.dart index 636b5923d..e83f4186a 100644 --- a/lib/widgets/settings/common/quick_actions/action_panel.dart +++ b/lib/widgets/settings/common/quick_actions/action_panel.dart @@ -1,4 +1,5 @@ import 'package:aves/theme/durations.dart'; +import 'package:aves/theme/themes.dart'; import 'package:flutter/material.dart'; class ActionPanel extends StatelessWidget { @@ -14,11 +15,7 @@ class ActionPanel extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final color = highlight - ? theme.colorScheme.secondary - : theme.brightness == Brightness.dark - ? Colors.blueGrey - : Colors.blueGrey.shade100; + final color = highlight ? theme.colorScheme.primary : Color.alphaBlend(theme.colorScheme.surfaceTint.withOpacity(.2), Themes.secondLayerColor(context)); return AnimatedContainer( foregroundDecoration: BoxDecoration( color: color.withOpacity(.2), diff --git a/lib/widgets/settings/common/quick_actions/editor_page.dart b/lib/widgets/settings/common/quick_actions/editor_page.dart index 2f50fb405..49f0c63af 100644 --- a/lib/widgets/settings/common/quick_actions/editor_page.dart +++ b/lib/widgets/settings/common/quick_actions/editor_page.dart @@ -14,7 +14,6 @@ import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart'; import 'package:aves/widgets/settings/common/quick_actions/quick_actions.dart'; import 'package:aves_utils/aves_utils.dart'; import 'package:collection/collection.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; @@ -148,11 +147,9 @@ class _QuickActionEditorBodyState extends State widget.save(_quickActions), child: ListView( children: [ Padding( @@ -279,7 +276,7 @@ class _QuickActionEditorBodyState extends State tabs: tabs.map((t) => t.$1).toList(), ), ), - body: WillPopScope( - onWillPop: () { + body: PopScope( + canPop: true, + onPopInvoked: (didPop) { settings.drawerTypeBookmarks = _typeItems.where(_visibleTypes.contains).toList(); settings.drawerAlbumBookmarks = _albumItems; settings.drawerPageBookmarks = _pageItems.where(_visiblePages.contains).toList(); - return SynchronousFuture(true); }, child: SafeArea( child: TabBarView( diff --git a/lib/widgets/settings/privacy/file_picker/crumb_line.dart b/lib/widgets/settings/privacy/file_picker/crumb_line.dart index 30cdfdfa6..7ad896d88 100644 --- a/lib/widgets/settings/privacy/file_picker/crumb_line.dart +++ b/lib/widgets/settings/privacy/file_picker/crumb_line.dart @@ -68,7 +68,7 @@ class _CrumbLineState extends State { return Center( child: DefaultTextStyle.merge( style: TextStyle( - color: Theme.of(context).colorScheme.secondary, + color: Theme.of(context).colorScheme.primary, ), child: _buildText(text), ), diff --git a/lib/widgets/settings/privacy/file_picker/file_picker_page.dart b/lib/widgets/settings/privacy/file_picker/file_picker_page.dart index 592411125..a458578b0 100644 --- a/lib/widgets/settings/privacy/file_picker/file_picker_page.dart +++ b/lib/widgets/settings/privacy/file_picker/file_picker_page.dart @@ -57,15 +57,14 @@ class _FilePickerPageState extends State { return !isHidden; } }).toList(); - return WillPopScope( - onWillPop: () { - if (_directory.relativeDir.isEmpty) { - return SynchronousFuture(true); - } + return PopScope( + canPop: _directory.relativeDir.isEmpty, + onPopInvoked: (didPop) { + if (didPop) return; + final parent = pContext.dirname(currentDirectoryPath); _goTo(parent); setState(() {}); - return SynchronousFuture(false); }, child: AvesScaffold( appBar: AppBar( diff --git a/lib/widgets/settings/settings_mobile_page.dart b/lib/widgets/settings/settings_mobile_page.dart index 6dc4cbd2d..27633b15b 100644 --- a/lib/widgets/settings/settings_mobile_page.dart +++ b/lib/widgets/settings/settings_mobile_page.dart @@ -6,6 +6,7 @@ import 'package:aves/ref/mime_types.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/basic/font_size_icon_theme.dart'; @@ -179,6 +180,7 @@ class _SettingsMobilePageState extends State with FeedbackMi SearchPageRoute( delegate: SettingsSearchDelegate( searchFieldLabel: context.l10n.settingsSearchFieldLabel, + searchFieldStyle: Themes.searchFieldStyle(context), sections: SettingsPage.sections, ), ), diff --git a/lib/widgets/settings/settings_search.dart b/lib/widgets/settings/settings_search.dart index 7c92ea90a..ac547b44f 100644 --- a/lib/widgets/settings/settings_search.dart +++ b/lib/widgets/settings/settings_search.dart @@ -15,6 +15,7 @@ class SettingsSearchDelegate extends AvesSearchDelegate { SettingsSearchDelegate({ required super.searchFieldLabel, + required super.searchFieldStyle, required this.sections, }) : super( routeName: pageRouteName, diff --git a/lib/widgets/settings/settings_tv_page.dart b/lib/widgets/settings/settings_tv_page.dart index 1fc742bb8..66a612989 100644 --- a/lib/widgets/settings/settings_tv_page.dart +++ b/lib/widgets/settings/settings_tv_page.dart @@ -80,7 +80,7 @@ class _ContentState extends State<_Content> { valueListenable: _indexNotifier, builder: (context, selectedIndex, child) { final rail = NavigationRail( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, + backgroundColor: Theme.of(context).colorScheme.background, extended: true, destinations: sections .map((section) => NavigationRailDestination( diff --git a/lib/widgets/settings/thumbnails/overlay.dart b/lib/widgets/settings/thumbnails/overlay.dart index d136ddbe1..a4904a372 100644 --- a/lib/widgets/settings/thumbnails/overlay.dart +++ b/lib/widgets/settings/thumbnails/overlay.dart @@ -90,8 +90,8 @@ class ThumbnailOverlayPage extends StatelessWidget { } static double _getIconSize(BuildContext context) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - return IconTheme.of(context).size! * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + return textScaler.scale(IconTheme.of(context).size!); } static Color _getIconColor(BuildContext context) => context.select((v) => v.neutral); diff --git a/lib/widgets/stats/date/histogram.dart b/lib/widgets/stats/date/histogram.dart index 69acdcc41..55cebcaa9 100644 --- a/lib/widgets/stats/date/histogram.dart +++ b/lib/widgets/stats/date/histogram.dart @@ -194,7 +194,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi final drawPoints = !isInterpolated; final colorScheme = Theme.of(context).colorScheme; - final accentColor = colorScheme.secondary; + final accentColor = colorScheme.primary; final axisColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onPrimary.withOpacity(.9) : Colors.transparent); final measureLineColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onPrimary.withOpacity(.1) : Colors.transparent); final histogramLineColor = charts.ColorUtil.fromDartColor(drawLine ? accentColor : Colors.white); @@ -326,7 +326,7 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi Text( numberFormat.format(count), style: TextStyle( - color: Theme.of(context).textTheme.bodySmall!.color, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), textAlign: TextAlign.end, ), diff --git a/lib/widgets/stats/filter_table.dart b/lib/widgets/stats/filter_table.dart index c6fe71c41..7e0673940 100644 --- a/lib/widgets/stats/filter_table.dart +++ b/lib/widgets/stats/filter_table.dart @@ -1,6 +1,7 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/settings/enums/accessibility_animations.dart'; import 'package:aves/model/settings/settings.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/stats/percent_text.dart'; @@ -46,8 +47,8 @@ class FilterTable extends StatelessWidget { }); } - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final lineHeight = 16 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final lineHeight = textScaler.scale(16); final barRadius = Radius.circular(lineHeight / 2); final isRtl = context.isRtl; @@ -57,13 +58,13 @@ class FilterTable extends StatelessWidget { builder: (context, constraints) { final showPercentIndicator = constraints.maxWidth - (chipWidth + countWidth) > percentIndicatorMinWidth; final displayedEntries = maxRowCount != null ? sortedEntries.take(maxRowCount!) : sortedEntries; - final theme = Theme.of(context); final isMonochrome = settings.themeColorMode == AvesThemeColorMode.monochrome; return Table( children: displayedEntries.map((kv) { final filter = filterBuilder(kv.key); final count = kv.value; final percent = count / totalEntryCount; + final colorScheme = Theme.of(context).colorScheme; return TableRow( children: [ Container( @@ -82,23 +83,30 @@ class FilterTable extends StatelessWidget { future: filter.color(context), builder: (context, snapshot) { final color = snapshot.data; - return LinearPercentIndicator( - percent: percent, - lineHeight: lineHeight, - backgroundColor: theme.colorScheme.onPrimary.withOpacity(.1), - progressColor: isMonochrome ? theme.colorScheme.secondary : color, - animation: animate, - isRTL: isRtl, - barRadius: barRadius, - center: LinearPercentIndicatorText(percent: percent), - padding: EdgeInsets.symmetric(horizontal: lineHeight), + return Stack( + // use a stack instead of `center` field, so that the widgets + // are centered even when the center child has larger height + alignment: Alignment.center, + children: [ + LinearPercentIndicator( + percent: percent, + lineHeight: lineHeight, + backgroundColor: Themes.secondLayerColor(context), + progressColor: isMonochrome ? colorScheme.primary : color, + animation: animate, + isRTL: isRtl, + barRadius: barRadius, + padding: EdgeInsets.symmetric(horizontal: lineHeight), + ), + LinearPercentIndicatorText(percent: percent), + ], ); }, ), Text( numberFormat.format(count), style: TextStyle( - color: theme.textTheme.bodySmall!.color, + color: colorScheme.onSurfaceVariant, ), textAlign: TextAlign.end, ), diff --git a/lib/widgets/stats/percent_text.dart b/lib/widgets/stats/percent_text.dart index 1ead911d5..839b41ce0 100644 --- a/lib/widgets/stats/percent_text.dart +++ b/lib/widgets/stats/percent_text.dart @@ -24,7 +24,7 @@ class LinearPercentIndicatorText extends StatelessWidget { ), ) ], - outlineColor: theme.scaffoldBackgroundColor, + outlineColor: theme.colorScheme.background, ); } } diff --git a/lib/widgets/stats/stats_page.dart b/lib/widgets/stats/stats_page.dart index 186294e68..07d6596cd 100644 --- a/lib/widgets/stats/stats_page.dart +++ b/lib/widgets/stats/stats_page.dart @@ -13,6 +13,7 @@ import 'package:aves/model/source/collection_source.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/theme/styles.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/utils/file_utils.dart'; import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart'; @@ -416,8 +417,8 @@ class _LocationIndicator extends StatelessWidget { final withGps = catalogued.where((entry) => entry.hasGps); final withGpsCount = withGps.length; final withGpsPercent = withGpsCount / entries.length; - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final lineHeight = 16 * textScaleFactor; + final textScaler = MediaQuery.textScalerOf(context); + final lineHeight = textScaler.scale(16); final barRadius = Radius.circular(lineHeight / 2); return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), @@ -428,16 +429,23 @@ class _LocationIndicator extends StatelessWidget { children: [ const Icon(AIcons.location), Expanded( - child: LinearPercentIndicator( - percent: withGpsPercent, - lineHeight: lineHeight, - backgroundColor: theme.colorScheme.onPrimary.withOpacity(.1), - progressColor: theme.colorScheme.secondary, - animation: context.select((v) => v.accessibilityAnimations.animate), - isRTL: context.isRtl, - barRadius: barRadius, - center: LinearPercentIndicatorText(percent: withGpsPercent), - padding: EdgeInsets.symmetric(horizontal: lineHeight), + child: Stack( + // use a stack instead of `center` field, so that the widgets + // are centered even when the center child has larger height + alignment: Alignment.center, + children: [ + LinearPercentIndicator( + percent: withGpsPercent, + lineHeight: lineHeight, + backgroundColor: Themes.secondLayerColor(context), + progressColor: theme.colorScheme.primary, + animation: context.select((v) => v.accessibilityAnimations.animate), + isRTL: context.isRtl, + barRadius: barRadius, + padding: EdgeInsets.symmetric(horizontal: lineHeight), + ), + LinearPercentIndicatorText(percent: withGpsPercent), + ], ), ), // end padding to match leading, so that inside label is aligned with outside label below diff --git a/lib/widgets/viewer/entry_viewer_stack.dart b/lib/widgets/viewer/entry_viewer_stack.dart index 1f0c5cf3e..e34da51ee 100644 --- a/lib/widgets/viewer/entry_viewer_stack.dart +++ b/lib/widgets/viewer/entry_viewer_stack.dart @@ -214,10 +214,12 @@ class _EntryViewerStackState extends State with EntryViewContr @override Widget build(BuildContext context) { final viewStateConductor = context.read(); - return WillPopScope( - onWillPop: () { - _onWillPop(); - return SynchronousFuture(false); + return PopScope( + canPop: false, + onPopInvoked: (didPop) { + if (didPop) return; + + _onPopInvoked(); }, child: ValueListenableProvider.value( value: _heroInfoNotifier, @@ -561,7 +563,7 @@ class _EntryViewerStackState extends State with EntryViewContr if (_overlayVisible.value) { _overlayVisible.value = false; } else { - _onWillPop(); + _onPopInvoked(); } } else if (notification is TvShowMoreInfoNotification) { if (!_overlayVisible.value) { @@ -782,7 +784,7 @@ class _EntryViewerStackState extends State with EntryViewContr } } - void _onWillPop() { + void _onPopInvoked() { if (_currentVerticalPage.value == infoPage) { // back from info to image _goToVerticalPage(imagePage); diff --git a/lib/widgets/viewer/info/common.dart b/lib/widgets/viewer/info/common.dart index 710ef8c24..cf10ebcf9 100644 --- a/lib/widgets/viewer/info/common.dart +++ b/lib/widgets/viewer/info/common.dart @@ -51,7 +51,10 @@ class InfoRowGroup extends StatefulWidget { static const valueStyle = TextStyle(fontSize: fontSize); static final _keyStyle = valueStyle.copyWith(height: 2.0); - static TextStyle keyStyle(BuildContext context) => Theme.of(context).textTheme.bodySmall!.merge(_keyStyle); + static TextStyle keyStyle(BuildContext context) { + final theme = Theme.of(context); + return theme.textTheme.bodySmall!.copyWith(color: theme.colorScheme.onSurfaceVariant).merge(_keyStyle); + } const InfoRowGroup({ super.key, @@ -97,8 +100,8 @@ class _InfoRowGroupState extends State { final _keyStyle = InfoRowGroup.keyStyle(context); // compute the size of keys and space in order to align values - final textScaleFactor = MediaQuery.textScaleFactorOf(context); - final keySizes = Map.fromEntries(keyValues.keys.map((key) => MapEntry(key, _getSpanWidth(TextSpan(text: _buildTextValue(key), style: _keyStyle), textScaleFactor)))); + final textScaler = MediaQuery.textScalerOf(context); + final keySizes = Map.fromEntries(keyValues.keys.map((key) => MapEntry(key, _getSpanWidth(TextSpan(text: _buildTextValue(key), style: _keyStyle), textScaler)))); final lastKey = keyValues.keys.last; return LayoutBuilder( @@ -115,6 +118,7 @@ class _InfoRowGroupState extends State { final value = kv.value; final spanBuilder = spanBuilders[key] ?? _buildTextValueSpans; final thisSpaceSize = max(0.0, (baseValueX - keySizes[key]!)) + InfoRowGroup.keyValuePadding; + final textScaleFactor = textScaler.scale(thisSpaceSize) / thisSpaceSize; return [ TextSpan(text: _buildTextValue(key), style: _keyStyle), @@ -138,11 +142,11 @@ class _InfoRowGroupState extends State { ); } - double _getSpanWidth(TextSpan span, double textScaleFactor) { + double _getSpanWidth(TextSpan span, TextScaler textScaler) { final paragraph = RenderParagraph( span, textDirection: TextDirection.ltr, - textScaleFactor: textScaleFactor, + textScaler: textScaler, )..layout(const BoxConstraints(), parentUsesSize: true); final width = paragraph.getMaxIntrinsicWidth(double.infinity); paragraph.dispose(); diff --git a/lib/widgets/viewer/info/info_app_bar.dart b/lib/widgets/viewer/info/info_app_bar.dart index 767a4b1d6..178cf8bc1 100644 --- a/lib/widgets/viewer/info/info_app_bar.dart +++ b/lib/widgets/viewer/info/info_app_bar.dart @@ -6,6 +6,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; +import 'package:aves/theme/themes.dart'; import 'package:aves/view/view.dart'; import 'package:aves/widgets/common/app_bar/app_bar_title.dart'; import 'package:aves/widgets/common/app_bar/sliver_app_bar_title.dart'; @@ -113,6 +114,7 @@ class InfoAppBar extends StatelessWidget { context: context, delegate: InfoSearchDelegate( searchFieldLabel: context.l10n.viewerInfoSearchFieldLabel, + searchFieldStyle: Themes.searchFieldStyle(context), entry: entry, metadataNotifier: metadataNotifier, isSelecting: isSelecting, diff --git a/lib/widgets/viewer/info/info_search.dart b/lib/widgets/viewer/info/info_search.dart index 5f5d48307..081f3410b 100644 --- a/lib/widgets/viewer/info/info_search.dart +++ b/lib/widgets/viewer/info/info_search.dart @@ -18,11 +18,13 @@ class InfoSearchDelegate extends SearchDelegate { InfoSearchDelegate({ required String searchFieldLabel, + required TextStyle searchFieldStyle, required this.entry, required this.metadataNotifier, required this.isSelecting, }) : super( searchFieldLabel: searchFieldLabel, + searchFieldStyle: searchFieldStyle, ); @override diff --git a/lib/widgets/viewer/info/metadata/tv_page.dart b/lib/widgets/viewer/info/metadata/tv_page.dart index 46af8c63b..5ed23345f 100644 --- a/lib/widgets/viewer/info/metadata/tv_page.dart +++ b/lib/widgets/viewer/info/metadata/tv_page.dart @@ -64,7 +64,7 @@ class _TvMetadataPageState extends State { if (selectedDir == null) return const SizedBox(); final rail = NavigationRail( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, + backgroundColor: Theme.of(context).colorScheme.background, extended: true, destinations: titles.mapIndexed((i, title) { final dir = metadata[titles[i]]!; diff --git a/lib/widgets/viewer/overlay/details/rating_tags.dart b/lib/widgets/viewer/overlay/details/rating_tags.dart index f2a93d3f5..f2b92c0d0 100644 --- a/lib/widgets/viewer/overlay/details/rating_tags.dart +++ b/lib/widgets/viewer/overlay/details/rating_tags.dart @@ -29,10 +29,13 @@ class OverlayRatingTagsRow extends AnimatedWidget { ratingString = '${'★' * rating}${'☆' * (5 - rating)}'; } - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final tags = entry.tags.toList()..sort(compareAsciiUpperCaseNatural); final hasTags = tags.isNotEmpty; + const iconSize = ViewerDetailOverlayContent.iconSize; + final textScaleFactor = textScaler.scale(iconSize) / iconSize; + return Text.rich( TextSpan( children: [ @@ -45,7 +48,7 @@ class OverlayRatingTagsRow extends AnimatedWidget { padding: const EdgeInsetsDirectional.only(end: ViewerDetailOverlayContent.iconPadding), child: DecoratedIcon( AIcons.tag, - size: ViewerDetailOverlayContent.iconSize / textScaleFactor, + size: iconSize / textScaleFactor, shadows: ViewerDetailOverlayContent.shadows(context), ), ), diff --git a/lib/widgets/viewer/overlay/video/progress_bar.dart b/lib/widgets/viewer/overlay/video/progress_bar.dart index cdf245690..2c547f16a 100644 --- a/lib/widgets/viewer/overlay/video/progress_bar.dart +++ b/lib/widgets/viewer/overlay/video/progress_bar.dart @@ -74,7 +74,7 @@ class _VideoProgressBarState extends State { ), child: MediaQuery( data: MediaQuery.of(context).copyWith( - textScaleFactor: 1, + textScaler: TextScaler.noScaling, ), child: Column( key: _progressBarKey, @@ -154,14 +154,14 @@ class _VideoProgressBarState extends State { Widget _buildMuteIndicator() => StreamBuilder( stream: controller?.volumeStream ?? Stream.value(1.0), builder: (context, snapshot) { - final textScaleFactor = MediaQuery.textScaleFactorOf(context); + final textScaler = MediaQuery.textScalerOf(context); final isMuted = controller?.isMuted ?? false; return isMuted ? Padding( padding: const EdgeInsetsDirectional.only(end: 8), child: Icon( AIcons.mute, - size: 16 * textScaleFactor, + size: textScaler.scale(16), ), ) : const SizedBox(); diff --git a/lib/widgets/viewer/overlay/viewer_buttons.dart b/lib/widgets/viewer/overlay/viewer_buttons.dart index 79cdd6595..4c3069986 100644 --- a/lib/widgets/viewer/overlay/viewer_buttons.dart +++ b/lib/widgets/viewer/overlay/viewer_buttons.dart @@ -397,6 +397,7 @@ class _ViewerButtonRowContentState extends State { Widget buildItem(EntryAction action) => Expanded( child: Material( + color: Colors.transparent, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(8)), ), diff --git a/lib/widgets/viewer/panorama_page.dart b/lib/widgets/viewer/panorama_page.dart index feaebfe1f..aa9c74691 100644 --- a/lib/widgets/viewer/panorama_page.dart +++ b/lib/widgets/viewer/panorama_page.dart @@ -11,7 +11,6 @@ import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/media_query.dart'; import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:panorama/panorama.dart'; @@ -57,11 +56,9 @@ class _PanoramaPageState extends State { @override Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () { - _onLeave(); - return SynchronousFuture(true); - }, + return PopScope( + canPop: true, + onPopInvoked: (didPop) => _onLeave(), child: AvesScaffold( body: Stack( children: [ diff --git a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart index 25533e096..1855fe33c 100644 --- a/lib/widgets/viewer/visual/video/subtitle/subtitle.dart +++ b/lib/widgets/viewer/visual/video/subtitle/subtitle.dart @@ -156,7 +156,7 @@ class VideoSubtitles extends StatelessWidget { final paragraph = RenderParagraph( TextSpan(children: spans), textDirection: TextDirection.ltr, - textScaleFactor: MediaQuery.textScaleFactorOf(context), + textScaler: MediaQuery.textScalerOf(context), )..layout(const BoxConstraints()); final textWidth = paragraph.getMaxIntrinsicWidth(double.infinity); final textHeight = paragraph.getMaxIntrinsicHeight(double.infinity); diff --git a/plugins/aves_magnifier/pubspec.lock b/plugins/aves_magnifier/pubspec.lock index 25b80882d..4a5a1557f 100644 --- a/plugins/aves_magnifier/pubspec.lock +++ b/plugins/aves_magnifier/pubspec.lock @@ -20,10 +20,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" equatable: dependency: "direct main" description: @@ -65,10 +65,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" nested: dependency: transitive description: @@ -102,10 +102,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=1.16.0" diff --git a/plugins/aves_magnifier/pubspec.yaml b/plugins/aves_magnifier/pubspec.yaml index d51f0aa56..66636960d 100644 --- a/plugins/aves_magnifier/pubspec.yaml +++ b/plugins/aves_magnifier/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_map/lib/src/marker/image.dart b/plugins/aves_map/lib/src/marker/image.dart index 3a2c33f52..d8ade2496 100644 --- a/plugins/aves_map/lib/src/marker/image.dart +++ b/plugins/aves_map/lib/src/marker/image.dart @@ -79,7 +79,7 @@ class ImageMarker extends StatelessWidget { Container( padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 2), decoration: ShapeDecoration( - color: theme.colorScheme.secondary, + color: theme.colorScheme.primary, shape: Directionality.of(context) == TextDirection.rtl ? CustomRoundedRectangleBorder( leftSide: borderSide, diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index 1feb34cba..261a1a3d8 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -36,10 +36,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" custom_rounded_rectangle_border: dependency: "direct main" description: @@ -89,10 +89,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -153,10 +153,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -262,10 +262,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" wkt_parser: dependency: transitive description: @@ -275,5 +275,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.10.0" diff --git a/plugins/aves_map/pubspec.yaml b/plugins/aves_map/pubspec.yaml index 9509d443f..7fc819894 100644 --- a/plugins/aves_map/pubspec.yaml +++ b/plugins/aves_map/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_model/pubspec.lock b/plugins/aves_model/pubspec.lock index f679f514e..a9c9e5861 100644 --- a/plugins/aves_model/pubspec.lock +++ b/plugins/aves_model/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" equatable: dependency: "direct main" description: @@ -58,10 +58,10 @@ packages: dependency: "direct main" description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sky_engine: dependency: transitive description: flutter @@ -79,9 +79,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_model/pubspec.yaml b/plugins/aves_model/pubspec.yaml index fe317bde2..72d9ab0ba 100644 --- a/plugins/aves_model/pubspec.yaml +++ b/plugins/aves_model/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_platform_meta/pubspec.lock b/plugins/aves_platform_meta/pubspec.lock index 474c0929d..290892640 100644 --- a/plugins/aves_platform_meta/pubspec.lock +++ b/plugins/aves_platform_meta/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -50,18 +50,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" plugin_platform_interface: dependency: "direct main" description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" sky_engine: dependency: transitive description: flutter @@ -79,9 +79,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_platform_meta/pubspec.yaml b/plugins/aves_platform_meta/pubspec.yaml index c87c30f04..5b8468351 100644 --- a/plugins/aves_platform_meta/pubspec.yaml +++ b/plugins/aves_platform_meta/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_report/pubspec.lock b/plugins/aves_report/pubspec.lock index e154f77d2..0d7dc5310 100644 --- a/plugins/aves_report/pubspec.lock +++ b/plugins/aves_report/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" path: dependency: transitive description: @@ -87,9 +87,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_report/pubspec.yaml b/plugins/aves_report/pubspec.yaml index ea3090164..5d8ef6fd9 100644 --- a/plugins/aves_report/pubspec.yaml +++ b/plugins/aves_report/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_report_console/pubspec.lock b/plugins/aves_report_console/pubspec.lock index 4845b171f..4c0f5e17b 100644 --- a/plugins/aves_report_console/pubspec.lock +++ b/plugins/aves_report_console/pubspec.lock @@ -20,10 +20,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -57,10 +57,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" path: dependency: transitive description: @@ -94,9 +94,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_report_console/pubspec.yaml b/plugins/aves_report_console/pubspec.yaml index 369f1c8b5..cdc06eb1c 100644 --- a/plugins/aves_report_console/pubspec.yaml +++ b/plugins/aves_report_console/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index d5778adc8..c49abcb7d 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "8942974ee5dc932427704ede5e0db8b5f2b8f22172964544b56e6bd37f6c3634" + sha256: dd68ecea9f1e3556d385521bd21c7bafd6311a8c1e11abe2595ca27974f468ee url: "https://pub.dev" source: hosted - version: "1.3.12" + version: "1.3.13" async: dependency: transitive description: @@ -52,10 +52,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" fake_async: dependency: transitive description: @@ -68,10 +68,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "45f3f9babfc6f56fb94c3cd11584cf3c9672868228373b699b94427010e01dc3" + sha256: "471b46ea6a9af503184d4de691566887daedd312aec5baac5baa42d819f56446" url: "https://pub.dev" source: hosted - version: "2.22.0" + version: "2.23.0" firebase_core_platform_interface: dependency: transitive description: @@ -92,18 +92,18 @@ packages: dependency: "direct main" description: name: firebase_crashlytics - sha256: "0d09f0e17b4174d850fd26a5036d51bb1b3e09c36a35ffcdc9dfa99fdbd6e9bb" + sha256: "27f78b1fdad2a7f557abea17c3e0ba882bd0430ddffb7844634d41e51422e43e" url: "https://pub.dev" source: hosted - version: "3.4.4" + version: "3.4.5" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "7ebb08dc5d53da3ca4122f2e84837dbfb1c3e6cc15731d5998893a5d41037a97" + sha256: "48b6cfb3e2fe3955ce1dfe16a0cceacb7d293277fda77eb47c058bfff94268e0" url: "https://pub.dev" source: hosted - version: "3.6.12" + version: "3.6.13" flutter: dependency: "direct main" description: flutter @@ -163,10 +163,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" path: dependency: transitive description: @@ -179,10 +179,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" sky_engine: dependency: transitive description: flutter @@ -200,18 +200,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -232,10 +232,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" vector_math: dependency: transitive description: @@ -248,10 +248,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.3.0" diff --git a/plugins/aves_report_crashlytics/pubspec.yaml b/plugins/aves_report_crashlytics/pubspec.yaml index 9186c9e74..1ce3651ec 100644 --- a/plugins/aves_report_crashlytics/pubspec.yaml +++ b/plugins/aves_report_crashlytics/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_screen_state/pubspec.lock b/plugins/aves_screen_state/pubspec.lock index 474c0929d..290892640 100644 --- a/plugins/aves_screen_state/pubspec.lock +++ b/plugins/aves_screen_state/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -50,18 +50,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" plugin_platform_interface: dependency: "direct main" description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" sky_engine: dependency: transitive description: flutter @@ -79,9 +79,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_screen_state/pubspec.yaml b/plugins/aves_screen_state/pubspec.yaml index 9b6570b39..8efc400d2 100644 --- a/plugins/aves_screen_state/pubspec.yaml +++ b/plugins/aves_screen_state/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index 80fe5ff43..2509df018 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -43,10 +43,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" custom_rounded_rectangle_border: dependency: transitive description: @@ -96,10 +96,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -160,10 +160,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -269,10 +269,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" wkt_parser: dependency: transitive description: @@ -282,5 +282,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.10.0" diff --git a/plugins/aves_services/pubspec.yaml b/plugins/aves_services/pubspec.yaml index b19e726a8..33c13b011 100644 --- a/plugins/aves_services/pubspec.yaml +++ b/plugins/aves_services/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index 5f1359a21..1e53dab2d 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -57,10 +57,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" csslib: dependency: transitive description: @@ -81,10 +81,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "7035152271ff67b072a211152846e9f1259cf1be41e34cd3e0b5463d2d6b8419" + sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -243,10 +243,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -323,10 +323,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -355,10 +355,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" polylabel: dependency: transitive description: @@ -456,18 +456,18 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" win32: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.0" win32_registry: dependency: transitive description: @@ -485,5 +485,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.1.0 <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.13.0" diff --git a/plugins/aves_services_google/pubspec.yaml b/plugins/aves_services_google/pubspec.yaml index f787173c4..41e580892 100644 --- a/plugins/aves_services_google/pubspec.yaml +++ b/plugins/aves_services_google/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_services_huawei/pubspec.lock b/plugins/aves_services_huawei/pubspec.lock index efcf6e786..c02c76e5e 100644 --- a/plugins/aves_services_huawei/pubspec.lock +++ b/plugins/aves_services_huawei/pubspec.lock @@ -64,10 +64,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" custom_rounded_rectangle_border: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -199,10 +199,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -231,10 +231,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" polylabel: dependency: transitive description: @@ -316,10 +316,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" wkt_parser: dependency: transitive description: @@ -329,5 +329,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.10.0" diff --git a/plugins/aves_services_huawei/pubspec.yaml b/plugins/aves_services_huawei/pubspec.yaml index 794aff2b1..ad685727b 100644 --- a/plugins/aves_services_huawei/pubspec.yaml +++ b/plugins/aves_services_huawei/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index ced677938..3b9e8af2e 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" custom_rounded_rectangle_border: dependency: transitive description: @@ -103,10 +103,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -167,10 +167,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -276,10 +276,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" wkt_parser: dependency: transitive description: @@ -289,5 +289,5 @@ packages: source: hosted version: "2.0.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.10.0" diff --git a/plugins/aves_services_none/pubspec.yaml b/plugins/aves_services_none/pubspec.yaml index c189e084e..6b647c69d 100644 --- a/plugins/aves_services_none/pubspec.yaml +++ b/plugins/aves_services_none/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_ui/lib/src/dot.dart b/plugins/aves_ui/lib/src/dot.dart index 9ca5e2726..5ae99afb5 100644 --- a/plugins/aves_ui/lib/src/dot.dart +++ b/plugins/aves_ui/lib/src/dot.dart @@ -49,7 +49,7 @@ class AvesDot extends StatelessWidget { child: Container( width: diameter, height: diameter, - color: theme.colorScheme.secondary, + color: theme.colorScheme.primary, ), ), ), diff --git a/plugins/aves_ui/pubspec.lock b/plugins/aves_ui/pubspec.lock index 8810a2ac3..fdb60c503 100644 --- a/plugins/aves_ui/pubspec.lock +++ b/plugins/aves_ui/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sky_engine: dependency: transitive description: flutter @@ -71,9 +71,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_ui/pubspec.yaml b/plugins/aves_ui/pubspec.yaml index bc1256456..9e86b2f71 100644 --- a/plugins/aves_ui/pubspec.yaml +++ b/plugins/aves_ui/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_utils/pubspec.lock b/plugins/aves_utils/pubspec.lock index 85de65a94..03319746f 100644 --- a/plugins/aves_utils/pubspec.lock +++ b/plugins/aves_utils/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" flutter: dependency: "direct main" description: flutter @@ -50,10 +50,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sky_engine: dependency: transitive description: flutter @@ -71,9 +71,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_utils/pubspec.yaml b/plugins/aves_utils/pubspec.yaml index 52f2d1f3d..3544183b4 100644 --- a/plugins/aves_utils/pubspec.yaml +++ b/plugins/aves_utils/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_video/pubspec.lock b/plugins/aves_video/pubspec.lock index d08c8cad0..0da6fab12 100644 --- a/plugins/aves_video/pubspec.lock +++ b/plugins/aves_video/pubspec.lock @@ -27,10 +27,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" equatable: dependency: transitive description: @@ -72,10 +72,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sky_engine: dependency: transitive description: flutter @@ -93,9 +93,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_video/pubspec.yaml b/plugins/aves_video/pubspec.yaml index 258cd6ded..6a11dc7a5 100644 --- a/plugins/aves_video/pubspec.yaml +++ b/plugins/aves_video/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_video_ffmpeg/pubspec.lock b/plugins/aves_video_ffmpeg/pubspec.lock index 0d7242017..67e6be94a 100644 --- a/plugins/aves_video_ffmpeg/pubspec.lock +++ b/plugins/aves_video_ffmpeg/pubspec.lock @@ -34,10 +34,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" equatable: dependency: transitive description: @@ -96,18 +96,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" sky_engine: dependency: transitive description: flutter @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=2.0.0" diff --git a/plugins/aves_video_ffmpeg/pubspec.yaml b/plugins/aves_video_ffmpeg/pubspec.yaml index 7a1469924..866cc9e35 100644 --- a/plugins/aves_video_ffmpeg/pubspec.yaml +++ b/plugins/aves_video_ffmpeg/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_video_ijk/pubspec.lock b/plugins/aves_video_ijk/pubspec.lock index 23a25a317..e91054b9e 100644 --- a/plugins/aves_video_ijk/pubspec.lock +++ b/plugins/aves_video_ijk/pubspec.lock @@ -34,10 +34,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" equatable: dependency: transitive description: @@ -88,10 +88,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sky_engine: dependency: transitive description: flutter @@ -109,9 +109,9 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" diff --git a/plugins/aves_video_ijk/pubspec.yaml b/plugins/aves_video_ijk/pubspec.yaml index e1cdc9f77..b32a0f928 100644 --- a/plugins/aves_video_ijk/pubspec.yaml +++ b/plugins/aves_video_ijk/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/plugins/aves_video_mpv/pubspec.lock b/plugins/aves_video_mpv/pubspec.lock index 66f83c8c7..d90c65e3a 100644 --- a/plugins/aves_video_mpv/pubspec.lock +++ b/plugins/aves_video_mpv/pubspec.lock @@ -58,10 +58,10 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" convert: dependency: transitive description: @@ -82,10 +82,10 @@ packages: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.10" equatable: dependency: transitive description: @@ -124,10 +124,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_parser: dependency: transitive description: @@ -204,18 +204,18 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" package_info_plus: dependency: transitive description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "5.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -236,18 +236,18 @@ packages: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.1" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" pointycastle: dependency: transitive description: @@ -409,10 +409,10 @@ packages: dependency: transitive description: name: wakelock_plus - sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 + sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.1.4" wakelock_plus_platform_interface: dependency: transitive description: @@ -425,26 +425,26 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" win32: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.0" xml: dependency: transitive description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.4.2" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.7.0" diff --git a/plugins/aves_video_mpv/pubspec.yaml b/plugins/aves_video_mpv/pubspec.yaml index 4a15a0563..4f2fb26d0 100644 --- a/plugins/aves_video_mpv/pubspec.yaml +++ b/plugins/aves_video_mpv/pubspec.yaml @@ -3,7 +3,7 @@ version: 0.0.1 publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" + sdk: '>=3.2.0 <4.0.0' dependencies: flutter: diff --git a/pubspec.lock b/pubspec.lock index bfcc09aaf..280cb56c6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" _flutterfire_internals: dependency: transitive description: name: _flutterfire_internals - sha256: "8942974ee5dc932427704ede5e0db8b5f2b8f22172964544b56e6bd37f6c3634" + sha256: dd68ecea9f1e3556d385521bd21c7bafd6311a8c1e11abe2595ca27974f468ee url: "https://pub.dev" source: hosted - version: "1.3.12" + version: "1.3.13" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" archive: dependency: transitive description: @@ -202,18 +202,18 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" connectivity_plus: dependency: "direct main" description: name: connectivity_plus - sha256: b502a681ba415272ecc41400bd04fe543ed1a62632137dc84d25a91e7746f55f + sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.0.2" connectivity_plus_platform_interface: dependency: transitive description: @@ -242,10 +242,10 @@ packages: dependency: transitive description: name: coverage - sha256: "2fb815080e44a09b85e0f2ca8a820b15053982b2e714b59267719e8a9ff17097" + sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb" url: "https://pub.dev" source: hosted - version: "1.6.3" + version: "1.6.4" crypto: dependency: transitive description: @@ -274,10 +274,10 @@ packages: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.10" decorated_icon: dependency: "direct main" description: @@ -290,10 +290,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "7035152271ff67b072a211152846e9f1259cf1be41e34cd3e0b5463d2d6b8419" + sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" url: "https://pub.dev" source: hosted - version: "9.1.0" + version: "9.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -388,10 +388,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: "45f3f9babfc6f56fb94c3cd11584cf3c9672868228373b699b94427010e01dc3" + sha256: "471b46ea6a9af503184d4de691566887daedd312aec5baac5baa42d819f56446" url: "https://pub.dev" source: hosted - version: "2.22.0" + version: "2.23.0" firebase_core_platform_interface: dependency: transitive description: @@ -412,18 +412,18 @@ packages: dependency: transitive description: name: firebase_crashlytics - sha256: "0d09f0e17b4174d850fd26a5036d51bb1b3e09c36a35ffcdc9dfa99fdbd6e9bb" + sha256: "27f78b1fdad2a7f557abea17c3e0ba882bd0430ddffb7844634d41e51422e43e" url: "https://pub.dev" source: hosted - version: "3.4.4" + version: "3.4.5" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: "7ebb08dc5d53da3ca4122f2e84837dbfb1c3e6cc15731d5998893a5d41037a97" + sha256: "48b6cfb3e2fe3955ce1dfe16a0cceacb7d293277fda77eb47c058bfff94268e0" url: "https://pub.dev" source: hosted - version: "3.6.12" + version: "3.6.13" flex_color_picker: dependency: "direct main" description: @@ -503,7 +503,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: da1bd8f16cbce3fa60bae8fff478718fe9d6835e + resolved-ref: "051ba00b4a3edfdbf8d053ebfe946e76419912b9" url: "https://github.com/deckerst/flutter_localization_nn.git" source: git version: "0.0.1" @@ -675,10 +675,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.2" http_multi_server: dependency: transitive description: @@ -747,10 +747,10 @@ packages: dependency: "direct main" description: name: leak_tracker - sha256: b63ca5cc296c7509d71f6d4a8cb6085eec8461970c503f3ef3c5c541bc3f0a9a + sha256: "04be76c4a4bb50f14904e64749237e541e7c7bcf7ec0b196907322ab5d2fc739" url: "https://pub.dev" source: hosted - version: "9.0.6" + version: "9.0.16" lints: dependency: transitive description: @@ -891,10 +891,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -980,10 +980,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "5.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -1077,50 +1077,58 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" + sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78" url: "https://pub.dev" source: hosted - version: "11.0.1" + version: "11.1.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e + sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6" url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "12.0.1" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306" url: "https://pub.dev" source: hosted - version: "9.1.4" + version: "9.2.0" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: d96ff56a757b7f04fa825c469d296c5aebc55f743e87bd639fef91a466a24da8 + url: "https://pub.dev" + source: hosted + version: "0.1.0+1" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" + sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1 url: "https://pub.dev" source: hosted - version: "3.12.0" + version: "4.0.2" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004" url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "0.2.0" petitparser: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.1" pin_code_fields: dependency: "direct main" description: @@ -1133,18 +1141,18 @@ packages: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" pointycastle: dependency: transitive description: @@ -1325,10 +1333,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -1426,26 +1434,26 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "8ed044102f3135add97be8653662052838859f5400075ef227f8ad72ae320803" + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.5.0+1" + version: "2.5.0+2" stack_trace: dependency: "direct main" description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -1499,26 +1507,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "13b41f318e2a5751c3169137103b60c584297353d4b1761b66029bae6411fe46" + sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f url: "https://pub.dev" source: hosted - version: "1.24.3" + version: "1.24.9" test_api: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" test_core: dependency: transitive description: name: test_core - sha256: "99806e9e6d95c7b059b7a0fc08f07fc53fabe54a829497f0d9676299f1e8637e" + sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a url: "https://pub.dev" source: hosted - version: "0.5.3" + version: "0.5.9" transparent_image: dependency: "direct main" description: @@ -1579,10 +1587,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a" + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" url_launcher_linux: dependency: transitive description: @@ -1611,10 +1619,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" + sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" url_launcher_windows: dependency: transitive description: @@ -1643,10 +1651,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f + sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 url: "https://pub.dev" source: hosted - version: "11.7.1" + version: "11.10.0" volume_controller: dependency: "direct main" description: @@ -1659,10 +1667,10 @@ packages: dependency: transitive description: name: wakelock_plus - sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 + sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d url: "https://pub.dev" source: hosted - version: "1.1.3" + version: "1.1.4" wakelock_plus_platform_interface: dependency: transitive description: @@ -1683,10 +1691,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1715,10 +1723,10 @@ packages: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.0" win32_registry: dependency: transitive description: @@ -1747,10 +1755,10 @@ packages: dependency: "direct main" description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.4.2" yaml: dependency: transitive description: @@ -1760,5 +1768,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.1.0 <4.0.0" - flutter: ">=3.13.9" + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.16.1" diff --git a/pubspec.yaml b/pubspec.yaml index ba98710c5..b6dbb966c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,8 +13,8 @@ publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.13.9 - sdk: ">=3.0.0 <4.0.0" + flutter: 3.16.1 + sdk: '>=3.2.0 <4.0.0' # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor dependencies: @@ -168,20 +168,20 @@ flutter: # adapts from package `flutter_highlight` v0.7.0 # # `OutputBuffer` in `/services/common/output_buffer.dart` -# adapts from Flutter v3.10.0 `_OutputBuffer` in `/foundation/consolidate_response.dart` +# adapts from Flutter v3.16.0 `_OutputBuffer` in `/foundation/consolidate_response.dart` # # `TvLicensePage` in `/widgets/about/tv_license_page.dart` -# adapts from Flutter v3.10.0 `_LicenseData` in `/material/about.dart` +# adapts from Flutter v3.16.0 `_LicenseData` in `/material/about.dart` # and `_PackageLicensePage` in `/material/about.dart` # # `OverlaySnackBar` in `/widgets/common/action_mixins/overlay_snack_bar.dart` -# adapts from Flutter v3.10.0 `SnackBar` in `/material/snack_bar.dart` +# adapts from Flutter v3.16.0 `SnackBar` in `/material/snack_bar.dart` # # `EagerScaleGestureRecognizer` in `/widgets/common/behaviour/eager_scale_gesture_recognizer.dart` -# adapts from Flutter v3.10.0 `ScaleGestureRecognizer` in `/gestures/scale.dart` +# adapts from Flutter v3.16.0 `ScaleGestureRecognizer` in `/gestures/scale.dart` # # `KnownExtentScrollPhysics` in `/widgets/common/behaviour/known_extent_scroll_physics.dart` -# adapts from Flutter v3.10.0 `FixedExtentScrollPhysics` in `/widgets/list_wheel_scroll_view.dart` +# adapts from Flutter v3.16.0 `FixedExtentScrollPhysics` in `/widgets/list_wheel_scroll_view.dart` # # `TransitionImage` in `/widgets/common/fx/transition_image.dart` # adapts from Flutter v3.10.0 `_ImageState` in `/widgets/image.dart` @@ -190,5 +190,5 @@ flutter: # `_RenderSliverKnownExtentBoxAdaptor` in `/widgets/common/grid/sliver.dart` # adapts from Flutter v3.10.0 `RenderSliverFixedExtentBoxAdaptor` in `/rendering/sliver_fixed_extent_list.dart` # -# `CollectionSearchDelegate`, `SearchPageRoute` in `/widgets/search/search_delegate.dart` -# adapts from Flutter v3.10.0 `SearchDelegate`, `_SearchPageRoute` in `/material/search.dart` +# `AvesSearchDelegate`, `SearchPageRoute` in `/widgets/common/search/*.dart` +# adapts from Flutter v3.16.0 `SearchDelegate`, `_SearchPageRoute` in `/material/search.dart` diff --git a/scripts/screenshot_post_process.sh b/scripts/screenshot_post_process.sh index 901ecb3f1..861b7cb9e 100755 --- a/scripts/screenshot_post_process.sh +++ b/scripts/screenshot_post_process.sh @@ -45,9 +45,10 @@ for source in overlay/*/*; do done mv izzy/en izzy/en-US mv izzy/es izzy/es-MX +mv izzy/nb izzy/nb-NO mv izzy/pt izzy/pt-BR mv izzy/zh izzy/zh-CN -mv izzy/zh_Hant izzy/zh-TW +mv izzy/zh_Hant izzy/zh-Hant # play: add device frame for source in overlay/*/*; do diff --git a/shaders.sksl.json b/shaders.sksl.json index 8c70d3018..bedeff7f7 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"SM G970N","engineRevision":"0545f8705df301877d787107bac1a6e9fc9ee1ad","data":{"HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAGULKMMQKAAAAAAMAAAAAIAAAAAAGIRBNAWEYZAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAC4BAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjbGVfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMV9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MxX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzFfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41ID8gMSA6IDApKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShfc3JjLCBDaXJjbGVfUzFfYzAoX3NyYykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAoAIAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"DAAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADdAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIG91dHB1dENvbG9yX1MwKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACsAQAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAIBAIAAAABLCIIBAAAAABAEGABBAMAACAIAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"DAAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAADJAwAAdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoTWF0cml4RWZmZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvbG9yX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAABEAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAAYQADAAAEBB7BH46AKAAAYAAAAAAAAIAAAABS2JQ7QD2PAEAAAMAAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB+BQAAY29uc3QgaW50IGtGaWxsQldfUzFfYzAgPSAwOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1cmVjdFVuaWZvcm1fUzFfYzA7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgUmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMV9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzFfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MxX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKFJlY3RfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","DASAAAAAQAAWAABAYAAQBYH7777Z6QQBAEAAAAAAEAAAAAAAEBSAAAB2AAAAAAACAAAAAEBSAAAAA":"DAAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADgAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHVDb2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCk7Cgl9CglvdXRwdXRDb2xvcl9TMCA9IG91dHB1dENvbG9yX1MwICogdGV4Q29sb3I7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAGVXOVKVEAAAAADAAAAAAAAEAABMHHPDNAYAQAACAEGNDQDEAAAACAAAAABAEM2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAIAACAAZBAAAAANQ4Z4NUDACAAAEAAAAACAI33BYT43IEAAAAAAAAAAAWARQ5UOAMQAAAAIAAAAAAABS4UIAYXAGAAAAAAAAAAA2AAQAAAAFAAAAAEASAAQAAAA":"DAAAAExTS1PlAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc182X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAAAAxwcAAHVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzA7CmhhbGY0IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gX2Nvb3JkczsKCXJldHVybiBoYWxmNChtaXgodXN0YXJ0X1MxX2MwX2MwX2MwLCB1ZW5kX1MxX2MwX2MwX2MwLCBoYWxmKF90bXBfMV9jb29yZHMueCkpKTsKfQpoYWxmNCBjb2xvcl94Zm9ybV9TMV9jMF9jMChmbG9hdDQgY29sb3IpIAp7Cgljb2xvci5yZ2IgKj0gY29sb3IuYTsKCXJldHVybiBoYWxmNChjb2xvcik7Cn0KaGFsZjQgQ29sb3JTcGFjZVhmb3JtX1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gY29sb3JfeGZvcm1fUzFfYzBfYzAoU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzAoX2lucHV0LCBfY29vcmRzKSk7Cn0KaGFsZjQgTGluZWFyTGF5b3V0X1MxX2MwX2MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMl9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfM19jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKCXJldHVybiBoYWxmNChoYWxmNChoYWxmKF90bXBfM19jb29yZHMueCkgKyAxZS0wNSwgMS4wLCAwLjAsIDAuMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTGluZWFyTGF5b3V0X1MxX2MwX2MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQ2xhbXBlZEdyYWRpZW50X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgdCA9IE1hdHJpeEVmZmVjdF9TMV9jMF9jMShfdG1wXzRfaW5Db2xvcik7CgloYWxmNCBvdXRDb2xvcjsKCWlmICghYm9vbChpbnQoMSkpICYmIHQueSA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSBoYWxmNCgwLjApOwoJfQoJZWxzZSBpZiAodC54IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IHVsZWZ0Qm9yZGVyQ29sb3JfUzFfYzA7Cgl9CgllbHNlIGlmICh0LnggPiAxLjApIAoJewoJCW91dENvbG9yID0gdXJpZ2h0Qm9yZGVyQ29sb3JfUzFfYzA7Cgl9CgllbHNlIAoJewoJCW91dENvbG9yID0gQ29sb3JTcGFjZVhmb3JtX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gKGhhbGY0KDEuMCkgLSBvdXRwdXRfUzEpICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQAAEAQAAAAGQCBAMQAAAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzAueSwgdWNsYW1wX1MxX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAHADAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzAueCwgdWNsYW1wX1MxX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBjbGFtcGVkQ29vcmQpOwoJcmV0dXJuIHRleHR1cmVDb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACAFBQATAAAAAAFAAMAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAABABAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgRWxsaXB0aWNhbFJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJZmxvYXQyIFogPSBkeHkgKiB1aW52UmFkaWlYWV9TMS54eTsKCWhhbGYgaW1wbGljaXQgPSBoYWxmKGRvdChaLCBkeHkpIC0gMS4wKTsKCWhhbGYgZ3JhZF9kb3QgPSBoYWxmKDQuMCAqIGRvdChaLCBaKSk7CglncmFkX2RvdCA9IG1heChncmFkX2RvdCwgMS4wZS00KTsKCWhhbGYgYXBwcm94X2Rpc3QgPSBpbXBsaWNpdCAqIGhhbGYoaW52ZXJzZXNxcnQoZ3JhZF9kb3QpKTsKCWhhbGYgYWxwaGEgPSBjbGFtcCgwLjUgKyBhcHByb3hfZGlzdCwgMC4wLCAxLjApOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRWxsaXB0aWNhbFJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAIAAEAAAABJYQAAAAAQAAIAAAAAWCBACAABAAAAANAECAZAAEAAAAAAAAFAAMAAAABAAAAAAABBAM":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IGNsYW1wKHN1YnNldENvb3JkLngsIHVjbGFtcF9TMV9jMF9jMF9jMC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueik7CgljbGFtcGVkQ29vcmQueSA9IHN1YnNldENvb3JkLnk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABYQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAB5AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAsQEAAHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAE0DAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgaW5Db29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkID0gY2xhbXAoc3Vic2V0Q29vcmQsIHVjbGFtcF9TMV9jMC54eSwgdWNsYW1wX1MxX2MwLnp3KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEADZABYAAAIAAAAAACQAGAAAAAQAAAAAAAQQG":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAADUAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAANAAAAAZ3N3DJRAAAAAAAAABAAAAAGJZFMBV5RUAQAAAAAAQAAAAAMACQCAACAAAAA2AIBAEIAAAAAAAAAAAAIADQAAAAIAAAAAAAIIDAAAAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAeAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1Y2lyY2xlRGF0YV9TMV9jMDsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCBfY29vcmRzKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBDaXJjbGVCbHVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjIgdmVjID0gaGFsZjIoKHNrX0ZyYWdDb29yZC54eSAtIGZsb2F0Mih1Y2lyY2xlRGF0YV9TMV9jMC54eSkpICogZmxvYXQodWNpcmNsZURhdGFfUzFfYzAudykpOwoJaGFsZiBkaXN0ID0gbGVuZ3RoKHZlYykgKyAoMC41IC0gdWNpcmNsZURhdGFfUzFfYzAueikgKiB1Y2lyY2xlRGF0YV9TMV9jMC53OwoJcmV0dXJuIGhhbGY0KE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgZmxvYXQyKGhhbGYyKGRpc3QsIDAuNSkpKS53d3d3KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKENpcmNsZUJsdXJfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAKPABAAAAAAB2AAAAAAACAAAAAEBSAAAAAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAACbBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBmbG9hdDIgdWludlJhZGlpWFlfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdmFyY2Nvb3JkX1MwOwpoYWxmNCBFbGxpcHRpY2FsUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CglmbG9hdDIgWiA9IGR4eSAqIHVpbnZSYWRpaVhZX1MxLnh5OwoJaGFsZiBpbXBsaWNpdCA9IGhhbGYoZG90KFosIGR4eSkgLSAxLjApOwoJaGFsZiBncmFkX2RvdCA9IGhhbGYoNC4wICogZG90KFosIFopKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjBlLTQpOwoJaGFsZiBhcHByb3hfZGlzdCA9IGltcGxpY2l0ICogaGFsZihpbnZlcnNlc3FydChncmFkX2RvdCkpOwoJaGFsZiBhbHBoYSA9IGNsYW1wKDAuNSArIGFwcHJveF9kaXN0LCAwLjAsIDEuMCk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEVsbGlwdGljYWxSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADgAAAHJhZGlpX3NlbGVjdG9yAAAZAAAAY29ybmVyX2FuZF9yYWRpdXNfb3V0c2V0cwAAABUAAABhYV9ibG9hdF9hbmRfY292ZXJhZ2UAAAAHAAAAcmFkaWlfeAAHAAAAcmFkaWlfeQAEAAAAc2tldxkAAAB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlAAAABQAAAGNvbG9yAAAAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAABAEAAAABJYQAAAAAACAIAAAAAWCBAAAIBAAAAANAECAZAAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAC8GAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmMiB1SW5jcmVtZW50X1MxX2MwOwp1bmlmb3JtIGhhbGYyIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwWzEzXTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglmbG9hdDIgaW5Db29yZCA9IF9jb29yZHM7CglmbG9hdDIgc3Vic2V0Q29vcmQ7CglzdWJzZXRDb29yZC54ID0gaW5Db29yZC54OwoJc3Vic2V0Q29vcmQueSA9IGluQ29vcmQueTsKCWZsb2F0MiBjbGFtcGVkQ29vcmQ7CgljbGFtcGVkQ29vcmQueCA9IHN1YnNldENvb3JkLng7CgljbGFtcGVkQ29vcmQueSA9IGNsYW1wKHN1YnNldENvb3JkLnksIHVjbGFtcF9TMV9jMF9jMF9jMC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAudyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBTbW9vdGhfUzFfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgY29vcmQsIGhhbGYyIG9mZnNldEFuZEtlcm5lbCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0LCAoY29vcmQgKyBvZmZzZXRBbmRLZXJuZWwueCAqIHVJbmNyZW1lbnRfUzFfYzApKSAqIG9mZnNldEFuZEtlcm5lbC55Owp9CmhhbGY0IEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgY29sb3IgPSBoYWxmNCgwKTsKCWZsb2F0MiBjb29yZCA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZm9yIChpbnQgaT0wOyBpPDEzOyArK2kpIAoJewoJCWNvbG9yICs9IFNtb290aF9TMV9jMChfaW5wdXQsIGNvb3JkLCB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFtpXSk7Cgl9CglyZXR1cm4gY29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkNvbnZvbHV0aW9uX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAADUAANAAAAAAAAAIAAAABLAIABAAAAABAEGABBAMAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAAAAA":"DAAAAExTS1M8AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAC2AgAAdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKE1hdHJpeEVmZmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb2xvcl9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAHMCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwKS5ycnJyOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACfAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGZsb2F0MiB2SW50VGV4dHVyZUNvb3Jkc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBEaXN0YW5jZUZpZWxkUGF0aAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQyIHV2ID0gdlRleHR1cmVDb29yZHNfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLnJycnI7Cgl9CgloYWxmIGRpc3RhbmNlID0gNy45Njg3NSoodGV4Q29sb3IuciAtIDAuNTAxOTYwNzg0MzEpOwoJaGFsZiBhZndpZHRoOwoJYWZ3aWR0aCA9IGFicygwLjY1KmhhbGYoZEZkeCh2SW50VGV4dHVyZUNvb3Jkc19TMC54KSkpOwoJaGFsZiB2YWwgPSBzbW9vdGhzdGVwKC1hZndpZHRoLCBhZndpZHRoLCBkaXN0YW5jZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KHZhbCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAD2AAAAAGQMH4A6TYBAAADAAAAACAAAAAAQCGHIGH6YNJQAAAABQAAAAAAAAAAAAFAAMAAAABAAAAAAABBAMAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAARQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IFJlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGNvdmVyYWdlOwoJaWYgKGludCgxKSA9PSBrRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKGFsbChncmVhdGVyVGhhbihmbG9hdDQoc2tfRnJhZ0Nvb3JkLnh5LCB1cmVjdFVuaWZvcm1fUzFfYzAuencpLCBmbG9hdDQodXJlY3RVbmlmb3JtX1MxX2MwLnh5LCBza19GcmFnQ29vcmQueHkpKSkpOwoJfQoJZWxzZSAKCXsKCQloYWxmNCBkaXN0czQgPSBzYXR1cmF0ZShoYWxmNCgxLjAsIDEuMCwgLTEuMCwgLTEuMCkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIHVyZWN0VW5pZm9ybV9TMV9jMCkpOwoJCWhhbGYyIGRpc3RzMiA9IChkaXN0czQueHkgKyBkaXN0czQuencpIC0gMS4wOwoJCWNvdmVyYWdlID0gZGlzdHMyLnggKiBkaXN0czIueTsKCX0KCWlmIChpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEFBX1MxX2MwKSAKCXsKCQljb3ZlcmFnZSA9IDEuMCAtIGNvdmVyYWdlOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGNvdmVyYWdlKSk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9tb2R1bGF0ZShSZWN0X1MxX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQml0bWFwVGV4dAoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHZUZXh0dXJlQ29vcmRzX1MwKS5ycnJyOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSB0ZXhDb2xvcjsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA7AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBVWKMG7QAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAArAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnVuaWZvcm0gc2FtcGxlckV4dGVybmFsT0VTIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc18zX1MwKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKGhhbGY0IF9pbnB1dCkgCnsKCV9pbnB1dCA9IE1hdHJpeEVmZmVjdF9TMV9jMChfaW5wdXQpOwoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglyZXR1cm4gaGFsZjQoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBDaXJjdWxhclJSZWN0X1MyKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAIAAAAcG9zaXRpb24FAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQNNQSEIYAQAADQAAAABAAAAAAABAEMVC2TBEKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABRBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSA/IDEgOiAwKSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MxX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IHhfcGx1c18xPXZhcmNjb29yZF9TMC54LCB5PXZhcmNjb29yZF9TMC55OwoJaGFsZiBjb3ZlcmFnZTsKCWlmICgwID09IHhfcGx1c18xKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoeSk7Cgl9CgllbHNlIAoJewoJCWZsb2F0IGZuID0geF9wbHVzXzEgKiAoeF9wbHVzXzEgLSAyKTsKCQlmbiA9IGZtYSh5LHksIGZuKTsKCQlmbG9hdCBmbndpZHRoID0gZndpZHRoKGZuKTsKCQljb3ZlcmFnZSA9IC41IC0gaGFsZihmbi9mbndpZHRoKTsKCQljb3ZlcmFnZSA9IGNsYW1wKGNvdmVyYWdlLCAwLCAxKTsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoY292ZXJhZ2UpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAGVXOVKVEAAAAADAAAAAFQ454NUDACAAAIAQZUOAMQAAAAIAAAAAEARTKLVK5LSAAAAABQAAAAAYGP6G2BSBAAAAAIO2HAGIAAAAAAAEAAAAAZ3RZTY3IGAEAAAAAAAAAGARI4UKA4WAAAAAAAEAAAABSMQII2XAGAAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"DAAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQMAAAAAAAAAEAAAABJYQAAAAAAAAIAAAAAWCBAAAABAAAAANAECAZAAAAAAAAAAAFAAMAAAABAAAAAAABBAM":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAPAEAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnVuaWZvcm0gaGFsZjIgdUluY3JlbWVudF9TMV9jMDsKdW5pZm9ybSBoYWxmMiB1T2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxM107CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IFNtb290aF9TMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBjb29yZCwgaGFsZjIgb2Zmc2V0QW5kS2VybmVsKSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfaW5wdXQsIChjb29yZCArIG9mZnNldEFuZEtlcm5lbC54ICogdUluY3JlbWVudF9TMV9jMCkpICogb2Zmc2V0QW5kS2VybmVsLnk7Cn0KaGFsZjQgR2F1c3NpYW5Db252b2x1dGlvbl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBjb2xvciA9IGhhbGY0KDApOwoJZmxvYXQyIGNvb3JkID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7Cglmb3IgKGludCBpPTA7IGk8MTM7ICsraSkgCgl7CgkJY29sb3IgKz0gU21vb3RoX1MxX2MwKF9pbnB1dCwgY29vcmQsIHVPZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldKTsKCX0KCXJldHVybiBjb2xvcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQ29udm9sdXRpb25fUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMCA9IGhhbGY0KDEpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","DAQAAAAAAABGAABAYAAQAIHCAIAYAQUBAEAAAAAAEAAAAAAAAAAAAIAHSADQAAAQAAAAAAFAAMAAAABAAAAAAABBAM":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAQAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwp1bmlmb3JtIHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAPAAAAaW5UZXh0dXJlQ29vcmRzAAAAAAA=","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAALAgAAdW5pZm9ybSBzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBSUmVjdFNoYWRvdwoJaGFsZjMgc2hhZG93UGFyYW1zOwoJc2hhZG93UGFyYW1zID0gdmluU2hhZG93UGFyYW1zX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJaGFsZiBkID0gbGVuZ3RoKHNoYWRvd1BhcmFtcy54eSk7CglmbG9hdDIgdXYgPSBmbG9hdDIoc2hhZG93UGFyYW1zLnogKiAoMS4wIC0gZCksIDAuNSk7CgloYWxmIGZhY3RvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdXYpLjAwMHIuYTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZmFjdG9yKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAOAAAAaW5TaGFkb3dQYXJhbXMAAAAAAAA="}} \ No newline at end of file +{"platform":"android","name":"SM G970N","engineRevision":"22b600f240548c1cf6f5d3f9ae65a5c9e51bc443","data":{"HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAWR0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"DAAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADVAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADYAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoBAAAAoAIAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAAUDLMERKGAAAAAMAAAAAIAAAAAAAIBDNIWUYZAUAAAAAAYAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAAJAeAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAADAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBoYWxmMyB2aW5TaGFkb3dQYXJhbXNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUlJlY3RTaGFkb3cKCWhhbGYzIHNoYWRvd1BhcmFtczsKCXNoYWRvd1BhcmFtcyA9IHZpblNoYWRvd1BhcmFtc19TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZCA9IGxlbmd0aChzaGFkb3dQYXJhbXMueHkpOwoJZmxvYXQyIHV2ID0gZmxvYXQyKHNoYWRvd1BhcmFtcy56ICogKDEuMCAtIGQpLCAwLjUpOwoJaGFsZiBmYWN0b3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS4wMDByLmE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGZhY3Rvcik7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAIAEAAAABSCQKL3IYIJ2AAAAAAAIAEAAAABLBCABAAAAABAEGABBAMAAACAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAueSwgdWNsYW1wX1MxX2MwX2MwX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclkgPSBoYWxmKHN1YnNldENvb3JkLnkgLSBjbGFtcGVkQ29vcmQueSk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclkpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQNNQSEIYAQAADQAAAABAAAAAAABAEMVC2TBEKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABJBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAABIADAAAAAIAAAAAAAIID":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAOAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAAAQCAAAAAVQEEAQAAAAAQCDAAQQGAAAAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBVWKMG7QAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAApAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnNhbXBsZXJFeHRlcm5hbE9FUyB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfM19TMCk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMihoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzIuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMi54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAGsCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAEQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAA8AwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXJFeHRlcm5hbE9FUyB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACkAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAqQEAAHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAth0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0IGR5MCA9IHVpbm5lclJlY3RfUzIuVCAtIHNrX0ZyYWdDb29yZC55OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChmbG9hdDIoZHh5MS54LCBtYXgoZHkwLCBkeHkxLnkpKSwgMC4wKTsKCWhhbGYgbGVmdEFscGhhID0gaGFsZihzYXR1cmF0ZShza19GcmFnQ29vcmQueCAtIHVpbm5lclJlY3RfUzIuTCkpOwoJaGFsZiBhbHBoYSA9IGxlZnRBbHBoYSAqIGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAANAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NoAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAADkDAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAWBRAAAABAAAAANAEIQCAAAAAAAAAAAAAUABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1N5AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzRfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIHBvc2l0aW9uLnh5MTsKCX0KfQoAAAAAAAAAzAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAzAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAAJQAAAAAAAACAAAAADYCAAIAAAAACABKAYABAAAAAFAEEQCEAAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAA":"DAAAAExTS1MIAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAC0HQAAZmxvYXQ0IGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwOwpmbG9hdDQgZnJhZ0NvbG9yX1MxX2MwOwpmbG9hdCB1X2FscGhhX1MxX2MwOwpmbG9hdCB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfYmx1cl9TMV9jMDsKZmxvYXQgdV9yYWRpdXNfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzI7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzJfYzBfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMiwgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzApLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MyX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGV2aWNlU3BhY2VfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMl9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfZHN0X2luKERldmljZVNwYWNlX1MyX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAGULKMMQKAAAAAAMAAAAAIAAAAAAGIRBNAWEYZAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAACoBAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwLngsIHVjbGFtcF9TMV9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABUDB7AHU6AIAAAYAAAAAQAAAAAEARR2BR7WDKMAAAAAMAAAAAAAAAAAABIADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAPQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBSZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAEUDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzAueHksIHVjbGFtcF9TMV9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAAAEAAAABSCQKL3IYIJ2AAAAAAAAAEAAAABLBAABAAAAABAEGABBAMAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAACoFAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IEdhdXNzaWFuQmx1cjFEX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQmx1cjFEX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAACAAAAAVREAAQAAAAAQCDAAQQGAABAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAGVXOVKVEAAAAADAAAAAFQ454NUDACAAAIAQZUOAMQAAAAIAAAAAEARTKLVK5LSAAAAABQAAAAAYGP6G2BSBAAAAAIO2HAGIAAAAAAAEAAAAAZ3RZTY3IGAEAAAAAAAAAGARI4UKA4WAAAAAAAEAAAABSMQII2XAGAAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"DAAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAAAAyhsAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACXAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAABsdAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBUAFS7EOCAAAAAGZJY26AAQAAAA2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAAAAEAAAAAZ3FHDLYADAAAABKDVK5LSCAIAABQAAAAAAACAAAGAT3RWSMYIAAAAADWRYBSQAAAAAAAQAAAAGJJOXLVOIIBAAAGAAAAAAAAIAAAIAPOH2NTBAAAAAAOKFAOLAAAAAAAEAAAAAMQQAIAAAYGP6G2BSBAAACAAAAAAAAM5S4Z4NUDACAAAAAAAAADAIUOKFAOLAAAAAAACAAAAAZGIEENLQDAAAAAAAAAAABQAKAIAAIAAAADIBCEAQAAAAAAAAAAAIADQAAAAUAAAAAAAIIDA":"DAAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc183X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAQAAAG4KAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIwbAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAB2BQ7SD2OAAAAAMAAAAAEAHQAACAAAAAAQCGHIGP7YJJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAAAAB2AAAAAAACAAAAAEBSAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAA2CAAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyX2MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMl9jMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyX2MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMl9jMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMl9jMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyX2MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMChfc3JjKSwgQ2lyY3VsYXJSUmVjdF9TMl9jMShfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChoYWxmKGNvdmVyYWdlKSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQmxlbmRfUzIob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAQCAAAAAVREEAQAAAAAQCDAAQQGAABAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAHwQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HWJQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OaAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGZsb2F0MiBsb2NhbENvb3JkOwppbiBmbG9hdDQgdGV4U3Vic2V0OwpvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpmbGF0IG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXZ0ZXhTdWJzZXRfUzAgPSB0ZXhTdWJzZXQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAAABcAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmZsYXQgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglmbG9hdDQgc3Vic2V0OwoJc3Vic2V0ID0gdnRleFN1YnNldF9TMDsKCXRleENvb3JkID0gY2xhbXAodGV4Q29vcmQsIHN1YnNldC5MVCwgc3Vic2V0LlJCKTsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoY292ZXJhZ2UpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlCgAAAGxvY2FsQ29vcmQAAAkAAAB0ZXhTdWJzZXQAAAAAAAAA","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAACAAAEAAAABSCQKL3IYIJ2AAAAACAAAEAAAABLRAABAAAAABAEGABBAMAAQAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclggPSBoYWxmKHN1YnNldENvb3JkLnggLSBjbGFtcGVkQ29vcmQueCk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclgpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA"}} \ No newline at end of file