From bfc0a678c16485ea35105ec941fdc00fe3ff413a Mon Sep 17 00:00:00 2001 From: Blankj <625783482@qq.com> Date: Sun, 25 Aug 2019 17:52:45 +0800 Subject: [PATCH] see 08/25 log --- CHANGELOG.md | 4 + README-CN.md | 2 +- README.md | 2 +- buildSrc/src/main/groovy/Config.groovy | 4 +- buildSrc/src/main/groovy/GitUtils.java | 12 --- gradle.properties | 3 +- gradle/wrapper/gradle-wrapper.properties | 2 +- lib/utilcode/README-CN.md | 15 ++- lib/utilcode/README.md | 17 +++- .../constant/PermissionConstants.java | 2 +- .../com/blankj/utilcode/util/AppUtils.java | 2 +- .../blankj/utilcode/util/ConvertUtils.java | 10 +- .../com/blankj/utilcode/util/CrashUtils.java | 2 +- .../com/blankj/utilcode/util/DeviceUtils.java | 37 ++++--- .../blankj/utilcode/util/EncryptUtils.java | 2 +- .../com/blankj/utilcode/util/FileUtils.java | 2 +- .../com/blankj/utilcode/util/ImageUtils.java | 93 +++++++++++++----- .../blankj/utilcode/util/KeyboardUtils.java | 10 +- .../com/blankj/utilcode/util/LogUtils.java | 24 ++++- .../com/blankj/utilcode/util/PhoneUtils.java | 13 ++- .../com/blankj/utilcode/util/ScreenUtils.java | 4 +- .../com/blankj/utilcode/util/SizeUtils.java | 10 +- .../com/blankj/utilcode/util/ViewUtils.java | 27 ++++- .../blankj/utilcode/util/ImageUtilsTest.java | 26 +++++ .../com/blankj/utilcode/util/TestConfig.java | 2 + .../src/test/res/image/ic_launcher.bmp | Bin 0 -> 49208 bytes .../src/test/res/image/ic_launcher.gif | Bin 0 -> 2195 bytes .../src/test/res/image/ic_launcher.ico | Bin 0 -> 1150 bytes .../src/test/res/image/ic_launcher.jpg | Bin 0 -> 14725 bytes .../src/test/res/image/ic_launcher.png | Bin 0 -> 2793 bytes .../src/test/res/image/ic_launcher.tif | Bin 0 -> 80948 bytes .../src/test/res/image/ic_launcher.webp | Bin 0 -> 1484 bytes 32 files changed, 228 insertions(+), 99 deletions(-) delete mode 100644 buildSrc/src/main/groovy/GitUtils.java create mode 100644 lib/utilcode/src/test/java/com/blankj/utilcode/util/ImageUtilsTest.java create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.bmp create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.gif create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.ico create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.jpg create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.png create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.tif create mode 100644 lib/utilcode/src/test/res/image/ic_launcher.webp diff --git a/CHANGELOG.md b/CHANGELOG.md index f48fe841..99103073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +* `19/08/25` [upd] ImageUtils#getImageType. [add] LogUtils# Publish v1.25.9. +* `19/08/24` [fix] PhoneUtils#getIMEI crash on SDK 29. +* `19/08/23` [add] ViewUtils#isLayoutRtl. +* `19/08/22` [add] LogUtils#getLogFiles. * `19/08/13` [add] MapUtils and MapUtilsTest. Publish v1.25.8. * `19/08/12` [add] CollectionUtils and CollectionUtilsTest. * `19/08/11` [add] ArrayUtils and ArrayUtilsTest. diff --git a/README-CN.md b/README-CN.md index 82d01dc0..ed00c0f6 100644 --- a/README-CN.md +++ b/README-CN.md @@ -51,7 +51,7 @@ [frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame_cn.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.8-brightgreen.svg +[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.9-brightgreen.svg [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg diff --git a/README.md b/README.md index 103970b8..9015f967 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ If this project helps you a lot and you want to support the project's developmen [frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.8-brightgreen.svg +[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.9-brightgreen.svg [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy index 692066d5..4335dca9 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -14,8 +14,8 @@ class Config { static compileSdkVersion = 28 static minSdkVersion = 14 static targetSdkVersion = 28 - static versionCode = 1_025_008 - static versionName = '1.25.8-alpha1'// E.g. 1.9.72 => 1,009,072 + static versionCode = 1_025_009 + static versionName = '1.25.9'// E.g. 1.9.72 => 1,009,072 // lib version static kotlin_version = '1.3.10' diff --git a/buildSrc/src/main/groovy/GitUtils.java b/buildSrc/src/main/groovy/GitUtils.java deleted file mode 100644 index d36a3c7b..00000000 --- a/buildSrc/src/main/groovy/GitUtils.java +++ /dev/null @@ -1,12 +0,0 @@ -package PACKAGE_NAME; - -/** - *
- *     author: blankj
- *     blog  : http://blankj.com
- *     time  : 2019/08/16
- *     desc  :
- * 
- */ -public class GitUtils { -} diff --git a/gradle.properties b/gradle.properties index 932a9819..63f495a0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,7 @@ org.gradle.jvmargs=-Xmx8192m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -XX:-UseGCOverheadLimit -Dfile.encoding=UTF-8 org.gradle.daemon=true #org.gradle.configureondemand=true -#org.gradle.parallel=true +org.gradle.parallel=true +org.gradle.caching=true #-Dorg.gradle.debug=true --no-daemon \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1129dccf..e4718dff 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md index 66b65419..d638ebbd 100644 --- a/lib/utilcode/README-CN.md +++ b/lib/utilcode/README-CN.md @@ -2,10 +2,10 @@ Gradle: ```groovy -implementation 'com.blankj:utilcode:1.25.8' +implementation 'com.blankj:utilcode:1.25.9' // if u use AndroidX, use the following -implementation 'com.blankj:utilcodex:1.25.8' +implementation 'com.blankj:utilcodex:1.25.9' ``` @@ -1069,6 +1069,15 @@ vibrate: 震动 cancel : 取消 ``` +* ### 视图相关 -> [ViewUtils.java][view.java] +``` +setViewEnabled : 设置视图是否可用 +runOnUiThread : 在 UI 线程运行 +runOnUiThreadDelayed: 在 UI 线程延迟运行 +isLayoutRtl : 布局是否从右到左 +fixScrollViewTopping: 修复 ScrollView 置顶问题 +``` + * ### 压缩相关 -> [ZipUtils.java][zip.java] -> [Test][zip.test] ``` zipFiles : 批量压缩文件 @@ -1262,5 +1271,7 @@ getComments : 获取压缩文件中的注释链表 [vibrate.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java [vibrate.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt +[view.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java + [zip.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ZipUtils.java [zip.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/ZipUtilsTest.java diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md index 230bd18b..c735e790 100644 --- a/lib/utilcode/README.md +++ b/lib/utilcode/README.md @@ -2,10 +2,10 @@ Gradle: ```groovy -implementation 'com.blankj:utilcode:1.25.8' +implementation 'com.blankj:utilcode:1.25.9' // if u use AndroidX, use the following -implementation 'com.blankj:utilcodex:1.25.8' +implementation 'com.blankj:utilcodex:1.25.9' ``` @@ -1069,6 +1069,15 @@ vibrate cancel ``` +* ### About View -> [ViewUtils.java][view.java] +``` +setViewEnabled +runOnUiThread +runOnUiThreadDelayed +isLayoutRtl +fixScrollViewTopping +``` + * ### About Zip -> [ZipUtils.java][zip.java] -> [Test][zip.test] ``` zipFiles @@ -1187,7 +1196,7 @@ getComments [log.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/log/LogActivity.kt [map.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/MapUtils.java -[map.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/MapUtilsTest.java +[map.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/MapUtilsTest.java [metaData.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java [metaData.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/metaData/MetaDataActivity.kt @@ -1262,5 +1271,7 @@ getComments [vibrate.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java [vibrate.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt +[view.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java + [zip.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/ZipUtils.java [zip.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/ZipUtilsTest.java diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java b/lib/utilcode/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java index 76f7e9a2..489de57a 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java @@ -64,7 +64,7 @@ public final class PermissionConstants { permission.RECEIVE_WAP_PUSH, permission.RECEIVE_MMS, }; private static final String[] GROUP_STORAGE = { - permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE + permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE, }; @StringDef({CALENDAR, CAMERA, CONTACTS, LOCATION, MICROPHONE, PHONE, SENSORS, SMS, STORAGE,}) diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java index 67c3c628..cf6efd6b 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java @@ -865,7 +865,7 @@ public final class AppUtils { return true; } - private static final char HEX_DIGITS[] = + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private static byte[] hashTemplate(final byte[] data, final String algorithm) { diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java index 4abbfb56..0c36f1b4 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java @@ -35,7 +35,7 @@ public final class ConvertUtils { throw new UnsupportedOperationException("u can't instantiate me..."); } - private static final char hexDigits[] = + private static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; /** @@ -581,7 +581,7 @@ public final class ConvertUtils { * @return value of px */ public static int dp2px(final float dpValue) { - final float scale = Resources.getSystem().getDisplayMetrics().density; + final float scale = Utils.getApp().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @@ -592,7 +592,7 @@ public final class ConvertUtils { * @return value of dp */ public static int px2dp(final float pxValue) { - final float scale = Resources.getSystem().getDisplayMetrics().density; + final float scale = Utils.getApp().getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } @@ -603,7 +603,7 @@ public final class ConvertUtils { * @return value of px */ public static int sp2px(final float spValue) { - final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + final float fontScale = Utils.getApp().getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @@ -614,7 +614,7 @@ public final class ConvertUtils { * @return value of sp */ public static int px2sp(final float pxValue) { - final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + final float fontScale = Utils.getApp().getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java index 18b5f814..8f9e2e2b 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java @@ -41,7 +41,7 @@ public final class CrashUtils { private static final String FILE_SEP = System.getProperty("file.separator"); @SuppressLint("SimpleDateFormat") - private static final Format FORMAT = new SimpleDateFormat("MM-dd HH-mm-ss"); + private static final Format FORMAT = new SimpleDateFormat("MM-dd_HH-mm-ss"); private static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER; private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER; diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java index fdfc398d..0741d4f3 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java @@ -22,6 +22,7 @@ import java.util.Enumeration; import java.util.UUID; import static android.Manifest.permission.ACCESS_WIFI_STATE; +import static android.Manifest.permission.CHANGE_WIFI_STATE; import static android.Manifest.permission.INTERNET; import static android.content.Context.WIFI_SERVICE; @@ -106,11 +107,12 @@ public final class DeviceUtils { /** * Return the MAC address. *

Must hold {@code }, - * {@code }

+ * {@code }, + * {@code }

