From eee78324eb4cdb4faab3248ef646d5750507b598 Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Sun, 26 Sep 2021 00:15:07 +0300 Subject: [PATCH 01/32] Shut the IndexOutOfBoundsException for good --- app/build.gradle | 7 +-- build.gradle | 4 ++ gradle/dependencies.gradle | 10 ++-- gradle/wrapper/gradle-wrapper.properties | 4 +- .../inputmask/MaskedTextChangedListener.kt | 53 +++++++++++++++++-- 5 files changed, 65 insertions(+), 13 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index af594f5..9956a46 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 30 defaultConfig { applicationId "com.redmadrobot.sample" minSdkVersion 14 - targetSdkVersion 28 + targetSdkVersion 30 versionCode 1 versionName "1.0" } @@ -16,11 +16,12 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + buildToolsVersion '30.0.1' } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation deps.kotlin.stdlib - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.appcompat:appcompat:1.3.1' implementation project(':inputmask') } diff --git a/build.gradle b/build.gradle index 2a1ca04..3048874 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,9 @@ buildscript { apply from: "${rootProject.projectDir}/gradle/dependencies.gradle" + ext { + kotlin_version = '1.3.72' + } addRepos(repositories) @@ -11,6 +14,7 @@ buildscript { classpath deps.kotlin.dokka classpath deps.bintray.android_maven_plugin classpath deps.bintray.gradle_bintray_plugin + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 6272c58..16c74b9 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -9,8 +9,8 @@ ext.addRepos = this.&addRepos def build_versions = [:] build_versions.min_sdk = 14 -build_versions.target_sdk = 28 -build_versions.compile_sdk = 28 +build_versions.target_sdk = 30 +build_versions.compile_sdk = 30 ext.build_versions = build_versions //endregion @@ -23,7 +23,7 @@ def deps = [:] //region Gradle def gradle = [:] -versions.android_plugin = "3.3.2" +versions.android_plugin = "4.1.3" gradle.android_plugin = "com.android.tools.build:gradle:$versions.android_plugin" @@ -33,8 +33,8 @@ deps.gradle = gradle //region Kotlin def kotlin = [:] -versions.kotlin = "1.3.21" -versions.dokka = "0.9.17" +versions.kotlin = "1.5.21" +versions.dokka = "0.9.18" kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin" kotlin.test = "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4d5bf4..c36e038 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Mar 12 18:40:51 MSK 2019 +#Sat Sep 25 23:02:38 MSK 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt index 0668e39..8027f8c 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt @@ -2,6 +2,7 @@ package com.redmadrobot.inputmask import android.text.Editable import android.text.TextWatcher +import android.util.Log import android.view.View import android.widget.EditText import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy @@ -146,7 +147,22 @@ open class MaskedTextChangedListener( with(field) { setText(result.formattedText.string) - setSelection(result.formattedText.caretPosition) + + try { + setSelection(result.formattedText.caretPosition) + } catch (e: java.lang.IndexOutOfBoundsException) { + Log.e( + "input-mask-android", + """ + + WARNING! Your text field is not configured for the MaskedTextChangedListener! + For more information please refer to + + InputMask vs. android:inputType and IndexOutOfBoundsException + https://github.com/RedMadRobot/input-mask-android#inputmask-vs-androidinputtype-and-indexoutofboundsexception + """ + ) + } } return result @@ -190,7 +206,23 @@ open class MaskedTextChangedListener( override fun afterTextChanged(edit: Editable?) { this.field.get()?.removeTextChangedListener(this) edit?.replace(0, edit.length, this.afterText) - this.field.get()?.setSelection(this.caretPosition) + + try { + this.field.get()?.setSelection(this.caretPosition) + } catch (e: IndexOutOfBoundsException) { + Log.e( + "input-mask-android", + """ + + WARNING! Your text field is not configured for the MaskedTextChangedListener! + For more information please refer to + + InputMask vs. android:inputType and IndexOutOfBoundsException + https://github.com/RedMadRobot/input-mask-android#inputmask-vs-androidinputtype-and-indexoutofboundsexception + """ + ) + } + this.field.get()?.addTextChangedListener(this) this.listener?.afterTextChanged(edit) } @@ -234,7 +266,22 @@ open class MaskedTextChangedListener( this.afterText = result.formattedText.string this.caretPosition = result.formattedText.caretPosition this.field.get()?.setText(afterText) - this.field.get()?.setSelection(result.formattedText.caretPosition) + + try { + this.field.get()?.setSelection(result.formattedText.caretPosition) + } catch (e: IndexOutOfBoundsException) { + Log.e( + "input-mask-android", + """ + + WARNING! Your text field is not configured for the MaskedTextChangedListener! + For more information please refer to + + InputMask vs. android:inputType and IndexOutOfBoundsException + https://github.com/RedMadRobot/input-mask-android#inputmask-vs-androidinputtype-and-indexoutofboundsexception + """ + ) + } this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText) } } From 1d5681d770b81933ebc79e4e5ccf2b977cccd5ec Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Sun, 26 Sep 2021 01:13:37 +0300 Subject: [PATCH 02/32] Bump version, update README and CHANGELOG --- CHANGELOG.md | 16 ++++++++++++++++ README.md | 40 +++++++++++++++++++++++++++++++--------- version.properties | 4 ++-- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c960a15..17ba06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +### `6.1.0` + +#### Removed: + +* `IndexOutOfBoundsException` + +HUZZAH! + +#### Modified: + +(none) + +#### Added: + +* `IndexOutOfBoundsException` with a link to docs + ### `6.0.0` #### Removed: diff --git a/README.md b/README.md index b55c844..53e0ff7 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,35 @@ Direct input -### Migration Guide: v.6 - -This update brings breaking changes. Namely, the `autocomplete` flag is now a part of the `CaretGravity` enum, thus the `Mask::apply` call is now single-argument, as all the necessary information is included into the `CaretString` structure. - -`v.6` introduces the «autoskip» feature, which allows the cursor to jump over formatting blocks of symbols in the middle of the text as if they were a single char when hitting `Backspace`, and this feature also allows to trim formatting characters on backspacing at the end of the line. - -Make sure to take a look at our [CHANGELOG](https://github.com/RedMadRobot/input-mask-android/blob/master/CHANGELOG.md). +## PSA: Migration to Maven Central and overall library development + +Input Mask library development is back on track. + +From now on, the official library distribution method is **JitPack**. + +
+My thoughts regarding the library migration to Maven Central +The "migration" took me long enough, okay. + +It's Saturday, the 25th of September, 2021, and yesterday I had an opportunity to complete the whole Sonatype manual on how mere mortals publish their libs to Maven Central. + +And it didn't feel right, so I decided to take a short, *last* break before pushing the changes. +The main, Central™, most important Java & Android depo doesn't feel like it's 2021 at all. + +I felt I was casting spells and performing some cargo cult rituals. +ALM-based system, the wait for approval, tickets, scripts, credentials, DNS records, artifact security assurance, corporate console library catalogs with Windows™ folder icons… + +The. Fuck. + +I know some of RedMadRobot libraries already made it to Sonatype. +But this is not the case. + +**Input Mask is never going to hit Maven Central**, and I'm not going to support this abomination of legacy and bureaucracy. +
+ +First things first, I'm going to get rid of some annoying library issues from the past, do some project cleanup, and then I'd like to put more real word use case scenarios into the core, so please feel free to share your ideas via feature requests. + +Meet `6.1.0`. ## Description @@ -73,11 +95,11 @@ Make sure you've added Kotlin support to your project. ```gradle repositories { - jcenter() + maven { url 'https://jitpack.io' } } dependencies { - implementation 'com.redmadrobot:input-mask-android:6.0.0' + implementation 'com.github.RedMadRobot:input-mask-android:6.1.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:$latest_version' } diff --git a/version.properties b/version.properties index 89f1804..e3b33e0 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ # This file should be checked into Version Control Systems, # as it contains default parameters to version configuration. -version_code=9 -version_name=6.0.0 +version_code=10 +version_name=6.1.0 From c099ca9165c3540dafe405a47bfba0e7904dd946 Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Fri, 26 Nov 2021 20:08:15 +0300 Subject: [PATCH 03/32] Bump Gradle version --- gradle/dependencies.gradle | 2 +- gradle/publish.gradle | 74 ------------------------ gradle/wrapper/gradle-wrapper.properties | 2 +- inputmask/build.gradle | 2 - 4 files changed, 2 insertions(+), 78 deletions(-) delete mode 100644 gradle/publish.gradle diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 16c74b9..02a2f93 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -23,7 +23,7 @@ def deps = [:] //region Gradle def gradle = [:] -versions.android_plugin = "4.1.3" +versions.android_plugin = "7.0.2" gradle.android_plugin = "com.android.tools.build:gradle:$versions.android_plugin" diff --git a/gradle/publish.gradle b/gradle/publish.gradle deleted file mode 100644 index 8d2acd6..0000000 --- a/gradle/publish.gradle +++ /dev/null @@ -1,74 +0,0 @@ -apply plugin: 'com.github.dcendents.android-maven' - -def publishPropertiesFile = rootProject.file("gradle/publish.properties") -def publishProperties = new Properties() - -if (publishPropertiesFile.canRead()) { - publishProperties.load(new FileInputStream(publishPropertiesFile)) -} -apply plugin: 'maven-publish' -apply plugin: 'com.jfrog.bintray' - -version publishProperties['lib_version'] -group publishProperties['group_id'] - -task androidSourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.kotlin.srcDirs -} - -publishing { - publications { - Production(MavenPublication) { - artifact("$buildDir/outputs/aar/input-mask-android-release.aar") - artifact androidSourcesJar - groupId - artifactId publishProperties['lib_name'] - version this.version - - pom.withXml { - def dependenciesNode = asNode().appendNode('dependencies') - - configurations.implementation.allDependencies.each { - if (it.name != 'unspecified') { - def dependencyNode = dependenciesNode.appendNode('dependency') - dependencyNode.appendNode('groupId', it.group) - dependencyNode.appendNode('artifactId', it.name) - dependencyNode.appendNode('version', it.version) - } - } - } - } - } -} - -bintray { - user = publishProperties['user'] - key = publishProperties['api_key'] - publications = ['Production'] - configurations = ['archives'] - override = true - - pkg { - repo = publishProperties['repository'] - name = publishProperties['lib_name'] - description = publishProperties['lib_description'] - userOrg = publishProperties['organization_id'] - licenses = ['MIT'] - websiteUrl = publishProperties['lib_website'] - vcsUrl = publishProperties['lib_vcs'] - issueTrackerUrl = publishProperties['lib_issue_tracker'] - publish = true - publicDownloadNumbers = true - - // set as true to test uploading - dryRun = true - - version { - name = this.version - released = new Date() - vcsTag = this.version - } - } -} - diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c36e038..e116f51 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/inputmask/build.gradle b/inputmask/build.gradle index 614720a..5abbd69 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -2,8 +2,6 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'org.jetbrains.dokka' -apply from: '../gradle/publish.gradle' - android { compileSdkVersion build_versions.compile_sdk From 1ef2952c79d923621faee6d3976b8fd02d8b8c67 Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Fri, 26 Nov 2021 20:11:20 +0300 Subject: [PATCH 04/32] Bump build tools version --- app/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9956a46..743a324 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 30 + compileSdkVersion 31 defaultConfig { applicationId "com.redmadrobot.sample" minSdkVersion 14 - targetSdkVersion 30 + targetSdkVersion 31 versionCode 1 versionName "1.0" } @@ -16,12 +16,12 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - buildToolsVersion '30.0.1' + buildToolsVersion '30.0.2' } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation deps.kotlin.stdlib - implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.appcompat:appcompat:1.4.0' implementation project(':inputmask') } From ba3cb468c05b593cb38feeba038383ef577ac68a Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Fri, 26 Nov 2021 20:12:54 +0300 Subject: [PATCH 05/32] Allow activity exporting --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 65082c3..25cfaa2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,7 +7,8 @@ android:label="@string/app_name" android:theme="@style/AppTheme"> - + From 9031783ce69dbe0c3ae7f4c67bda938af1e933c5 Mon Sep 17 00:00:00 2001 From: Jeorge Taflanidi Date: Fri, 26 Nov 2021 20:42:38 +0300 Subject: [PATCH 06/32] =?UTF-8?q?Bintray=20badge=20=E2=86=92=20JitPack=20b?= =?UTF-8?q?adge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53e0ff7..5e8082c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/4642) -[![Bintray](https://api.bintray.com/packages/redmadrobot-opensource/android/input-mask-android/images/download.svg)](https://bintray.com/redmadrobot-opensource/android/input-mask-android/_latestVersion) +[![](https://jitpack.io/v/RedMadRobot/input-mask-android.svg)](https://jitpack.io/#RedMadRobot/input-mask-android) [![codebeat badge](https://codebeat.co/badges/e87a117d-3be1-407b-ad4c-973f90d88cd2)](https://codebeat.co/projects/github-com-redmadrobot-input-mask-android-master) [![license](https://img.shields.io/github/license/mashape/apistatus.svg)]() From d1b4e5c2baf8a7f30b57b71324aca120129258cf Mon Sep 17 00:00:00 2001 From: Osip Fatkullin Date: Mon, 20 Jun 2022 14:43:34 +0300 Subject: [PATCH 07/32] Change library group to `com.redmadrobot` --- README.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 5e8082c..1188e27 100644 --- a/README.md +++ b/README.md @@ -22,30 +22,30 @@ Input Mask library development is back on track. -From now on, the official library distribution method is **JitPack**. - -
-My thoughts regarding the library migration to Maven Central -The "migration" took me long enough, okay. - -It's Saturday, the 25th of September, 2021, and yesterday I had an opportunity to complete the whole Sonatype manual on how mere mortals publish their libs to Maven Central. - -And it didn't feel right, so I decided to take a short, *last* break before pushing the changes. -The main, Central™, most important Java & Android depo doesn't feel like it's 2021 at all. - -I felt I was casting spells and performing some cargo cult rituals. -ALM-based system, the wait for approval, tickets, scripts, credentials, DNS records, artifact security assurance, corporate console library catalogs with Windows™ folder icons… - -The. Fuck. - -I know some of RedMadRobot libraries already made it to Sonatype. -But this is not the case. - -**Input Mask is never going to hit Maven Central**, and I'm not going to support this abomination of legacy and bureaucracy. -
- -First things first, I'm going to get rid of some annoying library issues from the past, do some project cleanup, and then I'd like to put more real word use case scenarios into the core, so please feel free to share your ideas via feature requests. - +From now on, the official library distribution method is **JitPack**. + +
+My thoughts regarding the library migration to Maven Central +The "migration" took me long enough, okay. + +It's Saturday, the 25th of September, 2021, and yesterday I had an opportunity to complete the whole Sonatype manual on how mere mortals publish their libs to Maven Central. + +And it didn't feel right, so I decided to take a short, *last* break before pushing the changes. +The main, Central™, most important Java & Android depo doesn't feel like it's 2021 at all. + +I felt I was casting spells and performing some cargo cult rituals. +ALM-based system, the wait for approval, tickets, scripts, credentials, DNS records, artifact security assurance, corporate console library catalogs with Windows™ folder icons… + +The. Fuck. + +I know some of RedMadRobot libraries already made it to Sonatype. +But this is not the case. + +**Input Mask is never going to hit Maven Central**, and I'm not going to support this abomination of legacy and bureaucracy. +
+ +First things first, I'm going to get rid of some annoying library issues from the past, do some project cleanup, and then I'd like to put more real word use case scenarios into the core, so please feel free to share your ideas via feature requests. + Meet `6.1.0`. ## Description @@ -99,7 +99,7 @@ repositories { } dependencies { - implementation 'com.github.RedMadRobot:input-mask-android:6.1.0' + implementation 'com.redmadrobot:input-mask-android:6.1.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:$latest_version' } From 32cb4763705f9c7dae7194ce756111a3865eaf66 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Fri, 31 Mar 2023 17:30:20 +0400 Subject: [PATCH 08/32] Update README --- Documentation/Assets/logo.png | Bin 0 -> 11697 bytes Documentation/Assets/logo.xcf | Bin 0 -> 31153 bytes LICENSE | 5 +- README.md | 144 ++++++++++------------------------ 4 files changed, 45 insertions(+), 104 deletions(-) create mode 100644 Documentation/Assets/logo.png create mode 100644 Documentation/Assets/logo.xcf diff --git a/Documentation/Assets/logo.png b/Documentation/Assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9e0ed5acfb83b1185c7b230c04d64a3745a655ba GIT binary patch literal 11697 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 DTI+j) literal 0 HcmV?d00001 diff --git a/Documentation/Assets/logo.xcf b/Documentation/Assets/logo.xcf new file mode 100644 index 0000000000000000000000000000000000000000..d620519777bb208d97e74c0cd575dd71e4d12813 GIT binary patch literal 31153 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 literal 0 HcmV?d00001 diff --git a/LICENSE b/LICENSE index 00bf69e..e98e758 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2015 Redmadrobot +Copyright (c) 2023 YEHOR TAFLANIDI Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index 1188e27..e647eb7 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,33 @@ -Input Mask - -[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/4642) -[![](https://jitpack.io/v/RedMadRobot/input-mask-android.svg)](https://jitpack.io/#RedMadRobot/input-mask-android) -[![codebeat badge](https://codebeat.co/badges/e87a117d-3be1-407b-ad4c-973f90d88cd2)](https://codebeat.co/projects/github-com-redmadrobot-input-mask-android-master) -[![license](https://img.shields.io/github/license/mashape/apistatus.svg)]() - -[![Platform](https://cdn.rawgit.com/RedMadRobot/input-mask-ios/assets/Assets/shields/platform.svg)]()[![Android](https://cdn.rawgit.com/RedMadRobot/input-mask-ios/assets/Assets/shields/android.svg)](https://github.com/RedMadRobot/input-mask-android)[![iOS](https://cdn.rawgit.com/RedMadRobot/input-mask-ios/assets/Assets/shields/ios_rect.svg)](https://github.com/RedMadRobot/input-mask-ios)[![macOS](https://cdn.rawgit.com/RedMadRobot/input-mask-ios/assets/Assets/shields/macos.svg)](https://github.com/RedMadRobot/input-mask-ios) - -Direct input -
-More GIFs [~3 MB] - Direct input - Direct input - Direct input
- Direct input - Direct input -
- -## PSA: Migration to Maven Central and overall library development - -Input Mask library development is back on track. - -From now on, the official library distribution method is **JitPack**. - -
-My thoughts regarding the library migration to Maven Central -The "migration" took me long enough, okay. - -It's Saturday, the 25th of September, 2021, and yesterday I had an opportunity to complete the whole Sonatype manual on how mere mortals publish their libs to Maven Central. - -And it didn't feel right, so I decided to take a short, *last* break before pushing the changes. -The main, Central™, most important Java & Android depo doesn't feel like it's 2021 at all. - -I felt I was casting spells and performing some cargo cult rituals. -ALM-based system, the wait for approval, tickets, scripts, credentials, DNS records, artifact security assurance, corporate console library catalogs with Windows™ folder icons… - -The. Fuck. - -I know some of RedMadRobot libraries already made it to Sonatype. -But this is not the case. - -**Input Mask is never going to hit Maven Central**, and I'm not going to support this abomination of legacy and bureaucracy. -
- -First things first, I'm going to get rid of some annoying library issues from the past, do some project cleanup, and then I'd like to put more real word use case scenarios into the core, so please feel free to share your ideas via feature requests. - -Meet `6.1.0`. - -## Description - -`Input Mask` is an [Android](https://github.com/RedMadRobot/input-mask-android) & [iOS](https://github.com/RedMadRobot/input-mask-ios) native library allowing to format user input on the fly. - -The library provides you with a text field listener; when attached, it puts separators into the text while user types it in, and gets rid of unwanted symbols, all according to custom predefined pattern. - -This allows to reformat whole strings pasted from the clipboard, e.g. turning pasted `8 800 123-45-67` into -`8 (800) 123 45 67`. - -Each pattern allows to extract valuable symbols from the entered text, returning you the immediate result with the text field listener's callback when the text changes. Such that, you'll be able to extract `1234567` from `8 (800) 123 45 67` or `19991234567` from `1 (999) 123 45 67` with two different patterns. - -All separators and valuable symbol placeholders have their own syntax. We call such patterns "masks". - -Mask examples: - -1. International phone numbers: `+1 ([000]) [000] [00] [00]` -2. Local phone numbers: `([000]) [000]-[00]-[00]` -3. Names: `[A][-----------------------------------------------------]` -4. Text: `[A…]` -5. Dates: `[00]{.}[00]{.}[9900]` -6. Serial numbers: `[AA]-[00000099]` -7. IPv4: `[099]{.}[099]{.}[099]{.}[099]` -8. Visa card numbers: `[0000] [0000] [0000] [0000]` -9. MM/YY: `[00]{/}[00]` -10. UK IBAN: `GB[00] [____] [0000] [0000] [0000] [00]` - -## Questions & Issues - -Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for further reading. -Please also take a closer look at our [Known issues](#knownissues) section before you incorporate our library into your project. - -For your bugreports and feature requests please file new issues as usually. - -Should you have any questions, search for closed [issues](https://github.com/RedMadRobot/input-mask-android/issues?q=is%3Aclosed) or open new ones at **[StackOverflow](https://stackoverflow.com/questions/tagged/input-mask)** with the `input-mask` tag. - -We also have a community-driven [cookbook](https://github.com/RedMadRobot/input-mask-android/blob/master/Documentation/COOKBOOK.md) of recipes, be sure to check it out, too. - - - -## Installation - +Input Mask + +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) + +Input masks restrict data input and allow you to guide users to enter correct values. +Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for quick start and further reading. + +## ⚙️ Features + +- Apply formatting to your text fields, see [examples](#examples) +- Filter out nonessential symbols (e.g. extract `0123456` from `+1 (999) 012-34-56`) +- For international phone numbers + - guess the country from the entered digits + - apply corresponding value restrictions (e.g. a 🇺🇸US phone will have a format like `+1 201 456-7890`) + + + +## 💳 Examples + +- Phone numbers: `+1 ([000]) [000] [00] [00]` +- Dates: `[00]{.}[00]{.}[9900]` +- Serial numbers: `[AA]-[00000099]` +- IPv4: `[099]{.}[099]{.}[099]{.}[099]` +- Visa/MasterCard numbers: `[0000] [0000] [0000] [0000]` +- UK IBAN: `GB[00] [____] [0000] [0000] [0000] [00]` + + + +## 🛠️ Installation + ### Gradle Make sure you've added Kotlin support to your project. @@ -105,9 +44,18 @@ dependencies { } ``` +## 📢 Communication, Questions & Issues + +Please take a closer look at our [Known issues](#knownissues) section before you incorporate our library into your project. + +For your bugreports and feature requests please file new issues [via GitHub](https://github.com/RedMadRobot/input-mask-android/issues/new/choose). + +Should you have any questions, please search for closed [issues](https://github.com/RedMadRobot/input-mask-android/issues?q=is%3Aclosed) or ask questions at **[StackOverflow](https://stackoverflow.com/questions/tagged/input-mask)** with the `input-mask` tag. + -# Known issues +## ❗Known issues + ## InputMask vs. `NoClassDefFoundError` ``` @@ -174,13 +122,7 @@ editText.setFilters(filters); Bare in mind, you might have to befriend this solution with your existing `android:digits` [property](#inputmask-vs-androidinputtype-and-indexoutofboundsexception) in case your text field accepts both digits and letters. -## References - -The list of projects that are using this library which were kind enough to share that information. - -Feel free to add yours below. - -## Special thanks +## 🙏 Special thanks These folks rock: @@ -191,6 +133,6 @@ These folks rock: * Vladislav [Shipaaaa](https://github.com/Shipaaaa) Shipugin * Vadim [vkotovv](https://github.com/vkotovv) Kotov -# License +## ♻️ License -The library is distributed under the MIT [LICENSE](https://opensource.org/licenses/MIT). +The library is distributed under the MIT [LICENSE](https://github.com/RedMadRobot/input-mask-android/blob/master/LICENSE). From 097dd287679670f05bf31cd6af12cd0dc3aa540c Mon Sep 17 00:00:00 2001 From: taflanidi Date: Fri, 31 Mar 2023 20:42:37 +0400 Subject: [PATCH 09/32] Add PhoneInputListener --- .../inputmask/MaskedTextChangedListener.kt | 2 +- .../inputmask/PhoneInputListener.kt | 102 +++ .../redmadrobot/inputmask/model/Country.kt | 797 ++++++++++++++++++ 3 files changed, 900 insertions(+), 1 deletion(-) create mode 100644 inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt create mode 100644 inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt index 8027f8c..796e7e4 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt @@ -286,7 +286,7 @@ open class MaskedTextChangedListener( } } - private fun pickMask( + open fun pickMask( text: CaretString ): Mask { if (this.affineFormats.isEmpty()) return this.primaryMask diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt new file mode 100644 index 0000000..09621f6 --- /dev/null +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt @@ -0,0 +1,102 @@ +package com.redmadrobot.inputmask + +import android.text.TextWatcher +import android.widget.EditText +import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy +import com.redmadrobot.inputmask.helper.Mask +import com.redmadrobot.inputmask.model.CaretString +import com.redmadrobot.inputmask.model.Country +import com.redmadrobot.inputmask.model.Notation + +/** + * ### PhoneInputListener + * + * A ```MaskedTextInputListener``` subclass for guessing a country based on the entered digit sequence + * + * Computed country dictates the phone formatting + */ +open class PhoneInputListener( + primaryFormat: String, + affineFormats: List = emptyList(), + customNotations: List = emptyList(), + affinityCalculationStrategy: AffinityCalculationStrategy = AffinityCalculationStrategy.WHOLE_STRING, + autocomplete: Boolean = true, + autoskip: Boolean = false, + field: EditText, + listener: TextWatcher? = null, + valueListener: ValueListener? = null, + rightToLeft: Boolean = false +): MaskedTextChangedListener( + primaryFormat, + affineFormats, + customNotations, + affinityCalculationStrategy, + autocomplete, + autoskip, + field, + listener, + valueListener, + rightToLeft +) { + /** + * A detected ```Country``` based on the entered digits + */ + var computedCountry: Country? = null + + /** + * A list of possible ```Country``` candidates based on the entered digits + */ + var computedCountries: List = listOf() + + /** + * Allowed ```Country``` list. Pre-filters the ```Country::all``` dictionary. + * + * May contain country names, native country names, ISO-3166 codes, country emojis, or their mix. + * + * E.g. + * ``` + * listener.enableCountries = listOf( + * "Greece", + * "BE", + * "🇪🇸" + * ) + * ``` + */ + var enableCountries: List? = null + + /** + * Blocked ```Country``` list. Pre-filters the ```Country::all``` dictionary. + * + * May contain country names, native country names, ISO-3166 codes, country emojis, or their mix. + * + * E.g. + * ``` + * listener.disableCountries = listOf( + * "Greece", + * "BE", + * "🇪🇸" + * ) + * ``` + */ + var disableCountries: List? = null + + /** + A custom ```Country``` list to be used instead of ```Country::all``` dictionary. + */ + var customCountries: List? = null + + override fun pickMask(text: CaretString): Mask { + computedCountries = Country.findCountries(customCountries, enableCountries, disableCountries, text.string) + computedCountry = if (computedCountries.count() == 1) computedCountries.first() else null + + val country = computedCountry + return if (country == null) { + Mask("+[000] [000] [000] [00] [00]") + } else { + primaryFormat = country.primaryFormat + affineFormats = country.affineFormats + + super.pickMask(text) + } + } +} diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt new file mode 100644 index 0000000..b72ef0e --- /dev/null +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt @@ -0,0 +1,797 @@ +package com.redmadrobot.inputmask.model + +/** + * ### Country + * + * Model object representing a **Country** record operated by the ```PhoneInputListener```. + */ +data class Country( + /** + * International country name. + */ + val name: String, + + /** + * Country name in its own language. + */ + val nameNative: String?, + + /** + * Country emoji. + */ + val emoji: String, + + /** + * Country ISO-3166 code, 2 valters. + */ + val iso3166alpha2: String, + + /** + * Country ISO-3166 code, 3 valters. + */ + val iso3166alpha3: String, + + /** + * Country dial code. + */ + val countryCode: String, + + /** + * Primary ```Mask``` format for the country phone numbers. + */ + val primaryFormat: String, + + /** + * Affine ```Mask``` formats for the country phone numbers. + */ + val affineFormats: List, + + /** + * A regular expression to detect whether or not the entered digits correspond to this particular country. + */ + val phoneRegex: String, +) { + fun phoneStartsWith(digits: String): Boolean = phoneRegex.toRegex().containsMatchIn(digits) + + companion object { + fun findCountries(customCountries: List?, includingTerms: List?, excludingTerms: List?, phone: String): List { + val includingTermsLowercased = includingTerms?.map { it.lowercase() } ?: listOf() + val excludingTermsLowercased = excludingTerms?.map { it.lowercase() } ?: listOf() + val phoneDigits = phone.filter(Char::isDigit) + + return customCountries ?: all.filter { + var include: Boolean = false + + if (includingTerms != null) { + include = include + || includingTermsLowercased.contains(it.name.lowercase()) + || includingTermsLowercased.contains(it.iso3166alpha2.lowercase()) + || includingTermsLowercased.contains(it.iso3166alpha3.lowercase()) + || includingTermsLowercased.contains(it.emoji) + + include = include || if (it.nameNative != null) includingTermsLowercased.contains(it.nameNative) else false + } else { + include = true + } + + var exclude: Boolean = false + + if (excludingTerms != null) { + exclude = exclude + || excludingTermsLowercased.contains(it.name.lowercase()) + || excludingTermsLowercased.contains(it.iso3166alpha2.lowercase()) + || excludingTermsLowercased.contains(it.iso3166alpha3.lowercase()) + || excludingTermsLowercased.contains(it.emoji) + + exclude = exclude || if (it.nameNative != null) excludingTermsLowercased.contains(it.nameNative) else false + } + + include = include && it.phoneStartsWith(phoneDigits) + + include && !exclude + } + } + + /** + A ```Country``` dictionary. + + Feel free to append/correct & file PRs, see https://countrycode.org + */ + val all: List = listOf( + Country( + "Canada", + "Canada", + "🇨🇦", + "CA", + "CAN", + "1", + "+{1} [000] [000]-[0000]", + listOf(), + "^1$|^1[2-9]$|^1[2-9][0-8]$|^1204|^1226|^1236|^1249|^1250|^1289|^1306|^1343|^1365|^1367|^1368|^1403|^1416|^1418|^1431|^1437|^1438|^1450|^1474|^1506|^1514|^1519|^1548|^1579|^1581|^1584|^1587|^1604|^1613|^1639|^1647|^1672|^1705|^1709|^1778|^1780|^1782|^1807|^1819|^1825|^1867|^1873|^1902|^1905" + ), + Country( + "USA", + "USA", + "🇺🇸", + "US", + "USA", + "1", + "+{1} [000] [000]-[0000]", + listOf(), + "^1$|^1[2-9]$|^1[2-9][0-8]$|^1201|^1202|^1203|^1205|^1206|^1207|^1208|^1209|^1209|^1210|^1212|^1213|^1214|^1215|^1216|^1217|^1218|^1219|^1224|^1225|^1227|^1228|^1229|^1231|^1234|^1239|^1240|^1248|^1251|^1252|^1253|^1254|^1256|^1260|^1262|^1267|^1269|^1270|^1274|^1276|^1278|^1281|^1283|^1301|^1302|^1303|^1304|^1305|^1307|^1308|^1309|^1310|^1312|^1313|^1314|^1315|^1316|^1317|^1318|^1319|^1320|^1321|^1323|^1325|^1330|^1331|^1334|^1336|^1337|^1339|^1341|^1347|^1351|^1352|^1360|^1361|^1364|^1369|^1380|^1385|^1386|^1401|^1402|^1404|^1405|^1406|^1407|^1408|^1409|^1410|^1412|^1413|^1414|^1415|^1417|^1419|^1423|^1424|^1425|^1430|^1432|^1434|^1435|^1440|^1442|^1443|^1445|^1447|^1458|^1464|^1469|^1470|^1475|^1478|^1479|^1480|^1484|^1501|^1502|^1503|^1504|^1505|^1507|^1508|^1509|^1510|^1512|^1513|^1515|^1516|^1517|^1518|^1520|^1530|^1531|^1534|^1540|^1541|^1551|^1557|^1559|^1561|^1562|^1563|^1564|^1567|^1570|^1571|^1573|^1574|^1575|^1580|^1585|^1586|^1601|^1602|^1603|^1605|^1606|^1607|^1608|^1609|^1610|^1612|^1614|^1615|^1616|^1617|^1618|^1619|^1620|^1623|^1626|^1627|^1628|^1630|^1631|^1636|^1641|^1646|^1650|^1651|^1657|^1659|^1660|^1661|^1662|^1667|^1669|^1678|^1679|^1681|^1682|^1689|^1701|^1702|^1703|^1704|^1706|^1707|^1708|^1712|^1713|^1714|^1715|^1716|^1717|^1718|^1719|^1720|^1724|^1727|^1730|^1731|^1732|^1734|^1737|^1740|^1747|^1752|^1754|^1757|^1760|^1762|^1763|^1764|^1765|^1769|^1770|^1772|^1773|^1774|^1775|^1779|^1781|^1785|^1786|^1801|^1802|^1803|^1804|^1805|^1806|^1808|^1810|^1812|^1813|^1814|^1815|^1816|^1817|^1818|^1828|^1830|^1831|^1832|^1835|^1843|^1845|^1847|^1848|^1850|^1856|^1857|^1858|^1859|^1860|^1862|^1863|^1864|^1865|^1870|^1872|^1878|^1901|^1903|^1904|^1906|^1907|^1908|^1909|^1910|^1912|^1913|^1914|^1915|^1916|^1917|^1918|^1919|^1920|^1925|^1927|^1928|^1931|^1935|^1936|^1937|^1938|^1940|^1941|^1947|^1949|^1951|^1952|^1954|^1956|^1957|^1959|^1970|^1971|^1972|^1973|^1975|^1978|^1979|^1980|^1984|^1985|^1989" + ), + Country( + "Kazakhstan", + "Қазақстан", + "🇰🇿", + "KZ", + "KAZ", + "7", + "+{7} ([000]) [000]-[00]-[00]", + listOf(), + "^7$|^7[125670]" + ), + Country( + "Russian Federation", + "Российская Федерация", + "🇷🇺", + "RU", + "RUS", + "7", + "+{7} ([000]) [000]-[00]-[00]", + listOf(), + "^7$|^7[3489]" + ), + Country( + "Egypt", + "مصر", + "🇪🇬", + "EG", + "EGY", + "20", + "+{20}-[90]-[000]-[0000]", + listOf( + // TODO + ), + "^2$|^20$|^20[1-9]" + ), + Country( + "Greece", + "Ελλάδα", + "🇬🇷", + "GR", + "GRC", + "30", + "+{30} [9000] [000] [0000]", + listOf( + // TODO + ), + "^3$|^30" + ), + Country( + "Netherlands", + "Nederland", + "🇳🇱", + "NL", + "NLD", + "31", + "+{31} [9000] [000] [0000]", + listOf( + // TODO + ), + "^3$|^31" + ), + Country( + "Belgium", + "Koninkrijk België", + "🇧🇪", + "BE", + "BEL", + "32", + "+{32} [990] [900] [00] [00]", + listOf( + // TODO + ), + "^3$|^32" + ), + Country( + "France", + "France", + "🇫🇷", + "FR", + "FRA", + "33", + "+{33} [0] [00] [00] [00] [00]", + listOf( + // TODO + ), + "^3$|^33" + ), + Country( + "Spain", + "España", + "🇪🇸", + "ES", + "ESP", + "34", + "+{34} [000] [000] [000]", + listOf( + // TODO + ), + "^3$|^34" + ), + Country( + "Hungary", + "Magyarország", + "🇭🇺", + "HU", + "HUN", + "36", + "+{36} [90] [000] [000]", + listOf( + // TODO + ), + "^3$|^36" + ), + Country( + "Italy", + "Italia", + "🇮🇹", + "IT", + "ITA", + "39", + "+{39} [990] [000000]", + listOf( + // TODO + ), + "^3$|^39" + ), + Country( + "Romania", + "România", + "🇷🇴", + "RO", + "ROU", + "40", + "+{40} [900] [900] [000]", + listOf( + // TODO + ), + "^4$|^40" + ), + Country( + "Switzerland", + "Schweezerland", + "🇨🇭", + "CH", + "CHE", + "41", + "+{41} {0}[00] [000] [00] [00]", + listOf( + // TODO + ), + "^4$|^41" + ), + Country( + "Austria", + "Ausztria", + "🇦🇹", + "AT", + "AUT", + "43", + "+{43} [990] [000] [00] [00]", + listOf( + // TODO + ), + "^4$|^43" + ), + Country( + "United Kingdom", + "United Kingdom", + "🇬🇧", + "GB", + "GBR", + "44", + "+{44} ([000]) [0000] [0000]", + listOf( + // TODO + ), + "^4$|^44" + ), + Country( + "Denmark", + "Danmark", + "🇩🇰", + "DK", + "DNK", + "45", + "+{45} [00] [00] [00] [00]", + listOf( + // TODO + ), + "^4$|^45" + ), + Country( + "Sweden", + "Sverige", + "🇸🇪", + "SE", + "SWE", + "46", + "+{46} [000] [000] [0000]", + listOf( + // TODO + ), + "^4$|^46" + ), + Country( + "Norway", + "Noorweegen", + "🇳🇴", + "NO", + "NOR", + "47", + "+{47} [00] [00] [00] [00]", + listOf( + // TODO + ), + "^4$|^47" + ), + Country( + "Poland", + "Polska", + "🇵🇱", + "PL", + "POL", + "48", + "+{48} [00] [000] [00] [00]", + listOf( + // TODO + ), + "^4$|^48" + ), + Country( + "Germany", + "Deutschland", + "🇩🇪", + "DE", + "DEU", + "49", + "+{49} [99900] [9900] [0000]", + listOf( + // TODO + ), + "^4$|^49" + ), + Country( + "Peru", + "Perú", + "🇵🇪", + "PE", + "PER", + "51", + "+{51} [000] [000] [000]", + listOf( + // TODO + ), + "^5$|^51" + ), + Country( + "Mexico", + "México", + "🇲🇽", + "MX", + "MEX", + "52", + "+{52} [0000000000]", + listOf( + // TODO + ), + "^5$|^52" + ), + Country( + "Cuba", + "Cuba", + "🇨🇺", + "CU", + "CUB", + "53", + "+{53} [00] [000] [0000]", + listOf( + // TODO + ), + "^5$|^53" + ), + Country( + "Argentina", + "Argentina", + "🇦🇷", + "AR", + "ARG", + "54", + "+{54} [000] [000]–[0000]", + listOf( + // TODO + ), + "^5$|^54" + ), + Country( + "Brazil", + "Brasil", + "🇧🇷", + "BR", + "BRA", + "55", + "+{55} [00] [0000]-[0000]", + listOf( + "+{55} [00] 9[0000]-[0000]", // TODO + ), + "^5$|^55" + ), + Country( + "Chile", + "Chile", + "🇨🇱", + "CL", + "CHL", + "56", + "+{56} ([000]) [000] [000]", + listOf( + // TODO + ), + "^5$|^56" + ), + Country( + "Colombia", + "Colombia", + "🇨🇴", + "CO", + "COL", + "57", + "+{57}-[000]-[0000000]", + listOf( + // TODO + ), + "^5$|^57" + ), + Country( + "Venezuela", + "Venezuela", + "🇻🇪", + "VE", + "VEN", + "58", + "+{58} [000] [0000000]", + listOf( + // TODO + ), + "^5$|^58" + ), + Country( + "Malaysia", + null, + "🇲🇾", + "MY", + "MYS", + "60", + "+{60} [990] [9000] [0000]", + listOf( + // TODO + ), + "^6$|^60" + ), + Country( + "Australia", + "Australia", + "🇦🇺", + "AU", + "AUS", + "61", + "+{61} [000] [000] [000]", + listOf( + // TODO + ), + "^6$|^61" + ), + Country( + "Indonesia", + "Indonesia", + "🇮🇩", + "ID", + "IDN", + "62", + "+{62} [9000]-[0000]-[0000]", + listOf( + // TODO + ), + "^6$|^62" + ), + Country( + "Philippines", + "Pilipinas", + "🇵🇭", + "PH", + "PHL", + "63", + "+{63} [900]-[000]-[0000]", + listOf( + // TODO + ), + "^6$|^63" + ), + Country( + "New Zealand", + "Aotearoa", + "🇳🇿", + "NZ", + "NZL", + "64", + "+{64} [9000] [000] [9000]", + listOf( + // TODO + ), + "^6$|^64" + ), + Country( + "Singapore", + "Singapura", + "🇸🇬", + "SG", + "SGP", + "65", + "+{65} [0000] [0000]", + listOf( + // TODO + ), + "^6$|^65" + ), + Country( + "Thailand", + "ประเทศไทย", + "🇹🇭", + "TH", + "THA", + "66", + "+{66} [0000000000]", + listOf( + // TODO + ), + "^6$|^66" + ), + Country( + "Japan", + "日本", + "🇯🇵", + "JP", + "JPN", + "81", + "+{81} [9900]-[9900]-[0000]", + listOf( + // TODO + ), + "^8$|^81" + ), + Country( + "South Korea", + "대한민국", + "🇰🇷", + "KR", + "KOR", + "82", + "+{82} [00] [0000] [0000]", + listOf( + // TODO + ), + "^8$|^82" + ), + Country( + "Vietnam", + "Việt Nam", + "🇻🇳", + "VN", + "VNM", + "84", + "+{84} [0000] [000] [000]", + listOf( + // TODO + ), + "^8$|^84" + ), + Country( + "China", + "中国", + "🇨🇳", + "CN", + "CHN", + "86", + "+{86} [000]-[0000]-[0000]", + listOf( + // TODO + ), + "^8$|^86" + ), + Country( + "Türkiye", + "Türkiye", + "🇹🇷", + "TR", + "TUR", + "90", + "+{90} ([000]) [000]-[00]-[00]", + listOf( + // TODO + ), + "^9$|^90" + ), + Country( + "India", + "Bhārat Gaṇarājya", + "🇮🇳", + "IN", + "IND", + "91", + "+{91} [000] [0000000]", + listOf( + // TODO + ), + "^9$|^91" + ), + Country( + "Pakistan", + "پاکِستان", + "🇵🇰", + "PK", + "PAK", + "92", + "+{92} ([000]) [0000000]", + listOf( + // TODO + ), + "^9$|^92" + ), + Country( + "Afghanistan", + null, + "🇦🇫", + "AF", + "AFG", + "93", + "+{93} [00] [0000000]", + listOf( + // TODO + ), + "^9$|^93" + ), + Country( + "Sri Lanka", + "ශ්‍රී ලංකා", + "🇱🇰", + "LK", + "LKA", + "94", + "+{94} [000]-[000] [0000]", + listOf( + // TODO + ), + "^9$|^94" + ), + Country( + "Greenland", + "Kalaallit Nunaat", + "🇬🇱", + "GL", + "GRL", + "299", + "+{299} [00] [00] [00]", + listOf( + // TODO + ), + "^2$|^29$|^299" + ), + Country( + "Portugal", + "Portugal", + "🇵🇹", + "PT", + "PRT", + "351", + "+{351} [000] [000] [9000]", + listOf( + // TODO + ), + "^3$|^35$|^351" + ), + Country( + "Finland", + "Suomi", + "🇫🇮", + "FI", + "FIN", + "358", + "+{358} [0] [000] [000]", + listOf( + // TODO + ), + "^3$|^35$|^358" + ), + Country( + "Lithuania", + "Lietuva", + "🇱🇹", + "LT", + "LTU", + "370", + "+{370} ([9000]) [900] [0000]", + listOf( + // TODO + ), + "^3$|^37$|^370" + ), + Country( + "Latvia", + "Latvija", + "🇱🇻", + "LV", + "LVA", + "371", + "+{371} [900] [9900] [900]", + listOf( + // TODO + ), + "^3$|^37$|^371" + ), + Country( + "Estonia", + "Eesti", + "🇪🇪", + "EE", + "EST", + "372", + "+{372} [000] [0000]", + listOf( + // TODO + ), + "^3$|^37$|^372" + ), + Country( + "Belarus", + "Белару́сь", + "", + "BY", + "BLR", + "375", + "+{375} ([000]) [000]-[00]-[00]", + listOf( + // TODO + ), + "^3$|^37$|^375" + ), + Country( + "Ukraine", + "Україна", + "🇺🇦", + "UA", + "UKR", + "380", + "+{380} ([00]) [000]-[00]-[00]", + listOf(), + "^3$|^38$|^380" + ), + Country( + "Georgia", + "საქართველო", + "🇬🇪", + "GE", + "GEO", + "995", + "+{995} ([000]) [000] [000]", + listOf( + // TODO + ), + "^9$|^99$|^995" + ), + ) + + } + +} From 4aef835aad8b1f4bf169967ee2d5f6f137c1883b Mon Sep 17 00:00:00 2001 From: taflanidi Date: Fri, 31 Mar 2023 20:52:41 +0400 Subject: [PATCH 10/32] Add tail placeholder calculation --- .../inputmask/MaskedTextChangedListener.kt | 13 +++++++++---- .../com/redmadrobot/inputmask/helper/Mask.kt | 19 ++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt index 796e7e4..9fe69ce 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/MaskedTextChangedListener.kt @@ -34,7 +34,12 @@ open class MaskedTextChangedListener( ) : TextWatcher, View.OnFocusChangeListener { interface ValueListener { - fun onTextChanged(maskFilled: Boolean, extractedValue: String, formattedValue: String) + fun onTextChanged( + maskFilled: Boolean, + extractedValue: String, + formattedValue: String, + tailPlaceholder: String + ) } private val primaryMask: Mask @@ -130,7 +135,7 @@ open class MaskedTextChangedListener( val result = setText(text, it, autocomplete) this.afterText = result.formattedText.string this.caretPosition = result.formattedText.caretPosition - this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText) + this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText, result.tailPlaceholder) return result } } @@ -247,7 +252,7 @@ open class MaskedTextChangedListener( this.afterText = result.formattedText.string this.caretPosition = result.formattedText.caretPosition - this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText) + this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText, result.tailPlaceholder) } override fun onFocusChange(view: View?, hasFocus: Boolean) { @@ -282,7 +287,7 @@ open class MaskedTextChangedListener( """ ) } - this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText) + this.valueListener?.onTextChanged(result.complete, result.extractedValue, afterText, result.tailPlaceholder) } } diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt index 3c58434..04a2707 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt @@ -48,14 +48,19 @@ open class Mask(format: String, protected val customNotations: List) { /** * User input is complete. */ - val complete: Boolean + val complete: Boolean, + /** + Placeholder for remaining text. + */ + val tailPlaceholder: String ) { fun reversed() = Result( this.formattedText.reversed(), this.extractedValue.reversed(), this.affinity, - this.complete + this.complete, + this.tailPlaceholder.reversed() ) } @@ -163,6 +168,9 @@ open class Mask(format: String, protected val customNotations: List) { } } + var tailState = state + var tail = "" + while (text.caretGravity.autoskip && !autocompletionStack.empty()) { val skip: Next = autocompletionStack.pop() if (modifiedString.length == modifiedCaretPosition) { @@ -178,8 +186,12 @@ open class Mask(format: String, protected val customNotations: List) { modifiedCaretPosition -= 1 } } + tailState = skip.state + tail = if (skip.insert != null) skip.insert.toString() else tail } + val tailPlaceholder = appendPlaceholder(tailState, tail) + return Result( CaretString( modifiedString, @@ -188,7 +200,8 @@ open class Mask(format: String, protected val customNotations: List) { ), extractedValue, affinity, - this.noMandatoryCharactersLeftAfterState(state) + this.noMandatoryCharactersLeftAfterState(state), + tailPlaceholder ) } From 925a636bd8978d3fbef818db15e48d721690da88 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 10 Apr 2023 17:33:29 +0400 Subject: [PATCH 11/32] Update sample project --- app/build.gradle | 6 +- .../com/redmadrobot/sample/MainActivity.java | 95 +++++++++++++------ app/src/main/res/layout/activity_main.xml | 66 +++++++++++-- app/src/main/res/values/strings.xml | 5 +- .../inputmask/PhoneInputListener.kt | 80 ++++++++++++++++ 5 files changed, 210 insertions(+), 42 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 743a324..67c2eba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { applicationId "com.redmadrobot.sample" - minSdkVersion 14 - targetSdkVersion 31 + minSdkVersion 17 + targetSdkVersion 33 versionCode 1 versionName "1.0" } diff --git a/app/src/main/java/com/redmadrobot/sample/MainActivity.java b/app/src/main/java/com/redmadrobot/sample/MainActivity.java index 09bcc2d..c01fd04 100644 --- a/app/src/main/java/com/redmadrobot/sample/MainActivity.java +++ b/app/src/main/java/com/redmadrobot/sample/MainActivity.java @@ -1,15 +1,24 @@ package com.redmadrobot.sample; +import android.graphics.Paint; +import android.graphics.Rect; import android.os.Bundle; import android.util.Log; +import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.EditText; +import android.widget.TextView; + import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.redmadrobot.inputmask.MaskedTextChangedListener; +import com.redmadrobot.inputmask.PhoneInputListener; import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy; +import com.redmadrobot.inputmask.model.Country; +import com.redmadrobot.inputmask.model.Notation; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -18,32 +27,51 @@ * @author taflanidi */ public final class MainActivity extends AppCompatActivity { + private PhoneInputListener listener = null; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - setupPrefixSample(); - setupSuffixSample(); + setupCurrencySample(); + setupDateSample(); + setupPhoneSample(); + } + + private void setupCurrencySample() { + // TODO } - private void setupPrefixSample() { - final EditText editText = findViewById(R.id.prefix_edit_text); - final CheckBox checkBox = findViewById(R.id.prefix_check_box); - final List affineFormats = new ArrayList<>(); - affineFormats.add("8 ([000]) [000]-[00]-[00]"); + private void setupDateSample() { + final EditText editText = findViewById(R.id.date_edit_text); + final CheckBox checkBox = findViewById(R.id.date_check_box); + final TextView placeholder = findViewById(R.id.date_placeholder_text_view); final MaskedTextChangedListener listener = MaskedTextChangedListener.Companion.installOn( editText, - "+7 ([000]) [000]-[00]-[00]", - affineFormats, - AffinityCalculationStrategy.PREFIX, + "[90].[90].[0000]", + new ArrayList(), + new ArrayList(), + AffinityCalculationStrategy.WHOLE_STRING, + true, + true, + null, new MaskedTextChangedListener.ValueListener() { @Override - public void onTextChanged(boolean maskFilled, @NonNull final String extractedValue, @NonNull String formattedText) { - logValueListener(maskFilled, extractedValue, formattedText); + public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { + logValueListener(maskFilled, extractedValue, formattedValue); checkBox.setChecked(maskFilled); + + placeholder.setText(formattedValue.isEmpty() ? "" : tailPlaceholder); + + Rect textBounds = new Rect(); + Paint paint = placeholder.getPaint(); + paint.getTextBounds(formattedValue, 0, formattedValue.length(), textBounds); + int width = textBounds.width(); + + ViewGroup.MarginLayoutParams placeholderParams = (ViewGroup.MarginLayoutParams) placeholder.getLayoutParams(); + placeholderParams.setMarginStart(width + 16); // 16 is an empirical value } } ); @@ -51,24 +79,37 @@ public void onTextChanged(boolean maskFilled, @NonNull final String extractedVal editText.setHint(listener.placeholder()); } - private void setupSuffixSample() { - final EditText editText = findViewById(R.id.suffix_edit_text); - final CheckBox checkBox = findViewById(R.id.suffix_check_box); - final List affineFormats = new ArrayList<>(); - affineFormats.add("+7 ([000]) [000]-[00]-[00]#[000]"); + private void setupPhoneSample() { + final EditText editText = findViewById(R.id.phone_edit_text); + final CheckBox checkBox = findViewById(R.id.phone_check_box); + final TextView countriesTextView = findViewById(R.id.countries_text_view); - final MaskedTextChangedListener listener = MaskedTextChangedListener.Companion.installOn( - editText, - "+7 ([000]) [000]-[00]-[00]", - affineFormats, - AffinityCalculationStrategy.WHOLE_STRING, - new MaskedTextChangedListener.ValueListener() { - @Override - public void onTextChanged(boolean maskFilled, @NonNull final String extractedValue, @NonNull String formattedText) { - logValueListener(maskFilled, extractedValue, formattedText); - checkBox.setChecked(maskFilled); + listener = PhoneInputListener.Companion.installOn( + editText, + true, + false, + null, + new MaskedTextChangedListener.ValueListener() { + @Override + public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { + logValueListener(maskFilled, extractedValue, formattedValue); + checkBox.setChecked(maskFilled); + + StringBuilder countriesList = new StringBuilder(); + if (listener != null) { + for (Country country: listener.getComputedCountries()) { + countriesList + .append(country.getCountryCode()) + .append(" ") + .append(country.getEmoji()) + .append(" ") + .append(country.getName()) + .append("\n"); + } } + countriesTextView.setText(countriesList.toString()); } + } ); editText.setHint(listener.placeholder()); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 1d1e0e9..aee5e60 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,24 +3,27 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingEnd="16dp" - android:paddingStart="16dp"> + android:paddingStart="16dp" + android:paddingEnd="16dp"> + android:textStyle="bold" + android:textSize="20sp" + android:text="@string/currency_label" /> + android:digits="1234567890., $€" + android:inputType="numberDecimal" + android:text="" /> + android:textStyle="bold" + android:textSize="20sp" + android:text="@string/date_label" /> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f09a38b..729a6ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ InputMask - Phone Prefix Sample - Phone Suffix Sample + Currency: + Date: + Phone: diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt index 09621f6..a0549aa 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt @@ -38,6 +38,46 @@ open class PhoneInputListener( valueListener, rightToLeft ) { + /** + * Convenience constructor. + */ + constructor(field: EditText): + this(field, null) + + /** + * Convenience constructor. + */ + constructor(field: EditText, valueListener: ValueListener?): + this(field, null, valueListener) + + /** + * Convenience constructor. + */ + constructor(field: EditText, listener: TextWatcher?, valueListener: ValueListener?): + this(true, false, field, listener, valueListener) + + /** + * Convenience constructor. + */ + constructor( + autocomplete: Boolean, + autoskip: Boolean, + field: EditText, + listener: TextWatcher?, + valueListener: ValueListener? + ): + this( + "", + emptyList(), + emptyList(), + AffinityCalculationStrategy.WHOLE_STRING, + autocomplete, + autoskip, + field, + listener, + valueListener + ) + /** * A detected ```Country``` based on the entered digits */ @@ -99,4 +139,44 @@ open class PhoneInputListener( super.pickMask(text) } } + + companion object { + /** + * Create a `PhoneInputListener` instance and assign it as a field's + * `TextWatcher` and `onFocusChangeListener`. + */ + fun installOn( + editText: EditText, + valueListener: ValueListener? = null + ): PhoneInputListener = installOn( + editText, + true, + false, + null, + valueListener + ) + + /** + * Create a `PhoneInputListener` instance and assign it as a field's + * `TextWatcher` and `onFocusChangeListener`. + */ + fun installOn( + editText: EditText, + autocomplete: Boolean = true, + autoskip: Boolean = false, + listener: TextWatcher? = null, + valueListener: ValueListener? = null + ): PhoneInputListener { + val maskedListener = PhoneInputListener( + autocomplete, + autoskip, + editText, + listener, + valueListener + ) + editText.addTextChangedListener(maskedListener) + editText.onFocusChangeListener = maskedListener + return maskedListener + } + } } From a6f02e843e907d565137e92a51cb3c1c5b6dde77 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 10 Apr 2023 18:54:57 +0400 Subject: [PATCH 12/32] Add basic NumberInputListener --- app/build.gradle | 2 +- .../com/redmadrobot/sample/MainActivity.java | 23 +- app/src/main/res/layout/activity_main.xml | 1 + gradle/dependencies.gradle | 6 +- .../inputmask/MaskedTextChangedListener.kt | 2 +- .../inputmask/NumberInputListener.kt | 248 ++++++++++++++++++ 6 files changed, 276 insertions(+), 6 deletions(-) create mode 100644 inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt diff --git a/app/build.gradle b/app/build.gradle index 67c2eba..6463398 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ android { defaultConfig { applicationId "com.redmadrobot.sample" - minSdkVersion 17 + minSdkVersion 30 targetSdkVersion 33 versionCode 1 versionName "1.0" diff --git a/app/src/main/java/com/redmadrobot/sample/MainActivity.java b/app/src/main/java/com/redmadrobot/sample/MainActivity.java index c01fd04..3a79626 100644 --- a/app/src/main/java/com/redmadrobot/sample/MainActivity.java +++ b/app/src/main/java/com/redmadrobot/sample/MainActivity.java @@ -2,6 +2,8 @@ import android.graphics.Paint; import android.graphics.Rect; +import android.icu.number.NumberFormatter; +import android.icu.util.Currency; import android.os.Bundle; import android.util.Log; import android.view.ViewGroup; @@ -12,6 +14,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.redmadrobot.inputmask.MaskedTextChangedListener; +import com.redmadrobot.inputmask.NumberInputListener; import com.redmadrobot.inputmask.PhoneInputListener; import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy; import com.redmadrobot.inputmask.model.Country; @@ -40,7 +43,25 @@ protected void onCreate(final Bundle savedInstanceState) { } private void setupCurrencySample() { - // TODO + final EditText editText = findViewById(R.id.currency_edit_text); + final CheckBox checkBox = findViewById(R.id.currency_check_box); + + final NumberInputListener listener = NumberInputListener.Companion.installOn( + editText, + new MaskedTextChangedListener.ValueListener() { + @Override + public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { + logValueListener(maskFilled, extractedValue, formattedValue); + checkBox.setChecked(maskFilled); + } + } + ); + + listener.setFormatter( + listener.getFormatter().unit(Currency.getInstance("USD")) + ); + + editText.setHint(listener.placeholder()); } private void setupDateSample() { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index aee5e60..0fa43b0 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -20,6 +20,7 @@ android:layout_height="wrap_content" android:digits="1234567890., $€" android:inputType="numberDecimal" + android:gravity="end" android:text="" /> = emptyList(), + customNotations: List = emptyList(), + affinityCalculationStrategy: AffinityCalculationStrategy = AffinityCalculationStrategy.WHOLE_STRING, + autocomplete: Boolean = true, + autoskip: Boolean = false, + field: EditText, + listener: TextWatcher? = null, + valueListener: ValueListener? = null, + rightToLeft: Boolean = false +): MaskedTextChangedListener( + primaryFormat, + affineFormats, + customNotations, + affinityCalculationStrategy, + autocomplete, + autoskip, + field, + listener, + valueListener, + rightToLeft +) { + /** + * Convenience constructor. + */ + constructor(field: EditText): + this(field, null) + + /** + * Convenience constructor. + */ + constructor(field: EditText, valueListener: ValueListener?): + this(field, null, valueListener) + + /** + * Convenience constructor. + */ + constructor(field: EditText, listener: TextWatcher?, valueListener: ValueListener?): + this(true, false, field, listener, valueListener) + + /** + * Convenience constructor. + */ + constructor( + autocomplete: Boolean, + autoskip: Boolean, + field: EditText, + listener: TextWatcher?, + valueListener: ValueListener? + ): + this( + "", + emptyList(), + emptyList(), + AffinityCalculationStrategy.WHOLE_STRING, + autocomplete, + autoskip, + field, + listener, + valueListener + ) + + open var formatter: LocalizedNumberFormatter = + NumberFormatter + .withLocale(Locale("en_us")) + .roundingMode(RoundingMode.FLOOR) + + override fun placeholder(): String { + val text = "0" + val mask = pickMask( + CaretString(text, text.length, CaretString.CaretGravity.FORWARD(autocomplete)) + ) + return mask.placeholder() + } + + override fun pickMask(text: CaretString): Mask { + val sanitisedNumberString = extractNumberAndDecimalSeparator(formatter, text.string) + + val intNum = sanitisedNumberString.intPart.toLong() + val intMaskFormat = formatter.format(intNum) + +// guard let intNum = NumberFormatter().number(from: sanitisedNumberString.intPart), let intMaskFormat = formatter.string(from: intNum) +// else { +// return try! Mask.getOrCreate(withFormat: "[…]") +// } + + val intZero = intNum == 0.toLong() + val notationChar = assignNonZeroNumberNotation() + + var maskFormat = "" + var first = true + intMaskFormat.toString().forEach { c: Char -> + if (c.isDigit()) { + if (first && !intZero) { + maskFormat += "[$notationChar]" + first = false + } else { + maskFormat += "[0]" + } + } else { + maskFormat += "{$c}" + } + } + + if (sanitisedNumberString.numberOfOccurrencesOfDecimalSeparator > 0) { + maskFormat += "{${sanitisedNumberString.expectedDecimalSeparator}}" + } + + sanitisedNumberString.decPart.forEach { c: Char -> + maskFormat += "[0]" + } + + primaryFormat = maskFormat + return super.pickMask(text) + } + + private data class SanitisedNumberString( + val intPart: String, + val decPart: String, + val expectedDecimalSeparator: String, + val numberOfOccurrencesOfDecimalSeparator: Int + ) + + private fun extractNumberAndDecimalSeparator( + formatter: LocalizedNumberFormatter, + text: String + ): SanitisedNumberString { +// val appliedDecimalSeparator = formatter.decimalSeparator ?? NumberInputListener.decimalSeparator +// val appliedCurrencyDecimalSeparator = formatter.currencyDecimalSeparator ?? NumberInputListener.decimalSeparator + + val expectedDecimalSeparator: String = decimalSeparator +// if (text.contains(appliedCurrencyDecimalSeparator)) { +// expectedDecimalSeparator = appliedCurrencyDecimalSeparator +// } + +// var digitsAndDecimalSeparators = text.replace(ep) +// .replacingOccurrences(of: appliedDecimalSeparator, with: NumberInputListener.decimalSeparator) +// .replacingOccurrences(of: appliedCurrencyDecimalSeparator, with: NumberInputListener.decimalSeparator) +// .filter { c in +// return CharacterSet.decimalDigits.isMember(character: c) || String(c) == NumberInputListener.decimalSeparator +// } + + + var digitsAndDecimalSeparators = text.filter { c: Char -> c.isDigit() || c.toString() == decimalSeparator } + +// val numberOfOccurencesOfDecimalSeparator = digitsAndDecimalSeparators.numberOfOccurencesOf(NumberInputListener.decimalSeparator) + val numberOfOccurencesOfDecimalSeparator = digitsAndDecimalSeparators.count { c: Char -> c.toString() == decimalSeparator } + if (numberOfOccurencesOfDecimalSeparator > 1) { +// digitsAndDecimalSeparators = +// digitsAndDecimalSeparators +// .reversed() +// .replace() +// .repl(decimalSeparator, with: "", maxReplacements: numberOfOccurencesOfDecimalSeparator - 1) +// .reversed + } + + val components = digitsAndDecimalSeparators.split(decimalSeparator) + + var intStr = "" + var decStr = "" + + if (components.size > 1) { + intStr = components.first() + decStr = components.last() + } else { + intStr = components.first() + } + + intStr = if (intStr.isEmpty()) "0" else intStr +// intStr = String(intStr.prefix(formatter.maximumIntegerDigits)) +// decStr = String(decStr.prefix(formatter.maximumFractionDigits)) + + return SanitisedNumberString( + intStr, + decStr, + expectedDecimalSeparator, + numberOfOccurencesOfDecimalSeparator + ) + } + + private fun assignNonZeroNumberNotation(): Char { + val character = '1' + customNotations = listOf( + Notation( + character, + "123456789", + false + ) + ) + return character + } + + companion object { + val decimalSeparator = "." + + /** + * Create a `NumberInputListener` instance and assign it as a field's + * `TextWatcher` and `onFocusChangeListener`. + */ + fun installOn( + editText: EditText, + valueListener: ValueListener? = null + ): NumberInputListener = installOn( + editText, + true, + false, + null, + valueListener + ) + + /** + * Create a `NumberInputListener` instance and assign it as a field's + * `TextWatcher` and `onFocusChangeListener`. + */ + fun installOn( + editText: EditText, + autocomplete: Boolean = true, + autoskip: Boolean = false, + listener: TextWatcher? = null, + valueListener: ValueListener? = null + ): NumberInputListener { + val maskedListener = NumberInputListener( + autocomplete, + autoskip, + editText, + listener, + valueListener + ) + editText.addTextChangedListener(maskedListener) + editText.onFocusChangeListener = maskedListener + return maskedListener + } + } +} \ No newline at end of file From 0d34b099e796124dfa8d5d8ec2e8b7278610104d Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 10 Apr 2023 19:23:44 +0400 Subject: [PATCH 13/32] Cleanup --- .../inputmask/NumberInputListener.kt | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt index 0f1e658..e81429e 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt @@ -2,6 +2,7 @@ package com.redmadrobot.inputmask import android.icu.number.LocalizedNumberFormatter import android.icu.number.NumberFormatter +import android.icu.number.Precision import android.text.TextWatcher import android.widget.EditText import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy @@ -11,6 +12,22 @@ import com.redmadrobot.inputmask.model.Notation import java.math.RoundingMode import java.util.* +/** + * — Mom, can we have a neural network? + * — No, we have a neural network at home. + * + * Neural network at home: + */ + +/** + * ### NumberInputListener + * + * A ``MaskedTextInputListener`` subclass for numbers. + * + * Use with caution, this module is still in development. + * + * - seealso: the ``NumberInputListener/formatter`` field + */ open class NumberInputListener( primaryFormat: String, affineFormats: List = emptyList(), @@ -78,6 +95,7 @@ open class NumberInputListener( NumberFormatter .withLocale(Locale("en_us")) .roundingMode(RoundingMode.FLOOR) + .precision(Precision.unlimited()) override fun placeholder(): String { val text = "0" @@ -93,11 +111,6 @@ open class NumberInputListener( val intNum = sanitisedNumberString.intPart.toLong() val intMaskFormat = formatter.format(intNum) -// guard let intNum = NumberFormatter().number(from: sanitisedNumberString.intPart), let intMaskFormat = formatter.string(from: intNum) -// else { -// return try! Mask.getOrCreate(withFormat: "[…]") -// } - val intZero = intNum == 0.toLong() val notationChar = assignNonZeroNumberNotation() @@ -139,33 +152,20 @@ open class NumberInputListener( formatter: LocalizedNumberFormatter, text: String ): SanitisedNumberString { -// val appliedDecimalSeparator = formatter.decimalSeparator ?? NumberInputListener.decimalSeparator -// val appliedCurrencyDecimalSeparator = formatter.currencyDecimalSeparator ?? NumberInputListener.decimalSeparator - val expectedDecimalSeparator: String = decimalSeparator -// if (text.contains(appliedCurrencyDecimalSeparator)) { -// expectedDecimalSeparator = appliedCurrencyDecimalSeparator -// } - -// var digitsAndDecimalSeparators = text.replace(ep) -// .replacingOccurrences(of: appliedDecimalSeparator, with: NumberInputListener.decimalSeparator) -// .replacingOccurrences(of: appliedCurrencyDecimalSeparator, with: NumberInputListener.decimalSeparator) -// .filter { c in -// return CharacterSet.decimalDigits.isMember(character: c) || String(c) == NumberInputListener.decimalSeparator -// } - var digitsAndDecimalSeparators = text.filter { c: Char -> c.isDigit() || c.toString() == decimalSeparator } -// val numberOfOccurencesOfDecimalSeparator = digitsAndDecimalSeparators.numberOfOccurencesOf(NumberInputListener.decimalSeparator) val numberOfOccurencesOfDecimalSeparator = digitsAndDecimalSeparators.count { c: Char -> c.toString() == decimalSeparator } if (numberOfOccurencesOfDecimalSeparator > 1) { -// digitsAndDecimalSeparators = -// digitsAndDecimalSeparators -// .reversed() -// .replace() -// .repl(decimalSeparator, with: "", maxReplacements: numberOfOccurencesOfDecimalSeparator - 1) -// .reversed + var numberOfReplacements = numberOfOccurencesOfDecimalSeparator - 1 + digitsAndDecimalSeparators = digitsAndDecimalSeparators.reversed().filter { c: Char -> + if (!c.isDigit() && numberOfReplacements > 0) { + numberOfReplacements -= 1 + return@filter false + } + true + }.reversed() } val components = digitsAndDecimalSeparators.split(decimalSeparator) @@ -181,8 +181,8 @@ open class NumberInputListener( } intStr = if (intStr.isEmpty()) "0" else intStr -// intStr = String(intStr.prefix(formatter.maximumIntegerDigits)) -// decStr = String(decStr.prefix(formatter.maximumFractionDigits)) +// intStr = String(intStr.prefix(formatter.maximumIntegerDigits)) TODO +// decStr = String(decStr.prefix(formatter.maximumFractionDigits)) TODO return SanitisedNumberString( intStr, From 093c99173fbc65a517c8a94594c755c3c7ac4556 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 10 Apr 2023 19:39:34 +0400 Subject: [PATCH 14/32] Docs cleanup --- .../inputmask/NumberInputListener.kt | 4 +- .../inputmask/PhoneInputListener.kt | 16 +++---- .../helper/AffinityCalculationStrategy.kt | 2 +- .../inputmask/helper/CaretStringIterator.kt | 4 +- .../redmadrobot/inputmask/helper/Compiler.kt | 46 +++++++++---------- .../inputmask/helper/FormatSanitizer.kt | 36 +++++++-------- .../com/redmadrobot/inputmask/helper/Mask.kt | 22 ++++----- .../redmadrobot/inputmask/helper/RTLMask.kt | 2 +- .../redmadrobot/inputmask/model/Country.kt | 8 ++-- .../com/redmadrobot/inputmask/model/Next.kt | 2 +- .../com/redmadrobot/inputmask/model/State.kt | 12 ++--- .../inputmask/model/state/EOLState.kt | 2 +- .../inputmask/model/state/FixedState.kt | 2 +- .../inputmask/model/state/FreeState.kt | 2 +- .../model/state/OptionalValueState.kt | 6 +-- .../inputmask/model/state/ValueState.kt | 16 +++---- 16 files changed, 91 insertions(+), 91 deletions(-) diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt index e81429e..a9e2152 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt @@ -208,7 +208,7 @@ open class NumberInputListener( val decimalSeparator = "." /** - * Create a `NumberInputListener` instance and assign it as a field's + * Create a ``NumberInputListener`` instance and assign it as a field's * `TextWatcher` and `onFocusChangeListener`. */ fun installOn( @@ -223,7 +223,7 @@ open class NumberInputListener( ) /** - * Create a `NumberInputListener` instance and assign it as a field's + * Create a ``NumberInputListener`` instance and assign it as a field's * `TextWatcher` and `onFocusChangeListener`. */ fun installOn( diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt index a0549aa..f1587a4 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/PhoneInputListener.kt @@ -11,7 +11,7 @@ import com.redmadrobot.inputmask.model.Notation /** * ### PhoneInputListener * - * A ```MaskedTextInputListener``` subclass for guessing a country based on the entered digit sequence + * A ``MaskedTextInputListener`` subclass for guessing a country based on the entered digit sequence * * Computed country dictates the phone formatting */ @@ -79,17 +79,17 @@ open class PhoneInputListener( ) /** - * A detected ```Country``` based on the entered digits + * A detected ``Country`` based on the entered digits */ var computedCountry: Country? = null /** - * A list of possible ```Country``` candidates based on the entered digits + * A list of possible ``Country`` candidates based on the entered digits */ var computedCountries: List = listOf() /** - * Allowed ```Country``` list. Pre-filters the ```Country::all``` dictionary. + * Allowed ``Country`` list. Pre-filters the ``Country::all`` dictionary. * * May contain country names, native country names, ISO-3166 codes, country emojis, or their mix. * @@ -105,7 +105,7 @@ open class PhoneInputListener( var enableCountries: List? = null /** - * Blocked ```Country``` list. Pre-filters the ```Country::all``` dictionary. + * Blocked ``Country`` list. Pre-filters the ``Country::all`` dictionary. * * May contain country names, native country names, ISO-3166 codes, country emojis, or their mix. * @@ -121,7 +121,7 @@ open class PhoneInputListener( var disableCountries: List? = null /** - A custom ```Country``` list to be used instead of ```Country::all``` dictionary. + A custom ``Country`` list to be used instead of ``Country::all`` dictionary. */ var customCountries: List? = null @@ -142,7 +142,7 @@ open class PhoneInputListener( companion object { /** - * Create a `PhoneInputListener` instance and assign it as a field's + * Create a ``PhoneInputListener`` instance and assign it as a field's * `TextWatcher` and `onFocusChangeListener`. */ fun installOn( @@ -157,7 +157,7 @@ open class PhoneInputListener( ) /** - * Create a `PhoneInputListener` instance and assign it as a field's + * Create a ``PhoneInputListener`` instance and assign it as a field's * `TextWatcher` and `onFocusChangeListener`. */ fun installOn( diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/AffinityCalculationStrategy.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/AffinityCalculationStrategy.kt index a8815d9..6b10358 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/AffinityCalculationStrategy.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/AffinityCalculationStrategy.kt @@ -11,7 +11,7 @@ enum class AffinityCalculationStrategy { /** * Default strategy. * - * Uses ```Mask``` built-in mechanism to calculate total affinity between the text and the mask format. + * Uses ``Mask`` built-in mechanism to calculate total affinity between the text and the mask format. * * For example: * ``` diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/CaretStringIterator.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/CaretStringIterator.kt index 017c5b6..2d7051a 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/CaretStringIterator.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/CaretStringIterator.kt @@ -5,10 +5,10 @@ import com.redmadrobot.inputmask.model.CaretString /** * ### CaretStringIterator * - * Iterates over CaretString.string characters. Each ```next()``` call returns current character and + * Iterates over CaretString.string characters. Each `next()` call returns current character and * adjusts iterator position. * - * ```CaretStringIterator``` is used by the ```Mask``` instance to iterate over the string that + * ``CaretStringIterator`` is used by the ``Mask`` instance to iterate over the string that * should be formatted. * * @author taflanidi diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Compiler.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Compiler.kt index 45bf076..9a41458 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Compiler.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Compiler.kt @@ -8,27 +8,27 @@ import com.redmadrobot.inputmask.model.state.* * ### Compiler * * Creates a sequence of states from the mask format string. - * @see ```State``` class. + * @see ``State`` class. * - * @complexity ```O(formatString.characters.count)``` plus ```FormatSanitizer``` complexity. + * @complexity `O(formatString.characters.count)` plus ``FormatSanitizer`` complexity. * - * @requires Format string to contain only flat groups of symbols in ```[]``` and ```{}``` brackets - * without nested brackets, like ```[[000]99]```. Also, ```[…]``` groups may contain only the - * specified characters ("0", "9", "A", "a", "…", "_" and "-"). Square bracket ```[]``` groups cannot + * @requires Format string to contain only flat groups of symbols in `[]` and `{}` brackets + * without nested brackets, like `[[000]99]`. Also, `[…]` groups may contain only the + * specified characters ("0", "9", "A", "a", "…", "_" and "-"). Square bracket `[]` groups cannot * contain mixed types of symbols ("0" and "9" with "A" and "a" or "_" and "-"). * - * ```Compiler``` object is initialized and ```Compiler.compile(formatString:)``` is called during - * the ```Mask``` instance initialization. + * ``Compiler`` object is initialized and ``Compiler.compile(formatString:)`` is called during + * the ``Mask`` instance initialization. * - * ```Compiler``` uses ```FormatSanitizer``` to prepare ```formatString``` for the compilation. + * ``Compiler`` uses ``FormatSanitizer`` to prepare `formatString` for the compilation. * * @author taflanidi */ class Compiler( /** - * A list of custom rules to compile square bracket ```[]``` groups of format symbols. + * A list of custom rules to compile square bracket `[]` groups of format symbols. * - * @see ```Notation``` class. + * @see ``Notation`` class. */ private val customNotations: List ) { @@ -36,20 +36,20 @@ class Compiler( /** * ### FormatError * - * Compiler error exception type, thrown when ```formatString``` contains inappropriate + * Compiler error exception type, thrown when `formatString` contains inappropriate * character sequences. * - * ```FormatError``` is used by the ```Compiler``` and ```FormatSanitizer``` classes. + * ``FormatError`` is used by the ``Compiler`` and ``FormatSanitizer`` classes. */ class FormatError : Exception() /** - * Compile ```formatString``` into the sequence of states. + * Compile `formatString` into the sequence of states. * - * * "Free" characters from ```formatString``` are converted to ```FreeState```-s. - * * Characters in square brackets are converted to ```ValueState```-s and ```OptionalValueState```-s. - * * Characters in curly brackets are converted to ```FixedState```-s. - * * End of the formatString line makes ```EOLState```. + * * "Free" characters from `formatString` are converted to ``FreeState``-s. + * * Characters in square brackets are converted to ``ValueState``-s and ``OptionalValueState``-s. + * * Characters in curly brackets are converted to ``FixedState``-s. + * * End of the formatString line makes ``EOLState``. * * For instance, * @@ -74,17 +74,17 @@ class Compiler( * * @param formatString string with a mask format. * - * @see ```State``` class. + * @see ``State`` class. * - * @complexity ```O(formatString.characters.count)``` plus ```FormatSanitizer``` complexity. + * @complexity `O(formatString.characters.count)` plus ``FormatSanitizer`` complexity. * - * @requires: Format string to contain only flat groups of symbols in ```[]``` and ```{}``` brackets - * without nested brackets, like ```[[000]99]```. Also, ```[…]``` groups may contain only the + * @requires: Format string to contain only flat groups of symbols in `[]` and `{}` brackets + * without nested brackets, like `[[000]99]`. Also, `[…]` groups may contain only the * specified characters ("0", "9", "A", "a", "…", "_" and "-"). * - * @returns Initialized ```State``` object with assigned ```State.child``` chain. + * @returns Initialized ``State`` object with assigned ``State.child`` chain. * - * @throws ```FormatError``` if ```formatString``` does not conform to the method requirements. + * @throws ``FormatError`` if `formatString` does not conform to the method requirements. */ @Throws(FormatError::class) fun compile(formatString: String): State { diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/FormatSanitizer.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/FormatSanitizer.kt index 7c2b45e..74e830d 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/FormatSanitizer.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/FormatSanitizer.kt @@ -5,28 +5,28 @@ import java.util.* /** * ### FormatSanitizer * - * Sanitizes given ```formatString``` before it's compilation. + * Sanitizes given `formatString` before it's compilation. * - * @complexity ```O(2*floor(log(n)))```, and switches to ```O(n^2)``` for ```n < 20``` where - * ```n = formatString.characters.count``` + * @complexity `O(2*floor(log(n)))`, and switches to `O(n^2)` for `n < 20` where + * `n = formatString.characters.count` * - * @requires Format string to contain only flat groups of symbols in ```[]``` and ```{}``` brackets - * without nested brackets, like ```[[000]99]```. Square bracket ```[]``` groups may contain mixed + * @requires Format string to contain only flat groups of symbols in `[]` and `{}` brackets + * without nested brackets, like `[[000]99]`. Square bracket `[]` groups may contain mixed * types of symbols ("0" and "9" with "A" and "a" or "_" and "-"), which sanitizer will divide into - * separate groups. Such that, ```[0000Aa]``` group will be divided in two groups: ```[0000]``` - * and ```[Aa]```. + * separate groups. Such that, `[0000Aa]` group will be divided in two groups: `[0000]` + * and `[Aa]`. * - * ```FormatSanitizer``` is used by ```Compiler``` before format string compilation. + * ``FormatSanitizer`` is used by ``Compiler`` before format string compilation. * * @author taflanidi */ class FormatSanitizer { /** - * Sanitize ```formatString``` before compilation. + * Sanitize `formatString` before compilation. * * In order to do so, sanitizer splits the string into groups of regular symbols, symbols in square - * brackets [] and symbols in curly brackets {}. Then, characters in square brackets are sorted in + * brackets `[]` and symbols in curly brackets `{}`. Then, characters in square brackets are sorted in * a way that mandatory symbols go before optional symbols. For instance, * * ``` @@ -39,22 +39,22 @@ class FormatSanitizer { * a ([0099]) b * ``` * - * Also, ellipsis in square brackets [] is always placed at the end. + * Also, ellipsis in square brackets `[]` is always placed at the end. * - * @complexity ```O(2*floor(log(n)))```, and switches to ```O(n^2)``` for ```n < 20``` where - * ```n = formatString.characters.count``` + * @complexity `O(2*floor(log(n)))`, and switches to `O(n^2)` for `n < 20` where + * `n = formatString.characters.count` * - * @requires Format string to contain only flat groups of symbols in ```[]``` and ```{}``` brackets - * without nested brackets, like ```[[000]99]```. Square bracket ```[]``` groups may contain mixed + * @requires Format string to contain only flat groups of symbols in `[]` and `{}` brackets + * without nested brackets, like `[[000]99]`. Square bracket `[]` groups may contain mixed * types of symbols ("0" and "9" with "A" and "a" or "_" and "-"), which sanitizer will divide into - * separate groups. Such that, ```[0000Aa]``` group will be divided in two groups: ```[0000]``` - * and ```[Aa]```. + * separate groups. Such that, `[0000Aa]` group will be divided in two groups: `[0000]` + * and `[Aa]`. * * @param formatString: mask format string. * * @returns Sanitized format string. * - * @throws ```FormatError``` if ```formatString``` does not conform to the method requirements. + * @throws ``FormatError`` if `formatString` does not conform to the method requirements. */ @Throws(Compiler.FormatError::class) fun sanitize(formatString: String): String { diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt index 04a2707..ddc7242 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/Mask.kt @@ -13,10 +13,10 @@ import java.util.* * Iterates over user input. Creates formatted strings from it. Extracts value specified by mask * format. * - * Provided mask format string is translated by the ```Compiler``` class into a set of states, which + * Provided mask format string is translated by the ``Compiler`` class into a set of states, which * define the formatting and value extraction. * - * @see ```Compiler```, ```State``` and ```CaretString``` classes. + * @see ``Compiler``, ``State`` and ``CaretString`` classes. * * @author taflanidi */ @@ -70,11 +70,11 @@ open class Mask(format: String, protected val customNotations: List) { /** * Factory constructor. * - * Operates over own ```Mask``` cache where initialized ```Mask``` objects are stored under + * Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under * corresponding format key: - * ```[format : mask]``` + * `[format : mask]` * - * @returns Previously cached ```Mask``` object for requested format string. If such it + * @returns Previously cached ``Mask`` object for requested format string. If such it * doesn't exist in cache, the object is constructed, cached and returned. */ fun getOrCreate(format: String, customNotations: List): Mask { @@ -90,10 +90,10 @@ open class Mask(format: String, protected val customNotations: List) { * Check your mask format is valid. * * @param format mask format. - * @param customNotations a list of custom rules to compile square bracket ```[]``` groups of format symbols. + * @param customNotations a list of custom rules to compile square bracket `[]` groups of format symbols. * - * @returns ```true``` if this format coupled with custom notations will compile into a working ```Mask``` object. - * Otherwise ```false```. + * @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object. + * Otherwise `false`. */ fun isValid(format: String, customNotations: List): Boolean { return try { @@ -365,10 +365,10 @@ open class Mask(format: String, protected val customNotations: List) { * While scanning through the input string in the `.apply(…)` method, the mask builds a graph of * autocompletion steps. * - * This graph accumulates the results of `.autocomplete()` calls for each consecutive `State`, - * acting as a `stack` of `Next` object instances. + * This graph accumulates the results of `.autocomplete()` calls for each consecutive ``State``, + * acting as a `stack` of ``Next`` object instances. * - * Each time the `State` returns `null` for its `.autocomplete()`, the graph resets empty. + * Each time the ``State`` returns `null` for its `.autocomplete()`, the graph resets empty. */ private class AutocompletionStack : Stack() { override fun push(item: Next?): Next? { diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/RTLMask.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/RTLMask.kt index 16c2b49..b8ed0f2 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/RTLMask.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/helper/RTLMask.kt @@ -7,7 +7,7 @@ import java.util.HashMap /** * ### RTLMask * - * A right-to-left ```Mask``` subclass. Applies format from the string end. + * A right-to-left ``Mask`` subclass. Applies format from the string end. */ class RTLMask(format: String, customNotations: List) : Mask(reversedFormat(format), customNotations) { companion object Factory { diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt index b72ef0e..3a40769 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt @@ -3,7 +3,7 @@ package com.redmadrobot.inputmask.model /** * ### Country * - * Model object representing a **Country** record operated by the ```PhoneInputListener```. + * Model object representing a **Country** record operated by the ``PhoneInputListener``. */ data class Country( /** @@ -37,12 +37,12 @@ data class Country( val countryCode: String, /** - * Primary ```Mask``` format for the country phone numbers. + * Primary ``Mask`` format for the country phone numbers. */ val primaryFormat: String, /** - * Affine ```Mask``` formats for the country phone numbers. + * Affine ``Mask`` formats for the country phone numbers. */ val affineFormats: List, @@ -93,7 +93,7 @@ data class Country( } /** - A ```Country``` dictionary. + A ``Country`` dictionary. Feel free to append/correct & file PRs, see https://countrycode.org */ diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Next.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Next.kt index 4971101..048fc8e 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Next.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Next.kt @@ -4,7 +4,7 @@ package com.redmadrobot.inputmask.model * ### Next * * Model object that represents a set of actions that should take place when transition from one - * ```State``` to another occurs. + * ``State`` to another occurs. * * @author taflanidi */ diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/State.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/State.kt index e3dfbed..50a1724 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/State.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/State.kt @@ -18,7 +18,7 @@ abstract class State(val child: State?) { * * @param character character from the user input string. * - * @returns ```Next``` object instance with a set of actions that should take place when the user + * @returns ``Next`` object instance with a set of actions that should take place when the user * input character is accepted. * * @throws Fatal error, if the method is not implemented. @@ -28,8 +28,8 @@ abstract class State(val child: State?) { /** * Automatically complete user input. * - * @returns ```Next``` object instance with a set of actions to complete user input. If no - * autocomplete available, returns ```nil```. + * @returns ``Next`` object instance with a set of actions to complete user input. If no + * autocomplete available, returns `null`. */ open fun autocomplete(): Next? { return null @@ -38,10 +38,10 @@ abstract class State(val child: State?) { /** * Obtain the next state. * - * Sometimes it is necessary to override this behavior. For instance, ```State``` may want to - * return ```self``` as the next state under certain conditions. + * Sometimes it is necessary to override this behavior. For instance, ``State`` may want to + * return ``self`` as the next state under certain conditions. * - * @returns ```State``` object. + * @returns ``State`` object. */ open fun nextState(): State { return this.child!! diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/EOLState.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/EOLState.kt index cc4d667..24f8b6b 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/EOLState.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/EOLState.kt @@ -8,7 +8,7 @@ import com.redmadrobot.inputmask.model.State * * End-of-line state. Serves as mask format terminator character. * - * Does not accept any character. Always returns ```self``` as the next state, ignoring the child + * Does not accept any character. Always returns `self` as the next state, ignoring the child * state given during initialization. * * @author taflanidi diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FixedState.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FixedState.kt index 84a6a7a..e5a84a6 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FixedState.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FixedState.kt @@ -6,7 +6,7 @@ import com.redmadrobot.inputmask.model.State /** * ### FixedState * - * Represents characters in curly braces {}. + * Represents characters in curly braces `{}`. * * Accepts every character but does not put it into the result string, unless the character equals * the one from the mask format. If it's not, inserts the symbol from the mask format into the diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FreeState.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FreeState.kt index 1bf61b9..8c0a12b 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FreeState.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/FreeState.kt @@ -12,7 +12,7 @@ import com.redmadrobot.inputmask.model.State * the one from the mask format. If it's not, inserts the symbol from the mask format into the * result. * - * Always returns ```nil``` as an extracted value, does not affect the resulting value. + * Always returns `null` as an extracted value, does not affect the resulting value. * * @author taflanidi */ diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/OptionalValueState.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/OptionalValueState.kt index cdff87e..85ffa86 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/OptionalValueState.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/OptionalValueState.kt @@ -6,14 +6,14 @@ import com.redmadrobot.inputmask.model.State /** * ### OptionalValueState * - * Represents optional characters in square brackets []. + * Represents optional characters in square brackets `[]`. * * Accepts any characters, but puts into the result string only the characters of own type - * (see ```StateType```). + * (see ``StateType``). * * Returns accepted characters of own type as an extracted value. * - * @see ```OptionalValueState.StateType``` + * @see ``OptionalValueState.StateType`` * * @author taflanidi */ diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/ValueState.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/ValueState.kt index de698f2..42326bf 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/ValueState.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/state/ValueState.kt @@ -6,14 +6,14 @@ import com.redmadrobot.inputmask.model.State /** * ### ValueState * - * Represents mandatory characters in square brackets []. + * Represents mandatory characters in square brackets `[]`. * - * Accepts only characters of own type (see ```StateType```). Puts accepted characters into the + * Accepts only characters of own type (see ``StateType``). Puts accepted characters into the * result string. * * Returns accepted characters as an extracted value. * - * @see ```ValueState.StateType``` + * @see ``ValueState.StateType`` * * @author taflanidi */ @@ -22,10 +22,10 @@ class ValueState : State { /** * ### StateType * - * ```Numeric``` stands for [9] characters - * ```Literal``` stands for [a] characters - * ```AlphaNumeric``` stands for [-] characters - * ```Ellipsis``` stands for […] characters + * `Numeric` stands for `[9]` characters + * `Literal` stands for `[a]` characters + * `AlphaNumeric` stands for `[-]` characters + * `Ellipsis` stands for `[…]` characters */ sealed class StateType { class Numeric : StateType() @@ -38,7 +38,7 @@ class ValueState : State { val type: StateType /** - * Constructor for elliptical ```ValueState``` + * Constructor for elliptical ``ValueState`` */ constructor(inheritedType: StateType) : super(null) { this.type = StateType.Ellipsis(inheritedType) From 99e153aa84fb9917b0cdd6c29e8c12e002b7eafa Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 10 Apr 2023 19:54:47 +0400 Subject: [PATCH 15/32] Tidy up layout --- app/src/main/res/layout/activity_main.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 0fa43b0..cd20091 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -9,6 +9,7 @@ Date: Mon, 10 Apr 2023 19:55:23 +0400 Subject: [PATCH 16/32] Update README --- README.md | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index e647eb7..91cee6b 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,20 @@ [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) -Input masks restrict data input and allow you to guide users to enter correct values. -Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for quick start and further reading. - -## ⚙️ Features - -- Apply formatting to your text fields, see [examples](#examples) -- Filter out nonessential symbols (e.g. extract `0123456` from `+1 (999) 012-34-56`) -- For international phone numbers - - guess the country from the entered digits - - apply corresponding value restrictions (e.g. a 🇺🇸US phone will have a format like `+1 201 456-7890`) - - - +Input masks restrict data input and allow you to guide users to enter correct values. +Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for quick start and further reading. + +## ⚙️ Features + +- Apply formatting to your text fields, see [examples](#examples) +- Filter out nonessential symbols (e.g. extract `0123456` from `+1 (999) 012-34-56`) +- For international phone numbers + - guess the country from the entered digits + - apply corresponding value restrictions (e.g. a 🇺🇸US phone will have a format like `+1 201 456-7890`) +- Apply number/currency formatting + + + ## 💳 Examples - Phone numbers: `+1 ([000]) [000] [00] [00]` @@ -24,10 +25,10 @@ Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for - Visa/MasterCard numbers: `[0000] [0000] [0000] [0000]` - UK IBAN: `GB[00] [____] [0000] [0000] [0000] [00]` - - -## 🛠️ Installation - + + +## 🛠️ Installation + ### Gradle Make sure you've added Kotlin support to your project. @@ -38,7 +39,7 @@ repositories { } dependencies { - implementation 'com.redmadrobot:input-mask-android:6.1.0' + implementation 'com.redmadrobot:input-mask-android:7.1.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:$latest_version' } @@ -54,7 +55,7 @@ Should you have any questions, please search for closed [issues](https://github. -## ❗Known issues +## ❗Known issues ## InputMask vs. `NoClassDefFoundError` @@ -135,4 +136,4 @@ These folks rock: ## ♻️ License -The library is distributed under the MIT [LICENSE](https://github.com/RedMadRobot/input-mask-android/blob/master/LICENSE). +The library is distributed under the MIT [LICENSE](https://github.com/RedMadRobot/input-mask-android/blob/master/LICENSE). From 266497350b37a4df016bc736205cde2f33cb9a3c Mon Sep 17 00:00:00 2001 From: taflanidi Date: Tue, 11 Apr 2023 11:42:39 +0400 Subject: [PATCH 17/32] Update CHANGELOG --- CHANGELOG.md | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17ba06d..cd3d025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,47 +1,55 @@ # Changelog -### `6.1.0` +## 7.1.0 -#### Removed: +**⤵️ Added:** -* `IndexOutOfBoundsException` +* New logo :D +* New README :D +* Text listener callbacks now return a `tailPlaceholder` for the value to be completed +* `Country`: a model object representing a country with phone formatting, ISO codes & emojis +* `Country.all`: a dictionary of known countries +* `PhoneInputListener`: a `MaskedTextChangedListener` allowing to enter a phone number of any known country +* `NumberInputListener`: a `MaskedTextChangedListener` allowing to enter currencies and other numbers -HUZZAH! +**🔄 Modified:** -#### Modified: +* `minSdkVersion` → `30` -(none) +## 6.1.0 -#### Added: +**⤴️ Removed:** -* `IndexOutOfBoundsException` with a link to docs +* `IndexOutOfBoundsException` + +HUZZAH! -### `6.0.0` +## 6.0.0 -#### Removed: +**⤴️ Removed:** * `Mask::apply()`, the `autocomplete` flag This flag is now a part of the `CaretGravity.FORWARD`. -#### Modified: +**🔄 Modified:** * `CaretGravity` is now a sealed class -#### Added: +**⤵️ Added:** * `CaretGravity.FORWARD`, the `autocomplete` flag * `CaretGravity.BACKWARD`, the [`autoskip`](https://github.com/RedMadRobot/input-mask-android/wiki/0.-Mask#autoskip-flag) flag -### `5.0.0` +## 5.0.0 -#### Removed: +**⤴️ Removed:** * `CaretStringIterator::beforeCaret()` This method is now replaced with `::insertionAffectsCaret()` and `::deletionAffectsCaret()` calls. -#### Added: +**⤵️ Added:** * `CaretString` instances now contain caret gravity. @@ -55,26 +63,26 @@ These methods allow to incorporate new caret gravity setting. * Right-to-left masks. -### `4.3.0` +## 4.3.0 -#### Added: +**⤵️ Added:** * `AffinityCalculationStrategy.EXTRACTED_VALUE_CAPACITY` option allowing to have radically different mask format depending on the extracted value length -### `4.2.0` +## 4.2.0 -#### Added: +**⤵️ Added:** * `AffinityCalculationStrategy.CAPACITY` affinity calculation option allowing to have radically different mask format depending on the input length -### `4.1.0` +## 4.1.0 -#### Added: +**⤵️ Added:** * `formattedText` to `MaskedTextChangedListener.ValueListener::onTextChanged` * by [Nikita Barishok](https://github.com/nbarishok) in [PR#73](https://github.com/RedMadRobot/input-mask-android/pull/73) * `Mask::isValid(format:customNotations:)` method for format checks -#### Fixed: +**🔄 Fixed:** * Optional blocks of symbols are now ignored when extracted value completeness is calculated, see [#70](https://github.com/RedMadRobot/input-mask-android/issues/70) From b9587031f278f371ab8a9b608ea2cf766ed36cee Mon Sep 17 00:00:00 2001 From: Egor Taflanidi <6849363+taflanidi@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:10:41 +0400 Subject: [PATCH 18/32] add: gradle build w/ android.yml --- .github/workflows/android.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/android.yml diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 0000000..e519f16 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,26 @@ +name: Android CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build From 2af5e6a2b366d584c95f25753aae411b9fb6ebfd Mon Sep 17 00:00:00 2001 From: Egor Taflanidi <6849363+taflanidi@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:17:12 +0400 Subject: [PATCH 19/32] add: build status to the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91cee6b..e828ce8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Input Mask -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Actions](https://img.shields.io/github/actions/workflow/status/RedMadRobot/input-mask-android/android.yml?style=for-the-badge)](https://github.com/RedMadRobot/input-mask-android/actions/workflows/android.yml) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) Input masks restrict data input and allow you to guide users to enter correct values. Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for quick start and further reading. From b83cfcd59f86f1a9dc964bd2354f4e66a21f5177 Mon Sep 17 00:00:00 2001 From: Egor Taflanidi <6849363+taflanidi@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:33:56 +0400 Subject: [PATCH 20/32] Update README.md, mention iOS version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e828ce8..3737549 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Input Mask -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Actions](https://img.shields.io/github/actions/workflow/status/RedMadRobot/input-mask-android/android.yml?style=for-the-badge)](https://github.com/RedMadRobot/input-mask-android/actions/workflows/android.yml) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Actions](https://img.shields.io/github/actions/workflow/status/RedMadRobot/input-mask-android/android.yml?style=for-the-badge)](https://github.com/RedMadRobot/input-mask-android/actions/workflows/android.yml) [![iOS Version](https://img.shields.io/badge/-ios_version-red?color=teal&logo=ios&style=for-the-badge)](https://github.com/RedMadRobot/input-mask-ios) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license) Input masks restrict data input and allow you to guide users to enter correct values. Check out our [wiki](https://github.com/RedMadRobot/input-mask-android/wiki) for quick start and further reading. From d70533b92a4088350f7269a8ecfcca3ca96af65c Mon Sep 17 00:00:00 2001 From: taflanidi Date: Sun, 16 Apr 2023 18:27:29 +0400 Subject: [PATCH 21/32] Tune down min sdk to 23 --- CHANGELOG.md | 6 ++++++ app/build.gradle | 2 +- gradle.properties | 13 +++++++------ gradle/dependencies.gradle | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 6 +++--- inputmask/build.gradle | 1 + .../redmadrobot/inputmask/NumberInputListener.kt | 3 +++ 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3d025..70d6818 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 7.1.1 + +**🔄 Modified:** + +* `minSdkVersion` → `23` + ## 7.1.0 **⤵️ Added:** diff --git a/app/build.gradle b/app/build.gradle index 6463398..0923f81 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - buildToolsVersion '30.0.2' + buildToolsVersion '30.0.3' } dependencies { diff --git a/gradle.properties b/gradle.properties index c1c84d8..7e44f54 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,16 +1,17 @@ -# 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 +## 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. -# Default value: -Xmx10248m -XX:MaxPermSize=256m +# Default value: -Xmx1024m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +# # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +#Sun Apr 16 18:25:25 GET 2023 +org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" android.enableJetifier=true android.useAndroidX=true +org.gradle.unsafe.configuration-cache=true diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index f300567..df20384 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -8,7 +8,7 @@ ext.addRepos = this.&addRepos //region Build versions def build_versions = [:] -build_versions.min_sdk = 30 +build_versions.min_sdk = 23 build_versions.target_sdk = 33 build_versions.compile_sdk = 33 @@ -23,7 +23,7 @@ def deps = [:] //region Gradle def gradle = [:] -versions.android_plugin = "7.0.2" +versions.android_plugin = "7.4.2" gradle.android_plugin = "com.android.tools.build:gradle:$versions.android_plugin" @@ -33,7 +33,7 @@ deps.gradle = gradle //region Kotlin def kotlin = [:] -versions.kotlin = "1.5.21" +versions.kotlin = "1.8.0" versions.dokka = "0.9.18" kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e116f51..8609c62 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Sep 25 23:02:38 MSK 2021 +#Sun Apr 16 18:05:37 GET 2023 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +zipStoreBase=GRADLE_USER_HOME diff --git a/inputmask/build.gradle b/inputmask/build.gradle index 5abbd69..e6a09ea 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -48,6 +48,7 @@ android { dependencies { implementation deps.kotlin.stdlib + implementation 'androidx.annotation:annotation:1.6.0' testImplementation deps.test.junit } diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt index a9e2152..89eaa71 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt @@ -3,8 +3,10 @@ package com.redmadrobot.inputmask import android.icu.number.LocalizedNumberFormatter import android.icu.number.NumberFormatter import android.icu.number.Precision +import android.os.Build import android.text.TextWatcher import android.widget.EditText +import androidx.annotation.RequiresApi import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy import com.redmadrobot.inputmask.helper.Mask import com.redmadrobot.inputmask.model.CaretString @@ -28,6 +30,7 @@ import java.util.* * * - seealso: the ``NumberInputListener/formatter`` field */ +@RequiresApi(Build.VERSION_CODES.R) open class NumberInputListener( primaryFormat: String, affineFormats: List = emptyList(), From 2074a50171c01e3452352214f44c92876d164315 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 19:10:05 +0400 Subject: [PATCH 22/32] Re-assemble the library project --- app/build.gradle | 39 ++-- app/proguard-rules.pro | 16 +- .../sample/SampleInstrumentedTest.kt | 70 ++++++++ app/src/main/AndroidManifest.xml | 14 +- .../com/redmadrobot/sample/MainActivity.java | 146 --------------- .../com/redmadrobot/sample/MainActivity.kt | 137 ++++++++++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 ++++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 9 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../res/mipmap-anydpi-v33/ic_launcher.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3418 -> 0 bytes app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2206 -> 0 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4842 -> 0 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 7718 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes app/src/main/res/values-night/themes.xml | 16 ++ app/src/main/res/values/colors.xml | 10 ++ app/src/main/res/values/strings.xml | 2 +- app/src/main/res/values/styles.xml | 8 - app/src/main/res/values/themes.xml | 16 ++ build.gradle | 29 +-- gradle.properties | 24 ++- gradle/dependencies.gradle | 73 -------- gradle/version.gradle | 21 --- gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 117 +++++++----- gradlew.bat | 53 +++--- inputmask/build.gradle | 77 ++++---- inputmask/consumer-rules.pro | 0 inputmask/proguard-rules.pro | 16 +- inputmask/src/main/AndroidManifest.xml | 3 +- .../inputmask/NumberInputListener.kt | 13 +- settings.gradle | 19 +- version.properties | 4 - 46 files changed, 703 insertions(+), 447 deletions(-) create mode 100644 app/src/androidTest/java/com/redmadrobot/sample/SampleInstrumentedTest.kt delete mode 100644 app/src/main/java/com/redmadrobot/sample/MainActivity.java create mode 100644 app/src/main/java/com/redmadrobot/sample/MainActivity.kt create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml delete mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/values/themes.xml delete mode 100644 gradle/dependencies.gradle delete mode 100644 gradle/version.gradle create mode 100644 inputmask/consumer-rules.pro delete mode 100644 version.properties diff --git a/app/build.gradle b/app/build.gradle index 0923f81..709fd3c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,27 +1,44 @@ -apply plugin: 'com.android.application' +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} android { - compileSdkVersion 33 + namespace 'com.redmadrobot.sample' + compileSdk 33 defaultConfig { applicationId "com.redmadrobot.sample" - minSdkVersion 30 - targetSdkVersion 33 + minSdk 30 + targetSdk 33 versionCode 1 versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - buildToolsVersion '30.0.3' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } } dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation deps.kotlin.stdlib - implementation 'androidx.appcompat:appcompat:1.4.0' - implementation project(':inputmask') -} + implementation project(":inputmask") + implementation 'androidx.core:core-ktx:1.10.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.8.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 3ee60e8..481bb43 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,17 +1,21 @@ # Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/maximefimov/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. +# 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 -# Add any project specific keep options here: - # 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 \ No newline at end of file diff --git a/app/src/androidTest/java/com/redmadrobot/sample/SampleInstrumentedTest.kt b/app/src/androidTest/java/com/redmadrobot/sample/SampleInstrumentedTest.kt new file mode 100644 index 0000000..1cdacf4 --- /dev/null +++ b/app/src/androidTest/java/com/redmadrobot/sample/SampleInstrumentedTest.kt @@ -0,0 +1,70 @@ +package com.redmadrobot.sample + +import android.view.View +import android.widget.EditText +import android.widget.TextView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.typeText +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.ActivityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.TypeSafeMatcher +import org.junit.Assert.* +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Sample app UI tests. + * + * @author taflanidi + */ +@RunWith(AndroidJUnit4::class) +class SampleInstrumentedTest { + @get: Rule + var activityRule = ActivityScenarioRule(MainActivity::class.java) + + @Test + fun testCurrencyField_enter12345point678_showsDollar12comma345point678() { + onView(withId(R.id.currency_edit_text)) + .perform(typeText("12345.678")) + .check(matches(hasValueEqualTo("$12,345.678"))) + } + + @Test + fun testDateField_enter1point021989_shows1point02point1989() { + onView(withId(R.id.date_edit_text)) + .perform(typeText("1.021989")) + .check(matches(hasValueEqualTo("1.02.1989"))) + } + + @Test + fun testPhoneField_enter38123456789_showsPlus380SpaceBracket12SpaceBracketSpace345Dash67Dash89() { + onView(withId(R.id.phone_edit_text)) + .perform(typeText("381234567890")) + .check(matches(hasValueEqualTo("+380 (12) 345-67-89"))) + } + + private fun hasValueEqualTo(content: String): Matcher? { + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("Has EditText/TextView the value: $content") + } + + override fun matchesSafely(view: View?): Boolean { + if (view !is TextView && view !is EditText) { + return false + } + val text: String = if (view is TextView) { + view.text.toString() + } else { + (view as EditText).text.toString() + } + return text.equals(content, ignoreCase = true) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 25cfaa2..11f0fd8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,13 +1,16 @@ - + + - - + @@ -15,7 +18,6 @@ - diff --git a/app/src/main/java/com/redmadrobot/sample/MainActivity.java b/app/src/main/java/com/redmadrobot/sample/MainActivity.java deleted file mode 100644 index 3a79626..0000000 --- a/app/src/main/java/com/redmadrobot/sample/MainActivity.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.redmadrobot.sample; - -import android.graphics.Paint; -import android.graphics.Rect; -import android.icu.number.NumberFormatter; -import android.icu.util.Currency; -import android.os.Bundle; -import android.util.Log; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import com.redmadrobot.inputmask.MaskedTextChangedListener; -import com.redmadrobot.inputmask.NumberInputListener; -import com.redmadrobot.inputmask.PhoneInputListener; -import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy; -import com.redmadrobot.inputmask.model.Country; -import com.redmadrobot.inputmask.model.Notation; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Home screen for the sample app. - * - * @author taflanidi - */ -public final class MainActivity extends AppCompatActivity { - private PhoneInputListener listener = null; - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - setupCurrencySample(); - setupDateSample(); - setupPhoneSample(); - } - - private void setupCurrencySample() { - final EditText editText = findViewById(R.id.currency_edit_text); - final CheckBox checkBox = findViewById(R.id.currency_check_box); - - final NumberInputListener listener = NumberInputListener.Companion.installOn( - editText, - new MaskedTextChangedListener.ValueListener() { - @Override - public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { - logValueListener(maskFilled, extractedValue, formattedValue); - checkBox.setChecked(maskFilled); - } - } - ); - - listener.setFormatter( - listener.getFormatter().unit(Currency.getInstance("USD")) - ); - - editText.setHint(listener.placeholder()); - } - - private void setupDateSample() { - final EditText editText = findViewById(R.id.date_edit_text); - final CheckBox checkBox = findViewById(R.id.date_check_box); - final TextView placeholder = findViewById(R.id.date_placeholder_text_view); - - final MaskedTextChangedListener listener = MaskedTextChangedListener.Companion.installOn( - editText, - "[90].[90].[0000]", - new ArrayList(), - new ArrayList(), - AffinityCalculationStrategy.WHOLE_STRING, - true, - true, - null, - new MaskedTextChangedListener.ValueListener() { - @Override - public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { - logValueListener(maskFilled, extractedValue, formattedValue); - checkBox.setChecked(maskFilled); - - placeholder.setText(formattedValue.isEmpty() ? "" : tailPlaceholder); - - Rect textBounds = new Rect(); - Paint paint = placeholder.getPaint(); - paint.getTextBounds(formattedValue, 0, formattedValue.length(), textBounds); - int width = textBounds.width(); - - ViewGroup.MarginLayoutParams placeholderParams = (ViewGroup.MarginLayoutParams) placeholder.getLayoutParams(); - placeholderParams.setMarginStart(width + 16); // 16 is an empirical value - } - } - ); - - editText.setHint(listener.placeholder()); - } - - private void setupPhoneSample() { - final EditText editText = findViewById(R.id.phone_edit_text); - final CheckBox checkBox = findViewById(R.id.phone_check_box); - final TextView countriesTextView = findViewById(R.id.countries_text_view); - - listener = PhoneInputListener.Companion.installOn( - editText, - true, - false, - null, - new MaskedTextChangedListener.ValueListener() { - @Override - public void onTextChanged(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedValue, @NonNull String tailPlaceholder) { - logValueListener(maskFilled, extractedValue, formattedValue); - checkBox.setChecked(maskFilled); - - StringBuilder countriesList = new StringBuilder(); - if (listener != null) { - for (Country country: listener.getComputedCountries()) { - countriesList - .append(country.getCountryCode()) - .append(" ") - .append(country.getEmoji()) - .append(" ") - .append(country.getName()) - .append("\n"); - } - } - countriesTextView.setText(countriesList.toString()); - } - } - ); - - editText.setHint(listener.placeholder()); - } - - private void logValueListener(boolean maskFilled, @NonNull String extractedValue, @NonNull String formattedText) { - final String className = MainActivity.class.getSimpleName(); - Log.d(className, extractedValue); - Log.d(className, String.valueOf(maskFilled)); - Log.d(className, formattedText); - } - -} diff --git a/app/src/main/java/com/redmadrobot/sample/MainActivity.kt b/app/src/main/java/com/redmadrobot/sample/MainActivity.kt new file mode 100644 index 0000000..52cae4d --- /dev/null +++ b/app/src/main/java/com/redmadrobot/sample/MainActivity.kt @@ -0,0 +1,137 @@ +package com.redmadrobot.sample + +import android.graphics.Paint +import android.graphics.Rect +import android.icu.util.Currency +import android.os.Bundle +import android.util.Log +import android.view.ViewGroup.MarginLayoutParams +import android.widget.CheckBox +import android.widget.EditText +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.redmadrobot.inputmask.MaskedTextChangedListener.Companion.installOn +import com.redmadrobot.inputmask.MaskedTextChangedListener.ValueListener +import com.redmadrobot.inputmask.NumberInputListener +import com.redmadrobot.inputmask.PhoneInputListener +import com.redmadrobot.inputmask.helper.AffinityCalculationStrategy + +/** + * Home screen for the sample app. + * + * @author taflanidi + */ +class MainActivity : AppCompatActivity() { + private var listener: PhoneInputListener? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + setupCurrencySample() + setupDateSample() + setupPhoneSample() + } + + private fun setupCurrencySample() { + val editText = findViewById(R.id.currency_edit_text) + val checkBox = findViewById(R.id.currency_check_box) + val listener = NumberInputListener.installOn( + editText, + object : ValueListener { + override fun onTextChanged( + maskFilled: Boolean, + extractedValue: String, + formattedValue: String, + tailPlaceholder: String + ) { + logValueListener(maskFilled, extractedValue, formattedValue) + checkBox.isChecked = maskFilled + } + } + ) + listener.formatter = listener.formatter.unit(Currency.getInstance("USD")) + editText.hint = listener.placeholder() + } + + private fun setupDateSample() { + val editText = findViewById(R.id.date_edit_text) + val checkBox = findViewById(R.id.date_check_box) + val placeholder = findViewById(R.id.date_placeholder_text_view) + val listener = installOn( + editText, + "[90].[90].[0000]", + ArrayList(), + ArrayList(), + AffinityCalculationStrategy.WHOLE_STRING, + autocomplete = true, + autoskip = true, + listener = null, + valueListener = object : ValueListener { + override fun onTextChanged( + maskFilled: Boolean, + extractedValue: String, + formattedValue: String, + tailPlaceholder: String + ) { + logValueListener(maskFilled, extractedValue, formattedValue) + checkBox.isChecked = maskFilled + placeholder.text = if (formattedValue.isEmpty()) "" else tailPlaceholder + val textBounds = Rect() + val paint: Paint = placeholder.paint + paint.getTextBounds(formattedValue, 0, formattedValue.length, textBounds) + val width = textBounds.width() + val placeholderParams = placeholder.layoutParams as MarginLayoutParams + placeholderParams.marginStart = width + 16 // 16 is an empirical value + } + } + ) + editText.hint = listener.placeholder() + } + + private fun setupPhoneSample() { + val editText = findViewById(R.id.phone_edit_text) + val checkBox = findViewById(R.id.phone_check_box) + val countriesTextView = findViewById(R.id.countries_text_view) + listener = PhoneInputListener.installOn( + editText, + autocomplete = true, + autoskip = false, + listener = null, + valueListener = object : ValueListener { + override fun onTextChanged( + maskFilled: Boolean, + extractedValue: String, + formattedValue: String, + tailPlaceholder: String + ) { + logValueListener(maskFilled, extractedValue, formattedValue) + checkBox.isChecked = maskFilled + val countriesList = StringBuilder() + this@MainActivity.listener?.computedCountries?.forEach { country -> + countriesList + .append(country.countryCode) + .append(" ") + .append(country.emoji) + .append(" ") + .append(country.name) + .append("\n") + } + countriesTextView.text = countriesList.toString() + } + } + ) + editText.hint = listener?.placeholder() + } + + private fun logValueListener( + maskFilled: Boolean, + extractedValue: String, + formattedText: String + ) { + val className = MainActivity::class.java.simpleName + Log.d(className, extractedValue) + Log.d(className, maskFilled.toString()) + Log.d(className, formattedText) + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index cd20091..19d7d18 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ + tools:ignore="Autofill,LabelFor" /> + tools:ignore="Autofill,LabelFor" /> @@ -79,7 +79,8 @@ android:id="@+id/phone_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="phone" /> + android:inputType="phone" + tools:ignore="Autofill,LabelFor" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bcccec65160d92116f20ffce4fce0b5245c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3418 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 Kmw_-CKmY()leWbG literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..b2dfe3d1ba5cf3ee31b3ecc1ced89044a1f3b7a9 GIT binary patch literal 2898 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cbd379f5af6dbf1a899a0293ca5eccfad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2206 zcmZ{mc|6mPAICqNwJrBe)OTwlM~;a|Uz&T!k&1?zWA4p4M`7F7`J;wP4IvS^nJ7{y zAtgDMD>=W8<&GtU-}>|S$M5}kyxz~p>-~Pb{(irc?QF~icx8A201&Xin%Hxx@kekd zw>yHjlemC*8(JFz05gs6x7#7EM|xoGtpVVs0szqB0bqwaqAdVG7&rLc6#(=y0YEA! z=jFw}xeKVfmAMI*+}bv7qH=LK2#X5^06wul0s+}M(f|O@&WMyG9frlGyLb z&Eix=47rL84J+tEWcy_XTyc*xw9uOQy`qmHCjAeJ?d=dUhm;P}^F=LH42AEMIh6X8 z*I7Q1jK%gVlL|8w?%##)xSIY`Y+9$SC8!X*_A*S0SWOKNUtza(FZHahoC2|6f=*oD zxJ8-RZk!+YpG+J}Uqnq$y%y>O^@e5M3SSw^29PMwt%8lX^9FT=O@VX$FCLBdlj#<{ zJWWH<#iU!^E7axvK+`u;$*sGq1SmGYc&{g03Md&$r@btQSUIjl&yJXA&=79FdJ+D< z4K^ORdM{M0b2{wRROvjz1@Rb>5dFb@gfkYiIOAKM(NR3*1JpeR_Hk3>WGvU&>}D^HXZ02JUnM z@1s_HhX#rG7;|FkSh2#agJ_2fREo)L`ws+6{?IeWV(>Dy8A(6)IjpSH-n_uO=810y z#4?ez9NnERv6k)N13sXmx)=sv=$$i_QK`hp%I2cyi*J=ihBWZLwpx9Z#|s;+XI!0s zLjYRVt!1KO;mnb7ZL~XoefWU02f{jcY`2wZ4QK+q7gc4iz%d0)5$tPUg~$jVI6vFO zK^wG7t=**T40km@TNUK+WTx<1mL|6Tn6+kB+E$Gpt8SauF9E-CR9Uui_EHn_nmBqS z>o#G}58nHFtICqJPx<_?UZ;z0_(0&UqMnTftMKW@%AxYpa!g0fxGe060^xkRtYguj ze&fPtC!?RgE}FsE0*^2lnE>42K#jp^nJDyzp{JV*jU?{+%KzW37-q|d3i&%eooE6C8Z2t2 z9bBL;^fzVhdLxCQh1+Ms5P)ilz9MYFKdqYN%*u^ch(Fq~QJASr5V_=szAKA4Xm5M} z(Kka%r!noMtz6ZUbjBrJ?Hy&c+mHB{OFQ}=41Irej{0N90`E*~_F1&7Du+zF{Dky) z+KN|-mmIT`Thcij!{3=ibyIn830G zN{kI3d`NgUEJ|2If}J!?@w~FV+v?~tlo8ps3Nl`3^kI)WfZ0|ms6U8HEvD9HIDWkz6`T_QSewYZyzkRh)!g~R>!jaR9;K|#82kfE5^;R!~}H4C?q{1AG?O$5kGp)G$f%VML%aPD?{ zG6)*KodSZRXbl8OD=ETxQLJz)KMI7xjArKUNh3@0f|T|75?Yy=pD7056ja0W)O;Td zCEJ=7q?d|$3rZb+8Cvt6mybV-#1B2}Jai^DOjM2<90tpql|M5tmheg){2NyZR}x3w zL6u}F+C-PIzZ56q0x$;mVJXM1V0;F}y9F29ob51f;;+)t&7l30gloMMHPTuod530FC}j^4#qOJV%5!&e!H9#!N&XQvs5{R zD_FOomd-uk@?_JiWP%&nQ_myBlM6so1Ffa1aaL7B`!ZTXPg_S%TUS*>M^8iJRj1*~ e{{%>Z1YfTk|3C04d;8A^0$7;Zm{b|L#{L(;l>}-4 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..4f0f1d64e58ba64d180ce43ee13bf9a17835fbca GIT binary patch literal 982 zcmV;{11bDcNk&G_0{{S5MM6+kP&il$0000G0000l001ul06|PpNU8t;00Dqo+t#w^ z^1csucXz7-Qrhzl9HuHB%l>&>1tG2^vb*E&k^T3$FG1eQZ51g$uv4V+kI`0<^1Z@N zk?Jjh$olyC%l>)Xq;7!>{iBj&BjJ`P&$fsCfpve_epJOBkTF?nu-B7D!hO=2ZR}

