├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── LICENSE.md
├── Package.swift
├── PullToRefreshSample
├── PullToRefreshSample.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── swiftpm
│ │ │ └── Package.resolved
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── PullToRefreshSample.xcscheme
└── PullToRefreshSampleiOS
│ ├── PullToRefreshSampleApp.swift
│ ├── Resources
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── animation-pulling-shakuro_logo.json
│ ├── animation-pulling-shakuro_logo_old.json
│ ├── animation-refreshing-shakuro_logo.json
│ └── animation-refreshing-shakuro_logo_old.json
│ └── UI
│ ├── CircleAnimationWithProgressView.swift
│ ├── CircleAnimationWithRepeatView.swift
│ ├── ContentView.swift
│ ├── ContentViewWithSplitView.swift
│ ├── ListContentView.swift
│ └── ScrollContentView.swift
├── README.md
├── Resources
├── pull_to_refresh_example_1.gif
├── pull_to_refresh_example_2.gif
├── pull_to_refresh_example_main.gif
└── title_image.png
├── Shakuro.PullToRefreshSwiftUI.podspec
├── Sources
└── PullToRefreshSwiftUI
│ ├── GeometryGroupModifier.swift
│ ├── PullToRefreshListView.swift
│ ├── PullToRefreshListView18IOS.swift
│ ├── PullToRefreshListViewOldIOS.swift
│ ├── PullToRefreshScrollView.swift
│ └── View+readLayoutData.swift
└── Tests
└── PullToRefreshSwiftUITests
└── PullToRefreshSwiftUITests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | xcuserdata/
5 | DerivedData/
6 | .swiftpm/configuration/registries.json
7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8 | .netrc
9 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.9
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "PullToRefreshSwiftUI",
8 | platforms: [
9 | .iOS(.v15)
10 | ],
11 | products: [
12 | .library(
13 | name: "PullToRefreshSwiftUI",
14 | targets: ["PullToRefreshSwiftUI"]),
15 | ],
16 | dependencies: [
17 | ],
18 | targets: [
19 | .target(
20 | name: "PullToRefreshSwiftUI",
21 | dependencies: []),
22 | .testTarget(
23 | name: "PullToRefreshSwiftUITests",
24 | dependencies: ["PullToRefreshSwiftUI"]),
25 | ]
26 | )
27 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A51D6A4F2B83DE8000E44E19 /* PullToRefreshSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51D6A4E2B83DE8000E44E19 /* PullToRefreshSampleApp.swift */; };
11 | A51D6A612B83E0E800E44E19 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A51D6A5E2B83E0E800E44E19 /* Assets.xcassets */; };
12 | A51D6A622B83E0E800E44E19 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A51D6A602B83E0E800E44E19 /* Preview Assets.xcassets */; };
13 | A5288C602BA6B45A0033D0AE /* CircleAnimationWithProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5288C5F2BA6B45A0033D0AE /* CircleAnimationWithProgressView.swift */; };
14 | A5288C622BA6B4820033D0AE /* CircleAnimationWithRepeatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5288C612BA6B4820033D0AE /* CircleAnimationWithRepeatView.swift */; };
15 | A54348322B84672600D1DDB0 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54348312B84672600D1DDB0 /* ContentView.swift */; };
16 | A56DF71D2B852C2C00477FBD /* PullToRefreshSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = A56DF71C2B852C2C00477FBD /* PullToRefreshSwiftUI */; };
17 | A5BA6BAD2B870CEE00DAE39C /* ScrollContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5BA6BAC2B870CEE00DAE39C /* ScrollContentView.swift */; };
18 | A5BA6BAF2B870D0100DAE39C /* ListContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5BA6BAE2B870D0100DAE39C /* ListContentView.swift */; };
19 | A5D2E8062B9E31920079FD9B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = A5D2E8052B9E31920079FD9B /* Lottie */; };
20 | A5DD89652B8867C600EF70A5 /* animation-refreshing-shakuro_logo.json in Resources */ = {isa = PBXBuildFile; fileRef = A5DD89632B8867C600EF70A5 /* animation-refreshing-shakuro_logo.json */; };
21 | A5DD89662B8867C600EF70A5 /* animation-pulling-shakuro_logo.json in Resources */ = {isa = PBXBuildFile; fileRef = A5DD89642B8867C600EF70A5 /* animation-pulling-shakuro_logo.json */; };
22 | A5EEB88C2BB0AEB00048B46B /* ContentViewWithSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5EEB88B2BB0AEB00048B46B /* ContentViewWithSplitView.swift */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXFileReference section */
26 | A51D6A4B2B83DE8000E44E19 /* PullToRefreshSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PullToRefreshSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
27 | A51D6A4E2B83DE8000E44E19 /* PullToRefreshSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullToRefreshSampleApp.swift; sourceTree = ""; };
28 | A51D6A5C2B83DE9B00E44E19 /* PullToRefreshSwiftUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = PullToRefreshSwiftUI; path = ..; sourceTree = ""; };
29 | A51D6A5E2B83E0E800E44E19 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | A51D6A602B83E0E800E44E19 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
31 | A5288C5F2BA6B45A0033D0AE /* CircleAnimationWithProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleAnimationWithProgressView.swift; sourceTree = ""; };
32 | A5288C612BA6B4820033D0AE /* CircleAnimationWithRepeatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleAnimationWithRepeatView.swift; sourceTree = ""; };
33 | A54348312B84672600D1DDB0 /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
34 | A5BA6BAC2B870CEE00DAE39C /* ScrollContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollContentView.swift; sourceTree = ""; };
35 | A5BA6BAE2B870D0100DAE39C /* ListContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListContentView.swift; sourceTree = ""; };
36 | A5DD89632B8867C600EF70A5 /* animation-refreshing-shakuro_logo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "animation-refreshing-shakuro_logo.json"; sourceTree = ""; };
37 | A5DD89642B8867C600EF70A5 /* animation-pulling-shakuro_logo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "animation-pulling-shakuro_logo.json"; sourceTree = ""; };
38 | A5EEB88B2BB0AEB00048B46B /* ContentViewWithSplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewWithSplitView.swift; sourceTree = ""; };
39 | /* End PBXFileReference section */
40 |
41 | /* Begin PBXFrameworksBuildPhase section */
42 | A51D6A482B83DE8000E44E19 /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | A56DF71D2B852C2C00477FBD /* PullToRefreshSwiftUI in Frameworks */,
47 | A5D2E8062B9E31920079FD9B /* Lottie in Frameworks */,
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | /* End PBXFrameworksBuildPhase section */
52 |
53 | /* Begin PBXGroup section */
54 | A51D6A422B83DE8000E44E19 = {
55 | isa = PBXGroup;
56 | children = (
57 | A51D6A5C2B83DE9B00E44E19 /* PullToRefreshSwiftUI */,
58 | A51D6A4D2B83DE8000E44E19 /* PullToRefreshSampleiOS */,
59 | A51D6A4C2B83DE8000E44E19 /* Products */,
60 | A56DF71B2B852C2C00477FBD /* Frameworks */,
61 | );
62 | sourceTree = "";
63 | };
64 | A51D6A4C2B83DE8000E44E19 /* Products */ = {
65 | isa = PBXGroup;
66 | children = (
67 | A51D6A4B2B83DE8000E44E19 /* PullToRefreshSample.app */,
68 | );
69 | name = Products;
70 | sourceTree = "";
71 | };
72 | A51D6A4D2B83DE8000E44E19 /* PullToRefreshSampleiOS */ = {
73 | isa = PBXGroup;
74 | children = (
75 | A543482F2B8466B100D1DDB0 /* Application */,
76 | A51D6A5D2B83E0E800E44E19 /* Resources */,
77 | );
78 | path = PullToRefreshSampleiOS;
79 | sourceTree = "";
80 | };
81 | A51D6A5D2B83E0E800E44E19 /* Resources */ = {
82 | isa = PBXGroup;
83 | children = (
84 | A5DD89642B8867C600EF70A5 /* animation-pulling-shakuro_logo.json */,
85 | A5DD89632B8867C600EF70A5 /* animation-refreshing-shakuro_logo.json */,
86 | A51D6A5E2B83E0E800E44E19 /* Assets.xcassets */,
87 | A51D6A5F2B83E0E800E44E19 /* Preview Content */,
88 | );
89 | path = Resources;
90 | sourceTree = "";
91 | };
92 | A51D6A5F2B83E0E800E44E19 /* Preview Content */ = {
93 | isa = PBXGroup;
94 | children = (
95 | A51D6A602B83E0E800E44E19 /* Preview Assets.xcassets */,
96 | );
97 | path = "Preview Content";
98 | sourceTree = "";
99 | };
100 | A543482F2B8466B100D1DDB0 /* Application */ = {
101 | isa = PBXGroup;
102 | children = (
103 | A51D6A4E2B83DE8000E44E19 /* PullToRefreshSampleApp.swift */,
104 | A54348302B84672600D1DDB0 /* UI */,
105 | );
106 | name = Application;
107 | sourceTree = "";
108 | };
109 | A54348302B84672600D1DDB0 /* UI */ = {
110 | isa = PBXGroup;
111 | children = (
112 | A54348312B84672600D1DDB0 /* ContentView.swift */,
113 | A5EEB88B2BB0AEB00048B46B /* ContentViewWithSplitView.swift */,
114 | A5BA6BAC2B870CEE00DAE39C /* ScrollContentView.swift */,
115 | A5BA6BAE2B870D0100DAE39C /* ListContentView.swift */,
116 | A5288C5F2BA6B45A0033D0AE /* CircleAnimationWithProgressView.swift */,
117 | A5288C612BA6B4820033D0AE /* CircleAnimationWithRepeatView.swift */,
118 | );
119 | path = UI;
120 | sourceTree = "";
121 | };
122 | A56DF71B2B852C2C00477FBD /* Frameworks */ = {
123 | isa = PBXGroup;
124 | children = (
125 | );
126 | name = Frameworks;
127 | sourceTree = "";
128 | };
129 | /* End PBXGroup section */
130 |
131 | /* Begin PBXNativeTarget section */
132 | A51D6A4A2B83DE8000E44E19 /* PullToRefreshSample */ = {
133 | isa = PBXNativeTarget;
134 | buildConfigurationList = A51D6A592B83DE8200E44E19 /* Build configuration list for PBXNativeTarget "PullToRefreshSample" */;
135 | buildPhases = (
136 | A51D6A472B83DE8000E44E19 /* Sources */,
137 | A51D6A482B83DE8000E44E19 /* Frameworks */,
138 | A51D6A492B83DE8000E44E19 /* Resources */,
139 | );
140 | buildRules = (
141 | );
142 | dependencies = (
143 | );
144 | name = PullToRefreshSample;
145 | packageProductDependencies = (
146 | A56DF71C2B852C2C00477FBD /* PullToRefreshSwiftUI */,
147 | A5D2E8052B9E31920079FD9B /* Lottie */,
148 | );
149 | productName = PullToRefreshSample;
150 | productReference = A51D6A4B2B83DE8000E44E19 /* PullToRefreshSample.app */;
151 | productType = "com.apple.product-type.application";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | A51D6A432B83DE8000E44E19 /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | BuildIndependentTargetsInParallel = 1;
160 | LastSwiftUpdateCheck = 1520;
161 | LastUpgradeCheck = 1520;
162 | TargetAttributes = {
163 | A51D6A4A2B83DE8000E44E19 = {
164 | CreatedOnToolsVersion = 15.2;
165 | };
166 | };
167 | };
168 | buildConfigurationList = A51D6A462B83DE8000E44E19 /* Build configuration list for PBXProject "PullToRefreshSample" */;
169 | compatibilityVersion = "Xcode 14.0";
170 | developmentRegion = en;
171 | hasScannedForEncodings = 0;
172 | knownRegions = (
173 | en,
174 | Base,
175 | );
176 | mainGroup = A51D6A422B83DE8000E44E19;
177 | packageReferences = (
178 | A5D2E8042B9E31920079FD9B /* XCRemoteSwiftPackageReference "lottie-spm" */,
179 | );
180 | productRefGroup = A51D6A4C2B83DE8000E44E19 /* Products */;
181 | projectDirPath = "";
182 | projectRoot = "";
183 | targets = (
184 | A51D6A4A2B83DE8000E44E19 /* PullToRefreshSample */,
185 | );
186 | };
187 | /* End PBXProject section */
188 |
189 | /* Begin PBXResourcesBuildPhase section */
190 | A51D6A492B83DE8000E44E19 /* Resources */ = {
191 | isa = PBXResourcesBuildPhase;
192 | buildActionMask = 2147483647;
193 | files = (
194 | A51D6A622B83E0E800E44E19 /* Preview Assets.xcassets in Resources */,
195 | A5DD89662B8867C600EF70A5 /* animation-pulling-shakuro_logo.json in Resources */,
196 | A5DD89652B8867C600EF70A5 /* animation-refreshing-shakuro_logo.json in Resources */,
197 | A51D6A612B83E0E800E44E19 /* Assets.xcassets in Resources */,
198 | );
199 | runOnlyForDeploymentPostprocessing = 0;
200 | };
201 | /* End PBXResourcesBuildPhase section */
202 |
203 | /* Begin PBXSourcesBuildPhase section */
204 | A51D6A472B83DE8000E44E19 /* Sources */ = {
205 | isa = PBXSourcesBuildPhase;
206 | buildActionMask = 2147483647;
207 | files = (
208 | A54348322B84672600D1DDB0 /* ContentView.swift in Sources */,
209 | A5BA6BAD2B870CEE00DAE39C /* ScrollContentView.swift in Sources */,
210 | A5288C622BA6B4820033D0AE /* CircleAnimationWithRepeatView.swift in Sources */,
211 | A5EEB88C2BB0AEB00048B46B /* ContentViewWithSplitView.swift in Sources */,
212 | A5BA6BAF2B870D0100DAE39C /* ListContentView.swift in Sources */,
213 | A51D6A4F2B83DE8000E44E19 /* PullToRefreshSampleApp.swift in Sources */,
214 | A5288C602BA6B45A0033D0AE /* CircleAnimationWithProgressView.swift in Sources */,
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | };
218 | /* End PBXSourcesBuildPhase section */
219 |
220 | /* Begin XCBuildConfiguration section */
221 | A51D6A572B83DE8200E44E19 /* Debug */ = {
222 | isa = XCBuildConfiguration;
223 | buildSettings = {
224 | ALWAYS_SEARCH_USER_PATHS = NO;
225 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
226 | CLANG_ANALYZER_NONNULL = YES;
227 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
229 | CLANG_ENABLE_MODULES = YES;
230 | CLANG_ENABLE_OBJC_ARC = YES;
231 | CLANG_ENABLE_OBJC_WEAK = YES;
232 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
233 | CLANG_WARN_BOOL_CONVERSION = YES;
234 | CLANG_WARN_COMMA = YES;
235 | CLANG_WARN_CONSTANT_CONVERSION = YES;
236 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
245 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
247 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
249 | CLANG_WARN_STRICT_PROTOTYPES = YES;
250 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
252 | CLANG_WARN_UNREACHABLE_CODE = YES;
253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
254 | COPY_PHASE_STRIP = NO;
255 | DEBUG_INFORMATION_FORMAT = dwarf;
256 | ENABLE_STRICT_OBJC_MSGSEND = YES;
257 | ENABLE_TESTABILITY = YES;
258 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
259 | GCC_C_LANGUAGE_STANDARD = gnu17;
260 | GCC_DYNAMIC_NO_PIC = NO;
261 | GCC_NO_COMMON_BLOCKS = YES;
262 | GCC_OPTIMIZATION_LEVEL = 0;
263 | GCC_PREPROCESSOR_DEFINITIONS = (
264 | "DEBUG=1",
265 | "$(inherited)",
266 | );
267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
269 | GCC_WARN_UNDECLARED_SELECTOR = YES;
270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
271 | GCC_WARN_UNUSED_FUNCTION = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
274 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
275 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
276 | MTL_FAST_MATH = YES;
277 | ONLY_ACTIVE_ARCH = YES;
278 | SDKROOT = iphoneos;
279 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
280 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
281 | };
282 | name = Debug;
283 | };
284 | A51D6A582B83DE8200E44E19 /* Release */ = {
285 | isa = XCBuildConfiguration;
286 | buildSettings = {
287 | ALWAYS_SEARCH_USER_PATHS = NO;
288 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
289 | CLANG_ANALYZER_NONNULL = YES;
290 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
291 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
292 | CLANG_ENABLE_MODULES = YES;
293 | CLANG_ENABLE_OBJC_ARC = YES;
294 | CLANG_ENABLE_OBJC_WEAK = YES;
295 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
296 | CLANG_WARN_BOOL_CONVERSION = YES;
297 | CLANG_WARN_COMMA = YES;
298 | CLANG_WARN_CONSTANT_CONVERSION = YES;
299 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
301 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
302 | CLANG_WARN_EMPTY_BODY = YES;
303 | CLANG_WARN_ENUM_CONVERSION = YES;
304 | CLANG_WARN_INFINITE_RECURSION = YES;
305 | CLANG_WARN_INT_CONVERSION = YES;
306 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
307 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
308 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
310 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
311 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
312 | CLANG_WARN_STRICT_PROTOTYPES = YES;
313 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
314 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
315 | CLANG_WARN_UNREACHABLE_CODE = YES;
316 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
317 | COPY_PHASE_STRIP = NO;
318 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
319 | ENABLE_NS_ASSERTIONS = NO;
320 | ENABLE_STRICT_OBJC_MSGSEND = YES;
321 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
322 | GCC_C_LANGUAGE_STANDARD = gnu17;
323 | GCC_NO_COMMON_BLOCKS = YES;
324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
326 | GCC_WARN_UNDECLARED_SELECTOR = YES;
327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
328 | GCC_WARN_UNUSED_FUNCTION = YES;
329 | GCC_WARN_UNUSED_VARIABLE = YES;
330 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
331 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
332 | MTL_ENABLE_DEBUG_INFO = NO;
333 | MTL_FAST_MATH = YES;
334 | SDKROOT = iphoneos;
335 | SWIFT_COMPILATION_MODE = wholemodule;
336 | VALIDATE_PRODUCT = YES;
337 | };
338 | name = Release;
339 | };
340 | A51D6A5A2B83DE8200E44E19 /* Debug */ = {
341 | isa = XCBuildConfiguration;
342 | buildSettings = {
343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
344 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
345 | CODE_SIGN_STYLE = Automatic;
346 | CURRENT_PROJECT_VERSION = 1;
347 | DEVELOPMENT_ASSET_PATHS = "PullToRefreshSampleiOS/Resources/Preview\\ Content";
348 | DEVELOPMENT_TEAM = MW2UF479VW;
349 | ENABLE_PREVIEWS = YES;
350 | GENERATE_INFOPLIST_FILE = YES;
351 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
352 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
353 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
354 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
355 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
356 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
357 | LD_RUNPATH_SEARCH_PATHS = (
358 | "$(inherited)",
359 | "@executable_path/Frameworks",
360 | );
361 | MARKETING_VERSION = 1.0;
362 | PRODUCT_BUNDLE_IDENTIFIER = Shakuro.PullToRefreshSample;
363 | PRODUCT_NAME = "$(TARGET_NAME)";
364 | SWIFT_EMIT_LOC_STRINGS = YES;
365 | SWIFT_VERSION = 5.0;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | };
368 | name = Debug;
369 | };
370 | A51D6A5B2B83DE8200E44E19 /* Release */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
374 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
375 | CODE_SIGN_STYLE = Automatic;
376 | CURRENT_PROJECT_VERSION = 1;
377 | DEVELOPMENT_ASSET_PATHS = "PullToRefreshSampleiOS/Resources/Preview\\ Content";
378 | DEVELOPMENT_TEAM = MW2UF479VW;
379 | ENABLE_PREVIEWS = YES;
380 | GENERATE_INFOPLIST_FILE = YES;
381 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
382 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
383 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
384 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
385 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
386 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
387 | LD_RUNPATH_SEARCH_PATHS = (
388 | "$(inherited)",
389 | "@executable_path/Frameworks",
390 | );
391 | MARKETING_VERSION = 1.0;
392 | PRODUCT_BUNDLE_IDENTIFIER = Shakuro.PullToRefreshSample;
393 | PRODUCT_NAME = "$(TARGET_NAME)";
394 | SWIFT_EMIT_LOC_STRINGS = YES;
395 | SWIFT_VERSION = 5.0;
396 | TARGETED_DEVICE_FAMILY = "1,2";
397 | };
398 | name = Release;
399 | };
400 | /* End XCBuildConfiguration section */
401 |
402 | /* Begin XCConfigurationList section */
403 | A51D6A462B83DE8000E44E19 /* Build configuration list for PBXProject "PullToRefreshSample" */ = {
404 | isa = XCConfigurationList;
405 | buildConfigurations = (
406 | A51D6A572B83DE8200E44E19 /* Debug */,
407 | A51D6A582B83DE8200E44E19 /* Release */,
408 | );
409 | defaultConfigurationIsVisible = 0;
410 | defaultConfigurationName = Release;
411 | };
412 | A51D6A592B83DE8200E44E19 /* Build configuration list for PBXNativeTarget "PullToRefreshSample" */ = {
413 | isa = XCConfigurationList;
414 | buildConfigurations = (
415 | A51D6A5A2B83DE8200E44E19 /* Debug */,
416 | A51D6A5B2B83DE8200E44E19 /* Release */,
417 | );
418 | defaultConfigurationIsVisible = 0;
419 | defaultConfigurationName = Release;
420 | };
421 | /* End XCConfigurationList section */
422 |
423 | /* Begin XCRemoteSwiftPackageReference section */
424 | A5D2E8042B9E31920079FD9B /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
425 | isa = XCRemoteSwiftPackageReference;
426 | repositoryURL = "https://github.com/airbnb/lottie-spm.git";
427 | requirement = {
428 | kind = upToNextMajorVersion;
429 | minimumVersion = 4.4.1;
430 | };
431 | };
432 | /* End XCRemoteSwiftPackageReference section */
433 |
434 | /* Begin XCSwiftPackageProductDependency section */
435 | A56DF71C2B852C2C00477FBD /* PullToRefreshSwiftUI */ = {
436 | isa = XCSwiftPackageProductDependency;
437 | productName = PullToRefreshSwiftUI;
438 | };
439 | A5D2E8052B9E31920079FD9B /* Lottie */ = {
440 | isa = XCSwiftPackageProductDependency;
441 | package = A5D2E8042B9E31920079FD9B /* XCRemoteSwiftPackageReference "lottie-spm" */;
442 | productName = Lottie;
443 | };
444 | /* End XCSwiftPackageProductDependency section */
445 | };
446 | rootObject = A51D6A432B83DE8000E44E19 /* Project object */;
447 | }
448 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "lottie-spm",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/airbnb/lottie-spm.git",
7 | "state" : {
8 | "revision" : "3bd43e12d6fb54654366a61f7cfaca787318b8ce",
9 | "version" : "4.4.1"
10 | }
11 | }
12 | ],
13 | "version" : 2
14 | }
15 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSample.xcodeproj/xcshareddata/xcschemes/PullToRefreshSample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
16 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/PullToRefreshSampleApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | @main
10 | struct PullToRefreshSampleApp: App {
11 |
12 | var body: some Scene {
13 | WindowGroup {
14 | if #available(iOS 17.0, *) {
15 | ContentViewWithSplitView()
16 | } else {
17 | ContentView()
18 | }
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/animation-pulling-shakuro_logo.json:
--------------------------------------------------------------------------------
1 | {"v":"5.12.1","fr":60,"ip":0,"op":121,"w":2052,"h":570,"nm":"pulldown_pulling","ddd":0,"assets":[{"id":"comp_0","nm":"Logo Light 2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 8","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[73.465,73.465,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":30,"s":[100]},{"t":105,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":41,"s":[100]},{"t":117,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":15,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 7","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[69.526,69.526,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":24,"s":[100]},{"t":99,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":35,"s":[100]},{"t":111,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":9,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 6","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[65.653,65.653,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":15,"s":[100]},{"t":90,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":26,"s":[100]},{"t":102,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[111.9,111.9,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":30,"s":[100]},{"t":105,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":41,"s":[100]},{"t":117,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":15,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[105.9,105.9,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":24,"s":[100]},{"t":99,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":35,"s":[100]},{"t":111,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":9,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":15,"s":[100]},{"t":90,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":26,"s":[100]},{"t":102,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 2","parent":11,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[189.081,90.25,0],"ix":2,"l":2},"a":{"a":0,"k":[83.183,46.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.25,-45]],"o":[[0,0],[1.38,14.609]],"v":[[-18.5,-131.75],[-115,-25.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[49.75,105.5]],"o":[[0,0],[-24.918,-52.841]],"v":[[56.25,98.75],[96.5,-46]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":62,"s":[0]},{"t":96,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":50,"s":[0]},{"t":86,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 1","parent":7,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[36.738,-102.385],[0,0]],"o":[[0,0],[-30.5,85],[0,0]],"v":[[-121,-58.5],[78,29],[-124.5,136.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.8],"y":[0]},"t":89,"s":[3]},{"t":108,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-55,-73],[0,0]],"o":[[0,0],[55,73],[0,0]],"v":[[55.5,-131.5],[-76.5,22.5],[152,24]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.8],"y":[0]},"t":89,"s":[3]},{"t":108,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":21,"s":[0]},{"t":127,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":11,"s":[0]},{"t":117,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"Scale","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":32,"s":[270]},{"t":112,"s":[0]}],"ix":10},"p":{"a":0,"k":[540,264,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.79,0.79,0.79],"y":[0,0,0]},"t":10,"s":[126,126,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.8,0.8,0.8],"y":[0,0,0]},"t":69,"s":[155.941,155.941,100]},{"t":112,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":302,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Logo 1 Outlines","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":94,"s":[100]},{"t":129,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[43.475,60.775]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,61.3],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.5,6.2],[0,0],[25.87,-27.816],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[4.5,-20.4]],"v":[[17.2,-65.7],[-19.425,-76.05],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,131.35],"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 2","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":29,"s":[0]},{"t":103,"s":[100]}],"ix":2},"o":{"a":0,"k":125,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":85,"s":[3]},{"t":141,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.5,0.473,0.473,0.545,1,0.329,0.329,0.412],"ix":8}},"s":{"a":0,"k":[0,-66],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":123,"st":-52,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Logo 2 Outlines","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":94,"s":[100]},{"t":129,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.5,-6.2],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-25.108,-6.8],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.033,17.45]],"v":[[-17.075,64.725],[17.975,74.425],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[50.158,-8.25],"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 2","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":85,"s":[3]},{"t":141,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.5,0.473,0.473,0.545,1,0.329,0.329,0.412],"ix":8}},"s":{"a":0,"k":[80,-2],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":29,"s":[0]},{"t":103,"s":[100]}],"ix":2},"o":{"a":0,"k":125,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":123,"st":-53,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 10","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Logo 1 Outlines","parent":9,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[44.35,60.9]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.61568627451,0.61568627451,0.678431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,60.9],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 11","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Logo 2 Outlines","parent":9,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.61568627451,0.61568627451,0.678431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 12","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Logo 3 Outlines","parent":15,"tt":1,"tp":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53,-9.5,0],"ix":2,"l":2},"a":{"a":0,"k":[50.5,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.183,-6.65],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-28.4,-7.9],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.658,17.4]],"v":[[-17.825,66.725],[18.6,76.3],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.329,0.329,0.412,0.5,0.473,0.473,0.545,1,0.616,0.616,0.678],"ix":9}},"s":{"a":0,"k":[-12.836,68.551],"ix":5},"e":{"a":0,"k":[0.939,-59.545],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[47.758,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 13","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Logo Outlines","parent":13,"tt":1,"tp":18,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.5,131,0],"ix":2,"l":2},"a":{"a":0,"k":[50,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.3,7.275],[0,0],[22.8,-18.8],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[6.1,-22.6]],"v":[[17.45,-65.7],[-15.55,-74.3],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.329,0.329,0.412,0.5,0.473,0.473,0.545,1,0.616,0.616,0.678],"ix":9}},"s":{"a":0,"k":[23.859,-65.238],"ix":5},"e":{"a":0,"k":[-23.006,43.869],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 17","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Logo 1 Outlines 2","parent":9,"tt":1,"tp":20,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[44.35,60.9]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,60.9],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 16","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Logo 2 Outlines 2","parent":9,"tt":1,"tp":22,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Shape Layer 15","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Logo 3 Outlines 2","parent":23,"tt":1,"tp":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53,-9.5,0],"ix":2,"l":2},"a":{"a":0,"k":[50.5,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.183,-6.65],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-28.4,-7.9],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.658,17.4]],"v":[[-17.825,66.725],[18.6,76.3],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[47.758,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Shape Layer 14","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Logo Outlines 2","parent":21,"tt":1,"tp":26,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.5,131,0],"ix":2,"l":2},"a":{"a":0,"k":[50,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.3,7.275],[0,0],[22.8,-18.8],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[6.1,-22.6]],"v":[[17.45,-65.7],[-15.55,-74.3],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Logo Light 2","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"t":120,"s":[0]},{"t":184,"s":[-360]}],"ix":10,"x":"var $bm_rt;\n$bm_rt = loopOut();"},"p":{"a":0,"k":[1026,268,0],"ix":2,"l":2,"x":"var $bm_rt;\n$bm_rt = transform.position;"},"a":{"a":0,"k":[540,264,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":297,"s":[4.95]}],"ix":2},"w":1080,"h":562,"ip":0,"op":121,"st":0,"bm":0}],"markers":[],"props":{}}
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/animation-pulling-shakuro_logo_old.json:
--------------------------------------------------------------------------------
1 | {"v":"5.1.1","fr":60,"ip":0,"op":70,"w":464,"h":130,"nm":"Slicing Part 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 17","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[232,65.25,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"ip":0,"op":70,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Yellow Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":20,"s":[0],"e":[720]},{"t":70}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.5,"y":1},"o":{"x":0.5,"y":0},"n":"0p5_1_0p5_0","t":20,"s":[-310,-60,0],"e":[-25.714,-7.786,0],"to":[20.9523811340332,50.476188659668,0],"ti":[-78.0952377319336,40.9523811340332,0]},{"t":70}],"ix":2},"a":{"a":0,"k":[20.5,33,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":[[0,4.72],[-2.52,4],[0,0],[1.28,-1.18],[3.82,-3.56],[1.822,-1.901],[-0.111,-2.921],[-4.04,-3.76],[-5.7,-5.04],[-2.973,0.456],[-0.944,2.856],[2.115,2.138],[3.02,4.18],[0.6,1.18],[1.22,1.7]],"o":[[0,-4.74],[0,0],[-1.28,1.2],[-3.82,3.56],[-2.015,1.696],[-1.898,2.223],[0.2,6],[5.58,5.18],[1.757,2.441],[2.973,-0.456],[0.944,-2.855],[-2.72,-4.38],[-0.78,-1.24],[-1.4,-2],[-2.6,-4.02]],"v":[[-288.345,347.56],[-282.725,335.78],[-282.185,335.02],[-286.005,338.62],[-297.405,349.36],[-303.165,354.76],[-305.945,362.76],[-296.505,376.1],[-279.845,391.78],[-272.138,395.014],[-265.756,389.617],[-267.665,381.48],[-276.385,368.54],[-278.645,365.04],[-282.645,359.34]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960784314,0.035294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.945,-330],"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,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.12,0.18],[3.02,4.18],[0,2.5],[-1.34,2.12],[-2.72,4.4],[1.134,2.805],[2.657,0.444],[1.945,-2.361],[1.9,-1.78],[3.82,-3.56],[1.822,-1.901],[-0.111,-2.921],[-4.04,-3.76],[-5.7,-5.04],[-2.973,0.456],[-0.944,2.856],[2.115,2.138]],"o":[[-2.72,-4.38],[-1.34,-2.12],[0,-2.5],[3.02,-4.18],[1.899,-2.355],[-1.088,-2.464],[-3.033,-0.395],[-2,1.72],[-3.7,3.56],[-2.015,1.696],[-1.898,2.223],[0.2,6],[5.58,5.18],[1.757,2.441],[2.973,-0.456],[0.944,-2.855],[-0.1,-0.2]],"v":[[-267.665,381.46],[-276.385,368.52],[-279.365,362.3],[-276.385,356.06],[-267.665,343.12],[-266.425,334.76],[-272.425,330.1],[-280.425,333.26],[-286.125,338.62],[-297.405,349.36],[-303.165,354.76],[-305.945,362.76],[-296.505,376.1],[-279.845,391.78],[-272.138,395.014],[-265.756,389.617],[-267.665,381.48]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.866666666667,0.752941176471,0.047058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.945,-330],"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 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":70,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Green Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":20,"s":[0],"e":[720]},{"t":70}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.5,"y":1},"o":{"x":0.5,"y":0},"n":"0p5_1_0p5_0","t":20,"s":[311.458,-48.214,0],"e":[27,12.607,0],"to":[-19.1590003967285,77.3095169067383,0],"ti":[67.5363998413086,40.0297584533691,0]},{"t":70}],"ix":2},"a":{"a":0,"k":[20.5,32.5,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":[[0,-4.72],[2.52,-4],[0.18,-0.26],[0,0],[-3.82,3.56],[-1.82,1.896],[0.125,2.923],[4.04,3.76],[5.72,5.04],[3.38,-2.85],[-2.85,-3.38],[-3.02,-4.18],[-0.6,-1.18],[0,0]],"o":[[0,4.74],[-0.18,0.24],[0,0],[3.82,-3.56],[2.004,-1.701],[1.911,-2.216],[-0.2,-6],[-5.58,-5.18],[-2.85,-3.38],[-3.38,2.85],[2.72,4.38],[0.8,1.24],[0,0],[2.64,4]],"v":[[-282.835,378.52],[-288.455,390.3],[-288.975,391.06],[-285.175,387.46],[-273.755,376.72],[-268.015,371.32],[-265.235,363.32],[-274.675,349.98],[-291.335,334.3],[-302.615,333.34],[-303.575,344.62],[-294.855,357.56],[-292.575,361.06],[-288.575,366.76]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.619607843137,0.76862745098,0.247058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.575,-331],"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,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.16],[-3.02,-4.18],[0,-2.5],[1.34,-2],[2.72,-4.4],[-1.134,-2.805],[-2.657,-0.444],[-1.942,2.364],[-1.9,1.78],[-3.82,3.56],[-1.82,1.896],[0.125,2.923],[4.04,3.76],[5.72,5.04],[3.413,-2.855],[-2.855,-3.413]],"o":[[2.72,4.38],[1.34,2.12],[0,2.5],[-3.02,4.18],[-1.899,2.355],[1.088,2.464],[3.033,0.399],[2,-1.72],[3.82,-3.56],[2.004,-1.701],[1.911,-2.216],[-0.2,-6],[-5.58,-5.18],[-2.855,-3.413],[-3.413,2.855],[0.18,0.18]],"v":[[-303.572,344.441],[-294.852,357.381],[-291.872,363.601],[-294.792,369.821],[-303.512,382.761],[-304.752,391.121],[-298.752,395.781],[-290.752,392.621],[-285.052,387.261],[-273.632,376.521],[-267.892,371.121],[-265.112,363.121],[-274.552,349.781],[-291.212,334.101],[-302.562,333.091],[-303.572,344.441]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.666666666667,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.572,-330.821],"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 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":70,"st":0,"bm":0}],"markers":[]}
2 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/animation-refreshing-shakuro_logo.json:
--------------------------------------------------------------------------------
1 | {"v":"5.12.1","fr":60,"ip":0,"op":64,"w":2052,"h":570,"nm":"pulldown_procces","ddd":0,"assets":[{"id":"comp_0","nm":"Logo Light 2","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 8","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[73.465,73.465,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":30,"s":[100]},{"t":105,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":41,"s":[100]},{"t":117,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":15,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 7","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[69.526,69.526,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":24,"s":[100]},{"t":99,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":35,"s":[100]},{"t":111,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":9,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 6","parent":9,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":-2.114,"ix":10},"p":{"a":0,"k":[0.656,-0.024,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[65.653,65.653,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":15,"s":[100]},{"t":90,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":26,"s":[100]},{"t":102,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":103,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[111.9,111.9,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":30,"s":[100]},{"t":105,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":41,"s":[100]},{"t":117,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":15,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[105.9,105.9,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":24,"s":[100]},{"t":99,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":35,"s":[100]},{"t":111,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":9,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[541,264,0],"ix":2,"l":2},"a":{"a":0,"k":[1,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[416.602,416.602],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[1,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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":15,"s":[100]},{"t":90,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":26,"s":[100]},{"t":102,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":103,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 2","parent":11,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[189.081,90.25,0],"ix":2,"l":2},"a":{"a":0,"k":[83.183,46.25,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.25,-45]],"o":[[0,0],[1.38,14.609]],"v":[[-18.5,-131.75],[-115,-25.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[49.75,105.5]],"o":[[0,0],[-24.918,-52.841]],"v":[[56.25,98.75],[96.5,-46]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":3,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":62,"s":[0]},{"t":96,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":50,"s":[0]},{"t":86,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 1","parent":7,"sr":1,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[36.738,-102.385],[0,0]],"o":[[0,0],[-30.5,85],[0,0]],"v":[[-121,-58.5],[78,29],[-124.5,136.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.8],"y":[0]},"t":89,"s":[3]},{"t":108,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-55,-73],[0,0]],"o":[[0,0],[55,73],[0,0]],"v":[[55.5,-131.5],[-76.5,22.5],[152,24]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.8],"y":[0]},"t":89,"s":[3]},{"t":108,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.498,0.475,0.475,0.547,0.996,0.333,0.333,0.416],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"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,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":21,"s":[0]},{"t":127,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":11,"s":[0]},{"t":117,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":172,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":3,"nm":"Scale","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":32,"s":[270]},{"t":112,"s":[0]}],"ix":10},"p":{"a":0,"k":[540,264,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.79,0.79,0.79],"y":[0,0,0]},"t":10,"s":[126,126,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.8,0.8,0.8],"y":[0,0,0]},"t":69,"s":[155.941,155.941,100]},{"t":112,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"ip":0,"op":302,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Logo 1 Outlines","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":94,"s":[100]},{"t":129,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[43.475,60.775]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,61.3],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.5,6.2],[0,0],[25.87,-27.816],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[4.5,-20.4]],"v":[[17.2,-65.7],[-19.425,-76.05],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,131.35],"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 2","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":29,"s":[0]},{"t":103,"s":[100]}],"ix":2},"o":{"a":0,"k":125,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":85,"s":[3]},{"t":141,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.5,0.473,0.473,0.545,1,0.329,0.329,0.412],"ix":8}},"s":{"a":0,"k":[0,-66],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":123,"st":-52,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Logo 2 Outlines","parent":9,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":94,"s":[100]},{"t":129,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.5,-6.2],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-25.108,-6.8],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.033,17.45]],"v":[[-17.075,64.725],[17.975,74.425],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[50.158,-8.25],"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 2","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":1,"k":[{"i":{"x":[0.21],"y":[1]},"o":{"x":[0.79],"y":[0]},"t":85,"s":[3]},{"t":141,"s":[0]}],"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.616,0.616,0.678,0.5,0.473,0.473,0.545,1,0.329,0.329,0.412],"ix":8}},"s":{"a":0,"k":[80,-2],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":2,"lj":2,"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.29],"y":[1]},"o":{"x":[0.71],"y":[0]},"t":29,"s":[0]},{"t":103,"s":[100]}],"ix":2},"o":{"a":0,"k":125,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":123,"st":-53,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 10","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Logo 1 Outlines","parent":9,"tt":1,"tp":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[44.35,60.9]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.61568627451,0.61568627451,0.678431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,60.9],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 11","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Logo 2 Outlines","parent":9,"tt":1,"tp":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.61568627451,0.61568627451,0.678431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 12","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Logo 3 Outlines","parent":15,"tt":1,"tp":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53,-9.5,0],"ix":2,"l":2},"a":{"a":0,"k":[50.5,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.183,-6.65],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-28.4,-7.9],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.658,17.4]],"v":[[-17.825,66.725],[18.6,76.3],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.329,0.329,0.412,0.5,0.473,0.473,0.545,1,0.616,0.616,0.678],"ix":9}},"s":{"a":0,"k":[-12.836,68.551],"ix":5},"e":{"a":0,"k":[0.939,-59.545],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[47.758,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 13","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.21,"y":1},"o":{"x":0.79,"y":0},"t":75,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":136,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Logo Outlines","parent":13,"tt":1,"tp":18,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.5,131,0],"ix":2,"l":2},"a":{"a":0,"k":[50,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.3,7.275],[0,0],[22.8,-18.8],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[6.1,-22.6]],"v":[[17.45,-65.7],[-15.55,-74.3],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.329,0.329,0.412,0.5,0.473,0.473,0.545,1,0.616,0.616,0.678],"ix":9}},"s":{"a":0,"k":[23.859,-65.238],"ix":5},"e":{"a":0,"k":[-23.006,43.869],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":302,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 17","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Logo 1 Outlines 2","parent":9,"tt":1,"tp":20,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.6,-14,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,11.1],[35,9.6],[0,0],[0,0],[0,0],[0,0],[6.2,-22.5],[0.6,-1.6]],"o":[[0,-36.3],[0,0],[0,0],[0,0],[0,0],[22.5,6.2],[-0.5,1.7],[4.2,-10]],"v":[[50.85,28.9],[-8.45,-48.9],[-52.25,-60.9],[-52.25,-15],[-20.05,-6.1],[16.55,4],[46.05,55.9],[44.35,60.9]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,60.9],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 16","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Logo 2 Outlines 2","parent":9,"tt":1,"tp":22,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-52.9,17,0],"ix":2,"l":2},"a":{"a":0,"k":[52,61,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.2,22.5],[-0.7,1.7],[0,-11.1],[-35,-9.6],[0,0],[0,0],[0,0]],"o":[[-22.5,-6.2],[0.5,-1.7],[-4.3,10],[0,36.3],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.5,-3.95],[-46,-55.85],[-44.3,-60.85],[-50.9,-28.95],[8.4,48.85],[52.2,60.85],[52.2,14.95],[20,6.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[50.9,60.85],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Shape Layer 15","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Logo 3 Outlines 2","parent":23,"tt":1,"tp":24,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53,-9.5,0],"ix":2,"l":2},"a":{"a":0,"k":[50.5,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-22.183,-6.65],[0,0],[-22.8,18.8],[0,0],[0,0],[0,0],[5,-11.7],[0.4,-1.8]],"o":[[0,0],[-28.4,-7.9],[0,0],[0,0],[0,0],[-10.1,8.3],[-0.7,1.7],[-4.658,17.4]],"v":[[-17.825,66.725],[18.6,76.3],[6.7,15.75],[52.3,-21.75],[52.3,-79.05],[-21.4,-18.55],[-44.3,11.95],[-46.1,17.05]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[47.758,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Shape Layer 14","parent":21,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.8,"y":0},"t":66,"s":[374.001,-234.909,0],"to":[-47.967,35.386,0],"ti":[47.967,-35.386,0]},{"t":127,"s":[86.2,-22.596,0]}],"ix":2,"l":2},"a":{"a":0,"k":[82.594,-102.985,0],"ix":1,"l":2},"s":{"a":0,"k":[94.766,94.766,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[297.188,298.029],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.074509803922,0.074509803922,0.137254901961,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.5,0.5,0.5,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[34.502,-14.813],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[151.791,151.791],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":-9,"ct":1,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Logo Outlines 2","parent":21,"tt":1,"tp":26,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.5,131,0],"ix":2,"l":2},"a":{"a":0,"k":[50,79.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[19.3,7.275],[0,0],[22.8,-18.8],[0,0],[0,0],[0,0],[-5,11.7],[-0.5,1.7]],"o":[[0,0],[28.4,7.9],[0,0],[0,0],[0,0],[10.1,-8.3],[0.7,-1.6],[6.1,-22.6]],"v":[[17.45,-65.7],[-15.55,-74.3],[-6.65,-15.75],[-52.25,21.75],[-52.25,79.05],[21.45,18.55],[44.35,-11.95],[46.15,-16.95]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.364705882353,0.364705882353,0.443137284821,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[52.25,79.05],"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,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":194,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Logo Light 2","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.25],"y":[1]},"o":{"x":[0.75],"y":[0]},"t":0,"s":[0]},{"t":64,"s":[-360]}],"ix":10,"x":"var $bm_rt;\n$bm_rt = loopOut();"},"p":{"a":0,"k":[1026,268,0],"ix":2,"l":2,"x":"var $bm_rt;\n$bm_rt = transform.position;"},"a":{"a":0,"k":[540,264,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"tm":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-120,"s":[0]},{"t":177,"s":[4.95]}],"ix":2},"w":1080,"h":562,"ip":0,"op":64,"st":-120,"bm":0}],"markers":[],"props":{}}
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/Resources/animation-refreshing-shakuro_logo_old.json:
--------------------------------------------------------------------------------
1 | {"v":"5.1.1","fr":60,"ip":0,"op":80,"w":464,"h":130,"nm":"Slicing Part 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 17","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":0,"s":[0],"e":[180]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":30,"s":[180],"e":[180]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":40,"s":[180],"e":[360]},{"t":70}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[232,65.25,0],"e":[232,68.25,0],"to":[0,0.5,0],"ti":[0,-0.5,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":30,"s":[232,68.25,0],"e":[232,68.25,0],"to":[0,0,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":40,"s":[232,68.25,0],"e":[232,65.25,0],"to":[0,-0.5,0],"ti":[0,0.5,0]},{"t":70}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[70,70,100],"ix":6}},"ao":0,"ip":0,"op":80,"st":-70,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Yellow Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":-50,"s":[0],"e":[720]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p833_1_0p5_0"],"t":0,"s":[720],"e":[747]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":10,"s":[747],"e":[747]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p5_1_0p167_0"],"t":20,"s":[747],"e":[720]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":30,"s":[720],"e":[720]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p833_1_0p5_0"],"t":40,"s":[720],"e":[747]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":50,"s":[747],"e":[747]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p5_1_0p167_0"],"t":60,"s":[747],"e":[720]},{"t":70}],"ix":10},"p":{"a":0,"k":[-25.714,-7.786,0],"ix":2},"a":{"a":0,"k":[20.5,33,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":[[0,4.72],[-2.52,4],[0,0],[1.28,-1.18],[3.82,-3.56],[1.822,-1.901],[-0.111,-2.921],[-4.04,-3.76],[-5.7,-5.04],[-2.973,0.456],[-0.944,2.856],[2.115,2.138],[3.02,4.18],[0.6,1.18],[1.22,1.7]],"o":[[0,-4.74],[0,0],[-1.28,1.2],[-3.82,3.56],[-2.015,1.696],[-1.898,2.223],[0.2,6],[5.58,5.18],[1.757,2.441],[2.973,-0.456],[0.944,-2.855],[-2.72,-4.38],[-0.78,-1.24],[-1.4,-2],[-2.6,-4.02]],"v":[[-288.345,347.56],[-282.725,335.78],[-282.185,335.02],[-286.005,338.62],[-297.405,349.36],[-303.165,354.76],[-305.945,362.76],[-296.505,376.1],[-279.845,391.78],[-272.138,395.014],[-265.756,389.617],[-267.665,381.48],[-276.385,368.54],[-278.645,365.04],[-282.645,359.34]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960784314,0.035294117647,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.945,-330],"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,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.12,0.18],[3.02,4.18],[0,2.5],[-1.34,2.12],[-2.72,4.4],[1.134,2.805],[2.657,0.444],[1.945,-2.361],[1.9,-1.78],[3.82,-3.56],[1.822,-1.901],[-0.111,-2.921],[-4.04,-3.76],[-5.7,-5.04],[-2.973,0.456],[-0.944,2.856],[2.115,2.138]],"o":[[-2.72,-4.38],[-1.34,-2.12],[0,-2.5],[3.02,-4.18],[1.899,-2.355],[-1.088,-2.464],[-3.033,-0.395],[-2,1.72],[-3.7,3.56],[-2.015,1.696],[-1.898,2.223],[0.2,6],[5.58,5.18],[1.757,2.441],[2.973,-0.456],[0.944,-2.855],[-0.1,-0.2]],"v":[[-267.665,381.46],[-276.385,368.52],[-279.365,362.3],[-276.385,356.06],[-267.665,343.12],[-266.425,334.76],[-272.425,330.1],[-280.425,333.26],[-286.125,338.62],[-297.405,349.36],[-303.165,354.76],[-305.945,362.76],[-296.505,376.1],[-279.845,391.78],[-272.138,395.014],[-265.756,389.617],[-267.665,381.48]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.866666666667,0.752941176471,0.047058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.945,-330],"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 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":80,"st":-70,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Green Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":-50,"s":[0],"e":[720]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p833_1_0p5_0"],"t":0,"s":[720],"e":[747]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":10,"s":[747],"e":[747]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p5_1_0p167_0"],"t":20,"s":[747],"e":[720]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p5_1_0p5_0"],"t":30,"s":[720],"e":[720]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.5],"y":[0]},"n":["0p833_1_0p5_0"],"t":40,"s":[720],"e":[747]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":50,"s":[747],"e":[747]},{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p5_1_0p167_0"],"t":60,"s":[747],"e":[720]},{"t":70}],"ix":10},"p":{"a":0,"k":[27,12.607,0],"ix":2},"a":{"a":0,"k":[20.5,32.5,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":[[0,-4.72],[2.52,-4],[0.18,-0.26],[0,0],[-3.82,3.56],[-1.82,1.896],[0.125,2.923],[4.04,3.76],[5.72,5.04],[3.38,-2.85],[-2.85,-3.38],[-3.02,-4.18],[-0.6,-1.18],[0,0]],"o":[[0,4.74],[-0.18,0.24],[0,0],[3.82,-3.56],[2.004,-1.701],[1.911,-2.216],[-0.2,-6],[-5.58,-5.18],[-2.85,-3.38],[-3.38,2.85],[2.72,4.38],[0.8,1.24],[0,0],[2.64,4]],"v":[[-282.835,378.52],[-288.455,390.3],[-288.975,391.06],[-285.175,387.46],[-273.755,376.72],[-268.015,371.32],[-265.235,363.32],[-274.675,349.98],[-291.335,334.3],[-302.615,333.34],[-303.575,344.62],[-294.855,357.56],[-292.575,361.06],[-288.575,366.76]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.619607843137,0.76862745098,0.247058823529,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.575,-331],"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,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.16],[-3.02,-4.18],[0,-2.5],[1.34,-2],[2.72,-4.4],[-1.134,-2.805],[-2.657,-0.444],[-1.942,2.364],[-1.9,1.78],[-3.82,3.56],[-1.82,1.896],[0.125,2.923],[4.04,3.76],[5.72,5.04],[3.413,-2.855],[-2.855,-3.413]],"o":[[2.72,4.38],[1.34,2.12],[0,2.5],[-3.02,4.18],[-1.899,2.355],[1.088,2.464],[3.033,0.399],[2,-1.72],[3.82,-3.56],[2.004,-1.701],[1.911,-2.216],[-0.2,-6],[-5.58,-5.18],[-2.855,-3.413],[-3.413,2.855],[0.18,0.18]],"v":[[-303.572,344.441],[-294.852,357.381],[-291.872,363.601],[-294.792,369.821],[-303.512,382.761],[-304.752,391.121],[-298.752,395.781],[-290.752,392.621],[-285.052,387.261],[-273.632,376.521],[-267.892,371.121],[-265.112,363.121],[-274.552,349.781],[-291.212,334.101],[-302.562,333.091],[-303.572,344.441]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.450980392157,0.666666666667,0.18431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[305.572,-330.821],"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 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":80,"st":-70,"bm":0}],"markers":[]}
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/CircleAnimationWithProgressView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | struct CircleAnimationWithProgressView: View {
10 |
11 | private var progress: CGFloat
12 |
13 | init(progress: CGFloat) {
14 | self.progress = progress
15 | }
16 |
17 | var body: some View {
18 | Circle()
19 | .trim(from: 0, to: progress * 0.9)
20 | .stroke(Color.green, lineWidth: 5)
21 | .frame(width: 40, height: 40)
22 | .rotationEffect(Angle(degrees: 270))
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/CircleAnimationWithRepeatView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | struct CircleAnimationWithRepeatView: View {
10 |
11 | @State private var rotationDegrees: CGFloat = 0.0
12 |
13 | var body: some View {
14 | Circle()
15 | .trim(from: 0, to: 0.9)
16 | .stroke(Color.green, lineWidth: 5)
17 | .frame(width: 40, height: 40)
18 | .rotationEffect(Angle(degrees: 270))
19 | .rotationEffect(Angle(degrees: rotationDegrees))
20 | .animation(.linear(duration: 1).repeatForever(autoreverses: false), value: rotationDegrees)
21 | .onAppear(perform: {
22 | rotationDegrees = 360
23 | })
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | struct ContentView: View {
10 |
11 | private enum Option {
12 | case list
13 | case scroll
14 | }
15 |
16 | @State private var options: [Option] = [.list, .scroll]
17 |
18 | var body: some View {
19 | NavigationView(content: {
20 | List(content: {
21 | ForEach(options, id: \.self, content: { (option) in
22 | NavigationLink(destination: {
23 | switch option {
24 | case .list:
25 | ListContentView()
26 | case .scroll:
27 | ScrollContentView()
28 | }
29 | }, label: {
30 | switch option {
31 | case .list:
32 | Text("List View")
33 | case .scroll:
34 | Text("Scroll View")
35 | }
36 | })
37 | })
38 | })
39 | .navigationTitle("Options")
40 | .navigationBarTitleDisplayMode(.inline)
41 | })
42 | }
43 |
44 | }
45 |
46 | #Preview {
47 | ContentView()
48 | }
49 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/ContentViewWithSplitView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | @available(iOS 17.0, *)
10 | struct ContentViewWithSplitView: View {
11 |
12 | private enum Option {
13 | case list
14 | case scroll
15 | }
16 |
17 | @State private var options: [Option] = [.list, .scroll]
18 | @State private var preferredColumn = NavigationSplitViewColumn.sidebar
19 | @State private var selectedOption: Option?
20 |
21 | var body: some View {
22 | NavigationSplitView(preferredCompactColumn: $preferredColumn) {
23 | List(selection: $selectedOption) {
24 | ForEach(Array(options), id: \.self) { (option) in
25 | NavigationLink(value: option) {
26 | switch option {
27 | case .list:
28 | Text("List View")
29 | case .scroll:
30 | Text("Scroll View")
31 | }
32 | }
33 | }
34 | }
35 | .navigationTitle("Options")
36 | .navigationBarTitleDisplayMode(.inline)
37 | } detail: {
38 | switch selectedOption {
39 | case .list:
40 | ListContentView()
41 | case .scroll:
42 | ScrollContentView()
43 | case .none:
44 | Text("Choose an item from the content")
45 | }
46 | }
47 | }
48 |
49 | }
50 |
51 | @available(iOS 17.0, *)
52 | #Preview(body: {
53 | ContentViewWithSplitView()
54 | })
55 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/ListContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import Lottie
8 | import PullToRefreshSwiftUI
9 | import SwiftUI
10 |
11 | struct ListItem: Identifiable {
12 |
13 | var title: String
14 |
15 | // MARK: - Identifiable
16 |
17 | var id: String {
18 | return title
19 | }
20 |
21 | }
22 |
23 | struct ListContentView: View {
24 |
25 | private enum AnimationType {
26 | case native
27 | case progressView
28 | case lottie
29 | }
30 |
31 | @State private var isRefreshing: Bool = false
32 | @State private var animationType: AnimationType = .native
33 |
34 | @State private var items: [ListItem] = [
35 | ListItem(title: "Item 1"),
36 | ListItem(title: "Item 2"),
37 | ListItem(title: "Item 3"),
38 | ListItem(title: "Item 4"),
39 | ListItem(title: "Item 5"),
40 | ListItem(title: "Item 6"),
41 | ListItem(title: "Item 7"),
42 | ListItem(title: "Item 8"),
43 | ListItem(title: "Item 9"),
44 | ListItem(title: "Item 10"),
45 | ListItem(title: "Item 11"),
46 | ListItem(title: "Item 12"),
47 | ListItem(title: "Item 13"),
48 | ListItem(title: "Item 14"),
49 | ListItem(title: "Item 15"),
50 | ListItem(title: "Item 16"),
51 | ListItem(title: "Item 17"),
52 | ListItem(title: "Item 18"),
53 | ListItem(title: "Item 19"),
54 | ListItem(title: "Item 20"),
55 | ListItem(title: "Item 21"),
56 | ]
57 |
58 | var body: some View {
59 | PullToRefreshListView(
60 | pullToRefreshAnimationHeight: 100,
61 | pullToRefreshPullHeight: 100,
62 | showsIndicators: true,
63 | isRefreshing: $isRefreshing,
64 | onRefresh: {
65 | debugPrint("Refreshing")
66 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(5), execute: {
67 | isRefreshing = false
68 | items.shuffle()
69 | })
70 | },
71 | animationViewBuilder: { (state) in
72 | switch state {
73 | case .idle:
74 | Color.clear
75 | case .pulling(let progress):
76 | switch animationType {
77 | case .native:
78 | CircleAnimationWithProgressView(progress: progress)
79 | case .progressView:
80 | ProgressView(value: max(min(progress, 1), 0), total: 1)
81 | .progressViewStyle(.linear)
82 | case .lottie:
83 | LottieView(animation: .named("animation-pulling-shakuro_logo"))
84 | .playbackMode(.paused(at: .progress(progress)))
85 | }
86 | case .refreshing:
87 | switch animationType {
88 | case .native:
89 | CircleAnimationWithRepeatView()
90 | case .progressView:
91 | ProgressView()
92 | .progressViewStyle(.circular)
93 | case .lottie:
94 | LottieView(animation: .named("animation-refreshing-shakuro_logo"))
95 | .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
96 | }
97 | case .finishing:
98 | switch animationType {
99 | case .native:
100 | CircleAnimationWithRepeatView()
101 | case .progressView:
102 | ProgressView()
103 | .progressViewStyle(.circular)
104 | case .lottie:
105 | LottieView(animation: .named("animation-refreshing-shakuro_logo"))
106 | .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
107 | }
108 | }
109 | },
110 | contentViewBuilder: { _ in
111 | Picker("Current animation type", selection: $animationType) {
112 | Text("Native").tag(AnimationType.native)
113 | Text("ProgressView").tag(AnimationType.progressView)
114 | Text("Lottie").tag(AnimationType.lottie)
115 | }
116 | .pickerStyle(.segmented)
117 | .listRowSeparator(.hidden, edges: .top)
118 | ForEach(items, content: { (item) in
119 | ListContentItemView(listItem: item)
120 | })
121 | .onDelete(perform: { (indexSet) in
122 | items.remove(atOffsets: indexSet)
123 | })
124 | .onMove(perform: { (indices, newOffset) in
125 | items.move(fromOffsets: indices, toOffset: newOffset)
126 | })
127 | })
128 | .navigationTitle("Items")
129 | .navigationBarTitleDisplayMode(.inline)
130 | .navigationBarItems(trailing: EditButton())
131 | }
132 |
133 | }
134 |
135 | struct ListContentItemView: View {
136 |
137 | let listItem: ListItem
138 |
139 | var body: some View {
140 | NavigationLink(destination: ListContentItemDetailView(listItem: listItem)) {
141 | HStack {
142 | Text(listItem.title)
143 | .font(.headline)
144 | .lineLimit(1)
145 | Spacer()
146 | }
147 | .padding(.vertical, 8)
148 | }
149 | }
150 | }
151 |
152 | struct ListContentItemDetailView: View {
153 |
154 | let listItem: ListItem
155 |
156 | var body: some View {
157 | ZStack {
158 | VStack {
159 | Text(listItem.title)
160 | .font(.largeTitle)
161 | .padding(.bottom, 10)
162 | Spacer()
163 | }
164 | }
165 | .navigationTitle(listItem.title)
166 | .edgesIgnoringSafeArea(.bottom)
167 | }
168 | }
169 |
170 | #Preview {
171 | ListContentView()
172 | }
173 |
--------------------------------------------------------------------------------
/PullToRefreshSample/PullToRefreshSampleiOS/UI/ScrollContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import Lottie
8 | import PullToRefreshSwiftUI
9 | import SwiftUI
10 |
11 | struct ScrollContentView: View {
12 |
13 | private enum AnimationType {
14 | case native
15 | case progressView
16 | case lottie
17 | }
18 |
19 | @State private var isRefreshing: Bool = false
20 | @State private var animationType: AnimationType = .native
21 |
22 | var body: some View {
23 | PullToRefreshScrollView(
24 | pullToRefreshAnimationHeight: 100,
25 | animationDuration: 0.3,
26 | offsetAboveRefreshingAnimation: 110,
27 | isRefreshing: $isRefreshing,
28 | onRefresh: {
29 | debugPrint("Refreshing")
30 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(5), execute: {
31 | isRefreshing = false
32 | })
33 | },
34 | animationViewBuilder: { (state) in
35 | switch state {
36 | case .idle:
37 | Color.clear
38 | case .pulling(let progress):
39 | switch animationType {
40 | case .native:
41 | CircleAnimationWithProgressView(progress: progress)
42 | case .progressView:
43 | ProgressView(value: progress, total: 1)
44 | .progressViewStyle(.linear)
45 | case .lottie:
46 | LottieView(animation: .named("animation-pulling-shakuro_logo"))
47 | .playbackMode(.paused(at: .progress(progress)))
48 | }
49 | case .refreshing:
50 | switch animationType {
51 | case .native:
52 | CircleAnimationWithRepeatView()
53 | case .progressView:
54 | ProgressView()
55 | .progressViewStyle(.circular)
56 | case .lottie:
57 | LottieView(animation: .named("animation-refreshing-shakuro_logo"))
58 | .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
59 | }
60 | case .finishing(let progress, let isTriggered):
61 | if isTriggered {
62 | switch animationType {
63 | case .native:
64 | CircleAnimationWithRepeatView()
65 | case .progressView:
66 | ProgressView()
67 | .progressViewStyle(.circular)
68 | case .lottie:
69 | LottieView(animation: .named("animation-refreshing-shakuro_logo"))
70 | .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
71 | .opacity(progress)
72 | .scaleEffect(progress)
73 | }
74 | } else {
75 | switch animationType {
76 | case .native:
77 | CircleAnimationWithProgressView(progress: progress)
78 | case .progressView:
79 | ProgressView(value: progress, total: 1)
80 | .progressViewStyle(.linear)
81 | case .lottie:
82 | LottieView(animation: .named("animation-pulling-shakuro_logo"))
83 | .playbackMode(.paused(at: .progress(progress)))
84 | }
85 | }
86 | }
87 | },
88 | contentViewBuilder: { _ in
89 | VStack(spacing: 16, content: {
90 | Text(isRefreshing ? "Refreshing" : "Idle")
91 | .font(.largeTitle)
92 | .foregroundStyle(isRefreshing ? .white : .black)
93 | Picker("Current animation type", selection: $animationType) {
94 | Text("Native").tag(AnimationType.native)
95 | Text("ProgressView").tag(AnimationType.progressView)
96 | Text("Lottie").tag(AnimationType.lottie)
97 | }
98 | .pickerStyle(.segmented)
99 | Color.clear
100 | })
101 | .padding(EdgeInsets(top: 16, leading: 16, bottom: 16, trailing: 16))
102 | .background(Color(isRefreshing ? .darkGray : .lightGray))
103 | .animation(.linear(duration: 0.3), value: isRefreshing)
104 | .frame(height: 1000)
105 | })
106 | .navigationTitle("Scroll View Example")
107 | .navigationBarTitleDisplayMode(.inline)
108 | }
109 |
110 | }
111 |
112 | #Preview {
113 | ScrollContentView()
114 | }
115 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # PullToRefreshSwiftUI
4 | 
5 | 
6 | 
7 |
8 | - [ScrollView](#scrollview)
9 | - [List](#list)
10 | - [Requirements](#requirements)
11 | - [Installation](#installation)
12 | - [Usage](#usage)
13 | - [License](#license)
14 |
15 | `PullToRefreshSwiftUI` package contains `PullToRefreshScrollView` and `PullToRefreshListView` controls, that allows to add pull to refresh to ScrollView and List SwiftUI containers.
16 |
17 | 
18 |
19 | ## ScrollView
20 |
21 | A `PullToRefreshScrollView` is a custom control that alows to put some content on scroll view with pull to refresh action.
22 |
23 | `PullToRefreshScrollView` example:
24 |
25 | ```swift
26 | PullToRefreshListView(
27 | pullToRefreshAnimationHeight: 100,
28 | pullToRefreshPullHeight: 100,
29 | isRefreshing: .constant(true),
30 | onRefresh: {
31 | debugPrint("Refreshing")
32 | },
33 | animationViewBuilder: { (state) in
34 | switch state {
35 | case .idle:
36 | Color.clear
37 | case .pulling(let progress):
38 | ProgressView(value: progress, total: 1)
39 | .progressViewStyle(.linear)
40 | case .refreshing:
41 | ProgressView()
42 | .progressViewStyle(.circular)
43 | case .finishing(let progress, let isTriggered):
44 | if isTriggered {
45 | ProgressView()
46 | .progressViewStyle(.circular)
47 | } else {
48 | ProgressView(value: progress, total: 1)
49 | .progressViewStyle(.linear)
50 | }
51 | }
52 | },
53 | contentViewBuilder: { _ in
54 | ForEach(0..<5, content: { (item) in
55 | Text("Item \(item)")
56 | })
57 | })
58 | ```
59 |
60 | 
61 |
62 | ## List
63 |
64 | A `PullToRefreshListView` is a custom control that alows to add some content to list view with pull to refresh action.
65 |
66 | `PullToRefreshListView` example:
67 |
68 | ```swift
69 | PullToRefreshListView(
70 | options: PullToRefreshListViewOptions(pullToRefreshAnimationHeight: 100,
71 | animationDuration: 0.3,
72 | animatePullingViewPresentation: true,
73 | animateRefreshingViewPresentation: true),
74 | isRefreshing: $isRefreshing,
75 | onRefresh: {
76 | debugPrint("Refreshing")
77 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(5), execute: {
78 | isRefreshing = false
79 | })
80 | },
81 | animationViewBuilder: { (state) in
82 | switch state {
83 | case .idle:
84 | Color.clear
85 | case .pulling(let progress):
86 | ProgressView(value: progress, total: 1)
87 | .progressViewStyle(.linear)
88 | case .refreshing:
89 | ProgressView()
90 | .progressViewStyle(.circular)
91 | case .finishing(let progress, let isTriggered):
92 | if isTriggered {
93 | ProgressView()
94 | .progressViewStyle(.circular)
95 | } else {
96 | ProgressView(value: progress, total: 1)
97 | .progressViewStyle(.linear)
98 | }
99 | }
100 | },
101 | contentViewBuilder: { _ in
102 | ForEach(0..<5, content: { (item) in
103 | Text("Item \(item)")
104 | })
105 | })
106 | ```
107 |
108 | 
109 |
110 | ## Requirements
111 |
112 | - iOS 15.0+
113 | - Xcode 15.0+
114 | - Swift 5.9+
115 |
116 | ## Installation
117 |
118 | ### Swift Package Manager
119 |
120 | **App dependency**
121 |
122 | Select File > Add Package Dependencies and enter the repository URL ([Adding Package Dependencies to Your App](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app))
123 |
124 | **Package dependency**
125 |
126 | Add `PullToRefreshSwiftUI` as a dependency in your `Package.swift` manifest:
127 |
128 | ```swift
129 | dependencies: [
130 | .package(url: "https://github.com/shakurocom/PullToRefreshSwiftUI.git", from: "1.6.0")
131 | ]
132 | ```
133 |
134 | ### CocoaPods
135 |
136 | To integrate PullToRefreshSwiftUI into your Xcode project with CocoaPods, specify it in your `Podfile`:
137 |
138 | ```ruby
139 | pod 'Shakuro.PullToRefreshSwiftUI'
140 | ```
141 |
142 | Then, run the following command:
143 |
144 | ```bash
145 | $ pod install
146 | ```
147 |
148 | ### Manually
149 |
150 | If you prefer not to use CocoaPods, you can integrate Shakuro.PullToRefreshSwiftUI simply by copying it to your project.
151 |
152 | ## Usage
153 |
154 | Have a look at the [PullToRefreshSampleiOS](https://github.com/shakurocom/PullToRefreshSwiftUI/tree/main/PullToRefreshSample)
155 |
156 | ## License
157 |
158 | Shakuro.PullToRefreshSwiftUI is released under the MIT license. [See LICENSE](https://github.com/shakurocom/PullToRefreshSwiftUI/blob/main/LICENSE.md) for details.
159 |
160 | ## Give it a try and reach us
161 |
162 | Explore our expertise in Native Mobile Development and iOS Development.
163 |
164 | If you need professional assistance with your mobile or web project, feel free to contact our team
165 |
--------------------------------------------------------------------------------
/Resources/pull_to_refresh_example_1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shakurocom/PullToRefreshSwiftUI/8a75b3693449f9fe062492584575887b76d528bb/Resources/pull_to_refresh_example_1.gif
--------------------------------------------------------------------------------
/Resources/pull_to_refresh_example_2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shakurocom/PullToRefreshSwiftUI/8a75b3693449f9fe062492584575887b76d528bb/Resources/pull_to_refresh_example_2.gif
--------------------------------------------------------------------------------
/Resources/pull_to_refresh_example_main.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shakurocom/PullToRefreshSwiftUI/8a75b3693449f9fe062492584575887b76d528bb/Resources/pull_to_refresh_example_main.gif
--------------------------------------------------------------------------------
/Resources/title_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shakurocom/PullToRefreshSwiftUI/8a75b3693449f9fe062492584575887b76d528bb/Resources/title_image.png
--------------------------------------------------------------------------------
/Shakuro.PullToRefreshSwiftUI.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = 'Shakuro.PullToRefreshSwiftUI'
4 | s.version = '1.6.5'
5 | s.summary = 'PullToRefreshSwiftUI'
6 | s.homepage = 'https://github.com/shakurocom/PullToRefreshSwiftUI'
7 | s.license = { :type => "MIT", :file => "LICENSE.md" }
8 | s.authors = {'wwwpix' => 'spopov@shakuro.com'}
9 | s.source = { :git => 'https://github.com/shakurocom/PullToRefreshSwiftUI.git', :tag => s.version }
10 | s.swift_versions = ['5.9']
11 | s.source_files = 'Sources/PullToRefreshSwiftUI/*'
12 | s.ios.deployment_target = '15.0'
13 |
14 | end
15 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/GeometryGroupModifier.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | public struct GeometryGroupModifier: ViewModifier {
10 |
11 | public init() { }
12 |
13 | public func body(content: Content) -> some View {
14 | if #available(iOS 17.0, *) {
15 | content
16 | // https://medium.com/the-swift-cooperative/swiftui-geometrygroup-guide-from-theory-to-practice-1a7f4b04c4ec
17 | .geometryGroup()
18 | } else {
19 | content
20 | .transformEffect(.identity)
21 | }
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/PullToRefreshListView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | public enum PullToRefreshListViewState: Equatable {
10 | case idle
11 | case pulling(progress: CGFloat)
12 | case refreshing
13 | case finishing // state after refreshing - view returning to idle state
14 | }
15 |
16 | public struct PullToRefreshListView: View {
17 |
18 | private let pullToRefreshAnimationHeight: CGFloat
19 | private let pullToRefreshPullHeight: CGFloat
20 | private let offsetAboveRefreshingAnimation: CGFloat
21 | private let showsIndicators: Bool
22 | private let isPullToRefreshEnabled: Bool
23 | private let onScroll: (_ oldOffsetY: CGFloat, _ newOffsetY: CGFloat, _ isInteracting: Bool) -> Void
24 | private let onEndDragging: () -> Void
25 | private let isRefreshing: Binding
26 | private let onRefresh: () -> Void
27 | private let animationViewBuilder: (_ state: PullToRefreshListViewState) -> AnimationViewType
28 | private let contentViewBuilder: (_ scrollViewSize: CGSize) -> ContentViewType
29 |
30 | // MARK: - Initialization
31 |
32 | /// - parameter onScroll: iOS 18+
33 | /// - parameter onEndDragging: iOS 18+
34 | public init(pullToRefreshAnimationHeight: CGFloat,
35 | pullToRefreshPullHeight: CGFloat,
36 | showsIndicators: Bool = true,
37 | isPullToRefreshEnabled: Bool = true,
38 | offsetAboveRefreshingAnimation: CGFloat = 0,
39 | onScroll: @escaping (_ oldOffsetY: CGFloat, _ newOffsetY: CGFloat, _ isInteracting: Bool) -> Void = { _, _, _ in },
40 | onEndDragging: @escaping () -> Void = { },
41 | isRefreshing: Binding,
42 | onRefresh: @escaping () -> Void,
43 | @ViewBuilder animationViewBuilder: @escaping (_ state: PullToRefreshListViewState) -> AnimationViewType,
44 | @ViewBuilder contentViewBuilder: @escaping (_ scrollViewSize: CGSize) -> ContentViewType) {
45 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
46 | self.pullToRefreshPullHeight = pullToRefreshPullHeight
47 | self.offsetAboveRefreshingAnimation = offsetAboveRefreshingAnimation
48 | self.showsIndicators = showsIndicators
49 | self.isPullToRefreshEnabled = isPullToRefreshEnabled
50 | self.onScroll = onScroll
51 | self.onEndDragging = onEndDragging
52 | self.isRefreshing = isRefreshing
53 | self.onRefresh = onRefresh
54 | self.animationViewBuilder = animationViewBuilder
55 | self.contentViewBuilder = contentViewBuilder
56 | }
57 |
58 | // MARK: - UI
59 |
60 | public var body: some View {
61 | if #available(iOS 18.0, *) {
62 | PullToRefreshListView18IOS(pullToRefreshAnimationHeight: pullToRefreshAnimationHeight,
63 | pullToRefreshPullHeight: pullToRefreshPullHeight,
64 | showsIndicators: showsIndicators,
65 | isPullToRefreshEnabled: isPullToRefreshEnabled,
66 | offsetAboveRefreshingAnimation: offsetAboveRefreshingAnimation,
67 | onScroll: onScroll,
68 | onEndDragging: onEndDragging,
69 | isRefreshing: isRefreshing,
70 | onRefresh: onRefresh,
71 | animationViewBuilder: animationViewBuilder,
72 | contentViewBuilder: contentViewBuilder)
73 | } else {
74 | PullToRefreshListViewOldIOS(pullToRefreshAnimationHeight: pullToRefreshAnimationHeight,
75 | showsIndicators: showsIndicators,
76 | isPullToRefreshEnabled: isPullToRefreshEnabled,
77 | offsetAboveRefreshingAnimation: offsetAboveRefreshingAnimation,
78 | isRefreshing: isRefreshing,
79 | onRefresh: onRefresh,
80 | animationViewBuilder: animationViewBuilder,
81 | contentViewBuilder: contentViewBuilder)
82 | }
83 | }
84 |
85 | }
86 |
87 | // MARK: - Preview
88 |
89 | #Preview(body: {
90 | PullToRefreshListView(
91 | pullToRefreshAnimationHeight: 100,
92 | pullToRefreshPullHeight: 100,
93 | isRefreshing: .constant(true),
94 | onRefresh: {
95 | debugPrint("Refreshing")
96 | },
97 | animationViewBuilder: { (state) in
98 | switch state {
99 | case .idle:
100 | Color.clear
101 | case .pulling(let progress):
102 | ProgressView(value: progress, total: 1)
103 | .progressViewStyle(.linear)
104 | case .refreshing:
105 | ProgressView()
106 | .progressViewStyle(.circular)
107 | case .finishing:
108 | ProgressView()
109 | .progressViewStyle(.circular)
110 | }
111 | },
112 | contentViewBuilder: { _ in
113 | ForEach(0..<5, content: { (item) in
114 | Text("Item \(item)")
115 | })
116 | })
117 | })
118 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/PullToRefreshListView18IOS.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2025 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | @available(iOS 18.0, *)
10 | public struct PullToRefreshListView18IOS: View {
11 |
12 | private let pullToRefreshAnimationHeight: CGFloat
13 | private let pullToRefreshPullHeight: CGFloat
14 | private let animationDuration: TimeInterval
15 | private let offsetAboveRefreshingAnimation: CGFloat
16 | private let showsIndicators: Bool
17 | private let isPullToRefreshEnabled: Bool
18 | private let onScroll: (_ oldOffsetY: CGFloat, _ newOffsetY: CGFloat, _ isInteracting: Bool) -> Void
19 | private let onEndDragging: () -> Void
20 | private let isRefreshing: Binding
21 | private let onRefresh: () -> Void
22 | private let animationViewBuilder: (_ state: PullToRefreshListViewState) -> AnimationViewType
23 | private let contentViewBuilder: (_ scrollViewSize: CGSize) -> ContentViewType
24 |
25 | @State private var scrollViewSize: CGSize = .zero // needed to build content
26 | @State private var animationOffsetY: CGFloat = 0 // offset to keep refreshing animation in proper place
27 | @State private var pullToRefreshProgressPoints: CGFloat = 0 // progress of pull-to-refresh
28 | @State private var isInteracting: Bool = false // user is actively dragging scroll
29 | @State private var pullToRefreshState: PullToRefreshListViewState = .idle // state of the animation
30 |
31 | // MARK: - Initialization
32 |
33 | public init(pullToRefreshAnimationHeight: CGFloat,
34 | pullToRefreshPullHeight: CGFloat,
35 | animationDuration: TimeInterval = 0.3,
36 | showsIndicators: Bool = true,
37 | isPullToRefreshEnabled: Bool = true,
38 | offsetAboveRefreshingAnimation: CGFloat = 0,
39 | onScroll: @escaping (_ oldOffsetY: CGFloat, _ newOffsetY: CGFloat, _ isInteracting: Bool) -> Void = { _, _, _ in },
40 | onEndDragging: @escaping () -> Void = { },
41 | isRefreshing: Binding,
42 | onRefresh: @escaping () -> Void,
43 | @ViewBuilder animationViewBuilder: @escaping (_ state: PullToRefreshListViewState) -> AnimationViewType,
44 | @ViewBuilder contentViewBuilder: @escaping (_ scrollViewSize: CGSize) -> ContentViewType) {
45 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
46 | self.pullToRefreshPullHeight = pullToRefreshPullHeight
47 | self.animationDuration = animationDuration
48 | self.offsetAboveRefreshingAnimation = offsetAboveRefreshingAnimation
49 | self.showsIndicators = showsIndicators
50 | self.isPullToRefreshEnabled = isPullToRefreshEnabled
51 | self.onScroll = onScroll
52 | self.onEndDragging = onEndDragging
53 | self.isRefreshing = isRefreshing
54 | self.onRefresh = onRefresh
55 | self.animationViewBuilder = animationViewBuilder
56 | self.contentViewBuilder = contentViewBuilder
57 | }
58 |
59 | // MARK: - UI
60 |
61 | public var body: some View {
62 | ZStack(alignment: .top, content: {
63 | pullToRefreshAnimationView()
64 | mainListView()
65 | })
66 | .clipped()
67 | .onChange(of: isRefreshing.wrappedValue, { (_, newIsRefreshing: Bool) -> Void in
68 | if newIsRefreshing {
69 | showPullToRefreshAnimationIfNeeded()
70 | } else {
71 | endPullToRefreshAnimationIfNeeded()
72 | }
73 | })
74 | }
75 |
76 | @ViewBuilder
77 | private func mainListView() -> some View {
78 | List(content: {
79 | Color.clear
80 | .frame(height: offsetAboveRefreshingAnimation)
81 | .listRowSeparator(.hidden)
82 | .listRowInsets(EdgeInsets())
83 | .listRowBackground(Color.clear)
84 | .id("above-offset")
85 | if pullToRefreshState == .refreshing {
86 | Color.clear
87 | .frame(height: pullToRefreshPullHeight)
88 | .listRowSeparator(.hidden)
89 | .listRowInsets(EdgeInsets())
90 | .listRowBackground(Color.clear)
91 | .id("refreshing-spacer")
92 | }
93 | contentViewBuilder(scrollViewSize)
94 | .modifier(GeometryGroupModifier())
95 | })
96 | .environment(\.defaultMinListRowHeight, 0)
97 | .listStyle(PlainListStyle())
98 | .animation(.easeInOut(duration: animationDuration), value: pullToRefreshState)
99 | .onScrollGeometryChange(
100 | for: ScrollGeometry.self,
101 | of: { return $0 },
102 | action: { (oldValue: ScrollGeometry, newValue: ScrollGeometry) -> Void in
103 | scrollViewSize = newValue.bounds.size
104 | // top inset is usually added by standard navigation bar
105 | let oldOffsetY = oldValue.contentOffset.y + oldValue.contentInsets.top
106 | let newOffsetY = newValue.contentOffset.y + newValue.contentInsets.top
107 | onScroll(oldOffsetY, newOffsetY, isInteracting)
108 | updateAnimationOffset(contentOffset: newOffsetY)
109 | })
110 | .onScrollPhaseChange({ (oldPhase: ScrollPhase, newPhase: ScrollPhase) -> Void in
111 | isInteracting = newPhase == .interacting
112 | if oldPhase == .interacting && newPhase != .interacting {
113 | // user released finger
114 | onEndDragging()
115 | triggerPullToRefreshIfNeeded()
116 | }
117 | })
118 | }
119 |
120 | @ViewBuilder
121 | private func pullToRefreshAnimationView() -> some View {
122 | ZStack(alignment: .top, content: {
123 | animationViewBuilder(pullToRefreshState)
124 | .frame(height: pullToRefreshAnimationHeight)
125 | .modifier(GeometryGroupModifier())
126 | })
127 | .opacity(isPullToRefreshEnabled ? 1 : 0)
128 | .frame(height: pullToRefreshAnimationViewHeight(), alignment: .top)
129 | .frame(maxWidth: .infinity)
130 | .clipped()
131 | .offset(x: 0, y: animationOffsetY + offsetAboveRefreshingAnimation)
132 | }
133 |
134 | // MARK: - Private
135 |
136 | private func pullToRefreshAnimationViewHeight() -> CGFloat {
137 | switch pullToRefreshState {
138 | case .idle: return 0
139 | case .pulling: return min(pullToRefreshProgressPoints, pullToRefreshAnimationHeight)
140 | case .refreshing: return pullToRefreshAnimationHeight
141 | case .finishing: return 0
142 | }
143 | }
144 |
145 | private func updateAnimationOffset(contentOffset: CGFloat) {
146 | if contentOffset > 0 {
147 | animationOffsetY = -contentOffset
148 | pullToRefreshProgressPoints = 0
149 | } else {
150 | animationOffsetY = 0
151 | pullToRefreshProgressPoints = -contentOffset
152 | }
153 | updatePullToRefreshPullingState()
154 | }
155 |
156 | private func updatePullToRefreshPullingState() {
157 | switch pullToRefreshState {
158 | case .idle,
159 | .pulling:
160 | if pullToRefreshProgressPoints <= 0.5 {
161 | pullToRefreshState = .idle
162 | } else {
163 | let progress = pullToRefreshProgressPoints / pullToRefreshPullHeight
164 | if progress >= 1.0 {
165 | triggerPullToRefresh()
166 | } else {
167 | pullToRefreshState = .pulling(progress: progress)
168 | }
169 | }
170 |
171 | case .refreshing:
172 | // need to wait for external signal that refreshing has ended
173 | break
174 |
175 | case .finishing:
176 | if pullToRefreshProgressPoints <= 0.5 {
177 | pullToRefreshState = .idle
178 | } else {
179 | pullToRefreshState = .finishing
180 | }
181 | }
182 | }
183 |
184 | private func triggerPullToRefreshIfNeeded() {
185 | guard isPullToRefreshEnabled else {
186 | return
187 | }
188 | switch pullToRefreshState {
189 | case .idle,
190 | .refreshing,
191 | .finishing:
192 | // wrong state
193 | break
194 |
195 | case .pulling(let progress):
196 | if progress >= 1.0 {
197 | triggerPullToRefresh()
198 | }
199 | }
200 | }
201 |
202 | private func triggerPullToRefresh() {
203 | pullToRefreshState = .refreshing
204 | isRefreshing.wrappedValue = true
205 | onRefresh()
206 | UIImpactFeedbackGenerator(style: .medium).impactOccurred()
207 | }
208 |
209 | private func showPullToRefreshAnimationIfNeeded() {
210 | switch pullToRefreshState {
211 | case .idle,
212 | .pulling,
213 | .finishing:
214 | pullToRefreshState = .refreshing
215 |
216 | case .refreshing:
217 | // already refreshing
218 | break
219 | }
220 | }
221 |
222 | private func endPullToRefreshAnimationIfNeeded() {
223 | switch pullToRefreshState {
224 | case .idle:
225 | // should not be here
226 | break
227 |
228 | case .pulling:
229 | // no need to finish - deceleration will do the trick
230 | break
231 |
232 | case .refreshing:
233 | withAnimation(.easeInOut(duration: animationDuration), {
234 | pullToRefreshState = .finishing
235 | })
236 |
237 | case .finishing:
238 | // already finishing
239 | break
240 | }
241 | }
242 |
243 | }
244 |
245 | // MARK: - Preview
246 |
247 | #Preview(body: {
248 | if #available(iOS 18.0, *) {
249 | PullToRefreshListView18IOS(
250 | pullToRefreshAnimationHeight: 100,
251 | pullToRefreshPullHeight: 100,
252 | isRefreshing: .constant(true),
253 | onRefresh: {
254 | print("Refreshing")
255 | },
256 | animationViewBuilder: { (state) in
257 | switch state {
258 | case .idle:
259 | Color.clear
260 | case .pulling(let progress):
261 | ProgressView(value: progress, total: 1)
262 | .progressViewStyle(.linear)
263 | case .refreshing:
264 | ProgressView()
265 | .progressViewStyle(.circular)
266 | case .finishing:
267 | ProgressView()
268 | .progressViewStyle(.circular)
269 | }
270 | },
271 | contentViewBuilder: { _ in
272 | ForEach(0..<5, content: { (item) in
273 | Text("Item \(item)")
274 | })
275 | })
276 | } else {
277 | // Fallback on earlier versions
278 | }
279 | })
280 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/PullToRefreshListViewOldIOS.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | public struct PullToRefreshListViewOldIOS: View {
10 |
11 | private let pullToRefreshAnimationHeight: CGFloat
12 | private let animationDuration: TimeInterval
13 | private let offsetAboveRefreshingAnimation: CGFloat
14 | private let showsIndicators: Bool
15 | private let isPullToRefreshEnabled: Bool
16 | private let isRefreshing: Binding
17 | private let onRefresh: () -> Void
18 | private let animationViewBuilder: (_ state: PullToRefreshListViewState) -> AnimationViewType
19 | private let contentViewBuilder: (_ scrollViewSize: CGSize) -> ContentViewType
20 |
21 | @StateObject private var scrollViewState: ScrollViewState2
22 | @State private var topOffset: CGFloat = 0
23 | private let isLogEnabled: Bool = false
24 |
25 | // MARK: - Initialization
26 |
27 | public init(pullToRefreshAnimationHeight: CGFloat,
28 | animationDuration: TimeInterval = 0.3,
29 | showsIndicators: Bool = true,
30 | isPullToRefreshEnabled: Bool = true,
31 | offsetAboveRefreshingAnimation: CGFloat = 0,
32 | isRefreshing: Binding,
33 | onRefresh: @escaping () -> Void,
34 | @ViewBuilder animationViewBuilder: @escaping (_ state: PullToRefreshListViewState) -> AnimationViewType,
35 | @ViewBuilder contentViewBuilder: @escaping (_ scrollViewSize: CGSize) -> ContentViewType) {
36 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
37 | self.animationDuration = animationDuration
38 | self.offsetAboveRefreshingAnimation = offsetAboveRefreshingAnimation
39 | self.showsIndicators = showsIndicators
40 | self.isPullToRefreshEnabled = isPullToRefreshEnabled
41 | self.isRefreshing = isRefreshing
42 | self.onRefresh = onRefresh
43 | self.animationViewBuilder = animationViewBuilder
44 | self.contentViewBuilder = contentViewBuilder
45 | _scrollViewState = StateObject(wrappedValue: ScrollViewState2(pullToRefreshAnimationHeight: pullToRefreshAnimationHeight))
46 | }
47 |
48 | // MARK: - UI
49 |
50 | public var body: some View {
51 | let defaultAnimation: Animation = .easeInOut(duration: animationDuration)
52 | ZStack(alignment: .top, content: {
53 | // Animations
54 | VStack(spacing: 0, content: {
55 | Color.clear
56 | .frame(height: offsetAboveRefreshingAnimation)
57 | ZStack(alignment: .center, content: {
58 | animationViewBuilder(scrollViewState.state)
59 | .modifier(GeometryGroupModifier())
60 | })
61 | .frame(height: pullToRefreshAnimationHeight)
62 | Color.clear
63 | })
64 | .opacity(isPullToRefreshEnabled ? 1 : 0)
65 | // List content
66 | GeometryReader(content: { (geometryProxy) in
67 | VStack(spacing: 0, content: {
68 | // view to show pull to refresh animations
69 | // List inset is calculated as safeAreaTopInset + this view height
70 | Color.clear
71 | .frame(height: pullToRefreshAnimationHeight * scrollViewState.progress)
72 | // scrolling direction is not possible to nicely calculate in old ios versions
73 | List(content: {
74 | Color.clear
75 | .frame(height: offsetAboveRefreshingAnimation)
76 | .listRowSeparator(.hidden)
77 | .listRowInsets(EdgeInsets())
78 | .listRowBackground(Color.clear)
79 | Color.clear
80 | .listRowSeparator(.hidden)
81 | .listRowBackground(Color.clear)
82 | .frame(height: 1)
83 | .listRowInsets(EdgeInsets())
84 | .readLayoutData(coordinateSpace: .global, onChange: { (data) in
85 | let offsetConclusive = data.frameInCoordinateSpace.minY - topOffset - offsetAboveRefreshingAnimation
86 | if isLogEnabled {
87 | debugPrint("Current offset: \(offsetConclusive) = \(data.frameInCoordinateSpace.minY)" +
88 | " - \(topOffset) - \(offsetAboveRefreshingAnimation)")
89 | }
90 | scrollViewState.contentOffset = offsetConclusive
91 | updateProgressIfNeeded()
92 | stopIfNeeded()
93 | resetReadyTriggeredStateIfNeeded()
94 | startIfNeeded()
95 | })
96 | contentViewBuilder(geometryProxy.size)
97 | .modifier(GeometryGroupModifier())
98 | })
99 | .environment(\.defaultMinListRowHeight, 0)
100 | .listStyle(PlainListStyle())
101 | })
102 | .animation(scrollViewState.isDragging ? nil : defaultAnimation, value: scrollViewState.progress)
103 | })
104 | })
105 | .readLayoutData(coordinateSpace: .global, onChange: { (data) in
106 | topOffset = data.frameInCoordinateSpace.minY
107 | if isLogEnabled {
108 | debugPrint("Setting topOffset = \(topOffset)")
109 | }
110 | })
111 | .onAppear(perform: {
112 | scrollViewState.addGestureRecognizer()
113 | })
114 | .onDisappear(perform: {
115 | scrollViewState.removeGestureRecognizer()
116 | })
117 | .onChange(of: isRefreshing.wrappedValue, perform: { (isRefreshing) in
118 | if !isRefreshing {
119 | scrollViewState.isRefreshing = false
120 | scrollViewState.isFinishing = true
121 | stopIfNeeded()
122 | resetReadyTriggeredStateIfNeeded()
123 | }
124 | })
125 | .onChange(of: scrollViewState.isDragging, perform: { (_) in
126 | stopIfNeeded()
127 | resetReadyTriggeredStateIfNeeded()
128 | })
129 | }
130 |
131 | // MARK: - Private
132 |
133 | private func startIfNeeded() {
134 | if isPullToRefreshEnabled,
135 | scrollViewState.contentOffset > pullToRefreshAnimationHeight,
136 | !scrollViewState.isTriggered &&
137 | !scrollViewState.isRefreshing {
138 |
139 | scrollViewState.isTriggered = true
140 | scrollViewState.isRefreshing = true
141 | isRefreshing.wrappedValue = true
142 | onRefresh()
143 | UIImpactFeedbackGenerator(style: .medium).impactOccurred()
144 | }
145 | }
146 |
147 | private func stopIfNeeded() {
148 | if !scrollViewState.isRefreshing && !scrollViewState.isDragging {
149 | scrollViewState.isFinishing = true
150 | Timer.scheduledTimer(withTimeInterval: 0.005, repeats: true, block: { (timer) in
151 | let progressLocal = scrollViewState.progress - 0.03
152 | if progressLocal <= 0 {
153 | scrollViewState.isFinishing = false
154 | scrollViewState.progress = 0
155 | resetReadyTriggeredStateIfNeeded()
156 | timer.invalidate()
157 | } else {
158 | scrollViewState.progress = progressLocal
159 | }
160 | })
161 | }
162 | }
163 |
164 | private func resetReadyTriggeredStateIfNeeded() {
165 | if scrollViewState.contentOffset <= 1 &&
166 | scrollViewState.progress == 0 &&
167 | scrollViewState.isTriggered &&
168 | !scrollViewState.isRefreshing &&
169 | !scrollViewState.isDragging {
170 |
171 | scrollViewState.isTriggered = false
172 | }
173 | }
174 |
175 | private func updateProgressIfNeeded() {
176 | if scrollViewState.isDragging && !scrollViewState.isRefreshing && !scrollViewState.isTriggered && !scrollViewState.isFinishing {
177 | // initial pulling will increase progress to 1; then when drag finished or
178 | // fetch finished stopIfNeeded() will be called where progress will be set to 0.
179 | // isRefreshing check is here because we need to remove conflict between setting progress.
180 | let progress = min(max(scrollViewState.contentOffset / pullToRefreshAnimationHeight, 0), 1)
181 | if progress > scrollViewState.progress { // dragging back to top leads to issues
182 | scrollViewState.progress = progress
183 | }
184 | }
185 | }
186 |
187 | }
188 |
189 | // MARK: - Preview
190 |
191 | #Preview(body: {
192 | PullToRefreshListViewOldIOS(
193 | pullToRefreshAnimationHeight: 100,
194 | isRefreshing: .constant(true),
195 | onRefresh: {
196 | debugPrint("Refreshing")
197 | },
198 | animationViewBuilder: { (state) in
199 | switch state {
200 | case .idle:
201 | Color.clear
202 | case .pulling(let progress):
203 | ProgressView(value: progress, total: 1)
204 | .progressViewStyle(.linear)
205 | case .refreshing:
206 | ProgressView()
207 | .progressViewStyle(.circular)
208 | case .finishing:
209 | ProgressView()
210 | .progressViewStyle(.circular)
211 | }
212 | },
213 | contentViewBuilder: { _ in
214 | ForEach(0..<5, content: { (item) in
215 | Text("Item \(item)")
216 | })
217 | })
218 | })
219 |
220 | // MARK: - ScrollViewState
221 |
222 | private class ScrollViewState2: NSObject, ObservableObject, UIGestureRecognizerDelegate {
223 |
224 | @Published var isDragging: Bool = false
225 | var isTriggered: Bool = false
226 | var isRefreshing: Bool = false
227 | var isFinishing: Bool = false
228 | var contentOffset: CGFloat = 0
229 | @Published var progress: CGFloat = 0
230 |
231 | private var panGestureRecognizer: UIPanGestureRecognizer?
232 |
233 | let pullToRefreshAnimationHeight: CGFloat
234 |
235 | var state: PullToRefreshListViewState {
236 | if isRefreshing {
237 | return .refreshing
238 | } else if progress > 0 && !isTriggered && !isFinishing {
239 | return .pulling(progress: progress)
240 | } else if isFinishing {
241 | if isTriggered {
242 | return .pulling(progress: progress)
243 | } else {
244 | return .finishing
245 | }
246 | } else {
247 | return .idle
248 | }
249 | }
250 |
251 | // MARK: - Initialization
252 |
253 | init(pullToRefreshAnimationHeight: CGFloat) {
254 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
255 | }
256 |
257 | // MARK: - Public
258 |
259 | internal func addGestureRecognizer() {
260 | guard let controller = getRootViewController() else {
261 | return
262 | }
263 | // there is no ability to get isDragging state from SwiftUI ScrollView,
264 | // because ScrollView gesture recognizer intercepts event.
265 | // That's why custom gesture recognizer is added to application window rootViewController view.
266 | let recognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
267 | panGestureRecognizer = recognizer
268 | recognizer.delegate = self
269 | controller.view.addGestureRecognizer(recognizer)
270 | }
271 |
272 | internal func removeGestureRecognizer() {
273 | guard let controller = getRootViewController(),
274 | let recognizer = panGestureRecognizer
275 | else {
276 | return
277 | }
278 | controller.view.removeGestureRecognizer(recognizer)
279 | }
280 |
281 | // MARK: - UIGestureRecognizerDelegate
282 |
283 | internal func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
284 | shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
285 | return true
286 | }
287 |
288 | // MARK: - Interface Callbacks
289 |
290 | @objc
291 | private func handlePanGesture(_ recognizer: UIPanGestureRecognizer) {
292 | switch recognizer.state {
293 |
294 | case .possible,
295 | .changed:
296 | break
297 | case .began:
298 | isDragging = true
299 | case .ended,
300 | .cancelled,
301 | .failed:
302 | isDragging = false
303 | @unknown default:
304 | break
305 | }
306 | }
307 |
308 | // MARK: - Private
309 |
310 | private func getRootViewController() -> UIViewController? {
311 | return (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first?.rootViewController
312 | }
313 |
314 | }
315 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/PullToRefreshScrollView.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | public enum PullToRefreshScrollViewState {
10 | case idle
11 | case pulling(progress: CGFloat)
12 | case refreshing
13 | case finishing(progress: CGFloat, isTriggered: Bool)
14 | }
15 |
16 | public struct PullToRefreshScrollView: View {
17 |
18 | private let pullToRefreshAnimationHeight: CGFloat
19 | private let animationDuration: TimeInterval
20 | private let showsIndicators: Bool
21 | private let isPullToRefreshEnabled: Bool
22 | private let offsetAboveRefreshingAnimation: CGFloat
23 | private let isRefreshing: Binding
24 | private let onRefresh: () -> Void
25 | private let animationViewBuilder: (_ state: PullToRefreshScrollViewState) -> AnimationViewType
26 | private let contentViewBuilder: (_ scrollViewSize: CGSize) -> ContentViewType
27 |
28 | @StateObject private var scrollViewState: ScrollViewState
29 |
30 | @State private var topOffset: CGFloat = 0
31 |
32 | private let isLogEnabled: Bool = false
33 |
34 | // MARK: - Initialization
35 |
36 | public init(pullToRefreshAnimationHeight: CGFloat,
37 | animationDuration: TimeInterval = 0.3,
38 | showsIndicators: Bool = true,
39 | isPullToRefreshEnabled: Bool = true,
40 | offsetAboveRefreshingAnimation: CGFloat = 0,
41 | isRefreshing: Binding,
42 | onRefresh: @escaping () -> Void,
43 | @ViewBuilder animationViewBuilder: @escaping (_ state: PullToRefreshScrollViewState) -> AnimationViewType,
44 | @ViewBuilder contentViewBuilder: @escaping (_ scrollViewSize: CGSize) -> ContentViewType) {
45 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
46 | self.animationDuration = animationDuration
47 | self.showsIndicators = showsIndicators
48 | self.isPullToRefreshEnabled = isPullToRefreshEnabled
49 | self.offsetAboveRefreshingAnimation = offsetAboveRefreshingAnimation
50 | self.isRefreshing = isRefreshing
51 | self.onRefresh = onRefresh
52 | self.animationViewBuilder = animationViewBuilder
53 | self.contentViewBuilder = contentViewBuilder
54 | _scrollViewState = StateObject(wrappedValue: ScrollViewState(pullToRefreshAnimationHeight: pullToRefreshAnimationHeight))
55 | }
56 |
57 | // MARK: - UI
58 |
59 | public var body: some View {
60 | let defaultAnimation: Animation = .easeInOut(duration: animationDuration)
61 | ZStack(alignment: .top, content: {
62 | // Animations
63 | VStack(spacing: 0, content: {
64 | Color.clear
65 | .frame(height: offsetAboveRefreshingAnimation)
66 | ZStack(alignment: .center, content: {
67 | animationViewBuilder(scrollViewState.state)
68 | .modifier(GeometryGroupModifier())
69 | })
70 | .frame(height: pullToRefreshAnimationHeight)
71 | Color.clear
72 | })
73 | .opacity(isPullToRefreshEnabled ? 1 : 0)
74 | // Scroll content
75 | GeometryReader(content: { geometryProxy in
76 | ScrollView(.vertical, showsIndicators: showsIndicators, content: {
77 | VStack(spacing: 0, content: {
78 | Color.clear
79 | .frame(height: offsetAboveRefreshingAnimation)
80 | Color.clear
81 | .frame(height: pullToRefreshAnimationHeight * scrollViewState.progress)
82 | contentViewBuilder(geometryProxy.size)
83 | .modifier(GeometryGroupModifier())
84 | })
85 | .animation(scrollViewState.isDragging ? nil : defaultAnimation, value: scrollViewState.progress)
86 | .readLayoutData(coordinateSpace: .global, onChange: { (data) in
87 | let offsetConclusive = data.frameInCoordinateSpace.minY - topOffset
88 | if isLogEnabled {
89 | debugPrint("Current offset: \(offsetConclusive) = \(data.frameInCoordinateSpace.minY) - \(topOffset)")
90 | }
91 | scrollViewState.contentOffset = offsetConclusive
92 | updateProgressIfNeeded()
93 | resetReadyTriggeredStateIfNeeded()
94 | startIfNeeded()
95 | })
96 | })
97 | })
98 | })
99 | .readLayoutData(coordinateSpace: .global, onChange: { (data) in
100 | topOffset = data.frameInCoordinateSpace.minY
101 | if isLogEnabled {
102 | debugPrint("Setting topOffset = \(topOffset)")
103 | }
104 | })
105 | .onAppear(perform: {
106 | scrollViewState.addGestureRecognizer()
107 | })
108 | .onDisappear(perform: {
109 | scrollViewState.removeGestureRecognizer()
110 | })
111 | .onChange(of: isRefreshing.wrappedValue, perform: { (isRefreshing) in
112 | if !isRefreshing {
113 | scrollViewState.isRefreshing = false
114 | scrollViewState.isFinishing = true
115 | stopIfNeeded()
116 | resetReadyTriggeredStateIfNeeded()
117 | }
118 | })
119 | .onChange(of: scrollViewState.isDragging, perform: { (_) in
120 | stopIfNeeded()
121 | resetReadyTriggeredStateIfNeeded()
122 | })
123 | }
124 |
125 | // MARK: - Private
126 |
127 | private func startIfNeeded() {
128 | if isPullToRefreshEnabled,
129 | (scrollViewState.contentOffset * 2) > pullToRefreshAnimationHeight,
130 | !scrollViewState.isTriggered &&
131 | !scrollViewState.isRefreshing {
132 |
133 | scrollViewState.isTriggered = true
134 | scrollViewState.isRefreshing = true
135 | isRefreshing.wrappedValue = true
136 | onRefresh()
137 | UIImpactFeedbackGenerator(style: .medium).impactOccurred()
138 | }
139 | }
140 |
141 | private func stopIfNeeded() {
142 | if !scrollViewState.isRefreshing && !scrollViewState.isDragging {
143 | if scrollViewState.progress > 0 {
144 | if scrollViewState.isTriggered {
145 | scrollViewState.isFinishing = true
146 | Timer.scheduledTimer(withTimeInterval: 0.005, repeats: true, block: { (timer) in
147 | let progressLocal = scrollViewState.progress - 0.03
148 | if progressLocal <= 0 {
149 | scrollViewState.isFinishing = false
150 | scrollViewState.progress = 0
151 | resetReadyTriggeredStateIfNeeded()
152 | timer.invalidate()
153 | } else {
154 | scrollViewState.progress = progressLocal
155 | }
156 | })
157 | } else {
158 | scrollViewState.progress = 0
159 | resetReadyTriggeredStateIfNeeded()
160 | }
161 | }
162 | }
163 | }
164 |
165 | private func resetReadyTriggeredStateIfNeeded() {
166 | if scrollViewState.contentOffset <= 1 &&
167 | scrollViewState.progress == 0 &&
168 | scrollViewState.isTriggered &&
169 | !scrollViewState.isRefreshing &&
170 | !scrollViewState.isDragging {
171 |
172 | scrollViewState.isTriggered = false
173 | }
174 | }
175 |
176 | private func updateProgressIfNeeded() {
177 | if !scrollViewState.isRefreshing && !scrollViewState.isTriggered && !scrollViewState.isFinishing {
178 | // initial pulling will increase progress to 1; then when drag finished or
179 | // fetch finished stopIfNeeded() will be called where progress will be set to 0.
180 | // isRefreshing check is here because we need to remove conflict between setting progress.
181 | scrollViewState.progress = min(max((scrollViewState.contentOffset * 2) / pullToRefreshAnimationHeight, 0), 1)
182 | }
183 | }
184 |
185 | }
186 |
187 | // MARK: - Preview
188 |
189 | #Preview(body: {
190 | PullToRefreshScrollView(
191 | pullToRefreshAnimationHeight: 100,
192 | animationDuration: 0.3,
193 | isRefreshing: .constant(true),
194 | onRefresh: {
195 | debugPrint("Refreshing")
196 | },
197 | animationViewBuilder: { (state) in
198 | switch state {
199 | case .idle:
200 | Color.clear
201 | case .pulling(let progress):
202 | ProgressView(value: progress, total: 1)
203 | .progressViewStyle(.linear)
204 | case .refreshing:
205 | ProgressView()
206 | .progressViewStyle(.circular)
207 | case .finishing(let progress, let isTriggered):
208 | if isTriggered {
209 | ProgressView()
210 | .progressViewStyle(.circular)
211 | } else {
212 | ProgressView(value: progress, total: 1)
213 | .progressViewStyle(.linear)
214 | }
215 | }
216 | },
217 | contentViewBuilder: { _ in
218 | Color(.lightGray)
219 | .frame(height: 1000)
220 | })
221 | })
222 |
223 | // MARK: - ScrollViewState
224 |
225 | private class ScrollViewState: NSObject, ObservableObject, UIGestureRecognizerDelegate {
226 |
227 | @Published var isDragging: Bool = false
228 | var isTriggered: Bool = false
229 | var isRefreshing: Bool = false
230 | var isFinishing: Bool = false
231 | var contentOffset: CGFloat = 0
232 | @Published var progress: CGFloat = 0
233 |
234 | private var panGestureRecognizer: UIPanGestureRecognizer?
235 |
236 | let pullToRefreshAnimationHeight: CGFloat
237 |
238 | var state: PullToRefreshScrollViewState {
239 | if isRefreshing {
240 | return .refreshing
241 | } else if progress > 0 && !isTriggered && !isFinishing {
242 | return .pulling(progress: progress)
243 | } else if isFinishing {
244 | return .finishing(progress: progress, isTriggered: isTriggered)
245 | } else {
246 | return .idle
247 | }
248 | }
249 |
250 | // MARK: - Initialization
251 |
252 | init(pullToRefreshAnimationHeight: CGFloat) {
253 | self.pullToRefreshAnimationHeight = pullToRefreshAnimationHeight
254 | }
255 |
256 | // MARK: - Public
257 |
258 | internal func addGestureRecognizer() {
259 | guard let controller = getRootViewController() else {
260 | return
261 | }
262 | // there is no ability to get isDragging state from SwiftUI ScrollView,
263 | // because ScrollView gesture recognizer intercepts event.
264 | // That's why custom gesture recognizer is added to application window rootViewController view.
265 | let recognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
266 | panGestureRecognizer = recognizer
267 | recognizer.delegate = self
268 | controller.view.addGestureRecognizer(recognizer)
269 | }
270 |
271 | internal func removeGestureRecognizer() {
272 | guard let controller = getRootViewController(),
273 | let recognizer = panGestureRecognizer
274 | else {
275 | return
276 | }
277 | controller.view.removeGestureRecognizer(recognizer)
278 | }
279 |
280 | // MARK: - UIGestureRecognizerDelegate
281 |
282 | internal func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
283 | shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
284 | return true
285 | }
286 |
287 | // MARK: - Interface Callbacks
288 |
289 | @objc
290 | private func handlePanGesture(_ recognizer: UIPanGestureRecognizer) {
291 | switch recognizer.state {
292 |
293 | case .possible,
294 | .changed:
295 | break
296 | case .began:
297 | isDragging = true
298 | case .ended,
299 | .cancelled,
300 | .failed:
301 | isDragging = false
302 | @unknown default:
303 | break
304 | }
305 | }
306 |
307 | // MARK: - Private
308 |
309 | private func getRootViewController() -> UIViewController? {
310 | return (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first?.rootViewController
311 | }
312 |
313 | }
314 |
--------------------------------------------------------------------------------
/Sources/PullToRefreshSwiftUI/View+readLayoutData.swift:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2024 Shakuro (https://shakuro.com/)
4 | //
5 | //
6 |
7 | import SwiftUI
8 |
9 | struct LayoutData: Equatable {
10 | let size: CGSize
11 | let frameInCoordinateSpace: CGRect
12 | let safeAreaInsets: EdgeInsets
13 | }
14 |
15 | extension View {
16 |
17 | func readLayoutData(coordinateSpace: CoordinateSpace, onChange: @escaping (LayoutData) -> Void) -> some View {
18 | self
19 | .background(
20 | GeometryReader(content: { (geometryProxy) in
21 | Color.clear
22 | .preference(key: SizePreferenceKey.self,
23 | value: LayoutData(size: geometryProxy.size,
24 | frameInCoordinateSpace: geometryProxy.frame(in: coordinateSpace),
25 | safeAreaInsets: geometryProxy.safeAreaInsets))
26 | })
27 | )
28 | .onPreferenceChange(SizePreferenceKey.self, perform: onChange)
29 | }
30 |
31 | }
32 |
33 | private struct SizePreferenceKey: PreferenceKey {
34 |
35 | static var defaultValue: LayoutData = LayoutData(size: .zero, frameInCoordinateSpace: CGRect.zero, safeAreaInsets: EdgeInsets())
36 |
37 | static func reduce(value: inout LayoutData, nextValue: () -> LayoutData) { }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/PullToRefreshSwiftUITests/PullToRefreshSwiftUITests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import PullToRefreshSwiftUI
3 |
4 | final class PullToRefreshSwiftUITests: XCTestCase {
5 | func testExample() throws {
6 | // XCTest Documentation
7 | // https://developer.apple.com/documentation/xctest
8 |
9 | // Defining Test Cases and Test Methods
10 | // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
11 | }
12 | }
13 |
--------------------------------------------------------------------------------