From 3ba74229ae15c61e0fdaf8d02fec14300b9c3daa Mon Sep 17 00:00:00 2001 From: illiashenkoo Date: Mon, 3 Jun 2019 21:53:16 +0300 Subject: [PATCH] first commit --- .gitignore | 241 ++++++++++++++++++ LICENSE | 201 +++++++++++++++ README.md | 93 +++++++ build.gradle | 29 +++ dependencies.gradle | 106 ++++++++ gradle.properties | 10 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 160 ++++++++++++ gradlew.bat | 90 +++++++ images/ic_gradle.png | Bin 0 -> 1977 bytes images/ic_kotlin.png | Bin 0 -> 1128 bytes images/logo.png | Bin 0 -> 45030 bytes images/repository-open-graph-template.png | Bin 0 -> 51470 bytes library/.gitignore | 1 + library/build.gradle | 46 ++++ library/proguard-rules.pro | 21 ++ library/src/main/AndroidManifest.xml | 5 + .../startask/permissions/Permission.kt | 165 ++++++++++++ .../startask/permissions/PermissionUtils.kt | 166 ++++++++++++ .../model/PermissionCheckResult.kt | 47 ++++ .../model/PermissionRequestResult.kt | 51 ++++ .../startask/permissions/BaseLibTest.kt | 41 +++ .../permissions/PermissionCheckResultTest.kt | 69 +++++ .../PermissionRequestResultTest.kt | 71 ++++++ .../startask/permissions/PermissionTest.kt | 71 ++++++ .../permissions/PermissionUtilsTest.kt | 176 +++++++++++++ sample/.gitignore | 1 + sample/build.gradle | 30 +++ sample/proguard-rules.pro | 21 ++ sample/src/main/AndroidManifest.xml | 29 +++ .../permissions/sample/PermissionsActivity.kt | 84 ++++++ .../sample/utils/ClickController.kt | 24 ++ .../permissions/sample/utils/ktx/ViewKtx.kt | 12 + .../drawable-v24/ic_launcher_foreground.xml | 34 +++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++++++ sample/src/main/res/layout/activity_main.xml | 14 + .../main/res/layout/activity_permissions.xml | 20 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes sample/src/main/res/values/colors.xml | 6 + sample/src/main/res/values/strings.xml | 5 + sample/src/main/res/values/styles.xml | 11 + settings.gradle | 3 + 54 files changed, 2339 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 build.gradle create mode 100644 dependencies.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 images/ic_gradle.png create mode 100644 images/ic_kotlin.png create mode 100644 images/logo.png create mode 100644 images/repository-open-graph-template.png create mode 100644 library/.gitignore create mode 100644 library/build.gradle create mode 100644 library/proguard-rules.pro create mode 100644 library/src/main/AndroidManifest.xml create mode 100644 library/src/main/java/net/codecision/startask/permissions/Permission.kt create mode 100644 library/src/main/java/net/codecision/startask/permissions/PermissionUtils.kt create mode 100644 library/src/main/java/net/codecision/startask/permissions/model/PermissionCheckResult.kt create mode 100644 library/src/main/java/net/codecision/startask/permissions/model/PermissionRequestResult.kt create mode 100644 library/src/test/java/net/codecision/startask/permissions/BaseLibTest.kt create mode 100644 library/src/test/java/net/codecision/startask/permissions/PermissionCheckResultTest.kt create mode 100644 library/src/test/java/net/codecision/startask/permissions/PermissionRequestResultTest.kt create mode 100644 library/src/test/java/net/codecision/startask/permissions/PermissionTest.kt create mode 100644 library/src/test/java/net/codecision/startask/permissions/PermissionUtilsTest.kt create mode 100644 sample/.gitignore create mode 100644 sample/build.gradle create mode 100644 sample/proguard-rules.pro create mode 100644 sample/src/main/AndroidManifest.xml create mode 100644 sample/src/main/java/net/codecision/startask/permissions/sample/PermissionsActivity.kt create mode 100644 sample/src/main/java/net/codecision/startask/permissions/sample/utils/ClickController.kt create mode 100644 sample/src/main/java/net/codecision/startask/permissions/sample/utils/ktx/ViewKtx.kt create mode 100644 sample/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 sample/src/main/res/drawable/ic_launcher_background.xml create mode 100644 sample/src/main/res/layout/activity_main.xml create mode 100644 sample/src/main/res/layout/activity_permissions.xml create mode 100644 sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 sample/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 sample/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 sample/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 sample/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 sample/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 sample/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 sample/src/main/res/values/colors.xml create mode 100644 sample/src/main/res/values/strings.xml create mode 100644 sample/src/main/res/values/styles.xml create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d4d299 --- /dev/null +++ b/.gitignore @@ -0,0 +1,241 @@ + +# Created by https://www.gitignore.io/api/macos,android,androidstudio +# Edit at https://www.gitignore.io/?templates=macos,android,androidstudio + +### Android ### +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +.idea/caches +.idea/codeStyles +# Android Studio 3 in .gitignore file. +.idea/caches/build_file_checksums.ser +.idea/modules.xml +.idea/sonarIssues.xml +.idea/vcs.xml +.idea/runConfigurations.xml +.idea/sonarlint/ + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +### Android Patch ### +gen-external-apklibs +output.json + +### AndroidStudio ### +# Covers files to be ignored for android development using Android Studio. + +# Built application files + +# Files for the ART/Dalvik VM + +# Java class files + +# Generated files + +# Gradle files +.gradle + +# Signing files +.signing/ + +# Local configuration file (sdk path, etc) + +# Proguard folder generated by Eclipse + +# Log Files + +# Android Studio +/*/build/ +/*/local.properties +/*/out +/*/*/build +/*/*/production +*.ipr +*~ +*.swp + +# Android Patch + +# External native build folder generated in Android Studio 2.2 and later + +# NDK +obj/ + +# IntelliJ IDEA +*.iws +/out/ + +# User-specific configurations +.idea/caches/ +.idea/libraries/ +.idea/shelf/ +.idea/.name +.idea/compiler.xml +.idea/copyright/profiles_settings.xml +.idea/encodings.xml +.idea/misc.xml +.idea/scopes/scope_settings.xml +.idea/vcs.xml +.idea/jsLibraryMappings.xml +.idea/datasources.xml +.idea/dataSources.ids +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# OS-specific files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Legacy Eclipse project files +.classpath +.project +.cproject +.settings/ + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.war +*.ear + +# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) +hs_err_pid* + +## Plugin-specific files: + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Mongo Explorer plugin +.idea/mongoSettings.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### AndroidStudio Patch ### + +!/gradle/wrapper/gradle-wrapper.jar + +### macOS ### +# General +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.TemporaryItems +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### SonarQube ### +# SonarQube ignore files. +# +# https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner +# Sonar Scanner working directories +.sonar/ +.scannerwork/ + +# http://www.sonarlint.org/commandline/ +# SonarLint working directories, configuration files (including credentials) +.sonarlint/ + + +# End of https://www.gitignore.io/api/macos,android,androidstudio \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..55f3a52 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# StartaskPermissions +[![JitPack](https://jitpack.io/v/illiashenkoo/startask-permissions.svg)](https://jitpack.io/#illiashenkoo/startask-permissions) + +StartaskPermissions is a library that helps to handle runtime permissions on Android, entirely written using Kotlin language. + +![](https://raw.githubusercontent.com/illiashenkoo/startask-permissions/master/images/logo.png) +## Using in your projects + +### ![Gradle](https://raw.githubusercontent.com/illiashenkoo/startask-permissions/master/images/ic_gradle.png) Gradle + +The library is published to [JitPack](https://jitpack.io/#illiashenkoo/startask-permissions) repository. + +1. Add the JitPack repository to your root build.gradle at the end of repositories. +```groovy +allprojects { + repositories { + //... + maven { url 'https://jitpack.io' } + } +} +``` + +2. Add the dependency + +`${latest.version}` is [![](https://jitpack.io/v/illiashenkoo/startask-permissions.svg)](https://jitpack.io/#illiashenkoo/startask-permissions) + +```groovy +dependencies { + implementation "com.github.illiashenkoo:startaskpermissions:${latest.version}" +} +``` + +### ![Kotlin](https://raw.githubusercontent.com/illiashenkoo/startask-permissions/master/images/ic_kotlin.png) Usage with Kotlin + +1. Add the following line to AndroidManifest.xml: +```xml + +``` + +2. Create a `Permission` object +``` kotlin +private val permission: Permission by lazy { + Permission.Builder(Manifest.permission.CAMERA) + .setRequestCode(MY_PERMISSIONS_REQUEST_CODE) + .build() +} +``` + +3. Check and request permission if needed + +``` kotlin +permission.check(this) + .onGranted { + // All requested permissions are granted + }.onShowRationale { + // Provide an explanation if the user has already denied that permission request + } +``` + +4. Delegate the permission handling to library +``` kotlin +override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + permission.onRequestPermissionsResult(this, requestCode, grantResults) + .onGranted { + // All requested permissions are granted + }.onDenied { + // Oops, some of the permissions are denied + }.onNeverAskAgain { + // Oops, some of the permissions are denied + // User chose "never ask again" about a permission + } +} +``` + +[Look at the examples of using the library](https://github.com/illiashenkoo/startask-permissions/blob/master/sample/src/main/java/net/codecision/startask/permissions/sample/PermissionsActivity.kt) + +## License + +[Apache License 2.0](https://github.com/illiashenkoo/startask-permissions/blob/master/LICENSE) + +## Contacts + +[Oleg Illiashenko](mailto:illiashenkoo.dev@gmail.com) + +## Contributions and releases + +All development (both new features and bug fixes) is performed in `develop` branch. +This way `master` sources always contain sources of the most recently released version. +Please send PRs with bug fixes to `develop` branch. +Fixes to documentation in markdown files are an exception to this rule. They are updated directly in `master`. + +The `develop` branch is pushed to `master` during release. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e356252 --- /dev/null +++ b/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + jcenter() + google() + mavenCentral() + maven { url 'https://jitpack.io' } + } + + dependencies { + apply from: 'dependencies.gradle' + classpath buildPlugins.gradle + classpath buildPlugins.kotlin + classpath buildPlugins.dcendents + classpath buildPlugins.dokka + } +} + +allprojects { + repositories { + google() + jcenter() + maven { url "https://maven.google.com" } + maven { url 'https://jitpack.io' } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/dependencies.gradle b/dependencies.gradle new file mode 100644 index 0000000..1a573bf --- /dev/null +++ b/dependencies.gradle @@ -0,0 +1,106 @@ +ext { + + /*====================================== MAIN ======================================*/ + + android = [ + compileSdkVersion: 28, + minSdkVersion : 16, + targetSdkVersion : 28, + buildToolsVersion: "28.0.3", + ] + + libVersion = "1.0.0" + libGroup = "com.github.illiashenkoo" + + /*================================= BUILD PLUGINS ==================================*/ + + buildVersions = [ + gradle : '3.4.1', + kotlin : '1.3.31', + dcendents: '2.1', + dokka : '0.9.18', + ] + + buildPlugins = [ + gradle : "com.android.tools.build:gradle:$buildVersions.gradle", + kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$buildVersions.kotlin", + dcendents: "com.github.dcendents:android-maven-gradle-plugin:$buildVersions.dcendents", + dokka : "org.jetbrains.dokka:dokka-android-gradle-plugin:$buildVersions.dokka", + ] + + /*================================== DEPENDENCIES ==================================*/ + + def androidx_appcompat = '1.0.2' + def androidx_fragment = '1.0.0' + def junit_version = '4.12' + def mockito_version = '2.7.22' + def robolectric_version = '4.2.1' + + def libs = [ + kotlin_stdlib : "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$buildVersions.kotlin", + + androidx_appcompat: "androidx.appcompat:appcompat:$androidx_appcompat", + androidx_fragment : "androidx.fragment:fragment:$androidx_fragment", + + ] + + def testLibs = [ + jnuit : "junit:junit:$junit_version", + mockito : "org.mockito:mockito-core:$mockito_version", + robolectric: "org.robolectric:robolectric:$robolectric_version" + ] + + /*============================== MODULE DEPENDENCIES ==============================*/ + + def modules = [ + library: ":startask-permissions", + ] + + libraryModuleDependencies = [ + [configuration: "implementation", dependency: libs.androidx_appcompat], + [configuration: "implementation", dependency: libs.androidx_fragment], + + [configuration: "implementation", dependency: libs.kotlin_stdlib], + + [configuration: "testImplementation", dependency: testLibs.jnuit], + [configuration: "testImplementation", dependency: testLibs.mockito], + [configuration: "testImplementation", dependency: testLibs.robolectric], + ] + + sampleModuleDependencies = [ + [configuration: "implementation", dependency: libs.androidx_appcompat], + + [configuration: "implementation", dependency: libs.kotlin_stdlib], + + [configuration: "implementation", dependency: project(modules.library)] + ] + + /*==================================== PLUGINS =====================================*/ + + def plugins = [ + android_library : 'com.android.library', + android_application : 'com.android.application', + kotlin_android : 'kotlin-android', + kotlin_android_extensions: 'kotlin-android-extensions', + kotlin_kapt : 'kotlin-kapt', + android_maven : 'com.github.dcendents.android-maven', + dokka_android : 'org.jetbrains.dokka-android', + jacoco : 'jacoco', + + ] + + sampleModulePlugins = [ + plugins.android_application, + plugins.kotlin_android, + plugins.kotlin_android_extensions, + plugins.kotlin_kapt, + ] + + libraryModulePlugins = [ + plugins.android_library, + plugins.kotlin_android, + plugins.android_maven, + plugins.dokka_android, + ] + +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..0c8a62f --- /dev/null +++ b/gradle.properties @@ -0,0 +1,10 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +android.enableUnitTestBinaryResources=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d757f3d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/images/ic_gradle.png b/images/ic_gradle.png new file mode 100644 index 0000000000000000000000000000000000000000..eee0735d0cbdb59d6892309ddbe33309c76d1fc2 GIT binary patch literal 1977 zcmV;q2S)gbP)x{M{+QAvqcE*-*>a86po!07LxujgA;ZDeALw0i^Ap>e1I$%@~ z3~9iUgxtP;Pyb+62_#{$lstc)?>X=JeP_=5e(y&Np<IvA&2OyNKjsq0SUyB#CAb z1caft_GRSkz0%L20(F-inyBO!TAC!lCZVYmk&B`_mZA>{F;}R&dtJScmZi-34*C;Mhb9Fh!%l1ky_m?QhlNz z?c$BDKPTwlYEdWcP0zl+SXCP8{Qo3%XT-3hOM-Vg)$zC`cnriui`qt_PKYxES}59K z0i!57#u6q8&3z=)A`Xb?hT+bhEfqOAU6IuC1}jqutrfKsc4y{(I={B!cS2-4t_!)T z;X4Aenu-EaKQ_Rh9Yon@p-+#Xs3@H%a4ZS8fs zEfPATMqn)GZ2+Lu_Z3(+DD0?rYsN!O4Fo|N^`2cgvmB&e?*#$ic%i!uKq-LI`*t20 z>2g_5DRl*1_6up{Rco9M^ZKEztd{dA%I~-bgO_aP5fr3rh)o-q7)k$6tBaA_5eQ6x9VJ z>b?c%%5a_nX(W#hxWPtjY)l|RTZQ^vOR(fz(aiP#J8oY+Qc_}_yM0_9sdGt9vIHFh zE$!(w?^NXE*Z?rUswxgH`*Taoi~YjJZLG_%RJIH8385c|ARio-)KZk(K2YH)J8Ne{ zL#}_#%Q!fYC*@!;)uHAmmW4kAa@_TiywJn770+4Jmt1!DgllFtZhgaS8ab$nvf*8A z9uDh%hJXkzz0mJ!s+_!|b|sAZ1V|mMuo$xtz>iEQvY{%d^Nl623c&CGo{@jPPiN!S zA5H=#KXur9H42^DTr{gG?7wSA)i|d*{v<@61%3K>VfxzZ0i=~z zW?Cx41G(-!gZYY8rM}j`lf=~S={@;k`&k6OErsdQCz*nb1?5VgF zASc;YD7g znsA%|FygO`BYG@zN}#LSm!!No&?4hYf_Flki!B(0oT2Tf3o}mKOvqwYsR>lBhTvHd z{A_oc=Z!0$698h~X?%_}D=vjD-i@V^eZOzE=GE5^>+0%QFGQgbPwdI?ymht50RRep zg53qiDH^t#P^l5{DC|m zw1BF)`#hdOK>3*rI0YXeWS2G;T>D2rm=u7%@KrDp2>=Dz_p0dgIYwoHANp4;CszKn7JbyAHS_GAHe1gS9>RbC&Te+`;Nxiy&d~NwumM79`jzl znWYDVF})r5C8_VG@2@;lotNbY02HeLRri8={6=7fswWjl3Ru(5L$PdPY5jz7yr-vQse|jL!Nw87o2VG9teU$KAPAw*hdd zF|9WO>mYH0g4Ec*9eL1!5C~=npp5C-++RXe)TnKC_xV4+P?%tg##5aUD10brt2ukJ*o<&LZH>rZS5c22<(3WtMvOILTW7RLA>BrAH*j?&^{=bb`*=0(m-evO^cAUR%+Bz z+Y)!PyXW&^cV=g1XLe@SesDN5=j=JZ-?{G4ooVK94hXLTjiuapFQu?4R~Saz9Gdy@ z>5iTO5EJT)39+)KwidcXb8zn1QyY381nP%V9Q(wIT6@bDUON8dUHyGvQa}WNJ=-|J z0ifm?XjGPGwzl?l11y*Y0D!1ai-Z9O03iwRE73rgPrcmS+o>QIWEPMBlv1593Bq35 zg*VJa0s#C-gm7){burMca;}jPFv@*PIKT}7FNq*$&Q7g9dRqvYCVkq?;VIz)w+OgN zsK_n8|JRlqnsDt#Nx}g6mZ$=+5U@)qDE$7_(pI&(aOoB%0Vr0G4~Ycr!hScnqkt}v zQTfkr7KXEJx#e~yVIlaDAVPxT`KoYN0b+US+qrF5I#fWTM2 zJe~OCo~uh;Oyyh3w*(=vX3syq;7$T7pPoLj*n9cxeUbzeTkoC{M2XPY1>bPH!0N&I z^!(<(=X)fnPyk4Y8YE~uJbrGn7Pwg;H}&)9vs*5n+-TqJek6!6-njov&2U|yFt%{` z6ukXDZr)r zVlMFY)dNRASU%A)F~M#J!du{#g=3p^2ul;tL*k3vr1p#4^vJ5fV8d_ts9p(02bCqf zXW}y@p`D_ENLB?h0>}msZ8(n)>yZ%5<#m^ezOH~&sJQ;H?uk#rquLp4j07wD8frKX zX7Gyy^8IljB&!yXRRWf}_ilPsn-}*-f_c~eUPwg&PWzV-EJX##N#dQBVQn_lT@7BA z7zFbne#wu7U{)PRYnGV2<2h}n>E1}l8?MK2GKzmW%_CkC#uB(m?CpG3JF&LQ&&chu zEj0wj#~7*hBgMSK&8I=Kium2nXw&PuB3S|GDPwweD$5AKbUL;thxpyPz&M5_ ziCBL`o4$3u0na*qveXr^?FfcyG;?gH~WuZI}%$4#2_WcI~;8a>R4*&810000<2X`!DY@eRkK2Gg!~W~86bM1lIAZM|*I$mx|MR53w?^Yz zMEW0Vc=ZYakuU~Tl9%$opGUFmiT!t(|EvoQ9T8dYHQD2Z5C8o`*DCm4@Y`-t9g{YO*yK_Ds&-0yZekH;$mVC-JTgIEnGbHn|MsnR9qVK&{p zA2lP~CGjr|{}e6twd#Ly9{PPioE3f}nzvz-?yu%4FX$uM z`8^cYvvE~kPP4maaMe!rb%UW=Bw&x-bt1yk>q%aDjvu+oJgv=&i;%Pe=c6bCp3L7L z(vLs~@At9`N;LeBTL^8Fx8ypwkzSZ}{&~{y=i->dNh8E}U)ZBBk#lQc&$dn^F0u7< z;uu{BR!Ve9*^!63lMA zZeR{Zk#=}UA7_+poKNfJJKw7!aBqrv$2za57p;+-NInPxWi91TU;Zd^8YOFXDA{3t z6@jIFJK^4NYgsl6<}9|!k6~Rn)9~8ac?NL^I1vPsj;A;ICdl8$V$jeecy9%vjXF4ijzFQbSUmx zYDy2*b@p=y()$HpXT4yl)v9PTCre;&%VOi5Tif}r$oR0e)!R}mI{HU@WUsbZv}S4h zONkk=7ph*8HNh~!5!m-Y|49}=SVByqyG<hN!}v|S9ttz4aTa$nLFD5&3v9TsgE zB)!3%5zpgv$}!JzpD}r17s+A1XF7xIFo55|$)zO8Mp^{*2?K0aP*rqne!S{mzHhR96U5e|}Z>&NH!KQ%pg z&uRJLQ@l&*6lpbww@T4=L9F+WoWp>Fjn5^nvU1(waS3GoI(dH}v&zlCg&${g$=|y~ZSt$EqiFS)cBv>=Z}1T4xIaN4GEoUN@;08+5rdIviE{XG_feblCF!9r|eAbt=U7tTsTdm(W8Wew60 zwP*=DLuvXpO?EZpXhY7Sv{^=K+_jxtw*N2*C-@$;I)Mxx9v=MY?qwX2q5FI=8)GZ2h42dkjsx;Rpx7-ECv;FFPRTO{U&avu`mFVgF#kECnct1HD*r|et zcTR&+bEmqRjSs<4+nKxdYq~FkKMGE&q0&e$+<~&;PR!Z7ee2Lsz7r|5Y2LK-&B3Xe^(o*BpUxyfT#S6wg(A-LXT8m1}wr z&7>h!7pvdn)-rp_&I!9#>{4Og^Sos=Hl(fB%i?g3D25G+n>4R9JA2D-cc?YqH0ye9 z<|SFcRfo+614mXsS%v*>)Vj$CI%ORD>CcAhJnauUbZvc(6|y2&^5~VU4J}!SUO1et zDB;*`bykc+=GW#ji=b=X#5pYEu6fD|DU+0`9lIOZmFy9&=_v+pL>8GCpE+Q8kNT{- z%2+rY7Fl#3-QElnIQK8HM7Q}(Kf8&;Xo;gHzxSRf1W@UpG=6G$3`BDUb;lDoK#|6C zN?XUsi1C;_f03Tu#+HdP9=28+88{dN9)IK;zV(?*fWbSby)*F{yCQs*KV(rRifQ#B zv1KLULkdql`svf_ZwC{kZ<~H7v^R`D-(n%R$94{_36RHDJKwY<_W;<4j|W*zKfS~G z+(*b~?7{f5fX#{zP_sK$Eq09e9L~O7Mfv{HZyd0gm3Anu^5ocv9K6+|_tAFY54jr)BjiD;!fb#``Xfiyib__}vp)Lf= zBeBF|$60y%=JVdq{~`I&G9Xfu7@5Wi%=;wp5Ammn1X#S)2O0JMLBly@5D>xtd-?xG zmgyVUB2<5QUzuGV(u8Kjdn>f&BoZ`93`1#*Jn`a~}$q^FFhPgC^lQ@REd zqUYoOSc??6C#e7=SvHbz3V?_w=*?^5Rc51w%GdVC`!g<(F;2maW1ppH)I)Df_GyRA z#DZmrhr%x1Vs%_tA4kJ)$S4qO!i-IIfOkI zWhjIJf8SYo%?zyUHCi<`(enT(K;D0U3XVQau>V)#8*~C(wxx~p4goprgV=O>3CGvdZ&$_P8Z}iHo(5u4)ua8M+QLp?eBObyr^cLOmlgurV3KD=)NFW=sUo=a9 z_SZ5EUEOMbTx@lczEfrxJU}vAEyiltKfupvtfjI)vS0>qv$c}dUW90dHiKS%NLxg% zQ7WBq>eBsL+|MH))u9x2?7ALOp|JfRPCdBoWbnk=Y0)t_0TZ;LZPy@NdXVpp7G#Ae z^Z~%X(N!b34(D3w%?B8x;&LVpU)FR@Xk+84K_Sre=%uSaaileA0fRrNZ`06)0i#d= zMWNQKL~O+%5#ZiLl;s;|NRWvmo~{y~?fmX~FEilNdqfHHr2%kCM1-LXqSWr(Pmuck3}3=n`tDd0lN=@%x{C-Jkc?!XoGUlJBW=GB3F$ zZ^!LUv@?!vx8rebZcaO9p|ERfRaQfobF|I@B~z?y8!Uy{gvFZN@sU>^fXs0sGkM zfRv&J>4jv6KroymjCSOi9Su>(3|i(M)jc^ml1Yzk4LDsI0c1`=T32eD_ z4LbIlexS94KH$^ndY(p#!#swQnuN&`av@c81Zp6l`aEbWz2xvZVEl=`f`28$_x4)2s3W9jPd zyPS@JqJE*G?@|)(0c|^JQ(J&tmoBdGp+Dc-f5exlJiEeo4Pt_Our_7%d>y#h^`jI# z17@cO4%K$Lz^fDJifsxKM{tx)Joe4?DDd~+q2X2? z31h(Ny2g3O_)QWpC-5Sv7`Y1Ahz3EUpl_#Lw zcUM=l2P}G=A>I^)YyDt}k9G*FFP=Z)!|y>o}7li4RRQ(5`>B)3i4G|wg@ zZSd9gZ4=iwzEIr?@Ha!1+x7JL8P?I3neM(LVtoEc<&R@|Z7y-e9C_B=cn&%m;8xnb zd9Yz+QaB9;pT^uiqcgsCHf5^>?{*7wUuqTUd5CUA+nNzDS7D|O-Gk0z_EOtWO&_>?w%!1+f4jdtlRT6_miS#CEC4Y2La z0+=;!={BSby-T-T!LO`sE9)e?E@#Nthvhpv9-PXJ5CX}qRVnKcG6fDX=wgE=HgXP>oCpS8@B zbZpjB1AK$7ZhjKVnyXu1s~BHauo_Z*fCeg=B+uRyckLBJ@gbXB$aOmQppQ#l^ zxHT3`eJOEQIdEXQw5SR>es8f^QYcWfMN-6)S}+9*A9Bvwt=?BZN~21@+T7r9x7ID} zI=D0_Ly}qlajJ(G`CbU_%Dr$fmc;-x2ntu^Q}C@9qc@AZD^e)$c&04InPbS}Jg&?4 z>ciAG)pDwPBZ)@K&g_Trze=MY>X;o zRe%Z9z$!z^Ss%W>P55*VvQ3#@T%k^A=48Fl4Y|=B%PIGBnr?Q`iSn~AnBerC zKled2je9um5;_?$b{AT2GHyi&b7rZaa0ssy6I1-;J4ZfH>EpG^O}K}5^q^|p87QNV z!=8S3muQ9Ma6?WzbQ{rmg`d7^;~Lh%^Wk63m)Rj88htiD-H%8<3LQOm+5CXp;=Z!I z604EX)g;K;n9_|+LRpmOXPu}VtAjsu0T)RQlCio9a}}+i5?wDVu;WLO)LNm6QGI)? zhc$U7yJ@f3Z+GyN7NT-Y)H=NJGNB8Hp}e-Q%_ZCywRP7b|YS80aC$Vi*K&cU3R(=fR^=Cn)qmh}ikjzvT?ul3`=>*wEd_RT> z=dzNcb4l0F+Eh>dVob^-S+6Fq@nruLJU@rflf|$uI{C>VW`*!)ckFz_^Ok8Ki_T=# zKeXfu-5FmLQ7_ALz1dIRTQ_#;%O;~PQ$T4Cxp4~JZmp3}z}7l1U})Nzylzdz&|c8g zG#EX}AmDyeojqAb^HD5Q^`)V=cOIZQx?t3F@eXPT9{WW5ekRMnk7}EOECI@=zsFCT zg%`fpUBXh^hhH?)7HG*Yhh>{KP^i6E-v%JhGw!+fmfgT;UHaBFsIRD}dAHl@NJRL= zS$uwG8>#whmGyqw0-Sa=GRPI~v;~0E=Dd0212`=!+V%=jFIfg|QHOV6uPMx3G}G`v zO5u~JDikOgO~QCJ+gNhujX%tnR|tcBClfbpy;0iJo>gG?IJ$L0&K~z$4n!;gLg1GY z2hs@h80Vy+AHGMjHiK4QS-v{1+8$}pYg;p z*G44t($J>@h2IZ_Cz=*7_9`b80xk4S!PU;3`~3I*`4ukzYFj@0WrM*sh43)lq>< z^@+_Uv-hd|=I>9QrFA|dt8tg}(gD3II%6KG^!8=*!_aUcb;-ZAOp;;xA)>I_T5`INo;{C8+>T64 zuRsg6-NidfsM|^Uz?aK_i?FNTMZ-Nisukd;7DcIMm*oAWb+F&KN6XP#=K4Agpi+TQ zMjk!=ncp41^(wyy@c`xeDrI0GW18jQYf2?0ZTk)}1Lo zgMxaAJjGlU#p)84<1uYAy-l?F%Pg?@B~Xu*kf&H#{!+1%2|%mAN{uxiLwUb$czaRj z1a1PBpmuq*@8g3_UuDLX7U*X8HCdJVWN_osrI**>6lm9=@djO8wmH^&jln}X1o_km zB~_Tu+Mpne_nK?7J?R z4!rwsJfjCJ&BLG500qg4E@M_cDrK5Bv0}bx_~4D_MP~e{>FilKeoL9%NidSeH*x5@Fv56WA-_*t#a=~jyhGkk= zl5qNEtY>_bOV?4{l%(p%?q12-8U?H^LXFkM65Vq4aRnz2`cY(?@D{20ESz=AKrFAh zbq|o|A_zt5kLs%@J4HfOSgno*X)8yGtXt^Wm{`)&WVI4T6#+xvqL+W*xJ}0u2D+7% zuPLS^J4(;dIcH55c{d@)C&_^&oRPyWl!%9VyV^_$O{A$sP1FU`Ka|>-uS+gQ_DPBqeVWsc6w&BO}tK;aY0NWw$ zg0-II;h-$dGTwFjXjX-gVh_}%*M-y-8}J@n#CWCPZR1gO;GIs8)0%JPy)Maz@LD*T z;&r{do)U3nzC64=FRDC@#6G%*0TApf@L~sdd4*_QzX!wt@#8}Rh3>O;n& zF<4vA(8?KP*QM!loVl-?azw;40}v>l((|5~3Fn)}He3nMnir*RyI}D}?D+HPS)gsl zw7WKh1e`Z+%c=fT15_XRS(RK36Q)(m%3i80#+`3q8+;A8-dk#XyLb+;d@s~!EWnAs zQAf9)z5GTZ@a#^$O=x$qc(OLUc!96oZ2gs~&AZq&(n_wLhFNQFN7ZuuBe$Rgwx8$4 zH|9*AJ;y}Kj4E?)FYj3X1e#Gq(qo-z@wcZj&`bY|Fd=`#D`5iwsSHFfV@g+T2Hz)} z0h*Rs@9wDkts%$Rw)t|@^(H2~z>bMz?P`msNNnV=!|&dTv7(y*8fcGsf?|>h{reA3 zSoV!M1mL{rnm)rPSSrHd$-=OPuBMft`KI$WHK3~)yY$u>IQsq~J_t_-i6YT=_tigEGfgM?1XH>OORRZ{sq&3k zz-o7}a*Te7WDgzs*pTR1F12~TDl~8`MNJ|V_Emu%2w0=cJ#oRvBSXWdBi!7=qZ>LU z05TuE$9R~IC=6`RU(NVVl8Jtd2yLhRh)xY({68WMT}D-Tz-dAFMoWO3v4}@(>&uKK zphq|D@Iehuj{aU4Z37y7=Eh;|9I~xW(b#+~*AtJpl|+6J5`w_#xZD|d$*}jvglxbih@yJI5B`10M=@2$2P_nuVL-dM$`g%ZIc!UtQ{`Vv zRw_q+*H8D}q|^v?pgk-e0oG1%kY&02?`7&CpB4tvaW+kj8CYIhtkoqX^2(Ell&beJ z_U#9LCKselHdvtc@gR+F5sc~)Sv#6>>+FUdi4d2*9M?sYz+EN|dQKtnAHyn;*mm*& zi?~OeuS$3|^;IcN^RVy|XU8F-m%Ke5BDapik5njd@IXx89`(M@O#at8GJc`&FZ%Z^ zo=jRSr|}fzDek7#6`V9m z04>>PvjK7jp4LU$B3AJVNgJ`30~~KKkCt5IhEj#Wa-6@!C>-E<$blU5*?lYX&QPD| z95)B}XQ~#^I8S2S1h4i*|A;bD_tVMuUC`I{c-&qqi$($Q9*Q9Q{Nauj$CH0sHyio1 z9dGM&8IKehBMyKArF5n>4DKL6$UW~2Fr=&Vw>8fH`Eu*8eP*a|9@}~E(qMr;zCl3L z%vX$e`k2)If#`t4`BgZR7XPb4Ypos9-4L1kFHkTdzsr;_d({3iLkaL5jI&;jQYHKZ zwxSMbTXC~mx4g~6Gp&EziGl>Un7KZMgT!w90dl2GU^=u)Cb^a(IxvtWc_NXQz(H0c z3d-#8XIYMjCs)Qmt4W-vcxf#U{~w247DA+-1$+U?Cn|NA0yzi-XxNP9sC|w2)j#GrTd?UIWqx1WfN z6417TXdAcW!SapTb2*_W7o~tLh z7zH-^wpDD~&8Tc8P#g?2Z>*erll_;sQfLC;0A_?#!@CXtpa}3Ig(TqEa=1@7|8?d4 zFP$ZUcGCanoP*cv>%=ZXok7U}3*wUe^anpG)+b2R1~InJA>Ga}QHFaK+M5kPMOiRvG< zU=zFrAhggoB!l4dt{=?0e#<#AAfsY7?D6>DXv)E(6U(8&^yq*0??Wt zlrF2pG+E(+eDf-yNqtW*r%Iuh*v!1HaS{e>|j7|HML58(FYm69=mdYL3t?!NaPBFuRTX;?=_+x!5$1U&{avr1rGkDBGA zD^Z;8n;f6T`AQiA2b%zxN#-hCLhyPMNIT|rVU*dZuA_nH0v$};VVXCEwNhFR)3oXQ zi0c|w1ic4pmCrj-OwT%W%ub2~AyrwY81Q;O37*sj#q{00jY3_#9pPPXGeI(|7brNWKy4U{Ae-HBJg>3DRWSXzaPa8Rw?tF$5d<7~=w*X3U$yH!J2vzD zLZ$9-MRR@Bu+&BS58TukpW&_>H4)0AuT$W&=m^}|6TMtQpe=nNLQ>r9_wQf>!2%xZ z%TsY(@0uNW*0GFEEd1T9QYlFqa6U42zABLy*JjhxsQx{Hh`{@>n=WK@U z;lGJatjha37ISC```4d%|4RChAbYCB!)S=k?5W2Kfq`s{z#ToyCN*K#+%?a~z3eQw(q zai7N_9|NtqCv6KC_8GnsY=V1a9dw>^BNd+HM4ckt6Kb5;_I3XE1C%sKra*z5@Ag)o z?=Q@V;44Mu>d12^3)~V1H3kzmtaqcRXc)u~U*|d8tzT&!Io?p1#}0W+TXR-GQu6+# z5TgREIVay1PNtloq|jAkTg3nvu?+eB7ZSZBjevR90iBqONyOs^-`uQH|MfgPCA(Z= z=IuswzQL#bUY`cE*%{u7KfPZjKvqvrdms=pa(%zUxDJXO2VLV+vsu=WYof(gLknCyffbRvZ5C=SsNA=M*v4jUC=Gy<}Cud19ZZQ0tp?a?n^H4~1Q2S`5P~vl(#yvB!zWn|2 zCptEtUZsNKzIkq5ox0kfzbR||UEolC!KTW=Wb&SRyA?_!mdlK8y+H> zEf`v6&vCsj(zLp~f0KETKYqQ@OnLR<^^-Dj zZ~Bzle=@6Cc%XIBPI!0Dgx(vFf{lUW%p)QZ%9FMaxm*|#_rYLAQ!4m-q<+4&`4h zj;kcQk_GHk=eqy8)0m`KO^h|&q{6k^HSp#^#%rj(KPC&(Gsc#NRLSnb3*Ls?j%v1ZF>Sx^3c8tD{a{@)$CqKU>t zv;@mZF{e%pv&EVj0)n@%!w4h%WsNB^bY62S)5Wjl>9;c|wV<7?)(wMezh8@*(>}uf zByw-*3$#bJ#W7#-lg2fTBa*JJ?FA+``Q=Z>fX7s(et6onAtkdRar~{o9NluKQ;6_F{vVIrc=GnGq~HX=WL)@i@dFb z4Nt9kCf(|zxuSYbTmq+93-el5|Kz{Wc#8bsQE~08G`A9+z7$G|dvocx?nh={)F#y| zoJs!<^r5^mny(%>_*TnlCzV=ogq+f`IhInkW6Jr9aGFKr9^ldgty3qDbZl!BbERXQ z5c81U+7^M;d6~aL!YbvWLN4y!kD?QqIH@Sd^sNPWQTib-Ik+u&EZcLX_B)c~<%hrF z*-4#2EM4>2I?cAe7>)1QYamt|{@7V?8e09v=O7W!#=MV_he5~VoT8VxOlqAwd0+5d zhCEWZ4sAL3skdi4?kZA1o>a1{f&_bM?3vjhYvVf#WPCFf7;s8*;c!l|s0|#&x?8x} z=l1$X81>8FXrU30k6;q?6Yr>oHj|BaMfl>CEe^d@If2W9*ziY&!^}4e14}Dr7Fbi& z5%aL$PJI1Vx!$L3?5}YuypDWIK1c4iYXXdN=|6>h8Sz7VOcvxcKFh)JoHxsY5oR%6 zY;bOlVTdV(5Bz~SHkHcd7+71 zK=mk?z*gWjeyys_h2m09a(UIHkj?6bTckZl-V1O)AQIGY{lyfD6HWP8^eU;%4-!+B z%k$6k21uw0^|*Q^k13qi z_i|0-^_A8OYO6N5TdLKh6fK@85CMf05Y=ME!HEI^azje%a_u{xEDiWx=CTrltGCr06c%u(Sx7RHu0GC!i0T5$3qmHZ4eHUF@wxk5_spPAJ0Cs9?zbYL3i7t5~8 zF05%(v74X!Xpv@FI6#93Ux@ggxhoA25IqQf7}QM7Mi*J7_j1J@TFi^IHIYES&9xiO zjXz4n$GA(CmYh+=>6ArBxePhP6c2$f)GV<*n?K8Jv5!I9zQ)pppU`nON3zJWr=F<8 z2m1Ljnpxmq9gt(>u{sd>3^-4Dc>FGx-t|+Ku!Zl2U{ z3sX}ogD{~*5snK;Ui#q26igy9$5=fXO#T`c<7Y%n{!44{F;()4cTOzGfj+s5R{F+&3Y(r;a-x{GITN6?ZD3Iki_Gw zS7bOm;iV5jy|v8QUvScb9tu%iMzmQ@O=TAhjdut<`APCs{XpBLkHv=z-p5Ry?cPs0w8XtOcfLRp|td2XcN!A6^ z1L`dwFaTtK7Cn3K0)c+25uF`h8F3S$x0Pkb)z(>c#@kM0%3M^dpOv)E55Q6goY`e8 zqXR@PE_{iHwS=A~4@qZ{>6`0&_&lntgC4~*{XrIVau5Ulua@iR^D%-e?|2=8znW;a z2AU1<{bA%Wb|lM>@t2kkzKp+`$*lPJS~hQB%l?WrGr1AW_EbqnkZKHO(XW1vWb#62 zk9q&4NVdT$K6YVdwo8}ktdAu>d86&6y%@<=X0c3~8rJ9Bu%8;fQR*Q49H?pBdjH_O zPHL|cfkpdnJ;a{-Pq~%%PA1sJIuM0-^Cy|oxn$`FA-#SUL^;8*BYwIq*J}bGczZB{ zj7=|LS*iGDwN+_2E|~)u4a=gIiYZnx%z5tyBgc@h%E3pwJH!iZB8_wa`3`af2?v` z{mx_p9i4DOw4uy%FFIY6r0!Ig4gL9<2jkp!BO^hZ9nESAsa!C;WdL9^Y1xc5LZ0~~ zYIEnpG)sLVS}H!CTD&EhH{J3=g4m;*gu1`zsMW7!{-%q2l&(|!Rfd~V zmYzM`=NFOC9uM#|rz4huIZ!tEPg7a#?4M)*oLLs9&<4F6&DDIc>?|(Ei(=@q=dA61 zfYPvoP_l^`^jU-{{nT0Pc;MGyUs=0c&C>N4O<@`x?lf|44JZ+xBu0O{u3~`g&FHyKUKhB{}=gj-~6lTXe zoAi?kR3Cc$`DT@j-v+w4 z_Cq?Oq2(nDZ$Dj;IMw1;$G6BS?i$|>>?e+&Np&8~c`3y@0_zXNxARtS4{G_T!lD>- ziu07Ka#AB3ChGpk=F4DNn&?|PVP+*+Enu2k#!sVvFl^`PbaJfO(bbR(lxAj|{Rloz zd3M^7JRno;R(bJE)hrX&rS+s!m+i3iT?3Jz;Xq=<-Lj|U;mRI2qOhF`Hq+=heQKcU zF%%dR6BjNuIrLTaX_QK$<8t z^31})|1C9X3V3vxCAPjz*{*1*U!@))M9lkoTKcoeK0v|#@+ynHOP5Qgg=#(E=1jR^ z%V&5d;8Fp(&}h6oyvZ4QfjH=b-t9mV5%_SK0xc+$=J$`;9_-JJwknp3jw>`H69Q~h ziw{1?HZvS34YoJbN!K9yb@>d)%}CpizHMt2LlJGd=^iqOW)>Q z>MoE?yJ5FcMcp{-SEC<;XxWU6a<&<@2_I_%{a&y0gJ-Ptx)XIi%cZXq)p_NP$GLD) ztj6mxc$0HihaOHp`g95dj*VKs1BhW*bbIib&-%2ecQ4u7&dOfLRz%_mPu=S@S{2R= zfv-qt3y)H=irdRPk75!GAEaUeq%_(P+1-}M2N_Qu}2`@ygpe@j(7Ey7hp; z=cc#B56?k>m>>vy{=8DiA>KgeW&W<*IJJR9jhAtXy>7c*a|xh0;L3 z?%~m_QN4zJ((XpEL?G2XIrUK$kjs<+OyG?qaI)avNL}()g4%Bx;r~P-2c5rJ4oWYH zlRnb6{KrLSU6MBd{D@o7h0#9tJQrZOnDhYkGNrp#*&hPq5M8>kW|V~-Ub&dAqVAse zux4wl$6DkAyJS3J15>8H`fvD+rSiTe_$9m;nYT@TGQx9!_hv2mwvk_7>b$#Ok9GtT z0}y=?K$H|l*i7tOR@>ICY)vCW?fl#B{5iNz-p50q)3_1-{w)A9cnS#s3H0Zp#^=9v zQRtc*8uY<+z4zZEHn8 zR1GC{sCgwUR*XaTd1|yko+cZSTaGMw7Vv2*pa1MoyX00w{gi1}qAc6ZMGcViy0bVz zJhgs`BLzg7=*Y`B@B{fcAdubWEY-rvliVT@o-yVbUf*(i;Xug_c&S<9@CGVgxhAiG zj8RGX2sk28ZgV1{ecSn9ro~Q_)8YJ2VC6(!JQUGMS7jx;%Fv!6D>9*e@#M*Y>x|it zoLHSG&FA@(wXLnJ97uVIbRD7G+-C>PLYl1=HB&|Cz>o@1azawYfHs64bVyP~S^dkA zzIMTuOPA@}wCH0j+3aDxZ+7@b1U?{y&KkHsX>oEnL4IZPUh@Mzn96c-&`P?-Xmru{KDU83-e)Uc>iY5W+X9?cXAuma7dx7W`jfX1j3{}A4`-VRUC+3|Wh8|I8d*4-c zz+qhh>czf++oCmo0(pUxoFTv+-f@_j#S-pzx$MgJ|74$R1X)ZC%?KP@hBr#!GcYp~ z90=Z5GLWeDa;H@1W5Fj{%+UcYvWiiw0nWL3Hz`vpIvOt+?GsqD@*WLZiM}Phdn0eW zx1TC}RU}ob9WipPJR!y3g&D&Yj@1%%1&AJ7y&MnaY-x-Tb2;EM!G+$|-2nf@eu6cq&xKs>one= zvGHCr1*lE;FexQtX}V3@ihe8=D=Ge^DB4!{J%vTfY4#`xsxh!rv1C2&rn8~)R3}e`=1|fkb zfh%yCs7E-c;N)k|N6lf#ZF<@znRzX$B;_*c4==D>+(VY6^~}5O14Xnr2y^hu+Mg0O zRpa%d{2pwFS#Hr@WHsy5Gd#Lv?fQqBQF}8!+#EwER9~J3fc1D-I4&(9dL$LIu*qc2 z5CghWx2g{u57c7ra3ipN-yGlkrqGK2Ex(8Slf{Olmhu#@736~A(yt*$-i?H^mG{Ps zMcz%OLJdO3em)BIrOfH;%cpIMlJD3gcw~4{+pA$H>^R-8Ga%4bEc}fL2`!wL%a<#yILsFl=H01KO9+9y+#S31nS-iS z&;K$uZ$0IbpBMGF6&~O-V(j?&L`qg6M-t!*g#kBwHRWjAGIDjonN#RMUI-5?)yfAK(Pa)(1zOYC|=?I9CGC=F>srq z=Ohymuc@cTY=50pm`eMO_)|f<1T_tfo|fCogcN?esZM|;0~<_Hg#4n28g^2z&Aeqp zuO_GclJF79O19OM7f2S9evpg_Ki8x0BCodZqDI%eKiJRN=+?<*$_QGB$)kw^^xT0K z*4)YF*R+zMiJUX7;YkPIxp=VUrOA)d>%PJt&AQJ);5K8b44+p(Dplck{+&O6`Tl3e zgxdv1kO=OG>Lx1(>f_HTUpqrP{j4c(9}<)Vj!SdS&*Rqh=|N!ObL3yf>4(>E$1_9V zv5)adEKVDJ1^EjW<5TwzSMN7&Uv-b(c6|-^evq?4YvI;~b6IJw9yk*S`x*Xr#{K{~ z;_5U|>4dT3*{6vd_c(RQ>tiAsS-zjh#B;kjSw%C&&#fzAFCba2pUKe%Ex!gD4EP<- zZT63_KO?fEUt(k}1P+%8M|`KA+kkj5f9WHR@912;n}P_E!_6;bIO5sch*z}sc@dLh zF;>3IQ?*o*b@}ltxL5^gkWBu|>`l3?m+%`(eOa?eB1(=@ln5RbC^lQAey>h=6 z%MJ+Iw4HfjvHb2e+Ez3$sMNCL9h(^0@iGGkePT+zpWsNF3g}Z}IC(Nep(Acl+Sofp z7m1e35$l|vz1Z-;MS*+EX;7fx@f)Ys2zo9VaT zS(J)wU3N|MOcuQ?i$0V8HPoKCkkMT$bF=8TW)^<>tAH7QLWn?xhjpYr zSDUcMqn};Bk#QXidq@;6_N%50>fI!lasDYWH&J5R5Q{xDW6QxEUGHz_eJ_u2oe z@%|wwkW8%-&>mHkL-j)a4Vb<~(3z}4KO}oFJ)do&HKCwHhvUgCdcC+@wF&*_Vll`E z6(xxoU+z;0FuqDswt^jZe~vCE_-POC%e|D;vWaFM?u92Ov!PGZkJ2^g7io8Y{K4sY z66Du}mE#&vlJ?r`RB8Q9r0v-kcZz5%kZG=4Zw@buL~~bAXm%u$6qtd@uiv(Sz0E@S zWTfAz`1L)dXvG_8nkbHjbjD7tJ!C8!vwzozul_RG{#-{<&64X7Igwn0B>Ab8;`>sg za{J_cf-%>*_*&y17vkhtpcy*H+o&|IDl40PtJp@E{2j%uYqq^T6o>3qC7ZQri!@As zYI*O2ok#PhQkZP^y%-Z{{7FQd7g!-OPBKXv0dcxt*Z8nY)lAGUQpgv^*`gJ5e}3GL z66dkJzTRL?}w<$ST~l8y9QZ?!`|%1yohgBY|| zz&MwyhTYL;BxnxiZW?c$txDJ2>{3fYoc{>PKIkz%EGF6`D<{hj3VZc zb?|h5!XP!?iE1z&wn|((bZ+n%8`MCRff~=3hYDV%z>xyEZ_G_r0Y^}cjraYhE+YbE z@y@py#0Q=G-kfg$vs|k53iR6W^Rhs~{UlAH^9ZFYLDix)Qe&0qbVPyf<+yF_&1kvh zM2RmAqsjiq$pOx@y=f-HU+0Mih{NHr^9!Gz0%xZvp3k~Qkz#?2sWU>p7JJSK0a_1k zZRu8V8*m&SbO8s#LKsUNqTZiW5VssWfp*dxp~U0rYv6c+LHlJETjxySwwi;oaQ7|1-wRX9n!O*IHN1YtFg2K+?4blj18^ zzx?@=5T;Q|qiI)Lz!wRdLPDK+2&Jx3P3Mr=Fk#RCO$4vg`9r8C(mqzVD=B0YzEeCg zrPh%wN@ivC&c3Qm(t!SCN%viJ(@V9c<;dLKgBvzCg4weeYrq>INAM*;O0&Qt>9anE6PGD?Zy2;&TLRm+m{2%+Zz!`XA2fNtUIdf?%TSXHiqMY0)w=QZg6%yR|5t9xQ`yX>A?|>q zF(s9CU6o8TCM0jMN}NWK-Z9fwru`X2*ljXAYH@@08>u@BNLz%1%$Bu={9OCLtnkg( zmL+J|h@CNJs5o>QNue9iKizCaWKr$XHQD6@1d=A=I@#CJ0KYAUtZ!cTASeD@aN;f! zGp4gsdy|q$MiI`bawhH8vE=gjU3dNG3PE#YWKHX_2HaZvXM}fcR}={U8oY#IHbV)Ek|j zTp0#m7o+l5@WL`(AglZeD-FlM%=qZ$a4y)qN4fAJB|iklWa(m)VeOVj_y6*YK4xKY zc~saMuMW^~^|Fz$8od$(an+tc{=e!5lp5$_fs}C(G4S8W3`Syo`(hwHMOipG?x(g8Wf2g=2hXTU$|lG6ewOFr<=s4dqlq|soHPoNp3Wc zaqp=SFDbaDPH+g@E+LxRoLEVKU8BM;3(cOjF}Y!%8^^hQ(Oebs`+qAw5AKsZiJ@Js zQ8at2*w02%r}N6oX7so~Ix-&3vreXW6WiG8P&eT_-_nSEozrIBBcw4&P?xPTdrv#3 z&`~GQ#q+mk7QkKaa7r~ukV;XwafFsg)L7y&t}&jyYknf%swXrk@$CQKW|RQ|lO-`@ zZH_+xu5bEk%2Ibp>6l(cDOM zG$uR_y}t!=8bzEM36F(lf#x$5nB(~_($$J!z7}ZR0{n@j-$=2pwNypXr}Y?C%-EF_ zcXuY!9;aNGMg#p17)Al>t&@>-k#MBNrpB8#?nI{;;_VM`uTj7Uut%uUd1%iIZlG%; zMzc`^l}UVFvm3UXh^6`8K_}TAiXUJW)``NU&S0o<@e`E5{5t+kqcecJBQ^bto!>~Z zYaR&e{&V!9+eeYhmKl6H{o@5#9IzljdZ9K3xv36nSZOho`QwG*3Mu#h_8IlVG~QoT<{ra3A|s+2u;+LMsv$1ND6nd- z5}ld7^1eoHrjE%4N!R+;j>;Sh;Xk-zTzE^3Gm2CM$j46&rnvd8JaCcWO2Ul{hEuD% zHoKrrT*u9G;_qKq;{t8HGG>{_9IW|!eyK-l@o>BS#Zz87gQFvwPjuyv+G{vaqq12h z(4Q3Ib`2eLd+aZyG%@hRaUL4FS5_^maLo@Mt@i#Tbf~O-1?y_I@i*mH&Xu2O*KH*6 z&dbu!TOj^_AO?moc4}^;aL3NW8#yM3MkpJo_)Dg9@9n$vP>4ZN0Ih?Q%;vr`B$)ro zZ5W|T;4w{{XBnMUteN@!sh3Tt#{w>J2n}TqAdB9U2Qg* zsS(^!6wm(R(8@F0$y>oTT3S;!$7c9w)*=oXl z%Gqq@a8u!baDS7rbYQrsX8p29B1%&^t`0-%kra2FNAd{2`S{q=0el4CZYm~&L6@fM zzCd{;ExCJt(H*|QIx0+SNRS<=7FPzbRL*oBg#H_)@TuMPjd4Hup{xxiRsr)Od`~z*DZ zP05qi1GOG{cCRI0OEX_VGFdq#Qra~(o!!#3Wy?IlKM^%(ef~a3T?z!ozb)Ht{c*&W z*7MP>6Bu4eE*O&PKhA6m`{N_ycjl5r>xQ7men3MtrCK8 zbpF+SCCa_hQ^Gec6EqUUgzU9^!wb)Yx>!M^Zhe4%NA>+>GV@Q>67KUWR=Y>?)P14r z`+XV!K=$uk)efc-hm_&?r{Dq>t>;*j6Wlu>tSv>u`0#4SDyPPZtZu~}j*idmG7=h+uP@Ft5O z3M3bx>=s5iUUcKYIG>KbNt0*hR4#P&lZY*A3>|9Nq>~S01ho|sqmC8B^=AI68>=~V zKbf!AHYoqRXTExRqMcbr3W)81kym7AXFiN^#}fCIXZ074^n(6wjG?G@L;xE(@wCm! ze~)~Cu+Ii8FbtNEs7LgUOJS5e&Ik4AxOwlbgW6wH4-~8 z7JmhyfO7sl@tWyvi&lUO(v(oxAuWrI9DnzRvO>B=@cC=W= zl!sd?9~V__JK+w{fkwBRKg&rsLet@y;DBHi@7L*MzcxZ;Ks64(-k=r!BKaH?`VN=V z)JC;glJ9k`R4;118#rgaWYvEC`8_#tw_Ccf=&U>RAAQqwor+hA~V;`)&J*N>;@cZc;E3YO|3 z$Pq}7DP^{v$V{FQr~YF9aR&jRJ8Y`iXw0DNByaBLipTFJlR`eGDc3e5E$S&;c-tu& zj2LZc=&wr^DlqfI@=xA8J&ViqiZh zj~gwHr1Bt9)6D;>rOWuvLNTH3MbvWs)}13*aiI>tKF%kpLMcuqVQ{ixBw=T6EIO2i zQse4|bAl1!1B-7Ht>`drPHU;^Bwuj?H_it`hT|vI%~B0cnK;vw1lyfb>&=xRuDtyE zaty}fYRyMAgD=j#`~T;$_#nWK>aXt6E2(DN!(CKbJP;{85f+ZNuHh+CxvP=~fGA>+ ze*-Z?D@(UKDtr5YMnSd~3@9s&p02xg-+e&!RS=^*1gp?-bhYZv7c=HGDyG3rM(nbqu_vzJ?#b&A#A}!Y2pn{V1Ji z>rPM4fc$?IYdY#^TtfWNlhTyo&1hJj6X2HX5b|og^<6xxc0`l9#UrjG?xK|F^k-a5 zC^c1M8gW@E0MnKw)cMiLN0d?j#8Lc3GvJ|7Ar)&VWdWf)_Ki2o=HKJ%iGpzA;uXt@tiLtor_q&#__A^wAqbPvt(ureFiB?FYVc5~TQeH&bkjzV) z=i@h6-%p>I4*W>v*E9`!<%*I;xID#;lw?dOViIShqHw2lTQy80z?k}RsPAgCijI6G zkQNWLdA`(GQ{;ERrWSwyzkiGb66$wIIR2rO+OeqVazi(vF!LYhv|3CT+G`+XPxC9Bl9_Qvn{?dNbDfq#Awq(O>Xxo~87~OuDHF%6g2W^@BjvCvrv|EeJh)PerGtNb( zc@+?#k^f^Zl^S^!x@rQ(a(=+J=0O9Ir2p2-ReFT_&AdfNHXMosg4lvS@HS8TY<@U2l;!*Xsf(Y*3|V6zH8hO$Te zY)@2OQzZLFskw$AnKZ#bMpZlD7f+U3{Oft%Gv`Nqv6^)g`F z+SxjkDVven&AShvV!yd+%xy?<9FMv)!|=vtoTCjO;e=)i@m|JxkLY zNEMTS$>5RUQz^RL@c?3t*bBcNN{k#9H%wc}QBP*OBIU?&oC%Rv&3b?8IIP9#M-o6* zx8yK^K>VyZ$+t`P-6(3z>R>OTMPqbV6q#~WR86+D$*$dUooqOdQ>O&=mzI4Bw&Yyp zI}W8lrx#x_n}_D7*18&Lz&*zC>Saiw{M{2642=8$@{-{}yuqvFUtX(3M^X6KZ;P)T zY%24xmVlH#A?s~5iEJbITKx@=UbW>9g$Y-T_ zI_Bc`@&b0tuczyx0jrX1*l2jzj1IdvC0^;LG#0-f-%}saJ##lQ2pvrshI?n^d(?Fz zxf6An)7vQFEG-}SQ-8Xe(%kTgj^49iE5-9+W?7LOs|JE3|M3&=HMQJ%;T!C@lGk$kc3#f zd;X^vbez#xYCqq@Z^t{k(CFycUjwktrSV(FrW7ck2k9*P`3Idx_~i512*_32Fx*1N zg)ySJ1mq11{_Y^fjp9IZBc)oGp-0QyNUY4*G|T}us^ZpVT~b}h&{Q+4m`+!v&X~kp zqe^Y6^)8&J0xhqU;!#!h)Udf(S>3RMj%v+l0|i>@|DOrBa^95;EnUj#Sf%c`hlX7~ zhPjWV*X||vmj@~$1Z46Ds_oSN(;VWl>N`J2{e@00l~w*n@hx%@;5;3-H}S;wNWQLV zYUwgxXhya^7W}R$mg=6k+(2QVy?mVLYwLHS<}K5ON-qgg)c7i_H@*TrpIB_ZebAB) z8AkSn!%5wV6*=C&6vDFY!exJ^m<(aLS&>v`TDkd_|AxirxF8ZL2kY23H^?kyH+WcL z?+EUha4p9J2CfB;W~5jd>LsR~W1mtgf19`Cl7XaQZce2MxaePvuYmFT0|+1}nFFTU zZA{o`)Nfu>`aJB`Asz=^`5Ph=d7;8mnyPN8aqNQ%Kp0~mVJ<2%r!u^%RbVuCtFW8M zlIX8f2)+);#o7(XonW+x4?1=G)n*&`m?gxyyS8Zw(uBYXsi z{Y=qq7R#Lq^V$UQQiqM^>J_S;#}5Vybcnxwk3L8Hx6s&?v$$QQ!%f9l?#jbWSWo~b zwk`v8jek$Lg5hl8h&;o5)E&KYN&LJ+d)fBlQmTO$eT|XSEL!JfpJL&DQaeG4vI{BJ2J<7QX(gQ| zPtVgo1;SI`e~@j2r13yw`(i_lf+m#~O+K~BJwPv{nON)Z-%OJ?SU5u1%y&ux*&;|4 zyt&C8qEH!)n@|WEg5}d8gTEvCJpG5coSUk0bfgp+cfqjTf~uh$h=we7HpEmV#*bBF zT3?oF$USNH!Y4Tkh>@TsYJdd@L{}!)!MV$Ih?e@_G$r*wsV>V62R_xc=FDM9Tf5)b zj&sTIM-F$BqfOhQn+qBxlG$H_v!!)3E6KK) z3rZMBm$!O&i|vUfZ4r+pDi(5+b!|Oh>L!${UoKXe*Z^m0^3Q6zuA&5 z-pGCF-y)Um%%?*Y%O_~*tUQ2P#bGv{cLg0UbX+I#4VYXJ<`al+rmn3<6YkBfG~C%* z_3A3EfD*l#S^2lN`c5JD9L{B$PUGU@c8ImL_475Et|QWXPSem$RGoTw=ivLq<<;ND z!*P33(Ud(uWAU!Ao2A5CpAXKU)U@jqC_7ApV=%fg}$+IdiP6qG%USu*_(R_4IT41Ha|5 z+fwoJHuBK?f+&~ei@;^SWlwA;90V10aj)aL=60ljxNdg#o0c)+_K((IegX(3x)SadpDfRyR&swW%1XJ`1+%B+hg$fW@|S*f*bJ= z&NQHjm}A>umg?clTtTzic+{9{W6<_?-7!8&S`iTG&LZTEKQeK$NNbqlD;fO&v^D8q z2OXEooIM`r(*op+gePIPR*VnxnB7Xd zmtu>pj}Ta5_jzd@ZsYNni^!8U+J&D6V&+sQA#A>y6O?me;?D@z*L4d$k&q>mm%ypW zv}Giriw}~X$rXsps&gJ*L;YmXy_Y@s`fcUujyp!)x<9pca2gyH&#Y%HmY7;y%{Ruo z6?4tYF%Y$-;_cHH_?HdQjFN(0uNz`+b5EgkUw))|1%I}&G#+tk{&60s>8O!QOS3 zCjhv}_3!jG@V}kvIFCEwYEAb3N=PqbLJN7TVR8SXkC~{mcr~va#9)zz=XR{vGD@Uc z)xw@=VU@s7MVd-3y(4no)B%-id3=;|-|%id{0zSvJ1@ETK@Rlir$Q%2glo=pWM|Ge z(U&|YgkL?)eS_*n)qCUbzJ)NUm8Bd*yq#ve?i#c&AwBw)}+Uj>hP3&-A&muJ*cQDwU^CEsH% z0v98xYi!naOMF_T(s7re^)UD&CKa!#-t+Qm?_|0M!bbE{@K0>II5;^nGNZ=(&f8ba4I74G6fSVGyjm83rw=Wx&XgTjf5#f$Yz7lr%Y zOzED_;qBIo>r}aWdG(bHiiU|ZrA_)Yx}aXM6P&l#a?u4`$F9{*X3RKnxVjP2JTC)0 zPgQvJgJe$D8s{iVL%y1%^PBg<#-;tN>0wyK({mg?2~H9HGs2@*^`PYao$K2s>a8;m zI)`BS$712qmKSK_^Y{z2no4dA|0pJSb^-wqvw@)x9WSn2UQX1N)o{Xs==nu2&kw}y zmO9XrL`yFxcZZS;s1xL7?a5WfW3dfJ0TR$3t-f^M+RmX96_{$?6w142g;|cOyjzCf z!fx<#IoDx4g^9Fr7-1@^Qt~{*$YYdwPrK(|WvgEG<*n7T;h7dujrU_idwmru3-DUi z2-jz4$nvmEWAtjz>V>R$ux;M+n6?mAc4X90!4QDGuSdsNwlI+X9pAh2zA;KnzQFC? z?J8*QxYru`7kf7`W>Inx&UYH)e$M;)`_ZYThINPFv4lg}LW_0eqW6;u-}&|^YG^es z@2tto`3tnPrKlEulXl)kD==`gEQw_5cH?mwbB6(GucxR!HC?;%<&GWtcS>4v_q5(p zd$zaZ;%Izv&|WCjdi9wf!+t6j>GtmB^2~B62o8AqRzzy1C3s#hQUt}xW%-vXnTvd! zjz!dC^D6(KCCS+a>i7Y~Mzpb~<>H8CN_3Y2vcajQWLL;4yO(~VPE+)@@gy5U?(a_P z=SUqVm7aS3S~1^<-y@4E-g`=r)42+Znv4_h-aruyWOL1{kI2n|qa_5KmUuJx8&vj> z?avRSf<;Pa?aYdHuQ{)mwf4s7UxLG-SP^TG`90|+9Iq2Zd~RxUz1ciFFQ*CUn2C48 ze0eF*nCpwI&o69r9?o(#9^j(YP|B`gAX1~>b&*-lPT)#K6RE-AT&5>$+p=?k(gV0- zxZB*fe0g5#R3uO1Un3b@m@te zk1(cH<)9+ZH?%+2Kd*K?*bYK!0GoI;Ef9tUF?1Qz>2jlIqKuri4gq=^pLjOXZ+jvHRx)Bk;m(MOX%*)c6e^@Wz_ai-4);nzEfX4CW?V@7jL)2W?=MP z#rKu{mG2CU!m7H2LL_{Z7{Y&Gmm8$ef#y~ljn*Ksa~`Eb7S(tn=0JT@jqu)0-Pikx z(Oa)yc1+{MI`uRbpKqM`>Ihy)fzh0{B!gi+QpyyT8u%=3h_%l33qicDUsA)lKKu0P?63(+(jv{NTEhrwZUu8$^lr*s@-&Pwu>ZbbBabskE}W`ZG27o9l&Kx#wu5Q z0E|lm8alceU@15`km1(Hu#MZs*vD5C_X)47vwqtZYHp56x-NKcU$YP#&oUMNof9dt z=j$REP@$jX@pTwlw|S&r*iM|%n8EuNW9$>|S9(Ke*ow-*a*6X1+0^Sn4N3IY_R71 z`9TO)%h6yb&Tcn*`37FT*r%)u+cij^xzp9<3OQ?7J&*^v(C)j}+$OzFD|mLzg(mWm zdmhfcG8yMDQI%aF6)z3!$FwiMD_s$WtqdA9P9XfHFJln1_5xkaarIFU>n*ND)dzP@&{K6v3H;Ia{btsG4fh6kVKhU-*{NFwF@Y^Nv2%);PtN{=vKb?o`0+2I`v(5p6jEw}5D6)GjN6I( z2huGUYASFNwLJWY#mcA@CK&ASN~|Fd%1Y!ioh;5<3n1ECa9qzqA{u^AWFgtXR0~??Wd__ zJ>%0T)e6R4rQ==wJ*MPl?CHS9X+OJCsk|L)g%J~XtO4oftSSyK#9 zAxvk!=`Mqg;MR zMxUlAO3h8BB@uoWE}3}mkU1^ebDb!g7B!)a2} zcJG#Rcy&2ujy5aP%n!aVkH?A$zqJaIA!K@9>0mMDgN`jZJx|hKCBXxQUY0aC1G*3f zxa}1G`GTn@=QsBh(^5LzK#!ev*gb{1Fi`fz{YZ4~3bn@s_~l<<6axHORF7l7^k&(m zpEax&pdbcc{suZL-acfNK@4521u&8(I>%0FN~#*Fli&Ap0*k68r_HX~woU9NXKmLx zWfeKQsv~|H0$LE>-EH#AbCcGQ$89u<`4!q!b?YEVrEma5C9#}c5ZdHn+WwCcfA|B_ zPNdh~3u?e}pP(^NZls`bxb0>kH3acw&HJVhWcrKv`_Nel*u+?AQj|=PAvBuFj&T0U zR;D4nzXq4bbE;ynbFpxmRPem~)_R;^)zCI1BK_HChbg3azbU zUswpkdoiBfHCS`=e6RT@`-=@8Qi0t=1gC~3H54SWcER|PYQ69@BIrZ~1)N%nMfl4n z+yt(2HI`8ba0?f0Ic2W_6rjb%US$v^TU@!$9?eFnx5nwJXG=Ae}*=li$JCZGYo70zQDqo5*6kk9nc~%nyGuzo0to#_wcNBTsGCs`aY< z`M}!~Ch@>hSnZAPBqDXpaj%K=QVz7h6#%iQ3*-749ix0&^3#Dw_`Evm&-i0tMXP%7 z3!NSCIXIn$A1_PJ7Bambde6xefNd%af`xxP29m#R$&%QM6?QO_ z;->99-6Qz%tyUwlNh#rma^jd^=M3D{t{Aq*o3=?*Ns?{0KjaQpPpi2a+vW2+DrsW&r_TI3RRuefMaIg><5}qBCbbWd#NI;xDBET@0U=X zmm8Jt$k&tl3H%{xI|Mbe#=s;f%%ZoL9BtouBj4f83DJ*Gc|IUiJXWpR)3I%Jkf9<{yJWzjI_U=4aj6$I zy*?=Oo2g~`f{&n$7$wZkG{Hx+I?tZ61XH0#*6Kubn~2;@`_r8rR-pbfG`LIf*Zj^| zk|agqdjV0n?F&;mIU!!F%nQr|*GEwb=sJT4wN7sBy`Ra5iY$V*Ex)5wy~vjAeOUBR zJw9YRS|&hIu^Dett5JJF8U{cFXVWzvJflWWj<(xJddTeAi%%ydDO!FJ8Hviy)*i}I z&Ui+j6f;~KBWh3=Y#Eya$(8}G^SOcyOb|6IIt)(U>Unc%dFjHu{|?FDn@bF97qVF% zrHZl1&FZ!-7z~Ez_2P)%l8Vpw1ZW^RihpOMfB7J^#P!fW8KK24rxU;Ft$iTeKaD6A zo@6C5;H{Xcew1>Pth%;UUlX%4uGLvXS5dh$2^e)l6-+E+5F8o20U37NohuF$Lw)WR6sJ?^szN2K1H zPUTfTJ;Y}hLm}Go$~|ns{HNL=<9VSL3o)d~E2vnIPCJ;dHm`a^x$z6{CEwPjX{RsV zH8rD@Zs1>l#^lR(N9+3C;lZ*HGpg@jbPf-@4z2t3&s;bAU$Vt0%bgq83)@x#Q$^#B ziOnuLWf2-q0`NM(Fmw03^LcO0*>-%TPazylO$$Rr%ubvzC1fJHrg{tIPuo1NdBbvh zR`su$s3S=wJ1ElgzLe)KxxcKa=`zUApkS%A!ka~hzh>E8{JMJt*)TgnQkrgQw8Sc< zq>^roelfF&;&gT<`dwtF6;?;+87MRWI zFn!0$jhD{0mfU#wL;9~*Oj!~{eE^?PP`a!cmT|t;fa^QIB}^09tX_@ zpIpYVp9G>ozKs|IwGE5?UQk%4Sz?4cdFInevb(`$512eK6XJL>@xb5ZB>}5A33nSc zof{uYzWbWYdGqlO%#2^3!TMtSjLN?=ISp|%YYF+h2U70NvndkZ$g3ZmYU5aCyvu44 z?T)~J2aY_)wY)ar9x%f44#-`1RmFI=?Y$akgX~(mLw1}`cI(hTty45N#LhMPi^89n zcpof~sIO>iBoem@_tR4Nh`Fpj@l&d6n=-|oCv9A}Ij=TYd*4tf9HPAgZwm8AlaG6^ z=caof#yQ?uIm-N2;3_nC1;=@~zjTE=Hts}VFal5Dax<5($lxY_4o}o%_tX`t{YgPy zP}j+AwY>4Wv~m;VEV3YX<}1r@@K=Y;!AM>U8ShJdrPb{t7Za>j@|qjHoVYiXq#du1 z(cT(|Y%CuE*`mNBU;@9$;fO2k)+fAHT;_}@&nB`%sUsCvVYU3M|X&#T}VA&5rV+Kc+fDOIKV z2=0%d^5|=Gr&EjVA^40B9!@DfRIEJ&6R@;d-J`V5QiH!(tx&$;O#Bwtt@|Z&Tod^c zUtqD$uQQ`DcV@u)J7dwxQ{mDo!k4ySWF%=6he>sPbIGyFa!Z;}Y-H&mqM2@@KUF(<4mRD6?K{AFtET zFPqO;nxl8)SNWbZ!gyt0;&d~5sJ_u{PrcG9vF0@eKxv@|6i9HOIue`n`KWZ;38$g& z8Zvy@W!T|lo|1Rr)5GPYI9BOe!g1jaIww_j2#q|T@ZnRuTt-s%-P3s58SgFvocBfL zCgn*j7qf&7{80%cGdRLnc#JBgRNjwz?#BgV$}3vT4Q@QoyjFV-8v`yo;oeA*YSe$6 z8&CU`WR7{{xW)qqCve>-6i_rhx0GGP^U>xpVM5r{77Q(gYEKZ2ES#-u%h>iAVlb@A zTm>@pm#As9;{dCF>WuBO>D09gIby0keJk6HhR(sGjY;*|-MOxnJEBIV)8B1J`d0c5 z&9#IJ??BR7tW)}t-1dtZb{F|Soaz|3)YjB_5}jZ8jZBD%Yy22%%uEA^%MJ!cdy17!aW4J0DDzgkc+5>#WN60=b(=jX=qYXn7F+fT4DO{>TM=s3vz zIIc{#zPVtnR9F`oo9b{k1f=~QjwYJ(@H^7JGZ{ERX@lKsU9||C!wX8m6D0JX=Hv6d zCgby4wX-$=L&luY^AVXQ$?7p30Ru7 zD_$1@S_=)Qqr)HcGCfrW(pdn$(7Q;=`Mb{Ds1j?z9hpb|_skWAcBiWO05zVR;B~9ldIL@xFRHez; zeMB1?#tvKJ(l$2enk}WfwgJQC^r)+AgwNYP9@h~TqYXOrrdVAq_`3wx2V0OR`Ay@u zkAz7Fj)h~C%qdjfDNR#5_{5K^k_iiZx3GGv7|>S$dqC#U%r6m=8!@@UijyOqWH&GOBz`}*f?>!k>#lv%R%$>}AE zdL`8TSR!%v>E7ihx~*;TzX_qE*Zi)KMNjv$A&66dfn8fJd6P@IT zhA6*SZO}8t-~7~z!;h^i_K+g#eu+6{)H{s$$MvM-R{~j z^#;=UlrHWZsn$<~{J}m0$!gZV`$UnFdwr_R8K1c9=F~kWU(;@m$8Kk28U^;w$qYP9 zCdBV2rF=qGfHJ?K0FiQCyk5!SCm|<^1m(d*^_JD7nv-pJJ8;2(mz^l-KJ)7uxsLV` z8BU?m(d)<4`UHQM=J%5pJgrA+ZebU(99il5a1n#S1Hv$+8Y8R^;(off#jy^h!;PO@ znX{l8|Da+5>u>xny)7|2jwVz@t+dtMXw{hVh~s0qs*y*!-+L{4QsC@U@QjEb@!`O61FBuJ9|(4Q`FvKrz5R5NSzFm2@9q}moaesX49IaE zEBh2i=5ct?8TiA8iZ(AxJot+D&RxBSgn;wA)0>{n zNyLHgR(8w&87_9`O$+;tc=4;CdW)|xA;jeI)WN0F53-s16GBK?G*;3Ey zOQp-2eb}9rw;HpZ`Ls^VG+(x{ZT^KCtsbR$ir?eDbq7+zYFGLFSDzFSKYo+MJ*%tS zB~MuTSz+0jAJ<}Ow7x!J_GjNKPwi{eNT~!Gup>><5#)2lKQZyOtQ+j-TX;NMA43h9 z_*f32si(VFT6-%f&Vwb6%ktS=` ziQwn9#c_Ke>i_!OF|8hmkOR{FvL(@MelAhuGC}>J>3H1#%z=*hsbVgc;tqYx8~-zQ zoOssYnF@vl29QPF32HSC#TFQ_fa^ty_IDrIGc|>2Pom^yOZNew^YOiOJRu z4^Eh(ZZctl?ULT-vk?8UW{4J0_~vn}{sJY!pI^g~3_`huQ?BPwn{#UU5@6qsAG3BA=?W z##(!ZW7n)Xp;k3io}|(lWO=fXMGi|OmY7BEzBhGH=XBdzb%euK(gZ%9cJ&sv+{?xxadd-}%XtYsM|*tdn?i?X2Da zef;LxKD<)ftW|qM4(+nj)d?fylw0hv_wHzs!6yFHaFb2FF%@I-E-8&pPiSp>wgrjp z3tm?+Wu8*UzOtJ0JuZ&@6mPxjQ2rCe;Pu~DDVfo?Yg8fa)QQ-UkA>TFE1rbBM58Zm z9@=YUIOc8sJibdg+P`E;WRXDPF#nEb>jiKuLvveFX|&*h!nPcigk^bd}Wx=6gEV~md`I&3ZbgQYx0)ie!(-uU+p9CslysH&$({x3X)8dbV&dt&`|O@Gj&v0U zO;@`)3-`A6JCnXAq=BwX^jL=#RR6mZ5iFg#$~mZM=fi!0?n5S5|D4J6E&4qiJO5ZK z7|XaN@j=+6Yt2rcjrBRzgC&Xsn``hC*)xC%=Jor(vcgQN2;-mkIq$g!~fYSjD0ej;$>LDo%akXF%D)31bwrPiSYJip1Vm zuQV3TLknDbP?ARIuI%fxYAo}+3|xe;iLp`kZgdw75I$paI2DgRzLh|wQXAcmeIS%o z|2j01dC<#rF&6geidbF>8v8W2QQfH zH7E@+vP@=TzEVypp1uozoxz2KLDa`(w!8tIL#r?!L1ct5Ow_|*?fhzz=DR^U9c<72 znS@BjUXw&Z+H(-_U7+&uksU4E%Ei3w!Re$Eo2ObP_-fK$zq~l;U+1NbOx?si*OAxs zne?iw5QAqcXO2EPvA0Wre~@nos*i-s|u(pH`J?-+;H%#*(OX~ zk;0Ux6rkX>DE)%9gdYk)7c76%YNFgxo;!jxG)wn;yRHsyZl*Q=(Nh?tNxUAV$k}HL zJz!nku)-ak1gdTQxHS7~2rowm?7l)m0Z|qTa7x>B@|b7u^m04JoQDfBJAp?aoxC^h ztrkZSbbixnQHx4mTwed!JzbNXoRUC~K8AN=UGE)jHszn6DKS)HRZ`=mhAS{)26(RR z1|YMwZTK-+XNF)95To-7*G}Ux&+X)A?=Rj?oreiaOlqsy>Dh|U>FTa;&hTZ(oVAI6 z?tibnS0f=F=YQH$?vtg)r{VX^C@y9 z{)kF&yVWrGbe$7%c~ixW0m1tWcuQ`vX?t%X1o`lqPmJ8^Irph-lJAG?BY<~0wrC)7 zaBbMI?FFG+gN@B`QgJr_Ku_kZ-u$evmdEnt5VvXhZ|l~p1;*-U9D9v z^z+!ps>&$hIln+GKsG)@J3&~WykXAn>!hfFqFCGZ5Vc*YSK`l9ZixDv$AWR=^UH-X zt#888;Z_V?`!7bjw0&K&1H0CUG$!S%CizMiC?ErV&i=eW?bq-Bb}LpoxSJjc5|SEJ zGOYlvy&@}uT@c0l`;7HwE)x?y3r~e4*(f07h<0XCzWllMaR;)8aoAK0@5SAp!_t% zh%z%Xt8tE$KTgl!%614pH!2nihl<7{Wr=HB5qvVjUKvC8v(1>86}cC0uer#|)C2#4 zs9kgsn_Z069cbW=^&~s#=KSbkS#xv1{B7a{gB~URGvG{^Qfz^~AtG#k>2~TMhnu0+ z%IJ2Dz3pqu$(R5;5{ucSY8r0MvAKCR-$_qEfFUgBo^OH-iBtko=|W^m?Jkb1aD!4v3lm<^ec|toC!AT zZ(6ka#i)~ymfTW5)jAz2@a-gvIFxiB7C(>PTA22B`;@QDxe8ZkyzQ`cmDw$AuRz0~ zOmgRu@=tJX?54w|Ib-0-DU}9d`Br^#*_<(;d`^Mjn5LsuFEdrbPHUf$;Z^gLa?ttu z&*mAb7T24@p`M=Fe@p&Q0HWqXK0a8tCRDFHPyroqR-_5C)XP|Ke9It<<`{&v7 z^z@Ao!O9^6&OQVr_IERA*|vT63}IL-k{T%_c9!bylM}_G#mC>OoPw-4 z7f50WPby!{7zLE>e&r|b{`!k|B5q9FmAP=7X82K>6$%9MV4Pm*-ecu8Dp7F}6Ff~r z;Wyici_bHQ6nA`Hs=U|jtlMMzEWH2|d+U7i9`VQ`k8xyeBA{(+#zvNEU${c=-iJ>I zC=jWWzVGyq`EK)-}#d$c3DriuK{P~grN}@Nj*|ZfTxyTcTvce z>B0ItAf$F`a!$6o*P4%Y-%;@_9(%7rl_A>DK#0|ZcR_VZzDE1rl)d1QwG3t?aKz2)alGDwl}=d3kz;S-?0OXyl(@G#$K>LY(&rIsWnj$2#Nr9aYifA5=9)jPM+0!26?qzV&|S?nLhT8- z2w-!HTybmQ-pM42=u1se&x(N)gPgH*=S+Yu*ad1zdIWbXLW~bm3pU5*PY^XvlGU1 zCIk|U^CpwLvSv#Y!y|QsjV>TK}wUWX)MBkVjf`4yHLbnLor1C4r%O zCaTfFoUw9{>)#Wr*?M+g!zY^>Z?0~!^ajR}oELG#d)V~$>dv`g)W&Dek`l*Yx8Q{E zi&}ghxflFybVW3ZmF`EenlDH@y0zyoBt`9-j4VvMW1jrJ>e9G6~ZCrHP!%khdL-+W!cYqx_}r~NLgOU2zGqUx8ib3L|BHXuQ{I36jok@ai^g2WmNq7$s+&y{3`m}AaOWs z*8=(Us|0J@Oru2!?Zn$8_W?{s_9%KE%c{LYRqZ&Dy#$pgB3)3<=2^o-FE3X4?DTu8 zgM8N~Kps<`sseh$B3yddu}#d!9GlS_D6K<*?dMQo(4K$$q!I0x65nl%#C*kA8h2DC z4QKx}MY*9ow8R^}GWMy<&&}Cv2b<3DP$qX2&};0Qcc$P=Vt`S)Xrg(~Kx6BgHjEWM`e?SM4TtGQVs*yMl>1IKF zep=UO!HiI3_750uU7dfLJc%k_rH%2VuFIsnqWCe~eO8Lyig!L#*WQA6qLS8MMx7;2 zElMrEqj@b%-fe#No{MH-_l|W^?4Vo&pZV0$AC?ENYtVX3{uHNNcGq29u?g3!rtPVu zsj8yat1O3+PPsO0cR>NeP$=-5Ga1YC18dF~qHZXk3)L&Newvq(;dWF^`NQOlXieBK`PV0{=JqV@8BI_BqKIzkt(+@4NRi%eIFQ~aotmB= zNQF-u1g{-lE}Bs~Agx|*+Bou2$y+aKX&qhJ?e(OhHdbJ)1)aR(uf21>1C+-TP`^MX zr3lrVX7jR2+Q+wC8S}EVjtdu-#T55(=9$kED-k|^`8S%V65Eef!rvcSnUA3AJolSR zqz{*e*NX#hQ#yQUEt9`Fs$7h-j#o~UCO6o82XvteDG$9uz-E4fN#=tLU(Q%22#0gDb_;$}r}$Y{ zy_r4O+l$*Z`Vkem&k9g^QBXb7?r!m*N;X68lGudv*D!*bOB{r)*vbWLwDjm%ML?f#u+WRIAx(z~k{U?|b=v^u4k z2?cM+O8`Kg()H0k3k5Y`v`piY8N}^zVY-x$+tA8S0}FD`OxtxhZ_j3lYwlr;8@|H5T+NZK}%3!uBWq1;O@;mmX#($*5oYJ9?rtEYS! zJ;H^BU<9sZUXs<2#JfhMP%=2VNT(~X-&=bDZ$m5^9!s|*?G)j!7)9urU!8jSPm5Lw zh}D3Lv3*)?pLj|9X{+BEW{+^r$MY);f_w~q5e@(S-OLB@#GJ+sdZQbz$a_aF>}ygh zn5CiHyL;#{ncRN{;KgG&5t7^$wdj#KRIErmggzdK^`{Z_b<3ck$jJNW03Zu!@iAws zO5HwMmN*gp++4ceToxZ*Jq;u)U~>&rceP^ILUmO%=MGdQnE$-CbCAbL6tNSI_GL9 zGD9tcz51Y@N#RS`!9MgKx=g&T?9RU^DfCZ4R!?I{dTQzPZ#jB$^C&s`i0--?7fHRu z5D~aWX-d8Q3S^);u%TM;&j#2&3TcN4nrT_JpS){)g-dEvG!C2l-~+HE$=}!Fyimpz za}ztiZahaZ;ppf7m12Hn_+(DlTntC2u2K)!j}`vDDYxNC`soUo){5d0TI-`$4@e*a ztU5|es*VkXW~gC3jJ{c{ODyh6G+99F;f%Ef|4(hE8hHwK=FE%q zoz{A%p(hq(N-bc7MOKN~eW75rE4he+Tirsp4JZ#SVp@it3z11xc>uAjX*54Mu>2JD zq{V7;I@{Swc)rhMhz|6y!iR9HErCEr@;?%OdOR#3N2MUH}& z@(~O$%!{8t=Q^YeGYm5&0}2ZSlcH!SOe+!O<<+S;hu=<1AnJrKn&fml94$U88l)Bb z=gWyy%bGPE*8Ebbg5TpC7U|7AVEKYcO;>sZ{>c{Xha+8gR)G2wE%zg)kfy{pqJgDt zsT{013U8R08=g(RWM$f=!5qo99Vkh(pZ|QGIg*r#LSEy;+C=z;eCX6f8I4gQ0);(UMM+m_s}FaJY`HQeQK=f)LfLn~Y(YAmwQ zD|Lvv_>14%crXn;eyu}tm&sIucR}fUpfE2!T34nSzws8WH~D(7FK0uok$=5_3O=XJ z`Rr6G>w6COXr~>12yJmhH>5Go0%0c)>Kgi7nA_eO@`2+z2j6~Ebb?R&%sX0-kC$Da ze;agvG9mm!OTJt){^wbIBJ$Vt6Vr$F0#O!%!@N`bB@qvfd1kVwHC4{+d?>zD*Gh@< z@+O%UG6#Y4&1nvY;+7yWzo*|Zl?QeDu4I#!*JG54xyKiqVRbR-1KB6?F+GGED}0_H z>JFkc>bB0-pJy%V>A8~C0A~a6V*mgjC?p%eB$_lXp!Hlj)p54i7d`jB!q=;Hs43Y9 z?28kW!JzcC}X1#-pi`mWV&2JMZ=AM1K63pF*wD;{8#5idT@X zSv0(O%-m?)nF1N86xKH%(A9TF>c+_It-eC2~$z`g24jZdUj{m zqn!2_YoY{TldTRIn!i>#&cd_p%~xI>oe#GFJKIMiQKq*1xR6kvRfB%9*9-8L=>;8l zy1Pob`nj@R-A(eo-3v~tO=*aLSIJN!05wrFQ;VtQO4j2)_V-VZHb?`rd_bDywV$yj~JQMkv52 zs^X(^KVH~dEZAe(5s3_Gd`tX0p6%&EoF5GBZ2=P|;}MkxCxMN?aw5Yh`MPbl++`|- zV;an>VFOMiGo)R~c37XQYkCQ!Eom$NUI@MFSHr9AX%#4;xHDy^n_xTmdiv3Z|FvG3 z*qmhUnfRe}AzaiH^niZNFV~fT?Hy?m|lioR_4E&B)8ToVP^h7rmCA^UB)Y zTa6|?uW3@(<@#W$9o%Q#+N;~jDfh!<=A8n(4!Mubc@U!?|O1Q z9j+>3(V{%qZ2Hh&;%=oKx*0f-R@MS7T4-R3w#(wvUd-rm2R~DRSml}cc{|-uvClgn z_9NlDlDcmx@iR)Rs_1J{ZwilBY_M8NF!N4`W~_meCM>OWKVEK7kqHk$cFjB!81nj7Un1HyinE>x9-VFnchd3pg##|ny-~-7%R}LkO~3) zGyA5u%Q+OHY!*rAn505Jm7lDC_r7U-E{YUZ+&|He$0Xn zF}=UkxcZB!&h(=^8s5c&oKQRZD@2@lO3IQqvWZXX@DjHqE+&yuW{vlHtPJ?0(nMXG z7RG2CcEgodz~ARq*|J+7>zr1A5Wa3~tM zDqMMkzn;NUlQ9u=l1)b~i-1O`-8!eY!&xP9bM`)Kvn7djW+sb!FU$T2&lAK+MZo!F z$b)*ZJ~_ye6h{<)7n*Xre(S;dX`Ad4@xh=Wtp71h9uX3GXcO9VD2{X_?sfcXDZr6y zZ^w1St1YR!RZS|M&0- z7>Jh5OOoIFpG(jKZuG*3;Tw5m(f_y)9%cFW(SI@UF9!a_z`q#yKZAiUMn;ZBMG}Q# e|63l!+Cj%O>7R{5v4=qXfJ+Obr(UXR8~R__!e@B^ literal 0 HcmV?d00001 diff --git a/images/repository-open-graph-template.png b/images/repository-open-graph-template.png new file mode 100644 index 0000000000000000000000000000000000000000..d03dffd881869335506a179a6f113384341f35b7 GIT binary patch literal 51470 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 W3$7y%`pIzsf7i7PujXF98S*~?cwS5Z literal 0 HcmV?d00001 diff --git a/library/.gitignore b/library/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/library/.gitignore @@ -0,0 +1 @@ +/build diff --git a/library/build.gradle b/library/build.gradle new file mode 100644 index 0000000..49ae954 --- /dev/null +++ b/library/build.gradle @@ -0,0 +1,46 @@ +version = rootProject.libVersion + +rootProject.libraryModulePlugins.each { + apply plugin: it +} + +group=rootProject.libGroup + +android { + def ext = rootProject.extensions.ext + + compileSdkVersion ext.android.compileSdkVersion + buildToolsVersion ext.android.buildToolsVersion + + defaultConfig { + minSdkVersion ext.android.minSdkVersion + targetSdkVersion ext.android.targetSdkVersion + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + testOptions { + unitTests { + includeAndroidResources = true + } + } + + dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" + skipDeprecated = true + reportUndocumented = true + } +} + +dependencies { + rootProject.libraryModuleDependencies.each { + add(it.configuration, it.dependency, it.options) + } +} \ No newline at end of file diff --git a/library/proguard-rules.pro b/library/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/library/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cf04164 --- /dev/null +++ b/library/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/library/src/main/java/net/codecision/startask/permissions/Permission.kt b/library/src/main/java/net/codecision/startask/permissions/Permission.kt new file mode 100644 index 0000000..a577ccb --- /dev/null +++ b/library/src/main/java/net/codecision/startask/permissions/Permission.kt @@ -0,0 +1,165 @@ +package net.codecision.startask.permissions + +import android.app.Activity +import androidx.fragment.app.Fragment +import net.codecision.startask.permissions.model.PermissionCheckResult +import net.codecision.startask.permissions.model.PermissionRequestResult + + +class Permission private constructor( + private val requestCode: Int, + private val shouldShowRationale: Boolean, + private val shouldRequestAutomatically: Boolean, + private val permissions: Array +) { + + /** + * Checks whether your app has a given permission and whether the app op + * that corresponds to this permission is allowed. + * + * @param activity: Activity for accessing resources. + * @return The permission check result {@link PermissionCheckResult} + */ + fun check(activity: Activity): PermissionCheckResult { + return PermissionUtils.checkPermissions( + activity, + permissions, + requestCode, + shouldShowRationale, + shouldRequestAutomatically + ) + } + + /** + * Checks whether your app has a given permission and whether the app op + * that corresponds to this permission is allowed. + * + * @param fragment: Fragment for accessing resources. + * @return The permission check result {@link PermissionCheckResult} + */ + fun check(fragment: Fragment): PermissionCheckResult { + return PermissionUtils.checkPermissions( + fragment, + permissions, + requestCode, + shouldShowRationale, + shouldRequestAutomatically + ) + } + + /** + * Requests permissions to be granted to this application. + * + * @param activity: Activity for accessing resources. + */ + fun request(activity: Activity) { + return PermissionUtils.requestPermissions(activity, permissions, requestCode) + } + + /** + * Requests permissions to be granted to this application. + * + * @param fragment: Fragment for accessing resources. + */ + fun request(fragment: Fragment) { + return PermissionUtils.requestPermissions(fragment, permissions, requestCode) + } + + /** + * Checks whether your app has a given permission + * + * @param activity: Activity for accessing resources. + * @return The permission check result which is either {true or false}. + */ + fun isGranted(activity: Activity): Boolean { + return PermissionUtils.isGranted(activity, permissions) + } + + /** + * Checks whether your app has a given permission + * + * @param fragment: Fragment for accessing resources. + * @return The permission check result which is either {true or false}. + */ + fun isGranted(fragment: Fragment): Boolean { + return PermissionUtils.isGranted(fragment, permissions) + } + + /** + * Forwarding the result from requesting permissions. + * + * @param fragment: Fragment for accessing resources. + * @param requestCode + * @param grantResults + */ + fun onRequestPermissionsResult( + fragment: Fragment, + requestCode: Int, + grantResults: IntArray + ): PermissionRequestResult { + return if (requestCode == this.requestCode) { + PermissionUtils.onRequestPermissionsResult(fragment, grantResults, permissions) + } else { + PermissionRequestResult.getIncorrectCode() + } + } + + /** + * Forwarding the result from requesting permissions. + * + * @param activity: Activity for accessing resources. + * @param requestCode + * @param grantResults + */ + fun onRequestPermissionsResult( + activity: Activity, + requestCode: Int, + grantResults: IntArray + ): PermissionRequestResult { + return if (requestCode == this.requestCode) { + PermissionUtils.onRequestPermissionsResult(activity, grantResults, permissions) + } else { + PermissionRequestResult.getIncorrectCode() + } + } + + class Builder(private vararg val permissions: String) { + + private var requestCode: Int = PERMISSIONS_REQUEST_CODE + + private var shouldShowRationale = true + + private var shouldRequestAutomatically = true + + fun setRequestCode(requestCode: Int): Builder { + this.requestCode = requestCode + return this + } + + fun setShouldShowRationale(shouldShowRationale: Boolean): Builder { + this.shouldShowRationale = shouldShowRationale + return this + } + + fun setShouldRequestAutomatically(shouldRequestAutomatically: Boolean): Builder { + this.shouldRequestAutomatically = shouldRequestAutomatically + return this + } + + fun build(): Permission { + return if (permissions.isNotEmpty()) { + Permission(requestCode, shouldShowRationale, shouldRequestAutomatically, permissions) + } else { + throw IllegalArgumentException("Require one or more permission!") + } + } + + } + + companion object { + + const val PERMISSIONS_REQUEST_CODE = 43 + + } + +} \ No newline at end of file diff --git a/library/src/main/java/net/codecision/startask/permissions/PermissionUtils.kt b/library/src/main/java/net/codecision/startask/permissions/PermissionUtils.kt new file mode 100644 index 0000000..2fd0a06 --- /dev/null +++ b/library/src/main/java/net/codecision/startask/permissions/PermissionUtils.kt @@ -0,0 +1,166 @@ +package net.codecision.startask.permissions + +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.annotation.VisibleForTesting +import androidx.core.app.ActivityCompat +import androidx.core.content.PermissionChecker +import androidx.fragment.app.Fragment +import net.codecision.startask.permissions.model.PermissionCheckResult +import net.codecision.startask.permissions.model.PermissionRequestResult + +class PermissionUtils { + + companion object { + + fun checkPermissions( + activity: Activity, + permissions: Array, + requestCode: Int, + shouldShowRationale: Boolean, + shouldRequestAutomatically: Boolean + ): PermissionCheckResult { + return if (isGranted(activity, permissions)) { + PermissionCheckResult.getGranted() + } else { + doOnDenied(activity, permissions, requestCode, shouldShowRationale, shouldRequestAutomatically) + } + } + + fun checkPermissions( + fragment: Fragment, + permissions: Array, + requestCode: Int, + shouldShowRationale: Boolean, + shouldRequestAutomatically: Boolean): PermissionCheckResult { + return if (isGranted(fragment, permissions)) { + PermissionCheckResult.getGranted() + } else { + doOnDenied(fragment, permissions, requestCode, shouldShowRationale, shouldRequestAutomatically) + } + } + + fun isGranted(activity: Activity, permissions: Array) = isGranted(activity as Context, permissions) + + fun isGranted(fragment: Fragment, permissions: Array) = isGranted(fragment.requireContext(), permissions) + + fun requestPermissions(activity: Activity, permissions: Array, requestCode: Int) { + ActivityCompat.requestPermissions(activity, permissions, requestCode) + } + + fun requestPermissions(fragment: Fragment, permissions: Array, requestCode: Int) { + fragment.requestPermissions(permissions, requestCode) + } + + fun onRequestPermissionsResult( + fragment: Fragment, + grantResults: IntArray, + permissions: Array + ): PermissionRequestResult { + return if (verifyPermissionsResult(grantResults)) { + PermissionRequestResult.getGranted() + } else { + if (shouldShowRequestPermissionRationale(fragment, permissions)) { + PermissionRequestResult.getDenied() + } else { + PermissionRequestResult.getNeverAskAgain() + } + } + } + + fun onRequestPermissionsResult( + activity: Activity, + grantResults: IntArray, + permissions: Array + ): PermissionRequestResult { + return if (verifyPermissionsResult(grantResults)) { + PermissionRequestResult.getGranted() + } else { + if (shouldShowRequestPermissionRationale(activity, permissions)) { + PermissionRequestResult.getDenied() + } else { + PermissionRequestResult.getNeverAskAgain() + } + } + } + + private fun doOnDenied( + activity: Activity, + permissions: Array, + requestCode: Int, + shouldShowRationale: Boolean, + shouldRequestAutomatically: Boolean + ): PermissionCheckResult { + return if (shouldShowRationale && shouldShowRequestPermissionRationale(activity, permissions)) { + PermissionCheckResult.getShowRationale() + } else { + if (shouldRequestAutomatically) { + requestPermissions(activity, permissions, requestCode) + } + PermissionCheckResult.getRequiredRequest() + } + } + + private fun doOnDenied( + fragment: Fragment, + permissions: Array, + requestCode: Int, + shouldShowRationale: Boolean, + shouldRequestAutomatically: Boolean + ): PermissionCheckResult { + return if (shouldShowRationale && shouldShowRequestPermissionRationale(fragment, permissions)) { + PermissionCheckResult.getShowRationale() + } else { + if (shouldRequestAutomatically) { + requestPermissions(fragment, permissions, requestCode) + } + PermissionCheckResult.getRequiredRequest() + } + } + + @VisibleForTesting + fun verifyPermissionsResult(grantResults: IntArray): Boolean { + return grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED } + } + + private fun shouldShowRequestPermissionRationale(activity: Activity, permissions: Array): Boolean { + return permissions.any { ActivityCompat.shouldShowRequestPermissionRationale(activity, it) } + } + + private fun shouldShowRequestPermissionRationale(fragment: Fragment, permissions: Array): Boolean { + return permissions.any { fragment.shouldShowRequestPermissionRationale(it) } + } + + private fun isGranted(context: Context, permissions: Array): Boolean { + return isLessMarshmallow() || hasSelfPermissions(context, permissions) + } + + private fun hasSelfPermissions(context: Context, permissions: Array): Boolean { + return permissions.all { hasSelfPermission(context, it) } + } + + private fun hasSelfPermission(context: Context, permission: String): Boolean { + return try { + checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED + } catch (exception: RuntimeException) { + exception.printStackTrace() + false + } + } + + @VisibleForTesting + @Throws(RuntimeException::class) + fun checkSelfPermission(context: Context, permission: String): Int { + return PermissionChecker.checkSelfPermission(context, permission) + } + + @VisibleForTesting + fun isLessMarshmallow(): Boolean { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M + } + + } +} + diff --git a/library/src/main/java/net/codecision/startask/permissions/model/PermissionCheckResult.kt b/library/src/main/java/net/codecision/startask/permissions/model/PermissionCheckResult.kt new file mode 100644 index 0000000..37c3d23 --- /dev/null +++ b/library/src/main/java/net/codecision/startask/permissions/model/PermissionCheckResult.kt @@ -0,0 +1,47 @@ +package net.codecision.startask.permissions.model + +class PermissionCheckResult private constructor( + val result: Int +) { + + inline fun onGranted(action: () -> Unit): PermissionCheckResult { + if (result == GRANTED_RESULT) { + action() + } + return this + } + + inline fun onShowRationale(action: () -> Unit): PermissionCheckResult { + if (result == SHOW_RATIONALE_RESULT) { + action() + } + return this + } + + inline fun onRequiredRequest(action: () -> Unit): PermissionCheckResult { + if (result == REQUIRED_REQUEST_RESULT) { + action() + } + return this + } + + companion object { + + /** Result: The permission is granted. */ + const val GRANTED_RESULT = 0 + + /** Result: The permission is show rationale. */ + const val SHOW_RATIONALE_RESULT = 1 + + /** Result: The permission need request. */ + const val REQUIRED_REQUEST_RESULT = 3 + + fun getGranted() = PermissionCheckResult(GRANTED_RESULT) + + fun getShowRationale() = PermissionCheckResult(SHOW_RATIONALE_RESULT) + + fun getRequiredRequest() = PermissionCheckResult(REQUIRED_REQUEST_RESULT) + + } + +} diff --git a/library/src/main/java/net/codecision/startask/permissions/model/PermissionRequestResult.kt b/library/src/main/java/net/codecision/startask/permissions/model/PermissionRequestResult.kt new file mode 100644 index 0000000..2b435cd --- /dev/null +++ b/library/src/main/java/net/codecision/startask/permissions/model/PermissionRequestResult.kt @@ -0,0 +1,51 @@ +package net.codecision.startask.permissions.model + +class PermissionRequestResult private constructor( + val result: Int +) { + + inline fun onGranted(action: () -> Unit): PermissionRequestResult { + if (result == GRANTED_RESULT) { + action() + } + return this + } + + inline fun onDenied(action: () -> Unit): PermissionRequestResult { + if (result == DENIED_RESULT) { + action() + } + return this + } + + inline fun onNeverAskAgain(action: () -> Unit): PermissionRequestResult { + if (result == NEVER_ASK_AGAIN_RESULT) { + action() + } + return this + } + + companion object { + + /** Result: The permission is granted. */ + const val GRANTED_RESULT = 0 + + /** Result: The permission is denied. */ + const val DENIED_RESULT = 1 + + /** Result: The permission is never ask again. */ + const val NEVER_ASK_AGAIN_RESULT = 2 + + private const val INCORRECT_CODE_RESULT = -1 + + fun getGranted() = PermissionRequestResult(GRANTED_RESULT) + + fun getDenied() = PermissionRequestResult(DENIED_RESULT) + + fun getNeverAskAgain() = PermissionRequestResult(NEVER_ASK_AGAIN_RESULT) + + fun getIncorrectCode() = PermissionRequestResult(INCORRECT_CODE_RESULT) + + } + +} \ No newline at end of file diff --git a/library/src/test/java/net/codecision/startask/permissions/BaseLibTest.kt b/library/src/test/java/net/codecision/startask/permissions/BaseLibTest.kt new file mode 100644 index 0000000..b33df2b --- /dev/null +++ b/library/src/test/java/net/codecision/startask/permissions/BaseLibTest.kt @@ -0,0 +1,41 @@ +package net.codecision.startask.permissions + +import android.Manifest +import android.content.pm.PackageManager +import android.os.Build +import java.lang.reflect.Field +import java.lang.reflect.Modifier + +open class BaseLibTest { + + @Throws(NoSuchFieldException::class, IllegalAccessException::class, IllegalArgumentException::class) + protected fun setFinalStatic(field: Field, newValue: Any) { + field.isAccessible = true + + val modifiersField = Field::class.java.getDeclaredField("modifiers") + modifiersField.isAccessible = true + modifiersField.setInt(field, field.modifiers and Modifier.FINAL.inv()) + + field.set(null, newValue) + } + + protected inline fun d(message: () -> String) { + println(message()) + } + + protected fun getSdkVersionField(): Field { + return Build.VERSION::class.java.getField(SDK_VERSION_FIELD) + } + + companion object { + const val SDK_VERSION_FIELD = "SDK_INT" + + const val GRANTED = PackageManager.PERMISSION_GRANTED + const val DENIED = PackageManager.PERMISSION_DENIED + + const val CAMERA_PERMISSION = Manifest.permission.CAMERA + + const val PERMISSIONS_REQUEST_CODE = 99 + } + +} \ No newline at end of file diff --git a/library/src/test/java/net/codecision/startask/permissions/PermissionCheckResultTest.kt b/library/src/test/java/net/codecision/startask/permissions/PermissionCheckResultTest.kt new file mode 100644 index 0000000..3b41ddf --- /dev/null +++ b/library/src/test/java/net/codecision/startask/permissions/PermissionCheckResultTest.kt @@ -0,0 +1,69 @@ +package net.codecision.startask.permissions + +import net.codecision.startask.permissions.model.PermissionCheckResult +import org.junit.Assert.assertEquals +import org.junit.Test + +class PermissionCheckResultTest : BaseLibTest() { + + @Test + fun getGranted_Result_Granted() { + val permissionCheckResult = PermissionCheckResult.getGranted() + assertEquals(PermissionCheckResult.GRANTED_RESULT, permissionCheckResult.result) + } + + @Test + fun getGranted_Result_ShowRationale() { + val permissionCheckResult = PermissionCheckResult.getShowRationale() + assertEquals(PermissionCheckResult.SHOW_RATIONALE_RESULT, permissionCheckResult.result) + } + + @Test + fun getGranted_Result_RequiredRequest() { + val permissionCheckResult = PermissionCheckResult.getRequiredRequest() + assertEquals(PermissionCheckResult.REQUIRED_REQUEST_RESULT, permissionCheckResult.result) + } + + @Test + fun onGranted_Granted_True() { + PermissionCheckResult.getGranted() + .onGranted { + assert(true) + } + .onShowRationale { + assert(false) + } + .onRequiredRequest { + assert(false) + } + } + + @Test + fun onGranted_ShowRationale_True() { + PermissionCheckResult.getShowRationale() + .onGranted { + assert(false) + } + .onShowRationale { + assert(true) + } + .onRequiredRequest { + assert(false) + } + } + + @Test + fun onGranted_RequiredRequest_True() { + PermissionCheckResult.getRequiredRequest() + .onGranted { + assert(false) + } + .onShowRationale { + assert(false) + } + .onRequiredRequest { + assert(true) + } + } + +} \ No newline at end of file diff --git a/library/src/test/java/net/codecision/startask/permissions/PermissionRequestResultTest.kt b/library/src/test/java/net/codecision/startask/permissions/PermissionRequestResultTest.kt new file mode 100644 index 0000000..c062e01 --- /dev/null +++ b/library/src/test/java/net/codecision/startask/permissions/PermissionRequestResultTest.kt @@ -0,0 +1,71 @@ +package net.codecision.startask.permissions + +import net.codecision.startask.permissions.model.PermissionRequestResult +import org.junit.Assert +import org.junit.Test + +class PermissionRequestResultTest : BaseLibTest() { + + + @Test + fun getGranted_Result_Granted() { + val permissionCheckResult = PermissionRequestResult.getGranted() + Assert.assertEquals(PermissionRequestResult.GRANTED_RESULT, permissionCheckResult.result) + } + + @Test + fun getGranted_Result_Denied() { + val permissionCheckResult = PermissionRequestResult.getDenied() + Assert.assertEquals(PermissionRequestResult.DENIED_RESULT, permissionCheckResult.result) + } + + @Test + fun getGranted_Result_NeverAskAgain() { + val permissionCheckResult = PermissionRequestResult.getNeverAskAgain() + Assert.assertEquals(PermissionRequestResult.NEVER_ASK_AGAIN_RESULT, permissionCheckResult.result) + } + + @Test + fun getGranted_Result_IncorrectCode() { + val permissionCheckResult = PermissionRequestResult.getIncorrectCode() + Assert.assertEquals(-1, permissionCheckResult.result) + } + + @Test + fun onGranted_Granted_True() { + PermissionRequestResult.getGranted() + .onGranted { + assert(true) + }.onDenied { + assert(false) + }.onNeverAskAgain { + assert(false) + } + } + + @Test + fun onGranted_Denied_True() { + PermissionRequestResult.getDenied() + .onGranted { + assert(false) + }.onDenied { + assert(true) + }.onNeverAskAgain { + assert(false) + } + } + + @Test + fun onGranted_NeverAskAgain_True() { + PermissionRequestResult.getNeverAskAgain() + .onGranted { + assert(false) + }.onDenied { + assert(false) + }.onNeverAskAgain { + assert(true) + } + } + + +} \ No newline at end of file diff --git a/library/src/test/java/net/codecision/startask/permissions/PermissionTest.kt b/library/src/test/java/net/codecision/startask/permissions/PermissionTest.kt new file mode 100644 index 0000000..2bddc21 --- /dev/null +++ b/library/src/test/java/net/codecision/startask/permissions/PermissionTest.kt @@ -0,0 +1,71 @@ +package net.codecision.startask.permissions + +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.core.content.PermissionChecker +import net.codecision.startask.permissions.model.PermissionCheckResult +import net.codecision.startask.permissions.model.PermissionRequestResult +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [Build.VERSION_CODES.M]) +class PermissionTest : BaseLibTest() { + + lateinit var activity: Activity + + @Before + fun setUp() { + val activityController = Robolectric.buildActivity(Activity::class.java) + activity = Mockito.spy(activityController.setup().get()) + } + + @Test + @Throws(Exception::class) + fun checkActivity_NotNull_True() { + Assert.assertNotNull(activity) + } + + @Test + fun checkActivity_Granted_GrantedResult() { + Mockito.`when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_GRANTED) + + val permissionCheckResult = Permission.Builder(CAMERA_PERMISSION) + .build() + .check(activity) + assertEquals(PermissionCheckResult.GRANTED_RESULT, permissionCheckResult.result) + } + + @Test + fun isGranted_Granted_True() { + Mockito.`when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_GRANTED) + + assert(Permission.Builder(CAMERA_PERMISSION).build().isGranted(activity)) + } + + @Test + fun onRequestPermissionsResult_Granted() { + val permissionRequestResult = Permission.Builder(CAMERA_PERMISSION) + .build() + .onRequestPermissionsResult( + activity, + Permission.PERMISSIONS_REQUEST_CODE, + IntArray(1) { PackageManager.PERMISSION_GRANTED } + ) + assertEquals(PermissionRequestResult.GRANTED_RESULT, permissionRequestResult.result) + } + + private fun getContext() = activity as Context + +} \ No newline at end of file diff --git a/library/src/test/java/net/codecision/startask/permissions/PermissionUtilsTest.kt b/library/src/test/java/net/codecision/startask/permissions/PermissionUtilsTest.kt new file mode 100644 index 0000000..5aaee17 --- /dev/null +++ b/library/src/test/java/net/codecision/startask/permissions/PermissionUtilsTest.kt @@ -0,0 +1,176 @@ +package net.codecision.startask.permissions + +import android.app.Activity +import android.content.Context +import android.os.Build +import androidx.core.app.ActivityCompat +import androidx.core.content.PermissionChecker +import net.codecision.startask.permissions.model.PermissionCheckResult +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.`when` +import org.mockito.Mockito.spy +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [Build.VERSION_CODES.M]) +class PermissionUtilsTest : BaseLibTest() { + + lateinit var activity: Activity + + @Before + fun setUp() { + val activityController = Robolectric.buildActivity(Activity::class.java) + activity = spy(activityController.setup().get()) + } + + @Test + @Throws(Exception::class) + fun checkActivity_NotNull_True() { + assertNotNull(activity) + } + + @Test + fun checkIsLessMarshmallow_22_True() { + changeSdkVersion(Build.VERSION_CODES.LOLLIPOP_MR1) + assert(PermissionUtils.isLessMarshmallow()) + } + + @Test + fun checkIsLessMarshmallow_23_False() { + changeSdkVersion(Build.VERSION_CODES.M) + assertFalse(PermissionUtils.isLessMarshmallow()) + } + + @Test + fun checkIsLessMarshmallow_24_False() { + changeSdkVersion(Build.VERSION_CODES.N) + assertFalse(PermissionUtils.isLessMarshmallow()) + } + + @Test + fun isGranted_Granted_True() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_GRANTED) + assert(PermissionUtils.isGranted(activity, arrayOf(CAMERA_PERMISSION))) + } + + @Test + fun isGranted_Denied_False() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_DENIED) + assertFalse(PermissionUtils.isGranted(activity, arrayOf(CAMERA_PERMISSION))) + } + + @Test + fun isGranted_Exception_False() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenThrow(RuntimeException::class.java) + assertFalse(PermissionUtils.isGranted(activity, arrayOf(CAMERA_PERMISSION))) + } + + @Test + fun checkPermissions_GrantedShowRationale_GrantedResult() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_GRANTED) + + val permissionCheckResult = PermissionUtils.checkPermissions( + activity, + arrayOf(CAMERA_PERMISSION), + PERMISSIONS_REQUEST_CODE, + true, + true + ) + + assertEquals(PermissionCheckResult.GRANTED_RESULT, permissionCheckResult.result) + } + + @Test + fun checkPermissions_GrantedNotShowRationale_GrantedResult() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_GRANTED) + + val permissionCheckResult = PermissionUtils.checkPermissions( + activity, + arrayOf(CAMERA_PERMISSION), + PERMISSIONS_REQUEST_CODE, + false, + true + ) + + assertEquals(PermissionCheckResult.GRANTED_RESULT, permissionCheckResult.result) + } + + @Test + fun checkPermissions_DeniedShowRationale_True() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_DENIED) + + `when`(ActivityCompat.shouldShowRequestPermissionRationale(activity, CAMERA_PERMISSION)) + .thenReturn(true) + + val permissionCheckResult = PermissionUtils.checkPermissions( + activity, + arrayOf(CAMERA_PERMISSION), + PERMISSIONS_REQUEST_CODE, + true, + true + ) + + assertEquals(PermissionCheckResult.SHOW_RATIONALE_RESULT, permissionCheckResult.result) + } + + @Test + fun checkPermissions_DeniedNotShowRationale_True() { + `when`(PermissionUtils.checkSelfPermission(getContext(), CAMERA_PERMISSION)) + .thenReturn(PermissionChecker.PERMISSION_DENIED) + + `when`(ActivityCompat.shouldShowRequestPermissionRationale(activity, CAMERA_PERMISSION)) + .thenReturn(true) + + val permissionCheckResult = PermissionUtils.checkPermissions( + activity, + arrayOf(CAMERA_PERMISSION), + PERMISSIONS_REQUEST_CODE, + false, + true + ) + + assertEquals(PermissionCheckResult.REQUIRED_REQUEST_RESULT, permissionCheckResult.result) + } + + @Test + fun verifyPermissionsResult_GrantedOne_True() { + assertTrue(PermissionUtils.verifyPermissionsResult(IntArray(1) { GRANTED })) + } + + @Test + fun verifyPermissionsResult_GrantedTwo_True() { + assertTrue(PermissionUtils.verifyPermissionsResult(IntArray(2) { GRANTED; GRANTED })) + } + + @Test + fun verifyPermissionsResult_GrantedZero_False() { + assertFalse(PermissionUtils.verifyPermissionsResult(IntArray(0))) + } + + @Test + fun verifyPermissionsResult_Denied_False() { + assertFalse(PermissionUtils.verifyPermissionsResult(IntArray(1) { DENIED })) + } + + @Test + fun verifyPermissionsResult_GrantedDenied_False() { + assertFalse(PermissionUtils.verifyPermissionsResult(IntArray(2) { GRANTED; DENIED })) + } + + private fun getContext() = activity as Context + + private fun changeSdkVersion(sdkVersion: Int) = setFinalStatic(getSdkVersionField(), sdkVersion) + +} \ No newline at end of file diff --git a/sample/.gitignore b/sample/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/sample/.gitignore @@ -0,0 +1 @@ +/build diff --git a/sample/build.gradle b/sample/build.gradle new file mode 100644 index 0000000..818680c --- /dev/null +++ b/sample/build.gradle @@ -0,0 +1,30 @@ +rootProject.sampleModulePlugins.each { + apply plugin: it +} + +android { + def ext = rootProject.extensions.ext + compileSdkVersion ext.android.compileSdkVersion + defaultConfig { + applicationId "net.codecision.startask.permissions.sample" + minSdkVersion ext.android.minSdkVersion + targetSdkVersion ext.android.targetSdkVersion + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + rootProject.sampleModuleDependencies.each { + add(it.configuration, it.dependency, it.options) + } +} + +repositories { + mavenCentral() +} diff --git a/sample/proguard-rules.pro b/sample/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/sample/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml new file mode 100644 index 0000000..67d02cb --- /dev/null +++ b/sample/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample/src/main/java/net/codecision/startask/permissions/sample/PermissionsActivity.kt b/sample/src/main/java/net/codecision/startask/permissions/sample/PermissionsActivity.kt new file mode 100644 index 0000000..a638c96 --- /dev/null +++ b/sample/src/main/java/net/codecision/startask/permissions/sample/PermissionsActivity.kt @@ -0,0 +1,84 @@ +package net.codecision.startask.permissions.sample + +import android.Manifest +import android.annotation.SuppressLint +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import kotlinx.android.synthetic.main.activity_permissions.* +import net.codecision.startask.permissions.Permission +import net.codecision.startask.permissions.sample.utils.ktx.setSingleClickListener + +class PermissionsActivity : AppCompatActivity() { + + private val cameraPermission: Permission by lazy { + Permission.Builder(Manifest.permission.CAMERA) + .setRequestCode(MY_PERMISSIONS_REQUEST_CODE) + .build() + } + + @SuppressLint("SetTextI18n") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_permissions) + + initView() + initListeners() + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + onRequestLocationPermissionResult(requestCode, grantResults) + } + + @SuppressLint("SetTextI18n") + private fun checkLocationPermission() { + cameraPermission.check(this) + .onGranted { + statusView.text = "Granted!" + }.onShowRationale { + showRationaleDialog() + } + } + + @SuppressLint("SetTextI18n") + private fun onRequestLocationPermissionResult(requestCode: Int, grantResults: IntArray) { + cameraPermission.onRequestPermissionsResult(this, requestCode, grantResults) + .onGranted { + statusView.text = "Granted!" + }.onDenied { + statusView.text = "Denied!" + }.onNeverAskAgain { + statusView.text = "NeverAskAgain!" + } + } + + private fun showRationaleDialog() { + AlertDialog.Builder(this) + .setTitle("Camera permission") + .setMessage("Allow app to use your camera to take photos and record videos.") + .setPositiveButton("Allow") { _, _ -> + cameraPermission.request(this) + } + .setNegativeButton("Deny") { _, _ -> + + } + .create() + .show() + } + + private fun initView() { + statusView.text = "Unknown!" + } + + private fun initListeners() { + checkButton.setSingleClickListener { + checkLocationPermission() + } + } + + companion object { + const val MY_PERMISSIONS_REQUEST_CODE = 99 + } + +} \ No newline at end of file diff --git a/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ClickController.kt b/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ClickController.kt new file mode 100644 index 0000000..b7d0ddc --- /dev/null +++ b/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ClickController.kt @@ -0,0 +1,24 @@ +package net.codecision.startask.permissions.sample.utils + +object ClickController { + + private const val MIN_CLICK_INTERVAL_MS = 600L + + private var lastClickTime: Long = 0L + + fun isClickAllowed(): Boolean { + val currentTime = getCurrentTimeMillis() + val isClickAllowed = isClickAllowed(currentTime) + + if (isClickAllowed) { + lastClickTime = currentTime + } + + return isClickAllowed + } + + private fun isClickAllowed(currentTime: Long): Boolean = (currentTime - lastClickTime) > MIN_CLICK_INTERVAL_MS + + private fun getCurrentTimeMillis(): Long = System.currentTimeMillis() + +} \ No newline at end of file diff --git a/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ktx/ViewKtx.kt b/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ktx/ViewKtx.kt new file mode 100644 index 0000000..462b033 --- /dev/null +++ b/sample/src/main/java/net/codecision/startask/permissions/sample/utils/ktx/ViewKtx.kt @@ -0,0 +1,12 @@ +package net.codecision.startask.permissions.sample.utils.ktx + +import android.view.View +import net.codecision.startask.permissions.sample.utils.ClickController + +fun View.setSingleClickListener(listener: (v: View) -> Unit) { + this.setOnClickListener { + if (ClickController.isClickAllowed()) { + listener(this) + } + } +} \ No newline at end of file diff --git a/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..c7bd21d --- /dev/null +++ b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/sample/src/main/res/drawable/ic_launcher_background.xml b/sample/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d5fccc5 --- /dev/null +++ b/sample/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..1c9c6af --- /dev/null +++ b/sample/src/main/res/layout/activity_main.xml @@ -0,0 +1,14 @@ + + + +