├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── art
└── sample.gif
├── build.gradle
├── dependencies.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library-date
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── io
│ └── denison
│ └── typedvalue
│ └── date
│ ├── DateValue.kt
│ ├── LocalDateTimeValue.kt
│ ├── LocalDateValue.kt
│ └── TimeIntervalValue.kt
├── library
├── build.gradle
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── io
│ │ └── denison
│ │ └── typedvalue
│ │ ├── KeyValueDelegate.kt
│ │ ├── TypedValue.kt
│ │ ├── common
│ │ ├── BoolValue.kt
│ │ ├── DoubleValue.kt
│ │ ├── FloatValue.kt
│ │ ├── IntValue.kt
│ │ ├── LongValue.kt
│ │ ├── ParcelableValue.kt
│ │ ├── StringListValue.kt
│ │ ├── StringSetValue.kt
│ │ └── StringValue.kt
│ │ └── delegate
│ │ ├── BundleDelegate.kt
│ │ ├── MapDelegate.kt
│ │ └── PreferenceDelegate.kt
│ └── test
│ └── java
│ └── io
│ └── denison
│ └── typedvalue
│ ├── BundleDelegateTest.kt
│ ├── MapDelegateTest.kt
│ └── PreferenceDelegateTest.kt
├── sample
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── io
│ │ └── denison
│ │ └── typedvalue
│ │ └── sample
│ │ ├── MainActivity.kt
│ │ ├── SampleApplication.kt
│ │ ├── di
│ │ ├── AppComponent.kt
│ │ ├── AppModule.kt
│ │ └── ViewScope.kt
│ │ ├── model
│ │ └── AnimationType.kt
│ │ ├── mvp
│ │ ├── MvpPresenter.kt
│ │ ├── MvpView.kt
│ │ ├── presenter
│ │ │ └── BasePresenter.kt
│ │ └── view
│ │ │ └── MvpConstraintLayout.kt
│ │ ├── preferences
│ │ ├── AppPreferences.kt
│ │ ├── AppPreferencesImpl.kt
│ │ └── value
│ │ │ └── AnimationTypeValue.kt
│ │ └── ui
│ │ ├── animation
│ │ ├── AnimationComponent.kt
│ │ ├── AnimationLayout.kt
│ │ ├── AnimationPresenter.kt
│ │ └── AnimationView.kt
│ │ └── settings
│ │ ├── SettingsComponent.kt
│ │ ├── SettingsLayout.kt
│ │ ├── SettingsPresenter.kt
│ │ └── SettingsView.kt
│ └── res
│ ├── drawable-v21
│ └── setting_item_bkg.xml
│ ├── drawable
│ └── setting_item_bkg.xml
│ ├── font
│ ├── fonts.xml
│ └── roboto_medium.ttf
│ ├── layout
│ └── ac_main.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── raw
│ ├── confetti.json
│ ├── favourite.json
│ └── plane.json
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Android Studio
2 | .idea
3 | *.iml
4 | .externalNativeBuild
5 | .gradle/
6 | build/
7 | captures/
8 |
9 | # Local configuration file (sdk path, etc)
10 | local.properties
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | sudo: false
3 |
4 | jdk:
5 | - oraclejdk8
6 |
7 | android:
8 | components:
9 | - tools
10 | - platform-tools
11 | - build-tools-28.0.2
12 | - android-28
13 | - extra-android-m2repository
14 | - extra-google-m2repository
15 |
16 | cache:
17 | directories:
18 | - $HOME/.m2
19 | - $HOME/.gradle
20 |
21 | before_script:
22 | - chmod +x gradlew
23 |
24 | script:
25 | - ./gradlew library:build library-date:build
26 |
27 | after_success:
28 | - ./gradlew jacocoTestReport && bash <(curl -s https://codecov.io/bash)
29 |
30 | env:
31 | global:
32 | - secure: cnxxpwWf6vcAq+NlTqKUv8lFG0u7leTnw/zyk3Ujxf/McGAKoUmxji14ClgncD1iFt8MRxXAs/E3wpBM6lH+cclTcC77eDKSvcvU4Tc8F8hty/u7fZGDcQQjYq/HKYM0qYAfCbkB3CEfoAqwB5WS0mT2Dh9x3vv9tDYuDsoZu6dWzy8kHc5V1bejgFmP75u5nMeRxgIXIUwqE6JtiueYrioNjAz5Rn79xZ6TwJaGD3PRt+nuuZdom+7OtZPOgkW4YtHaHmvBhnDI+6bu9R1hwqff/07nn9Q0wiKGeiGd0hnIejvGhZuIrLJ7+ZLMORdWssqfc1QMX4J2hW0xYDNYbuwFzpJIH2EhLrPSLp7BR+UVL4M8U0u1gmmHTTiYITqC3oLw9NMuj3yrJavKnli34fPSsvOHK1pt0pPy4tP4/9wZZgxoo2MTApmtRl7HcZ7oRzCW++ExzKIAP5MjwvSZ9tvMgS+pT6k9P4/+9ajGHWR8SSsxr6vNk+UtZ2r7m8dxi5yQInbP9VXuEtkGVfceO21C2tEAUpWtaFYpkSZcp3FXRrHNYFs677VZx+sZ5iGJ8qhJDfo2M/Ti3S2KeFffe/ORr95OAfyTeIbg1bjYoJjw5wK2bUN75j97tPGwl5NQU0SHKGBfh1rvPHBHABcXhNfznVF3onBxRB5IYS7AVE4=
33 | - secure: HfgUt9NsOqF9j7ayaFe/jwvFVvagQTAVc0EuqYFinlAmAd5NS7YRRZb8wwABnsyHc7KH+RA5AtFc1yIzwjeH5siC+LDXbmN8sAKjS2/pROxjdZZbdL3V3YnzD/ZF1J7ab5MeaAR1Le6rHVBs6uKOgb2MKIMiLIfYjnOb2+U7Np/ZNkRw+SggClD1ohTWvv/F3UdtrZp9yhkusMjpOiMVjL+DhQlLgFLMoI3oZDBrjXfMqAJ0EjglbBWkoiWIgTUeBziy9LVl5uPTrTg81vPTDREAiyV3gJHmlbH79aqy3ulxusu4RaEo/dVVlaUfCoqfmMDYfGZvQ5gSKgpDo18kbQd1f9Rk2os/B4sjqJu0ZiKvsDbIFFcPQlAfwikyqtyK4QCU/aq/L7Hwa2XKtt6tN0Yi30IHqtSUbt13zsF00injqzitxUap3n9UeW6K+QteGK9WlAHeBZA0RM5HvuC5Szyji2ZzX9Bp+Xn8j6+4tIR4codsaKnj2fSaKejtpjuf5pxy+ng9gSEOBacmWSdYjPq0Fl2UeY/Mcw3hPt5ds6z1bXL8oMMTb7/MIjsWEvWXi5dLyMrjfjOBkmWEMw9G2dHc9polTUhP9cKqMmzNoOMpjFoIGMnnXaix79iarlja0mto6u/7ga9ldl9O7qsikT0SfoMbp53OYHiJHdwswQ8=
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TypedValue
2 | [](https://travis-ci.org/YuriDenison/typedvalue)
3 | [](https://android-arsenal.com/api?level=14)
4 | [ ](https://bintray.com/volkman/android/typedvalue/_latestVersion)
5 | [](https://android-arsenal.com/details/1/6872)
6 | 
7 |
8 | TypedValue is a tiny library project to simplify access to SharedPreferences, Bundle or any other key-value storage with it's own [`KeyValueDelegate`][key_value_delegate]
9 |
10 | Common values are available out of the box:
11 | * [BoolValue][bool_value]
12 | * [StringValue][string_value]
13 | * [IntValue][int_value]
14 | * [LongValue][long_value]
15 | * [FloatValue][float_value]
16 | * [DoubleValue][double_value]
17 | * [ParcelableValue][parcelable_value]
18 | * [StringListValue][string_list_value]
19 | * [StringSetValue][string_set_value]
20 |
21 | Date module contains custom TypedValues for managing dates:
22 | * [DateValue][date_value]
23 | * [LocalDateValue][local_date_value]
24 | * [LocalDateTimeValue][local_date_time_value]
25 |
26 | For `java.time` entities [ThreeTen][threeten] library is used.
27 |
28 |
29 | ## Demo app
30 | 
31 |
32 | The `sample` application demonstrates:
33 | * Convenient way to manage application preferences: [AppPreferences][app_preferences] and [AppPreferencesImpl][app_preferences_impl]
34 |
35 | Any calls (`get()`, `set()`, `asObservable()`, etc.) of each preference can be easily find via interface properties
36 | ``` kotlin
37 | interface AppPreferences {
38 | val animationTypeValue: AnimationTypeValue
39 | val scaleValue: FloatValue
40 | val messageShownValue: BoolValue
41 | }
42 | ```
43 | ``` kotlin
44 | class AppPreferencesImpl(app: Application) : AppPreferences {
45 | private val delegate = PreferenceDelegate(PreferenceManager.getDefaultSharedPreferences(app))
46 |
47 | override val animationTypeValue: AnimationTypeValue by lazy { AnimationTypeValue(delegate, KEY_ANIMATION_TYPE, AnimationType.CONFETTI) }
48 | override val scaleValue: FloatValue by lazy { FloatValue(delegate, KEY_SCALE, 0.8f) }
49 | override val messageShownValue: BoolValue by lazy { BoolValue(delegate, KEY_MESSAGE_SHOWN) }
50 |
51 | private companion object {
52 | const val KEY_ANIMATION_TYPE = ".key_animation_type"
53 | const val KEY_SCALE = ".key_scale"
54 | const val KEY_MESSAGE_SHOWN = ".key_message_shown"
55 | }
56 | }
57 | ```
58 |
59 |
60 | * benefits of observable SharedPreferences with uni-directional data flow of ['SettingsPresenter'][settings_presenter]
61 | * custom [TypedValue][typed_value]: [AnimationTypeValue][animation_type_value]
62 |
63 | ## Installation
64 | Add the following dependency to your `build.gradle` file:
65 |
66 | ```
67 | dependencies {
68 | implementation 'io.denison:typedvalue:${LATEST_VERSION}'
69 | implementation 'io.denison:typedvalue-date:${LATEST_VERSION}'
70 | }
71 | ```
72 |
73 | ## License
74 | Please see [LICENSE](/LICENSE)
75 |
76 |
77 | [key_value_delegate]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/KeyValueDelegate.kt
78 | [typed_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/TypedValue.kt
79 | [animation_type_value]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/value/AnimationTypeValue.kt
80 | [settings_presenter]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsPresenter.kt
81 | [app_preferences]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferences.kt
82 | [app_preferences_impl]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferencesImpl.kt
83 | [bool_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/BoolValue.kt
84 | [double_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/DoubleValue.kt
85 | [float_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/FloatValue.kt
86 | [int_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/IntValue.kt
87 | [long_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/LongValue.kt
88 | [parcelable_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/ParcelableValue.kt
89 | [string_list_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringListValue.kt
90 | [string_set_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringSetValue.kt
91 | [string_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringValue.kt
92 | [date_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/DateValue.kt
93 | [local_date_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/LocalDateValue.kt
94 | [local_date_time_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/LocalDateTimeValue.kt
95 | [threeten]: https://github.com/JakeWharton/ThreeTenABP
96 |
--------------------------------------------------------------------------------
/art/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/art/sample.gif
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | apply from: 'dependencies.gradle'
3 |
4 | repositories {
5 | mavenLocal()
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath gradlePlugins.android
11 | classpath gradlePlugins.kotlin
12 | classpath gradlePlugins.bintray
13 | classpath gradlePlugins.versions
14 | classpath gradlePlugins.yacoco
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | mavenLocal()
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
30 | apply from: 'dependencies.gradle'
31 | apply plugin: 'com.github.ben-manes.versions'
32 |
--------------------------------------------------------------------------------
/dependencies.gradle:
--------------------------------------------------------------------------------
1 | ext.bintrayConstants = [
2 | repoName : 'android',
3 | userOrg : 'volkman',
4 | libraryGroup : 'io.denison',
5 | libraryDesc : 'Typed value abstraction to deal with SharedPreferences, Bundle, etc.',
6 | github : 'https://github.com/YuriDenison/typedvalue.git',
7 |
8 | libraryVersion: '0.9.4'
9 | ]
10 |
11 | ext.versions = [
12 | compileSdk : 28,
13 | buildTools : '28.0.3',
14 |
15 | androidGradlePlugin : '3.2.1',
16 | versionsGradlePlugin: '0.20.0',
17 | bintrayGradlePlugin : '1.8.4',
18 | yacocoGradlePlugin : '0.1.3',
19 |
20 | kotlin : '1.3.11',
21 |
22 | androidX : '1.0.1',
23 | appCompat : '1.0.2',
24 | constraintLayout : '2.0.0-alpha2',
25 | dagger : '2.19',
26 | gson : '2.8.2',
27 | lottie : '2.8.0',
28 | threeten : '1.1.1',
29 |
30 | rxAndroid2 : '2.1.0',
31 | rxJava2 : '2.2.4',
32 | rxKotlin : '2.3.0',
33 | rxRelay : '2.1.0',
34 | timber : '4.7.1',
35 | snackbar : '2.11.0',
36 |
37 | junit : '4.12',
38 | robolectric : '4.0.2',
39 |
40 | typedvalue : '0.9.4'
41 | ]
42 |
43 | ext.gradlePlugins = [
44 | android : "com.android.tools.build:gradle:$versions.androidGradlePlugin",
45 | kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin",
46 | versions: "com.github.ben-manes:gradle-versions-plugin:$versions.versionsGradlePlugin",
47 | bintray : "com.jfrog.bintray.gradle:gradle-bintray-plugin:$versions.bintrayGradlePlugin",
48 | yacoco : "com.dicedmelon.gradle:jacoco-android:$versions.yacocoGradlePlugin"
49 | ]
50 |
51 | ext.libraries = [
52 | kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlin",
53 |
54 | androidAnnotations: "androidx.annotation:annotation:$versions.androidX",
55 | androidAppCompat : "androidx.appcompat:appcompat:$versions.appCompat",
56 | androidDesign : "com.google.android.material:material:$versions.androidX",
57 | constraintLayout : "androidx.constraintlayout:constraintlayout:$versions.constraintLayout",
58 |
59 | dagger : "com.google.dagger:dagger:$versions.dagger",
60 | daggerCompiler : "com.google.dagger:dagger-compiler:$versions.dagger",
61 |
62 | gson : "com.google.code.gson:gson:$versions.gson",
63 | lottie : "com.airbnb.android:lottie:$versions.lottie",
64 | timber : "com.jakewharton.timber:timber:$versions.timber",
65 | snackbar : "com.nispok:snackbar:$versions.snackbar",
66 | threeten : "com.jakewharton.threetenabp:threetenabp:$versions.threeten",
67 |
68 | rxAndroid2 : "io.reactivex.rxjava2:rxandroid:$versions.rxAndroid2",
69 | rxJava2 : "io.reactivex.rxjava2:rxjava:$versions.rxJava2",
70 | rxKotlin : "io.reactivex.rxjava2:rxkotlin:$versions.rxKotlin",
71 | rxRelay : "com.jakewharton.rxrelay2:rxrelay:$versions.rxRelay",
72 |
73 | junit : "junit:junit:$versions.junit",
74 | kotlinTestJunit : "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin",
75 | robolectric : "org.robolectric:robolectric:$versions.robolectric",
76 |
77 | typedvalue : "io.denison:typedvalue:$versions.typedvalue"
78 | ]
79 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 | android.enableJetifier=true
3 | android.enableR8=true
4 | android.enableR8.fullMode=true
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/library-date/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'jacoco-android'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'maven-publish'
5 | apply plugin: 'com.jfrog.bintray'
6 |
7 | version = bintrayConstants.libraryVersion
8 | group = bintrayConstants.libraryGroup
9 |
10 | android {
11 | compileSdkVersion versions.compileSdk
12 | buildToolsVersion versions.buildTools
13 |
14 | defaultConfig {
15 | minSdkVersion 14
16 | }
17 | }
18 |
19 | dependencies {
20 | implementation libraries.typedvalue
21 | implementation libraries.threeten
22 |
23 | testImplementation libraries.junit
24 | testImplementation libraries.kotlinTestJunit
25 | testImplementation libraries.robolectric
26 | }
27 |
28 | publishing {
29 | publications {
30 | Production(MavenPublication) {
31 | artifact("$buildDir/outputs/aar/library-date-release.aar")
32 | artifact sourcesJar
33 |
34 | groupId bintrayConstants.libraryGroup
35 | version bintrayConstants.libraryVersion
36 | artifactId 'typedvalue-date'
37 |
38 | pom.withXml {
39 | def dependenciesNode = asNode().appendNode('dependencies')
40 |
41 | configurations.implementation.allDependencies.each {
42 | if (it.name != 'unspecified') {
43 | def dependencyNode = dependenciesNode.appendNode('dependency')
44 | dependencyNode.appendNode('groupId', it.group)
45 | dependencyNode.appendNode('artifactId', it.name)
46 | dependencyNode.appendNode('version', it.version)
47 | }
48 | }
49 | }
50 | }
51 | }
52 | }
53 |
54 | bintray {
55 | user = project.hasProperty("bintrayUser") ? project.getProperty("bintrayUser") : System.getenv('BINTRAY_USER')
56 | key = project.hasProperty("bintrayKey") ? project.getProperty("bintrayKey") : System.getenv('BINTRAY_KEY')
57 | publications = ['Production']
58 | configurations = ['archives']
59 | override = true
60 |
61 | pkg {
62 | repo = bintrayConstants.repoName
63 | name = 'typedvalue-date'
64 | userOrg = bintrayConstants.userOrg
65 | licenses = ['Apache-2.0']
66 | vcsUrl = bintrayConstants.github
67 | dryRun = false
68 | publish = true
69 |
70 | version {
71 | name = bintrayConstants.libraryVersion
72 | desc = bintrayConstants.libraryDesc
73 | }
74 | }
75 | }
76 |
77 | task sourcesJar(type: Jar) {
78 | classifier = 'sources'
79 | from android.sourceSets.main.java.srcDirs
80 | }
81 |
82 | artifacts {
83 | archives sourcesJar
84 | }
85 |
--------------------------------------------------------------------------------
/library-date/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library-date/src/main/java/io/denison/typedvalue/date/DateValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.date
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 | import java.util.Date
6 |
7 | class DateValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Date = Date()) : TypedValue(delegate, key, defaultValue) {
8 | override fun get(): Date = Date(delegate.getLong(key, 0))
9 | override fun set(value: Date) = delegate.putLong(key, value.time)
10 | }
--------------------------------------------------------------------------------
/library-date/src/main/java/io/denison/typedvalue/date/LocalDateTimeValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.date
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 | import org.threeten.bp.Clock
6 | import org.threeten.bp.Instant
7 | import org.threeten.bp.LocalDateTime
8 | import org.threeten.bp.ZoneOffset
9 |
10 | class LocalDateTimeValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: LocalDateTime = LocalDateTime.now()) : TypedValue(delegate, key, defaultValue) {
11 | override fun get(): LocalDateTime = Instant.ofEpochMilli(delegate.getLong(key, 0)).atZone(Clock.systemUTC().zone).toLocalDateTime()
12 | override fun set(value: LocalDateTime) = delegate.putLong(key, value.toInstant(ZoneOffset.UTC).toEpochMilli())
13 | }
--------------------------------------------------------------------------------
/library-date/src/main/java/io/denison/typedvalue/date/LocalDateValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.date
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 | import org.threeten.bp.Clock
6 | import org.threeten.bp.Instant
7 | import org.threeten.bp.LocalDate
8 |
9 | class LocalDateValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: LocalDate = LocalDate.now()) : TypedValue(delegate, key, defaultValue) {
10 | override fun get(): LocalDate = Instant.ofEpochMilli(delegate.getLong(key, 0)).atZone(Clock.systemUTC().zone).toLocalDate()
11 | override fun set(value: LocalDate) = delegate.putLong(key, value.atStartOfDay(Clock.systemUTC().zone).toInstant().toEpochMilli())
12 | }
--------------------------------------------------------------------------------
/library-date/src/main/java/io/denison/typedvalue/date/TimeIntervalValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.date
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.common.LongValue
5 |
6 | class TimeIntervalValue(delegate: KeyValueDelegate, key: String) : LongValue(delegate, key) {
7 | private var duration = 0L
8 |
9 | fun trackStart() = set(System.currentTimeMillis())
10 | fun trackEnd() {
11 | duration += System.currentTimeMillis() - get()
12 | }
13 |
14 | fun getMillis(): Long = duration
15 | fun getSeconds(): Long = duration / 1000
16 | }
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'jacoco-android'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'maven-publish'
5 | apply plugin: 'com.jfrog.bintray'
6 |
7 | version = bintrayConstants.libraryVersion
8 | group = bintrayConstants.libraryGroup
9 |
10 | android {
11 | compileSdkVersion versions.compileSdk
12 | buildToolsVersion versions.buildTools
13 |
14 | defaultConfig {
15 | minSdkVersion 14
16 | }
17 | }
18 |
19 | dependencies {
20 | implementation libraries.kotlinStdLib
21 | implementation libraries.rxJava2
22 |
23 | testImplementation libraries.junit
24 | testImplementation libraries.kotlinTestJunit
25 | testImplementation libraries.robolectric
26 | }
27 |
28 | publishing {
29 | publications {
30 | Production(MavenPublication) {
31 | artifact("$buildDir/outputs/aar/library-release.aar")
32 | artifact sourcesJar
33 |
34 | groupId bintrayConstants.libraryGroup
35 | version bintrayConstants.libraryVersion
36 | artifactId 'typedvalue'
37 |
38 | pom.withXml {
39 | def dependenciesNode = asNode().appendNode('dependencies')
40 |
41 | configurations.implementation.allDependencies.each {
42 | if (it.name != 'unspecified') {
43 | def dependencyNode = dependenciesNode.appendNode('dependency')
44 | dependencyNode.appendNode('groupId', it.group)
45 | dependencyNode.appendNode('artifactId', it.name)
46 | dependencyNode.appendNode('version', it.version)
47 | }
48 | }
49 | }
50 | }
51 | }
52 | }
53 |
54 | bintray {
55 | user = project.hasProperty("bintrayUser") ? project.getProperty("bintrayUser") : System.getenv('BINTRAY_USER')
56 | key = project.hasProperty("bintrayKey") ? project.getProperty("bintrayKey") : System.getenv('BINTRAY_KEY')
57 | publications = ['Production']
58 | configurations = ['archives']
59 | override = true
60 |
61 | pkg {
62 | repo = bintrayConstants.repoName
63 | name = 'typedvalue'
64 | userOrg = bintrayConstants.userOrg
65 | licenses = ['Apache-2.0']
66 | vcsUrl = bintrayConstants.github
67 | dryRun = false
68 | publish = true
69 |
70 | version {
71 | name = bintrayConstants.libraryVersion
72 | desc = bintrayConstants.libraryDesc
73 | }
74 | }
75 | }
76 |
77 | task sourcesJar(type: Jar) {
78 | classifier = 'sources'
79 | from android.sourceSets.main.java.srcDirs
80 | }
81 |
82 | artifacts {
83 | archives sourcesJar
84 | }
85 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/KeyValueDelegate.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue
2 |
3 | import android.os.Parcelable
4 | import io.reactivex.Observable
5 |
6 | interface KeyValueDelegate {
7 |
8 | fun getInt(key: String, defaultValue: Int): Int
9 | fun putInt(key: String, value: Int)
10 |
11 | fun getBoolean(key: String, defaultValue: Boolean): Boolean
12 | fun putBoolean(key: String, value: Boolean)
13 |
14 | fun getLong(key: String, defaultValue: Long): Long
15 | fun putLong(key: String, value: Long)
16 |
17 | fun getString(key: String, defaultValue: String): String
18 | fun putString(key: String, value: String)
19 |
20 | fun getDouble(key: String, defaultValue: Double): Double
21 | fun putDouble(key: String, value: Double)
22 |
23 | fun getFloat(key: String, defaultValue: Float): Float
24 | fun putFloat(key: String, value: Float)
25 |
26 | fun getStringSet(key: String, defaultValue: Set): Set
27 | fun putStringSet(key: String, value: Set)
28 |
29 | fun getStringList(key: String, defaultValue: List): List
30 | fun putStringList(key: String, value: List)
31 |
32 | fun getParcelable(key: String, defaultValue: T): T
33 | fun putParcelable(key: String, value: T)
34 |
35 | operator fun contains(key: String): Boolean
36 |
37 | fun remove(key: String)
38 |
39 | fun clear()
40 |
41 | fun keyChanges(): Observable
42 | }
43 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/TypedValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.functions.Consumer
5 |
6 | abstract class TypedValue protected constructor(protected val delegate: KeyValueDelegate, val key: String, protected val defaultValue: T) {
7 |
8 | abstract fun get(): T
9 | abstract fun set(value: T)
10 |
11 | fun remove() = delegate.remove(key)
12 |
13 | open fun isSet(): Boolean = delegate.contains(key)
14 |
15 | fun asObservable(): Observable = delegate.keyChanges()
16 | .filter { k -> k == key }
17 | .startWith("")
18 | .map { get() }
19 |
20 | fun asConsumer(): Consumer = Consumer { set(it) }
21 | }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/BoolValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | class BoolValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Boolean = EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getBoolean(key, defaultValue)
10 | override fun set(value: Boolean) = delegate.putBoolean(key, value)
11 |
12 | fun toggle() = set(!get())
13 |
14 | companion object {
15 | const val EMPTY = false
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/DoubleValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | class DoubleValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Double = DoubleValue.EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getDouble(key, defaultValue)
10 | override fun set(value: Double) = delegate.putDouble(key, value)
11 |
12 |
13 | companion object {
14 | const val EMPTY = 0.0
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/FloatValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | class FloatValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Float = FloatValue.EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getFloat(key, defaultValue)
10 | override fun set(value: Float) = delegate.putFloat(key, value)
11 |
12 | companion object {
13 | const val EMPTY = 0.0f
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/IntValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | open class IntValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Int = IntValue.EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getInt(key, defaultValue)
10 | override fun set(value: Int) = delegate.putInt(key, value)
11 |
12 | fun increment() = set(get() + 1)
13 | fun decrement() = set(get() - 1)
14 |
15 | companion object {
16 | const val EMPTY = 0
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/LongValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | open class LongValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Long = LongValue.EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getLong(key, defaultValue)
10 | override fun set(value: Long) = delegate.putLong(key, value)
11 |
12 | companion object {
13 | const val EMPTY = 0L
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/ParcelableValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import android.os.Parcelable
4 | import io.denison.typedvalue.KeyValueDelegate
5 | import io.denison.typedvalue.TypedValue
6 |
7 | class ParcelableValue(delegate: KeyValueDelegate, key: String, defaultValue: T) : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getParcelable(key, defaultValue)
10 | override fun set(value: T) = delegate.putParcelable(key, value)
11 | }
12 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/StringListValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | class StringListValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: List = emptyList()) : TypedValue>(delegate, key, defaultValue) {
7 |
8 | override fun get() = delegate.getStringList(key, defaultValue)
9 | override fun set(value: List) = delegate.putStringList(key, value)
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/StringSetValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | class StringSetValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Set = emptySet()) : TypedValue>(delegate, key, defaultValue) {
7 |
8 | override fun get() = delegate.getStringSet(key, defaultValue)
9 | override fun set(value: Set) = delegate.putStringSet(key, value)
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/common/StringValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.common
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 |
6 | open class StringValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: String = StringValue.EMPTY)
7 | : TypedValue(delegate, key, defaultValue) {
8 |
9 | override fun get() = delegate.getString(key, defaultValue)
10 | override fun set(value: String) = delegate.putString(key, value)
11 |
12 | override fun isSet() = delegate.contains(key) && EMPTY != get()
13 |
14 | companion object {
15 | const val EMPTY = ""
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/delegate/BundleDelegate.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.delegate
2 |
3 | import android.os.Bundle
4 | import android.os.Parcelable
5 | import io.denison.typedvalue.KeyValueDelegate
6 | import io.reactivex.Observable
7 | import java.util.ArrayList
8 |
9 | class BundleDelegate(private val bundle: Bundle = Bundle()) : KeyValueDelegate {
10 | override fun getInt(key: String, defaultValue: Int) = bundle.getInt(key, defaultValue)
11 | override fun putInt(key: String, value: Int) = bundle.putInt(key, value)
12 |
13 | override fun getBoolean(key: String, defaultValue: Boolean) = bundle.getBoolean(key, defaultValue)
14 | override fun putBoolean(key: String, value: Boolean) = bundle.putBoolean(key, value)
15 |
16 | override fun getLong(key: String, defaultValue: Long) = bundle.getLong(key, defaultValue)
17 | override fun putLong(key: String, value: Long) = bundle.putLong(key, value)
18 |
19 | override fun getString(key: String, defaultValue: String): String = bundle.getString(key, defaultValue)
20 | override fun putString(key: String, value: String) = bundle.putString(key, value)
21 |
22 | override fun getDouble(key: String, defaultValue: Double) = bundle.getDouble(key, defaultValue)
23 | override fun putDouble(key: String, value: Double) = bundle.putDouble(key, value)
24 |
25 | override fun getFloat(key: String, defaultValue: Float) = bundle.getFloat(key, defaultValue)
26 | override fun putFloat(key: String, value: Float) = bundle.putFloat(key, value)
27 |
28 | override fun getStringSet(key: String, defaultValue: Set): Set = throw IllegalArgumentException("Unsupported type 'Set'")
29 | override fun putStringSet(key: String, value: Set) = throw IllegalArgumentException("Unsupported type 'Set'")
30 |
31 | override fun getStringList(key: String, defaultValue: List): List = bundle.getStringArrayList(key) ?: defaultValue
32 | override fun putStringList(key: String, value: List) = bundle.putStringArrayList(key, ArrayList(value))
33 |
34 | override fun getParcelable(key: String, defaultValue: T): T = bundle.getParcelable(key) ?: defaultValue
35 | override fun putParcelable(key: String, value: T) = bundle.putParcelable(key, value)
36 |
37 | override fun remove(key: String) = bundle.remove(key)
38 |
39 | override fun clear() = bundle.clear()
40 |
41 | override fun keyChanges(): Observable = Observable.empty()
42 |
43 | override operator fun contains(key: String) = bundle.containsKey(key)
44 | }
45 |
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/delegate/MapDelegate.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.delegate
2 |
3 | import android.os.Parcelable
4 | import io.denison.typedvalue.KeyValueDelegate
5 | import io.reactivex.Observable
6 | import java.util.concurrent.ConcurrentHashMap
7 |
8 | class MapDelegate(private val map: MutableMap = ConcurrentHashMap()) : KeyValueDelegate {
9 | override fun getInt(key: String, defaultValue: Int): Int = map[key] as Int? ?: defaultValue
10 | override fun putInt(key: String, value: Int) {
11 | map[key] = value
12 | }
13 |
14 | override fun getBoolean(key: String, defaultValue: Boolean) = map[key] as Boolean? ?: defaultValue
15 | override fun putBoolean(key: String, value: Boolean) {
16 | map[key] = value
17 | }
18 |
19 | override fun getLong(key: String, defaultValue: Long) = map[key] as Long? ?: defaultValue
20 | override fun putLong(key: String, value: Long) {
21 | map[key] = value
22 | }
23 |
24 | override fun getString(key: String, defaultValue: String) = map[key] as String? ?: defaultValue
25 | override fun putString(key: String, value: String) {
26 | map[key] = value
27 | }
28 |
29 | override fun getDouble(key: String, defaultValue: Double) = map[key] as Double? ?: defaultValue
30 | override fun putDouble(key: String, value: Double) {
31 | map[key] = value
32 | }
33 |
34 | override fun getFloat(key: String, defaultValue: Float) = map[key] as Float? ?: defaultValue
35 | override fun putFloat(key: String, value: Float) {
36 | map[key] = value
37 | }
38 |
39 | @Suppress("UNCHECKED_CAST")
40 | override fun getStringSet(key: String, defaultValue: Set): Set = map[key] as Set? ?: defaultValue
41 |
42 | override fun putStringSet(key: String, value: Set) {
43 | map[key] = value
44 | }
45 |
46 | @Suppress("UNCHECKED_CAST")
47 | override fun getStringList(key: String, defaultValue: List) = map[key] as List? ?: defaultValue
48 |
49 | override fun putStringList(key: String, value: List) {
50 | map[key] = value
51 | }
52 |
53 | @Suppress("UNCHECKED_CAST")
54 | override fun getParcelable(key: String, defaultValue: T): T = map[key] as T? ?: defaultValue
55 |
56 | override fun putParcelable(key: String, value: T) {
57 | map[key] = value
58 | }
59 |
60 | override fun contains(key: String): Boolean = map.contains(key)
61 |
62 | override fun remove(key: String) {
63 | map.remove(key)
64 | }
65 |
66 | override fun clear() = map.clear()
67 |
68 | override fun keyChanges(): Observable = Observable.empty()
69 | }
--------------------------------------------------------------------------------
/library/src/main/java/io/denison/typedvalue/delegate/PreferenceDelegate.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.delegate
2 |
3 | import android.content.SharedPreferences
4 | import android.os.Parcelable
5 | import io.denison.typedvalue.KeyValueDelegate
6 | import io.reactivex.Observable
7 | import io.reactivex.ObservableOnSubscribe
8 | import java.lang.Double.doubleToLongBits
9 | import java.lang.Double.longBitsToDouble
10 |
11 | class PreferenceDelegate(private val prefs: SharedPreferences) : KeyValueDelegate {
12 | private val keyChangesObservable: Observable
13 |
14 | init {
15 | keyChangesObservable = io.reactivex.Observable.create(ObservableOnSubscribe { emitter ->
16 | val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> emitter.onNext(key) }
17 | emitter.setCancellable { prefs.unregisterOnSharedPreferenceChangeListener(listener) }
18 | prefs.registerOnSharedPreferenceChangeListener(listener)
19 | }).share()
20 | }
21 |
22 | override fun getInt(key: String, defaultValue: Int) = prefs.getInt(key, defaultValue)
23 | override fun putInt(key: String, value: Int) = prefs.edit().putInt(key, value).apply()
24 |
25 | override fun getString(key: String, defaultValue: String): String = prefs.getString(key, defaultValue) ?: defaultValue
26 | override fun putString(key: String, value: String) = prefs.edit().putString(key, value).apply()
27 |
28 | override fun getBoolean(key: String, defaultValue: Boolean) = prefs.getBoolean(key, defaultValue)
29 | override fun putBoolean(key: String, value: Boolean) = prefs.edit().putBoolean(key, value).apply()
30 |
31 | override fun getLong(key: String, defaultValue: Long) = prefs.getLong(key, defaultValue)
32 | override fun putLong(key: String, value: Long) = prefs.edit().putLong(key, value).apply()
33 |
34 | override fun getDouble(key: String, defaultValue: Double) = longBitsToDouble(prefs.getLong(key, doubleToLongBits(defaultValue)))
35 | override fun putDouble(key: String, value: Double) = prefs.edit().putLong(key, doubleToLongBits(value)).apply()
36 |
37 | override fun getFloat(key: String, defaultValue: Float) = prefs.getFloat(key, defaultValue)
38 | override fun putFloat(key: String, value: Float) = prefs.edit().putFloat(key, value).apply()
39 |
40 | override fun getStringSet(key: String, defaultValue: Set): Set = prefs.getStringSet(key, defaultValue) ?: defaultValue
41 | override fun putStringSet(key: String, value: Set) = prefs.edit().putStringSet(key, value).apply()
42 |
43 | override fun getStringList(key: String, defaultValue: List) = throw IllegalArgumentException("Unsupported type 'List'")
44 | override fun putStringList(key: String, value: List) = throw IllegalArgumentException("Unsupported type 'List'")
45 |
46 | override fun getParcelable(key: String, defaultValue: T): T = throw IllegalArgumentException("Unsupported type 'Parcelable'")
47 | override fun putParcelable(key: String, value: T) = throw IllegalArgumentException("Unsupported type 'Parcelable'")
48 |
49 | override operator fun contains(key: String) = prefs.contains(key)
50 |
51 | override fun remove(key: String) = prefs.edit().remove(key).apply()
52 |
53 | override fun clear() = prefs.edit().clear().apply()
54 |
55 | override fun keyChanges(): Observable = keyChangesObservable
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/test/java/io/denison/typedvalue/BundleDelegateTest.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue
2 |
3 | import android.os.Bundle
4 | import io.denison.typedvalue.delegate.BundleDelegate
5 | import org.junit.Before
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 | import org.robolectric.RobolectricTestRunner
9 | import kotlin.test.assertEquals
10 | import kotlin.test.assertFails
11 | import kotlin.test.assertFalse
12 | import kotlin.test.assertTrue
13 |
14 | @RunWith(RobolectricTestRunner::class)
15 | class BundleDelegateTest {
16 | private lateinit var bundle: Bundle
17 | private lateinit var delegate: BundleDelegate
18 |
19 | @Before
20 | fun setUp() {
21 | bundle = Bundle().apply {
22 | putInt(KEY_INT_DEFAULT, 1)
23 | putBoolean(KEY_BOOLEAN_DEFAULT, true)
24 | putLong(KEY_LONG_DEFAULT, 1)
25 | putString(KEY_STRING_DEFAULT, "default")
26 | putDouble(KEY_DOUBLE_DEFAULT, 1.0)
27 | putFloat(KEY_FLOAT_DEFAULT, 1f)
28 | putStringArrayList(KEY_STRING_LIST_DEFAULT, arrayListOf("default"))
29 | putParcelable(KEY_PARCELABLE_DEFAULT, PARCELABLE_BUNDLE)
30 | }
31 | delegate = BundleDelegate(bundle)
32 | }
33 |
34 | @Test
35 | fun testGetInt() {
36 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2))
37 | assertEquals(2, delegate.getInt(KEY_INT, 2))
38 | }
39 |
40 | @Test
41 | fun testPutInt() {
42 | delegate.putInt(KEY_INT, 1)
43 | assertEquals(1, bundle.getInt(KEY_INT))
44 | }
45 |
46 | @Test
47 | fun testGetBoolean() {
48 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) }
49 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) }
50 | }
51 |
52 | @Test
53 | fun testPutBoolean() {
54 | delegate.putBoolean(KEY_BOOLEAN, true)
55 | assertEquals(true, bundle.getBoolean(KEY_BOOLEAN))
56 | }
57 |
58 | @Test
59 | fun testGetLong() {
60 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2))
61 | assertEquals(2, delegate.getLong(KEY_LONG, 2))
62 | }
63 |
64 | @Test
65 | fun testPutLong() {
66 | delegate.putLong(KEY_LONG, 1)
67 | assertEquals(1, bundle.getLong(KEY_LONG))
68 | }
69 |
70 | @Test
71 | fun testGetString() {
72 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val"))
73 | assertEquals("val", delegate.getString(KEY_STRING, "val"))
74 | }
75 |
76 | @Test
77 | fun testPutString() {
78 | delegate.putString(KEY_STRING, "val")
79 | assertEquals("val", bundle.getString(KEY_STRING))
80 | }
81 |
82 | @Test
83 | fun testGetDouble() {
84 | assertEquals(1.0, delegate.getDouble(KEY_DOUBLE_DEFAULT, 2.0))
85 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0))
86 | }
87 |
88 | @Test
89 | fun testPutDouble() {
90 | delegate.putDouble(KEY_DOUBLE, 2.0)
91 | assertEquals(2.0, bundle.getDouble(KEY_DOUBLE))
92 | }
93 |
94 | @Test
95 | fun testGetFloat() {
96 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f))
97 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f))
98 | }
99 |
100 | @Test
101 | fun testPutFloat() {
102 | delegate.putFloat(KEY_FLOAT, 2f)
103 | assertEquals(2f, bundle.getFloat(KEY_FLOAT))
104 | }
105 |
106 | @Test
107 | fun testGetStringSet() {
108 | assertFails { delegate.getStringSet(KEY_STRING_SET, emptySet()) }
109 | }
110 |
111 | @Test
112 | fun testPutStringSet() {
113 | assertFails { delegate.putStringSet(KEY_STRING_SET, setOf()) }
114 | }
115 |
116 | @Test
117 | fun testGetStringList() {
118 | assertEquals(arrayListOf("default"), delegate.getStringList(KEY_STRING_LIST_DEFAULT, emptyList()))
119 | assertEquals(emptyList(), delegate.getStringList(KEY_STRING_LIST, emptyList()))
120 | }
121 |
122 | @Test
123 | fun testPutStringList() {
124 | delegate.putStringList(KEY_STRING_LIST, arrayListOf("val"))
125 | assertEquals(arrayListOf("val"), bundle.getStringArrayList(KEY_STRING_LIST))
126 | }
127 |
128 | @Test
129 | fun testGetParcelable() {
130 | val bundle = Bundle()
131 | assertEquals(PARCELABLE_BUNDLE, delegate.getParcelable(KEY_PARCELABLE_DEFAULT, Bundle()))
132 | assertEquals(bundle, delegate.getParcelable(KEY_PARCELABLE, bundle))
133 | }
134 |
135 | @Test
136 | fun testPutParcelable() {
137 | delegate.putParcelable(KEY_PARCELABLE, PARCELABLE_BUNDLE)
138 | assertEquals(PARCELABLE_BUNDLE, bundle.getParcelable(KEY_PARCELABLE)!!)
139 | }
140 |
141 | @Test
142 | fun testContains() {
143 | assertTrue { KEY_INT_DEFAULT in delegate }
144 | assertTrue { KEY_INT !in delegate }
145 | }
146 |
147 | @Test
148 | fun testRemove() {
149 | delegate.remove(KEY_INT_DEFAULT)
150 | assertTrue { KEY_INT_DEFAULT !in delegate }
151 | assertFalse { bundle.containsKey(KEY_INT_DEFAULT) }
152 | }
153 |
154 | @Test
155 | fun testClear() {
156 | delegate.clear()
157 | assertTrue { KEY_INT_DEFAULT !in delegate }
158 | assertTrue { bundle.isEmpty }
159 | }
160 |
161 |
162 | private companion object {
163 | const val KEY_INT = ".KEY_INT"
164 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT"
165 | const val KEY_BOOLEAN = "KEY_BOOLEAN"
166 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT"
167 | const val KEY_LONG = "KEY_LONG"
168 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT"
169 | const val KEY_STRING = "KEY_STRING"
170 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT"
171 | const val KEY_DOUBLE = "KEY_DOUBLE"
172 | const val KEY_DOUBLE_DEFAULT = "KEY_DOUBLE_DEFAULT"
173 | const val KEY_FLOAT = "KEY_FLOAT"
174 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT"
175 | const val KEY_STRING_SET = "KEY_STRING_SET"
176 | const val KEY_STRING_LIST = "KEY_STRING_LIST"
177 | const val KEY_STRING_LIST_DEFAULT = "KEY_STRING_LIST_DEFAULT"
178 | const val KEY_PARCELABLE = "KEY_PARCELABLE"
179 | const val KEY_PARCELABLE_DEFAULT = "KEY_PARCELABLE_DEFAULT"
180 |
181 | val PARCELABLE_BUNDLE = Bundle().apply { putInt(KEY_INT, 1) }
182 | }
183 | }
--------------------------------------------------------------------------------
/library/src/test/java/io/denison/typedvalue/MapDelegateTest.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue
2 |
3 | import android.os.Bundle
4 | import io.denison.typedvalue.delegate.MapDelegate
5 | import org.junit.Before
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 | import org.robolectric.RobolectricTestRunner
9 | import kotlin.test.assertEquals
10 | import kotlin.test.assertFails
11 | import kotlin.test.assertFalse
12 | import kotlin.test.assertTrue
13 |
14 | @RunWith(RobolectricTestRunner::class)
15 | class MapDelegateTest {
16 | private lateinit var map: MutableMap
17 | private lateinit var delegate: MapDelegate
18 |
19 | @Before
20 | fun setUp() {
21 | map = mutableMapOf(
22 | KEY_INT_DEFAULT to 1,
23 | KEY_BOOLEAN_DEFAULT to true,
24 | KEY_LONG_DEFAULT to 1L,
25 | KEY_STRING_DEFAULT to "default",
26 | KEY_DOUBLE_DEFAULT to 1.0,
27 | KEY_FLOAT_DEFAULT to 1f,
28 | KEY_STRING_LIST_DEFAULT to arrayListOf("default"),
29 | KEY_STRING_SET_DEFAULT to setOf("default"),
30 | KEY_PARCELABLE_DEFAULT to PARCELABLE_BUNDLE
31 | )
32 | delegate = MapDelegate(map)
33 | }
34 |
35 | @Test
36 | fun testGetInt() {
37 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2))
38 | assertEquals(2, delegate.getInt(KEY_INT, 2))
39 | }
40 |
41 | @Test
42 | fun testPutInt() {
43 | delegate.putInt(KEY_INT, 1)
44 | assertEquals(1, map[KEY_INT])
45 | }
46 |
47 | @Test
48 | fun testGetBoolean() {
49 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) }
50 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) }
51 | }
52 |
53 | @Test
54 | fun testPutBoolean() {
55 | delegate.putBoolean(KEY_BOOLEAN, true)
56 | assertEquals(true, map[KEY_BOOLEAN])
57 | }
58 |
59 | @Test
60 | fun testGetLong() {
61 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2))
62 | assertEquals(2, delegate.getLong(KEY_LONG, 2))
63 | }
64 |
65 | @Test
66 | fun testPutLong() {
67 | delegate.putLong(KEY_LONG, 1)
68 | assertEquals(1L, map[KEY_LONG])
69 | }
70 |
71 | @Test
72 | fun testGetString() {
73 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val"))
74 | assertEquals("val", delegate.getString(KEY_STRING, "val"))
75 | }
76 |
77 | @Test
78 | fun testPutString() {
79 | delegate.putString(KEY_STRING, "val")
80 | assertEquals("val", map[KEY_STRING])
81 | }
82 |
83 | @Test
84 | fun testGetDouble() {
85 | assertEquals(1.0, delegate.getDouble(KEY_DOUBLE_DEFAULT, 2.0))
86 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0))
87 | }
88 |
89 | @Test
90 | fun testPutDouble() {
91 | delegate.putDouble(KEY_DOUBLE, 2.0)
92 | assertEquals(2.0, map[KEY_DOUBLE])
93 | }
94 |
95 | @Test
96 | fun testGetFloat() {
97 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f))
98 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f))
99 | }
100 |
101 | @Test
102 | fun testPutFloat() {
103 | delegate.putFloat(KEY_FLOAT, 2f)
104 | assertEquals(2f, map[KEY_FLOAT])
105 | }
106 |
107 | @Test
108 | fun testGetStringSet() {
109 | assertEquals(setOf("default"), delegate.getStringSet(KEY_STRING_SET_DEFAULT, emptySet()))
110 | assertEquals(emptySet(), delegate.getStringSet(KEY_STRING_SET, emptySet()))
111 | }
112 |
113 | @Test
114 | fun testPutStringSet() {
115 | delegate.putStringSet(KEY_STRING_SET, setOf("val"))
116 | assertEquals(setOf("val"), map[KEY_STRING_SET])
117 | }
118 |
119 | @Test
120 | fun testGetStringList() {
121 | assertEquals(arrayListOf("default"), delegate.getStringList(KEY_STRING_LIST_DEFAULT, emptyList()))
122 | assertEquals(emptyList(), delegate.getStringList(KEY_STRING_LIST, emptyList()))
123 | }
124 |
125 | @Test
126 | fun testPutStringList() {
127 | delegate.putStringList(KEY_STRING_LIST, arrayListOf("val"))
128 | assertEquals(arrayListOf("val"), map[KEY_STRING_LIST])
129 | }
130 |
131 | @Test
132 | fun testGetParcelable() {
133 | val bundle = Bundle()
134 | assertEquals(PARCELABLE_BUNDLE, delegate.getParcelable(KEY_PARCELABLE_DEFAULT, Bundle()))
135 | assertEquals(bundle, delegate.getParcelable(KEY_PARCELABLE, bundle))
136 | }
137 |
138 | @Test
139 | fun testPutParcelable() {
140 | delegate.putParcelable(KEY_PARCELABLE, PARCELABLE_BUNDLE)
141 | assertEquals(PARCELABLE_BUNDLE, map[KEY_PARCELABLE])
142 | }
143 |
144 | @Test
145 | fun testContains() {
146 | assertTrue { KEY_INT_DEFAULT in delegate }
147 | assertTrue { KEY_INT !in delegate }
148 | }
149 |
150 | @Test
151 | fun testRemove() {
152 | delegate.remove(KEY_INT_DEFAULT)
153 | assertTrue { KEY_INT_DEFAULT !in delegate }
154 | assertFalse { map.containsKey(KEY_INT_DEFAULT) }
155 | }
156 |
157 | @Test
158 | fun testClear() {
159 | delegate.clear()
160 | assertTrue { KEY_INT_DEFAULT !in delegate }
161 | assertTrue { map.isEmpty() }
162 | }
163 |
164 |
165 | private companion object {
166 | const val KEY_INT = ".KEY_INT"
167 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT"
168 | const val KEY_BOOLEAN = "KEY_BOOLEAN"
169 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT"
170 | const val KEY_LONG = "KEY_LONG"
171 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT"
172 | const val KEY_STRING = "KEY_STRING"
173 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT"
174 | const val KEY_DOUBLE = "KEY_DOUBLE"
175 | const val KEY_DOUBLE_DEFAULT = "KEY_DOUBLE_DEFAULT"
176 | const val KEY_FLOAT = "KEY_FLOAT"
177 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT"
178 | const val KEY_STRING_SET = "KEY_STRING_SET"
179 | const val KEY_STRING_SET_DEFAULT = "KEY_STRING_SET_DEFAULT"
180 | const val KEY_STRING_LIST = "KEY_STRING_LIST"
181 | const val KEY_STRING_LIST_DEFAULT = "KEY_STRING_LIST_DEFAULT"
182 | const val KEY_PARCELABLE = "KEY_PARCELABLE"
183 | const val KEY_PARCELABLE_DEFAULT = "KEY_PARCELABLE_DEFAULT"
184 |
185 | val PARCELABLE_BUNDLE = Bundle().apply { putInt(KEY_INT, 1) }
186 | }
187 | }
--------------------------------------------------------------------------------
/library/src/test/java/io/denison/typedvalue/PreferenceDelegateTest.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue
2 |
3 | import android.content.SharedPreferences
4 | import android.os.Bundle
5 | import android.preference.PreferenceManager
6 | import io.denison.typedvalue.delegate.PreferenceDelegate
7 | import org.junit.Before
8 | import org.junit.Test
9 | import org.junit.runner.RunWith
10 | import org.robolectric.RobolectricTestRunner
11 | import org.robolectric.RuntimeEnvironment
12 | import kotlin.test.assertEquals
13 | import kotlin.test.assertFails
14 | import kotlin.test.assertFalse
15 | import kotlin.test.assertTrue
16 |
17 | @RunWith(RobolectricTestRunner::class)
18 | class PreferenceDelegateTest {
19 | private lateinit var sharedPreferences: SharedPreferences
20 | private lateinit var delegate: PreferenceDelegate
21 |
22 | @Before
23 | fun setUp() {
24 | sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application).apply {
25 | edit()
26 | .putInt(KEY_INT_DEFAULT, 1)
27 | .putBoolean(KEY_BOOLEAN_DEFAULT, true)
28 | .putLong(KEY_LONG_DEFAULT, 1)
29 | .putString(KEY_STRING_DEFAULT, "default")
30 | .putFloat(KEY_FLOAT_DEFAULT, 1f)
31 | .putStringSet(KEY_STRING_SET_DEFAULT, setOf("default"))
32 | .commit()
33 | }
34 | delegate = PreferenceDelegate(sharedPreferences)
35 | }
36 |
37 | @Test
38 | fun testGetInt() {
39 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2))
40 | assertEquals(2, delegate.getInt(KEY_INT, 2))
41 | }
42 |
43 | @Test
44 | fun testPutInt() {
45 | delegate.putInt(KEY_INT, 1)
46 | assertEquals(1, sharedPreferences.getInt(KEY_INT, 0))
47 | }
48 |
49 | @Test
50 | fun testGetBoolean() {
51 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) }
52 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) }
53 | }
54 |
55 | @Test
56 | fun testPutBoolean() {
57 | delegate.putBoolean(KEY_BOOLEAN, true)
58 | assertEquals(true, sharedPreferences.getBoolean(KEY_BOOLEAN, false))
59 | }
60 |
61 | @Test
62 | fun testGetLong() {
63 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2))
64 | assertEquals(2, delegate.getLong(KEY_LONG, 2))
65 | }
66 |
67 | @Test
68 | fun testPutLong() {
69 | delegate.putLong(KEY_LONG, 1)
70 | assertEquals(1, sharedPreferences.getLong(KEY_LONG, 0))
71 | }
72 |
73 | @Test
74 | fun testGetString() {
75 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val"))
76 | assertEquals("val", delegate.getString(KEY_STRING, "val"))
77 | }
78 |
79 | @Test
80 | fun testPutString() {
81 | delegate.putString(KEY_STRING, "val")
82 | assertEquals("val", sharedPreferences.getString(KEY_STRING, ""))
83 | }
84 |
85 | @Test
86 | fun testGetDouble() {
87 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0))
88 | }
89 |
90 | @Test
91 | fun testPutDouble() {
92 | delegate.putDouble(KEY_DOUBLE, 2.0)
93 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 0.0))
94 | }
95 |
96 | @Test
97 | fun testGetFloat() {
98 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f))
99 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f))
100 | }
101 |
102 | @Test
103 | fun testPutFloat() {
104 | delegate.putFloat(KEY_FLOAT, 2f)
105 | assertEquals(2f, sharedPreferences.getFloat(KEY_FLOAT, 0f))
106 | }
107 |
108 | @Test
109 | fun testGetStringSet() {
110 | val set = setOf("val")
111 | assertEquals(setOf("default"), delegate.getStringSet(KEY_STRING_SET_DEFAULT, emptySet()))
112 | assertEquals(set, delegate.getStringSet(KEY_STRING_SET, set))
113 | }
114 |
115 | @Test
116 | fun testPutStringSet() {
117 | delegate.putStringSet(KEY_STRING_SET, setOf("val"))
118 | assertEquals(setOf("val"), sharedPreferences.getStringSet(KEY_STRING_SET, emptySet()))
119 | }
120 |
121 | @Test
122 | fun testGetStringList() {
123 | assertFails { delegate.getStringList(KEY_STRING_LIST, listOf()) }
124 | }
125 |
126 | @Test
127 | fun testPutStringList() {
128 | assertFails { delegate.putStringList(KEY_STRING_LIST, listOf()) }
129 | }
130 |
131 | @Test
132 | fun testGetParcelable() {
133 | assertFails { delegate.getParcelable(KEY_PARCELABLE, Bundle()) }
134 | }
135 |
136 | @Test
137 | fun testPutParcelable() {
138 | assertFails { delegate.putParcelable(KEY_PARCELABLE, Bundle()) }
139 | }
140 |
141 | @Test
142 | fun testContains() {
143 | assertTrue { KEY_INT_DEFAULT in delegate }
144 | assertTrue { KEY_INT !in delegate }
145 | }
146 |
147 | @Test
148 | fun testRemove() {
149 | delegate.remove(KEY_INT_DEFAULT)
150 | assertTrue { KEY_INT_DEFAULT !in delegate }
151 | assertFalse { sharedPreferences.contains(KEY_INT_DEFAULT) }
152 | }
153 |
154 | @Test
155 | fun testClear() {
156 | delegate.clear()
157 | assertTrue { KEY_INT_DEFAULT !in delegate }
158 | assertTrue { sharedPreferences.all.isEmpty() }
159 | }
160 |
161 |
162 | private companion object {
163 | const val KEY_INT = ".KEY_INT"
164 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT"
165 | const val KEY_BOOLEAN = "KEY_BOOLEAN"
166 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT"
167 | const val KEY_LONG = "KEY_LONG"
168 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT"
169 | const val KEY_STRING = "KEY_STRING"
170 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT"
171 | const val KEY_DOUBLE = "KEY_DOUBLE"
172 | const val KEY_FLOAT = "KEY_FLOAT"
173 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT"
174 | const val KEY_STRING_SET_DEFAULT = "KEY_STRING_SET_DEFAULT"
175 | const val KEY_STRING_SET = "KEY_STRING_SET"
176 | const val KEY_STRING_LIST = "KEY_STRING_LIST"
177 | const val KEY_PARCELABLE = "KEY_PARCELABLE"
178 | }
179 | }
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android-extensions'
3 | apply plugin: 'kotlin-android'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android {
7 | compileSdkVersion versions.compileSdk
8 | buildToolsVersion versions.buildTools
9 |
10 | defaultConfig {
11 | applicationId "io.denison.typedvalue.sample"
12 |
13 | minSdkVersion 19
14 | targetSdkVersion 28
15 | versionCode 1
16 | versionName "1.0"
17 | }
18 | }
19 |
20 | dependencies {
21 | implementation project(':library')
22 |
23 | implementation libraries.kotlinStdLib
24 | implementation libraries.androidAppCompat
25 | implementation libraries.androidAnnotations
26 | implementation libraries.timber
27 | implementation libraries.rxJava2
28 | implementation libraries.rxAndroid2
29 | implementation libraries.rxKotlin
30 | implementation libraries.rxRelay
31 | implementation libraries.constraintLayout
32 | implementation libraries.lottie
33 |
34 | implementation libraries.dagger
35 | kapt libraries.daggerCompiler
36 | }
37 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 |
6 | class MainActivity: AppCompatActivity() {
7 | override fun onCreate(savedInstanceState: Bundle?) {
8 | super.onCreate(savedInstanceState)
9 | setContentView(R.layout.ac_main)
10 | }
11 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/SampleApplication.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import io.denison.typedvalue.sample.di.AppComponent
6 | import io.denison.typedvalue.sample.di.AppModule
7 | import io.denison.typedvalue.sample.di.DaggerAppComponent
8 |
9 | class SampleApplication : Application() {
10 | private lateinit var component: AppComponent
11 |
12 | override fun onCreate() {
13 | super.onCreate()
14 |
15 | component = DaggerAppComponent.builder()
16 | .appModule(AppModule(this))
17 | .build()
18 | }
19 |
20 | companion object {
21 | fun appComponent(context: Context): AppComponent = (context.applicationContext as SampleApplication).component
22 | }
23 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/di/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.di
2 |
3 | import dagger.Component
4 | import io.denison.typedvalue.sample.preferences.AppPreferences
5 | import javax.inject.Singleton
6 |
7 | @Singleton
8 | @Component(modules = [AppModule::class])
9 | interface AppComponent {
10 | fun preferences(): AppPreferences
11 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/di/AppModule.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.di
2 |
3 | import android.app.Application
4 | import dagger.Module
5 | import dagger.Provides
6 | import io.denison.typedvalue.sample.SampleApplication
7 | import io.denison.typedvalue.sample.preferences.AppPreferences
8 | import io.denison.typedvalue.sample.preferences.AppPreferencesImpl
9 | import javax.inject.Singleton
10 |
11 | @Module
12 | class AppModule(private val app: SampleApplication) {
13 | @Singleton
14 | @Provides
15 | fun provideApplication(): Application = app
16 |
17 | @Singleton
18 | @Provides
19 | fun provideAppPreferences(app: Application): AppPreferences = AppPreferencesImpl(app)
20 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/di/ViewScope.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.di
2 |
3 | import javax.inject.Scope
4 | import kotlin.annotation.AnnotationRetention.RUNTIME
5 |
6 | @Scope
7 | @Retention(RUNTIME)
8 | annotation class ViewScope
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/model/AnimationType.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.model
2 |
3 | enum class AnimationType {
4 | CONFETTI,
5 | PLANE,
6 | FAVORITE
7 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/mvp/MvpPresenter.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.mvp
2 |
3 | import androidx.annotation.UiThread
4 |
5 | interface MvpPresenter {
6 | @UiThread fun attachView(view: V)
7 | @UiThread fun detachView()
8 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/mvp/MvpView.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.mvp
2 |
3 | interface MvpView
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/mvp/presenter/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.mvp.presenter
2 |
3 | import androidx.annotation.CallSuper
4 | import androidx.annotation.UiThread
5 | import io.denison.typedvalue.sample.mvp.MvpPresenter
6 | import io.denison.typedvalue.sample.mvp.MvpView
7 | import io.reactivex.Completable
8 | import io.reactivex.Maybe
9 | import io.reactivex.Observable
10 | import io.reactivex.Single
11 | import io.reactivex.disposables.CompositeDisposable
12 | import io.reactivex.disposables.Disposable
13 | import io.reactivex.exceptions.OnErrorNotImplementedException
14 | import java.lang.ref.WeakReference
15 |
16 | open class BasePresenter : MvpPresenter {
17 | private lateinit var viewRef: WeakReference
18 |
19 | private val viewDisposables: CompositeDisposable = CompositeDisposable()
20 |
21 | protected val view: V?
22 | get() = viewRef.get()
23 |
24 | @CallSuper
25 | @UiThread
26 | override fun attachView(view: V) {
27 | viewRef = WeakReference(view)
28 | }
29 |
30 | @CallSuper
31 | @UiThread
32 | override fun detachView() {
33 | viewDisposables.clear()
34 | viewRef.clear()
35 | }
36 |
37 | protected fun Observable.subscribeUntilDetach(
38 | onNext: (T) -> Unit = {},
39 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) },
40 | onComplete: () -> Unit = {}
41 | ): Disposable = subscribe(onNext, onError, onComplete).apply { viewDisposables.add(this) }
42 |
43 | protected fun Maybe.subscribeUntilDetach(
44 | onSuccess: (T) -> Unit = {},
45 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) },
46 | onComplete: () -> Unit = {}
47 | ): Disposable = subscribe(onSuccess, onError, onComplete).apply { viewDisposables.add(this) }
48 |
49 | protected fun Single.subscribeUntilDetach(
50 | onSuccess: (T) -> Unit = {},
51 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) }
52 | ): Disposable = subscribe(onSuccess, onError).apply { viewDisposables.add(this) }
53 |
54 | protected fun Completable.subscribeUntilDetach(
55 | onComplete: () -> Unit = {},
56 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) }
57 | ): Disposable = subscribe(onComplete, onError).apply { viewDisposables.add(this) }
58 | }
59 |
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/mvp/view/MvpConstraintLayout.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.mvp.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.constraintlayout.widget.ConstraintLayout
6 | import io.denison.typedvalue.sample.mvp.MvpPresenter
7 | import io.denison.typedvalue.sample.mvp.MvpView
8 |
9 | abstract class MvpConstraintLayout>(context: Context, attrs: AttributeSet?)
10 | : ConstraintLayout(context, attrs), MvpView {
11 |
12 | protected val presenter: P by lazy { createPresenter() }
13 |
14 | override fun onAttachedToWindow() {
15 | super.onAttachedToWindow()
16 | if (!isInEditMode) {
17 | presenter.attachView(getMvpView())
18 | }
19 | }
20 |
21 | override fun onDetachedFromWindow() {
22 | if (!isInEditMode) {
23 | presenter.detachView()
24 | }
25 | super.onDetachedFromWindow()
26 | }
27 |
28 | @Suppress("UNCHECKED_CAST")
29 | open fun getMvpView() = this as V
30 |
31 | abstract fun createPresenter(): P
32 | }
33 |
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferences.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.preferences
2 |
3 | import io.denison.typedvalue.common.BoolValue
4 | import io.denison.typedvalue.common.FloatValue
5 | import io.denison.typedvalue.sample.preferences.value.AnimationTypeValue
6 |
7 | interface AppPreferences {
8 | val animationTypeValue: AnimationTypeValue
9 | val scaleValue: FloatValue
10 | val messageShownValue: BoolValue
11 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferencesImpl.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.preferences
2 |
3 | import android.app.Application
4 | import android.preference.PreferenceManager
5 | import io.denison.typedvalue.common.BoolValue
6 | import io.denison.typedvalue.common.FloatValue
7 | import io.denison.typedvalue.delegate.PreferenceDelegate
8 | import io.denison.typedvalue.sample.model.AnimationType
9 | import io.denison.typedvalue.sample.preferences.value.AnimationTypeValue
10 |
11 | class AppPreferencesImpl(app: Application) : AppPreferences {
12 | private val delegate = PreferenceDelegate(PreferenceManager.getDefaultSharedPreferences(app))
13 |
14 | override val animationTypeValue: AnimationTypeValue by lazy { AnimationTypeValue(delegate, KEY_ANIMATION_TYPE, AnimationType.CONFETTI) }
15 | override val scaleValue: FloatValue by lazy { FloatValue(delegate, KEY_SCALE, 0.8f) }
16 | override val messageShownValue: BoolValue by lazy { BoolValue(delegate, KEY_MESSAGE_SHOWN) }
17 |
18 | private companion object {
19 | const val KEY_ANIMATION_TYPE = ".key_animation_type"
20 | const val KEY_SCALE = ".key_scale"
21 | const val KEY_MESSAGE_SHOWN = ".key_message_shown"
22 | }
23 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/preferences/value/AnimationTypeValue.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.preferences.value
2 |
3 | import io.denison.typedvalue.KeyValueDelegate
4 | import io.denison.typedvalue.TypedValue
5 | import io.denison.typedvalue.sample.model.AnimationType
6 |
7 | class AnimationTypeValue(delegate: KeyValueDelegate, key: String, defaultValue: AnimationType) : TypedValue(delegate, key, defaultValue) {
8 | override fun get(): AnimationType = AnimationType.valueOf(delegate.getString(key, defaultValue.name))
9 | override fun set(value: AnimationType) = delegate.putString(key, value.name)
10 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationComponent.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.animation
2 |
3 | import dagger.Component
4 | import io.denison.typedvalue.sample.di.AppComponent
5 | import io.denison.typedvalue.sample.di.ViewScope
6 |
7 | @ViewScope
8 | @Component(dependencies = [AppComponent::class])
9 | interface AnimationComponent {
10 | fun presenter(): AnimationPresenter
11 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationLayout.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.animation
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import io.denison.typedvalue.sample.R
6 | import io.denison.typedvalue.sample.SampleApplication
7 | import io.denison.typedvalue.sample.model.AnimationType
8 | import io.denison.typedvalue.sample.mvp.view.MvpConstraintLayout
9 | import kotlinx.android.synthetic.main.ac_main.view.lottieView
10 |
11 | class AnimationLayout(context: Context, attributeSet: AttributeSet) : MvpConstraintLayout(context, attributeSet), AnimationView {
12 | private lateinit var component: AnimationComponent
13 |
14 | override fun onAttachedToWindow() {
15 | injectDependencies()
16 | super.onAttachedToWindow()
17 | }
18 |
19 | override fun bindTo(type: AnimationType) {
20 | lottieView.setAnimation(when (type) {
21 | AnimationType.FAVORITE -> R.raw.favourite
22 | AnimationType.CONFETTI -> R.raw.confetti
23 | AnimationType.PLANE -> R.raw.plane
24 | })
25 | lottieView.playAnimation()
26 | }
27 |
28 | override fun bindTo(scale: Float) {
29 | lottieView.scale = scale
30 | }
31 |
32 |
33 | override fun createPresenter(): AnimationPresenter = component.presenter()
34 |
35 | private fun injectDependencies() {
36 | if (isInEditMode)
37 | return
38 |
39 | component = DaggerAnimationComponent.builder()
40 | .appComponent(SampleApplication.appComponent(context))
41 | .build()
42 | }
43 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationPresenter.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.animation
2 |
3 | import io.denison.typedvalue.sample.mvp.presenter.BasePresenter
4 | import io.denison.typedvalue.sample.preferences.AppPreferences
5 | import io.reactivex.android.schedulers.AndroidSchedulers
6 | import io.reactivex.schedulers.Schedulers
7 | import timber.log.Timber
8 | import javax.inject.Inject
9 |
10 | class AnimationPresenter @Inject constructor(
11 | private val appPreferences: AppPreferences
12 | ) : BasePresenter() {
13 |
14 | override fun attachView(view: AnimationView) {
15 | super.attachView(view)
16 |
17 | appPreferences.animationTypeValue.asObservable().startWith(appPreferences.animationTypeValue.get())
18 | .subscribeOn(Schedulers.io())
19 | .observeOn(AndroidSchedulers.mainThread())
20 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e)
21 |
22 | appPreferences.scaleValue.asObservable().startWith(appPreferences.scaleValue.get())
23 | .subscribeOn(Schedulers.io())
24 | .observeOn(AndroidSchedulers.mainThread())
25 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e)
26 |
27 | }
28 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationView.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.animation
2 |
3 | import io.denison.typedvalue.sample.model.AnimationType
4 | import io.denison.typedvalue.sample.mvp.MvpView
5 |
6 | interface AnimationView : MvpView {
7 | fun bindTo(type: AnimationType)
8 | fun bindTo(scale: Float)
9 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsComponent.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.settings
2 |
3 | import dagger.Component
4 | import io.denison.typedvalue.sample.di.AppComponent
5 | import io.denison.typedvalue.sample.di.ViewScope
6 |
7 | @ViewScope
8 | @Component(dependencies = [AppComponent::class])
9 | interface SettingsComponent {
10 | fun presenter(): SettingsPresenter
11 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsLayout.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.settings
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.widget.SeekBar
6 | import android.widget.SeekBar.OnSeekBarChangeListener
7 | import android.widget.Toast
8 | import com.jakewharton.rxrelay2.PublishRelay
9 | import io.denison.typedvalue.sample.R
10 | import io.denison.typedvalue.sample.SampleApplication
11 | import io.denison.typedvalue.sample.mvp.view.MvpConstraintLayout
12 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewAction
13 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel
14 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel.Content
15 | import io.reactivex.Observable
16 | import kotlinx.android.synthetic.main.ac_main.view.imageTypeSetting
17 | import kotlinx.android.synthetic.main.ac_main.view.imageTypeSettingText
18 | import kotlinx.android.synthetic.main.ac_main.view.scaleSettingValue
19 |
20 | class SettingsLayout(context: Context, attributeSet: AttributeSet) : MvpConstraintLayout(context, attributeSet), SettingsView {
21 | private lateinit var component: SettingsComponent
22 | private lateinit var model: ViewModel.Content
23 | private val actionsRelay = PublishRelay.create()
24 |
25 | override fun onAttachedToWindow() {
26 | injectDependencies()
27 | super.onAttachedToWindow()
28 | }
29 |
30 | override fun onFinishInflate() {
31 | super.onFinishInflate()
32 | imageTypeSetting.setOnClickListener { actionsRelay.accept(ViewAction.AnimationTypeClicked(model.type)) }
33 | scaleSettingValue.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
34 | override fun onStartTrackingTouch(seekBar: SeekBar?) {}
35 | override fun onStopTrackingTouch(seekBar: SeekBar?) {}
36 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
37 | if (fromUser)
38 | actionsRelay.accept(ViewAction.ScaleChanged(progress))
39 | }
40 | })
41 | }
42 |
43 | override fun bindTo(model: ViewModel) = when (model) {
44 | is ViewModel.Content -> bindContent(model)
45 | }
46 |
47 | private fun bindContent(model: Content) {
48 | this.model = model
49 | imageTypeSettingText.text = model.type.name
50 | scaleSettingValue.progress = model.scale
51 | }
52 |
53 | override fun showWelcomeMessage() {
54 | Toast.makeText(context, R.string.animation_playground, Toast.LENGTH_LONG).show()
55 | }
56 |
57 | override fun observeViewActions(): Observable = actionsRelay
58 |
59 | override fun createPresenter(): SettingsPresenter = component.presenter()
60 |
61 | private fun injectDependencies() {
62 | if (isInEditMode)
63 | return
64 |
65 | component = DaggerSettingsComponent.builder()
66 | .appComponent(SampleApplication.appComponent(context))
67 | .build()
68 | }
69 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsPresenter.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.settings
2 |
3 | import io.denison.typedvalue.sample.model.AnimationType
4 | import io.denison.typedvalue.sample.mvp.presenter.BasePresenter
5 | import io.denison.typedvalue.sample.preferences.AppPreferences
6 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewAction
7 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel
8 | import io.reactivex.android.schedulers.AndroidSchedulers
9 | import io.reactivex.rxkotlin.Observables
10 | import io.reactivex.schedulers.Schedulers
11 | import timber.log.Timber
12 | import javax.inject.Inject
13 |
14 | class SettingsPresenter @Inject constructor(
15 | private val appPreferences: AppPreferences
16 | ) : BasePresenter() {
17 |
18 | override fun attachView(view: SettingsView) {
19 | super.attachView(view)
20 |
21 | Observables.combineLatest(
22 | appPreferences.animationTypeValue.asObservable().startWith(appPreferences.animationTypeValue.get()),
23 | appPreferences.scaleValue.asObservable().startWith(appPreferences.scaleValue.get()),
24 | { type, scale -> ViewModel.Content(type, (scale * 100).toInt()) }
25 | )
26 | .subscribeOn(Schedulers.io())
27 | .observeOn(AndroidSchedulers.mainThread())
28 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e)
29 |
30 | view.observeViewActions()
31 | .subscribeOn(Schedulers.io())
32 | .observeOn(Schedulers.io())
33 | .subscribeUntilDetach(onNext = this::handleViewAction, onError = Timber::e)
34 |
35 | if (!appPreferences.messageShownValue.get()) {
36 | appPreferences.messageShownValue.set(true)
37 | view.showWelcomeMessage()
38 | }
39 | }
40 |
41 | private fun handleViewAction(action: ViewAction) = when (action) {
42 | is ViewAction.ScaleChanged -> appPreferences.scaleValue.set(action.value / 100f)
43 | is ViewAction.AnimationTypeClicked -> appPreferences.animationTypeValue.set(when (action.type) {
44 | AnimationType.CONFETTI -> AnimationType.PLANE
45 | AnimationType.PLANE -> AnimationType.FAVORITE
46 | AnimationType.FAVORITE -> AnimationType.CONFETTI
47 | })
48 | }
49 | }
--------------------------------------------------------------------------------
/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsView.kt:
--------------------------------------------------------------------------------
1 | package io.denison.typedvalue.sample.ui.settings
2 |
3 | import io.denison.typedvalue.sample.model.AnimationType
4 | import io.denison.typedvalue.sample.mvp.MvpView
5 | import io.reactivex.Observable
6 |
7 | interface SettingsView : MvpView {
8 | fun bindTo(model: ViewModel)
9 | fun showWelcomeMessage()
10 |
11 | fun observeViewActions(): Observable
12 |
13 | sealed class ViewModel {
14 | data class Content(val type: AnimationType, val scale: Int) : ViewModel()
15 | }
16 |
17 | sealed class ViewAction {
18 | data class AnimationTypeClicked(val type: AnimationType) : ViewAction()
19 | data class ScaleChanged(val value: Int) : ViewAction()
20 | }
21 | }
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-v21/setting_item_bkg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | -
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/setting_item_bkg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
-
13 |
14 |
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/src/main/res/font/fonts.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
--------------------------------------------------------------------------------
/sample/src/main/res/font/roboto_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/font/roboto_medium.ttf
--------------------------------------------------------------------------------
/sample/src/main/res/layout/ac_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
27 |
28 |
39 |
40 |
41 |
49 |
50 |
60 |
61 |
74 |
75 |
90 |
91 |
101 |
102 |
115 |
116 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/raw/confetti.json:
--------------------------------------------------------------------------------
1 | {"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":59.0000024031193,"w":800,"h":800,"nm":"confettis2","ddd":0,"assets":[{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"p20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[71,152,0],"to":[1.83333337306976,-220.66667175293,0],"ti":[85.1666641235352,-23.3333339691162,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"p19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[579,746,0],"to":[101.833335876465,91.3333358764648,0],"ti":[27.1666660308838,-153.33332824707,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"p18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[503,238,0],"to":[-84.1666641235352,-74.6666641235352,0],"ti":[-88.8333358764648,-45.3333320617676,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"p17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[91,556,0],"to":[-82.1666641235352,-112.666664123535,0],"ti":[73.1666641235352,-199.33332824707,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"p16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[511,308,0],"to":[77.8333358764648,91.3333358764648,0],"ti":[51.1666679382324,60.6666679382324,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"p15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[155,280,0],"to":[-30.1666660308838,-122.666664123535,0],"ti":[95.1666641235352,-53.3333320617676,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"p14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[681,388.872,0],"to":[143.83332824707,49.3333320617676,0],"ti":[-58.8333320617676,48.6666679382324,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"p13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[257,284,0],"to":[-24.1666660308838,-72.6666641235352,0],"ti":[75.1666641235352,-5.33333349227905,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"p12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[301,474,0],"to":[-14.1666669845581,31.3333339691162,0],"ti":[65.1666641235352,-13.3333330154419,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"p11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[499,570,0],"to":[-8.16666698455811,63.3333320617676,0],"ti":[-62.8333320617676,-29.3333339691162,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"p10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[557,68,0],"to":[81.8333358764648,-104.666664123535,0],"ti":[-58.8333320617676,104.666664123535,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"p9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[715,138,0],"to":[151.83332824707,-46.6666679382324,0],"ti":[-26.8333339691162,72.6666641235352,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"p8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[679,664,0],"to":[107.833335876465,89.3333358764648,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"p7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[97,686,0],"to":[-36.1666679382324,53.3333320617676,0],"ti":[75.1666641235352,-39.3333320617676,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"p6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":5,"s":[100],"e":[0]},{"t":44.0000017921567}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":5,"s":[400,400,0],"e":[65,340,0],"to":[-148.16667175293,-132.66667175293,0],"ti":[61.1666679382324,-65.3333358764648,0]},{"t":44.0000017921567}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"p5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":6,"s":[100],"e":[0]},{"t":45.0000018328876}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.004,"y":0.691},"o":{"x":0.014,"y":0},"n":"0p004_0p691_0p014_0","t":6,"s":[400,400,0],"e":[400,23.613,0],"to":[-55.3803939819336,-168.204071044922,0],"ti":[27.0301876068115,124.269813537598,0]},{"t":45.0000018328876}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"p4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":7,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":7,"s":[400,400,0],"e":[303,660,0],"to":[109.833335876465,69.3333358764648,0],"ti":[97.1666641235352,0.66666668653488,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"p3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":8,"s":[100],"e":[0]},{"t":47.0000019143492}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":8,"s":[400,400,0],"e":[663,498,0],"to":[41.8333320617676,109.333335876465,0],"ti":[-71.8333358764648,39.6666679382324,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.076272718608,0.735462605953,0.171031266451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"p2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":9,"s":[100],"e":[0]},{"t":48.0000019550801}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":9,"s":[400,400,0],"e":[187,88,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[89.1666641235352,6.66666650772095,0]},{"t":48.0000019550801}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.271778345108,0.528400123119,0.952267169952,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"p1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[621,234,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.903676450253,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":42,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":267,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":358,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":177,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":132,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":226,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":360.000014663101,"st":0,"bm":0}]}
--------------------------------------------------------------------------------
/sample/src/main/res/raw/favourite.json:
--------------------------------------------------------------------------------
1 | {"v":"4.5.8","fr":60,"ip":0,"op":80,"w":44,"h":44,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"star Outlines 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22.385,21.344,0]},"a":{"a":0,"k":[125,125,0]},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":14,"s":[0,0,100],"e":[9,9,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":25,"s":[9,9,100],"e":[6,6,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":41,"s":[6,6,100],"e":[10,10,100]},{"t":62}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[1.295,0],[1.356,0.96],[-0.521,3.196],[0,0],[0.312,0.315],[0,0],[-1.007,3.01],[-2.957,0.453],[0,0],[-0.175,0.372],[0,0],[-3.091,0],[-1.342,-2.867],[0,0],[0,0],[-0.341,-0.054],[0,0],[-0.972,-2.91],[2.182,-2.246],[0,0],[-0.08,-0.484],[0,0],[2.598,-1.833],[2.651,1.471],[0,0],[0.289,-0.161],[0,0]],"o":[[-1.578,0],[-2.601,-1.826],[0,0],[0.081,-0.484],[0,0],[-2.185,-2.245],[0.974,-2.91],[0,0],[0.345,-0.054],[0,0],[1.346,-2.867],[3.091,0],[0,0],[0,0],[0.175,0.376],[0,0],[2.96,0.453],[1.007,3.007],[0,0],[-0.308,0.322],[0,0],[0.524,3.196],[-2.471,1.738],[0,0],[-0.288,-0.161],[0,0],[-1.191,0.658]],"v":[[-53.993,95.484],[-58.493,94.041],[-61.867,85.891],[-52.366,27.545],[-52.741,26.257],[-92.993,-15.067],[-94.904,-23.585],[-88.533,-29.039],[-32.902,-37.551],[-32.072,-38.229],[-7.193,-91.319],[0.001,-95.968],[7.189,-91.319],[7.197,-91.319],[32.074,-38.235],[32.898,-37.551],[88.527,-29.039],[94.904,-23.585],[92.998,-15.07],[52.742,26.25],[52.366,27.552],[61.865,85.891],[58.502,94.041],[50.212,94.497],[0.454,66.948],[-0.456,66.948],[-50.208,94.497]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[125.015,126.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":14,"op":80,"st":14,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"star Outlines 5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22.385,21.344,0]},"a":{"a":0,"k":[125,125,0]},"s":{"a":0,"k":[10,10,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[1.295,0],[1.356,0.96],[-0.521,3.196],[0,0],[0.312,0.315],[0,0],[-1.007,3.01],[-2.957,0.453],[0,0],[-0.175,0.372],[0,0],[-3.091,0],[-1.342,-2.867],[0,0],[0,0],[-0.341,-0.054],[0,0],[-0.972,-2.91],[2.182,-2.246],[0,0],[-0.08,-0.484],[0,0],[2.598,-1.833],[2.651,1.471],[0,0],[0.289,-0.161],[0,0]],"o":[[-1.578,0],[-2.601,-1.826],[0,0],[0.081,-0.484],[0,0],[-2.185,-2.245],[0.974,-2.91],[0,0],[0.345,-0.054],[0,0],[1.346,-2.867],[3.091,0],[0,0],[0,0],[0.175,0.376],[0,0],[2.96,0.453],[1.007,3.007],[0,0],[-0.308,0.322],[0,0],[0.524,3.196],[-2.471,1.738],[0,0],[-0.288,-0.161],[0,0],[-1.191,0.658]],"v":[[-53.993,95.484],[-58.493,94.041],[-61.867,85.891],[-52.366,27.545],[-52.741,26.257],[-92.993,-15.067],[-94.904,-23.585],[-88.533,-29.039],[-32.902,-37.551],[-32.072,-38.229],[-7.193,-91.319],[0.001,-95.968],[7.189,-91.319],[7.197,-91.319],[32.074,-38.235],[32.898,-37.551],[88.527,-29.039],[94.904,-23.585],[92.998,-15.07],[52.742,26.25],[52.366,27.552],[61.865,85.891],[58.502,94.041],[50.212,94.497],[0.454,66.948],[-0.456,66.948],[-50.208,94.497]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":10},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[125.015,126.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":4,"st":-29,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Dot14","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-320},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Dot13","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-306.6},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Dot12","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-271.7},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Dot11","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-258.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.392,0.659,0.086,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Dot10","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-220.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Dot9","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-206.9},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-29,"s":[0.941,0.561,0,1],"e":[0.392,0.659,0.086,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.392,0.659,0.086,1],"e":[0.173,0.569,0.788,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":0,"k":44,"ix":1},"e":{"a":0,"k":45,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Dot8","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-168.2},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.941,0.561,0,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"Dot7","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-154.8},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.329,0.596,0.8,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.329,0.596,0.8,1],"e":[0.549,0.275,0.71,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":4,"nm":"Dot6","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-117.1},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.702,0.843,0.659,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":0,"k":29,"ix":1},"e":{"a":0,"k":30,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"Dot5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-103.7},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.722,0.847,0.949,1],"e":[0.173,0.569,0.788,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.173,0.569,0.788,1],"e":[0.392,0.659,0.086,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"Dot4","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-69.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.702,0.847,0.659,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":4,"nm":"Dot3","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-55.9},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.643,0.812,0.973,1],"e":[0.173,0.569,0.788,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.173,0.569,0.788,1],"e":[0.549,0.275,0.71,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":14,"ty":4,"nm":"Dot2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-13.4},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.631,0.51,0.624,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":15,"ty":4,"nm":"Dot1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.941,0.561,0,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":16,"ty":4,"nm":"C2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":9,"s":[25.744,25.744],"e":[60.744,60.744]},{"t":16}]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9,"s":[23.3],"e":[1]},{"t":16}]},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"mn":"ADBE Vector Group"}],"ip":9,"op":17,"st":-76,"bm":0,"sr":1},{"ddd":0,"ind":17,"ty":4,"nm":"C1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":4,"s":[4,4,100],"e":[40,40,100]},{"t":10}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[57.344,57.344]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[0.941,0.561,0,1],"e":[0.812,0.565,0.969,1]},{"t":10}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":4,"op":10,"st":-75,"bm":0,"sr":1}]}
--------------------------------------------------------------------------------
/sample/src/main/res/raw/plane.json:
--------------------------------------------------------------------------------
1 | {"v":"4.5.9","fr":29.9700012207031,"ip":0,"op":87.0000035435826,"w":350,"h":350,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Earth Outline","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[175,175,0]},"a":{"a":0,"k":[30,30,0]},"s":{"a":0,"k":[235,235,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[11.238,-3.576],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.491,2.648],[-0.322,0.244],[-0.809,1.455],[0.254,0.981],[-0.086,1.297],[0.058,0.483],[-0.104,1.657],[0.728,0.741],[-5.105,2.693],[-0.016,-0.329],[0,0],[0,0],[-0.578,0.534],[-0.53,0.196],[0.038,-0.214],[1.318,-0.692],[-0.184,-2.341],[0,0],[0,0],[-0.923,0],[-1.77,1.353],[-1.962,0],[-1.56,0.67],[-0.514,0.064],[0.172,-0.579],[0.69,0],[0.224,0.228],[1.738,-1.812],[-0.082,-1.981],[0,0],[0.12,0.054],[0.902,0],[0.163,-0.244],[-0.296,-0.703],[0.728,-1.222],[-0.433,-0.761],[-0.73,0],[-1.555,0.37],[-0.268,0],[-0.336,-0.928],[-0.862,-0.664],[-0.46,0],[-0.188,0.611],[-0.018,0.06],[-0.021,-0.232],[-0.47,0],[-1.023,0.474],[-0.257,0.005],[-0.042,-0.254],[-0.51,-0.775],[-3.249,0],[-1.154,1.791],[-0.17,1.174],[-0.397,0.274],[-1.196,-1.563],[-0.853,0],[0,0],[-0.269,0.306]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.183,-2.332],[0.317,-0.291],[0.807,-0.609],[0.734,-1.321],[-0.156,-0.594],[0.113,-1.697],[-0.049,-0.419],[0.119,-1.901],[2.634,-5.139],[-0.179,0.521],[0,0],[0,0],[0.409,0],[2.67,-2.462],[-0.004,0.12],[-0.193,1.072],[-1.65,0.869],[0,0],[0,0],[0.985,0.385],[2.54,0],[1.597,-1.22],[1.045,0],[0.909,-0.391],[1.124,0.896],[-0.513,1.709],[-0.1,0],[-1.647,-1.646],[-1.305,1.36],[0,0],[-0.123,-0.055],[-1.414,-0.644],[-0.784,0],[-0.475,0.717],[0.695,1.661],[-0.524,0.878],[0.269,0.473],[0.632,0],[0.396,-0.096],[0.546,0],[0.254,0.701],[0.535,0.41],[1.19,0],[0.015,-0.053],[0.083,0.09],[0.106,1.292],[0.458,0],[0.901,-0.411],[0.065,0.163],[0.115,0.676],[1.587,2.4],[1.945,0],[0.277,-0.431],[0.118,-0.819],[0.005,0],[0.48,0.629],[0,0],[0.472,0],[-0.103,12.386]],"v":[[8.474,26.686],[8.91,24.086],[12.306,21.33],[14.25,15.266],[6.25,15.233],[4.691,12.411],[-1.113,8.062],[-4.88,8.209],[-8.29,7.136],[-10.107,5.883],[-9.594,5.712],[-10.536,5.587],[-11.44,4.964],[-12.821,5.284],[-15.189,4.969],[-18.473,6.561],[-18.79,6.666],[-18.772,6.731],[-21.627,8.089],[-24.985,12.614],[-27.523,5.116],[-26.574,4.333],[-24.124,1.639],[-23.757,-1.405],[-24.001,-3.966],[-24.004,-6.647],[-24,-9.157],[-24.931,-12.72],[-13.021,-24.776],[-13.279,-23.558],[-13.234,-22.604],[-12.28,-22.604],[-11.136,-23.282],[-6.733,-26.666],[-6.792,-26.172],[-9.549,-23.751],[-13.067,-19.463],[-13.018,-18.839],[-12.435,-18.61],[-9.559,-18.028],[-3.418,-20.782],[1.648,-23.154],[5.726,-24.458],[8.374,-25.439],[8.867,-22.059],[6.511,-19.073],[6.027,-19.327],[0.197,-19.007],[-1.757,-13.668],[-1.724,-13.2],[-2.087,-13.365],[-5.626,-14.564],[-6.96,-13.911],[-6.856,-11.59],[-7.794,-7.187],[-8.338,-4.787],[-6.833,-4.075],[-3.672,-4.61],[-2.674,-4.753],[-1.711,-3.74],[-0.28,-1.504],[1.18,-0.9],[2.907,-2.652],[2.96,-2.827],[3.074,-2.386],[4.455,-0.899],[6.517,-1.559],[8.12,-2.06],[8.289,-1.279],[9.054,1.013],[17.078,5.995],[21.816,3.257],[22.365,1.019],[23.192,-2.251],[24.901,-0.644],[26.897,0.708],[26.898,0.708],[27.995,0.233]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[0,13.734],[0.671,2.488],[0,0],[0,0],[0.012,0.044],[0.271,0.731],[0.006,0.021],[0.301,0.657],[0.054,0.114],[0.337,0.6],[0.088,0.152],[0.382,0.563],[0.069,0.1],[0.398,0.499],[0.075,0.09],[0.489,0.518],[0.076,0.079],[6.459,1.095],[0.042,0.006],[0.76,0.067],[0.124,0.008],[0.768,0],[0.513,-0.026],[0.007,-0.001],[3.244,-1.383],[0,0],[0,0],[0,-12.178],[-3.848,-5.044],[0,0],[0,0],[-0.147,-0.181],[-0.08,-0.095],[-0.105,-0.121],[0,0],[0,0],[-4.412,-1.778],[0,0],[0,0],[-0.059,-0.022],[-0.183,-0.065],[-0.259,-0.083],[-0.208,-0.06],[-0.246,-0.065],[-0.213,-0.052],[-0.253,-0.056],[-0.211,-0.041],[-0.268,-0.045],[-0.203,-0.028],[-0.287,-0.033],[-0.192,-0.019],[-0.323,-0.02],[-0.16,-0.007],[-0.487,0],[-0.577,0.032],[-0.182,0.013],[-0.395,0.045],[-0.21,0.03],[-0.364,0.063],[-0.215,0.042],[-0.39,0.093],[-0.148,0.038],[0,0],[0,0]],"o":[[0,-2.698],[0,0],[0,0],[-0.013,-0.046],[-0.214,-0.756],[-0.008,-0.021],[-0.255,-0.682],[-0.053,-0.115],[-0.295,-0.625],[-0.086,-0.152],[-0.346,-0.59],[-0.07,-0.101],[-0.366,-0.524],[-0.073,-0.09],[-0.45,-0.552],[-0.075,-0.081],[-4.359,-4.53],[-0.042,-0.008],[-0.744,-0.123],[-0.123,-0.011],[-0.753,-0.057],[-0.516,0],[-0.006,0],[-3.521,0.181],[0,0],[0,0],[-10.449,4.697],[0,6.821],[0,0],[0,0],[0.141,0.183],[0.077,0.097],[0.103,0.124],[0,0],[0,0],[3.086,3.523],[0,0],[0,0],[0.059,0.022],[0.183,0.068],[0.257,0.09],[0.205,0.065],[0.246,0.073],[0.212,0.058],[0.252,0.063],[0.209,0.045],[0.265,0.052],[0.202,0.034],[0.284,0.042],[0.19,0.023],[0.32,0.03],[0.16,0.011],[0.486,0.024],[0.585,0],[0.18,-0.012],[0.399,-0.031],[0.211,-0.025],[0.366,-0.05],[0.215,-0.038],[0.395,-0.079],[0.149,-0.037],[0,0],[0,0],[12.613,-3.546]],"v":[[30,0],[28.965,-7.8],[28.966,-7.808],[28.906,-8.027],[28.864,-8.159],[28.142,-10.392],[28.119,-10.454],[27.279,-12.461],[27.123,-12.805],[26.17,-14.642],[25.908,-15.098],[24.821,-16.831],[24.609,-17.128],[23.463,-18.663],[23.246,-18.938],[21.835,-20.54],[21.608,-20.779],[5.031,-29.569],[4.906,-29.591],[2.651,-29.876],[2.281,-29.903],[0,-30],[-1.541,-29.96],[-1.563,-29.959],[-11.746,-27.61],[-12.25,-27.396],[-12.253,-27.373],[-30,0],[-23.86,18.157],[-23.854,18.184],[-23.717,18.36],[-23.276,18.899],[-23.041,19.187],[-22.734,19.561],[-22.596,19.723],[-22.564,19.738],[-11.172,27.834],[-11.17,27.851],[-10.62,28.06],[-10.442,28.123],[-9.893,28.317],[-9.12,28.579],[-8.5,28.766],[-7.761,28.976],[-7.124,29.138],[-6.366,29.315],[-5.737,29.444],[-4.937,29.587],[-4.331,29.683],[-3.474,29.792],[-2.903,29.858],[-1.938,29.931],[-1.46,29.963],[0,30],[1.741,29.947],[2.282,29.905],[3.474,29.793],[4.107,29.712],[5.202,29.54],[5.848,29.424],[7.022,29.163],[7.472,29.062],[8.103,28.901],[8.108,28.878]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge"},{"ty":"mm","mm":4,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge"},{"ty":"fl","c":{"a":0,"k":[0.137,0.118,0.122,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[30,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":5,"mn":"ADBE Vector Group"}],"ip":0,"op":900.000036657751,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Plane Outline","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[359]},{"t":87.0000035435826}]},"p":{"a":0,"k":[175,175,0]},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[174.42,246.5,0],"e":[174.42,232.5,0],"to":[0,-2.33333325386047,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43,"s":[174.42,232.5,0],"e":[174.42,246.5,0],"to":[0,0,0],"ti":[0,-2.33333325386047,0]},{"t":69.0000028104276}]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[150,150,100],"e":[186,186,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":43,"s":[186,186,100],"e":[150,150,100]},{"t":69.0000028104276}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-10.521,3.811],[-0.007,5.58],[5.236,1.909],[11.201,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.132,0],[0,0],[0.676,-0.952],[0,-0.745],[-0.134,-0.383],[0,0],[0,0],[0,0],[1.458,0],[0,0],[0.673,-1.006],[-0.466,-1.118],[0,0],[0,0],[0,0],[0,0],[0,-0.469],[-0.401,-0.604],[-1.208,0],[0,0],[-0.561,1.346],[0,0],[0,0],[0,0],[0,-0.395],[-0.445,-0.618],[-1.168,0],[0,0],[-0.687,0.905]],"o":[[0,0],[0,0],[0,0],[11.125,0],[5.248,-1.903],[0,-5.588],[-10.514,-3.838],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.687,-0.901],[0,0],[-1.168,0],[-0.445,0.622],[0,0.394],[0,0],[0,0],[0,0],[-0.561,-1.346],[0,0],[-1.208,0],[-0.676,1.009],[0,0],[0,0],[0,0],[0,0],[-0.188,0.448],[0,0.703],[0.673,1.005],[0,0],[1.458,0],[0,0],[0,0],[0,0],[-0.134,0.383],[0,0.741],[0.676,0.956],[0,0],[1.132,0],[0,0]],"v":[[-6.09,90.416],[21.346,54.25],[48.785,18.076],[67.356,18.083],[99.946,12.348],[108.593,0.033],[99.975,-12.3],[67.252,-18.083],[48.778,-18.09],[21.346,-54.25],[10.944,-68.716],[-6.09,-90.417],[-18.724,-107.071],[-21.606,-108.5],[-43.306,-108.5],[-46.25,-106.984],[-46.923,-104.883],[-46.724,-103.704],[-17.212,-18.112],[-68.641,-15.053],[-90.751,-44.792],[-94.09,-47.017],[-104.788,-47.017],[-107.799,-45.407],[-108.128,-42.007],[-94.462,-5.212],[-97.408,0.5],[-94.408,6.5],[-108.128,42.008],[-108.406,43.399],[-107.799,45.407],[-104.788,47.017],[-94.09,47.017],[-90.751,44.792],[-68.641,15.396],[-17.19,18.055],[-46.724,103.704],[-46.923,104.883],[-46.25,106.98],[-43.306,108.5],[-21.606,108.5],[-18.724,107.067]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.014,0,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[174.407,174.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[13.48,13.48],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":900.000036657751,"st":0,"bm":0,"sr":1}]}
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #4D000000
5 | #03A9F4
6 | #797A7C
7 |
8 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TypedValue
3 | Image type
4 | Welcome to TypedValue demo!
5 | Image scale
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
18 |
19 |
24 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library'
2 | include ':library-date'
3 | include ':sample'
4 |
--------------------------------------------------------------------------------