* * @return the MAC address */ - @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET}) + @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET, CHANGE_WIFI_STATE}) public static String getMacAddress() { String macAddress = getMacAddress((String[]) null); if (!macAddress.equals("") || getWifiEnabled()) return macAddress; @@ -126,10 +128,18 @@ public final class DeviceUtils { return manager.isWifiEnabled(); } + /** + * Enable or disable wifi. + *

Must hold {@code }

+ * + * @param enabled True to enabled, false otherwise. + */ + @RequiresPermission(CHANGE_WIFI_STATE) private static void setWifiEnabled(final boolean enabled) { @SuppressLint("WifiManagerLeak") WifiManager manager = (WifiManager) Utils.getApp().getSystemService(WIFI_SERVICE); if (manager == null) return; + if (enabled == manager.isWifiEnabled()) return; manager.setWifiEnabled(enabled); } @@ -372,9 +382,8 @@ public final class DeviceUtils { /** * Return the unique device id. *
{1}{UUID(macAddress)}
- *
{2}{UUID(deviceId  )}
- *
{3}{UUID(androidId )}
- *
{4}{UUID(random    )}
+ *
{2}{UUID(androidId )}
+ *
{9}{UUID(random    )}
* * @return the unique device id */ @@ -386,9 +395,8 @@ public final class DeviceUtils { /** * Return the unique device id. *
{prefix}{1}{UUID(macAddress)}
- *
{prefix}{2}{UUID(deviceId  )}
- *
{prefix}{3}{UUID(androidId )}
- *
{prefix}{4}{UUID(random    )}
+ *
{prefix}{2}{UUID(androidId )}
+ *
{prefix}{9}{UUID(random    )}
* * @param prefix The prefix of the unique device id. * @return the unique device id @@ -414,13 +422,8 @@ public final class DeviceUtils { return saveUdid(prefix + 2, androidId); } - final String deviceId = ((TelephonyManager) Utils.getApp().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); - if (!TextUtils.isEmpty(deviceId)) { - return saveUdid(prefix + 3, deviceId); - } - } catch (Exception ignore) {/**/} - return saveUdid(prefix + 4, ""); + return saveUdid(prefix + 9, ""); } } } @@ -448,12 +451,6 @@ public final class DeviceUtils { return false; } return uniqueDeviceId.substring(st + 1).equals(getUdid("", androidId)); - } else if (type.startsWith("3")) { - final String deviceId = ((TelephonyManager) Utils.getApp().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); - if (TextUtils.isEmpty(deviceId)) { - return false; - } - return uniqueDeviceId.substring(st + 1).equals(getUdid("", deviceId)); } return false; } diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java index d20ee711..d5edd2b2 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java @@ -1152,7 +1152,7 @@ public final class EncryptUtils { return ret; } - private static final char HEX_DIGITS[] = + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private static String bytes2HexString(final byte[] bytes) { diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java index 2610a3a3..44f8987f 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java @@ -1221,7 +1221,7 @@ public final class FileUtils { // other utils methods /////////////////////////////////////////////////////////////////////////// - private static final char HEX_DIGITS[] = + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private static String bytes2HexString(final byte[] bytes) { diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java index 83e01eb1..ed79e362 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java @@ -1562,7 +1562,7 @@ public final class ImageUtils { * @param filePath The path of file. * @return the type of image */ - public static String getImageType(final String filePath) { + public static ImageType getImageType(final String filePath) { return getImageType(getFileByPath(filePath)); } @@ -1572,12 +1572,12 @@ public final class ImageUtils { * @param file The file. * @return the type of image */ - public static String getImageType(final File file) { - if (file == null) return ""; + public static ImageType getImageType(final File file) { + if (file == null) return null; InputStream is = null; try { is = new FileInputStream(file); - String type = getImageType(is); + ImageType type = getImageType(is); if (type != null) { return type; } @@ -1592,36 +1592,57 @@ public final class ImageUtils { e.printStackTrace(); } } - return getFileExtension(file.getAbsolutePath()).toUpperCase(); - } - - private static String getFileExtension(final String filePath) { - if (isSpace(filePath)) return filePath; - int lastPoi = filePath.lastIndexOf('.'); - int lastSep = filePath.lastIndexOf(File.separator); - if (lastPoi == -1 || lastSep >= lastPoi) return ""; - return filePath.substring(lastPoi + 1); + return null; } - private static String getImageType(final InputStream is) { + private static ImageType getImageType(final InputStream is) { if (is == null) return null; try { - byte[] bytes = new byte[8]; - return is.read(bytes, 0, 8) != -1 ? getImageType(bytes) : null; + byte[] bytes = new byte[12]; + return is.read(bytes) != -1 ? getImageType(bytes) : null; } catch (IOException e) { e.printStackTrace(); return null; } } - private static String getImageType(final byte[] bytes) { - if (isJPEG(bytes)) return "JPEG"; - if (isGIF(bytes)) return "GIF"; - if (isPNG(bytes)) return "PNG"; - if (isBMP(bytes)) return "BMP"; - return null; + private static ImageType getImageType(final byte[] bytes) { + String type = bytes2HexString(bytes).toUpperCase(); + if (type.contains("FFD8FF")) { + return ImageType.TYPE_JPG; + } else if (type.contains("89504E47")) { + return ImageType.TYPE_PNG; + } else if (type.contains("47494638")) { + return ImageType.TYPE_GIF; + } else if (type.contains("49492A00") || type.contains("4D4D002A")) { + return ImageType.TYPE_TIFF; + } else if (type.contains("424D")) { + return ImageType.TYPE_BMP; + } else if (type.startsWith("52494646") && type.endsWith("57454250")) {//524946461c57000057454250-12个字节 + return ImageType.TYPE_WEBP; + } else if (type.contains("00000100") || type.contains("00000200")) { + return ImageType.TYPE_ICO; + } else { + return ImageType.TYPE_UNKNOWN; + } } + private static final char[] hexDigits = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + + private static String bytes2HexString(final byte[] bytes) { + if (bytes == null) return ""; + int len = bytes.length; + if (len <= 0) return ""; + char[] ret = new char[len << 1]; + for (int i = 0, j = 0; i < len; i++) { + ret[j++] = hexDigits[bytes[i] >> 4 & 0x0f]; + ret[j++] = hexDigits[bytes[i] & 0x0f]; + } + return new String(ret); + } + + private static boolean isJPEG(final byte[] b) { return b.length >= 2 && (b[0] == (byte) 0xFF) && (b[1] == (byte) 0xD8); @@ -1982,4 +2003,32 @@ public final class ImageUtils { } } } + + public enum ImageType { + TYPE_JPG("jpg"), + + TYPE_PNG("png"), + + TYPE_GIF("gif"), + + TYPE_TIFF("tiff"), + + TYPE_BMP("bmp"), + + TYPE_WEBP("webp"), + + TYPE_ICO("ico"), + + TYPE_UNKNOWN("unknown"); + + String value; + + ImageType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } } diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java index 28d79d41..a0f5c5a8 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java @@ -108,15 +108,7 @@ public final class KeyboardUtils { InputMethodManager imm = (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm == null) return; - imm.hideSoftInputFromWindow(view.getWindowToken(), 0, new ResultReceiver(new Handler()) { - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN - || resultCode == InputMethodManager.RESULT_SHOWN) { - toggleSoftInput(); - } - } - }); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } /** diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java index dfbf997c..e7f15a2a 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/LogUtils.java @@ -36,10 +36,13 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.Formatter; import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -233,6 +236,21 @@ public final class LogUtils { } } + public static List getLogFiles() { + String dir = CONFIG.getDir(); + File logDir = new File(dir); + if (!logDir.exists()) return new ArrayList<>(); + File[] files = logDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return isMatchLogFileName(name); + } + }); + List list = new ArrayList<>(); + Collections.addAll(list, files); + return list; + } + private static TagHead processTagAndHead(String tag) { if (!CONFIG.mTagIsSpace && !CONFIG.isLogHeadSwitch()) { tag = CONFIG.getGlobalTag(); @@ -527,7 +545,7 @@ public final class LogUtils { File[] files = parentFile.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { - return name.matches("^" + CONFIG.getFilePrefix() + "_[0-9]{4}_[0-9]{2}_[0-9]{2}_.*$"); + return isMatchLogFileName(name); } }); if (files == null || files.length <= 0) return; @@ -555,6 +573,10 @@ public final class LogUtils { } } + private static boolean isMatchLogFileName(String name) { + return name.matches("^" + CONFIG.getFilePrefix() + "_[0-9]{4}_[0-9]{2}_[0-9]{2}_.*$"); + } + private static String findDate(String str) { Pattern pattern = Pattern.compile("[0-9]{4}_[0-9]{2}_[0-9]{2}"); Matcher matcher = pattern.matcher(str); diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/PhoneUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/PhoneUtils.java index c71cb074..42cab859 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/PhoneUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/PhoneUtils.java @@ -1,24 +1,20 @@ package com.blankj.utilcode.util; import android.annotation.SuppressLint; -import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.support.annotation.RequiresPermission; -import android.telephony.SmsManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.List; import static android.Manifest.permission.CALL_PHONE; import static android.Manifest.permission.READ_PHONE_STATE; -import static android.Manifest.permission.SEND_SMS; /** *
@@ -46,6 +42,7 @@ public final class PhoneUtils {
 
     /**
      * Return the unique device id.
+     * 

If the version of SDK is greater than 28, it will return an empty string.

*

Must hold {@code }

* * @return the unique device id @@ -53,6 +50,9 @@ public final class PhoneUtils { @SuppressLint("HardwareIds") @RequiresPermission(READ_PHONE_STATE) public static String getDeviceId() { + if (Build.VERSION.SDK_INT >= 29) { + return ""; + } TelephonyManager tm = getTelephonyManager(); String deviceId = tm.getDeviceId(); if (!TextUtils.isEmpty(deviceId)) return deviceId; @@ -78,6 +78,7 @@ public final class PhoneUtils { /** * Return the IMEI. + *

If the version of SDK is greater than 28, it will return an empty string.

*

Must hold {@code }

* * @return the IMEI @@ -89,6 +90,7 @@ public final class PhoneUtils { /** * Return the MEID. + *

If the version of SDK is greater than 28, it will return an empty string.

*

Must hold {@code }

* * @return the MEID @@ -101,6 +103,9 @@ public final class PhoneUtils { @SuppressLint("HardwareIds") @RequiresPermission(READ_PHONE_STATE) public static String getImeiOrMeid(boolean isImei) { + if (Build.VERSION.SDK_INT >= 29) { + return ""; + } TelephonyManager tm = getTelephonyManager(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (isImei) { diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ScreenUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ScreenUtils.java index 7390fcee..a41a6f2b 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ScreenUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ScreenUtils.java @@ -100,7 +100,7 @@ public final class ScreenUtils { * @return the density of screen */ public static float getScreenDensity() { - return Resources.getSystem().getDisplayMetrics().density; + return Utils.getApp().getResources().getDisplayMetrics().density; } /** @@ -109,7 +109,7 @@ public final class ScreenUtils { * @return the screen density expressed as dots-per-inch */ public static int getScreenDensityDpi() { - return Resources.getSystem().getDisplayMetrics().densityDpi; + return Utils.getApp().getResources().getDisplayMetrics().densityDpi; } /** diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/SizeUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/SizeUtils.java index 5ef9047e..f5e0acf8 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/SizeUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/SizeUtils.java @@ -27,7 +27,7 @@ public final class SizeUtils { * @return value of px */ public static int dp2px(final float dpValue) { - final float scale = Resources.getSystem().getDisplayMetrics().density; + final float scale = Utils.getApp().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @@ -38,7 +38,7 @@ public final class SizeUtils { * @return value of dp */ public static int px2dp(final float pxValue) { - final float scale = Resources.getSystem().getDisplayMetrics().density; + final float scale = Utils.getApp().getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } @@ -49,7 +49,7 @@ public final class SizeUtils { * @return value of px */ public static int sp2px(final float spValue) { - final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + final float fontScale = Utils.getApp().getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @@ -60,7 +60,7 @@ public final class SizeUtils { * @return value of sp */ public static int px2sp(final float pxValue) { - final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; + final float fontScale = Utils.getApp().getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } @@ -75,7 +75,7 @@ public final class SizeUtils { * metrics depending on its unit. */ public static float applyDimension(final float value, final int unit) { - DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); + DisplayMetrics metrics = Utils.getApp().getResources().getDisplayMetrics(); switch (unit) { case TypedValue.COMPLEX_UNIT_PX: return value; diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java index 77f9421d..fa651b4a 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java @@ -1,8 +1,12 @@ package com.blankj.utilcode.util; +import android.os.Build; +import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import java.util.Locale; + /** *
  *     author: Blankj
@@ -63,9 +67,27 @@ public class ViewUtils {
     }
 
     /**
-     * 用于解决ScrollView嵌套ListView/GridView/WebView/RecyclerView等无法置顶问题
+     * Return whether horizontal layout direction of views are from Right to Left.
      *
-     * @param view ScrollView嵌套的跟视图
+     * @return {@code true}: yes
{@code false}: no + */ + public static boolean isLayoutRtl() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + Locale primaryLocale; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + primaryLocale = Utils.getApp().getResources().getConfiguration().getLocales().get(0); + } else { + primaryLocale = Utils.getApp().getResources().getConfiguration().locale; + } + return TextUtils.getLayoutDirectionFromLocale(primaryLocale) == View.LAYOUT_DIRECTION_RTL; + } + return false; + } + + /** + * Fix the problem of topping the ScrollView nested ListView/GridView/WebView/RecyclerView. + * + * @param view The root view inner of ScrollView. */ public static void fixScrollViewTopping(View view) { view.setFocusable(false); @@ -84,5 +106,4 @@ public class ViewUtils { } } } - } \ No newline at end of file diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/ImageUtilsTest.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/ImageUtilsTest.java new file mode 100644 index 00000000..486df32d --- /dev/null +++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/ImageUtilsTest.java @@ -0,0 +1,26 @@ +package com.blankj.utilcode.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2019/08/25
+ *     desc  : test ImageUtils
+ * 
+ */ +public class ImageUtilsTest extends BaseTest { + + @Test + public void getImageType() { + Assert.assertEquals(ImageUtils.ImageType.TYPE_JPG, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.jpg")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_PNG, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.png")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_GIF, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.gif")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_TIFF, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.tif")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_BMP, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.bmp")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_WEBP, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.webp")); + Assert.assertEquals(ImageUtils.ImageType.TYPE_ICO, ImageUtils.getImageType(TestConfig.PATH_IMAGE + "ic_launcher.ico")); + } +} diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/TestConfig.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/TestConfig.java index 6ea0c4b4..4075a147 100644 --- a/lib/utilcode/src/test/java/com/blankj/utilcode/util/TestConfig.java +++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/TestConfig.java @@ -32,5 +32,7 @@ public class TestConfig { static final String PATH_FILE = TEST_PATH + "file" + FILE_SEP; + static final String PATH_IMAGE = TEST_PATH + "image" + FILE_SEP; + static final String PATH_ZIP = TEST_PATH + "zip" + FILE_SEP; } diff --git a/lib/utilcode/src/test/res/image/ic_launcher.bmp b/lib/utilcode/src/test/res/image/ic_launcher.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2880951dd963b2c42fd932b1f25b3cbcff942c39 GIT binary patch literal 49208 zcmeI5U9VP06~~X>dgqlN!B1ek_TCtcZ@p;Kh;0=OMW~)On6_HwO*ou31tn6jv=j=Z zBub4Gf@pzY+XKWdQoVtCi2P=05oIDgON=fA9bQ-;d0Fg3{dFM^DVnef(qc_k#-l`R|DTTz&VSZ@zuu zFRwoPrwhM)?vFp?I(+)RL%;uCNDnU@}I#izFh2!lu?@C4n8 z@czHAVQ)vCU)LM3NdqAm;vr_oizl1Vt5uI8(+XDcpS5%!Pd_L%#LAgACU!DlJl{20s5a(_@Y>}U zCK2J3(1e1hnP!x|v?kwGqSv&(i?Y3dsv3j{bB29RlVPCp81@Knzw^eVBg`gvHT5Wt z`YIdkrV*oS9R9%*-+lboD<3)dt)K4w#zT+Z=3G?r5e*I;ze}U_sM?_ZP!uS^-+yei z19;^2=LeSWdv?{R5N;J_5DJI^S_Lx=ud zaa_v&$Iz@FN2GK+HXzKR8JS8Nub zpto7D`|zFH_T1qZ0O6TFHUpxL_5~%ItW*l%<=o51w(q@Dpy%PeI)TMN+gGQ9px%_x^SDiC_It z(C8>A^}&B|@BEg78@Lwt-)|EEM|ww8D8Wy4~E!)(h; zazrF37&Hj1rm_%xnF9MxE@;NG+oW!aTbEtwoUo92MCz>1SwNc3R!v{70zMS%Ikinc zsA;KRh%tU;zz_1`$NHpzv5ZpsLM`yK@dr|6UPx*D=uY0)tRv+Vymt9T(_5s#pnBM) zWkvA8fB(s~sRBrQ%@oiZKYcp+{6Y$p7Q&!O>emH-(^B%YCnK#!K@Py1_N@iqN((7q zbiYr(rd2T0pf30r|IRZ{o6a)|tqLY(_B{6wts1IZ~!2Q^uiSTHphn9Ue`e-4$#K7I%J~OJ)-f&^6C+$st6pTAM5zqNXyi3rhNgXRs^NPj{F* zJqra3JC=Qa!%bWiCI>!9nsjKM^EX`dKLwxz3byXLd(FD9UcVMs{OI(hh*fJo>eKQC zI)j_?X^R2eFF32YW3CxpT-g*10=@tU_$7<4&4T9PLUsJ<@Y?(T*>vosYzhVhAM^mf zaPhS%U|X$x#95b!Yzl@2ALszT{9w6F!BCDUgMz`q2RFbk41R3zr3?jwEXPR{i~)S$ z0{rUu3k!7H|Gq#;!AQUt{4rNStc!nPAt^yozI?P&Fdpy$yi@QEp`_`^l#;9t#;8>C z5e;ZoWd)B=Fe>m3KBFphN5Kv7l|*+z!P+x#R5`t%RAK7P>QZpmfl~{6?r|R3OdX=G z<*!A-!qKyv9=rZ#1N)Ip*TT<6|5YfkpBD%PoVeh)3x_U(Ke(onk7$tbJB!(X-Dm*_ z{JsMK3-c8Y1@_a=czKHNBQod}7UV=0_*ADLj=BHo6yHZw2tMb63=V78-@JLv%4=8O zsW=Nv=lTL71<#KaYC6KNo8xeR1Nf_N{v20D3OGT*Ar=l@IKN*IeyQXm8uar%qJFl( zdX|IW*QG!|kGg&z5#V=}f71hQw~T;akpeyb(z3hv5dr>q@VCML!J3-{aR1*bjwqD^ z+H+LNoF5}bt+EyXe%Ba+aRpoyxJ^2PQSv?_ zG5+qB034$o-WZ3!aq-qQE4~y&+o?W%Z4 zPT)P#IO8M0H-MXh9(jmJ1s@^xKjP!KOI)d>pBBcu3V!Mw5v;xoa4bIw`8@DZQ~5hS z%sYsQQ>mnYL7gvZZYA=!XDETR=8Kv(`20MZ7ypxC`AEf#3+D4}9Vz49gKj6Nmxclc z4SqLL3Dk~M+*Wi!65cOt|C%PYEcE%dn!ZwgO{$t23TzoPWykr5khNTp7(d`Uz-n$c zK5&ah{-!oQ+I|hM7;5@@Q++E1OS(gGEgm^i)^4dZsg=fxK!x}%r1b<&(Ye$&`g?WZpWfm}~gG19Tajz!1 zk(Ul7pN~-u;`xof%De$PCbK;$r$D)zLr9bGbWFmz&6@)9Fl8vuFBCNSXGcM9$yC&$ zfI*D`L<&md7f~~&011a-jUU}xS2vr8S`;XE(@NtP37G;JfzZ9HTF#Bw0gsfcggv&^ z#iKhLf6C<)D3dmTsqy@_c&U4V9lMwN@V3?z#{4$&Qg-sXwno8nIR(B9eoc~97&+0! z@2aV0&GIj{qU|)ecjcFxdMl~7pDP(%B89FgNHqx~YEnjs)Qtmg})zDDgZ-Bnqkj|E4_)@bg`J8-ux1!2D99 zK9sd7DEY~7t^a>hh)6xAzInr~uuz!Kcks-(&2vO2p5IMgBI7ZEkr23S1Flj|S_q6J zgBPG6V>wo46@uDTar-`Hd7I*(g#A|%l&0iSSO)eux*PW_`-YeZN`+KQ%5 z`8;>mgm$og>J&gFCW>v7Hx9!pFZEWf2m<#kQ%4W0RE_) zk=$s)u)IDsK{06xx=1gSQ$P$b^D8n6_8;o#sUhP!!@daBYNeF*kY=<@dTKTmM^yeK zD+9^wuV5!6Tc(0-Tuv03gxULKk?fjubc*mv`8pqg!D|T8n7NZ%mk}7TM-^d~P&pwM zW(;|oHCW(L)Mz~tf+60_*u0IrQ^u)Q`K?)e-PC`IFjM#Q4#JvSf(q`9Bj51IK4`g~}a?P`Q$Cq)RGRM3LhgMddXbiJCjH(l*=740CMd2%BTZHe=={ zo8y^fjxv1{DQzV2P|Z=w^Yr`&&*z8tZ|`5;p9}7;Cr$<<00_V=;Lov4bMwKRAXtsqU<`hZzR6m?-*8Ba%h5=-(aV!?w_(lZf{ z{zgRVYNQIgOMBaUB$I=mKJ>r)XY9+YY-2sDks6Tx5XGs=Y_B7 z7v6l5NWU-3*4MDTHHoyGtlsLR%B%CEihx@?x9q=K9Iyenf$ zls(a(E)@|z4&c5F;w1g(#UZ>@fE{Yj>Z^_Kt%(zN5QbVaH-D_khSL@WsY9%|7mV2d zX8d2y{|_b`@^SzG3}F37`|}AvX$t{ErJ^y|G+cVR0Ugvi`Mkc+Ejbm~e>zisCTRF`gq_*d6oqSApAFrpgU&s~IzZf1AQAftw zUzUj9Fke5Jcvm}FF#WOeLxbc~`E2j}V$lL>>1*M_x7D1_!c}iH^W$CR*;afkFI+fjNOy;MQp94X7f*EjJLGU z(DcM6N{mM$N_RT7YU5u=9lf#p0=7wqVC~Bn7Sh!1ty9=O)E1Y{(=YvTuzaxwA z)d|e-T=>CV9A-~!`I235I*WGRjE=Sh1Mcq3*7)Hnzg4;z*@;syE?bR(P4N*HBr;0)uy1$ywN+atLHbZ+>Lb_q_C-G=eCXoA3xG6w9~Vq9MMkozkKZ&! zB#%dvD=efc6sqjsG&XXBjfZkp&}XjAmxNN+zBTjW#8>ns3X2OW+)FQIl#Rr)K8DfB z>4*m|vW%33wO`Mi)&ue za$V7SuZ$FT*)3=IolsZS#HCuiGE~$}F-KxuW$!7T)@}73aCg7%>8K+^FOdqap$G%Z zRSeX5%l?qfIeviXmvSJHX&mf#-_7@5P{$YXfY5ATGgqmVV?L(X%)O?!hddU)EO~OK z?UY~C*#4t?wBhL(QE*42<6A(8?A`Tojahm$IBio1_m_t$ShGDZeJ{MCqHNBH-ttvD zD`nTFlS$}at-nHJY=*-+Vrm!ryFr@g1EF%7j=jrL-o7n6KHofTf>q@h=>YCK`pOjS zdp>@!zWucMJz$43Xdie~u*3kXxIYd6zVZZ>+f@6~-peVO5~ER7=0szDU4Q}SDC7>& zq;JfW<~cMGR~h4K5PDvtd2)K>CVA>!Bd=f2d--(Mw7;Cq`tAsvPs<06I&{QERSE#j zxLOV=evGjHeL_;JO`xgVEAKZ;K z$ND)(y!AVJnZGm2i_`5bJGI;#RkHcLy*Z9<({(n=M=M<3=GXTzEw7<1S*xJ(k&EY; zH%5Otb#Iq!a4z@F#x{kRR8<>q4eZa&t7ms?aKhDo0Y_|f)q<6+p91yP=gw>;ee~iy z-TSMe38k~&1*s-q3OWhm`4juCoKK*35Fqk~dwAhrz=f|JosQ~24yO*hHMR%$mNght zAl}JH(z^U{SN1YW6-`-&>J{uDn|hkiRfmP=_tc%7NwZO-st22QneNWfhBu^Z!kf+& zZ9<~X-2I?Rd*EOS!x%F4yflY%Q5xv?puNgG<-m2IHVVD12r;8KfNRs=4Ri{0RNaPX zlH1WSuk8N;ZB!|^a0E7wFIL|F$lli8aKCR(2z0-`p{0pE8N78YvRGo~20>p6(ZoHp zzNK?WcEKNQ=U@KbNy8&aXi?P=SL`u_yeOAD!vHEZGNeWW0tK!GpQO7YwHjQb_*s7? zM+ktNtX4c(!8PB!VBCe=i@#mVTxMbgx#nx!THxAQ3zx@0KdHBI;>goClYw-KcbEv&G+b4x=FS#pjM# zod^{x@VQF>5)M4e zXvmivoeXwXa9WfPD&cvPBpI~h3BkLnl(6MhWqFuoAJ@OnncBpj2H~wn_`8CXu!kH? zEO!DgSP|;|h;G|!x&gH+CDE9J9g*>vC6DugB&2lBH9dm~8~NQ_kg4_N7m8a^QF zSF9Bs%5mpY0wqHDjw$0F$IDy7J1TR94 z9T|+>Z_L!YBQE>SDZH7g(>Ar(@;>?PLn0r<_Y{f?{df8zJnuq}6y4TR%wAu){6yTz zy2PoS68pc-oBG9a{@Xn0(N|W-TiZR!=Y-9&`(}|#qR)aE_%-B6V#Dv2zs^f2(ZYs41&ON~;{pm)n;0LdNGyrQ*pyVQ)cU~iD7Mm& zqC6{5s0O6P*jO!^h_P4@NsB=9Idd)-8;mhtGMsbIneV$Z^UVm+MZex&LH|d@;6Wh{ z2_cS>(Gi^}=d=hxcYk|kBSt~i&z#;ChOymb6V9N4 z{PkFRJ&Ee>Hxx^sun;qoFL8wRuq~Qk2}NNIK7?C|i{oJIF?YmJdXbsNV*DoYYZ1#% zq0#(_%)2?_)Jg2s*c+JAb&Mwygg?VElo(6qbQ6E}{Zo`HU*V5i5ni#O(IEV~7k7N4 zP_Q*zUs;EJX-tVpiNQ(u0_WyWjp2LsGwOt^*K6RXu$6~3mci(&ofg&tPekU=-)B=b zlAO$u-Izyi(}(TKN6C>d?c#QF6*ECI9M83#x~Td}KB@!d#x>UA{-blqZ@iTpUy6C8 zvQH3CJ3Dn@JjbBMgU5ayuH86+kyHI}dM;u6hZ0AV>e<|@w{_ufwXj?R%tnovcAv(@ zkpY|??8hzJNs4s{Yae`4i)8Kr;;VO2-6@hT^K>Wcz*yFx&_h*b(-g>E<%jDU^m>FY?nL>GlL=rtn?wC2lWXw$SK(|7VTisqVN+~7j z>Xy<)6jHaRN-7CSPer9v2odJD&l%%!Z}DfhQM3GNRejh=W2veZ-DXS4XBFwQreFXoHF`2w7a3(kf}qT;4_ zGngD60-Oo~0F6$xr`u3)Bnln;6Kw!12zwYK?_VZ^puVvTu)CXfdR39abf(OPYVAp0HCSBK)Ecr3;QQqsp@^)a$1KuLAkRg4pmQU!x1ATW}! z5JpK^MO96Gl!hj7g5gLEq=Z!<^&pHg2CJm3q@t#(u7cGf1EfAydGctI%IpPYf1cY}p%l0VDsa)#K>;C?_o+?u!X zN~Ppw+Z@Z?M}IoA=jwx3pMS}}R@KnHh#j>lIkVt;bz=wBeQ{Xy=Do+xme#!P)Q6Om zfV9e}Olqns6jX%Cq|wSif|Vv?RBYBIjzuK6DY!>=LxL)eAa2!))+hVSY2%u&` zxqKf8kzv4c3$PQz^#daOwFH)fBFG*=T3EDCeaH!F_m_H_Pc_$!%-&y~e2%o^fwb^x zMh)-${+6FlWK&~B7h6Y>UX>X#gS*w3BC)vIB07TCxk((nXm`O7Wvx^^icN(s^`{sn>o1WKkjiX2nH%QmJKS#7% z|H6}$)OpR%N$Y$aH`UKmwASnRlfN%*3;e;32(q^sM~P(H^pcMrYAD#b6kado}6UPpUSa8<#hJB>3vCVPv5 zHGkc2J)zpTB5-Y9SGEkgT{Cz8oBA6zbGqB(WEG!xo=WMMM=i;;ipxnG)Ag)&nY6n5 zTH;0g8Eo_MqJ)MSA>9YF%=KQkk?U``d%W%OFT9Ymm2=ZBHgbPbW070X4E;h%qzUt^ z_|5+5r1_f`S7zP9^ET{#`*>yQ+JdHM?{s^T0=PR*_X7i!VC6-uyHtv0mLT z+$H?etDm6{9iG!1$j9?Y2aL5#G9EuOZlEk*pzlp{y;>1<;grAj*}zrIz>3}@^Ltyw znrYp6;Ra6@N1w5eV*zKX*mii<*)D$L=BoPcLvV=~{_byyI~H!^oIayXO?!vSdg7HC zvTgOYCBa_XbDn!_=*sq9cfVC+h2_95ZG z1j(KU-RzcySiiMcLVW zXD)+^jo&(*SQl3Hu4qql)`ZwyeXE}9ehGP%{p^T%p3jagq?YTii?nO>Kde4Kzcp^< z&-ZtkUOPL%ov8fQd%NLxg5#gxRh2G2-&%k2=<#;PV+oZxb-U946 z?<``+27T9^x8{^yyKyV_)`aD&zv#ZBSuKlhVA*UEw%v{Id2L;6Fg`WVEkGTc^f>LQ zP&xO-W#J^ct9}03z;gwWB_|!VIngbli`FhZqg(N`#<;=uY^y=`IXBg*?V0T)8{O;q{bf@*w*wx(vfl}%1IIj6aIDbdqx zcXNOxB!ymOE+S5A7lofrSsnIVtGI8gr_zn@pUED)kIiAeFN=J>I+Ay+%e%7g*ovFM z{6$y3E}!(U!jAm(?v|cs&DNe^-V%xbP$yv?gfjAC{`S z;^pZ(e(Kn;t9gf&u8}2Y$Em)>Z^y?*NqQH_pumr?Rv-J&@3CzccPClT%qiU%+frh1 zw`u7UpUbUnK2Bfg>+a7CHuk<1O!$>8?%Blqt#{uDqq@ zXc#f~PE^@pVdwN)jxe?MY7Bf*=jGWg(f2;4??=~AUV1X&OBYw4>ndiGG@IgcC*Io4{TWps(MyTZ_ZJhM8;eu8_up}g0 z#MdN(mDadn#{BMsW#*C+OWpVTxXg`9WYFq9%eJ`OU#2vqU)yDrSo6h6R@EL*E_s?7 ze(qJZlN+bgy|GvZk%OoGl)qTQJ8`KnL2tHaf;CA>smZwFSa5+Fq3XZq=`WR$m(CU+ zU)kZ**Zr|!n&%zykiR-kHhG%-GhrRb?rq z-FF086JF}kPJJ+3YT3E7@!>E08m$A$%=-MDEuw8Qs3|B=`=rgaoz!U43kfa<4kT>Y zi9ET^u6t72IT1X%Y7=<@)o@V8hZz~a3$Du`_}8e~y(#=t2N*e5-kka5l)N&btYGR>{)?#b?&XjXyC>=g6^%_?j{|o#o3X zQueH;Z@R9-x6qqaZF%$nE!eHldTfQ`zN(M(`SI#g_h0|b#Z_f>=I1)msSl3=*M5{i z7tVHherYK+jA7>9PO(fgKgbe8c60+D>SG(O@sVG@hP54(LHn%tIG@PMET~%Y=(;*I z^~jTJ+nGBgO)^MUjlNV73r>7ESrg&%uvvZj!6pZdrcrqlCarkQe@&G^7DfJ2=FP1% z)#A?t4e2`(-N$HI;d}6o(-9t*|Fz82wCO{T*}cX`Pp`ZwZt0Lg_vbtkHRQT8uFiDY zAeH9uR3k&~__loCA$7WA^gv0S=sI@E7SokpW~oZ^Fy=-lwd&#yq&Kc^#>J(sJw8P# zYJ81n1hY4|Y|W&{j}AOuYZ+_wtlKL@_vnjymwn|Ox_4ubeRV4ODfde9O?;_(OP`LD z&zr@|-BNH>i)X~qo^`2I1O$kyryoz>&Wl&E-Nj>GGh}*q?=eGPs%mA;<2DZNh{)DN z$llr0TiG0aG1o)$AsLFJqktNaBY0$I0zsMrA=p99mxu)tF{mP2ILKEdUKq;fb5ROU zo*0ICl1K!Bl+k-+7!KTZ(Y6aYF$je-M~t*V&~l!z(1#HT`@1di2OxQ8@&>*_KA*i1 z7E1*4Lsu{XQYCzHICa~FI3Cg%(hv;bK@Dx_%oX$cWzY(haJXU)4`l-IqflxW@19p?+g96nD3@CFE_i$Kg%hz+@LLxlqszc7*aK*dGKa~Z7g#DkT2 zp(>V)S{sBDk98*6oGMWR)najd`3+^Z4icz?440o2_0J%mK%oOv5t_(2) z(Et_FH_TV0@B^fb5Q94+HZ%`r%h~*)TYs=u|5mpPnOr&CSIC^T6ybm-J*JQ^SR4+6 z!393a;e{#8r-LB;fK1MOv6vsp<@3V&n`kL8hzLXA+6uTICoFs@LQ{bNvJKE9vjf{K zm!W^xuB5o5GsgnO>GXFBZcg!#+~2fO7!tiOLMbN>uVdTL`Y1F983t_yA{$83=${tA zVNnU%QK$z*V6y>+3vv*L0149%Nl)2706~Hq7$^|r3K|LuK|H@7g7W+V>JTJ=AlWw) z_6>smCQA07;80s2tbuO*mO>&wgEb;r!^rKSj7U9*Q%7t4^H*sWK!B^CixE;nqb_p$ ze}`1DULccejZ`5Jz>r^>5C>vHArKd0KoW=t%Ha?U2?4f$;(^j&8VZXCVB{K>h7u?c z{bC|jo`j36e~6;0p?nFCCHliGXNpMxhd2v_OpO8m1NA@nFXTMv=kW-=-=G^KbyX3U z!-PePxbu*Sh#A(83W@{Z(cn@;E1s@H`cexM@+E>{AXUDQ6UG@>W8D@a+~=b(z(boM z5%b+)9xP;tVHN;D{;LFvhk}Nj7=a)dPx+(azpX!3BIFKxw4lZx4)GR+4S)QoGPq)Y zM%XYa9VX1>`ol3|Pmzbe_dLaNr>+1GBOVpb7ydY#%L!9hN>{GDhXM=?pvHpP3<M~V3Y@Zc7~L)SMAE?5Zv z1l0;f7tTMyHNg;v|B)P>yHk*kAT4kyIekLQ^7*EZmKF0BiQdW`8jH3<=pij+5+GA0 zUVdS~{dZ6VanT7N&N&hX9f^aE#6d^mpd)e6kvQl`9CRcOIuZvRiGz;BK}X`C|7IK% z-FHj|+Y1N^1{c_wfWRa)8)89xC=_h=agZ9?l?|oXYF%Bjub2=y^V1fw_B@stBn4qUfa7(;>aV~rzjH6iF;h7||J&sDVCQ)ei zHnvvCX&E~Lkwzfd;)x_W5ge2u;rf#a=uOCC)BRlM^!Ej74krCdMMp&CzNanAY3-+YJ=s78yCv zg-Glc1=RRQqbx$U>;ykp#Fq$}uv-)m(^S!!NbCm>+H;t6iq3{N2jpmD0o_FiGe8*D zAB12PqdXY#|Hc_8q|5$RFo@m44kpN)Po((UfN`hLZK>1287U%BPU_8PaoDSd zlG@{KDE^A`Q^QDs)3HE2_@5H9m~=K@7|8%8<3uvTV8RLk9A<(W7zsKW$^bnB@yMtc z-rjUio=D8#F=0jjb)s zj-_bt%4bRt=Rn%a=Lw6?1Uv?NrBawAJGLG0e=5xmPa;uSczZI9hPMx;vY8}%GKtI# zRdACBz8Ku0ToI{QfFseC$fAH*inpV%7+BjPAh^ zfdO3AKgAZpEBi}a4i0rII)jP)9N}QXM1~p$`pChYZ`k8+_1xb+8U)e*;poe|5%JmL zXoe7;9R_Uo_gswdmm2VSNVscI2LVF}e*Y1}LXm?BTgZ>Z$=yM~3&V-|{S`5X%{KW< zmLf*fAiHmwgvn+Ad)wH8^$up?ZJA6m-k!~(;O$7EY%-M!6Ir%wg-M5+MDFFbbP6~q zXs7VMeHfM%2cwsPD*a`oEMhq5B-V8${?cv~89e;So)k7uzdESP0yM=CtK4*Rkokr_dFbDoH-Fd5z@vx`7Se&G^

9`}>#wvhW`) zrih!MiVu0eP=LTo3sM|-TXIyq)r{OnEHGk$5etl1V8j9=7WjW;fx&nS%meS@(IA@g z%`a_mlP8nS$P0+X1$C$RQ zG-)O0=_B9ofP-e}Q8SbpqXbAt+XzL&zfk!MkQnWwxmQn?lzF^~KlLJ|ZUX<@`NGkw z!>zEeWO0<|huT??hxJKmZEietd)4TmCXy!8;Ve0R93}8~)8G$uFMs;}h$-H1(=13^ zcJH&YowUqs&es`fD{3)8*Q|2NKhvN+$%PKK9^5$7!&5aMwXdK|oN9G={7M|8tU1Se zzPhP_2WEVKn&8%Yb#AVkPyWN_-G=epN5?aB zf7U;8r{+-y^D>_hBCDt?SetnF=T!2IWH@0mBd4lWIeVwkn$o#G-`~(!PQE_nkTE~S z)4#eDzm?ORsW$EX$G&5JOTT-G4>BC{(joB6m)=X4?Cxd;=S6uD?w9CKljI&#yEpxK z`R7jUJs%eY^Z4oazf56b6Sr=?JnmJAU+dS4+r9F39nbLp`Z8^deOQ8(ml4y4zgKoY zsx*cA;4t*~IRs5UdhLA{J$)CZnwPWI{Y_G_Tho``%cpm~kJ%}MjGHN(Oxse;roHFC zYkM0rdp5%WdoX!gbx5WD^vc8P*36*N=AMm?%-B7hu|&eJQ6k@^?1-cT!dUa5-A`Gq z9<_D%mY@CE^1)%H5Lsoo=EEF|qTQ2H$8TSDNDr~*{q6qa^``mkSr%4*sU>ZLA;z|A ztFwlt`Z>c>`Tn_m`@Y8a;%UEHja zb8s!KJuR&<9s*~!N+N8$epQn_sC?x<`tH7*4DO7V31jTJl9~H~6~9Y;Fn;-E|A*{JbWe)+Ddo!>nquCo%M|rBffkjx-t_bff^OblR4>V>75tG)mfj z)tHvsd9SR(t8{L>yqccUAglVUM6G%BHTibTrlci5ERsm8J?XVU8{P;fsm*;STC1&o z&5fa6n)EQIu46+Z^=(M>%Q2oe{$$rm{wzpo!O7(dYJ&|fY&J1mXwk@7RduU1uh=ce z*GnxBa8k3>s4FTN*Xj5=*J!d?vOccb$4OQVrVvKk;>-*T5Kh2IcYOf4P%?`BgN$;xlZO)k+~R32hN?h5oUqr|0{~*pA?^$S%rEor z0pKJG06v5O05%^0R?{y(@YxOk3QX_)coztW{;l@^|B^czss_6{-;cffE(Sr6^SD0$ zS=-A`lUZHOZ^R$l-VTMNW&|asow!?B*3m-0clBgTjn@$dAuF5NbbV%Fp8u$kSenCV zs`eqU@DXu-baq79W&bGl@tUHLthDg*iwCK3C+=TsAL=7l6-eh~w2FeL2bE2IqTJ^C z^oAOL7AK>z_Gm$7QCDmD zUd&CnbB!LC@m)F-S<4TMJAEYO?6E5s7UyTW8#80Br1v(ZKfMvvew}%$JhS^Iv;fx@8t3X({zz{t@cli@b zj^wUg>ulMc8t&_IL`PCczpP6&jCKljHPrQEE?V5E<2c3+skvbAdVcGfj_At<40bGA z=5tj`($G-Oi8V@BeVde$=w&dcsk*o|NFL}wN^BQPR4vc7@)Ye15muRA>g(0AzX=Xm z+-zXqFwiucxUQ2M-26W37L}BB4kPc#i)lKX#m?y$sbx>{pPyYLoIPgxui(p^;DPvO zT!H!5;A*^q;6-Q0I52dhHv%b0cw0+LUBs5xm&(i>49`2O{VX|t_o+itPEN4T(#z9d zx}DVwzh!Gg$(8Etu{gg4ro!hqS_F0N24dONY(2EIA-xQo-=b!)L z^!oc|tcnVZ&(ANq?5GfyJbu7CY|c7mdR2p$)h~+b!e2oKt5b|a1?vdg7~D{e`%XQygm@=zfhKp}t1#&NiVGi={6-(t zE9YnEj-4ZpB3iDFo;9sAGNtQJo>P3WEumV|)0e)hqqR^$aSbY1FJ@S)H7P{2=DGh( zRpU=4sH_@2Ax;M*_;FO4NWMu4kv&Hbc%P9`-RF63O9o;&W}ksZj#E)#nkFz({g zc(P5-bd7$v(kZ8#E81Z$zCYousbzp6e9pDnF2|rpMOmd>A!mAKs(I*3r9RvwnRTyM zH9(Gdc!kvatXt99_8{ar<;~zT%o7(%`hcgi7dKIeg`2L#){(@BOPu|^KZ#>YeO&OU znCV}b@~PAZ?Y2}Mx~fV3SJn=BNj0?x0~2dG+K!t@AA&Z@vSKdTCn5q6Z(GFCcw*)N z_YyFkoC6e|YH=gTPi-$mh(S zLkbQxaWg^bl>KAXR>glWaSn=bcJ}I*(%R=az{o($vyt?x^MW;x?CpAnwcgF+5@@85 zCsuXT(Uzqe{St+Ks%LJ#!-#Ig62l@np! zB|4KM-Cu$Pf?r=}&$aC#7`6iz&(x)$AFJuNse3Y!_L9^UrnJVw_lXpA6Zclm$1Lf$ z!j&#er2%|jgqmP~A8t%5XJ=`Y$EdbfbnL?-eclV=LTkO;qz|r{8==Bxd=2rDu1$*` zgk`0u8dU~#eY3oS+|2aar1Lyve%{xjzt%Z^y0xx$l{yh+-S3XH+UZyoq^A6vAqt87 zwojpV;n%_}Zuh9a8UGYfpB1i7t)&9W`+(S&1x-mPLDcZc5Q#EnNw_uNWKe7FIx8-H>sm_m<6 zXjriH&`Wi?o&Nn`uc}wO*1;CP@GehGs&+3JuFCNMA`1fWFX z)&0;wW!CzBuI7-(=5MX@xZ^uT{2g&`^U~&q%LW54J(k!>Im01(+lKsKdGrOY2=<4R zD~czQw+AFb$MmR|!Qkht+H-s_(bOqRm{2%78(pcxZ8fq{rs560}oLE+7^v**n)9z zz^uRBSPmh&Kjb+;jwJ$H5L?}y^9D?tp1 z^DhTM3}u`m6KGTfmB>UA!l>3{O87rN2~;E_ihx9;9Z;CRcN+%;)GA;huh zp_cn2ixz5&VHGH4EnC@23*Gm$bj|0Gv}N+GxMF9Gw0l!8wL-4 zjnpHAJVlC$1CgM_ek3who{oydqAW#O23i9M%1m_HrjDsBMY*|z*W*2ukbhaoJY_1= z_D`G2(@}0=k|zfUc~0WU`fUcK&zs86pxn|z&nu=f?W>bSO4{Mw2{N5geiG$@D2GZV z3g;6Ia_a!+4Me3gLEvzN;oy*hVu>eRJYw{E>Ubtk?1 zPWE$^dnq(d;}qjPecx)6wm-a$lc(ETZANz+;xfcp4@A)kDrf1D0>wqwM5l`f1ar0ZP49ZtlH? z4}90u9cpj2@z7}edUfnLY0{()le%XNh)U#*LjxL=$cJAy931{^bUybWzXJ2(& zUWr-HK!sYa^7PYqDt(=(Ue|F-f6ZHM+R%=KAJe>i{Dh8t)g9OzJIIwj9Vff`b?nr^ zrDJ)G+~h(VKYx`s8=9NEqrzL^qwv+J(XLau?flHv6PlOmQeaouF>EqqNcoM;y(QZ+)U^zI{K zN%rn&-KfL{CHfQtT{Vh6boDyBba!^?Hlj1uNVi^Hd;A-V*~P^|2`_1-V~Ent(|wAC zjyIe;cN<~e0hT%}B&~H|O}n{jTt#WIl(o>~Chz60RQb4S`gr=dj#qTlc)Gjy?pQ*# z5EV?_Yk<;QslvDveY*7SSRUD;6*GUY!Mb$XsF5)&dAlPm1i&w>@DpsOax@#u6suXXJ#|ja*`FXvi z8(MeJyCVeMahs_jI8LQJ6+E-@$xGPQ6CP>3ni!X*YJL8cZi z0SYmNTDZiZB*@glB|ssjPz#qBlmwYtxCAJ~6l&oTgOVUq3zq{67A`R;2{N^C2~dbB)WRhOB|)YZE&&QL zg<818pd`rD!X-cg_uGuTw+iXWNP6Opb%52 zg-Z-df=n%30u*8jwQz|+Nsy_9OMpU5p%yMNCnJ7A^q_F@;*V z#GoX|)WRh|A*N6%Tn$PdSycGqImJnMAn}d;^!j%D4&0j zvZ0>}Peu;)*ZBEsKy<_(8K%~JG!751F^R#x8im5w--j}2nZ5grcfxy9*7hUM$yB1h zr-rtnY+k2A^&uV;8S&1T5g_rM@ePKlluGxH6dHfOq2ngV!F2R^(WA%QumE4$m^APc z_^7dl{k=85rZF@c=kMvQ@$_X%z^~7w2Mqc6eZuDWCRHJI#!JZ@|79`9q3nrAHTW&4 zF@34R33e}+FQfu!zO$88!m`9&?@A39t_X<;i*v5Iv6&7nA*G!XqgJ*oerCP zpm68aSamxB&)}BV?MHHNo<2+^@Aom)zX=LWmAz08Go9V+n$9q^Z8k!jxn;=hDjx2>A0~v&O36YxL*{XV(@tT-A z#arL$gkNus8O;H&t(fGqrR%aRRb7fyIhvBDm;b-RgJlskfM)( zm(*NXO~T{hKu1l-O}B%LwWW`_3wv1F4-N5W($tEU@Blo1nCx@3B%|}^XHKhlDBSc% z%cgBci^7j3Z91s*uhfsFfSFO^REV#?H}!UOT6OU3w6B}mYER2Goxo$mq#Hq4Z6I2$ zR?@#@RZj<-3@=%^$)$wrdni?3z3uHe z-hB2n<6dr;kyVBR-rj{AC76Y!qS^H@P^wfLv1vUxyds0hA_K_wK&^Buh5Q2Bm7DGrn54?vzoKAd6&{J zY~U9(zelM&X+$>x-73@hKMCFspx9^_d4@=gmy9W-5qk*!ivdH3)R;<|uo`iL9Qaqs z_oPw1diCnpYgE5}qvj18G;ID<(?*S&KK0BKPdxR+6VEhn#C}X~e8u`z(zs#6#!VVG zYtp3IlTDg5d6K>~d6I9^T#N$a0n)r4CNNzlX+xyVC9>uc<2CHudd5SNz8IyWg#BQ^ z^atOzA$4%9Q@39I1`Q?FOq?7tGqV|yI7nnt2dQJ-I`tf7jkGi+OczNKG5pM73H)y)I zI6E>%k-6*pgXjEjXT95g>Bb*+FFSNTHha^a!x!QVqujMKmv7#CB)pxo9 zA3Y^kcg=XI4jn+zN5!9b$Dj|PO&Fi%E#u{m3Ikpjd}m`qMW8D z-M18cvG2FeeRe9s-f8SJBzfAB@Yc$rr*yim=hk)6ecGz|t-?>AzI*3tVO(05s}p5~ zXHxpLThi|D4|J~&ToSV9FQ;QJ|4odH2+G@kz3twZ_wu$}3EHUpwypfby?vuz-`nrc z;5~mvo|$wj#YoogNzdQg>a%VOFS`~VjStvWa6&h@fnrt{-J3tZc)RfPgqI>Tsr&sM zM(c*`nYce|wUI0t`_!n5{^O3XX?1i$y|+UazOHKABk|ddy1||M8c!QW(s^FH6foH%t#I!03oR}z z9=3Nw$bvzKz8~5$F#O8mcDlF6E#8@->b&l^nJs=UmgS#%zr_oAA2$kI6Pk6iZ_g7u z4j}rQ}?ZCJ+*IIMDg&AI_ELR4t>|SS&re;u^0AUId!M^pcjXz$2Q#h zQ-^1wTA%skn_YQ3jO66S|NImmbFA~b`Gx@Fnd}9@t8zZ*@#p5(19q-^BJalK&va4w zhZl!C@0O)(+qW?8%`fuT2EEkmZdR9=WA6=0C>#+Iw)02Nzq?QK`Dw|WeeZnwX7iA4 zK5gW`YvO$q;8|F`*&o&yh^(S`+&X#D#p zQ{a` zuP%B!X75{lw_IK88&%+?JQwg~-^~Bq7^~mVA~|MxisKH?j5i0pxwiPL8%K`@J-7MX z``Vr1Q~HL+%`z;%voGJXWz^Z*MY~$(JJ*?VYeDaq4U2;VX3X1neaWhv(C%*?@gBd^ zNSf!}xI$swzj&AP`6p8L>}wj=1F-)6bcavA?nx4y`_3?)jn7IksFk}`P2F&_QIFyu zcdXG3Zm(O_^Z3huzja z`#A63>ajjg&+58-%)!9a28sKg%JHAnNZY;hb1xam{?-Y7w|_hSLejovDM8OnTU0#d zX489L#O}DUUh~0+^JjO;IC6Ji^&KJ;v4U)jTf|jXUn%mi&G}(`gK#^xqbTU!2cX^3|sE= z^u(s#h4p6zoEdrUySE)w&0XuveruiaT(r}7Z^ynos!L+_E+sb`IDYUu#WAk=zy-(O zJ$m@q@oC4O`F!fVrb#_t|7=p6Tj!aotjOtwcRTEF@${Nc-Wgd>wj_Gpb(Oy?6HopTvF58U{@C$)Vcy-N{cr0(eIuj)u&B*1xAdCu z&Cu5;U)-57?9&#fPpsM#ozth`Ygg8NbfQ(ane}1cd%eCr+k0&5A;-sd-0H3=oay_2m*?G;$m_4H zJ0xP=hCPm-C9Hhf-L30;@hjind2K^(z^}1mt2}EwpCWp+|Mo* zZ)-x`!urp0qdxs9DPg1f)AtwVoD7KHEmN*4p76zcO|$>VDcaEby`~$lA99}e!M@+N zUyrDlKP0um@nJNvG2S zS9I|TN&foDPMs5v2TkqTHlfEKuOxN3P~U&v`mqb&9i&;>&ca}ytUBqnwL|Y+!$y5_ zJ}$FhQB0fJT|evNRd?5t@1LL3^1qqG;Sv^xJ6~K3Pun`~&7t{gPrT&+XZxnfE4}64 zk1>*|#qF~Ke%tg)T;SnFtrlOr*VlN#Ffzjb`WlZvVx#)L>2Iv zyZx__h0Wd`ys$$jUAK!H4))m_*2AmLh-KF|o%8wY_x;-@=JYMjPm6nP@F~suag#s% zzI%Sa(BFGq3(kqUvAOs_K{*bZo@*qDpMKK#*UpC*^qAB(Y~g^_s~65#Ku@mUzrA)e_gNfW zmlykvj8c5MA@$7-2mFp0iDIkv@`_c;;MJ}>5616K@B77DmScI#J$4{kSC z*7WS{t2y(&Y1wDV)MmRqlb%t!{ds-${@vdNJiYz3ChNC6>wNLVJ54_S{Ml~HzUwvf zNE7AD&H6>P-?+Nx*mpuYJb9+i$_r_|hEA{d>Q6`hZ@@sushhK}s)JLneDY12k%ax8 zH~3!0(Uz0tznxswe%(uJ-87_ouNEKni0B(??A@OF>qV~tms0Bedu`%d4HE0`dgl2Fca?X07|F}~M(E^! z|Jbw6{_KtobV=%7AGZ1|BpESIjz_?rf)j1qCZ>Mc?)052*AK?;&&V;7v+rI}$Nl!6 z>!IF#XXtc0ee3vqacWq`3pu*Jr&^tt)^i#7_T9Yr+qJVR&m6?RfFrxLdajax5a1=z1P##~N@{xC zk8^)K;9{Vz#0pj{-YC2|9%pPG)Y!2^55`6Vb1U2)P!%1ayV`xh!@ejY>;d6?U$yA^ zf71}>lkWsxICfurYD@rw!H^!*_I_ma<`m>(z0EovQe(i{)DZ@T;bD-E3}DqZ5KIck z-+iMOo8Wpt!Wblm`j4@~V}!h=LH`+6fKz>By^ST>6_qjg$Mjr4Y*S}?9*PMN15~~+{@1uQ85CjV|F6L-X1+D!i2ea?2j}Lt%MmBzZeedTSvyzu3m`Jd1DapIn>4-0m_U;7-w`r`-u z_HOh)5N!A0tM>whte7Xx}A*b%*vV0(Ja9b?A1x2T)xR zDXzF;6^S2)CHTAv{wtqU^H#u^?eN2v;A0DjpLJPD44_&rR@>zE%YrX#gqpO1eQu{3 z!RO6U^@G5sJ6V;0U&B_gQO z-koOFy!4+ZlUAEzp8@|<><5$%q>}Bwg560%O*CJ zRr|JLQV($pSV3KGH8d)+8o}qg5RcM*6T>QA;eWVWpj^PMh|9uuSJ%oHG>gZ-@(97! zn7?el4{-}rJ~aWWc_G0F)yj_iz7$KJFKFWn_ibw_P)USbEze}}TVV900P!KHAX&xx z1y-<>Tb;k3v*W^kCE%kMOL*^F2FT?O%%-b7mGr`IfpM!A2&jrL;385bn(xahcV1S+ zwGn^aSC5rI<>1?jKa`hyMW`w#uhoG0EdUePu?xnpS!Jb7eANo-a;vsZ^Sy3v;KK}rL$)Sm_L)Ev78H|m|2yn91=wQ1N2g*iv6Lx$U!c02kI)OwI39od ztYDuBkXV(w=B+QAe%1rm#eTW5hk$O1-4qjRufDP{-q+o%hIt6%Dv15qR8tQyiRml zcJBA3SY0Q-ue{v?I1BjW*lIg`K5zDL_eu8+jchW(43w6!5WYu=s&Lj=8dP z6hje?fO3x^F&e5OgZl;iEgSw^u-gO=3w-`M>V%-xc7p)eVZ>^W{B0VKWq@Rd2_6>s z$hr8N2-wRu&DTm8;Mc(6Yt^Y$)ov3!EbxUpIEd@4=3;9V;MdsUTgljLHGyLJvWE!% zcf07FR{X2t;s+oA-_{S7R{~>IST>o!Z|eMPLrzuVM*G?dZU^9dbL*-yU%oBCui@aQ zk}+GF;Nz*^R+O4OEbwvQ3OA0CbJ=kdq3qlN{-c9GhG%Jlv9o8EHNisxA8|e(YVvN! zeZ$gf0Uz@P_zxxcEV~i}N+l+!7VvGlK!M8(mdFEtfM1n|GK6XJg+~p1epKa}pt``v z>4__5xM+#%#^v5G01+$*K#X7T!fSQ89V;t5f>oSu!mQzlsu6rat*r$Nsk+?GBM5le zA>q0T4-rW>}F(a>D@PYrS9qPDaGZ!4H(zQx4BmW1;JP7bpj?FMc z&PqA;-vkDv(v{sX%H2DQTd{jxYeAj*Bgf7DC>l&T$n*wpI7T@MItE43oQf22$R z@T>R!3&1be$y;Gn?Nyt=e{@U$@T>9uW3`-~c9_Nv@E;Kq0Q~B@|BjVk_0zK^!G9D? z0Pw5j^Cu6>?HKOmo(h?dP^Y43hX=Xx*N2!F@Sj2ldR0u^9?F3W@F)Ge)OW#@L)+EJ zaLb08mBVhyeJCaX?EHSOVhDuhcKD4dHo;ZR$?KMlnKc#vd>2iPJ@UOJo_3UL-UI?} zRXl=gKF;SaDa+R^_;}9O_=m#u?TeC6&b9+~%O*8!0>I8M!m1p>f)T5@p2at}yq@p& z^CJA?ui-y-Ca_$$cKd&uE-wH&e2NB7pyNXY_=f_jAle5$e?1>pm4#bckCzE7XKmjR zAo7uOz9W37K=}NUc`3(dxc5DHg9#XT!ylh$gqjQk7 z1fL)FV`l=Zh|#_*K;(03K&&j_Who+e!IA5i%Dt2Ic$t8Y{4IAnt{&LB1;kwHu>>FM z7N4TQlNb0<0sf(Ys^Gohh{T))=(M77J}xEz)RxHeWjkC@StV8!OYrfbf^t8<1fuYP zHyp=S8p^F!gg@wyg$b;j4?jmcTu`~-2t-Tp@o|nyKm!W`@JNV=gyxkLDp&RBo1m=o z;U{a;_s>)w{MZCOk0*8kg3?N07g&|!5ALIEf{MO>2D7vE`-e27yn1u1eIq@Sk+=?$IFxpj(ykAB76!9l0u z=L^Z|H9=g&JezvA6c#x_@s~p_Go~tnk8z63=Fq9-q{Nh~*90>U+4-N62p2rd?r2Mj z_$>g;`G!>o-=<3$VlcOosYVklKfK9GxtOZR#n0m@atk11g?vqdkM8XIz8yeRT_&&( zf02uy#~)ijOdy1h%3D5Ea^EDY+;t*;RJQfV_-*7^o^H2oIZU z>k~;jRO3teBX}M@a!;wj$4Q^*feFEj@@!CV#j>}tC?C=?EoJ+7k}^4 z*0pEVwN=&11XqsCvHUoMWf?1<2OoDUtdvwzE%!Qqxgb|U#P$)N5mz!8o@EF4xGBSf zU-j?XDLXt%6JTv`+%y07-=#js0_5TI;da2qKk=tOK&y)9v9yS-|Nmy$X;uY%A;hiT z#V-uf$^-xzXwL~=h=2G%1rIy_ip4Mf^r^1@f0H*v)jy_g$I2Jn4yKPgl>%bbUMOn< zOW1`nZkUSf8gN-I;A$yXpvE+rji};EOL{f^r|n=E29x7Y}~5xc#yw6PXm3 zT_LuD|KPrFr|j6QD9YXIEx(l!-~)O1eDQ9_j#RfS)D=WI_Y3&$K*S|wT*Q0azi+1oz~>RG zHpEn0gAm&a@%_CC-J!0ZD z>GR93f1ZN8pem_Z4FL5Zy1v*s<4w<^P_+Vrg1gFbvQn8)4ETOll_il74P?IGq1=o$lfOk*1{ z2#b{A4N+t9Dmto#y&}`#TUiiz0HSIPnV<>^q1N&%Un&|vEnPqW`+_$Iu6F@IF-GB` zh9sKsfIs5yMMfmQ;ExbuG!i2H#etQlqb{>3ql%xm-IU`LPQyHu8l~Dp>E|?1DfjnL z_-dR6x@ugV`g<$oUS!DN{%@$JxPH+7b;309EvMs+{yCtRR7VuZfJT&0U#0Aow)0Ub zeT}3Z=}L!#pI6u`9oPN;>O_S8cH7B?_3!EH?+wN1jgaC|{XcUeJYA*s^`3bv6z~Ys!^AyUVzvg#ynQy`KO25{@IQic?#PU}P8(RNb z@-5qy*2ve)Jz9^1a_NY9I$z>t&98K>=GivG>?24Wr+(8HhKHx+8tbHmhcBGo&nbeO zA+mnc!_yLsvb6B&{mzgJMC#-he#0mY_j9^HF40=#Wur9G&*>7mLL|eub4Cd_>i?x{F+@OH&C0NcETu4o8IgOxy5QnS?v~yL8}`FjglL~Vn{5JIE9BBCE-r7 zBo51dzmZIjBX>cK3^7U~o$iu&BKb1yccUcj%XpGN$iiJlvM_-p5lOSiosejjM3RZb zms^bF%QTWsh|4A;aY-i`l)s7cGe{;aZ=mH& zk_Fv20->*27Rn@YosmRlk!$kR zCHDw%T4p3p_h=~`rSN+skC0(YjAU3I$*27+q5b5eOr|eJn|x9LYT9DxY*v6WnZ6Lz z0#Zn+3n{e_W#TvANc>po21+*yNfETph1Mck;!xs>NHKb!gWij2$qywzR*FO^vY5b8 zIL$Ijo!~FPMahqq!chvRr61r%B&6RDMoB-sPsjUoyocjG9Pep(2c}Llpr7=^YdPvQl<^HhTH%vI$@Ann{I(`9l6Lrg2_^bVIWM5r z7QZi(S5a=oexD=Hl4nQ@{5=a=Tlm>0$y3nL48P6E6WA`#qF(a*3?!d}u2*q_zYKjH zQF@uQH)(zaB}z5_wq>Je3w{&~Nadgc%<^~!s+)F1ECQct{7OTBQgmipfyE%m(HwAANr z(Nb@_NlQKL1}*in2eh(T+fK$67-exMw*{nYski-0D_MCy%SaZbYpKK4qk1jVNVcVF zsn0#6l>{8jKs5!`Y?7gse);*tiy+2j7^Um|{8O~l3ukD_=fy)Ma?KU3WKj;p*A**> zIz>zUGUXKxmHt<*xrSzDreBhlI_gX?^BD6cuamX(O9V5QF>@F*MoZ`*s8+vtE%oNK zVb)N|f90`SveL}DqowX0tPvSQ$*4Fjp%Y<^;=swHLz$31l*sR*jhS;>OWl8(mWn-#C2g6YC9_J{(rw0oYzP#fy>z@{B-42+u@$K^&yNDzSty3@=gHbZii;f}Bn4zUdRw8XZ z8grcp^BE=c{Q=sxdyH9(b&HF*(a9IT=uZ^>q@ao6Jky)=E^KkotUh4y3ZQk{=9N z#=1EN16QsLJeY$Pksef#5UfioNJdjR16|(H6tYw;c;q@|7Mhs3JX3mE;m32MDYwYP z&7<6_M(I3-hUa3dOdO9Dz!YP2j2o($0IQITK*G!_;#sm7r9zdgjS@HxlRwVm$&R5Qd-x}6&+_!K1(c4N zUY-ZDx%($*&zKlRl#y&CfJ+iN59V@L$7@eBro-5wLn+VE@ZIEfhhyMnVh*pHT&R$E z_}|q=YKeETLOPZTNDSYlDkR?iceJOp4t@&7cLqjFQ%F2jvDyf&)Q?iw4BWF6k_oC9 z5CKrKu|A!ZyV~E+%cDRc^YHT1+=LFsax6SG8LTtt$yC2^;_wvpX$+3l>l9u%apF|m zg437^Bh+Jr6hq2_GuoSG$LI*hIE(h=$a9Mgl9UB!wJ|0qS;8o!jC0yp>Mo0mZ95snn zYaw^bEXTHNu7Yl1={k3Hk=D^dD#k2D{p31>g8Bl<5p_W+q1zBDhHs{Rl6vfh?%oqs zs)^nhloJ2XIf=_FB_7AzRJxWImU#IWXdV2$6pB!T@m?vxJ0`(glNZm$f>bOs7;{TW z-Gx*UJ#1#(Gs(d_c+E2yb4rONFt3`S%`*vQYbE~k4MsyLp+pE3LRY>?2wK+~jM*hJ zNrc4UtY9Zt23<**Z%n3HF2z9Ns9XWb(&7Lz$pJ%l zAZ1vH%}iydR+d(_4qp~xKB}mnO*c!W8pv`gl~1y@Qe}w{?`BQ*OoLDwJ4G>dkMGQi zn2Sv{Yf3ke1ym@Hz~58X$Bw*A>Sonsgl3_ehRb2Df37p$<3MEREa}3NI>Sz{yEvc&CgLO6^{xkWHF1 zXF7GDnk)oL*>o#Y5$2$AJgMDt6l7u+;;Ss2_>^UG((pxUk36&klZI&6oZEnu$y49Z zN|fV^6jFCDO(xixbbl-=@zv2G1yqv33@p?kRV2#rCBqB@CQV6{ycoA)xpeM&m*wV|!BiRr@dZ3qX z3iM?f67}RV9IZ)%?6T2#IZMw{2)*==K&AyE@i-cz>2%P^Wq9&ST5R9E%q9Yl6X&B!gDFoO^A%xZ`m<&$l zkYG9nq!4pQ7UsK*6vD(L`-%f4i+nS|PS;DqQjkIv06Z!}Qm7D82t5fdqC#0rh(tq6ya6H< zt28}JA@n4yfQn>81ic>u(wB1~LJ{Xh;-Ed4$rvDmK?K8r#vdub`ih6?f_bUidda?R zkecV71F0;%BqR?pQbFv6GiNTu7NAAU7AlAof)^x{sGNZ=Zv@sM!Kr$dLQrO5AkWO@ znbP>cy*xLXa*IsdJjz815fT{2bFo$a*n}0p6k~LZ8x1-+>$=j70DB%v=(Vx;g>0U}#yU-vHJb^kk}s{u;C? z^fU&?>UHu%fBkjGu|uaZ6-KDX6CzI?I-|d7c8rd2jK^tDjy$(GQgZ6hS$&MjNtQ4Q zDdU_zmby!%5WI9gC7##c!CH$&0M8TeQQ`&tUFzTjVh$xn>Er281Y$NNUeqT*vV@pP ziI?<=rsnrT=q%DH@iJBlyaes(-p>oR?>Lr9saM&`OoodCJ#XEtS&NP&Q+l+Sj^WnL z+qGuSoHg4|GR`%|!MZzx6oLZ$^Ur~SCf;@MkU}u8ST`>!EF>f>3Z`$!+aYv=Ab6AQ z&ot&ACDE{sWJ@&Uf?*Q9-a_t{S&nVl+(5d8rH3|z7U>-=q+-lc)K4BV1X5ohxgJ_j zO6WF(kU}s&N&RiZ4cs65_Wi+OP+RigRq!3I5&My`zgoVhlWRnO1BtEMy8D(6V%V9o261C$zdvm6hbfEQX<5= zS(81}Ae6>VQA~ZyF7uhkTx_aYQ+gzI-zK11J1|)a z0Va?#dFmT_$?i=>fzl1ZVVPhfg`iQ4;H#tcvao&oFlClP=w(MP$CPr^M-dYuh0v3| z8Pr1`Mc9ZG0@Y0FoR1)uL<#}Sm|H%K023*MUS{Es4bDFi}Nq!0*CkwPF; zMGAqi6)6NlSfmgLXOTi6v_%SmFc&EVLSCd02!D}6AQVOlfv^}U1VUt_5D1s~(785+ z01g~WAvl&oa4d!3SPH?h6oO+Z1jkYcj-?PBOCdOxLU1gF;8+U5u@r)1DFnw-2#%!? z97`cMmO^kWh2U5U!O21*Zl&XJPrnthJDp=G1SdIo2b(@Dont8ks!52iBT_k*LU5AZ z(FoBaQcy(-!Aa-;xb-54>DY7!HU_6~EQR36kHu=q;-D*>BrG4|`-^pCdkV)=2=EHk z(n*VhuA!NkxiN`jDFm2#jCqsS$y#nq1QRI)m^q9Y!x1_Ns&!*L$5IIJvec4Ei(@%< zgMzW{a4d!3$kYrqnHI+pIuXW+0|zMthxk=Z7T-l1Gv_wPQV5Pr%YeF|c#cpoSfg}~ zgk^Coh2SJ>f21uFI1*CAmPQzNXF~uf1SegtL$A<~$dL#*T9XD@gwYt0#jzBElWx{A zEfBedqcMt32c1N~li#8;NFg}sDwCchj-(@nxVK8DV?sC<(la@hLU7WpyrLuyDMX}6 z04W4xCzt3*24A|HZ;uoLY@`rE>l91|Cv)&xItHW=xLuCB5VUmw=DHQ;!>1a80a^r7 z2zD<$fwo-$=8u#~{-Qjj5FAS(IN2)Qf&d`DDwQ&$VZI2Y5GE$sTC9`&I5iXObWReK zgcKql;878hM1_z-aAa)}70O~l1ZO*Nf(XSbjbkYUM}i8dNH#>!`+guDkqZ%uI4=?h z?Q5Bg0WuiGFL0o@b{AlM-Gb?U;iYbKlC7&CHG5JHq_Q~4ulJBbJS2ur7$_VykRk zjupTZV|0ugsap-Jkc&XV%qrqpvZPhIt;t-Jz;Rf`akPyLD`Zs?cR^rCmr=6Az0Eq^ z)+Fw{iJq&L%%?XephmYYkvqqezs=*xj*%d*2u|eA^7NSnl#ZFk2E%MigA=$jCPoou zAcX*2l54>**V66r+-b&in5kA%p5wjEzwD1nf|p5(+W$+TPO>8SE*Ht+!l+I7%fdFS+zBmi{PXiDTU2oX_ij1dTR`b00=1roz>Fq!5i1E zDA37Ptlb!N6FL~nF=xR%u+E?-Q+=LFvtava435?7I>IrA(4HK5Zt*P1k6X`jF(xNj!YHJSb6hNSmq;Oa>3m8&&)vaVi$(y?6Yo*t z1@10&Z~`%h5~H|yIuwDJO^Fw|1W1+;Gb!;BmuPC9J0G){kxq%1u~OhAXivFIr>NC4 zQYrN+TbaplaaRHKvf`=a`(#RwHq$ZOy7x9O`1=1Qq)iGH|VG@kX+hcP)g`FgpfioKS}*vsZ{50i9R{`P9^6WL zUMcZ7=84ida3CyM8(hFS1h3WUB9TIr61-y)L<+&YcrF&CZZ}ehQc`yzg%ko4Mhd~? z;2qWmBZVj>mcYDf28R@a31xGVV7Ny^DWOCNA%)1L_aS!5HHLJEOXqeO^zvnG3{K`4!#qL})M&E_+Yx!6>*ru124D;2_B z2;R@IBM*Ub@Y)o!3^u~-pmZG9NFg{G+=fYpI^1NlP}VHT+^rcb4#?r)Y?%x~6}a6b zvy5SuboOEF_lLavd zC(xexVeI_vOR>1-&n}wfID775oo+3aK?=cSc&CgLYWvb6oow;Kg^Q>I4a!2GgcO1o zVGbI{)Apq~IZKm?K@)liv(Ng{_s;m}9sjvojmC8t SrO?mQLhfDq*lSic^A)z>R>_DIp z31SFv0gdUdpt&?$pS$A+*2~vI)i=>EOC*CY#Ir%H#scfDRXR6m&9|bHwac&n$lOeB zRVzXve6pXRgJ%NI#vWy+|4?=|!F(r5a@w$HRCh24Ot8wM5fR{66tiv-fuSy`wl`Hl zM2%?m!owuT;EIic1R|9A_4x?|6H`jCkpYy3hI&!wuqq1eC}RQQI1A)FwJ<^BQE&?L z)V6^~TTVY;y@f5RFek0Ug5$ z(QPSHmLGE36E%!?lDar%7UM`I)!RhEViSh2_y7R@)sVY2nrp2?CVo^2f$yMQ;5mr*42ltNG(-{l&PoJgkHK6*-eKZ^f2pbPi z;SHC43nhKPj7`oAe1RXTdqg;+YRB1?Ds?GpcpX({g=U}J2Kf851i&}`s;;Qw#d*dG zlEFT4fmD_iV>rQ4-Y(l|m(4Py=Nj}r(SRZM;x`5VAmCF{G6Nyzdq+lJteGY@84#PH zcfQ)>#+y~?T9*>}1?V+?R~skFcZf@fpO z6CL-~;}BU+lpGBQo{`wnIzZKF0+(w6hT0pN+C?vavdS@g4%bB3u=IsVt@&RlC?_H$ z{0^b0^$Zzb2oc&Rs8T@3zgu#WjLD!tBXox|!{l+O)ym@>-9>Jcpp<;jAs^8DF=|9)_b0r_a z7_y*l`w0FQ2>>G4H!Uy5MP=!Bgp>OAEM5*8&_=SUfpos~*{q6a*=CsmcfYB+CPP@zCG>8gbH4o+dz;#iOFFQ2;FWG&o&Fy|!|3>Rc)z zA%SWi25X|p6z^|lnF;!^IB)#&*@M#QtJ4}^$^OM5zFLh3uEHrbVH<2l|I4xLy8SIG0$tYoN--O~YoPaAhTe!+V1xvsXbDwJZaRM?g=M^%Z8`-(}usL9faRVlv zIBgmjRIQPv$^}WrAURn$uKQS`^b*afxMCrat5U9F%CtTar(x1-URehZDxN$e<@IY0 zg9$f4@LLB>(qhezg#kF{g#Zvyd*zpCg~qX@^T&W};8O5l0L?1&Edwn)e_gpqUg#Qk zv#D`IFY3WKkhe&^*-~o)@x?nGO?N;TF&CBeuROomJEO$-QK2l63!C}3U4h<2RNb5F zO2Q62aA?{$BtN1W^yM mgN~z(mGV&4s294L0=6Fa7cCGFRO~Bb^UsYvbt0e+&OiWL)WoI$ literal 0 HcmV?d00001 -- GitLab