C%4 zc_9eOXvPbC4kzU8YowIA8cW~Uv|eB&yYwAObSwL2vY~UYI7NXPvf3b+c^?wcs~_t{ ze_m66-0)^{JdOMKPwjpQ@Sna!*?$wTZ~su*tNv7o!gXT!GRgivP}ec?5>l1!7<(rT zds|8x(qGc673zrvYIz;J23FG{9nHMnAuP}NpAED^laz3mAN1sy+NXK)!6v1FxQ;lh zOBLA>$~P3r4b*NcqR;y6pwyhZ3_PiDb|%n1gGjl3ZU}ujInlP{eks-#oA6>rh&g+!f`hv#_%JrgYPu z(U^&XLW^QX7F9Z*SRPpQl{B%x)_AMp^}_v~?j7 zapvHMKxSf*Mtyx8I}-<*UGn3)oHd(nn=)BZ`d$lDBwq_GL($_TPaS{UeevT(AJ`p0 z9%+hQb6z)U9qjbuXjg|dExCLjpS8$VKQ55VsIC%@{N5t{NsW)=hNGI`J=x97_kbz@ E0Of=7!TQj4N+cqN`nQhxvX7dAV-`K|Ub$-q+H-5I?Tx0g9jWxd@A|?POE8`3b8fO$T))xP* z(X?&brZw({`)WU&rdAs1iTa0x6F@PIxJ&&L|dpySV!ID|iUhjCcKz(@mE z!x@~W#3H<)4Ae(4eQJRk`Iz3<1)6^m)0b_4_TRZ+cz#eD3f8V;2r-1fE!F}W zEi0MEkTTx}8i1{`l_6vo0(Vuh0HD$I4SjZ=?^?k82R51bC)2D_{y8mi_?X^=U?2|F{Vr7s!k(AZC$O#ZMyavHhlQ7 zUR~QXuH~#o#>(b$u4?s~HLF*3IcF7023AlwAYudn0FV~|odGH^05AYPEfR)8p`i{n zwg3zPVp{+wOsxKc>)(pMupKF!Y2HoUqQ3|Yu|8lwR=?5zZuhG6J?H`bSNk_wPoM{u zSL{c@pY7+c2kck>`^q1^^gR0QB7Y?KUD{vz-uVX~;V-rW)PDcI)$_UjgVV?S?=oLR zf4}zz{#*R_{LkiJ#0RdQLNC^2Vp%JPEUvG9ra2BVZ92(p9h7Ka@!yf9(lj#}>+|u* z;^_?KWdzkM`6gqPo9;;r6&JEa)}R3X{(CWv?NvgLeOTq$cZXqf7|sPImi-7cS8DCN zGf;DVt3Am`>hH3{4-WzH43Ftx)SofNe^-#|0HdCo<+8Qs!}TZP{HH8~z5n`ExcHuT zDL1m&|DVpIy=xsLO>8k92HcmfSKhflQ0H~9=^-{#!I1g(;+44xw~=* zxvNz35vfsQE)@)Zsp*6_GjYD};Squ83<_?^SbALb{a`j<0Gn%6JY!zhp=Fg}Ga2|8 z52e1WU%^L1}15Ex0fF$e@eCT(()_P zvV?CA%#Sy08_U6VPt4EtmVQraWJX` zh=N|WQ>LgrvF~R&qOfB$!%D3cGv?;Xh_z$z7k&s4N)$WYf*k=|*jCEkO19{h_(%W4 zPuOqbCw`SeAX*R}UUsbVsgtuG?xs(#Ikx9`JZoQFz0n*7ZG@Fv@kZk`gzO$HoA9kN z8U5{-yY zvV{`&WKU2$mZeoBmiJrEdzUZAv1sRxpePdg1)F*X^Y)zp^Y*R;;z~vOv-z&)&G)JQ{m!C9cmziu1^nHA z`#`0c>@PnQ9CJKgC5NjJD8HM3|KC(g5nnCq$n0Gsu_DXk36@ql%npEye|?%RmG)

FJ$wK}0tWNB{uH;AM~i literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e7b91d006d22352c9ff2f134e504e3c1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4842 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 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..948a3070fe34c611c42c0d3ad3013a0dce358be0 GIT binary patch literal 1900 zcmV-y2b1_xNk&Fw2LJ$9MM6+kP&il$0000G0001A003VA06|PpNH75a00DqwTbm-~ zullQTcXxO9ki!OCRx^i?oR|n!<8G0=kI^!JSjFi-LL*`V;ET0H2IXfU0*i>o6o6Gy zRq6Ap5(_{XLdXcL-MzlN`ugSdZY_`jXhcENAu)N_0?GhF))9R;E`!bo9p?g?SRgw_ zEXHhFG$0{qYOqhdX<(wE4N@es3VIo$%il%6xP9gjiBri+2pI6aY4 zJbgh-Ud|V%3O!IcHKQx1FQH(_*TK;1>FQWbt^$K1zNn^cczkBs=QHCYZ8b&l!UV{K z{L0$KCf_&KR^}&2Fe|L&?1I7~pBENnCtCuH3sjcx6$c zwqkNkru);ie``q+_QI;IYLD9OV0ZxkuyBz|5<$1BH|vtey$> z5oto4=l-R-Aaq`Dk0}o9N0VrkqW_#;!u{!bJLDq%0092{Ghe=F;(kn} z+sQ@1=UlX30+2nWjkL$B^b!H2^QYO@iFc0{(-~yXj2TWz?VG{v`Jg zg}WyYnwGgn>{HFaG7E~pt=)sOO}*yd(UU-D(E&x{xKEl6OcU?pl)K%#U$dn1mDF19 zSw@l8G!GNFB3c3VVK0?uyqN&utT-D5%NM4g-3@Sii9tSXKtwce~uF zS&Jn746EW^wV~8zdQ1XC28~kXu8+Yo9p!<8h&(Q({J*4DBglPdpe4M_mD8AguZFn~ ztiuO~{6Bx?SfO~_ZV(GIboeR9~hAym{{fV|VM=77MxDrbW6`ujX z<3HF(>Zr;#*uCvC*bpoSr~C$h?_%nXps@A)=l_;({Fo#6Y1+Zv`!T5HB+)#^-Ud_; zBwftPN=d8Vx)*O1Mj+0oO=mZ+NVH*ptNDC-&zZ7Hwho6UQ#l-yNvc0Cm+2$$6YUk2D2t#vdZX-u3>-Be1u9gtTBiMB^xwWQ_rgvGpZ6(C@e23c!^K=>ai-Rqu zhqT`ZQof;9Bu!AD(i^PCbYV%yha9zuoKMp`U^z;3!+&d@Hud&_iy!O-$b9ZLcSRh? z)R|826w}TU!J#X6P%@Zh=La$I6zXa#h!B;{qfug}O%z@K{EZECu6zl)7CiNi%xti0 zB{OKfAj83~iJvmpTU|&q1^?^cIMn2RQ?jeSB95l}{DrEPTW{_gmU_pqTc)h@4T>~& zluq3)GM=xa(#^VU5}@FNqpc$?#SbVsX!~RH*5p0p@w z;~v{QMX0^bFT1!cXGM8K9FP+=9~-d~#TK#ZE{4umGT=;dfvWi?rYj;^l_Zxywze`W z^Cr{55U@*BalS}K%Czii_80e0#0#Zkhlij4-~I@}`-JFJ7$5{>LnoJSs??J8kWVl6|8A}RCGAu9^rAsfCE=2}tHwl93t0C?#+jMpvr7O3`2=tr{Hg$=HlnjVG^ewm|Js0J*kfPa6*GhtB>`fN!m#9J(sU!?(OSfzY*zS(FJ<-Vb zfAIg+`U)YaXv#sY(c--|X zEB+TVyZ%Ie4L$gi#Fc++`h6%vzsS$pjz9aLt+ZL(g;n$Dzy5=m=_TV(3H8^C{r0xd zp#a%}ht55dOq?yhwYPrtp-m1xXp;4X;)NhxxUpgP%XTLmO zcjaFva^}dP3$&sfFTIR_jC=2pHh9kpI@2(6V*GQo7Ws)`j)hd+tr@P~gR*2gO@+1? zG<`_tB+LJuF|SZ9tIec;h%}}6WClT`L>HSW?E{Hp1h^+mlbf_$9zA>!ug>NALJsO{ mU%z=YwVD?}XMya)Bp;vlyE5&E_6!fzx9pwrdz474!~g(M6R?N? literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..1b9a6956b3acdc11f40ce2bb3f6efbd845cc243f GIT binary patch literal 3918 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 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..28d4b77f9f036a47549d47db79c16788749dca10 GIT binary patch literal 2884 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�(p-{x$&=IACIfoAR!za)F-^da-t3#0Dycnp zwO~NVXwXCl;jE<}>%@xz|=8fIJAB?>+E{7)|4l${4ngA3G|=r z2Dyv;VVWSgZx9Wj>qUjleGl3Ei9K4>h!(lPS%8VOG>Xu0%6VDz^O=bjJmuP7>DeUv zrbI}MlHB^^d?{zv6d=@_ZD2lg1&G7UjnVN{1}9WkaM3H~btX0GtSzB+tZ^qRgWo4m z!GmimlG$=wgXCnr6j@m<1gAL46#T~5Bnm=2{^@>|t&`9mkEPddj zAvG~@Tv~TAm2i%VW}R-g(Z0)z-Y|szHr@rk>4MAyG*Ma*7Yh#H7(!-5>DZ@8r;_dx z{prSe<>~099F8vsYd2xff7uAS%7{S)f(|@me3t2$iy&NEc7OUEchp@9A|X;;IA>8!oX+y(BKJ$EzV* znR$z;!L$s7uy@{OT~nG#B!NRraT8(X##Ho!0r_o@gg0CA-9H^;-uE&?$2$nHv_00o z%cbuUc-tCx$Uh&EZ4Nf4Zgqv)Y6>usG3>GeQnxx_Z6+PcbX-+ysbt1hQ`K1LDpOE? zrAhIZhSN9yVIAOa22gn577tbc&i3|3V8NWy&!tw##`}9*x}gtI^h1DzZRA>UuaJG) zaZ7j)dq!O}{?#8Y7~7i6fHh4{`pL?>-18|p!S75Y#^DM>-S3)vuZG+Q7l@ek zQP~#cBpWgg#mApc_sPYjpw8odQuRokmTkzcNl`^CcKB7e&;zViV;{Y{o^Y$%7i0m# z62%#1Lq!RC?}lK>%mp}T!3Xv;L*0v*>USLm``N%>w>@fwC+#T&Tx2bN4w(20JB}oU zuSa6v^kXi0xPs?pbaOHnyiqq6By1EZY9OZ^^QA>{q-Hsd&m`pbQ%8121aWG-F5xf zlZ%;B{;C>X19|`^_?dVyCq>n+41w7|!tUS!{9rHlbhX=SZO5CQ^;!Du_E7*`GiR^Q w)2!4MKjfSAeNo!9>IaV6aUZ*?W>} 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

UmY2RIYtNPVDpE$%vda+HD#3m z&VuXJ{BK&Qe+rBa7eq}Q(bq|tn(RrJAk|ztj2(i{d>nmQnM?;HF2k&9sA6up5tmjl z7lySlzMbifH17-m-Lwa_F&e7nOH?ESi3#ckR3tsM+jsck3`oG!uMS}|eAwVXv>}qxwq?QY%QJ0}r@^;fhuUA9W z*BVl>TGo&N004@xSiwDUXUvp51sVmqO3m)=B55aPwf@0=e}cN+$-BdKxY`YrT_4)0 z_d10#i44Q*rFr8MC>*)v$EJvz``(pb{e&*6k+b zsMz%($|1+8hn8c2?P(l@;Rb&CsZeYoCI3?2!LqjbwPXW3z4G$Qfj=cT5Yb%vY0(AX oeb?AaKtwrnc|$|zzw9vfvn^aJJ!zd)XFXqqy0000001=f@-~a#s literal 0 HcmV?d00001 diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..c0fd1e9 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 729a6ac..6180c98 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - InputMask + Sample Currency: Date: Phone: diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index 766ab99..0000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..fb0958c --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3048874..70924b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - apply from: "${rootProject.projectDir}/gradle/dependencies.gradle" - ext { - kotlin_version = '1.3.72' - } - - addRepos(repositories) - - dependencies { - classpath deps.gradle.android_plugin - classpath deps.kotlin.plugin - classpath deps.kotlin.dokka - classpath deps.bintray.android_maven_plugin - classpath deps.bintray.gradle_bintray_plugin - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } +plugins { + id 'com.android.application' version '7.4.2' apply false + id 'com.android.library' version '7.4.2' apply false + id 'org.jetbrains.kotlin.android' version '1.8.0' apply false } - -allprojects { - apply from: "${rootProject.projectDir}/gradle/version.gradle" - - addRepos(repositories) -} - - diff --git a/gradle.properties b/gradle.properties index 7e44f54..3c5031e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,23 @@ -## For more details on how to configure your build environment visit +# 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. -# Default value: -Xmx1024m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -# +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -#Sun Apr 16 18:25:25 GET 2023 -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -android.enableJetifier=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -org.gradle.unsafe.configuration-cache=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle deleted file mode 100644 index df20384..0000000 --- a/gradle/dependencies.gradle +++ /dev/null @@ -1,73 +0,0 @@ -static def addRepos(RepositoryHandler handler) { - handler.google() - handler.jcenter() -} - -ext.addRepos = this.&addRepos - -//region Build versions -def build_versions = [:] - -build_versions.min_sdk = 23 -build_versions.target_sdk = 33 -build_versions.compile_sdk = 33 - -ext.build_versions = build_versions -//endregion - -def versions = [:] - -ext.deps = [:] -def deps = [:] - -//region Gradle -def gradle = [:] - -versions.android_plugin = "7.4.2" - -gradle.android_plugin = "com.android.tools.build:gradle:$versions.android_plugin" - -deps.gradle = gradle -//endregion - -//region Kotlin -def kotlin = [:] - -versions.kotlin = "1.8.0" -versions.dokka = "0.9.18" - -kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin" -kotlin.test = "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin" -kotlin.plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" -kotlin.dokka = "org.jetbrains.dokka:dokka-android-gradle-plugin:$versions.dokka" - -deps.kotlin = kotlin -//endregion - -//region Testing -def test = [:] - -versions.junit = "4.12" -versions.assertj = "3.10.0" -versions.mockito_kotlin = "2.0.0" - -test.junit = "junit:junit:$versions.junit" -test.mockito_kotlin = "com.nhaarman.mockitokotlin2:mockito-kotlin:$versions.mockito_kotlin" -test.assertj = "org.assertj:assertj-core:$versions.assertj" - -deps.test = test -//endregion - -//region Bintray -def bintray = [:] - -versions.maven_plugin = "2.0" -versions.bintray_plugin = "1.8.4" - -bintray.android_maven_plugin = "com.github.dcendents:android-maven-gradle-plugin:$versions.maven_plugin" -bintray.gradle_bintray_plugin = "com.jfrog.bintray.gradle:gradle-bintray-plugin:$versions.bintray_plugin" - -deps.bintray = bintray -//endregion - -ext.deps = deps \ No newline at end of file diff --git a/gradle/version.gradle b/gradle/version.gradle deleted file mode 100644 index 3ec56f2..0000000 --- a/gradle/version.gradle +++ /dev/null @@ -1,21 +0,0 @@ -def getVersionCodeFromProperties() { - Properties versionProperties = loadVersionProperties() - return (versionProperties["version_code"] ?: "0").toString().toInteger() -} - -def getVersionNameFromProperties() { - Properties versionProperties = loadVersionProperties() - return versionProperties["version_name"] -} - -private Properties loadVersionProperties() { - Properties versionProperties = new Properties() - //noinspection GroovyAssignabilityCheck - versionProperties.load(project.rootProject.file('version.properties').newDataInputStream()) - versionProperties -} - -ext { - getVersionCodeFromProperties = this.&getVersionCodeFromProperties - getVersionNameFromProperties = this.&getVersionNameFromProperties -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch literal 59203 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

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM literal 49896 zcmagFb986H(k`5d^NVfUwr$(C?M#x1ZQHiZiEVpg+jrjgoQrerx!>1o_ul)D>ebz~ zs=Mmxr&>W81QY-S1PKWQ%N-;H^tS;2*XwVA`dej1RRn1z<;3VgfE4~kaG`A%QSPsR z#ovnZe+tS9%1MfeDyz`RirvdjPRK~p(#^q2(^5@O&NM19EHdvN-A&StN>0g6QA^VN z0Gx%Gq#PD$QMRFzmK+utjS^Y1F0e8&u&^=w5K<;4Rz|i3A=o|IKLY+g`iK6vfr9?+ z-`>gmU&i?FGSL5&F?TXFu`&Js6h;15QFkXp2M1H9|Eq~bpov-GU(uz%mH0n55wUl- zv#~ccAz`F5wlQ>e_KlJS3@{)B?^v*EQM=IxLa&76^y51a((wq|2-`qON>+4dLc{Oo z51}}o^Zen(oAjxDK7b++9_Yg`67p$bPo3~BCpGM7uAWmvIhWc5Gi+gQZ|Pwa-Gll@<1xmcPy z|NZmu6m)g5Ftu~BG&Xdxclw7Cij{xbBMBn-LMII#Slp`AElb&2^Hw+w>(3crLH!;I zN+Vk$D+wP1#^!MDCiad@vM>H#6+`Ct#~6VHL4lzmy;lSdk>`z6)=>Wh15Q2)dQtGqvn0vJU@+(B5{MUc*qs4!T+V=q=wy)<6$~ z!G>e_4dN@lGeF_$q9`Ju6Ncb*x?O7=l{anm7Eahuj_6lA{*#Gv*TaJclevPVbbVYu z(NY?5q+xxbO6%g1xF0r@Ix8fJ~u)VRUp`S%&rN$&e!Od`~s+64J z5*)*WSi*i{k%JjMSIN#X;jC{HG$-^iX+5f5BGOIHWAl*%15Z#!xntpk($-EGKCzKa zT7{siZ9;4TICsWQ$pu&wKZQTCvpI$Xvzwxoi+XkkpeE&&kFb!B?h2hi%^YlXt|-@5 zHJ~%AN!g_^tmn1?HSm^|gCE#!GRtK2(L{9pL#hp0xh zME}|DB>(5)`iE7CM)&_+S}-Bslc#@B5W4_+k4Cp$l>iVyg$KP>CN?SVGZ(&02>iZK zB<^HP$g$Lq*L$BWd?2(F?-MUbNWTJVQdW7$#8a|k_30#vHAD1Z{c#p;bETk0VnU5A zBgLe2HFJ3032$G<`m*OB!KM$*sdM20jm)It5OSru@tXpK5LT>#8)N!*skNu1$TpIw zufjjdp#lyH5bZ%|Iuo|iu9vG1HrIVWLH>278xo>aVBkPN3V$~!=KnlXQ4eDqS7%E% zQ!z^$Q$b^6Q)g#cLpwur(|<0gWHo6A6jc;n`t(V9T;LzTAU{IAu*uEQ%Ort1k+Kn+f_N`9|bxYC+~Z1 zCC1UCWv*Orx$_@ydv9mIe(liLfOr7mhbV@tKw{6)q^1DH1nmvZ0cj215R<~&I<4S| zgnr;9Cdjqpz#o8i0CQjtl`}{c*P)aSdH|abxGdrR)-3z+02-eX(k*B)Uqv6~^nh** z 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 \(.*\)$'` + 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 APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,33 +75,14 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# 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\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - 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 @@ -90,7 +106,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -110,11 +126,13 @@ 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 +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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="" @@ -138,27 +156,30 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $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" ;; + 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=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index aec9973..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,20 +24,23 @@ @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 Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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="-Xmx64m" "-Xms64m" + @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 +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,34 +64,14 @@ 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% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/inputmask/build.gradle b/inputmask/build.gradle index e6a09ea..96e7c36 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -1,65 +1,56 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'org.jetbrains.dokka' +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'maven-publish' +} android { - compileSdkVersion build_versions.compile_sdk + namespace 'com.redmadrobot.inputmask' + compileSdk 33 defaultConfig { - minSdkVersion build_versions.min_sdk - targetSdkVersion build_versions.target_sdk - - archivesBaseName = "input-mask-android" + minSdk 23 + targetSdk 33 - versionCode getVersionCodeFromProperties() - versionName getVersionNameFromProperties() + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" } buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - - androidTest.java.srcDirs += 'src/androidTest/kotlin' - test.java.srcDirs += 'src/test/kotlin' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } - dokka { - outputFormat = 'html' - outputDirectory = "$buildDir/documentation" - - reportUndocumented = false - includeNonPublic = true - skipEmptyPackages = false - - includes = ['module-info.md'] - - sourceDirs = files('src/main/kotlin') - kotlinTasks { - // Workaround to avoid generating unnecessary documentation - } + kotlinOptions { + jvmTarget = '1.8' } } dependencies { - implementation deps.kotlin.stdlib - implementation 'androidx.annotation:annotation:1.6.0' - - testImplementation deps.test.junit -} - -task dokkaMarkdown(type: org.jetbrains.dokka.gradle.DokkaTask) { - outputFormat = 'markdown' - outputDirectory = "$buildDir/markdowndoc" + implementation 'androidx.core:core-ktx:1.10.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.8.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } -task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { - outputFormat = 'javadoc' - outputDirectory = "$buildDir/javadoc" +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + groupId = 'com.redmadrobot' + artifactId = 'inputmask' + version = '7.2.0' + } + } + } } - diff --git a/inputmask/consumer-rules.pro b/inputmask/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/inputmask/proguard-rules.pro b/inputmask/proguard-rules.pro index 3ee60e8..481bb43 100644 --- a/inputmask/proguard-rules.pro +++ b/inputmask/proguard-rules.pro @@ -1,17 +1,21 @@ # Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/maximefimov/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. +# 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 -# Add any project specific keep options here: - # 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 \ No newline at end of file diff --git a/inputmask/src/main/AndroidManifest.xml b/inputmask/src/main/AndroidManifest.xml index 64678ab..bdae66c 100644 --- a/inputmask/src/main/AndroidManifest.xml +++ b/inputmask/src/main/AndroidManifest.xml @@ -1,3 +1,2 @@ - - + diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt index 89eaa71..6bf8970 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/NumberInputListener.kt @@ -109,7 +109,10 @@ open class NumberInputListener( } override fun pickMask(text: CaretString): Mask { - val sanitisedNumberString = extractNumberAndDecimalSeparator(formatter, text.string) + val sanitisedNumberString = extractNumberAndDecimalSeparator( +// formatter, + text.string + ) val intNum = sanitisedNumberString.intPart.toLong() val intMaskFormat = formatter.format(intNum) @@ -136,8 +139,8 @@ open class NumberInputListener( maskFormat += "{${sanitisedNumberString.expectedDecimalSeparator}}" } - sanitisedNumberString.decPart.forEach { c: Char -> - maskFormat += "[0]" + sanitisedNumberString.decPart.forEach { + maskFormat += "[0]" } primaryFormat = maskFormat @@ -152,7 +155,7 @@ open class NumberInputListener( ) private fun extractNumberAndDecimalSeparator( - formatter: LocalizedNumberFormatter, +// formatter: LocalizedNumberFormatter, text: String ): SanitisedNumberString { val expectedDecimalSeparator: String = decimalSeparator @@ -173,7 +176,7 @@ open class NumberInputListener( val components = digitsAndDecimalSeparators.split(decimalSeparator) - var intStr = "" + var intStr: String var decStr = "" if (components.size > 1) { diff --git a/settings.gradle b/settings.gradle index de0e53f..aaec5cc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,18 @@ -include ':app', ':inputmask' +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url 'https://jitpack.io' } + } +} +rootProject.name = "input-mask-android" +include ':app' +include ':inputmask' diff --git a/version.properties b/version.properties deleted file mode 100644 index e3b33e0..0000000 --- a/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file should be checked into Version Control Systems, -# as it contains default parameters to version configuration. -version_code=10 -version_name=6.1.0 From 7eeec562040519c3637b05d72d2a631aded48ed6 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 19:11:25 +0400 Subject: [PATCH 23/32] Update READMEs --- CHANGELOG.md | 6 ++++++ README.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d6818..00f5576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 7.2.0 + +**🔄 Modified:** + +* Re-write the sample project + ## 7.1.1 **🔄 Modified:** diff --git a/README.md b/README.md index 3737549..bce3af5 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ repositories { } dependencies { - implementation 'com.redmadrobot:input-mask-android:7.1.0' + implementation 'com.redmadrobot:input-mask-android:7.2.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:$latest_version' } From 46ea21bdc8bcfb5e20c4fd774a3509929e20e622 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 19:24:28 +0400 Subject: [PATCH 24/32] Update build configs --- build.gradle | 1 + inputmask/build.gradle | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 70924b0..bdbf79e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,4 +3,5 @@ plugins { id 'com.android.application' version '7.4.2' apply false id 'com.android.library' version '7.4.2' apply false id 'org.jetbrains.kotlin.android' version '1.8.0' apply false + id 'maven-publish' } diff --git a/inputmask/build.gradle b/inputmask/build.gradle index 96e7c36..9eae4cc 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -1,7 +1,6 @@ plugins { id 'com.android.library' id 'org.jetbrains.kotlin.android' - id 'maven-publish' } android { From 953940d86aac72fbf8ed1fb90287b312f04b587c Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 19:41:31 +0400 Subject: [PATCH 25/32] Add group and version --- inputmask/build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inputmask/build.gradle b/inputmask/build.gradle index 9eae4cc..83c4cde 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -3,6 +3,9 @@ plugins { id 'org.jetbrains.kotlin.android' } +group = 'com.redmadrobot' +version = '7.2.2' + android { namespace 'com.redmadrobot.inputmask' compileSdk 33 @@ -48,7 +51,7 @@ afterEvaluate { from components.release groupId = 'com.redmadrobot' artifactId = 'inputmask' - version = '7.2.0' + version = '7.2.2' } } } From 864aa3c1071521adba1ab873a598637678ecfa52 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 19:48:46 +0400 Subject: [PATCH 26/32] Update Gradle version --- gradle/wrapper/gradle-wrapper.properties | 2 +- inputmask/build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 66baffe..02305e6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Apr 17 15:07:31 GET 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/inputmask/build.gradle b/inputmask/build.gradle index 83c4cde..dbec807 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.redmadrobot' -version = '7.2.2' +version = '7.2.3' android { namespace 'com.redmadrobot.inputmask' @@ -51,7 +51,7 @@ afterEvaluate { from components.release groupId = 'com.redmadrobot' artifactId = 'inputmask' - version = '7.2.2' + version = '7.2.3' } } } From 0df16c4d2f42d9518fff8b8ae70c04ea671fe5e6 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 20:19:33 +0400 Subject: [PATCH 27/32] Downgrade build tools --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- inputmask/build.gradle | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index bdbf79e..37d2fb6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.4.2' apply false - id 'com.android.library' version '7.4.2' apply false + id 'com.android.application' version '7.1.3' apply false + id 'com.android.library' version '7.1.3' apply false id 'org.jetbrains.kotlin.android' version '1.8.0' apply false id 'maven-publish' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 02305e6..55c9da8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Apr 17 15:07:31 GET 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/inputmask/build.gradle b/inputmask/build.gradle index dbec807..b305df4 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -3,9 +3,6 @@ plugins { id 'org.jetbrains.kotlin.android' } -group = 'com.redmadrobot' -version = '7.2.3' - android { namespace 'com.redmadrobot.inputmask' compileSdk 33 @@ -51,7 +48,7 @@ afterEvaluate { from components.release groupId = 'com.redmadrobot' artifactId = 'inputmask' - version = '7.2.3' + version = '7.2.4' } } } From 2a62805db0f3c2e5a65b3c7522f12d2583f2400e Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 20:24:28 +0400 Subject: [PATCH 28/32] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bce3af5..760314a 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ repositories { } dependencies { - implementation 'com.redmadrobot:input-mask-android:7.2.0' + implementation 'com.redmadrobot:input-mask-android:7.2.4' implementation 'org.jetbrains.kotlin:kotlin-stdlib:$latest_version' } From b9a7d2979b29c86898425f91cab0e643ea27edf5 Mon Sep 17 00:00:00 2001 From: taflanidi Date: Mon, 17 Apr 2023 23:53:51 +0400 Subject: [PATCH 29/32] Cleanup & bump min sdk --- app/build.gradle | 4 ---- inputmask/build.gradle | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 709fd3c..faccb37 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,10 +35,6 @@ android { dependencies { implementation project(":inputmask") implementation 'androidx.core:core-ktx:1.10.0' - implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } \ No newline at end of file diff --git a/inputmask/build.gradle b/inputmask/build.gradle index b305df4..3108a2c 100644 --- a/inputmask/build.gradle +++ b/inputmask/build.gradle @@ -8,7 +8,7 @@ android { compileSdk 33 defaultConfig { - minSdk 23 + minSdk 24 targetSdk 33 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -34,11 +34,7 @@ android { dependencies { implementation 'androidx.core:core-ktx:1.10.0' - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.8.0' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } afterEvaluate { From 4d59279f1c03133ab70497edbd5170ac3555f52c Mon Sep 17 00:00:00 2001 From: taflanidi Date: Fri, 5 May 2023 16:05:16 +0400 Subject: [PATCH 30/32] fix: bloomer --- CHANGELOG.md | 6 ++++++ .../main/kotlin/com/redmadrobot/inputmask/model/Country.kt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f5576..e118500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 7.2.4 + +**🔄 Modified:** + +* `Country::findCountries` → fix bloomer + ## 7.2.0 **🔄 Modified:** diff --git a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt index 3a40769..efe8ae3 100644 --- a/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt +++ b/inputmask/src/main/kotlin/com/redmadrobot/inputmask/model/Country.kt @@ -59,7 +59,7 @@ data class Country( val excludingTermsLowercased = excludingTerms?.map { it.lowercase() } ?: listOf() val phoneDigits = phone.filter(Char::isDigit) - return customCountries ?: all.filter { + return (customCountries ?: all).filter { var include: Boolean = false if (includingTerms != null) { From f62571bfa38aebb7a629d6c20534ad30354e6534 Mon Sep 17 00:00:00 2001 From: Egor Taflanidi <6849363+taflanidi@users.noreply.github.com> Date: Fri, 5 May 2023 16:12:40 +0400 Subject: [PATCH 31/32] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e118500..263b2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 7.2.4 +## 7.2.6 **🔄 Modified:** From df452edc0c52a37e5082adcfc3d05d77b5aa34e8 Mon Sep 17 00:00:00 2001 From: Egor Taflanidi <6849363+taflanidi@users.noreply.github.com> Date: Fri, 5 May 2023 16:39:42 +0400 Subject: [PATCH 32/32] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 760314a..05e691e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Input Mask +Input Mask [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Input%20Mask-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/details/1/4642) [![](https://img.shields.io/jitpack/version/com.redmadrobot/input-mask-android?style=for-the-badge)](https://jitpack.io/#RedMadRobot/input-mask-android) [![Awesome](https://img.shields.io/badge/-mentioned_in_awesome_android-CCA6C4.svg?colorA=CCA6C4&colorB=261120&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BICAgIDxwYXRoIGZpbGw9IiMyNjExMjAiIGQ9Ik0xOS4xNCA0LjVMMTQuMjMgMGwtLjY5Ljc1IDQuMDkgMy43NUgxLjUxTDUuNi43NSA0LjkxIDAgMCA0LjV2Mi45N0MwIDguODEgMS4yOSA5LjkgMi44OCA5LjloMy4wM2MxLjU5IDAgMi44OC0xLjA5IDIuODgtMi40M1Y1LjUyaDEuNTd2MS45NWMwIDEuMzQgMS4yOSAyLjQzIDIuODggMi40M2gzLjAzYzEuNTkgMCAyLjg4LTEuMDkgMi44OC0yLjQzbC0uMDEtMi45N3oiLz48L3N2Zz4%3D&style=for-the-badge)](https://github.com/JStumpp/awesome-android) [![Actions](https://img.shields.io/github/actions/workflow/status/RedMadRobot/input-mask-android/android.yml?style=for-the-badge)](https://github.com/RedMadRobot/input-mask-android/actions/workflows/android.yml) [![iOS Version](https://img.shields.io/badge/-ios_version-red?color=teal&logo=ios&style=for-the-badge)](https://github.com/RedMadRobot/input-mask-ios) [![Telegram](https://img.shields.io/badge/-telegram_author-red?color=blue&logo=telegram&style=for-the-badge)](https://t.me/jeorge_taflanidi) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge)](#license)